Compare commits
No commits in common. "main" and "v0.5.1" have entirely different histories.
@ -2,9 +2,9 @@
|
|||||||
"name": "webman/admin",
|
"name": "webman/admin",
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "基于Webman官方的Admin修改",
|
"description": "Webman Admin",
|
||||||
"require": {
|
"require": {
|
||||||
"workerman/webman-framework": ">=1.4",
|
"workerman/webman-framework": "^1.4",
|
||||||
"illuminate/database": ">=7.30",
|
"illuminate/database": ">=7.30",
|
||||||
"illuminate/pagination": ">=7.30",
|
"illuminate/pagination": ">=7.30",
|
||||||
"illuminate/events": ">=7.30",
|
"illuminate/events": ">=7.30",
|
||||||
|
@ -39,9 +39,10 @@ class Auth
|
|||||||
*/
|
*/
|
||||||
public static function canAccess(string $controller, string $action, int &$code = 0, string &$msg = ''): bool
|
public static function canAccess(string $controller, string $action, int &$code = 0, string &$msg = ''): bool
|
||||||
{
|
{
|
||||||
// 无控制器信息说明是函数调用,函数不属于任何控制器,鉴权操作应该在函数内部完成。
|
|
||||||
if (!$controller) {
|
if (!$controller) {
|
||||||
return true;
|
$msg = '无法识别当前控制器';
|
||||||
|
$code = 3;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
// 获取控制器鉴权信息
|
// 获取控制器鉴权信息
|
||||||
$class = new \ReflectionClass($controller);
|
$class = new \ReflectionClass($controller);
|
||||||
@ -98,9 +99,9 @@ class Auth
|
|||||||
|
|
||||||
// 如果action为index,规则里有任意一个以$controller开头的权限即可
|
// 如果action为index,规则里有任意一个以$controller开头的权限即可
|
||||||
if (strtolower($action) === 'index') {
|
if (strtolower($action) === 'index') {
|
||||||
|
$controller = str_replace('\\', '\\\\', $controller);
|
||||||
$rule = Rule::where(function ($query) use ($controller, $action) {
|
$rule = Rule::where(function ($query) use ($controller, $action) {
|
||||||
$controller_like = str_replace('\\', '\\\\', $controller);
|
$query->where('key', 'like', "$controller@%")->orWhere('key', $controller);
|
||||||
$query->where('key', 'like', "$controller_like@%")->orWhere('key', $controller);
|
|
||||||
})->whereIn('id', $rule_ids)->first();
|
})->whereIn('id', $rule_ids)->first();
|
||||||
if ($rule) {
|
if ($rule) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace plugin\admin\api;
|
namespace plugin\admin\api;
|
||||||
|
|
||||||
use ReflectionException;
|
|
||||||
use Webman\Http\Request;
|
use Webman\Http\Request;
|
||||||
use Webman\Http\Response;
|
use Webman\Http\Response;
|
||||||
use Webman\MiddlewareInterface;
|
use Webman\MiddlewareInterface;
|
||||||
use support\exception\BusinessException;
|
use support\exception\BusinessException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对外提供的鉴权中间件
|
* 对外提供的webman-admin鉴权中间件
|
||||||
*/
|
*/
|
||||||
class Middleware implements MiddlewareInterface
|
class Middleware implements MiddlewareInterface
|
||||||
{
|
{
|
||||||
@ -17,7 +16,7 @@ class Middleware implements MiddlewareInterface
|
|||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @param callable $handler
|
* @param callable $handler
|
||||||
* @return Response
|
* @return Response
|
||||||
* @throws ReflectionException
|
* @throws \ReflectionException
|
||||||
* @throws BusinessException
|
* @throws BusinessException
|
||||||
*/
|
*/
|
||||||
public function process(Request $request, callable $handler): Response
|
public function process(Request $request, callable $handler): Response
|
||||||
@ -31,20 +30,7 @@ class Middleware implements MiddlewareInterface
|
|||||||
if ($request->expectsJson()) {
|
if ($request->expectsJson()) {
|
||||||
$response = json(['code' => $code, 'msg' => $msg, 'type' => 'error']);
|
$response = json(['code' => $code, 'msg' => $msg, 'type' => 'error']);
|
||||||
} else {
|
} else {
|
||||||
if ($code === 401) {
|
$response = \response($msg, 401);
|
||||||
$response = response(<<<EOF
|
|
||||||
<script>
|
|
||||||
if (self !== top) {
|
|
||||||
parent.location.reload();
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
EOF
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$request->app = '';
|
|
||||||
$request->plugin = 'admin';
|
|
||||||
$response = view('common/error/403')->withStatus(403);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$response = $request->method() == 'OPTIONS' ? response('') : $handler($request);
|
$response = $request->method() == 'OPTIONS' ? response('') : $handler($request);
|
||||||
@ -52,4 +38,4 @@ EOF
|
|||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,63 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace plugin\admin\app\common;
|
|
||||||
|
|
||||||
|
|
||||||
use plugin\admin\app\model\Admin;
|
|
||||||
use plugin\admin\app\model\AdminRole;
|
|
||||||
use plugin\admin\app\model\Role;
|
|
||||||
use plugin\admin\app\model\Rule;
|
|
||||||
|
|
||||||
class Auth
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 获取权限范围内的所有角色id
|
|
||||||
* @param bool $with_self
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function getScopeRoleIds(bool $with_self = false): array
|
|
||||||
{
|
|
||||||
if (!$admin = admin()) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
$role_ids = $admin['roles'];
|
|
||||||
$rules = Role::whereIn('id', $role_ids)->pluck('rules')->toArray();
|
|
||||||
if ($rules && in_array('*', $rules)) {
|
|
||||||
return Role::pluck('id')->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
$roles = Role::get();
|
|
||||||
$tree = new Tree($roles);
|
|
||||||
$descendants = $tree->getDescendant($role_ids, $with_self);
|
|
||||||
return array_column($descendants, 'id');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取权限范围内的所有管理员id
|
|
||||||
* @param bool $with_self
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function getScopeAdminIds(bool $with_self = false): array
|
|
||||||
{
|
|
||||||
$role_ids = static::getScopeRoleIds($with_self);
|
|
||||||
return AdminRole::whereIn('role_id', $role_ids)->pluck('admin_id')->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否是超级管理员
|
|
||||||
* @param int $admin_id
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function isSupperAdmin(int $admin_id = 0): bool
|
|
||||||
{
|
|
||||||
if (!$admin_id) {
|
|
||||||
if (!$roles = admin('roles')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$roles = AdminRole::where('admin_id', $admin_id)->pluck('role_id');
|
|
||||||
}
|
|
||||||
$rules = Role::whereIn('id', $roles)->pluck('rules');
|
|
||||||
return $rules && in_array('*', $rules->toArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace plugin\admin\app\common;
|
namespace plugin\admin\app\common;
|
||||||
|
|
||||||
use plugin\admin\app\common\Util;
|
|
||||||
use support\exception\BusinessException;
|
use support\exception\BusinessException;
|
||||||
|
|
||||||
class Layui
|
class Layui
|
||||||
@ -125,31 +124,6 @@ EOF;
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 输入框模糊查询
|
|
||||||
* @param $options
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function inputLike($options)
|
|
||||||
{
|
|
||||||
[$label, $field, $value, $props, $verify_string, $required_string, $class] = $this->options($options);
|
|
||||||
$type = $props['type'] ?? 'text';
|
|
||||||
|
|
||||||
$this->htmlContent .= <<<EOF
|
|
||||||
|
|
||||||
<div class="layui-form-item">
|
|
||||||
$label
|
|
||||||
<div class="$class">
|
|
||||||
<div class="layui-input-block">
|
|
||||||
<input type="hidden" autocomplete="off" name="{$field}[]" value="like" class="layui-input inline-block">
|
|
||||||
<input type="$type" autocomplete="off" name="{$field}[]" class="layui-input">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
EOF;
|
EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,17 +138,6 @@ EOF;
|
|||||||
$this->inputRange($options);
|
$this->inputRange($options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 数字输入框模糊查询
|
|
||||||
* @param $options
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function inputNumberLike($options)
|
|
||||||
{
|
|
||||||
$options['props']['type'] = 'number';
|
|
||||||
$this->inputLike($options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 密码输入框
|
* 密码输入框
|
||||||
* @param $options
|
* @param $options
|
||||||
@ -196,69 +159,16 @@ EOF;
|
|||||||
[$label, $field, $value, $props, $verify_string, $required_string, $class] = $this->options($options);
|
[$label, $field, $value, $props, $verify_string, $required_string, $class] = $this->options($options);
|
||||||
|
|
||||||
$placeholder_string = !empty($props['placeholder']) ? ' placeholder="'.$props['placeholder'].'"' : '';
|
$placeholder_string = !empty($props['placeholder']) ? ' placeholder="'.$props['placeholder'].'"' : '';
|
||||||
$disabled_string = !empty($props['disabled']) ? ' disabled' : '';
|
|
||||||
|
|
||||||
$this->htmlContent .= <<<EOF
|
$this->htmlContent .= <<<EOF
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
$label
|
$label
|
||||||
<div class="$class">
|
<div class="$class">
|
||||||
<textarea name="$field"$required_string$verify_string$placeholder_string$disabled_string class="layui-textarea">$value</textarea>
|
<textarea name="$field"$required_string$verify_string$placeholder_string class="layui-textarea">$value</textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 富文本
|
|
||||||
* @param $options
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function richText($options)
|
|
||||||
{
|
|
||||||
[$label, $field, $value, $props, $verify_string, $required_string, $class] = $this->options($options);
|
|
||||||
|
|
||||||
$placeholder_string = !empty($props['placeholder']) ? ' placeholder="'.$props['placeholder'].'"' : '';
|
|
||||||
$disabled_string = !empty($props['disabled']) ? ' disabled' : '';
|
|
||||||
$id = $field;
|
|
||||||
|
|
||||||
$this->htmlContent .= <<<EOF
|
|
||||||
|
|
||||||
<div class="layui-form-item">
|
|
||||||
$label
|
|
||||||
<div class="$class">
|
|
||||||
<textarea id="$id" name="$field"$required_string$verify_string$placeholder_string$disabled_string class="layui-textarea">$value</textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
EOF;
|
|
||||||
|
|
||||||
$options_string = '';
|
|
||||||
if (!isset($props['images_upload_url'])) {
|
|
||||||
$props['images_upload_url'] = '/app/admin/upload/image';
|
|
||||||
}
|
|
||||||
foreach ($props as $key => $item) {
|
|
||||||
if (is_array($item)) {
|
|
||||||
$item = json_encode($item, JSON_UNESCAPED_UNICODE);
|
|
||||||
$options_string .= "\n $key: $item,";
|
|
||||||
} else {
|
|
||||||
$options_string .= "\n $key: \"$item\",";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->jsContent .= <<<EOF
|
|
||||||
|
|
||||||
// 字段 {$options['label']} $field
|
|
||||||
layui.use(["tinymce"], function() {
|
|
||||||
var tinymce = layui.tinymce
|
|
||||||
var edit = tinymce.render({
|
|
||||||
elem: "#$id",$options_string
|
|
||||||
});
|
|
||||||
edit.on("blur", function(){
|
|
||||||
layui.$("#$id").val(edit.getContent());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
EOF;
|
EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,7 +274,7 @@ EOF;
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
$label
|
$label
|
||||||
<div class="$class">
|
<div class="$class">
|
||||||
<img class="img-3" src=""/>
|
<img style="max-width:90px;max-height:90px;" src=""/>
|
||||||
<input type="text" style="display:none" name="$field" value="$value" />
|
<input type="text" style="display:none" name="$field" value="$value" />
|
||||||
<button type="button" class="pear-btn pear-btn-primary pear-btn-sm" id="$id" permission="app.admin.upload.image">
|
<button type="button" class="pear-btn pear-btn-primary pear-btn-sm" id="$id" permission="app.admin.upload.image">
|
||||||
<i class="layui-icon layui-icon-upload"></i>上传图片
|
<i class="layui-icon layui-icon-upload"></i>上传图片
|
||||||
@ -701,9 +611,6 @@ EOF;
|
|||||||
$default_value_string = isset($props['initValue']) && $props['initValue'] != '' ? $props['initValue'] : $value;
|
$default_value_string = isset($props['initValue']) && $props['initValue'] != '' ? $props['initValue'] : $value;
|
||||||
$url = $props['url'] ?? '';
|
$url = $props['url'] ?? '';
|
||||||
$options_string = '';
|
$options_string = '';
|
||||||
if (isset($props['lay-verify'])) {
|
|
||||||
$props['layVerify'] = $props['lay-verify'];
|
|
||||||
}
|
|
||||||
unset($props['lay-verify'], $props['url']);
|
unset($props['lay-verify'], $props['url']);
|
||||||
foreach ($props as $key => $item) {
|
foreach ($props as $key => $item) {
|
||||||
if (is_array($item)) {
|
if (is_array($item)) {
|
||||||
@ -722,22 +629,19 @@ EOF;
|
|||||||
$this->jsContent .= <<<EOF
|
$this->jsContent .= <<<EOF
|
||||||
|
|
||||||
// 字段 {$options['label']} $field
|
// 字段 {$options['label']} $field
|
||||||
layui.use(["jquery", "xmSelect", "popup"], function() {
|
layui.use(["jquery", "xmSelect"], function() {
|
||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
url: "$url",
|
url: "$url",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
let value = layui.$("#$id").attr("value");
|
let value = layui.$("#$id").attr("value");
|
||||||
let initValue = value ? value.split(",") : [];
|
let initValue = value ? value.split(",") : [];
|
||||||
layui.xmSelect.render({
|
layui.xmSelect.render({
|
||||||
el: "#$id",
|
el: "#$id",
|
||||||
name: "$field",
|
name: "$field",
|
||||||
initValue: initValue,
|
initValue: initValue,
|
||||||
data: res.data, $options_string
|
data: e.data, $options_string
|
||||||
});
|
})
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -765,7 +669,7 @@ EOF;
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
$select_label
|
$select_label
|
||||||
<div class="$class">
|
<div class="$class">
|
||||||
<div name="$field" id="$id"$required_string value="$default_value_string" ></div>
|
<div name="$field" id="$id"$verify_string$required_string value="$default_value_string" ></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -780,7 +684,7 @@ EOF;
|
|||||||
* @return Layui
|
* @return Layui
|
||||||
* @throws BusinessException
|
* @throws BusinessException
|
||||||
*/
|
*/
|
||||||
public static function buildForm($table, string $type = 'insert'): Layui
|
static public function buildForm($table, string $type = 'insert'): Layui
|
||||||
{
|
{
|
||||||
if (!in_array($type, ['insert', 'update', 'search'])) {
|
if (!in_array($type, ['insert', 'update', 'search'])) {
|
||||||
$type = 'insert';
|
$type = 'insert';
|
||||||
@ -799,7 +703,6 @@ EOF;
|
|||||||
$field = $info['field'];
|
$field = $info['field'];
|
||||||
$default = $columns[$key]['default'];
|
$default = $columns[$key]['default'];
|
||||||
$control = strtolower($info['control']);
|
$control = strtolower($info['control']);
|
||||||
$auto_increment = $columns[$key]['auto_increment'];
|
|
||||||
// 搜索框里上传组件替换为input
|
// 搜索框里上传组件替换为input
|
||||||
if ($type == 'search' && in_array($control, ['upload', 'uploadimg'])) {
|
if ($type == 'search' && in_array($control, ['upload', 'uploadimg'])) {
|
||||||
$control = 'input';
|
$control = 'input';
|
||||||
@ -808,34 +711,20 @@ EOF;
|
|||||||
|
|
||||||
$props = Util::getControlProps($control, $info['control_args']);
|
$props = Util::getControlProps($control, $info['control_args']);
|
||||||
// 增加修改记录验证必填项
|
// 增加修改记录验证必填项
|
||||||
if ($filter == 'form_show' && !$columns[$key]['nullable'] && $default === null && ($field !== 'password' || $type === 'insert')) {
|
if ($filter == 'form_show' && !isset($props['lay-verify']) && !$columns[$key]['nullable'] && $default === null && ($field !== 'password' || $type === 'insert')) {
|
||||||
if (!isset($props['lay-verify'])) {
|
$props['lay-verify'] = 'required';
|
||||||
$props['lay-verify'] = 'required';
|
|
||||||
// 非类似字符串类型不允许传空
|
|
||||||
} elseif (!in_array($columns[$key]['type'], ['string', 'text', 'mediumText', 'longText', 'char', 'binary', 'json'])
|
|
||||||
&& strpos($props['lay-verify'], 'required') === false) {
|
|
||||||
$props['lay-verify'] = 'required|' . $props['lay-verify'];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// 增加记录显示默认值
|
// 增加记录显示默认值
|
||||||
if ($type === 'insert' && !isset($props['value']) && $default !== null) {
|
if ($type === 'insert' && !isset($props['value']) && $default !== null) {
|
||||||
$props['value'] = $default;
|
$props['value'] = $default;
|
||||||
}
|
}
|
||||||
// 主键是自增字段或者表单是更新类型不显示主键
|
// 表单不显示主键
|
||||||
if ($primary_key && $field == $primary_key && (($type == 'insert' && $auto_increment) || $type == 'update')) {
|
if ($filter == 'form_show' && $primary_key && $field == $primary_key) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 查询类型
|
// 范围查询
|
||||||
if ($type == 'search') {
|
if ($type == 'search' && $info['search_type'] == 'between' && method_exists($form, "{$control}Range")) {
|
||||||
if ($info['search_type'] == 'between' && method_exists($form, "{$control}Range")) {
|
$control = "{$control}Range";
|
||||||
$control = "{$control}Range";
|
|
||||||
} elseif ($info['search_type'] == 'like' && method_exists($form, "{$control}Like")) {
|
|
||||||
$control = "{$control}Like";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 查询类型移除lay-verify
|
|
||||||
if ($type == 'search' && !empty($props['lay-verify'])) {
|
|
||||||
$props['lay-verify'] = '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$options = [
|
$options = [
|
||||||
@ -856,7 +745,7 @@ EOF;
|
|||||||
* @return array|string|string[]
|
* @return array|string|string[]
|
||||||
* @throws BusinessException
|
* @throws BusinessException
|
||||||
*/
|
*/
|
||||||
public static function buildTable($table, int $indent = 0)
|
static public function buildTable($table, int $indent = 0)
|
||||||
{
|
{
|
||||||
$schema = Util::getSchema($table);
|
$schema = Util::getSchema($table);
|
||||||
$forms = $schema['forms'];
|
$forms = $schema['forms'];
|
||||||
@ -894,10 +783,7 @@ EOF;
|
|||||||
$.post(UPDATE_API, postData, function (res) {
|
$.post(UPDATE_API, postData, function (res) {
|
||||||
layer.close(load);
|
layer.close(load);
|
||||||
if (res.code) {
|
if (res.code) {
|
||||||
return layui.popup.failure(res.msg, function () {
|
return layui.popup.failure(res.msg);
|
||||||
data.elem.checked = !data.elem.checked;
|
|
||||||
form.render();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return layui.popup.success("操作成功");
|
return layui.popup.success("操作成功");
|
||||||
})
|
})
|
||||||
@ -949,8 +835,6 @@ EOF;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$api_result .= "\napiResults[\"$field\"] = " . json_encode($options, JSON_UNESCAPED_UNICODE) . ";";
|
$api_result .= "\napiResults[\"$field\"] = " . json_encode($options, JSON_UNESCAPED_UNICODE) . ";";
|
||||||
} else {
|
|
||||||
$api_result .= "\napiResults[\"$field\"] = [];";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$templet = <<<EOF
|
$templet = <<<EOF
|
||||||
@ -1044,9 +928,6 @@ layui.each(apis, function (k, item) {
|
|||||||
url: url,
|
url: url,
|
||||||
dateType: "json",
|
dateType: "json",
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
if (res.code) {
|
|
||||||
return layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
function travel(items) {
|
function travel(items) {
|
||||||
for (let k in items) {
|
for (let k in items) {
|
||||||
let item = items[k];
|
let item = items[k];
|
||||||
|
@ -1,187 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace plugin\admin\app\common;
|
|
||||||
|
|
||||||
|
|
||||||
class Tree
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取完整的树结构,包含祖先节点
|
|
||||||
*/
|
|
||||||
const INCLUDE_ANCESTORS = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取部分树,不包含祖先节点
|
|
||||||
*/
|
|
||||||
const EXCLUDE_ANCESTORS = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 数据
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $data = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 哈希树
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $hashTree = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 父级字段名
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $pidName = 'pid';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $data
|
|
||||||
* @param string $pid_name
|
|
||||||
*/
|
|
||||||
public function __construct($data, string $pid_name = 'pid')
|
|
||||||
{
|
|
||||||
$this->pidName = $pid_name;
|
|
||||||
if (is_object($data) && method_exists($data, 'toArray')) {
|
|
||||||
$this->data = $data->toArray();
|
|
||||||
} else {
|
|
||||||
$this->data = (array)$data;
|
|
||||||
}
|
|
||||||
$this->hashTree = $this->getHashTree();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取子孙节点
|
|
||||||
* @param array $include
|
|
||||||
* @param bool $with_self
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getDescendant(array $include, bool $with_self = false): array
|
|
||||||
{
|
|
||||||
$items = [];
|
|
||||||
foreach ($include as $id) {
|
|
||||||
if (!isset($this->hashTree[$id])) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
if ($with_self) {
|
|
||||||
$item = $this->hashTree[$id];
|
|
||||||
unset($item['children']);
|
|
||||||
$items[$item['id']] = $item;
|
|
||||||
}
|
|
||||||
foreach ($this->hashTree[$id]['children'] ?? [] as $item) {
|
|
||||||
unset($item['children']);
|
|
||||||
$items[$item['id']] = $item;
|
|
||||||
foreach ($this->getDescendant([$item['id']]) as $it) {
|
|
||||||
$items[$it['id']] = $it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return array_values($items);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取哈希树
|
|
||||||
* @param array $data
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function getHashTree(array $data = []): array
|
|
||||||
{
|
|
||||||
$data = $data ?: $this->data;
|
|
||||||
$hash_tree = [];
|
|
||||||
foreach ($data as $item) {
|
|
||||||
$hash_tree[$item['id']] = $item;
|
|
||||||
}
|
|
||||||
foreach ($hash_tree as $index => $item) {
|
|
||||||
if ($item[$this->pidName] && isset($hash_tree[$item[$this->pidName]])) {
|
|
||||||
$hash_tree[$item[$this->pidName]]['children'][$hash_tree[$index]['id']] = &$hash_tree[$index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $hash_tree;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取树
|
|
||||||
* @param array $include
|
|
||||||
* @param int $type
|
|
||||||
* @return array|null
|
|
||||||
*/
|
|
||||||
public function getTree(array $include = [], int $type = 1): ?array
|
|
||||||
{
|
|
||||||
// $type === static::EXCLUDE_ANCESTORS
|
|
||||||
if ($type === static::EXCLUDE_ANCESTORS) {
|
|
||||||
$items = [];
|
|
||||||
$include = array_unique($include);
|
|
||||||
foreach ($include as $id) {
|
|
||||||
if (!isset($this->hashTree[$id])) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
$items[] = $this->hashTree[$id];
|
|
||||||
}
|
|
||||||
return static::arrayValues($items);
|
|
||||||
}
|
|
||||||
|
|
||||||
// $type === static::INCLUDE_ANCESTORS
|
|
||||||
$hash_tree = $this->hashTree;
|
|
||||||
$items = [];
|
|
||||||
if ($include) {
|
|
||||||
$map = [];
|
|
||||||
foreach ($include as $id) {
|
|
||||||
if (!isset($hash_tree[$id])) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$item = $hash_tree[$id];
|
|
||||||
$max_depth = 100;
|
|
||||||
while ($max_depth-- > 0 && $item[$this->pidName] && isset($hash_tree[$item[$this->pidName]])) {
|
|
||||||
$last_item = $item;
|
|
||||||
$pid = $item[$this->pidName];
|
|
||||||
$item = $hash_tree[$pid];
|
|
||||||
$item_id = $item['id'];
|
|
||||||
if (empty($map[$item_id])) {
|
|
||||||
$map[$item_id] = 1;
|
|
||||||
$hash_tree[$pid]['children'] = [];
|
|
||||||
}
|
|
||||||
$hash_tree[$pid]['children'][$last_item['id']] = $last_item;
|
|
||||||
$item = $hash_tree[$pid];
|
|
||||||
}
|
|
||||||
$items[$item['id']] = $item;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$items = $hash_tree;
|
|
||||||
}
|
|
||||||
$formatted_items = [];
|
|
||||||
foreach ($items as $item) {
|
|
||||||
if (!$item[$this->pidName] || !isset($hash_tree[$item[$this->pidName]])) {
|
|
||||||
$formatted_items[] = $item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return static::arrayValues($formatted_items);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 递归重建数组下标
|
|
||||||
* @param $array
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function arrayValues($array): array
|
|
||||||
{
|
|
||||||
if (!$array) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
if (!isset($array['children'])) {
|
|
||||||
$current = current($array);
|
|
||||||
if (!is_array($current) || !isset($current['children'])) {
|
|
||||||
return $array;
|
|
||||||
}
|
|
||||||
$tree = array_values($array);
|
|
||||||
foreach ($tree as $index => $item) {
|
|
||||||
$tree[$index] = static::arrayValues($item);
|
|
||||||
}
|
|
||||||
return $tree;
|
|
||||||
}
|
|
||||||
$array['children'] = array_values($array['children']);
|
|
||||||
foreach ($array['children'] as $index => $child) {
|
|
||||||
$array['children'][$index] = static::arrayValues($child);
|
|
||||||
}
|
|
||||||
return $array;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -2,25 +2,23 @@
|
|||||||
|
|
||||||
namespace plugin\admin\app\common;
|
namespace plugin\admin\app\common;
|
||||||
|
|
||||||
use process\Monitor;
|
|
||||||
use Throwable;
|
|
||||||
use Illuminate\Database\Connection;
|
use Illuminate\Database\Connection;
|
||||||
use Illuminate\Database\Schema\Builder;
|
use Illuminate\Database\Schema\Builder;
|
||||||
use plugin\admin\app\model\Option;
|
use plugin\admin\app\model\Option;
|
||||||
use support\exception\BusinessException;
|
|
||||||
use support\Db;
|
use support\Db;
|
||||||
use Workerman\Timer;
|
use support\exception\BusinessException;
|
||||||
use Workerman\Worker;
|
use Throwable;
|
||||||
|
use function config;
|
||||||
|
|
||||||
class Util
|
class Util
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 密码哈希
|
* 密码哈希
|
||||||
* @param $password
|
* @param $password
|
||||||
* @param string $algo
|
* @param $algo
|
||||||
* @return false|string|null
|
* @return false|string|null
|
||||||
*/
|
*/
|
||||||
public static function passwordHash($password, string $algo = PASSWORD_DEFAULT)
|
static public function passwordHash($password, $algo = PASSWORD_DEFAULT)
|
||||||
{
|
{
|
||||||
return password_hash($password, $algo);
|
return password_hash($password, $algo);
|
||||||
}
|
}
|
||||||
@ -31,7 +29,7 @@ class Util
|
|||||||
* @param $hash
|
* @param $hash
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function passwordVerify(string $password, string $hash): bool
|
static public function passwordVerify($password, $hash): bool
|
||||||
{
|
{
|
||||||
return password_verify($password, $hash);
|
return password_verify($password, $hash);
|
||||||
}
|
}
|
||||||
@ -40,7 +38,7 @@ class Util
|
|||||||
* 获取webman-admin数据库连接
|
* 获取webman-admin数据库连接
|
||||||
* @return Connection
|
* @return Connection
|
||||||
*/
|
*/
|
||||||
public static function db(): Connection
|
static function db(): Connection
|
||||||
{
|
{
|
||||||
return Db::connection('plugin.admin.mysql');
|
return Db::connection('plugin.admin.mysql');
|
||||||
}
|
}
|
||||||
@ -49,65 +47,17 @@ class Util
|
|||||||
* 获取SchemaBuilder
|
* 获取SchemaBuilder
|
||||||
* @return Builder
|
* @return Builder
|
||||||
*/
|
*/
|
||||||
public static function schema(): Builder
|
static function schema(): Builder
|
||||||
{
|
{
|
||||||
return Db::schema('plugin.admin.mysql');
|
return Db::schema('plugin.admin.mysql');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取语义化时间
|
|
||||||
* @param $time
|
|
||||||
* @return false|string
|
|
||||||
*/
|
|
||||||
public static function humanDate($time)
|
|
||||||
{
|
|
||||||
$timestamp = is_numeric($time) ? $time : strtotime($time);
|
|
||||||
$dur = time() - $timestamp;
|
|
||||||
if ($dur < 0) {
|
|
||||||
return date('Y-m-d', $timestamp);
|
|
||||||
} else {
|
|
||||||
if ($dur < 60) {
|
|
||||||
return $dur . '秒前';
|
|
||||||
} else {
|
|
||||||
if ($dur < 3600) {
|
|
||||||
return floor($dur / 60) . '分钟前';
|
|
||||||
} else {
|
|
||||||
if ($dur < 86400) {
|
|
||||||
return floor($dur / 3600) . '小时前';
|
|
||||||
} else {
|
|
||||||
if ($dur < 2592000) { // 30天内
|
|
||||||
return floor($dur / 86400) . '天前';
|
|
||||||
} else {
|
|
||||||
return date('Y-m-d', $timestamp);;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return date('Y-m-d', $timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 格式化文件大小
|
|
||||||
* @param $file_size
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function formatBytes($file_size): string
|
|
||||||
{
|
|
||||||
$size = sprintf("%u", $file_size);
|
|
||||||
if($size == 0) {
|
|
||||||
return("0 Bytes");
|
|
||||||
}
|
|
||||||
$size_name = array(" Bytes", " KB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB");
|
|
||||||
return round($size/pow(1024, ($i = floor(log($size, 1024)))), 2) . $size_name[$i];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据库字符串转义
|
* 数据库字符串转义
|
||||||
* @param $var
|
* @param $var
|
||||||
* @return false|string
|
* @return false|string
|
||||||
*/
|
*/
|
||||||
public static function pdoQuote($var)
|
static public function pdoQuote($var)
|
||||||
{
|
{
|
||||||
return Util::db()->getPdo()->quote($var, \PDO::PARAM_STR);
|
return Util::db()->getPdo()->quote($var, \PDO::PARAM_STR);
|
||||||
}
|
}
|
||||||
@ -118,7 +68,7 @@ class Util
|
|||||||
* @return string
|
* @return string
|
||||||
* @throws BusinessException
|
* @throws BusinessException
|
||||||
*/
|
*/
|
||||||
public static function checkTableName(string $table): string
|
static public function checkTableName(string $table): string
|
||||||
{
|
{
|
||||||
if (!preg_match('/^[a-zA-Z_0-9]+$/', $table)) {
|
if (!preg_match('/^[a-zA-Z_0-9]+$/', $table)) {
|
||||||
throw new BusinessException('表名不合法');
|
throw new BusinessException('表名不合法');
|
||||||
@ -132,7 +82,7 @@ class Util
|
|||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws BusinessException
|
* @throws BusinessException
|
||||||
*/
|
*/
|
||||||
public static function filterAlphaNum($var)
|
static public function filterAlphaNum($var)
|
||||||
{
|
{
|
||||||
$vars = (array)$var;
|
$vars = (array)$var;
|
||||||
array_walk_recursive($vars, function ($item) {
|
array_walk_recursive($vars, function ($item) {
|
||||||
@ -149,7 +99,7 @@ class Util
|
|||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws BusinessException
|
* @throws BusinessException
|
||||||
*/
|
*/
|
||||||
public static function filterNum($var)
|
static public function filterNum($var)
|
||||||
{
|
{
|
||||||
$vars = (array)$var;
|
$vars = (array)$var;
|
||||||
array_walk_recursive($vars, function ($item) {
|
array_walk_recursive($vars, function ($item) {
|
||||||
@ -166,7 +116,7 @@ class Util
|
|||||||
* @return string
|
* @return string
|
||||||
* @throws BusinessException
|
* @throws BusinessException
|
||||||
*/
|
*/
|
||||||
public static function filterUrlPath($var): string
|
static public function filterUrlPath($var): string
|
||||||
{
|
{
|
||||||
if (!is_string($var) || !preg_match('/^[a-zA-Z0-9_\-\/&?.]+$/', $var)) {
|
if (!is_string($var) || !preg_match('/^[a-zA-Z0-9_\-\/&?.]+$/', $var)) {
|
||||||
throw new BusinessException('参数不合法');
|
throw new BusinessException('参数不合法');
|
||||||
@ -180,7 +130,7 @@ class Util
|
|||||||
* @return string
|
* @return string
|
||||||
* @throws BusinessException
|
* @throws BusinessException
|
||||||
*/
|
*/
|
||||||
public static function filterPath($var): string
|
static public function filterPath($var): string
|
||||||
{
|
{
|
||||||
if (!is_string($var) || !preg_match('/^[a-zA-Z0-9_\-\/]+$/', $var)) {
|
if (!is_string($var) || !preg_match('/^[a-zA-Z0-9_\-\/]+$/', $var)) {
|
||||||
throw new BusinessException('参数不合法');
|
throw new BusinessException('参数不合法');
|
||||||
@ -233,7 +183,7 @@ class Util
|
|||||||
* @param string $value
|
* @param string $value
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function camel(string $value): string
|
static public function camel(string $value): string
|
||||||
{
|
{
|
||||||
static $cache = [];
|
static $cache = [];
|
||||||
$key = $value;
|
$key = $value;
|
||||||
@ -252,7 +202,7 @@ class Util
|
|||||||
* @param $value
|
* @param $value
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function smCamel($value): string
|
static public function smCamel($value): string
|
||||||
{
|
{
|
||||||
return lcfirst(static::camel($value));
|
return lcfirst(static::camel($value));
|
||||||
}
|
}
|
||||||
@ -262,7 +212,7 @@ class Util
|
|||||||
* @param $comment
|
* @param $comment
|
||||||
* @return false|mixed|string
|
* @return false|mixed|string
|
||||||
*/
|
*/
|
||||||
public static function getCommentFirstLine($comment)
|
static public function getCommentFirstLine($comment)
|
||||||
{
|
{
|
||||||
if ($comment === false) {
|
if ($comment === false) {
|
||||||
return false;
|
return false;
|
||||||
@ -279,7 +229,7 @@ class Util
|
|||||||
* 表单类型到插件的映射
|
* 表单类型到插件的映射
|
||||||
* @return \string[][]
|
* @return \string[][]
|
||||||
*/
|
*/
|
||||||
public static function methodControlMap(): array
|
static public function methodControlMap(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
//method=>[控件]
|
//method=>[控件]
|
||||||
@ -315,8 +265,6 @@ class Util
|
|||||||
'char' => ['Input'],
|
'char' => ['Input'],
|
||||||
|
|
||||||
'binary' => ['Input'],
|
'binary' => ['Input'],
|
||||||
|
|
||||||
'json' => ['input']
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,7 +273,7 @@ class Util
|
|||||||
* @param $type
|
* @param $type
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function typeToControl($type): string
|
static public function typeToControl($type): string
|
||||||
{
|
{
|
||||||
if (stripos($type, 'int') !== false) {
|
if (stripos($type, 'int') !== false) {
|
||||||
return 'inputNumber';
|
return 'inputNumber';
|
||||||
@ -348,7 +296,7 @@ class Util
|
|||||||
* @param $unsigned
|
* @param $unsigned
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function typeToMethod($type, $unsigned = false)
|
static public function typeToMethod($type, $unsigned = false)
|
||||||
{
|
{
|
||||||
if (stripos($type, 'int') !== false) {
|
if (stripos($type, 'int') !== false) {
|
||||||
$type = str_replace('int', 'Integer', $type);
|
$type = str_replace('int', 'Integer', $type);
|
||||||
@ -371,11 +319,11 @@ class Util
|
|||||||
* @return array|mixed
|
* @return array|mixed
|
||||||
* @throws BusinessException
|
* @throws BusinessException
|
||||||
*/
|
*/
|
||||||
public static function getSchema($table, $section = null)
|
static public function getSchema($table, $section = null)
|
||||||
{
|
{
|
||||||
Util::checkTableName($table);
|
Util::checkTableName($table);
|
||||||
$database = config('database.connections')['plugin.admin.mysql']['database'];
|
$database = config('database.connections')['plugin.admin.mysql']['database'];
|
||||||
$schema_raw = $section !== 'table' ? Util::db()->select("select * from information_schema.COLUMNS where TABLE_SCHEMA = '$database' and table_name = '$table' order by ORDINAL_POSITION") : [];
|
$schema_raw = $section !== 'table' ? Util::db()->select("select * from information_schema.COLUMNS where TABLE_SCHEMA = '$database' and table_name = '$table'") : [];
|
||||||
$forms = [];
|
$forms = [];
|
||||||
$columns = [];
|
$columns = [];
|
||||||
foreach ($schema_raw as $item) {
|
foreach ($schema_raw as $item) {
|
||||||
@ -447,7 +395,7 @@ class Util
|
|||||||
* @param $schema
|
* @param $schema
|
||||||
* @return mixed|string
|
* @return mixed|string
|
||||||
*/
|
*/
|
||||||
public static function getLengthValue($schema)
|
static public function getLengthValue($schema)
|
||||||
{
|
{
|
||||||
$type = $schema->DATA_TYPE;
|
$type = $schema->DATA_TYPE;
|
||||||
if (in_array($type, ['float', 'decimal', 'double'])) {
|
if (in_array($type, ['float', 'decimal', 'double'])) {
|
||||||
@ -473,7 +421,7 @@ class Util
|
|||||||
* @param $control_args
|
* @param $control_args
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function getControlProps($control, $control_args): array
|
static public function getControlProps($control, $control_args): array
|
||||||
{
|
{
|
||||||
if (!$control_args) {
|
if (!$control_args) {
|
||||||
return [];
|
return [];
|
||||||
@ -513,7 +461,7 @@ class Util
|
|||||||
* @param string $package
|
* @param string $package
|
||||||
* @return mixed|string
|
* @return mixed|string
|
||||||
*/
|
*/
|
||||||
public static function getPackageVersion(string $package)
|
static public function getPackageVersion(string $package)
|
||||||
{
|
{
|
||||||
$installed_php = base_path('vendor/composer/installed.php');
|
$installed_php = base_path('vendor/composer/installed.php');
|
||||||
if (is_file($installed_php)) {
|
if (is_file($installed_php)) {
|
||||||
@ -524,44 +472,18 @@ class Util
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reload webman
|
* reload webman (不支持windows)
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function reloadWebman()
|
static public function reloadWebman()
|
||||||
{
|
{
|
||||||
if (function_exists('posix_kill')) {
|
if (function_exists('posix_kill')) {
|
||||||
try {
|
try {
|
||||||
posix_kill(posix_getppid(), SIGUSR1);
|
posix_kill(posix_getppid(), SIGUSR1);
|
||||||
return true;
|
return true;
|
||||||
} catch (Throwable $e) {}
|
} catch (Throwable $e) {}
|
||||||
} else {
|
|
||||||
Timer::add(1, function () {
|
|
||||||
Worker::stopAll();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
}
|
||||||
* Pause file monitor
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public static function pauseFileMonitor()
|
|
||||||
{
|
|
||||||
if (method_exists(Monitor::class, 'pause')) {
|
|
||||||
Monitor::pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resume file monitor
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public static function resumeFileMonitor()
|
|
||||||
{
|
|
||||||
if (method_exists(Monitor::class, 'resume')) {
|
|
||||||
Monitor::resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace plugin\admin\app\controller;
|
namespace plugin\admin\app\controller;
|
||||||
|
|
||||||
use plugin\admin\app\common\Auth;
|
|
||||||
use plugin\admin\app\common\Util;
|
use plugin\admin\app\common\Util;
|
||||||
use plugin\admin\app\model\Admin;
|
use plugin\admin\app\model\Admin;
|
||||||
use support\exception\BusinessException;
|
use support\exception\BusinessException;
|
||||||
@ -73,15 +72,11 @@ class AccountController extends Crud
|
|||||||
if (!$admin || !Util::passwordVerify($password, $admin->password)) {
|
if (!$admin || !Util::passwordVerify($password, $admin->password)) {
|
||||||
return $this->json(1, '账户不存在或密码错误');
|
return $this->json(1, '账户不存在或密码错误');
|
||||||
}
|
}
|
||||||
if ($admin->status != 0) {
|
|
||||||
return $this->json(1, '当前账户暂时无法登录');
|
|
||||||
}
|
|
||||||
$admin->login_at = date('Y-m-d H:i:s');
|
|
||||||
$admin->save();
|
|
||||||
$this->removeLoginLimit($username);
|
$this->removeLoginLimit($username);
|
||||||
$admin = $admin->toArray();
|
$admin = $admin->toArray();
|
||||||
$session = $request->session();
|
$session = $request->session();
|
||||||
unset($admin['password']);
|
unset($admin['password']);
|
||||||
|
$admin['roles'] = $admin['roles'] ? explode(',', $admin['roles']) : [];
|
||||||
$session->set('admin', $admin);
|
$session->set('admin', $admin);
|
||||||
return $this->json(0, '登录成功', [
|
return $this->json(0, '登录成功', [
|
||||||
'nickname' => $admin['nickname'],
|
'nickname' => $admin['nickname'],
|
||||||
@ -112,14 +107,15 @@ class AccountController extends Crud
|
|||||||
return $this->json(1);
|
return $this->json(1);
|
||||||
}
|
}
|
||||||
$info = [
|
$info = [
|
||||||
'id' => $admin['id'],
|
|
||||||
'username' => $admin['username'],
|
|
||||||
'nickname' => $admin['nickname'],
|
'nickname' => $admin['nickname'],
|
||||||
|
'desc' => 'manager',
|
||||||
'avatar' => $admin['avatar'],
|
'avatar' => $admin['avatar'],
|
||||||
|
'token' => $request->sessionId(),
|
||||||
|
'userId' => $admin['id'],
|
||||||
|
'username' => $admin['username'],
|
||||||
'email' => $admin['email'],
|
'email' => $admin['email'],
|
||||||
'mobile' => $admin['mobile'],
|
'mobile' => $admin['mobile'],
|
||||||
'isSupperAdmin' => Auth::isSupperAdmin(),
|
'roles' => []
|
||||||
'token' => $request->sessionId(),
|
|
||||||
];
|
];
|
||||||
return $this->json(0, 'ok', $info);
|
return $this->json(0, 'ok', $info);
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,7 @@
|
|||||||
|
|
||||||
namespace plugin\admin\app\controller;
|
namespace plugin\admin\app\controller;
|
||||||
|
|
||||||
use plugin\admin\app\common\Auth;
|
|
||||||
use plugin\admin\app\model\Admin;
|
use plugin\admin\app\model\Admin;
|
||||||
use plugin\admin\app\model\AdminRole;
|
|
||||||
use support\exception\BusinessException;
|
use support\exception\BusinessException;
|
||||||
use support\Request;
|
use support\Request;
|
||||||
use support\Response;
|
use support\Response;
|
||||||
@ -14,29 +12,12 @@ use support\Response;
|
|||||||
*/
|
*/
|
||||||
class AdminController extends Crud
|
class AdminController extends Crud
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* 不需要鉴权的方法
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $noNeedAuth = ['select'];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Admin
|
* @var Admin
|
||||||
*/
|
*/
|
||||||
protected $model = null;
|
protected $model = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* 开启auth数据限制
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $dataLimit = 'auth';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 以id为数据限制字段
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $dataLimitField = 'id';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造函数
|
* 构造函数
|
||||||
* @return void
|
* @return void
|
||||||
@ -55,36 +36,6 @@ class AdminController extends Crud
|
|||||||
return view('admin/index');
|
return view('admin/index');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询
|
|
||||||
* @param Request $request
|
|
||||||
* @return Response
|
|
||||||
* @throws BusinessException
|
|
||||||
*/
|
|
||||||
public function select(Request $request): Response
|
|
||||||
{
|
|
||||||
[$where, $format, $limit, $field, $order] = $this->selectInput($request);
|
|
||||||
$query = $this->doSelect($where, $field, $order);
|
|
||||||
if ($format === 'select') {
|
|
||||||
return $this->formatSelect($query->get());
|
|
||||||
}
|
|
||||||
$paginator = $query->paginate($limit);
|
|
||||||
$items = $paginator->items();
|
|
||||||
$admin_ids = array_column($items, 'id');
|
|
||||||
$roles = AdminRole::whereIn('admin_id', $admin_ids)->get();
|
|
||||||
$roles_map = [];
|
|
||||||
foreach ($roles as $role) {
|
|
||||||
$roles_map[$role['admin_id']][] = $role['role_id'];
|
|
||||||
}
|
|
||||||
$login_admin_id = admin_id();
|
|
||||||
foreach ($items as $index => $item) {
|
|
||||||
$admin_id = $item['id'];
|
|
||||||
$items[$index]['roles'] = isset($roles_map[$admin_id]) ? implode(',', $roles_map[$admin_id]) : '';
|
|
||||||
$items[$index]['show_toolbar'] = $admin_id != $login_admin_id;
|
|
||||||
}
|
|
||||||
return json(['code' => 0, 'msg' => 'ok', 'count' => $paginator->total(), 'data' => $items]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 插入
|
* 插入
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
@ -94,24 +45,7 @@ class AdminController extends Crud
|
|||||||
public function insert(Request $request): Response
|
public function insert(Request $request): Response
|
||||||
{
|
{
|
||||||
if ($request->method() === 'POST') {
|
if ($request->method() === 'POST') {
|
||||||
$data = $this->insertInput($request);
|
return parent::insert($request);
|
||||||
$admin_id = $this->doInsert($data);
|
|
||||||
$role_ids = $request->post('roles');
|
|
||||||
$role_ids = $role_ids ? explode(',', $role_ids) : [];
|
|
||||||
if (!$role_ids) {
|
|
||||||
return $this->json(1, '至少选择一个角色组');
|
|
||||||
}
|
|
||||||
if (!Auth::isSupperAdmin() && array_diff($role_ids, Auth::getScopeRoleIds())) {
|
|
||||||
return $this->json(1, '角色超出权限范围');
|
|
||||||
}
|
|
||||||
AdminRole::where('admin_id', $admin_id)->delete();
|
|
||||||
foreach ($role_ids as $id) {
|
|
||||||
$admin_role = new AdminRole;
|
|
||||||
$admin_role->admin_id = $admin_id;
|
|
||||||
$admin_role->role_id = $id;
|
|
||||||
$admin_role->save();
|
|
||||||
}
|
|
||||||
return $this->json(0, 'ok', ['id' => $admin_id]);
|
|
||||||
}
|
}
|
||||||
return view('admin/insert');
|
return view('admin/insert');
|
||||||
}
|
}
|
||||||
@ -125,53 +59,8 @@ class AdminController extends Crud
|
|||||||
public function update(Request $request): Response
|
public function update(Request $request): Response
|
||||||
{
|
{
|
||||||
if ($request->method() === 'POST') {
|
if ($request->method() === 'POST') {
|
||||||
|
return parent::update($request);
|
||||||
[$id, $data] = $this->updateInput($request);
|
|
||||||
$admin_id = $request->post('id');
|
|
||||||
if (!$admin_id) {
|
|
||||||
return $this->json(1, '缺少参数');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 不能禁用自己
|
|
||||||
if (isset($data['status']) && $data['status'] == 1 && $id == admin_id()) {
|
|
||||||
return $this->json(1, '不能禁用自己');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 需要更新角色
|
|
||||||
$role_ids = $request->post('roles');
|
|
||||||
if ($role_ids !== null) {
|
|
||||||
if (!$role_ids) {
|
|
||||||
return $this->json(1, '至少选择一个角色组');
|
|
||||||
}
|
|
||||||
$role_ids = explode(',', $role_ids);
|
|
||||||
|
|
||||||
$is_supper_admin = Auth::isSupperAdmin();
|
|
||||||
$exist_role_ids = AdminRole::where('admin_id', $admin_id)->pluck('role_id')->toArray();
|
|
||||||
$scope_role_ids = Auth::getScopeRoleIds();
|
|
||||||
if (!$is_supper_admin && !array_intersect($exist_role_ids, $scope_role_ids)) {
|
|
||||||
return $this->json(1, '无权限更改该记录');
|
|
||||||
}
|
|
||||||
if (!$is_supper_admin && array_diff($role_ids, $scope_role_ids)) {
|
|
||||||
return $this->json(1, '角色超出权限范围');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除账户角色
|
|
||||||
$delete_ids = array_diff($exist_role_ids, $role_ids);
|
|
||||||
AdminRole::whereIn('role_id', $delete_ids)->where('admin_id', $admin_id)->delete();
|
|
||||||
// 添加账户角色
|
|
||||||
$add_ids = array_diff($role_ids, $exist_role_ids);
|
|
||||||
foreach ($add_ids as $role_id) {
|
|
||||||
$admin_role = new AdminRole;
|
|
||||||
$admin_role->admin_id = $admin_id;
|
|
||||||
$admin_role->role_id = $role_id;
|
|
||||||
$admin_role->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->doUpdate($id, $data);
|
|
||||||
return $this->json(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return view('admin/update');
|
return view('admin/update');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,11 +80,7 @@ class AdminController extends Crud
|
|||||||
if (in_array(admin_id(), $ids)) {
|
if (in_array(admin_id(), $ids)) {
|
||||||
return $this->json(1, '不能删除自己');
|
return $this->json(1, '不能删除自己');
|
||||||
}
|
}
|
||||||
if (!Auth::isSupperAdmin() && array_diff($ids, Auth::getScopeAdminIds())) {
|
|
||||||
return $this->json(1, '无数据权限');
|
|
||||||
}
|
|
||||||
$this->model->whereIn($primary_key, $ids)->delete();
|
$this->model->whereIn($primary_key, $ids)->delete();
|
||||||
AdminRole::whereIn('admin_id', $ids)->delete();
|
|
||||||
return $this->json(0);
|
return $this->json(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,8 +4,6 @@ namespace plugin\admin\app\controller;
|
|||||||
|
|
||||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||||
use Illuminate\Database\Query\Builder as QueryBuilder;
|
use Illuminate\Database\Query\Builder as QueryBuilder;
|
||||||
use plugin\admin\app\common\Auth;
|
|
||||||
use plugin\admin\app\common\Tree;
|
|
||||||
use plugin\admin\app\common\Util;
|
use plugin\admin\app\common\Util;
|
||||||
use support\exception\BusinessException;
|
use support\exception\BusinessException;
|
||||||
use support\Model;
|
use support\Model;
|
||||||
@ -28,9 +26,9 @@ class Crud extends Base
|
|||||||
*/
|
*/
|
||||||
public function select(Request $request): Response
|
public function select(Request $request): Response
|
||||||
{
|
{
|
||||||
[$where, $format, $limit, $field, $order] = $this->selectInput($request);
|
[$where, $format, $page_size, $field, $order] = $this->selectInput($request);
|
||||||
$query = $this->doSelect($where, $field, $order);
|
$query = $this->doSelect($where, $field, $order);
|
||||||
return $this->doFormat($query, $format, $limit);
|
return $this->doFormat($query, $format, $page_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,7 +61,6 @@ class Crud extends Base
|
|||||||
* 删除
|
* 删除
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return Response
|
* @return Response
|
||||||
* @throws BusinessException
|
|
||||||
*/
|
*/
|
||||||
public function delete(Request $request): Response
|
public function delete(Request $request): Response
|
||||||
{
|
{
|
||||||
@ -72,6 +69,24 @@ class Crud extends Base
|
|||||||
return $this->json(0);
|
return $this->json(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 摘要
|
||||||
|
* @param Request $request
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
/*public function schema(Request $request): Response
|
||||||
|
{
|
||||||
|
$table = $this->model->getTable();
|
||||||
|
$data = Util::getSchema($table);
|
||||||
|
|
||||||
|
return $this->json(0, 'ok', [
|
||||||
|
'table' => $data['table'],
|
||||||
|
'columns' => array_values($data['columns']),
|
||||||
|
'forms' => array_values($data['forms']),
|
||||||
|
'keys' => array_values($data['keys']),
|
||||||
|
]);
|
||||||
|
}*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询前置
|
* 查询前置
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
@ -83,13 +98,10 @@ class Crud extends Base
|
|||||||
$field = $request->get('field');
|
$field = $request->get('field');
|
||||||
$order = $request->get('order', 'asc');
|
$order = $request->get('order', 'asc');
|
||||||
$format = $request->get('format', 'normal');
|
$format = $request->get('format', 'normal');
|
||||||
$limit = (int)$request->get('limit', $format === 'tree' ? 1000 : 10);
|
$page_size = $request->get('limit', $format === 'tree' ? 1000 : 10);
|
||||||
$limit = $limit <= 0 ? 10 : $limit;
|
|
||||||
$order = $order === 'asc' ? 'asc' : 'desc';
|
$order = $order === 'asc' ? 'asc' : 'desc';
|
||||||
$where = $request->get();
|
$where = $request->get();
|
||||||
$page = (int)$request->get('page');
|
$table = $this->model->getTable();
|
||||||
$page = $page > 0 ? $page : 1;
|
|
||||||
$table = config('plugin.admin.database.connections.mysql.prefix') . $this->model->getTable();
|
|
||||||
|
|
||||||
$allow_column = Util::db()->select("desc `$table`");
|
$allow_column = Util::db()->select("desc `$table`");
|
||||||
if (!$allow_column) {
|
if (!$allow_column) {
|
||||||
@ -108,13 +120,9 @@ class Crud extends Base
|
|||||||
// 按照数据限制字段返回数据
|
// 按照数据限制字段返回数据
|
||||||
if ($this->dataLimit === 'personal') {
|
if ($this->dataLimit === 'personal') {
|
||||||
$where[$this->dataLimitField] = admin_id();
|
$where[$this->dataLimitField] = admin_id();
|
||||||
} elseif ($this->dataLimit === 'auth') {
|
|
||||||
$primary_key = $this->model->getKeyName();
|
|
||||||
if (!Auth::isSupperAdmin() && (!isset($where[$primary_key]) || $this->dataLimitField != $primary_key)) {
|
|
||||||
$where[$this->dataLimitField] = ['in', Auth::getScopeAdminIds(true)];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return [$where, $format, $limit, $field, $order, $page];
|
|
||||||
|
return [$where, $format, $page_size, $field, $order];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -129,19 +137,11 @@ class Crud extends Base
|
|||||||
$model = $this->model;
|
$model = $this->model;
|
||||||
foreach ($where as $column => $value) {
|
foreach ($where as $column => $value) {
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
if ($value[0] === 'like') {
|
if (in_array($value[0], ['>', '=', '<', '<>', 'like'])) {
|
||||||
$model = $model->where($column, 'like', "%$value[1]%");
|
|
||||||
} elseif (in_array($value[0], ['>', '=', '<', '<>', 'not like'])) {
|
|
||||||
$model = $model->where($column, $value[0], $value[1]);
|
$model = $model->where($column, $value[0], $value[1]);
|
||||||
} elseif ($value[0] == 'in') {
|
} elseif ($value[0] == 'in') {
|
||||||
$model = $model->whereIn($column, $value[1]);
|
$model = $model->whereIn($column, $value[1]);
|
||||||
} elseif ($value[0] == 'not in') {
|
} else {
|
||||||
$model = $model->whereNotIn($column, $value[1]);
|
|
||||||
} elseif ($value[0] == 'null') {
|
|
||||||
$model = $model->whereNull($column, $value[1]);
|
|
||||||
} elseif ($value[0] == 'not null') {
|
|
||||||
$model = $model->whereNotNull($column, $value[1]);
|
|
||||||
} elseif ($value[0] !== '' || $value[1] !== '') {
|
|
||||||
$model = $model->whereBetween($column, $value);
|
$model = $model->whereBetween($column, $value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -155,25 +155,24 @@ class Crud extends Base
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化数据
|
|
||||||
* @param $query
|
* @param $query
|
||||||
* @param $format
|
* @param $format
|
||||||
* @param $limit
|
* @param $page_size
|
||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
protected function doFormat($query, $format, $limit): Response
|
protected function doFormat($query, $format, $page_size): Response
|
||||||
{
|
{
|
||||||
$methods = [
|
if (in_array($format, ['select', 'tree', 'table_tree'])) {
|
||||||
'select' => 'formatSelect',
|
$items = $query->get();
|
||||||
'tree' => 'formatTree',
|
if ($format == 'select') {
|
||||||
'table_tree' => 'formatTableTree',
|
return $this->formatSelect($items);
|
||||||
'normal' => 'formatNormal',
|
} elseif ($format == 'tree') {
|
||||||
];
|
return $this->formatTree($items);
|
||||||
$paginator = $query->paginate($limit);
|
}
|
||||||
$total = $paginator->total();
|
return $this->formatTableTree($items);
|
||||||
$items = $paginator->items();
|
}
|
||||||
$format_function = $methods[$format] ?? 'formatNormal';
|
$paginator = $query->paginate($page_size);
|
||||||
return call_user_func([$this, $format_function], $items, $total);
|
return json(['code' => 0, 'msg' => 'ok', 'count' => $paginator->total(), 'data' => $paginator->items()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -189,15 +188,6 @@ class Crud extends Base
|
|||||||
if (isset($data[$password_filed])) {
|
if (isset($data[$password_filed])) {
|
||||||
$data[$password_filed] = Util::passwordHash($data[$password_filed]);
|
$data[$password_filed] = Util::passwordHash($data[$password_filed]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Auth::isSupperAdmin() && $this->dataLimit) {
|
|
||||||
if (!empty($data[$this->dataLimitField])) {
|
|
||||||
$admin_id = $data[$this->dataLimitField];
|
|
||||||
if (!in_array($admin_id, Auth::getScopeAdminIds(true))) {
|
|
||||||
throw new BusinessException('无数据权限');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,12 +219,6 @@ class Crud extends Base
|
|||||||
$primary_key = $this->model->getKeyName();
|
$primary_key = $this->model->getKeyName();
|
||||||
$id = $request->post($primary_key);
|
$id = $request->post($primary_key);
|
||||||
$data = $this->inputFilter($request->post());
|
$data = $this->inputFilter($request->post());
|
||||||
if (!Auth::isSupperAdmin() && $this->dataLimit && !empty($data[$this->dataLimitField])) {
|
|
||||||
$admin_id = $data[$this->dataLimitField];
|
|
||||||
if (!in_array($admin_id, Auth::getScopeAdminIds(true))) {
|
|
||||||
throw new BusinessException('无数据权限');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$password_filed = 'password';
|
$password_filed = 'password';
|
||||||
if (isset($data[$password_filed])) {
|
if (isset($data[$password_filed])) {
|
||||||
// 密码为空,则不更新密码
|
// 密码为空,则不更新密码
|
||||||
@ -275,8 +259,8 @@ class Crud extends Base
|
|||||||
*/
|
*/
|
||||||
protected function inputFilter(array $data): array
|
protected function inputFilter(array $data): array
|
||||||
{
|
{
|
||||||
$table = config('plugin.admin.database.connections.mysql.prefix') . $this->model->getTable();
|
$table = $this->model->getTable();
|
||||||
$allow_column = $this->model->getConnection()->select("desc `$table`");
|
$allow_column = Util::db()->select("desc `$table`");
|
||||||
if (!$allow_column) {
|
if (!$allow_column) {
|
||||||
throw new BusinessException('表不存在', 2);
|
throw new BusinessException('表不存在', 2);
|
||||||
}
|
}
|
||||||
@ -307,22 +291,11 @@ class Crud extends Base
|
|||||||
* 删除前置方法
|
* 删除前置方法
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return array
|
* @return array
|
||||||
* @throws BusinessException
|
|
||||||
*/
|
*/
|
||||||
protected function deleteInput(Request $request): array
|
protected function deleteInput(Request $request): array
|
||||||
{
|
{
|
||||||
$primary_key = $this->model->getKeyName();
|
$primary_key = $this->model->getKeyName();
|
||||||
if (!$primary_key) {
|
return (array)$request->post($primary_key, []);
|
||||||
throw new BusinessException('该表无主键,不支持删除');
|
|
||||||
}
|
|
||||||
$ids = (array)$request->post($primary_key, []);
|
|
||||||
if (!Auth::isSupperAdmin() && $this->dataLimit) {
|
|
||||||
$admin_ids = $this->model->where($primary_key, $ids)->pluck($this->dataLimitField)->toArray();
|
|
||||||
if (array_diff($admin_ids, Auth::getScopeAdminIds(true))) {
|
|
||||||
throw new BusinessException('无数据权限');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $ids;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -346,17 +319,26 @@ class Crud extends Base
|
|||||||
*/
|
*/
|
||||||
protected function formatTree($items): Response
|
protected function formatTree($items): Response
|
||||||
{
|
{
|
||||||
$format_items = [];
|
$items_map = [];
|
||||||
foreach ($items as $item) {
|
foreach ($items as $item) {
|
||||||
$format_items[] = [
|
$items_map[$item->id] = [
|
||||||
'name' => $item->title ?? $item->name ?? $item->id,
|
'name' => $item->title ?? $item->name ?? $item->id,
|
||||||
'value' => (string)$item->id,
|
'value' => (string)$item->id,
|
||||||
'id' => $item->id,
|
|
||||||
'pid' => $item->pid,
|
'pid' => $item->pid,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
$tree = new Tree($format_items);
|
$formatted_items = [];
|
||||||
return $this->json(0, 'ok', $tree->getTree());
|
foreach ($items_map as $index => $item) {
|
||||||
|
if ($item['pid'] && isset($items_map[$item['pid']])) {
|
||||||
|
$items_map[$item['pid']]['children'][] = &$items_map[$index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($items_map as $item) {
|
||||||
|
if (!$item['pid']) {
|
||||||
|
$formatted_items[] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->json(0, 'ok', $formatted_items);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -366,8 +348,22 @@ class Crud extends Base
|
|||||||
*/
|
*/
|
||||||
protected function formatTableTree($items): Response
|
protected function formatTableTree($items): Response
|
||||||
{
|
{
|
||||||
$tree = new Tree($items);
|
$items_map = [];
|
||||||
return $this->json(0, 'ok', $tree->getTree());
|
foreach ($items as $item) {
|
||||||
|
$items_map[$item->id] = $item->toArray();
|
||||||
|
}
|
||||||
|
$formatted_items = [];
|
||||||
|
foreach ($items_map as $index => $item) {
|
||||||
|
if ($item['pid'] && isset($items_map[$item['pid']])) {
|
||||||
|
$items_map[$item['pid']]['children'][] = &$items_map[$index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($items_map as $item) {
|
||||||
|
if (!$item['pid']) {
|
||||||
|
$formatted_items[] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->json(0, 'ok', $formatted_items);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -387,15 +383,4 @@ class Crud extends Base
|
|||||||
return $this->json(0, 'ok', $formatted_items);
|
return $this->json(0, 'ok', $formatted_items);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 通用格式化
|
|
||||||
* @param $items
|
|
||||||
* @param $total
|
|
||||||
* @return Response
|
|
||||||
*/
|
|
||||||
protected function formatNormal($items, $total): Response
|
|
||||||
{
|
|
||||||
return json(['code' => 0, 'msg' => 'ok', 'count' => $total, 'data' => $items]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace plugin\admin\app\controller;
|
namespace plugin\admin\app\controller;
|
||||||
|
|
||||||
use plugin\admin\app\model\Dict;
|
|
||||||
use plugin\admin\app\model\Option;
|
use plugin\admin\app\model\Option;
|
||||||
use support\exception\BusinessException;
|
use support\exception\BusinessException;
|
||||||
use support\Request;
|
use support\Request;
|
||||||
@ -27,25 +26,6 @@ class DictController extends Base
|
|||||||
return view('dict/index');
|
return view('dict/index');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询
|
|
||||||
* @param Request $request
|
|
||||||
* @return Response
|
|
||||||
*/
|
|
||||||
public function select(Request $request): Response
|
|
||||||
{
|
|
||||||
$name = $request->get('name', '');
|
|
||||||
if ($name && is_string($name)) {
|
|
||||||
$items = Option::where('name', 'like', "dict_$name%")->get()->toArray();
|
|
||||||
} else {
|
|
||||||
$items = Option::where('name', 'like', 'dict_%')->get()->toArray();
|
|
||||||
}
|
|
||||||
foreach ($items as &$item) {
|
|
||||||
$item['name'] = Dict::optionNameTodictName($item['name']);
|
|
||||||
}
|
|
||||||
return $this->json(0, 'ok', $items);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 插入
|
* 插入
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
@ -56,11 +36,20 @@ class DictController extends Base
|
|||||||
{
|
{
|
||||||
if ($request->method() === 'POST') {
|
if ($request->method() === 'POST') {
|
||||||
$name = $request->post('name');
|
$name = $request->post('name');
|
||||||
if (Dict::get($name)) {
|
if (!preg_match('/[a-zA-Z]/', $name)) {
|
||||||
return $this->json(1, '字典已经存在');
|
return $this->json(1, '字典名只能包含字母');
|
||||||
|
}
|
||||||
|
$option_name = $this->dictNameToOptionName($name);
|
||||||
|
if (Option::where('name', $option_name)->first()) {
|
||||||
|
return $this->json(1, '字典已经存在' . $option_name);
|
||||||
}
|
}
|
||||||
$values = (array)$request->post('value', []);
|
$values = (array)$request->post('value', []);
|
||||||
Dict::save($name, $values);
|
$format_values = $this->filterValue($values);
|
||||||
|
$option = new Option;
|
||||||
|
$option->name = $option_name;
|
||||||
|
$option->value = json_encode($format_values, JSON_UNESCAPED_UNICODE);
|
||||||
|
$option->save();
|
||||||
|
return $this->json(0);
|
||||||
}
|
}
|
||||||
return view('dict/insert');
|
return view('dict/insert');
|
||||||
}
|
}
|
||||||
@ -75,26 +64,55 @@ class DictController extends Base
|
|||||||
{
|
{
|
||||||
if ($request->method() === 'POST') {
|
if ($request->method() === 'POST') {
|
||||||
$name = $request->post('name');
|
$name = $request->post('name');
|
||||||
if (!Dict::get($name)) {
|
if (!preg_match('/[a-zA-Z]/', $name)) {
|
||||||
|
return $this->json(1, '字典名只能包含字母');
|
||||||
|
}
|
||||||
|
$name = $this->dictNameToOptionName($name);
|
||||||
|
$option = Option::where('name', $name)->first();
|
||||||
|
if (!$option) {
|
||||||
return $this->json(1, '字典不存在');
|
return $this->json(1, '字典不存在');
|
||||||
}
|
}
|
||||||
Dict::save($name, $request->post('value'));
|
$format_values = $this->filterValue($request->post('value'));
|
||||||
|
$option->name = $this->dictNameToOptionName($request->post('name'));
|
||||||
|
$option->value = json_encode($format_values, JSON_UNESCAPED_UNICODE);
|
||||||
|
$option->save();
|
||||||
}
|
}
|
||||||
return view('dict/update');
|
return view('dict/update');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除
|
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
public function delete(Request $request): Response
|
public function delete(Request $request)
|
||||||
{
|
{
|
||||||
$names = (array)$request->post('name');
|
$names = (array)$request->post('name');
|
||||||
Dict::delete($names);
|
foreach ($names as $index => $name) {
|
||||||
|
$names[$index] = $this->dictNameToOptionName($name);
|
||||||
|
}
|
||||||
|
Option::whereIn('name', $names)->delete();
|
||||||
return $this->json(0);
|
return $this->json(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询
|
||||||
|
* @param Request $request
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
public function select(Request $request): Response
|
||||||
|
{
|
||||||
|
$name = $request->get('name', '');
|
||||||
|
if ($name && is_string($name)) {
|
||||||
|
$items = Option::where('name', 'like', "dict_$name%")->get()->toArray();
|
||||||
|
} else {
|
||||||
|
$items = Option::where('name', 'like', 'dict_%')->get()->toArray();
|
||||||
|
}
|
||||||
|
foreach ($items as &$item) {
|
||||||
|
$item['name'] = $this->optionNameTodictName($item['name']);
|
||||||
|
}
|
||||||
|
return $this->json(0, 'ok', $items);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取
|
* 获取
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
@ -103,7 +121,47 @@ class DictController extends Base
|
|||||||
*/
|
*/
|
||||||
public function get(Request $request, $name): Response
|
public function get(Request $request, $name): Response
|
||||||
{
|
{
|
||||||
return $this->json(0, 'ok', Dict::get($name));
|
$value = Option::where('name', $this->dictNameToOptionName($name))->value('value');
|
||||||
|
if ($value === null) {
|
||||||
|
return $this->json(1, '字典不存在');
|
||||||
|
}
|
||||||
|
return $this->json(1, 'ok', json_decode($value, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过滤字典选项
|
||||||
|
* @param array $values
|
||||||
|
* @return array
|
||||||
|
* @throws BusinessException
|
||||||
|
*/
|
||||||
|
protected function filterValue(array $values): array
|
||||||
|
{
|
||||||
|
$format_values = [];
|
||||||
|
foreach ($values as $item) {
|
||||||
|
if (!isset($item['value']) || !isset($item['name'])) {
|
||||||
|
throw new BusinessException('格式错误', 1);
|
||||||
|
}
|
||||||
|
$format_values[] = ['value' => $item['value'], 'name' => $item['name']];
|
||||||
|
}
|
||||||
|
return $format_values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function dictNameToOptionName(string $name): string
|
||||||
|
{
|
||||||
|
return "dict_$name";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function optionNameTodictName(string $name): string
|
||||||
|
{
|
||||||
|
return substr($name, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ namespace plugin\admin\app\controller;
|
|||||||
|
|
||||||
use plugin\admin\app\common\Util;
|
use plugin\admin\app\common\Util;
|
||||||
use plugin\admin\app\model\User;
|
use plugin\admin\app\model\User;
|
||||||
|
use support\Db;
|
||||||
use support\exception\BusinessException;
|
use support\exception\BusinessException;
|
||||||
use support\Request;
|
use support\Request;
|
||||||
use support\Response;
|
use support\Response;
|
||||||
@ -60,7 +61,7 @@ class IndexController
|
|||||||
// 总用户数
|
// 总用户数
|
||||||
$user_count = User::count();
|
$user_count = User::count();
|
||||||
// mysql版本
|
// mysql版本
|
||||||
$version = Util::db()->select('select VERSION() as version');
|
$version = Db::select('select VERSION() as version');
|
||||||
$mysql_version = $version[0]->version ?? 'unknown';
|
$mysql_version = $version[0]->version ?? 'unknown';
|
||||||
|
|
||||||
$day7_detail = [];
|
$day7_detail = [];
|
||||||
|
@ -70,7 +70,6 @@ class InstallController extends Base
|
|||||||
|
|
||||||
$tables_to_install = [
|
$tables_to_install = [
|
||||||
'wa_admins',
|
'wa_admins',
|
||||||
'wa_admin_roles',
|
|
||||||
'wa_roles',
|
'wa_roles',
|
||||||
'wa_rules',
|
'wa_rules',
|
||||||
'wa_options',
|
'wa_options',
|
||||||
@ -78,22 +77,18 @@ class InstallController extends Base
|
|||||||
'wa_uploads',
|
'wa_uploads',
|
||||||
];
|
];
|
||||||
|
|
||||||
$tables_exist = [];
|
|
||||||
foreach ($tables as $table) {
|
|
||||||
$tables_exist[] = current($table);
|
|
||||||
}
|
|
||||||
$tables_conflict = array_intersect($tables_to_install, $tables_exist);
|
|
||||||
if (!$overwrite) {
|
if (!$overwrite) {
|
||||||
|
$tables_exist = [];
|
||||||
|
foreach ($tables as $table) {
|
||||||
|
$tables_exist[] = current($table);
|
||||||
|
}
|
||||||
|
$tables_conflict = array_intersect($tables_to_install, $tables_exist);
|
||||||
if ($tables_conflict) {
|
if ($tables_conflict) {
|
||||||
return $this->json(1, '以下表' . implode(',', $tables_conflict) . '已经存在,如需覆盖请选择强制覆盖');
|
return $this->json(1, '以下表' . implode(',', $tables_conflict) . '已经存在,如需覆盖请选择强制覆盖');
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
foreach ($tables_conflict as $table) {
|
|
||||||
$db->exec("DROP TABLE `$table`");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql_file = base_path() . '/plugin/admin/install.sql';
|
$sql_file = base_path() . '/plugin/admin/webman-admin.sql';
|
||||||
if (!is_file($sql_file)) {
|
if (!is_file($sql_file)) {
|
||||||
return $this->json(1, '数据库SQL文件不存在');
|
return $this->json(1, '数据库SQL文件不存在');
|
||||||
}
|
}
|
||||||
@ -198,23 +193,22 @@ EOF;
|
|||||||
if ($password != $password_confirm) {
|
if ($password != $password_confirm) {
|
||||||
return $this->json(1, '两次密码不一致');
|
return $this->json(1, '两次密码不一致');
|
||||||
}
|
}
|
||||||
|
if (Admin::first()) {
|
||||||
|
return $this->json(1, '后台已经安装完毕,无法通过此页面创建管理员');
|
||||||
|
}
|
||||||
if (!is_file($config_file = base_path() . '/plugin/admin/config/database.php')) {
|
if (!is_file($config_file = base_path() . '/plugin/admin/config/database.php')) {
|
||||||
return $this->json(1, '请先完成第一步数据库配置');
|
return $this->json(1, '请先完成第一步数据库配置');
|
||||||
}
|
}
|
||||||
$config = include $config_file;
|
$config = include $config_file;
|
||||||
$connection = $config['connections']['mysql'];
|
$connection = $config['connections']['mysql'];
|
||||||
$pdo = $this->getPdo($connection['host'], $connection['username'], $connection['password'], $connection['port'], $connection['database']);
|
$pdo = $this->getPdo($connection['host'], $connection['username'], $connection['password'], $connection['port'], $connection['database']);
|
||||||
|
$smt = $pdo->prepare("insert into `wa_admins` (`username`, `password`, `nickname`, `roles`, `created_at`, `updated_at`) values (:username, :password, :nickname, :roles, :created_at, :updated_at)");
|
||||||
if ($pdo->query('select * from `wa_admins`')->fetchAll()) {
|
|
||||||
return $this->json(1, '后台已经安装完毕,无法通过此页面创建管理员');
|
|
||||||
}
|
|
||||||
|
|
||||||
$smt = $pdo->prepare("insert into `wa_admins` (`username`, `password`, `nickname`, `created_at`, `updated_at`) values (:username, :password, :nickname, :created_at, :updated_at)");
|
|
||||||
$time = date('Y-m-d H:i:s');
|
$time = date('Y-m-d H:i:s');
|
||||||
$data = [
|
$data = [
|
||||||
'username' => $username,
|
'username' => $username,
|
||||||
'password' => Util::passwordHash($password),
|
'password' => Util::passwordHash($password),
|
||||||
'nickname' => '超级管理员',
|
'nickname' => '超级管理员',
|
||||||
|
'roles' => '1',
|
||||||
'created_at' => $time,
|
'created_at' => $time,
|
||||||
'updated_at' => $time
|
'updated_at' => $time
|
||||||
];
|
];
|
||||||
@ -222,13 +216,6 @@ EOF;
|
|||||||
$smt->bindValue($key, $value);
|
$smt->bindValue($key, $value);
|
||||||
}
|
}
|
||||||
$smt->execute();
|
$smt->execute();
|
||||||
$admin_id = $pdo->lastInsertId();
|
|
||||||
|
|
||||||
$smt = $pdo->prepare("insert into `wa_admin_roles` (`role_id`, `admin_id`) values (:role_id, :admin_id)");
|
|
||||||
$smt->bindValue('role_id', 1);
|
|
||||||
$smt->bindValue('admin_id', $admin_id);
|
|
||||||
$smt->execute();
|
|
||||||
|
|
||||||
$request->session()->flush();
|
$request->session()->flush();
|
||||||
return $this->json(0);
|
return $this->json(0);
|
||||||
}
|
}
|
||||||
@ -381,7 +368,6 @@ EOF;
|
|||||||
}
|
}
|
||||||
$params = [
|
$params = [
|
||||||
\PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8mb4",
|
\PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8mb4",
|
||||||
\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
|
|
||||||
\PDO::ATTR_EMULATE_PREPARES => false,
|
\PDO::ATTR_EMULATE_PREPARES => false,
|
||||||
\PDO::ATTR_TIMEOUT => 5,
|
\PDO::ATTR_TIMEOUT => 5,
|
||||||
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
||||||
|
@ -5,18 +5,10 @@ namespace plugin\admin\app\controller;
|
|||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
use GuzzleHttp\Exception\GuzzleException;
|
use GuzzleHttp\Exception\GuzzleException;
|
||||||
use plugin\admin\app\common\Util;
|
use plugin\admin\app\common\Util;
|
||||||
use plugin\admin\app\controller\Base;
|
|
||||||
use process\Monitor;
|
|
||||||
use support\exception\BusinessException;
|
use support\exception\BusinessException;
|
||||||
use support\Log;
|
use support\Log;
|
||||||
use support\Request;
|
use support\Request;
|
||||||
use support\Response;
|
use support\Response;
|
||||||
use ZIPARCHIVE;
|
|
||||||
use function array_diff;
|
|
||||||
use function ini_get;
|
|
||||||
use function scandir;
|
|
||||||
use const DIRECTORY_SEPARATOR;
|
|
||||||
use const PATH_SEPARATOR;
|
|
||||||
|
|
||||||
class PluginController extends Base
|
class PluginController extends Base
|
||||||
{
|
{
|
||||||
@ -28,14 +20,11 @@ class PluginController extends Base
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return string
|
* @return Response
|
||||||
* @throws GuzzleException
|
|
||||||
*/
|
*/
|
||||||
public function index(Request $request)
|
public function index(Request $request): Response
|
||||||
{
|
{
|
||||||
$client = $this->httpClient();
|
return view('plugin/index');
|
||||||
$response = $client->get("/webman-admin/apps");
|
|
||||||
return (string)$response->getBody();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,7 +35,14 @@ class PluginController extends Base
|
|||||||
*/
|
*/
|
||||||
public function list(Request $request): Response
|
public function list(Request $request): Response
|
||||||
{
|
{
|
||||||
$installed = $this->getLocalPlugins();
|
$installed = [];
|
||||||
|
clearstatcache();
|
||||||
|
$plugin_names = \array_diff(\scandir(base_path() . '/plugin/'), array('.', '..')) ?: [];
|
||||||
|
foreach ($plugin_names as $plugin_name) {
|
||||||
|
if (is_dir(base_path() . "/plugin/$plugin_name") && $version = $this->getPluginVersion($plugin_name)) {
|
||||||
|
$installed[$plugin_name] = $version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$client = $this->httpClient();
|
$client = $this->httpClient();
|
||||||
$query = $request->get();
|
$query = $request->get();
|
||||||
@ -61,49 +57,75 @@ class PluginController extends Base
|
|||||||
return $this->json(1, '获取数据出错');
|
return $this->json(1, '获取数据出错');
|
||||||
}
|
}
|
||||||
$disabled = is_phar();
|
$disabled = is_phar();
|
||||||
foreach ($data['data']['items'] as $key => $item) {
|
foreach ($data['result']['items'] as $key => $item) {
|
||||||
$name = $item['name'];
|
$name = $item['name'];
|
||||||
$data['data']['items'][$key]['installed'] = $installed[$name] ?? 0;
|
$data['result']['items'][$key]['installed'] = $installed[$name] ?? 0;
|
||||||
$data['data']['items'][$key]['disabled'] = $disabled;
|
$data['result']['items'][$key]['disabled'] = $disabled;
|
||||||
}
|
}
|
||||||
$items = $data['data']['items'];
|
$items = $data['result']['items'];
|
||||||
$count = $data['data']['total'];
|
$count = $data['result']['total'];
|
||||||
return json(['code' => 0, 'msg' => 'ok', 'data' => $items, 'count' => $count]);
|
return json(['code' =>0, 'msg' => 'ok', 'data' => $items, 'count' => $count]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 摘要
|
||||||
|
* @param Request $request
|
||||||
|
* @return Response
|
||||||
|
* @throws GuzzleException
|
||||||
|
*/
|
||||||
|
public function schema(Request $request): Response
|
||||||
|
{
|
||||||
|
$client = $this->httpClient();
|
||||||
|
$response = $client->get('/api/app/schema', ['query' => $request->get()]);
|
||||||
|
$data = json_decode($response->getBody()->getContents(), true);
|
||||||
|
$result = $data['result'];
|
||||||
|
foreach ($result as &$item) {
|
||||||
|
$item['field'] = $item['field'] ?? $item['dataIndex'];
|
||||||
|
unset($item['dataIndex']);
|
||||||
|
}
|
||||||
|
return $this->json(0, 'ok', $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 安装
|
* 安装
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return Response
|
* @return Response
|
||||||
* @throws GuzzleException|BusinessException
|
* @throws GuzzleException
|
||||||
*/
|
*/
|
||||||
public function install(Request $request): Response
|
public function install(Request $request): Response
|
||||||
{
|
{
|
||||||
$name = $request->post('name');
|
$name = $request->post('name');
|
||||||
$version = $request->post('version');
|
$version = $request->post('version');
|
||||||
$installed_version = $this->getPluginVersion($name);
|
$installed_version = $this->getPluginVersion($name);
|
||||||
|
$host = $request->host(true);
|
||||||
if (!$name || !$version) {
|
if (!$name || !$version) {
|
||||||
return $this->json(1, '缺少参数');
|
return $this->json(1, '缺少参数');
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = session('app-plugin-user');
|
$user = session('app-plugin-user');
|
||||||
if (!$user) {
|
if (!$user) {
|
||||||
return $this->json(-1, '请登录');
|
return $this->json(0, '请登录', [
|
||||||
|
'code' => 401,
|
||||||
|
'msg' => '请登录'
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取下载zip文件url
|
// 获取下载zip文件url
|
||||||
$data = $this->getDownloadUrl($name, $version);
|
$data = $this->getDownloadUrl($name, $user['uid'], $host, $version);
|
||||||
if ($data['code'] != 0) {
|
if ($data['code'] == -1) {
|
||||||
return $this->json($data['code'], $data['msg'], $data['data'] ?? []);
|
return $this->json(0, '请登录', [
|
||||||
|
'code' => 401,
|
||||||
|
'msg' => '请登录'
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 下载zip文件
|
// 下载zip文件
|
||||||
$base_path = base_path() . "/plugin/$name";
|
$base_path = base_path() . "/plugin/$name";
|
||||||
$zip_file = "$base_path.zip";
|
$zip_file = "$base_path.zip";
|
||||||
$extract_to = base_path() . '/plugin/';
|
$extract_to = base_path() . '/plugin/';
|
||||||
$this->downloadZipFile($data['data']['url'], $zip_file);
|
$this->downloadZipFile($data['result']['url'], $zip_file);
|
||||||
|
|
||||||
$has_zip_archive = class_exists(ZipArchive::class, false);
|
$has_zip_archive = class_exists(\ZipArchive::class, false);
|
||||||
if (!$has_zip_archive) {
|
if (!$has_zip_archive) {
|
||||||
$cmd = $this->getUnzipCmd($zip_file, $extract_to);
|
$cmd = $this->getUnzipCmd($zip_file, $extract_to);
|
||||||
if (!$cmd) {
|
if (!$cmd) {
|
||||||
@ -114,45 +136,40 @@ class PluginController extends Base
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Util::pauseFileMonitor();
|
// 解压zip到plugin目录
|
||||||
try {
|
if ($has_zip_archive) {
|
||||||
// 解压zip到plugin目录
|
$zip = new \ZipArchive;
|
||||||
if ($has_zip_archive) {
|
$zip->open($zip_file, \ZIPARCHIVE::CHECKCONS);
|
||||||
$zip = new ZipArchive;
|
}
|
||||||
$zip->open($zip_file, ZIPARCHIVE::CHECKCONS);
|
|
||||||
}
|
|
||||||
|
|
||||||
$context = null;
|
$context = null;
|
||||||
$install_class = "\\plugin\\$name\\api\\Install";
|
$install_class = "\\plugin\\$name\\api\\Install";
|
||||||
if ($installed_version) {
|
if ($installed_version) {
|
||||||
// 执行beforeUpdate
|
// 执行beforeUpdate
|
||||||
if (class_exists($install_class) && method_exists($install_class, 'beforeUpdate')) {
|
if (class_exists($install_class) && method_exists($install_class, 'beforeUpdate')) {
|
||||||
$context = call_user_func([$install_class, 'beforeUpdate'], $installed_version, $version);
|
$context = call_user_func([$install_class, 'beforeUpdate'], $installed_version, $version);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty($zip)) {
|
if (!empty($zip)) {
|
||||||
$zip->extractTo(base_path() . '/plugin/');
|
$zip->extractTo(base_path() . '/plugin/');
|
||||||
unset($zip);
|
unset($zip);
|
||||||
} else {
|
} else {
|
||||||
$this->unzipWithCmd($cmd);
|
$this->unzipWithCmd($cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlink($zip_file);
|
||||||
|
|
||||||
|
if ($installed_version) {
|
||||||
|
// 执行update更新
|
||||||
|
if (class_exists($install_class) && method_exists($install_class, 'update')) {
|
||||||
|
call_user_func([$install_class, 'update'], $installed_version, $version, $context);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
unlink($zip_file);
|
// 执行install安装
|
||||||
|
if (class_exists($install_class) && method_exists($install_class, 'install')) {
|
||||||
if ($installed_version) {
|
call_user_func([$install_class, 'install'], $version);
|
||||||
// 执行update更新
|
|
||||||
if (class_exists($install_class) && method_exists($install_class, 'update')) {
|
|
||||||
call_user_func([$install_class, 'update'], $installed_version, $version, $context);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 执行install安装
|
|
||||||
if (class_exists($install_class) && method_exists($install_class, 'install')) {
|
|
||||||
call_user_func([$install_class, 'install'], $version);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
Util::resumeFileMonitor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Util::reloadWebman();
|
Util::reloadWebman();
|
||||||
@ -189,17 +206,7 @@ class PluginController extends Base
|
|||||||
// 删除目录
|
// 删除目录
|
||||||
clearstatcache();
|
clearstatcache();
|
||||||
if (is_dir($path)) {
|
if (is_dir($path)) {
|
||||||
$monitor_support_pause = method_exists(Monitor::class, 'pause');
|
$this->rmDir($path);
|
||||||
if ($monitor_support_pause) {
|
|
||||||
Monitor::pause();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
$this->rmDir($path);
|
|
||||||
} finally {
|
|
||||||
if ($monitor_support_pause) {
|
|
||||||
Monitor::resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
clearstatcache();
|
clearstatcache();
|
||||||
|
|
||||||
@ -208,27 +215,6 @@ class PluginController extends Base
|
|||||||
return $this->json(0);
|
return $this->json(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付
|
|
||||||
* @param Request $request
|
|
||||||
* @return string|Response
|
|
||||||
* @throws GuzzleException
|
|
||||||
*/
|
|
||||||
public function pay(Request $request)
|
|
||||||
{
|
|
||||||
$app = $request->get('app');
|
|
||||||
if (!$app) {
|
|
||||||
return response('app not found');
|
|
||||||
}
|
|
||||||
$token = session('app-plugin-token');
|
|
||||||
if (!$token) {
|
|
||||||
return 'Please login workerman.net';
|
|
||||||
}
|
|
||||||
$client = $this->httpClient();
|
|
||||||
$response = $client->get("/payment/app/$app/$token");
|
|
||||||
return (string)$response->getBody();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录验证码
|
* 登录验证码
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
@ -240,7 +226,7 @@ class PluginController extends Base
|
|||||||
$client = $this->httpClient();
|
$client = $this->httpClient();
|
||||||
$response = $client->get('/user/captcha?type=login');
|
$response = $client->get('/user/captcha?type=login');
|
||||||
$sid_str = $response->getHeaderLine('Set-Cookie');
|
$sid_str = $response->getHeaderLine('Set-Cookie');
|
||||||
if (preg_match('/PHPSID=([a-zA-Z_0-9]+?);/', $sid_str, $match)) {
|
if(preg_match('/PHPSID=([a-zA-z_0-9]+?);/', $sid_str, $match)) {
|
||||||
$sid = $match[1];
|
$sid = $match[1];
|
||||||
session()->set('app-plugin-token', $sid);
|
session()->set('app-plugin-token', $sid);
|
||||||
}
|
}
|
||||||
@ -250,17 +236,15 @@ class PluginController extends Base
|
|||||||
/**
|
/**
|
||||||
* 登录官网
|
* 登录官网
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return Response|string
|
* @return Response
|
||||||
* @throws GuzzleException
|
* @throws GuzzleException
|
||||||
*/
|
*/
|
||||||
public function login(Request $request)
|
public function login(Request $request): Response
|
||||||
{
|
{
|
||||||
$client = $this->httpClient();
|
|
||||||
if ($request->method() === 'GET') {
|
if ($request->method() === 'GET') {
|
||||||
$response = $client->get("/webman-admin/login");
|
return view('plugin/auth-login');
|
||||||
return (string)$response->getBody();
|
|
||||||
}
|
}
|
||||||
|
$client = $this->httpClient();
|
||||||
$response = $client->post('/api/user/login', [
|
$response = $client->post('/api/user/login', [
|
||||||
'form_params' => [
|
'form_params' => [
|
||||||
'email' => $request->post('username'),
|
'email' => $request->post('username'),
|
||||||
@ -288,27 +272,37 @@ class PluginController extends Base
|
|||||||
/**
|
/**
|
||||||
* 获取zip下载url
|
* 获取zip下载url
|
||||||
* @param $name
|
* @param $name
|
||||||
|
* @param $uid
|
||||||
|
* @param $host
|
||||||
* @param $version
|
* @param $version
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws BusinessException
|
* @throws BusinessException
|
||||||
* @throws GuzzleException
|
* @throws GuzzleException
|
||||||
*/
|
*/
|
||||||
protected function getDownloadUrl($name, $version)
|
protected function getDownloadUrl($name, $uid, $host, $version)
|
||||||
{
|
{
|
||||||
$client = $this->httpClient();
|
$client = $this->httpClient();
|
||||||
$response = $client->get("/app/download/$name?version=$version");
|
$response = $client->post('/api/app/download', [
|
||||||
|
'form_params' => [
|
||||||
|
'name' => $name,
|
||||||
|
'uid' => $uid,
|
||||||
|
'token' => session('app-plugin-token'),
|
||||||
|
'referer' => $host,
|
||||||
|
'version' => $version,
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
$content = $response->getBody()->getContents();
|
$content = $response->getBody()->getContents();
|
||||||
$data = json_decode($content, true);
|
$data = json_decode($content, true);
|
||||||
if (!$data) {
|
if (!$data) {
|
||||||
$msg = "/api/app/download return $content";
|
$msg = "/api/app/download return $content";
|
||||||
Log::error($msg);
|
Log::error($msg);
|
||||||
throw new BusinessException('访问官方接口失败 ' . $response->getStatusCode() . ' ' . $response->getReasonPhrase());
|
throw new BusinessException('访问官方接口失败');
|
||||||
}
|
}
|
||||||
if ($data['code'] && $data['code'] != -1 && $data['code'] != -2) {
|
if ($data['code'] && $data['code'] != -1) {
|
||||||
throw new BusinessException($data['message']);
|
throw new BusinessException($data['msg']);
|
||||||
}
|
}
|
||||||
if ($data['code'] == 0 && !isset($data['data']['url'])) {
|
if ($data['code'] == 0 && !isset($data['result']['url'])) {
|
||||||
throw new BusinessException('官方接口返回数据错误');
|
throw new BusinessException('官方接口返回数据错误');
|
||||||
}
|
}
|
||||||
return $data;
|
return $data;
|
||||||
@ -347,10 +341,10 @@ class PluginController extends Base
|
|||||||
protected function getUnzipCmd($zip_file, $extract_to)
|
protected function getUnzipCmd($zip_file, $extract_to)
|
||||||
{
|
{
|
||||||
if ($cmd = $this->findCmd('unzip')) {
|
if ($cmd = $this->findCmd('unzip')) {
|
||||||
$cmd = "$cmd -o -qq $zip_file -d $extract_to";
|
$cmd = "$cmd -qq $zip_file -d $extract_to";
|
||||||
} else if ($cmd = $this->findCmd('7z')) {
|
} else if ($cmd = $this->findCmd('7z')) {
|
||||||
$cmd = "$cmd x -bb0 -y $zip_file -o$extract_to";
|
$cmd = "$cmd x -bb0 -y $zip_file -o$extract_to";
|
||||||
} else if ($cmd = $this->findCmd('7zz')) {
|
} else if ($cmd= $this->findCmd('7zz')) {
|
||||||
$cmd = "$cmd x -bb0 -y $zip_file -o$extract_to";
|
$cmd = "$cmd x -bb0 -y $zip_file -o$extract_to";
|
||||||
}
|
}
|
||||||
return $cmd;
|
return $cmd;
|
||||||
@ -365,8 +359,8 @@ class PluginController extends Base
|
|||||||
protected function unzipWithCmd($cmd)
|
protected function unzipWithCmd($cmd)
|
||||||
{
|
{
|
||||||
$desc = [
|
$desc = [
|
||||||
0 => ["pipe", "r"],
|
0 => STDIN,
|
||||||
1 => ["pipe", "w"],
|
1 => STDOUT,
|
||||||
2 => ["pipe", "w"],
|
2 => ["pipe", "w"],
|
||||||
];
|
];
|
||||||
$handler = proc_open($cmd, $desc, $pipes);
|
$handler = proc_open($cmd, $desc, $pipes);
|
||||||
@ -381,34 +375,6 @@ class PluginController extends Base
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取已安装的插件列表
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function getLocalPlugins(): array
|
|
||||||
{
|
|
||||||
clearstatcache();
|
|
||||||
$installed = [];
|
|
||||||
$plugin_names = array_diff(scandir(base_path() . '/plugin/'), array('.', '..')) ?: [];
|
|
||||||
foreach ($plugin_names as $plugin_name) {
|
|
||||||
if (is_dir(base_path() . "/plugin/$plugin_name") && $version = $this->getPluginVersion($plugin_name)) {
|
|
||||||
$installed[$plugin_name] = $version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $installed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取已安装的插件列表
|
|
||||||
* @param Request $request
|
|
||||||
* @return Response
|
|
||||||
*/
|
|
||||||
public function getInstalledPlugins(Request $request): Response
|
|
||||||
{
|
|
||||||
return $this->json(0, 'ok', $this->getLocalPlugins());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取本地插件版本
|
* 获取本地插件版本
|
||||||
* @param $name
|
* @param $name
|
||||||
@ -440,10 +406,10 @@ class PluginController extends Base
|
|||||||
protected function rmDir($src)
|
protected function rmDir($src)
|
||||||
{
|
{
|
||||||
$dir = opendir($src);
|
$dir = opendir($src);
|
||||||
while (false !== ($file = readdir($dir))) {
|
while(false !== ( $file = readdir($dir)) ) {
|
||||||
if (($file != '.') && ($file != '..')) {
|
if (( $file != '.' ) && ( $file != '..' )) {
|
||||||
$full = $src . '/' . $file;
|
$full = $src . '/' . $file;
|
||||||
if (is_dir($full)) {
|
if ( is_dir($full) ) {
|
||||||
$this->rmDir($full);
|
$this->rmDir($full);
|
||||||
} else {
|
} else {
|
||||||
unlink($full);
|
unlink($full);
|
||||||
@ -469,7 +435,7 @@ class PluginController extends Base
|
|||||||
'http_errors' => false,
|
'http_errors' => false,
|
||||||
'headers' => [
|
'headers' => [
|
||||||
'Referer' => \request()->fullUrl(),
|
'Referer' => \request()->fullUrl(),
|
||||||
'User-Agent' => 'webman-app-plugin',
|
'User-Agent' => 'webman-app-plugin',
|
||||||
'Accept' => 'application/json;charset=UTF-8',
|
'Accept' => 'application/json;charset=UTF-8',
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
@ -493,7 +459,7 @@ class PluginController extends Base
|
|||||||
'http_errors' => false,
|
'http_errors' => false,
|
||||||
'headers' => [
|
'headers' => [
|
||||||
'Referer' => \request()->fullUrl(),
|
'Referer' => \request()->fullUrl(),
|
||||||
'User-Agent' => 'webman-app-plugin',
|
'User-Agent' => 'webman-app-plugin',
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
if ($token = session('app-plugin-token')) {
|
if ($token = session('app-plugin-token')) {
|
||||||
@ -511,8 +477,8 @@ class PluginController extends Base
|
|||||||
*/
|
*/
|
||||||
protected function findCmd(string $name, string $default = null, array $extraDirs = [])
|
protected function findCmd(string $name, string $default = null, array $extraDirs = [])
|
||||||
{
|
{
|
||||||
if (ini_get('open_basedir')) {
|
if (\ini_get('open_basedir')) {
|
||||||
$searchPath = array_merge(explode(PATH_SEPARATOR, ini_get('open_basedir')), $extraDirs);
|
$searchPath = array_merge(explode(\PATH_SEPARATOR, \ini_get('open_basedir')), $extraDirs);
|
||||||
$dirs = [];
|
$dirs = [];
|
||||||
foreach ($searchPath as $path) {
|
foreach ($searchPath as $path) {
|
||||||
if (@is_dir($path)) {
|
if (@is_dir($path)) {
|
||||||
@ -525,19 +491,19 @@ class PluginController extends Base
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$dirs = array_merge(
|
$dirs = array_merge(
|
||||||
explode(PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')),
|
explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')),
|
||||||
$extraDirs
|
$extraDirs
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$suffixes = [''];
|
$suffixes = [''];
|
||||||
if ('\\' === DIRECTORY_SEPARATOR) {
|
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||||
$pathExt = getenv('PATHEXT');
|
$pathExt = getenv('PATHEXT');
|
||||||
$suffixes = array_merge($pathExt ? explode(PATH_SEPARATOR, $pathExt) : ['.exe', '.bat', '.cmd', '.com'], $suffixes);
|
$suffixes = array_merge($pathExt ? explode(\PATH_SEPARATOR, $pathExt) : $this->suffixes, $suffixes);
|
||||||
}
|
}
|
||||||
foreach ($suffixes as $suffix) {
|
foreach ($suffixes as $suffix) {
|
||||||
foreach ($dirs as $dir) {
|
foreach ($dirs as $dir) {
|
||||||
if (@is_file($file = $dir . DIRECTORY_SEPARATOR . $name . $suffix) && ('\\' === DIRECTORY_SEPARATOR || @is_executable($file))) {
|
if (@is_file($file = $dir.\DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === \DIRECTORY_SEPARATOR || @is_executable($file))) {
|
||||||
return $file;
|
return $file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,7 @@
|
|||||||
|
|
||||||
namespace plugin\admin\app\controller;
|
namespace plugin\admin\app\controller;
|
||||||
|
|
||||||
use plugin\admin\app\common\Auth;
|
|
||||||
use plugin\admin\app\common\Tree;
|
|
||||||
use plugin\admin\app\model\Role;
|
use plugin\admin\app\model\Role;
|
||||||
use plugin\admin\app\model\Rule;
|
|
||||||
use support\exception\BusinessException;
|
use support\exception\BusinessException;
|
||||||
use support\Request;
|
use support\Request;
|
||||||
use support\Response;
|
use support\Response;
|
||||||
@ -15,12 +12,6 @@ use support\Response;
|
|||||||
*/
|
*/
|
||||||
class RoleController extends Crud
|
class RoleController extends Crud
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* 不需要鉴权的方法
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $noNeedAuth = ['select'];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Role
|
* @var Role
|
||||||
*/
|
*/
|
||||||
@ -43,26 +34,6 @@ class RoleController extends Crud
|
|||||||
return view('role/index');
|
return view('role/index');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询
|
|
||||||
* @param Request $request
|
|
||||||
* @return Response
|
|
||||||
* @throws BusinessException
|
|
||||||
*/
|
|
||||||
public function select(Request $request): Response
|
|
||||||
{
|
|
||||||
$id = $request->get('id');
|
|
||||||
[$where, $format, $limit, $field, $order] = $this->selectInput($request);
|
|
||||||
$role_ids = Auth::getScopeRoleIds(true);
|
|
||||||
if (!$id) {
|
|
||||||
$where['id'] = ['in', $role_ids];
|
|
||||||
} elseif (!in_array($id, $role_ids)) {
|
|
||||||
throw new BusinessException('无权限');
|
|
||||||
}
|
|
||||||
$query = $this->doSelect($where, $field, $order);
|
|
||||||
return $this->doFormat($query, $format, $limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 插入
|
* 插入
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
@ -72,18 +43,7 @@ class RoleController extends Crud
|
|||||||
public function insert(Request $request): Response
|
public function insert(Request $request): Response
|
||||||
{
|
{
|
||||||
if ($request->method() === 'POST') {
|
if ($request->method() === 'POST') {
|
||||||
$data = $this->insertInput($request);
|
return parent::insert($request);
|
||||||
$pid = $data['pid'] ?? null;
|
|
||||||
if (!$pid) {
|
|
||||||
return $this->json(1, '请选择父级角色组');
|
|
||||||
}
|
|
||||||
if (!Auth::isSupperAdmin() && !in_array($pid, Auth::getScopeRoleIds(true))) {
|
|
||||||
return $this->json(1, '父级角色组超出权限范围');
|
|
||||||
}
|
|
||||||
$this->checkRules($pid, $data['rules'] ?? '');
|
|
||||||
|
|
||||||
$id = $this->doInsert($data);
|
|
||||||
return $this->json(0, 'ok', ['id' => $id]);
|
|
||||||
}
|
}
|
||||||
return view('role/insert');
|
return view('role/insert');
|
||||||
}
|
}
|
||||||
@ -100,59 +60,11 @@ class RoleController extends Crud
|
|||||||
return view('role/update');
|
return view('role/update');
|
||||||
}
|
}
|
||||||
[$id, $data] = $this->updateInput($request);
|
[$id, $data] = $this->updateInput($request);
|
||||||
$is_supper_admin = Auth::isSupperAdmin();
|
// id为1的管理员权限固定为*
|
||||||
$descendant_role_ids = Auth::getScopeRoleIds();
|
if (isset($data['rules']) && $id == 1) {
|
||||||
if (!$is_supper_admin && !in_array($id, $descendant_role_ids)) {
|
$data['rules'] = '*';
|
||||||
return $this->json(1, '无数据权限');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$role = Role::find($id);
|
|
||||||
if (!$role) {
|
|
||||||
return $this->json(1, '数据不存在');
|
|
||||||
}
|
|
||||||
$is_supper_role = $role->rules === '*';
|
|
||||||
|
|
||||||
// 超级角色组不允许更改rules pid 字段
|
|
||||||
if ($is_supper_role) {
|
|
||||||
unset($data['rules'], $data['pid']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key_exists('pid', $data)) {
|
|
||||||
$pid = $data['pid'];
|
|
||||||
if (!$pid) {
|
|
||||||
return $this->json(1, '请选择父级角色组');
|
|
||||||
}
|
|
||||||
if ($pid == $id) {
|
|
||||||
return $this->json(1, '父级不能是自己');
|
|
||||||
}
|
|
||||||
if (!$is_supper_admin && !in_array($pid, Auth::getScopeRoleIds(true))) {
|
|
||||||
return $this->json(1, '父级超出权限范围');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$pid = $role->pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$is_supper_role) {
|
|
||||||
$this->checkRules($pid, $data['rules'] ?? '');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->doUpdate($id, $data);
|
$this->doUpdate($id, $data);
|
||||||
|
|
||||||
// 删除所有子角色组中已经不存在的权限
|
|
||||||
if (!$is_supper_role) {
|
|
||||||
$tree = new Tree(Role::select(['id', 'pid'])->get());
|
|
||||||
$descendant_roles = $tree->getDescendant([$id]);
|
|
||||||
$descendant_role_ids = array_column($descendant_roles, 'id');
|
|
||||||
$rule_ids = $data['rules'] ? explode(',', $data['rules']) : [];
|
|
||||||
foreach ($descendant_role_ids as $role_id) {
|
|
||||||
$tmp_role = Role::find($role_id);
|
|
||||||
$tmp_rule_ids = $role->getRuleIds();
|
|
||||||
$tmp_rule_ids = array_intersect($rule_ids, $tmp_rule_ids);
|
|
||||||
$tmp_role->rules = implode(',', $tmp_rule_ids);
|
|
||||||
$tmp_role->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->json(0);
|
return $this->json(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +72,6 @@ class RoleController extends Crud
|
|||||||
* 删除
|
* 删除
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return Response
|
* @return Response
|
||||||
* @throws BusinessException
|
|
||||||
*/
|
*/
|
||||||
public function delete(Request $request): Response
|
public function delete(Request $request): Response
|
||||||
{
|
{
|
||||||
@ -168,85 +79,8 @@ class RoleController extends Crud
|
|||||||
if (in_array(1, $ids)) {
|
if (in_array(1, $ids)) {
|
||||||
return $this->json(1, '无法删除超级管理员角色');
|
return $this->json(1, '无法删除超级管理员角色');
|
||||||
}
|
}
|
||||||
if (!Auth::isSupperAdmin() && array_diff($ids, Auth::getScopeRoleIds())) {
|
|
||||||
return $this->json(1, '无删除权限');
|
|
||||||
}
|
|
||||||
$tree = new Tree(Role::get());
|
|
||||||
$descendants = $tree->getDescendant($ids);
|
|
||||||
if ($descendants) {
|
|
||||||
$ids = array_merge($ids, array_column($descendants, 'id'));
|
|
||||||
}
|
|
||||||
$this->doDelete($ids);
|
$this->doDelete($ids);
|
||||||
return $this->json(0);
|
return $this->json(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取角色权限
|
|
||||||
* @param Request $request
|
|
||||||
* @return Response
|
|
||||||
*/
|
|
||||||
public function rules(Request $request): Response
|
|
||||||
{
|
|
||||||
$role_id = $request->get('id');
|
|
||||||
if (empty($role_id)) {
|
|
||||||
return $this->json(0, 'ok', []);
|
|
||||||
}
|
|
||||||
if (!Auth::isSupperAdmin() && !in_array($role_id, Auth::getScopeRoleIds(true))) {
|
|
||||||
return $this->json(1, '角色组超出权限范围');
|
|
||||||
}
|
|
||||||
$rule_id_string = Role::where('id', $role_id)->value('rules');
|
|
||||||
if ($rule_id_string === '') {
|
|
||||||
return $this->json(0, 'ok', []);
|
|
||||||
}
|
|
||||||
$rules = Rule::get();
|
|
||||||
$include = [];
|
|
||||||
if ($rule_id_string !== '*') {
|
|
||||||
$include = explode(',', $rule_id_string);
|
|
||||||
}
|
|
||||||
$items = [];
|
|
||||||
foreach ($rules as $item) {
|
|
||||||
$items[] = [
|
|
||||||
'name' => $item->title ?? $item->name ?? $item->id,
|
|
||||||
'value' => (string)$item->id,
|
|
||||||
'id' => $item->id,
|
|
||||||
'pid' => $item->pid,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
$tree = new Tree($items);
|
|
||||||
return $this->json(0, 'ok', $tree->getTree($include));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查权限字典是否合法
|
|
||||||
* @param int $role_id
|
|
||||||
* @param $rule_ids
|
|
||||||
* @return void
|
|
||||||
* @throws BusinessException
|
|
||||||
*/
|
|
||||||
protected function checkRules(int $role_id, $rule_ids)
|
|
||||||
{
|
|
||||||
if ($rule_ids) {
|
|
||||||
$rule_ids = explode(',', $rule_ids);
|
|
||||||
if (in_array('*', $rule_ids)) {
|
|
||||||
throw new BusinessException('非法数据');
|
|
||||||
}
|
|
||||||
$rule_exists = Rule::whereIn('id', $rule_ids)->pluck('id');
|
|
||||||
if (count($rule_exists) != count($rule_ids)) {
|
|
||||||
throw new BusinessException('权限不存在');
|
|
||||||
}
|
|
||||||
$rule_id_string = Role::where('id', $role_id)->value('rules');
|
|
||||||
if ($rule_id_string === '') {
|
|
||||||
throw new BusinessException('数据超出权限范围');
|
|
||||||
}
|
|
||||||
if ($rule_id_string === '*') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$legal_rule_ids = explode(',', $rule_id_string);
|
|
||||||
if (array_diff($rule_ids, $legal_rule_ids)) {
|
|
||||||
throw new BusinessException('数据超出权限范围');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace plugin\admin\app\controller;
|
namespace plugin\admin\app\controller;
|
||||||
|
|
||||||
use plugin\admin\app\common\Tree;
|
|
||||||
use plugin\admin\app\common\Util;
|
use plugin\admin\app\common\Util;
|
||||||
use plugin\admin\app\model\Role;
|
use plugin\admin\app\model\Role;
|
||||||
use plugin\admin\app\model\Rule;
|
use plugin\admin\app\model\Rule;
|
||||||
@ -20,7 +19,7 @@ class RuleController extends Crud
|
|||||||
*
|
*
|
||||||
* @var string[]
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
protected $noNeedAuth = ['get', 'permission'];
|
protected $noNeedAuth = ['get', 'permissionCodes'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Rule
|
* @var Rule
|
||||||
@ -60,39 +59,54 @@ class RuleController extends Crud
|
|||||||
* 获取菜单
|
* 获取菜单
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return Response
|
* @return Response
|
||||||
|
* @throws BusinessException
|
||||||
*/
|
*/
|
||||||
function get(Request $request): Response
|
function get(Request $request): Response
|
||||||
{
|
{
|
||||||
$rules = $this->getRules(admin('roles'));
|
$rules = $this->getRules(admin('roles'));
|
||||||
|
$items = Rule::orderBy('weight', 'desc')->get()->toArray();
|
||||||
$types = $request->get('type', '0,1');
|
$types = $request->get('type', '0,1');
|
||||||
$types = is_string($types) ? explode(',', $types) : [0, 1];
|
$types = is_string($types) ? explode(',', $types) : [0, 1];
|
||||||
$items = Rule::orderBy('weight', 'desc')->get()->toArray();
|
$items_map = [];
|
||||||
|
|
||||||
$formatted_items = [];
|
|
||||||
foreach ($items as $item) {
|
foreach ($items as $item) {
|
||||||
$item['pid'] = (int)$item['pid'];
|
$item['pid'] = (int)$item['pid'];
|
||||||
$item['name'] = $item['title'];
|
$item['name'] = $item['title'];
|
||||||
$item['value'] = $item['id'];
|
$item['value'] = $item['id'];
|
||||||
$item['icon'] = $item['icon'] ? "layui-icon {$item['icon']}" : '';
|
$items_map[$item['id']] = $item;
|
||||||
$formatted_items[] = $item;
|
}
|
||||||
|
$formatted_items = [];
|
||||||
|
foreach ($items_map as $index => $item) {
|
||||||
|
//$items_map[$index]['type'] = $items_map[$index]['href'] ? 1 : 0;
|
||||||
|
$items_map[$index]['icon'] = $items_map[$index]['icon'] ? "layui-icon {$items_map[$index]['icon']}" : '';
|
||||||
|
if ($item['pid'] && isset($items_map[$item['pid']])) {
|
||||||
|
$items_map[$item['pid']]['children'][] = &$items_map[$index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($items_map as $item) {
|
||||||
|
if (!$item['pid']) {
|
||||||
|
$formatted_items[] = $item;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$tree = new Tree($formatted_items);
|
|
||||||
$tree_items = $tree->getTree();
|
|
||||||
// 超级管理员权限为 *
|
// 超级管理员权限为 *
|
||||||
if (!in_array('*', $rules)) {
|
if (!in_array('*', $rules)) {
|
||||||
$this->removeNotContain($tree_items, 'id', $rules);
|
$this->removeUncontain($formatted_items, 'id', $rules);
|
||||||
}
|
}
|
||||||
$this->removeNotContain($tree_items, 'type', $types);
|
$this->removeUncontain($formatted_items, 'type', $types);
|
||||||
return $this->json(0, 'ok', Tree::arrayValues($tree_items));
|
$formatted_items = array_values($formatted_items);
|
||||||
|
foreach ($formatted_items as &$item) {
|
||||||
|
$this->arrayValues($item);
|
||||||
|
}
|
||||||
|
return $this->json(0, 'ok', $formatted_items);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取权限
|
* 获取控制器详细权限
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return Response
|
* @return Response
|
||||||
|
* @throws BusinessException
|
||||||
*/
|
*/
|
||||||
public function permission(Request $request): Response
|
public function permissionCodes(Request $request): Response
|
||||||
{
|
{
|
||||||
$rules = $this->getRules(admin('roles'));
|
$rules = $this->getRules(admin('roles'));
|
||||||
// 超级管理员
|
// 超级管理员
|
||||||
@ -173,7 +187,7 @@ class RuleController extends Crud
|
|||||||
*/
|
*/
|
||||||
protected function selectInput(Request $request): array
|
protected function selectInput(Request $request): array
|
||||||
{
|
{
|
||||||
[$where, $format, $limit, $field, $order] = parent::selectInput($request);
|
[$where, $format, $page_size, $field, $order] = parent::selectInput($request);
|
||||||
// 允许通过type=0,1格式传递菜单类型
|
// 允许通过type=0,1格式传递菜单类型
|
||||||
$types = $request->get('type');
|
$types = $request->get('type');
|
||||||
if ($types && is_string($types)) {
|
if ($types && is_string($types)) {
|
||||||
@ -184,7 +198,7 @@ class RuleController extends Crud
|
|||||||
$field = 'weight';
|
$field = 'weight';
|
||||||
$order = 'desc';
|
$order = 'desc';
|
||||||
}
|
}
|
||||||
return [$where, $format, $limit, $field, $order];
|
return [$where, $format, $page_size, $field, $order];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -265,7 +279,7 @@ class RuleController extends Crud
|
|||||||
* @param $values
|
* @param $values
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function removeNotContain(&$array, $key, $values)
|
protected function removeUncontain(&$array, $key, $values)
|
||||||
{
|
{
|
||||||
foreach ($array as $k => &$item) {
|
foreach ($array as $k => &$item) {
|
||||||
if (!is_array($item)) {
|
if (!is_array($item)) {
|
||||||
@ -277,7 +291,7 @@ class RuleController extends Crud
|
|||||||
if (!isset($item['children'])) {
|
if (!isset($item['children'])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$this->removeNotContain($item['children'], $key, $values);
|
$this->removeUncontain($item['children'], $key, $values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,6 +322,25 @@ class RuleController extends Crud
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归删除某些key
|
||||||
|
* @param $array
|
||||||
|
* @param $keys
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function recursiveRemove(&$array, $keys)
|
||||||
|
{
|
||||||
|
if (!is_array($array)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
unset($array[$key]);
|
||||||
|
}
|
||||||
|
foreach ($array as &$item) {
|
||||||
|
$this->recursiveRemove($item, $keys);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取权限规则
|
* 获取权限规则
|
||||||
* @param $roles
|
* @param $roles
|
||||||
@ -326,4 +359,20 @@ class RuleController extends Crud
|
|||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归重建数组下标
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function arrayValues(&$array)
|
||||||
|
{
|
||||||
|
if (!is_array($array) || !isset($array['children'])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$array['children'] = array_values($array['children']);
|
||||||
|
|
||||||
|
foreach ($array['children'] as &$child) {
|
||||||
|
$this->arrayValues($child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ use plugin\admin\app\model\Option;
|
|||||||
use support\exception\BusinessException;
|
use support\exception\BusinessException;
|
||||||
use support\Request;
|
use support\Request;
|
||||||
use support\Response;
|
use support\Response;
|
||||||
use Throwable;
|
|
||||||
|
|
||||||
class TableController extends Base
|
class TableController extends Base
|
||||||
{
|
{
|
||||||
@ -59,20 +58,16 @@ class TableController extends Base
|
|||||||
*/
|
*/
|
||||||
public function show(Request $request): Response
|
public function show(Request $request): Response
|
||||||
{
|
{
|
||||||
$limit = (int)$request->get('limit', 10);
|
|
||||||
$page = (int)$request->get('page', 1);
|
|
||||||
$offset = ($page - 1) * $limit;
|
|
||||||
$database = config('database.connections')['plugin.admin.mysql']['database'];
|
$database = config('database.connections')['plugin.admin.mysql']['database'];
|
||||||
$field = $request->get('field', 'TABLE_NAME');
|
$field = $request->get('field', 'TABLE_NAME');
|
||||||
$field = Util::filterAlphaNum($field);
|
$field = Util::filterAlphaNum($field);
|
||||||
$order = $request->get('order', 'asc');
|
$order = $request->get('order', 'asc');
|
||||||
$allow_column = ['TABLE_NAME', 'TABLE_COMMENT', 'ENGINE', 'TABLE_ROWS', 'CREATE_TIME', 'UPDATE_TIME', 'TABLE_COLLATION'];
|
$allow_column = ['TABLE_NAME','TABLE_COMMENT','ENGINE','TABLE_ROWS','CREATE_TIME','UPDATE_TIME','TABLE_COLLATION'];
|
||||||
if (!in_array($field, $allow_column)) {
|
if (!in_array($field, $allow_column)) {
|
||||||
$field = 'TABLE_NAME';
|
$field = 'TABLE_NAME';
|
||||||
}
|
}
|
||||||
$order = $order === 'asc' ? 'asc' : 'desc';
|
$order = $order === 'asc' ? 'asc' : 'desc';
|
||||||
$total = Util::db()->select("SELECT count(*)total FROM information_schema.`TABLES` WHERE TABLE_SCHEMA='$database'")[0]->total ?? 0;
|
$tables = Util::db()->select("SELECT TABLE_NAME,TABLE_COMMENT,ENGINE,TABLE_ROWS,CREATE_TIME,UPDATE_TIME,TABLE_COLLATION FROM information_schema.`TABLES` WHERE TABLE_SCHEMA='$database' order by $field $order");
|
||||||
$tables = Util::db()->select("SELECT TABLE_NAME,TABLE_COMMENT,ENGINE,TABLE_ROWS,CREATE_TIME,UPDATE_TIME,TABLE_COLLATION FROM information_schema.`TABLES` WHERE TABLE_SCHEMA='$database' order by $field $order limit $offset,$limit");
|
|
||||||
|
|
||||||
if ($tables) {
|
if ($tables) {
|
||||||
$table_names = array_column($tables, 'TABLE_NAME');
|
$table_names = array_column($tables, 'TABLE_NAME');
|
||||||
@ -85,7 +80,7 @@ class TableController extends Base
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return json(['code' => 0, 'msg' => 'ok', 'count' => $total, 'data' => $tables]);
|
return $this->json(0, 'ok', $tables);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,7 +103,6 @@ class TableController extends Base
|
|||||||
|
|
||||||
$primary_key_count = 0;
|
$primary_key_count = 0;
|
||||||
foreach ($columns as $index => $item) {
|
foreach ($columns as $index => $item) {
|
||||||
$columns[$index]['field'] = trim($item['field']);
|
|
||||||
if (!$item['field']) {
|
if (!$item['field']) {
|
||||||
unset($columns[$index]);
|
unset($columns[$index]);
|
||||||
continue;
|
continue;
|
||||||
@ -201,7 +195,7 @@ class TableController extends Base
|
|||||||
$data = $request->post();
|
$data = $request->post();
|
||||||
$old_table_name = Util::filterAlphaNum($data['old_table']);
|
$old_table_name = Util::filterAlphaNum($data['old_table']);
|
||||||
$table_name = Util::filterAlphaNum($data['table']);
|
$table_name = Util::filterAlphaNum($data['table']);
|
||||||
$table_comment = $data['table_comment'];
|
$table_comment = Util::pdoQuote($data['table_comment']);
|
||||||
$columns = $data['columns'];
|
$columns = $data['columns'];
|
||||||
$forms = $data['forms'];
|
$forms = $data['forms'];
|
||||||
$keys = $data['keys'];
|
$keys = $data['keys'];
|
||||||
@ -213,7 +207,6 @@ class TableController extends Base
|
|||||||
|
|
||||||
$primary_key_count = $auto_increment_count = 0;
|
$primary_key_count = $auto_increment_count = 0;
|
||||||
foreach ($columns as $index => $item) {
|
foreach ($columns as $index => $item) {
|
||||||
$columns[$index]['field'] = trim($item['field']);
|
|
||||||
if (!$item['field']) {
|
if (!$item['field']) {
|
||||||
unset($columns[$index]);
|
unset($columns[$index]);
|
||||||
continue;
|
continue;
|
||||||
@ -291,7 +284,6 @@ class TableController extends Base
|
|||||||
|
|
||||||
$table = Util::getSchema($table_name, 'table');
|
$table = Util::getSchema($table_name, 'table');
|
||||||
if ($table_comment !== $table['comment']) {
|
if ($table_comment !== $table['comment']) {
|
||||||
$table_comment = Util::pdoQuote($table_comment);
|
|
||||||
Util::db()->statement("ALTER TABLE `$table_name` COMMENT $table_comment");
|
Util::db()->statement("ALTER TABLE `$table_name` COMMENT $table_comment");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,10 +320,9 @@ class TableController extends Base
|
|||||||
$key_name = $key['name'];
|
$key_name = $key['name'];
|
||||||
$old_key = $old_keys[$key_name] ?? [];
|
$old_key = $old_keys[$key_name] ?? [];
|
||||||
// 如果索引有变动,则删除索引,重新建立索引
|
// 如果索引有变动,则删除索引,重新建立索引
|
||||||
if ($old_key && ($key['type'] != $old_key['type'] || $key['columns'] != implode(',', $old_key['columns']))) {
|
if ($old_key && ($key['type'] != $old_key['type'] || $key['columns'] != $old_key['columns'])) {
|
||||||
$old_key = [];
|
$old_key = [];
|
||||||
unset($old_keys[$key_name]);
|
unset($old_keys[$key_name]);
|
||||||
echo "Drop Index $key_name\n";
|
|
||||||
$table->dropIndex($key_name);
|
$table->dropIndex($key_name);
|
||||||
}
|
}
|
||||||
// 重新建立索引
|
// 重新建立索引
|
||||||
@ -343,7 +334,6 @@ class TableController extends Base
|
|||||||
$table->unique($columns, $name);
|
$table->unique($columns, $name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
echo "Create Index $key_name\n";
|
|
||||||
$table->index($columns, $name);
|
$table->index($columns, $name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -353,7 +343,6 @@ class TableController extends Base
|
|||||||
$old_keys_names = array_column($old_keys, 'name');
|
$old_keys_names = array_column($old_keys, 'name');
|
||||||
$drop_keys_names = array_diff($old_keys_names, $exists_key_names);
|
$drop_keys_names = array_diff($old_keys_names, $exists_key_names);
|
||||||
foreach ($drop_keys_names as $name) {
|
foreach ($drop_keys_names as $name) {
|
||||||
echo "Drop Index $name\n";
|
|
||||||
$table->dropIndex($name);
|
$table->dropIndex($name);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -396,8 +385,7 @@ class TableController extends Base
|
|||||||
{
|
{
|
||||||
$table_name = $request->input('table');
|
$table_name = $request->input('table');
|
||||||
Util::checkTableName($table_name);
|
Util::checkTableName($table_name);
|
||||||
$prefix = 'wa_';
|
$table_basename = strpos($table_name, 'wa_') === 0 ? substr($table_name, 3) : $table_name;
|
||||||
$table_basename = strpos($table_name, $prefix) === 0 ? substr($table_name, strlen($prefix)) : $table_name;
|
|
||||||
$inflector = InflectorFactory::create()->build();
|
$inflector = InflectorFactory::create()->build();
|
||||||
$model_class = $inflector->classify($inflector->singularize($table_basename));
|
$model_class = $inflector->classify($inflector->singularize($table_basename));
|
||||||
$base_path = '/plugin/admin/app';
|
$base_path = '/plugin/admin/app';
|
||||||
@ -471,49 +459,44 @@ class TableController extends Base
|
|||||||
$app = strtolower($explode[1]) !== 'controller' ? $explode[1] : '';
|
$app = strtolower($explode[1]) !== 'controller' ? $explode[1] : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
Util::pauseFileMonitor();
|
$model_class = $model_file_name;
|
||||||
try {
|
$model_namespace = str_replace('/' , '\\', trim($model_path, '/'));
|
||||||
$model_class = $model_file_name;
|
|
||||||
$model_namespace = str_replace('/', '\\', trim($model_path, '/'));
|
|
||||||
|
|
||||||
// 创建model
|
// 创建model
|
||||||
$this->createModel($model_class, $model_namespace, base_path($model_file), $table_name);
|
$this->createModel($model_class, $model_namespace, base_path($model_file), $table_name);
|
||||||
|
|
||||||
$controller_suffix = $plugin ? config("plugin.$plugin.app.controller_suffix") : config('app.controller_suffix');
|
$controller_suffix = $plugin ? config("plugin.$plugin.app.controller_suffix") : config('app.controller_suffix');
|
||||||
$controller_class = $controller_file_name;
|
$controller_class = $controller_file_name;
|
||||||
$controller_namespace = str_replace('/', '\\', trim($controller_path, '/'));
|
$controller_namespace = str_replace('/' , '\\', trim($controller_path, '/'));
|
||||||
// 创建controller
|
// 创建controller
|
||||||
$controller_url_name = $controller_suffix && substr($controller_class, -strlen($controller_suffix)) === $controller_suffix ? substr($controller_class, 0, -strlen($controller_suffix)) : $controller_class;
|
$controller_url_name = $controller_suffix && substr($controller_class, -strlen($controller_suffix)) === $controller_suffix ? substr($controller_class, 0, -strlen($controller_suffix)) : $controller_class;
|
||||||
$controller_url_name = str_replace('_', '-', $inflector->tableize($controller_url_name));
|
$controller_url_name = str_replace('_', '-', $inflector->tableize($controller_url_name));
|
||||||
|
|
||||||
if ($plugin) {
|
if ($plugin) {
|
||||||
array_splice($explode, 0, 2);
|
array_splice($explode, 0, 2);
|
||||||
}
|
|
||||||
array_shift($explode);
|
|
||||||
if ($app) {
|
|
||||||
array_shift($explode);
|
|
||||||
}
|
|
||||||
foreach ($explode as $index => $item) {
|
|
||||||
if (strtolower($item) === 'controller') {
|
|
||||||
unset($explode[$index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$controller_base = implode('/', $explode);
|
|
||||||
$controller_class_with_namespace = "$controller_namespace\\$controller_class";
|
|
||||||
$template_path = $controller_base ? "$controller_base/$controller_url_name" : $controller_url_name;
|
|
||||||
$this->createController($controller_class, $controller_namespace, base_path($controller_file), $model_class, $model_namespace, $title, $template_path);
|
|
||||||
|
|
||||||
// 创建模版
|
|
||||||
$template_file_path = ($plugin ? "/plugin/$plugin" : '') . '/app/' . ($app ? "$app/" : '') . 'view/' . $template_path;
|
|
||||||
|
|
||||||
$model_class_with_namespace = "$model_namespace\\$model_class";
|
|
||||||
$primary_key = (new $model_class_with_namespace)->getKeyName();
|
|
||||||
$url_path_base = ($plugin ? "/app/$plugin/" : '/') . ($app ? "$app/" : '') . $template_path;
|
|
||||||
$this->createTemplate(base_path($template_file_path), $table_name, $url_path_base, $primary_key, "$controller_namespace\\$controller_class");
|
|
||||||
} finally {
|
|
||||||
Util::resumeFileMonitor();
|
|
||||||
}
|
}
|
||||||
|
array_shift($explode);
|
||||||
|
if ($app) {
|
||||||
|
array_shift($explode);
|
||||||
|
}
|
||||||
|
foreach ($explode as $index => $item) {
|
||||||
|
if (strtolower($item) === 'controller') {
|
||||||
|
unset($explode[$index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$controller_base = implode('/', $explode);
|
||||||
|
$controller_class_with_namespace = "$controller_namespace\\$controller_class";
|
||||||
|
$template_path = $controller_base ? "$controller_base/$controller_url_name" : $controller_url_name;
|
||||||
|
$this->createController($controller_class, $controller_namespace, base_path($controller_file), $model_class, $model_namespace, $title, $template_path);
|
||||||
|
|
||||||
|
// 创建模版
|
||||||
|
$template_file_path = ($plugin ? "/plugin/$plugin" : '') . '/app/' . ($app ? "$app/" : '') . 'view/' . $template_path;
|
||||||
|
|
||||||
|
$model_class_with_namespace = "$model_namespace\\$model_class";
|
||||||
|
$primary_key = (new $model_class_with_namespace)->getKeyName();
|
||||||
|
$url_path_base = ($plugin ? "/app/$plugin/" : '/') . ($app ? "$app/" : '') . $template_path;
|
||||||
|
$this->createTemplate(base_path($template_file_path), $table_name, $url_path_base, $primary_key, "$controller_namespace\\$controller_class");
|
||||||
|
|
||||||
$menu = Rule::where('key', $controller_class_with_namespace)->first();
|
$menu = Rule::where('key', $controller_class_with_namespace)->first();
|
||||||
if (!$menu) {
|
if (!$menu) {
|
||||||
@ -563,33 +546,20 @@ class TableController extends Base
|
|||||||
$pk = 'id';
|
$pk = 'id';
|
||||||
$properties = '';
|
$properties = '';
|
||||||
$timestamps = '';
|
$timestamps = '';
|
||||||
$incrementing = '';
|
|
||||||
$columns = [];
|
$columns = [];
|
||||||
try {
|
try {
|
||||||
$database = config('database.connections')['plugin.admin.mysql']['database'];
|
$database = config('database.connections')['plugin.admin.mysql']['database'];
|
||||||
//plugin.admin.mysql
|
//plugin.admin.mysql
|
||||||
foreach (Util::db()->select("select COLUMN_NAME,DATA_TYPE,COLUMN_KEY,COLUMN_COMMENT from INFORMATION_SCHEMA.COLUMNS where table_name = '$table' and table_schema = '$database' order by ORDINAL_POSITION") as $item) {
|
foreach (Util::db()->select("select COLUMN_NAME,DATA_TYPE,COLUMN_KEY,COLUMN_COMMENT from INFORMATION_SCHEMA.COLUMNS where table_name = '$table' and table_schema = '$database'") as $item) {
|
||||||
if ($item->COLUMN_KEY === 'PRI') {
|
if ($item->COLUMN_KEY === 'PRI') {
|
||||||
$pk = $item->COLUMN_NAME;
|
$pk = $item->COLUMN_NAME;
|
||||||
$item->COLUMN_COMMENT .= "(主键)";
|
$item->COLUMN_COMMENT .= "(主键)";
|
||||||
if (strpos(strtolower($item->DATA_TYPE), 'int') === false) {
|
|
||||||
$incrementing = <<<EOF
|
|
||||||
/**
|
|
||||||
* Indicates if the model's ID is auto-incrementing.
|
|
||||||
*
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
public \$incrementing = false;
|
|
||||||
|
|
||||||
EOF;
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$type = $this->getType($item->DATA_TYPE);
|
$type = $this->getType($item->DATA_TYPE);
|
||||||
$properties .= " * @property $type \${$item->COLUMN_NAME} {$item->COLUMN_COMMENT}\n";
|
$properties .= " * @property $type \${$item->COLUMN_NAME} {$item->COLUMN_COMMENT}\n";
|
||||||
$columns[$item->COLUMN_NAME] = $item->COLUMN_NAME;
|
$columns[$item->COLUMN_NAME] = $item->COLUMN_NAME;
|
||||||
}
|
}
|
||||||
} catch (Throwable $e) {echo $e;}
|
} catch (\Throwable $e) {echo $e;}
|
||||||
if (!isset($columns['created_at']) || !isset($columns['updated_at'])) {
|
if (!isset($columns['created_at']) || !isset($columns['updated_at'])) {
|
||||||
$timestamps = <<<EOF
|
$timestamps = <<<EOF
|
||||||
/**
|
/**
|
||||||
@ -598,7 +568,6 @@ EOF;
|
|||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
public \$timestamps = false;
|
public \$timestamps = false;
|
||||||
|
|
||||||
EOF;
|
EOF;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -628,8 +597,9 @@ class $class extends Base
|
|||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected \$primaryKey = '$pk';
|
protected \$primaryKey = '$pk';
|
||||||
|
|
||||||
$timestamps
|
$timestamps
|
||||||
$incrementing
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -857,9 +827,6 @@ EOF
|
|||||||
// 表格顶部搜索事件
|
// 表格顶部搜索事件
|
||||||
form.on("submit(table-query)", function(data) {
|
form.on("submit(table-query)", function(data) {
|
||||||
table.reload("data-table", {
|
table.reload("data-table", {
|
||||||
page: {
|
|
||||||
curr: 1
|
|
||||||
},
|
|
||||||
where: data.field
|
where: data.field
|
||||||
})
|
})
|
||||||
return false;
|
return false;
|
||||||
@ -871,16 +838,6 @@ EOF
|
|||||||
where: []
|
where: []
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
// 字段允许为空
|
|
||||||
form.verify({
|
|
||||||
phone: [/(^$)|^1\d{10}$/, "请输入正确的手机号"],
|
|
||||||
email: [/(^$)|^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/, "邮箱格式不正确"],
|
|
||||||
url: [/(^$)|(^#)|(^http(s*):\/\/[^\s]+\.[^\s]+)/, "链接格式不正确"],
|
|
||||||
number: [/(^$)|^\d+$/,'只能填写数字'],
|
|
||||||
date: [/(^$)|^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/, "日期格式不正确"],
|
|
||||||
identity: [/(^$)|(^\d{15}$)|(^\d{17}(x|X|\d)$)/, "请输入正确的身份证号"]
|
|
||||||
});
|
|
||||||
|
|
||||||
// 表格排序事件
|
// 表格排序事件
|
||||||
table.on("sort(data-table)", function(obj){
|
table.on("sort(data-table)", function(obj){
|
||||||
@ -990,7 +947,7 @@ EOF;
|
|||||||
<form class="layui-form" action="">
|
<form class="layui-form" action="">
|
||||||
|
|
||||||
<div class="mainBox">
|
<div class="mainBox">
|
||||||
<div class="main-container mr-5">
|
<div class="main-container">
|
||||||
$html
|
$html
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1020,15 +977,6 @@ EOF;
|
|||||||
$js
|
$js
|
||||||
//提交事件
|
//提交事件
|
||||||
layui.use(["form", "popup"], function () {
|
layui.use(["form", "popup"], function () {
|
||||||
// 字段验证允许为空
|
|
||||||
layui.form.verify({
|
|
||||||
phone: [/(^$)|^1\d{10}$/, "请输入正确的手机号"],
|
|
||||||
email: [/(^$)|^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/, "邮箱格式不正确"],
|
|
||||||
url: [/(^$)|(^#)|(^http(s*):\/\/[^\s]+\.[^\s]+)/, "链接格式不正确"],
|
|
||||||
number: [/(^$)|^\d+$/,'只能填写数字'],
|
|
||||||
date: [/(^$)|^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/, "日期格式不正确"],
|
|
||||||
identity: [/(^$)|(^\d{15}$)|(^\d{17}(x|X|\d)$)/, "请输入正确的身份证号"]
|
|
||||||
});
|
|
||||||
layui.form.on("submit(save)", function (data) {
|
layui.form.on("submit(save)", function (data) {
|
||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
url: INSERT_API,
|
url: INSERT_API,
|
||||||
@ -1075,7 +1023,7 @@ EOF;
|
|||||||
<form class="layui-form">
|
<form class="layui-form">
|
||||||
|
|
||||||
<div class="mainBox">
|
<div class="mainBox">
|
||||||
<div class="main-container mr-5">
|
<div class="main-container">
|
||||||
$html
|
$html
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1105,15 +1053,15 @@ EOF;
|
|||||||
const UPDATE_API = "$url_path_base/update";
|
const UPDATE_API = "$url_path_base/update";
|
||||||
|
|
||||||
// 获取数据库记录
|
// 获取数据库记录
|
||||||
layui.use(["form", "util", "popup"], function () {
|
layui.use(["form", "util"], function () {
|
||||||
let $ = layui.$;
|
let $ = layui.$;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: SELECT_API,
|
url: SELECT_API,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
|
|
||||||
// 给表单初始化数据
|
// 给表单初始化数据
|
||||||
layui.each(res.data[0], function (key, value) {
|
layui.each(e.data[0], function (key, value) {
|
||||||
let obj = $('*[name="'+key+'"]');
|
let obj = $('*[name="'+key+'"]');
|
||||||
if (key === "password") {
|
if (key === "password") {
|
||||||
obj.attr("placeholder", "不更新密码请留空");
|
obj.attr("placeholder", "不更新密码请留空");
|
||||||
@ -1127,27 +1075,13 @@ EOF;
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
$js
|
$js
|
||||||
|
|
||||||
// ajax返回失败
|
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
//提交事件
|
//提交事件
|
||||||
layui.use(["form", "popup"], function () {
|
layui.use(["form", "popup"], function () {
|
||||||
// 字段验证允许为空
|
|
||||||
layui.form.verify({
|
|
||||||
phone: [/(^$)|^1\d{10}$/, "请输入正确的手机号"],
|
|
||||||
email: [/(^$)|^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/, "邮箱格式不正确"],
|
|
||||||
url: [/(^$)|(^#)|(^http(s*):\/\/[^\s]+\.[^\s]+)/, "链接格式不正确"],
|
|
||||||
number: [/(^$)|^\d+$/,'只能填写数字'],
|
|
||||||
date: [/(^$)|^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/, "日期格式不正确"],
|
|
||||||
identity: [/(^$)|(^\d{15}$)|(^\d{17}(x|X|\d)$)/, "请输入正确的身份证号"]
|
|
||||||
});
|
|
||||||
layui.form.on("submit(save)", function (data) {
|
layui.form.on("submit(save)", function (data) {
|
||||||
data.field[PRIMARY_KEY] = layui.url().search[PRIMARY_KEY];
|
data.field[PRIMARY_KEY] = layui.url().search[PRIMARY_KEY];
|
||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
@ -1208,7 +1142,7 @@ EOF;
|
|||||||
$order = $request->get('order', 'asc');
|
$order = $request->get('order', 'asc');
|
||||||
$table = Util::filterAlphaNum($request->get('table', ''));
|
$table = Util::filterAlphaNum($request->get('table', ''));
|
||||||
$format = $request->get('format', 'normal');
|
$format = $request->get('format', 'normal');
|
||||||
$limit = $request->get('limit', $format === 'tree' ? 5000 : 10);
|
$page_size = $request->get('limit', $format === 'tree' ? 5000 : 10);
|
||||||
|
|
||||||
$allow_column = Util::db()->select("desc $table");
|
$allow_column = Util::db()->select("desc $table");
|
||||||
if (!$allow_column) {
|
if (!$allow_column) {
|
||||||
@ -1226,21 +1160,17 @@ EOF;
|
|||||||
}
|
}
|
||||||
if (isset($allow_column[$column])) {
|
if (isset($allow_column[$column])) {
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
if ($value[0] === 'like') {
|
if (in_array($value[0], ['', 'undefined']) || in_array($value[1], ['', 'undefined'])) {
|
||||||
$paginator = $paginator->where($column, 'like', "%$value[1]%");
|
continue;
|
||||||
} elseif (in_array($value[0], ['>', '=', '<', '<>', 'not like'])) {
|
|
||||||
$paginator = $paginator->where($column, $value[0], $value[1]);
|
|
||||||
} else {
|
|
||||||
if($value[0] !== '' || $value[1] !== '') {
|
|
||||||
$paginator = $paginator->whereBetween($column, $value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
$paginator = $paginator->whereBetween($column, $value);
|
||||||
} else {
|
} else {
|
||||||
$paginator = $paginator->where($column, $value);
|
$paginator = $paginator->where($column, $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$paginator = $paginator->orderBy($field, $order)->paginate($limit, '*', 'page', $page);
|
$paginator = $paginator->orderBy($field, $order)->paginate($page_size, '*', 'page', $page);
|
||||||
|
|
||||||
$items = $paginator->items();
|
$items = $paginator->items();
|
||||||
if ($format == 'tree') {
|
if ($format == 'tree') {
|
||||||
$items_map = [];
|
$items_map = [];
|
||||||
@ -1418,8 +1348,7 @@ EOF;
|
|||||||
if (!$tables) {
|
if (!$tables) {
|
||||||
return $this->json(0, 'not found');
|
return $this->json(0, 'not found');
|
||||||
}
|
}
|
||||||
$prefix = 'wa_';
|
$table_not_allow_drop = ['wa_admins', 'wa_users', 'wa_options', 'wa_roles', 'wa_rules'];
|
||||||
$table_not_allow_drop = ["{$prefix}admins", "{$prefix}users", "{$prefix}options", "{$prefix}roles", "{$prefix}rules", "{$prefix}admin_roles", "{$prefix}uploads"];
|
|
||||||
if ($found = array_intersect($tables, $table_not_allow_drop)) {
|
if ($found = array_intersect($tables, $table_not_allow_drop)) {
|
||||||
return $this->json(400, implode(',', $found) . '不允许删除');
|
return $this->json(400, implode(',', $found) . '不允许删除');
|
||||||
}
|
}
|
||||||
@ -1518,7 +1447,7 @@ EOF;
|
|||||||
$field = Util::filterAlphaNum($column['field']);
|
$field = Util::filterAlphaNum($column['field']);
|
||||||
$old_field = Util::filterAlphaNum($column['old_field'] ?? null);
|
$old_field = Util::filterAlphaNum($column['old_field'] ?? null);
|
||||||
$nullable = $column['nullable'];
|
$nullable = $column['nullable'];
|
||||||
$default = $column['default'] !== null ? Util::pdoQuote($column['default']) : null;
|
$default = Util::filterAlphaNum($column['default']);
|
||||||
$comment = Util::pdoQuote($column['comment']);
|
$comment = Util::pdoQuote($column['comment']);
|
||||||
$auto_increment = $column['auto_increment'];
|
$auto_increment = $column['auto_increment'];
|
||||||
$length = (int)$column['length'];
|
$length = (int)$column['length'];
|
||||||
@ -1528,9 +1457,9 @@ EOF;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($old_field && $old_field !== $field) {
|
if ($old_field && $old_field !== $field) {
|
||||||
$sql = "ALTER TABLE `$table` CHANGE COLUMN `$old_field` `$field` ";
|
$sql = "ALTER TABLE $table CHANGE COLUMN `$old_field` `$field` ";
|
||||||
} else {
|
} else {
|
||||||
$sql = "ALTER TABLE `$table` MODIFY `$field` ";
|
$sql = "ALTER TABLE $table MODIFY `$field` ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stripos($method, 'integer') !== false) {
|
if (stripos($method, 'integer') !== false) {
|
||||||
@ -1586,14 +1515,13 @@ EOF;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($method != 'text' && $default !== null) {
|
if ($method != 'text' && $default !== null) {
|
||||||
$sql .= "DEFAULT $default ";
|
$sql .= "DEFAULT '$default' ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($comment !== null) {
|
if ($comment !== null) {
|
||||||
$sql .= "COMMENT $comment ";
|
$sql .= "COMMENT $comment ";
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "$sql\n";
|
|
||||||
Util::db()->statement($sql);
|
Util::db()->statement($sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ class UploadController extends Crud
|
|||||||
*/
|
*/
|
||||||
public function select(Request $request): Response
|
public function select(Request $request): Response
|
||||||
{
|
{
|
||||||
[$where, $format, $limit, $field, $order] = $this->selectInput($request);
|
[$where, $format, $page_size, $field, $order] = $this->selectInput($request);
|
||||||
if (!empty($where['ext']) && is_string($where['ext'])) {
|
if (!empty($where['ext']) && is_string($where['ext'])) {
|
||||||
$where['ext'] = ['in', explode(',', $where['ext'])];
|
$where['ext'] = ['in', explode(',', $where['ext'])];
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ class UploadController extends Crud
|
|||||||
$where['name'] = ['like', "%{$where['name']}%"];
|
$where['name'] = ['like', "%{$where['name']}%"];
|
||||||
}
|
}
|
||||||
$query = $this->doSelect($where, $field, $order);
|
$query = $this->doSelect($where, $field, $order);
|
||||||
return $this->doFormat($query, $format, $limit);
|
return $this->doFormat($query, $format, $page_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -306,4 +306,19 @@ class UploadController extends Crud
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化文件大小
|
||||||
|
* @param $file_size
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function formatSize($file_size): string
|
||||||
|
{
|
||||||
|
$size = sprintf("%u", $file_size);
|
||||||
|
if($size == 0) {
|
||||||
|
return("0 Bytes");
|
||||||
|
}
|
||||||
|
$size_name = array(" Bytes", " KB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB");
|
||||||
|
return round($size/pow(1024, ($i = floor(log($size, 1024)))), 2) . $size_name[$i];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -27,14 +27,13 @@ class Handler extends \support\exception\Handler
|
|||||||
public function render(Request $request, Throwable $exception): Response
|
public function render(Request $request, Throwable $exception): Response
|
||||||
{
|
{
|
||||||
$code = $exception->getCode();
|
$code = $exception->getCode();
|
||||||
$debug = $this->_debug ?? $this->debug;
|
|
||||||
if ($request->expectsJson()) {
|
if ($request->expectsJson()) {
|
||||||
$json = ['code' => $code ?: 500, 'msg' => $debug ? $exception->getMessage() : 'Server internal error', 'type' => 'failed'];
|
$json = ['code' => $code ? $code : 500, 'msg' => $this->_debug ? $exception->getMessage() : 'Server internal error', 'type' => 'failed'];
|
||||||
$debug && $json['traces'] = (string)$exception;
|
$this->_debug && $json['traces'] = (string)$exception;
|
||||||
return new Response(200, ['Content-Type' => 'application/json'],
|
return new Response(200, ['Content-Type' => 'application/json'],
|
||||||
\json_encode($json, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
|
\json_encode($json, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
|
||||||
}
|
}
|
||||||
$error = $debug ? \nl2br((string)$exception) : 'Server internal error';
|
$error = $this->_debug ? \nl2br((string)$exception) : 'Server internal error';
|
||||||
return new Response(500, [], $error);
|
return new Response(500, [], $error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,15 +3,15 @@
|
|||||||
* Here is your custom functions.
|
* Here is your custom functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use plugin\admin\app\model\User;
|
use app\model\User;
|
||||||
use plugin\admin\app\model\Admin;
|
use plugin\admin\app\model\Admin;
|
||||||
use plugin\admin\app\model\AdminRole;
|
use support\exception\BusinessException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前管理员id
|
* 当前管理员id
|
||||||
* @return integer|null
|
* @return integer|null
|
||||||
*/
|
*/
|
||||||
function admin_id(): ?int
|
function admin_id()
|
||||||
{
|
{
|
||||||
return session('admin.id');
|
return session('admin.id');
|
||||||
}
|
}
|
||||||
@ -20,6 +20,7 @@ function admin_id(): ?int
|
|||||||
* 当前管理员
|
* 当前管理员
|
||||||
* @param null|array|string $fields
|
* @param null|array|string $fields
|
||||||
* @return array|mixed|null
|
* @return array|mixed|null
|
||||||
|
* @throws BusinessException
|
||||||
*/
|
*/
|
||||||
function admin($fields = null)
|
function admin($fields = null)
|
||||||
{
|
{
|
||||||
@ -44,7 +45,7 @@ function admin($fields = null)
|
|||||||
* 当前登录用户id
|
* 当前登录用户id
|
||||||
* @return integer|null
|
* @return integer|null
|
||||||
*/
|
*/
|
||||||
function user_id(): ?int
|
function user_id()
|
||||||
{
|
{
|
||||||
return session('user.id');
|
return session('user.id');
|
||||||
}
|
}
|
||||||
@ -53,6 +54,7 @@ function user_id(): ?int
|
|||||||
* 当前登录用户
|
* 当前登录用户
|
||||||
* @param null|array|string $fields
|
* @param null|array|string $fields
|
||||||
* @return array|mixed|null
|
* @return array|mixed|null
|
||||||
|
* @throws BusinessException
|
||||||
*/
|
*/
|
||||||
function user($fields = null)
|
function user($fields = null)
|
||||||
{
|
{
|
||||||
@ -77,6 +79,7 @@ function user($fields = null)
|
|||||||
* 刷新当前管理员session
|
* 刷新当前管理员session
|
||||||
* @param bool $force
|
* @param bool $force
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws BusinessException
|
||||||
*/
|
*/
|
||||||
function refresh_admin_session(bool $force = false)
|
function refresh_admin_session(bool $force = false)
|
||||||
{
|
{
|
||||||
@ -98,12 +101,7 @@ function refresh_admin_session(bool $force = false)
|
|||||||
}
|
}
|
||||||
$admin = $admin->toArray();
|
$admin = $admin->toArray();
|
||||||
unset($admin['password']);
|
unset($admin['password']);
|
||||||
// 账户被禁用
|
$admin['roles'] = $admin['roles'] ? explode(',', $admin['roles']) : [];
|
||||||
if ($admin['status'] != 0) {
|
|
||||||
$session->forget('admin');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$admin['roles'] = AdminRole::where('admin_id', $admin_id)->pluck('role_id')->toArray();
|
|
||||||
$admin['session_last_update_time'] = $time_now;
|
$admin['session_last_update_time'] = $time_now;
|
||||||
$session->set('admin', $admin);
|
$session->set('admin', $admin);
|
||||||
}
|
}
|
||||||
@ -113,6 +111,7 @@ function refresh_admin_session(bool $force = false)
|
|||||||
* 刷新当前用户session
|
* 刷新当前用户session
|
||||||
* @param bool $force
|
* @param bool $force
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws BusinessException
|
||||||
*/
|
*/
|
||||||
function refresh_user_session(bool $force = false)
|
function refresh_user_session(bool $force = false)
|
||||||
{
|
{
|
||||||
@ -136,4 +135,4 @@ function refresh_user_session(bool $force = false)
|
|||||||
unset($user['password']);
|
unset($user['password']);
|
||||||
$user['session_last_update_time'] = $time_now;
|
$user['session_last_update_time'] = $time_now;
|
||||||
$session->set('user', $user);
|
$session->set('user', $user);
|
||||||
}
|
}
|
@ -2,8 +2,6 @@
|
|||||||
namespace plugin\admin\app\middleware;
|
namespace plugin\admin\app\middleware;
|
||||||
|
|
||||||
use plugin\admin\api\Auth;
|
use plugin\admin\api\Auth;
|
||||||
use ReflectionException;
|
|
||||||
use support\exception\BusinessException;
|
|
||||||
use Webman\Http\Request;
|
use Webman\Http\Request;
|
||||||
use Webman\Http\Response;
|
use Webman\Http\Response;
|
||||||
use Webman\MiddlewareInterface;
|
use Webman\MiddlewareInterface;
|
||||||
@ -14,7 +12,7 @@ class AccessControl implements MiddlewareInterface
|
|||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @param callable $handler
|
* @param callable $handler
|
||||||
* @return Response
|
* @return Response
|
||||||
* @throws ReflectionException|BusinessException
|
* @throws \ReflectionException
|
||||||
*/
|
*/
|
||||||
public function process(Request $request, callable $handler): Response
|
public function process(Request $request, callable $handler): Response
|
||||||
{
|
{
|
||||||
@ -37,9 +35,7 @@ class AccessControl implements MiddlewareInterface
|
|||||||
EOF
|
EOF
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$request->app = '';
|
$response = view('common/error/403');
|
||||||
$request->plugin = 'admin';
|
|
||||||
$response = view('common/error/403')->withStatus(403);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,4 +47,4 @@ EOF
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -14,9 +14,7 @@ use plugin\admin\app\model\Base;
|
|||||||
* @property string $mobile 手机
|
* @property string $mobile 手机
|
||||||
* @property string $created_at 创建时间
|
* @property string $created_at 创建时间
|
||||||
* @property string $updated_at 更新时间
|
* @property string $updated_at 更新时间
|
||||||
* @property string $login_at 登录时间
|
|
||||||
* @property string $roles 角色
|
* @property string $roles 角色
|
||||||
* @property integer $status 状态 0正常 1禁用
|
|
||||||
*/
|
*/
|
||||||
class Admin extends Base
|
class Admin extends Base
|
||||||
{
|
{
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace plugin\admin\app\model;
|
|
||||||
|
|
||||||
use plugin\admin\app\model\Base;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property integer $id ID(主键)
|
|
||||||
* @property string $admin_id 管理员id
|
|
||||||
* @property string $role_id 角色id
|
|
||||||
*/
|
|
||||||
class AdminRole extends Base
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The table associated with the model.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $table = 'wa_admin_roles';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The primary key associated with the table.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $primaryKey = 'id';
|
|
||||||
|
|
||||||
|
|
||||||
public $timestamps = false;
|
|
||||||
|
|
||||||
}
|
|
@ -1,96 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace plugin\admin\app\model;
|
|
||||||
|
|
||||||
|
|
||||||
use support\exception\BusinessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字典相关
|
|
||||||
*/
|
|
||||||
class Dict
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 获取字典
|
|
||||||
* @param $name
|
|
||||||
* @return mixed|null
|
|
||||||
*/
|
|
||||||
public static function get($name)
|
|
||||||
{
|
|
||||||
$value = Option::where('name', static::dictNameToOptionName($name))->value('value');
|
|
||||||
return $value ? json_decode($value, true) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存字典
|
|
||||||
* @param $name
|
|
||||||
* @param $values
|
|
||||||
* @return void
|
|
||||||
* @throws BusinessException
|
|
||||||
*/
|
|
||||||
public static function save($name, $values)
|
|
||||||
{
|
|
||||||
if (!preg_match('/[a-zA-Z]/', $name)) {
|
|
||||||
throw new BusinessException('字典名只能包含字母');
|
|
||||||
}
|
|
||||||
$option_name = static::dictNameToOptionName($name);
|
|
||||||
if (!$option = Option::where('name', $option_name)->first()) {
|
|
||||||
$option = new Option;
|
|
||||||
}
|
|
||||||
$format_values = static::filterValue($values);
|
|
||||||
$option->name = $option_name;
|
|
||||||
$option->value = json_encode($format_values, JSON_UNESCAPED_UNICODE);
|
|
||||||
$option->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除字典
|
|
||||||
* @param array $names
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public static function delete(array $names)
|
|
||||||
{
|
|
||||||
foreach ($names as $index => $name) {
|
|
||||||
$names[$index] = static::dictNameToOptionName($name);
|
|
||||||
}
|
|
||||||
Option::whereIn('name', $names)->delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字典名到option名转换
|
|
||||||
* @param string $name
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function dictNameToOptionName(string $name): string
|
|
||||||
{
|
|
||||||
return "dict_$name";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* option名到字典名转换
|
|
||||||
* @param string $name
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function optionNameToDictName(string $name): string
|
|
||||||
{
|
|
||||||
return substr($name, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 过滤值
|
|
||||||
* @param array $values
|
|
||||||
* @return array
|
|
||||||
* @throws BusinessException
|
|
||||||
*/
|
|
||||||
public static function filterValue(array $values): array
|
|
||||||
{
|
|
||||||
$format_values = [];
|
|
||||||
foreach ($values as $item) {
|
|
||||||
if (!isset($item['value']) || !isset($item['name'])) {
|
|
||||||
throw new BusinessException('字典格式错误', 1);
|
|
||||||
}
|
|
||||||
$format_values[] = ['value' => $item['value'], 'name' => $item['name']];
|
|
||||||
}
|
|
||||||
return $format_values;
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace plugin\admin\app\model;
|
namespace plugin\admin\app\model;
|
||||||
|
|
||||||
|
use plugin\admin\app\model\Base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property integer $id 主键(主键)
|
* @property integer $id 主键(主键)
|
||||||
@ -9,7 +10,6 @@ namespace plugin\admin\app\model;
|
|||||||
* @property string $rules 权限
|
* @property string $rules 权限
|
||||||
* @property string $created_at 创建时间
|
* @property string $created_at 创建时间
|
||||||
* @property string $updated_at 更新时间
|
* @property string $updated_at 更新时间
|
||||||
* @property integer $pid 上级id
|
|
||||||
*/
|
*/
|
||||||
class Role extends Base
|
class Role extends Base
|
||||||
{
|
{
|
||||||
@ -26,13 +26,8 @@ class Role extends Base
|
|||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $primaryKey = 'id';
|
protected $primaryKey = 'id';
|
||||||
|
|
||||||
/**
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function getRuleIds()
|
|
||||||
{
|
|
||||||
return $this->rules ? explode(',', $this->rules) : [];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -89,10 +89,8 @@
|
|||||||
|
|
||||||
<!-- 表格行工具栏 -->
|
<!-- 表格行工具栏 -->
|
||||||
<script type="text/html" id="table-bar">
|
<script type="text/html" id="table-bar">
|
||||||
{{# if(d.show_toolbar){ }}
|
|
||||||
<button class="pear-btn pear-btn-xs tool-btn" lay-event="edit" permission="app.admin.admin.update">编辑</button>
|
<button class="pear-btn pear-btn-xs tool-btn" lay-event="edit" permission="app.admin.admin.update">编辑</button>
|
||||||
<button class="pear-btn pear-btn-xs tool-btn" lay-event="remove" permission="app.admin.admin.delete">删除</button>
|
<button class="pear-btn pear-btn-xs tool-btn" lay-event="remove" permission="app.admin.admin.delete">删除</button>
|
||||||
{{# } }}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="/app/admin/component/layui/layui.js"></script>
|
<script src="/app/admin/component/layui/layui.js"></script>
|
||||||
@ -132,8 +130,6 @@
|
|||||||
},{
|
},{
|
||||||
title: "ID",
|
title: "ID",
|
||||||
field: "id",
|
field: "id",
|
||||||
width: 100,
|
|
||||||
sort: true,
|
|
||||||
},{
|
},{
|
||||||
title: "用户名",
|
title: "用户名",
|
||||||
field: "username",
|
field: "username",
|
||||||
@ -149,16 +145,13 @@
|
|||||||
field: "avatar",
|
field: "avatar",
|
||||||
templet: function (d) {
|
templet: function (d) {
|
||||||
return '<img src="'+encodeURI(d['avatar'])+'" style="max-width:32px;max-height:32px;" alt="" />'
|
return '<img src="'+encodeURI(d['avatar'])+'" style="max-width:32px;max-height:32px;" alt="" />'
|
||||||
},
|
}
|
||||||
width: 90,
|
|
||||||
},{
|
},{
|
||||||
title: "邮箱",
|
title: "邮箱",
|
||||||
field: "email",
|
field: "email",
|
||||||
hide: true,
|
|
||||||
},{
|
},{
|
||||||
title: "手机",
|
title: "手机",
|
||||||
field: "mobile",
|
field: "mobile",
|
||||||
hide: true,
|
|
||||||
},{
|
},{
|
||||||
title: "创建时间",
|
title: "创建时间",
|
||||||
field: "created_at",
|
field: "created_at",
|
||||||
@ -168,9 +161,6 @@
|
|||||||
field: "updated_at",
|
field: "updated_at",
|
||||||
hide: true,
|
hide: true,
|
||||||
},{
|
},{
|
||||||
title: "登录时间",
|
|
||||||
field: "login_at",
|
|
||||||
},{
|
|
||||||
title: "角色",
|
title: "角色",
|
||||||
field: "roles",
|
field: "roles",
|
||||||
templet: function (d) {
|
templet: function (d) {
|
||||||
@ -183,32 +173,6 @@
|
|||||||
return util.escape(items.join(","));
|
return util.escape(items.join(","));
|
||||||
}
|
}
|
||||||
},{
|
},{
|
||||||
title: "禁用",
|
|
||||||
field: "status",
|
|
||||||
templet: function (d) {
|
|
||||||
let field = "status";
|
|
||||||
form.on("switch("+field+")", function (data) {
|
|
||||||
let load = layer.load();
|
|
||||||
let postData = {};
|
|
||||||
postData[field] = data.elem.checked ? 1 : 0;
|
|
||||||
postData[PRIMARY_KEY] = this.value;
|
|
||||||
$.post(UPDATE_API, postData, function (res) {
|
|
||||||
layer.close(load);
|
|
||||||
if (res.code) {
|
|
||||||
return layui.popup.failure(res.msg, function () {
|
|
||||||
data.elem.checked = !data.elem.checked;
|
|
||||||
form.render();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return layui.popup.success("操作成功");
|
|
||||||
})
|
|
||||||
});
|
|
||||||
let checked = d[field] === 1 ? "checked" : "";
|
|
||||||
if (parent.Admin.Account.id === d.id) return '';
|
|
||||||
return '<input type="checkbox" value="'+util.escape(d[PRIMARY_KEY])+'" lay-filter="'+util.escape(field)+'" lay-skin="switch" lay-text="'+util.escape('')+'" '+checked+'/>';
|
|
||||||
},
|
|
||||||
width: 90,
|
|
||||||
},{
|
|
||||||
title: "操作",
|
title: "操作",
|
||||||
toolbar: "#table-bar",
|
toolbar: "#table-bar",
|
||||||
align: "center",
|
align: "center",
|
||||||
@ -252,9 +216,6 @@
|
|||||||
url: url,
|
url: url,
|
||||||
dateType: "json",
|
dateType: "json",
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
if (res.code) {
|
|
||||||
return layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
function travel(items) {
|
function travel(items) {
|
||||||
for (let k in items) {
|
for (let k in items) {
|
||||||
let item = items[k];
|
let item = items[k];
|
||||||
@ -300,9 +261,6 @@
|
|||||||
// 表格顶部搜索事件
|
// 表格顶部搜索事件
|
||||||
form.on("submit(table-query)", function(data) {
|
form.on("submit(table-query)", function(data) {
|
||||||
table.reload("data-table", {
|
table.reload("data-table", {
|
||||||
page: {
|
|
||||||
curr: 1
|
|
||||||
},
|
|
||||||
where: data.field
|
where: data.field
|
||||||
})
|
})
|
||||||
return false;
|
return false;
|
||||||
|
@ -11,14 +11,7 @@
|
|||||||
<form class="layui-form" action="">
|
<form class="layui-form" action="">
|
||||||
|
|
||||||
<div class="mainBox">
|
<div class="mainBox">
|
||||||
<div class="main-container mr-5">
|
<div class="main-container">
|
||||||
|
|
||||||
<div class="layui-form-item">
|
|
||||||
<label class="layui-form-label required">角色</label>
|
|
||||||
<div class="layui-input-block">
|
|
||||||
<div name="roles" id="roles" value=""></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label required">用户名</label>
|
<label class="layui-form-label required">用户名</label>
|
||||||
@ -44,7 +37,7 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">头像</label>
|
<label class="layui-form-label">头像</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<img class="img-3" src=""/>
|
<img style="max-width:90px;max-height:90px;" src=""/>
|
||||||
<input type="text" style="display:none" name="avatar" value="/app/admin/avatar.png" />
|
<input type="text" style="display:none" name="avatar" value="/app/admin/avatar.png" />
|
||||||
<button type="button" class="pear-btn pear-btn-primary pear-btn-sm" id="avatar">
|
<button type="button" class="pear-btn pear-btn-primary pear-btn-sm" id="avatar">
|
||||||
<i class="layui-icon layui-icon-upload"></i>上传图片
|
<i class="layui-icon layui-icon-upload"></i>上传图片
|
||||||
@ -69,6 +62,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">角色</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<div name="roles" id="roles" value="" ></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -125,30 +125,21 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 字段 角色 roles
|
// 字段 角色 roles
|
||||||
layui.use(["jquery", "xmSelect", "popup"], function() {
|
layui.use(["jquery", "xmSelect"], function() {
|
||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
url: "/app/admin/role/select?format=tree",
|
url: "/app/admin/role/select?format=select",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
let value = layui.$("#roles").attr("value");
|
let value = layui.$("#roles").attr("value");
|
||||||
let initValue = value ? value.split(",") : [];
|
let initValue = value ? value.split(",") : [];
|
||||||
if (!top.Admin.Account.isSupperAdmin) {
|
|
||||||
layui.each(res.data, function (k, v) {
|
|
||||||
v.disabled = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
layui.xmSelect.render({
|
layui.xmSelect.render({
|
||||||
el: "#roles",
|
el: "#roles",
|
||||||
name: "roles",
|
name: "roles",
|
||||||
initValue: initValue,
|
initValue: initValue,
|
||||||
data: res.data,
|
data: e.data,
|
||||||
layVerify: "required",
|
tree: {"show":true},
|
||||||
tree: {"show":true, expandedKeys:true, strict:false},
|
toolbar: {"show":true,"list":["ALL","CLEAR","REVERSE"]},
|
||||||
toolbar: {show:true, list:["ALL","CLEAR","REVERSE"]},
|
})
|
||||||
});
|
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -11,15 +11,8 @@
|
|||||||
<form class="layui-form">
|
<form class="layui-form">
|
||||||
|
|
||||||
<div class="mainBox">
|
<div class="mainBox">
|
||||||
<div class="main-container mr-5">
|
<div class="main-container">
|
||||||
|
|
||||||
<div class="layui-form-item">
|
|
||||||
<label class="layui-form-label required">角色</label>
|
|
||||||
<div class="layui-input-block">
|
|
||||||
<div name="roles" id="roles" value="" ></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label required">用户名</label>
|
<label class="layui-form-label required">用户名</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
@ -44,7 +37,7 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">头像</label>
|
<label class="layui-form-label">头像</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<img class="img-3" src=""/>
|
<img style="max-width:90px;max-height:90px;" src=""/>
|
||||||
<input type="text" style="display:none" name="avatar" value="" />
|
<input type="text" style="display:none" name="avatar" value="" />
|
||||||
<button type="button" class="pear-btn pear-btn-primary pear-btn-sm" id="avatar" permission="app.admin.upload.avatar">
|
<button type="button" class="pear-btn pear-btn-primary pear-btn-sm" id="avatar" permission="app.admin.upload.avatar">
|
||||||
<i class="layui-icon layui-icon-upload"></i>上传图片
|
<i class="layui-icon layui-icon-upload"></i>上传图片
|
||||||
@ -69,6 +62,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">角色</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<div name="roles" id="roles" value="" ></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -96,15 +96,15 @@
|
|||||||
const UPDATE_API = "/app/admin/admin/update";
|
const UPDATE_API = "/app/admin/admin/update";
|
||||||
|
|
||||||
// 获取数据库记录
|
// 获取数据库记录
|
||||||
layui.use(["form", "util", "popup"], function () {
|
layui.use(["form", "util"], function () {
|
||||||
let $ = layui.$;
|
let $ = layui.$;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: SELECT_API,
|
url: SELECT_API,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
|
|
||||||
// 给表单初始化数据
|
// 给表单初始化数据
|
||||||
layui.each(res.data[0], function (key, value) {
|
layui.each(e.data[0], function (key, value) {
|
||||||
let obj = $('*[name="'+key+'"]');
|
let obj = $('*[name="'+key+'"]');
|
||||||
if (key === "password") {
|
if (key === "password") {
|
||||||
obj.attr("placeholder", "不更新密码请留空");
|
obj.attr("placeholder", "不更新密码请留空");
|
||||||
@ -150,36 +150,23 @@
|
|||||||
// 字段 角色 roles
|
// 字段 角色 roles
|
||||||
layui.use(["jquery", "xmSelect"], function() {
|
layui.use(["jquery", "xmSelect"], function() {
|
||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
url: "/app/admin/role/select?format=tree",
|
url: "/app/admin/role/select?format=select",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
let value = layui.$("#roles").attr("value");
|
let value = layui.$("#roles").attr("value");
|
||||||
let initValue = value ? value.split(",") : [];
|
let initValue = value ? value.split(",") : [];
|
||||||
if (!top.Admin.Account.isSupperAdmin) {
|
|
||||||
layui.each(res.data, function (k, v) {
|
|
||||||
v.disabled = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
layui.xmSelect.render({
|
layui.xmSelect.render({
|
||||||
el: "#roles",
|
el: "#roles",
|
||||||
name: "roles",
|
name: "roles",
|
||||||
initValue: initValue,
|
initValue: initValue,
|
||||||
data: res.data,
|
data: e.data,
|
||||||
layVerify: "required",
|
tree: {show: true, expandedKeys: initValue},
|
||||||
tree: {show: true, expandedKeys: true, strict: false},
|
|
||||||
toolbar: {show: true, list: ["ALL","CLEAR","REVERSE"]},
|
toolbar: {show: true, list: ["ALL","CLEAR","REVERSE"]},
|
||||||
})
|
})
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// ajax产生错误
|
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">网站Logo</label>
|
<label class="layui-form-label">网站Logo</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<img class="img-3" src=""/>
|
<img style="max-width:90px;max-height:90px;" src=""/>
|
||||||
<input type="text" style="display:none" name="image" value="/app/admin/admin/avatar.png" />
|
<input type="text" style="display:none" name="image" value="/app/admin/admin/avatar.png" />
|
||||||
<button type="button" class="pear-btn pear-btn-primary pear-btn-sm" id="image" permission="app.admin.upload.avatar">
|
<button type="button" class="pear-btn pear-btn-primary pear-btn-sm" id="image" permission="app.admin.upload.avatar">
|
||||||
<i class="layui-icon layui-icon-upload"></i>上传图片
|
<i class="layui-icon layui-icon-upload"></i>上传图片
|
||||||
@ -290,9 +290,6 @@
|
|||||||
url: "/app/admin/config/get",
|
url: "/app/admin/config/get",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
if (res.code) {
|
|
||||||
return layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
form.val("baseInfo", res.logo);
|
form.val("baseInfo", res.logo);
|
||||||
$("#image").prev().val(res.logo.image).prev().attr("src", res.logo.image);
|
$("#image").prev().val(res.logo.image).prev().attr("src", res.logo.image);
|
||||||
form.val("menuInfo", res.menu);
|
form.val("menuInfo", res.menu);
|
||||||
|
@ -156,9 +156,6 @@
|
|||||||
// 表格顶部搜索事件
|
// 表格顶部搜索事件
|
||||||
form.on("submit(table-query)", function(data) {
|
form.on("submit(table-query)", function(data) {
|
||||||
table.reload("data-table", {
|
table.reload("data-table", {
|
||||||
page: {
|
|
||||||
curr: 1
|
|
||||||
},
|
|
||||||
where: data.field
|
where: data.field
|
||||||
})
|
})
|
||||||
return false;
|
return false;
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
<form class="layui-form" action="" lay-filter="create-dict-form">
|
<form class="layui-form" action="" lay-filter="create-dict-form">
|
||||||
|
|
||||||
<div class="mainBox">
|
<div class="mainBox">
|
||||||
<div class="main-container mr-5">
|
<div class="main-container">
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
<form class="layui-form" action="" lay-filter="create-dict-form">
|
<form class="layui-form" action="" lay-filter="create-dict-form">
|
||||||
|
|
||||||
<div class="mainBox">
|
<div class="mainBox">
|
||||||
<div class="main-container mr-5">
|
<div class="main-container">
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
@ -135,10 +135,6 @@
|
|||||||
layui.each(data, function (k, v) {
|
layui.each(data, function (k, v) {
|
||||||
data[k]["_field_id"] = _field_id++;
|
data[k]["_field_id"] = _field_id++;
|
||||||
})
|
})
|
||||||
// ajax产生错误
|
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
<title>主页</title>
|
<title>主页</title>
|
||||||
<!-- 依 赖 样 式 -->
|
<!-- 依 赖 样 式 -->
|
||||||
<link rel="stylesheet" href="/app/admin/component/pear/css/pear.css" />
|
<link rel="stylesheet" href="component/pear/css/pear.css" />
|
||||||
<!-- 加 载 样 式 -->
|
<!-- 加 载 样 式 -->
|
||||||
<link rel="stylesheet" href="/app/admin/admin/css/loader.css" />
|
<link rel="stylesheet" href="admin/css/loader.css" />
|
||||||
<!-- 布 局 样 式 -->
|
<!-- 布 局 样 式 -->
|
||||||
<link rel="stylesheet" href="/app/admin/admin/css/admin.css" />
|
<link rel="stylesheet" href="admin/css/admin.css" />
|
||||||
<!-- 重置样式 -->
|
<!-- 重置样式 -->
|
||||||
<link rel="stylesheet" href="/app/admin/admin/css/reset.css" />
|
<link rel="stylesheet" href="admin/css/reset.css" />
|
||||||
</head>
|
</head>
|
||||||
<!-- 结 构 代 码 -->
|
<!-- 结 构 代 码 -->
|
||||||
<body class="layui-layout-body pear-admin">
|
<body class="layui-layout-body pear-admin">
|
||||||
@ -43,7 +43,7 @@
|
|||||||
<a class="layui-icon layui-icon-username" href="javascript:;"></a>
|
<a class="layui-icon layui-icon-username" href="javascript:;"></a>
|
||||||
<!-- 功 能 菜 单 -->
|
<!-- 功 能 菜 单 -->
|
||||||
<dl class="layui-nav-child">
|
<dl class="layui-nav-child">
|
||||||
<dd><a user-menu-url="/app/admin/account/index" user-menu-id="10" user-menu-title="基本资料">基本资料</a></dd>
|
<dd><a user-menu-url="/app/admin/account/index" user-menu-id="11" user-menu-title="基本资料">基本资料</a></dd>
|
||||||
<dd><a href="javascript:void(0);" class="logout">注销登录</a></dd>
|
<dd><a href="javascript:void(0);" class="logout">注销登录</a></dd>
|
||||||
</dl>
|
</dl>
|
||||||
</li>
|
</li>
|
||||||
@ -90,16 +90,10 @@
|
|||||||
<a href="#" class="layui-icon layui-icon-shrink-right"></a>
|
<a href="#" class="layui-icon layui-icon-shrink-right"></a>
|
||||||
</div>
|
</div>
|
||||||
<!-- 依 赖 脚 本 -->
|
<!-- 依 赖 脚 本 -->
|
||||||
<script src="/app/admin/component/layui/layui.js"></script>
|
<script src="component/layui/layui.js"></script>
|
||||||
<script src="/app/admin/component/pear/pear.js"></script>
|
<script src="component/pear/pear.js"></script>
|
||||||
<!-- 框 架 初 始 化 -->
|
<!-- 框 架 初 始 化 -->
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
// Admin
|
|
||||||
window.Admin = {
|
|
||||||
Account: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
layui.use(["admin","jquery","popup","drawer"], function() {
|
layui.use(["admin","jquery","popup","drawer"], function() {
|
||||||
var $ = layui.$;
|
var $ = layui.$;
|
||||||
var admin = layui.admin;
|
var admin = layui.admin;
|
||||||
@ -127,18 +121,9 @@
|
|||||||
return false;
|
return false;
|
||||||
})
|
})
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: "/app/admin/account/info",
|
|
||||||
dataType: 'json',
|
|
||||||
success: function (res) {
|
|
||||||
window.Admin.Account = res.data;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 消息点击回调
|
// 消息点击回调
|
||||||
//admin.message(function(id, title, context, form) {});
|
//admin.message(function(id, title, context, form) {});
|
||||||
});
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
69
src/plugin/admin/app/view/plugin/auth-login.html
Normal file
69
src/plugin/admin/app/view/plugin/auth-login.html
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
|
<title>登录 workerman.net 官网</title>
|
||||||
|
<link rel="stylesheet" href="/app/admin/component/pear/css/pear.css" />
|
||||||
|
<link rel="stylesheet" href="/app/admin/admin/css/pages/login.css" />
|
||||||
|
</head>
|
||||||
|
<body style="background: #fff !important;">
|
||||||
|
<form class="layui-form" style="margin-top:36px !important;">
|
||||||
|
<div class="layui-form-item pear-border" style="background:#ebf2f8;border:1px solid #ccddf6;padding:10px;border-radius: 4px;">
|
||||||
|
<div class="pear-text">注意此处登录 <a class="pear-text" href="https://www.workerman.net" target="_blank"><b>workerman.net</b></a> 官网账号</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<input lay-verify="required" hover class="layui-input" type="text" name="username" value="" />
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<input lay-verify="required" hover class="layui-input" type="password" name="password" value="" />
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<input hover lay-verify="required" class="code layui-input layui-input-inline" name="captcha" />
|
||||||
|
<img class="codeImage" width="120px"/>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<button type="submit" class="pear-btn pear-btn-primary login" lay-submit lay-filter="login">
|
||||||
|
登录
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script src="/app/admin/component/layui/layui.js"></script>
|
||||||
|
<script src="/app/admin/component/pear/pear.js"></script>
|
||||||
|
<script src="/app/admin/admin/js/permission.js"></script>
|
||||||
|
<script>
|
||||||
|
layui.use(["form", "button", "popup", "layer"], function() {
|
||||||
|
var $ = layui.$, layer = layui.layer, form = layui.form;
|
||||||
|
function switchCaptcha() {
|
||||||
|
$(".codeImage").attr("src", "/app/admin/plugin/captcha?v=" + new Date().getTime());
|
||||||
|
}
|
||||||
|
switchCaptcha();
|
||||||
|
form.on("submit(login)", function (data) {
|
||||||
|
layer.load();
|
||||||
|
$.ajax({
|
||||||
|
url: "/app/admin/plugin/login",
|
||||||
|
type: "POST",
|
||||||
|
data: data.field,
|
||||||
|
success: function (res) {
|
||||||
|
layer.closeAll("loading");
|
||||||
|
if (!res.code) {
|
||||||
|
layui.popup.success("登录成功", function () {
|
||||||
|
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
layui.popup.failure(res.msg, function () {
|
||||||
|
switchCaptcha();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
$(".codeImage").on("click", function () {
|
||||||
|
switchCaptcha();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
145
src/plugin/admin/app/view/plugin/index.html
Normal file
145
src/plugin/admin/app/view/plugin/index.html
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>应用插件管理</title>
|
||||||
|
<link rel="stylesheet" href="/app/admin/component/pear/css/pear.css" />
|
||||||
|
<link rel="stylesheet" href="/app/admin/admin/css/reset.css" />
|
||||||
|
</head>
|
||||||
|
<body class="pear-container">
|
||||||
|
|
||||||
|
<div class="layui-card">
|
||||||
|
<div class="layui-card-body">
|
||||||
|
<table id="data-table" lay-filter="data-table"></table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/html" id="install">
|
||||||
|
{{# if(!d.installed){ }}
|
||||||
|
<button class="pear-btn pear-btn-xs pear-btn-primary" onclick="install('{{ d.name }}','{{ d.version }}')">
|
||||||
|
安装
|
||||||
|
</button>
|
||||||
|
{{# }else{ }}
|
||||||
|
{{# if(d.installed !== d.version){ }}
|
||||||
|
<button class="pear-btn pear-btn-xs pear-btn-success" onclick="install('{{ d.name }}','{{ d.version }}')">
|
||||||
|
升级
|
||||||
|
</button>
|
||||||
|
{{# } }}
|
||||||
|
{{# if(d.name !== "admin"){ }}
|
||||||
|
<button class="pear-btn pear-btn-xs pear-btn-danger" onclick="uninstall('{{ d.name }}','{{ d.installed }}')">
|
||||||
|
卸载
|
||||||
|
</button>
|
||||||
|
{{# } }}
|
||||||
|
{{# } }}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script src="/app/admin/component/layui/layui.js"></script>
|
||||||
|
<script src="/app/admin/component/pear/pear.js"></script>
|
||||||
|
<script src="/app/admin/admin/js/permission.js"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
const SELECT_API = "/app/admin/plugin/list";
|
||||||
|
const AUTH_URL = "/app/admin/plugin/login";
|
||||||
|
const SCHEMA_API = "/app/admin/plugin/schema";
|
||||||
|
|
||||||
|
layui.use(["table", "form","common", "popup"], function() {
|
||||||
|
let table = layui.table;
|
||||||
|
let form = layui.form;
|
||||||
|
let $ = layui.$;
|
||||||
|
let common = layui.common;
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: SCHEMA_API,
|
||||||
|
dataType: "json",
|
||||||
|
success: function (e) {
|
||||||
|
let cols = e.data;
|
||||||
|
layui.each(cols, function (k, v) {
|
||||||
|
if (v.field === "installed") {
|
||||||
|
cols[k].templet = "#install";
|
||||||
|
}
|
||||||
|
})
|
||||||
|
function render()
|
||||||
|
{
|
||||||
|
table.render({
|
||||||
|
elem: "#data-table",
|
||||||
|
url: SELECT_API,
|
||||||
|
page: true,
|
||||||
|
cols: [cols],
|
||||||
|
skin: "line",
|
||||||
|
size: "lg",
|
||||||
|
autoSort: false,
|
||||||
|
defaultToolbar: [{
|
||||||
|
title: "刷新",
|
||||||
|
layEvent: "refresh",
|
||||||
|
icon: "layui-icon-refresh",
|
||||||
|
}, "filter", "print", "exports"]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
window.install = function(name, version) {
|
||||||
|
let loading = layer.load();
|
||||||
|
$.ajax({
|
||||||
|
url: "/app/admin/plugin/install",
|
||||||
|
type: "POST",
|
||||||
|
dataType: "json",
|
||||||
|
data: {name, version},
|
||||||
|
success: function (res) {
|
||||||
|
if (res.code) {
|
||||||
|
return layui.popup.failure(res.msg);
|
||||||
|
}
|
||||||
|
// 需要登录官网
|
||||||
|
if (res.data && res.data.code === 401) {
|
||||||
|
layer.open({
|
||||||
|
type: 2,
|
||||||
|
title: "登录 workerman.net 官网",
|
||||||
|
shade: 0.1,
|
||||||
|
area: [common.isModile()?"100%":"500px", common.isModile()?"100%":"450px"],
|
||||||
|
content: AUTH_URL
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return layui.popup.success("安装成功", function () {
|
||||||
|
parent.location.reload();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
complete: function () {
|
||||||
|
layer.close(loading);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
window.uninstall = function(name, version) {
|
||||||
|
layer.confirm("确定卸载?", {
|
||||||
|
icon: 3,
|
||||||
|
title: "提示"
|
||||||
|
}, function(index) {
|
||||||
|
layer.close(index);
|
||||||
|
let loading = layer.load();
|
||||||
|
$.ajax({
|
||||||
|
url: "/app/admin/plugin/uninstall",
|
||||||
|
type: "POST",
|
||||||
|
dataType: "json",
|
||||||
|
data: {name, version},
|
||||||
|
success: function (res) {
|
||||||
|
if (res.code) {
|
||||||
|
return layui.popup.failure(res.msg);
|
||||||
|
}
|
||||||
|
return layui.popup.success("卸载成功", function () {
|
||||||
|
parent.location.reload();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
complete: function () {
|
||||||
|
layer.close(loading);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -10,7 +10,44 @@
|
|||||||
<body class="pear-container">
|
<body class="pear-container">
|
||||||
|
|
||||||
<!-- 顶部查询表单 -->
|
<!-- 顶部查询表单 -->
|
||||||
|
<div class="layui-card">
|
||||||
|
<div class="layui-card-body">
|
||||||
|
<form class="layui-form top-search-from">
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">角色名</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="name" value="" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">创建时间</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<div class="layui-input-block" id="created_at">
|
||||||
|
<input type="text" autocomplete="off" name="created_at[]" id="created_at-date-start" class="layui-input inline-block" placeholder="开始时间">
|
||||||
|
-
|
||||||
|
<input type="text" autocomplete="off" name="created_at[]" id="created_at-date-end" class="layui-input inline-block" placeholder="结束时间">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item layui-inline">
|
||||||
|
<label class="layui-form-label"></label>
|
||||||
|
<button class="pear-btn pear-btn-md pear-btn-primary" lay-submit lay-filter="table-query">
|
||||||
|
<i class="layui-icon layui-icon-search"></i>查询
|
||||||
|
</button>
|
||||||
|
<button type="reset" class="pear-btn pear-btn-md" lay-submit lay-filter="table-reset">
|
||||||
|
<i class="layui-icon layui-icon-refresh"></i>重置
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="toggle-btn">
|
||||||
|
<a class="layui-hide">展开<i class="layui-icon layui-icon-down"></i></a>
|
||||||
|
<a class="layui-hide">收起<i class="layui-icon layui-icon-up"></i></a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 数据表格 -->
|
<!-- 数据表格 -->
|
||||||
<div class="layui-card">
|
<div class="layui-card">
|
||||||
@ -31,17 +68,14 @@
|
|||||||
|
|
||||||
<!-- 表格行工具栏 -->
|
<!-- 表格行工具栏 -->
|
||||||
<script type="text/html" id="table-bar">
|
<script type="text/html" id="table-bar">
|
||||||
{{# if(d.id!==1&&d.pid&&!d.isRoot){ }}
|
|
||||||
<button class="pear-btn pear-btn-xs tool-btn" lay-event="edit" permission="app.admin.role.update">编辑</button>
|
<button class="pear-btn pear-btn-xs tool-btn" lay-event="edit" permission="app.admin.role.update">编辑</button>
|
||||||
<button class="pear-btn pear-btn-xs tool-btn" lay-event="remove" permission="app.admin.role.delete">删除</button>
|
<button class="pear-btn pear-btn-xs tool-btn" lay-event="remove" permission="app.admin.role.delete">删除</button>
|
||||||
{{# } }}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="/app/admin/component/layui/layui.js"></script>
|
<script src="/app/admin/component/layui/layui.js"></script>
|
||||||
<script src="/app/admin/component/pear/pear.js"></script>
|
<script src="/app/admin/component/pear/pear.js"></script>
|
||||||
<script src="/app/admin/admin/js/permission.js"></script>
|
<script src="/app/admin/admin/js/permission.js"></script>
|
||||||
<script src="/app/admin/admin/js/common.js"></script>
|
<script src="/app/admin/admin/js/common.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
// 相关常量
|
// 相关常量
|
||||||
@ -52,9 +86,16 @@
|
|||||||
const INSERT_URL = "/app/admin/role/insert";
|
const INSERT_URL = "/app/admin/role/insert";
|
||||||
const UPDATE_URL = "/app/admin/role/update";
|
const UPDATE_URL = "/app/admin/role/update";
|
||||||
|
|
||||||
|
// 字段 创建时间 created_at
|
||||||
|
layui.use(["laydate"], function() {
|
||||||
|
layui.laydate.render({
|
||||||
|
elem: "#created_at",
|
||||||
|
range: ["#created_at-date-start", "#created_at-date-end"],
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
// 表格渲染
|
// 表格渲染
|
||||||
layui.use(["table", "treetable", "form", "common", "popup", "util"], function() {
|
layui.use(["table", "form", "common", "popup", "util"], function() {
|
||||||
let treeTable = layui.treetable;
|
|
||||||
let table = layui.table;
|
let table = layui.table;
|
||||||
let form = layui.form;
|
let form = layui.form;
|
||||||
let $ = layui.$;
|
let $ = layui.$;
|
||||||
@ -66,11 +107,12 @@
|
|||||||
{
|
{
|
||||||
type: "checkbox"
|
type: "checkbox"
|
||||||
},{
|
},{
|
||||||
title: "角色组",
|
|
||||||
field: "name",
|
|
||||||
},{
|
|
||||||
title: "主键",
|
title: "主键",
|
||||||
field: "id",
|
field: "id",
|
||||||
|
hide: true,
|
||||||
|
},{
|
||||||
|
title: "角色名",
|
||||||
|
field: "name",
|
||||||
},{
|
},{
|
||||||
title: "权限",
|
title: "权限",
|
||||||
field: "rules",
|
field: "rules",
|
||||||
@ -82,65 +124,50 @@
|
|||||||
items.push(apiResults[field][v] || v);
|
items.push(apiResults[field][v] || v);
|
||||||
});
|
});
|
||||||
return util.escape(items.join(","));
|
return util.escape(items.join(","));
|
||||||
},
|
}
|
||||||
hide: true,
|
|
||||||
},{
|
},{
|
||||||
title: "创建时间",
|
title: "创建时间",
|
||||||
field: "created_at",
|
field: "created_at",
|
||||||
},{
|
},{
|
||||||
title: "更新时间",
|
title: "更新时间",
|
||||||
field: "updated_at",
|
field: "updated_at",
|
||||||
},{
|
|
||||||
title: "父级",
|
|
||||||
field: "pid",
|
|
||||||
templet: function (d) {
|
|
||||||
let field = "pid";
|
|
||||||
if (typeof d[field] == "undefined") return "";
|
|
||||||
let items = [];
|
|
||||||
layui.each((d[field] + "").split(","), function (k , v) {
|
|
||||||
items.push(apiResults[field][v] || v);
|
|
||||||
});
|
|
||||||
return util.escape(items.join(","));
|
|
||||||
},
|
|
||||||
hide: true,
|
|
||||||
},{
|
},{
|
||||||
title: "操作",
|
title: "操作",
|
||||||
toolbar: "#table-bar",
|
toolbar: "#table-bar",
|
||||||
align: "center",
|
align: "center",
|
||||||
fixed: "right",
|
fixed: "right",
|
||||||
width: 120,
|
width: 130,
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
// 渲染表格
|
// 渲染表格
|
||||||
function render()
|
function render()
|
||||||
{
|
{
|
||||||
treeTable.render({
|
table.render({
|
||||||
elem: "#data-table",
|
elem: "#data-table",
|
||||||
url: SELECT_API,
|
url: SELECT_API,
|
||||||
treeColIndex: 1,
|
page: true,
|
||||||
treeIdName: "id",
|
cols: [cols],
|
||||||
treePidName: "pid",
|
skin: "line",
|
||||||
treeDefaultClose: false,
|
size: "lg",
|
||||||
cols: [cols],
|
toolbar: "#table-toolbar",
|
||||||
skin: "line",
|
autoSort: false,
|
||||||
size: "lg",
|
defaultToolbar: [{
|
||||||
toolbar: "#table-toolbar",
|
title: "刷新",
|
||||||
defaultToolbar: [{
|
layEvent: "refresh",
|
||||||
title: "刷新",
|
icon: "layui-icon-refresh",
|
||||||
layEvent: "refresh",
|
}, "filter", "print", "exports"],
|
||||||
icon: "layui-icon-refresh",
|
done: function () {
|
||||||
}, "filter", "print", "exports"]
|
layer.photos({photos: 'div[lay-id="data-table"]', anim: 5});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取表格中下拉或树形组件数据
|
// 获取表格中下拉或树形组件数据
|
||||||
let apis = [];
|
let apis = [];
|
||||||
apis.push(["rules", "/app/admin/rule/get?type=0,1,2"]);
|
apis.push(["rules", "/app/admin/rule/get?type=0,1,2"]);
|
||||||
apis.push(["pid", "/app/admin/role/select?format=tree"]);
|
|
||||||
let apiResults = {};
|
let apiResults = {};
|
||||||
apiResults["rules"] = [];
|
apiResults["rules"] = [];
|
||||||
apiResults["pid"] = [];
|
|
||||||
let count = apis.length;
|
let count = apis.length;
|
||||||
layui.each(apis, function (k, item) {
|
layui.each(apis, function (k, item) {
|
||||||
let [field, url] = item;
|
let [field, url] = item;
|
||||||
@ -148,9 +175,6 @@
|
|||||||
url: url,
|
url: url,
|
||||||
dateType: "json",
|
dateType: "json",
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
if (res.code) {
|
|
||||||
return layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
function travel(items) {
|
function travel(items) {
|
||||||
for (let k in items) {
|
for (let k in items) {
|
||||||
let item = items[k];
|
let item = items[k];
|
||||||
@ -196,9 +220,6 @@
|
|||||||
// 表格顶部搜索事件
|
// 表格顶部搜索事件
|
||||||
form.on("submit(table-query)", function(data) {
|
form.on("submit(table-query)", function(data) {
|
||||||
table.reload("data-table", {
|
table.reload("data-table", {
|
||||||
page: {
|
|
||||||
curr: 1
|
|
||||||
},
|
|
||||||
where: data.field
|
where: data.field
|
||||||
})
|
})
|
||||||
return false;
|
return false;
|
||||||
@ -289,7 +310,9 @@
|
|||||||
|
|
||||||
// 刷新表格数据
|
// 刷新表格数据
|
||||||
window.refreshTable = function(param) {
|
window.refreshTable = function(param) {
|
||||||
treeTable.reload("#data-table");
|
table.reloadData("data-table", {
|
||||||
|
scrollPos: "fixed"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -11,15 +11,8 @@
|
|||||||
<form class="layui-form" action="">
|
<form class="layui-form" action="">
|
||||||
|
|
||||||
<div class="mainBox">
|
<div class="mainBox">
|
||||||
<div class="main-container mr-5">
|
<div class="main-container">
|
||||||
|
|
||||||
<div class="layui-form-item">
|
|
||||||
<label class="layui-form-label">父级</label>
|
|
||||||
<div class="layui-input-block">
|
|
||||||
<div name="pid" id="pid" value="1" ></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label required">角色名</label>
|
<label class="layui-form-label required">角色名</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
@ -54,73 +47,31 @@
|
|||||||
<script src="/app/admin/component/layui/layui.js"></script>
|
<script src="/app/admin/component/layui/layui.js"></script>
|
||||||
<script src="/app/admin/component/pear/pear.js"></script>
|
<script src="/app/admin/component/pear/pear.js"></script>
|
||||||
<script src="/app/admin/admin/js/permission.js"></script>
|
<script src="/app/admin/admin/js/permission.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
// 相关接口
|
// 相关接口
|
||||||
const INSERT_API = "/app/admin/role/insert";
|
const INSERT_API = "/app/admin/role/insert";
|
||||||
|
|
||||||
// 字段 权限 rules
|
// 字段 权限 rules
|
||||||
layui.use(["jquery", "xmSelect", "popup"], function() {
|
layui.use(["jquery", "xmSelect"], function() {
|
||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
url: "/app/admin/role/rules?id=1",
|
url: "/app/admin/rule/get?type=0,1,2",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
let value = layui.$("#rules").attr("value");
|
let value = layui.$("#rules").attr("value");
|
||||||
let initValue = value ? value.split(",") : [];
|
let initValue = value ? value.split(",") : [];
|
||||||
layui.xmSelect.render({
|
layui.xmSelect.render({
|
||||||
el: "#rules",
|
el: "#rules",
|
||||||
name: "rules",
|
name: "rules",
|
||||||
initValue: initValue,
|
initValue: initValue,
|
||||||
data: res.data,
|
data: e.data,
|
||||||
tree: {"show":true,expandedKeys:initValue},
|
tree: {"show":true},
|
||||||
toolbar: {show:true,list:["ALL","CLEAR","REVERSE"]},
|
toolbar: {"show":true,"list":["ALL","CLEAR","REVERSE"]},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 字段 父级 pid
|
|
||||||
layui.use(["jquery", "xmSelect", "popup"], function() {
|
|
||||||
layui.$.ajax({
|
|
||||||
url: "/app/admin/role/select?format=tree",
|
|
||||||
dataType: "json",
|
|
||||||
success: function (res) {
|
|
||||||
let value = layui.$("#pid").attr("value");
|
|
||||||
let initValue = value ? value.split(",") : [];
|
|
||||||
layui.xmSelect.render({
|
|
||||||
el: "#pid",
|
|
||||||
name: "pid",
|
|
||||||
initValue: initValue,
|
|
||||||
tips: "请选择",
|
|
||||||
data: res.data,
|
|
||||||
value: "0",
|
|
||||||
model: {"icon":"hidden","label":{"type":"text"}},
|
|
||||||
clickClose: true,
|
|
||||||
radio: true,
|
|
||||||
tree: {show: true,"strict":false,"clickCheck":true,"clickExpand":false,expandedKeys:true},
|
|
||||||
on: function(data){
|
|
||||||
let id = data.arr[0] ? data.arr[0].value : "";
|
|
||||||
if (!id) return;
|
|
||||||
layui.$.ajax({
|
|
||||||
url: '/app/admin/role/rules?id=' + id,
|
|
||||||
dataType: 'json',
|
|
||||||
success: function (res) {
|
|
||||||
if (res.code) {
|
|
||||||
return layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
layui.xmSelect.get('#rules')[0].update({data:res.data});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//提交事件
|
//提交事件
|
||||||
layui.use(["form", "popup"], function () {
|
layui.use(["form", "popup"], function () {
|
||||||
layui.form.on("submit(save)", function (data) {
|
layui.form.on("submit(save)", function (data) {
|
||||||
|
@ -11,15 +11,8 @@
|
|||||||
<form class="layui-form">
|
<form class="layui-form">
|
||||||
|
|
||||||
<div class="mainBox">
|
<div class="mainBox">
|
||||||
<div class="main-container mr-5">
|
<div class="main-container">
|
||||||
|
|
||||||
<div class="layui-form-item">
|
|
||||||
<label class="layui-form-label">父级</label>
|
|
||||||
<div class="layui-input-block">
|
|
||||||
<div name="pid" id="pid" value="" ></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label required">角色名</label>
|
<label class="layui-form-label required">角色名</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
@ -53,7 +46,6 @@
|
|||||||
<script src="/app/admin/component/layui/layui.js"></script>
|
<script src="/app/admin/component/layui/layui.js"></script>
|
||||||
<script src="/app/admin/component/pear/pear.js"></script>
|
<script src="/app/admin/component/pear/pear.js"></script>
|
||||||
<script src="/app/admin/admin/js/permission.js"></script>
|
<script src="/app/admin/admin/js/permission.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
// 相关接口
|
// 相关接口
|
||||||
@ -62,15 +54,15 @@
|
|||||||
const UPDATE_API = "/app/admin/role/update";
|
const UPDATE_API = "/app/admin/role/update";
|
||||||
|
|
||||||
// 获取数据库记录
|
// 获取数据库记录
|
||||||
layui.use(["form", "util", "popup"], function () {
|
layui.use(["form", "util"], function () {
|
||||||
let $ = layui.$;
|
let $ = layui.$;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: SELECT_API,
|
url: SELECT_API,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
|
|
||||||
// 给表单初始化数据
|
// 给表单初始化数据
|
||||||
layui.each(res.data[0], function (key, value) {
|
layui.each(e.data[0], function (key, value) {
|
||||||
let obj = $('*[name="'+key+'"]');
|
let obj = $('*[name="'+key+'"]');
|
||||||
if (key === "password") {
|
if (key === "password") {
|
||||||
obj.attr("placeholder", "不更新密码请留空");
|
obj.attr("placeholder", "不更新密码请留空");
|
||||||
@ -85,74 +77,25 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 字段 权限 rules
|
// 字段 权限 rules
|
||||||
layui.use(["jquery", "xmSelect", "popup"], function() {
|
layui.use(["jquery", "xmSelect"], function() {
|
||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
url: "/app/admin/role/rules?id=" + res.data[0].pid,
|
url: "/app/admin/rule/get?type=0,1,2",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
let value = layui.$("#rules").attr("value");
|
let value = layui.$("#rules").attr("value");
|
||||||
let initValue = value ? value.split(",") : [];
|
let initValue = value ? value.split(",") : [];
|
||||||
layui.xmSelect.render({
|
layui.xmSelect.render({
|
||||||
el: "#rules",
|
el: "#rules",
|
||||||
name: "rules",
|
name: "rules",
|
||||||
initValue: initValue,
|
initValue: initValue,
|
||||||
data: res.data,
|
data: e.data,
|
||||||
tree: {"show":true,expandedKeys:initValue},
|
tree: {show: true, expandedKeys: initValue},
|
||||||
toolbar: {show:true,list:["ALL","CLEAR","REVERSE"]},
|
toolbar: {show: true, list: ["ALL","CLEAR","REVERSE"]},
|
||||||
})
|
})
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 字段 父级角色组 pid
|
|
||||||
layui.use(["jquery", "xmSelect", "popup"], function() {
|
|
||||||
layui.$.ajax({
|
|
||||||
url: "/app/admin/role/select?format=tree",
|
|
||||||
dataType: "json",
|
|
||||||
success: function (res) {
|
|
||||||
let value = layui.$("#pid").attr("value");
|
|
||||||
let initValue = value ? value.split(",") : [];
|
|
||||||
layui.xmSelect.render({
|
|
||||||
el: "#pid",
|
|
||||||
name: "pid",
|
|
||||||
initValue: initValue,
|
|
||||||
tips: "请选择",
|
|
||||||
toolbar: {show: true, list: ["CLEAR"]},
|
|
||||||
data: res.data,
|
|
||||||
value: "0",
|
|
||||||
model: {"icon":"hidden","label":{"type":"text"}},
|
|
||||||
clickClose: true,
|
|
||||||
radio: true,
|
|
||||||
tree: {show: true,"strict":false,"clickCheck":true,"clickExpand":false,expandedKeys:true},
|
|
||||||
on: function(data){
|
|
||||||
let id = data.arr[0] ? data.arr[0].value : "";
|
|
||||||
if (!id) return;
|
|
||||||
layui.$.ajax({
|
|
||||||
url: '/app/admin/role/rules?id=' + id,
|
|
||||||
dataType: 'json',
|
|
||||||
success: function (res) {
|
|
||||||
if (res.code) {
|
|
||||||
return layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
layui.xmSelect.get('#rules')[0].update({data:res.data});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// ajax产生错误
|
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -9,6 +9,33 @@
|
|||||||
</head>
|
</head>
|
||||||
<body class="pear-container">
|
<body class="pear-container">
|
||||||
|
|
||||||
|
<!-- 顶部搜索表单 -->
|
||||||
|
<div class="layui-card">
|
||||||
|
<div class="layui-card-body">
|
||||||
|
<form class="layui-form top-search-from">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">标题</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="title" value="" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item layui-inline">
|
||||||
|
<label class="layui-form-label"></label>
|
||||||
|
<button class="pear-btn pear-btn-md pear-btn-primary" lay-submit lay-filter="table-query">
|
||||||
|
<i class="layui-icon layui-icon-search"></i>查询
|
||||||
|
</button>
|
||||||
|
<button type="reset" class="pear-btn pear-btn-md" lay-submit lay-filter="table-reset">
|
||||||
|
<i class="layui-icon layui-icon-refresh"></i>重置
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="toggle-btn">
|
||||||
|
<a class="layui-hide">展开<i class="layui-icon layui-icon-down"></i></a>
|
||||||
|
<a class="layui-hide">收起<i class="layui-icon layui-icon-up"></i></a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 数据表格 -->
|
<!-- 数据表格 -->
|
||||||
<div class="layui-card">
|
<div class="layui-card">
|
||||||
<div class="layui-card-body">
|
<div class="layui-card-body">
|
||||||
@ -130,6 +157,7 @@
|
|||||||
elem: "#data-table",
|
elem: "#data-table",
|
||||||
url: SELECT_API,
|
url: SELECT_API,
|
||||||
treeColIndex: 1,
|
treeColIndex: 1,
|
||||||
|
treeSpid: 0,
|
||||||
treeIdName: "id",
|
treeIdName: "id",
|
||||||
treePidName: "pid",
|
treePidName: "pid",
|
||||||
treeDefaultClose: true,
|
treeDefaultClose: true,
|
||||||
@ -158,9 +186,6 @@
|
|||||||
url: url,
|
url: url,
|
||||||
dateType: "json",
|
dateType: "json",
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
if (res.code) {
|
|
||||||
return layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
function travel(items) {
|
function travel(items) {
|
||||||
for (let k in items) {
|
for (let k in items) {
|
||||||
let item = items[k];
|
let item = items[k];
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<form class="layui-form" action="">
|
<form class="layui-form" action="">
|
||||||
|
|
||||||
<div class="mainBox">
|
<div class="mainBox">
|
||||||
<div class="main-container mr-5">
|
<div class="main-container">
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label required">标题</label>
|
<label class="layui-form-label required">标题</label>
|
||||||
@ -103,11 +103,11 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 上级菜单
|
// 上级菜单
|
||||||
layui.use(["jquery", "xmSelect", "popup"], function() {
|
layui.use(["jquery", "xmSelect"], function() {
|
||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
url: "/app/admin/rule/select?format=tree&type=0,1",
|
url: "/app/admin/rule/select?format=tree&type=0,1",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
let value = layui.$("#pid").attr("value");
|
let value = layui.$("#pid").attr("value");
|
||||||
let initValue = value ? value.split(",") : [];
|
let initValue = value ? value.split(",") : [];
|
||||||
layui.xmSelect.render({
|
layui.xmSelect.render({
|
||||||
@ -116,16 +116,13 @@
|
|||||||
initValue: initValue,
|
initValue: initValue,
|
||||||
tips: "无",
|
tips: "无",
|
||||||
toolbar: {show: true, list: ["CLEAR"]},
|
toolbar: {show: true, list: ["CLEAR"]},
|
||||||
data: res.data,
|
data: e.data,
|
||||||
value: "0",
|
value: "0",
|
||||||
model: {"icon":"hidden","label":{"type":"text"}},
|
model: {"icon":"hidden","label":{"type":"text"}},
|
||||||
clickClose: true,
|
clickClose: true,
|
||||||
radio: true,
|
radio: true,
|
||||||
tree: {show: true,"strict":false,"clickCheck":true,"clickExpand":false},
|
tree: {show: true,"strict":false,"clickCheck":true,"clickExpand":false},
|
||||||
});
|
})
|
||||||
if (res.code) {
|
|
||||||
return layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<form class="layui-form">
|
<form class="layui-form">
|
||||||
|
|
||||||
<div class="mainBox">
|
<div class="mainBox">
|
||||||
<div class="main-container mr-5">
|
<div class="main-container">
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label required">标题</label>
|
<label class="layui-form-label required">标题</label>
|
||||||
@ -95,15 +95,15 @@
|
|||||||
const UPDATE_API = "/app/admin/rule/update";
|
const UPDATE_API = "/app/admin/rule/update";
|
||||||
|
|
||||||
// 获取行数据
|
// 获取行数据
|
||||||
layui.use(["form", "util", "popup"], function () {
|
layui.use(["form", "util"], function () {
|
||||||
let $ = layui.$;
|
let $ = layui.$;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: SELECT_API,
|
url: SELECT_API,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
|
|
||||||
// 赋值表单
|
// 赋值表单
|
||||||
layui.each(res.data[0], function (key, value) {
|
layui.each(e.data[0], function (key, value) {
|
||||||
let obj = $('*[name="'+key+'"]');
|
let obj = $('*[name="'+key+'"]');
|
||||||
if (key === "password") {
|
if (key === "password") {
|
||||||
obj.attr("placeholder", "不更新密码请留空");
|
obj.attr("placeholder", "不更新密码请留空");
|
||||||
@ -127,11 +127,11 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 获取上级菜单
|
// 获取上级菜单
|
||||||
layui.use(["jquery", "xmSelect", "popup"], function() {
|
layui.use(["jquery", "xmSelect"], function() {
|
||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
url: "/app/admin/rule/select?format=tree&type=0,1",
|
url: "/app/admin/rule/select?format=tree&type=0,1",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
let value = layui.$("#pid").attr("value");
|
let value = layui.$("#pid").attr("value");
|
||||||
let initValue = value ? value.split(",") : [];
|
let initValue = value ? value.split(",") : [];
|
||||||
layui.xmSelect.render({
|
layui.xmSelect.render({
|
||||||
@ -140,15 +140,12 @@
|
|||||||
initValue: initValue,
|
initValue: initValue,
|
||||||
tips: "无",
|
tips: "无",
|
||||||
toolbar: {show: true, list: ["CLEAR"]},
|
toolbar: {show: true, list: ["CLEAR"]},
|
||||||
data: res.data,
|
data: e.data,
|
||||||
model: {"icon":"hidden","label":{"type":"text"}},
|
model: {"icon":"hidden","label":{"type":"text"}},
|
||||||
clickClose: true,
|
clickClose: true,
|
||||||
radio: true,
|
radio: true,
|
||||||
tree: {show: true,"strict":false,"clickCheck":true,"clickExpand":false,expandedKeys: initValue},
|
tree: {show: true,"strict":false,"clickCheck":true,"clickExpand":false,expandedKeys: initValue},
|
||||||
});
|
})
|
||||||
if (res.code) {
|
|
||||||
return layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -168,10 +165,6 @@
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
// ajax产生错误
|
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -96,7 +96,7 @@
|
|||||||
|
|
||||||
<script type="text/html" id="col-type">
|
<script type="text/html" id="col-type">
|
||||||
<select name="columns[{{ d.LAY_INDEX-1 }}][type]" lay-verify="">
|
<select name="columns[{{ d.LAY_INDEX-1 }}][type]" lay-verify="">
|
||||||
{{# layui.each(["integer","string","text","date","enum","float","tinyInteger","smallInteger","mediumInteger","bigInteger","unsignedInteger","unsignedTinyInteger","unsignedSmallInteger","unsignedMediumInteger","unsignedBigInteger","decimal","double","mediumText","longText","dateTime","time","timestamp","char","binary","json"], function (index, item) { }}
|
{{# layui.each(["integer","string","text","date","enum","float","tinyInteger","smallInteger","mediumInteger","bigInteger","unsignedInteger","unsignedTinyInteger","unsignedSmallInteger","unsignedMediumInteger","unsignedBigInteger","decimal","double","mediumText","longText","dateTime","time","timestamp","char","binary"], function (index, item) { }}
|
||||||
<option value="{{ item }}" {{ d.type==item?"selected":""}}>{{ item }}</option>
|
<option value="{{ item }}" {{ d.type==item?"selected":""}}>{{ item }}</option>
|
||||||
{{# }); }}
|
{{# }); }}
|
||||||
</select>
|
</select>
|
||||||
@ -132,7 +132,7 @@
|
|||||||
|
|
||||||
<script type="text/html" id="form-control">
|
<script type="text/html" id="form-control">
|
||||||
<select name="forms[{{ d.LAY_INDEX-1 }}][control]" lay-verify="">
|
<select name="forms[{{ d.LAY_INDEX-1 }}][control]" lay-verify="">
|
||||||
{{# layui.each([["input", "文本框"],["inputNumber", "数字文本框"],["textArea", "多行文本"],["richText", "富文本"],["select", "下拉单选"],["selectMulti", "下拉多选"],["treeSelect", "树形单选"],["treeSelectMulti", "树形多选"],["datePicker", "日期选择"],["dateTimePicker", "日期时间选择"],["switch", "开关"],["upload", "上传文件"],["uploadImage", "上传图片"],["iconPicker", "图标选择"]], function (index, item) { }}
|
{{# layui.each([["input", "文本框"],["inputNumber", "数字文本框"],["textArea", "多行文本"],["select", "下拉单选"],["selectMulti", "下拉多选"],["treeSelect", "树形单选"],["treeSelectMulti", "树形多选"],["datePicker", "日期选择"],["dateTimePicker", "日期时间选择"],["switch", "开关"],["upload", "上传文件"],["uploadImage", "上传图片"],["iconPicker", "图标选择"]], function (index, item) { }}
|
||||||
<option value="{{ item[0] }}" {{ d.control.toLocaleLowerCase()==item[0].toLocaleLowerCase()?'selected':''}}>{{ item[1] }}</option>
|
<option value="{{ item[0] }}" {{ d.control.toLocaleLowerCase()==item[0].toLocaleLowerCase()?'selected':''}}>{{ item[1] }}</option>
|
||||||
{{# }); }}
|
{{# }); }}
|
||||||
</select>
|
</select>
|
||||||
@ -160,7 +160,7 @@
|
|||||||
|
|
||||||
<script type="text/html" id="form-search_type">
|
<script type="text/html" id="form-search_type">
|
||||||
<select name="forms[{{ d.LAY_INDEX-1 }}][search_type]" lay-verify="">
|
<select name="forms[{{ d.LAY_INDEX-1 }}][search_type]" lay-verify="">
|
||||||
{{# layui.each([["normal", "普通查询"], ["between", "范围查询"], ["like", "模糊查询"]], function (index, item) { }}
|
{{# layui.each([["normal", "普通查询"], ["between", "范围查询"]], function (index, item) { }}
|
||||||
<option value="{{ item[0] }}" {{ d.search_type==item[0]?'selected':''}}>{{ item[1] }}</option>
|
<option value="{{ item[0] }}" {{ d.search_type==item[0]?'selected':''}}>{{ item[1] }}</option>
|
||||||
{{# }); }}
|
{{# }); }}
|
||||||
</select>
|
</select>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<form class="layui-form" action="">
|
<form class="layui-form" action="">
|
||||||
|
|
||||||
<div class="mainBox">
|
<div class="mainBox">
|
||||||
<div class="main-container mr-5">
|
<div class="main-container">
|
||||||
<input type="hidden" name="table" value="<?=htmlspecialchars($table)?>">
|
<input type="hidden" name="table" value="<?=htmlspecialchars($table)?>">
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label required">菜单名</label>
|
<label class="layui-form-label required">菜单名</label>
|
||||||
@ -78,11 +78,11 @@
|
|||||||
|
|
||||||
const CRUD_API = "/app/admin/table/crud";
|
const CRUD_API = "/app/admin/table/crud";
|
||||||
|
|
||||||
layui.use(["jquery", "xmSelect", "popup"], function() {
|
layui.use(["jquery", "xmSelect"], function() {
|
||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
url: "/app/admin/rule/select?format=tree&type=0,1",
|
url: "/app/admin/rule/select?format=tree&type=0,1",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
let value = layui.$("#pid").attr("value");
|
let value = layui.$("#pid").attr("value");
|
||||||
let initValue = value ? value.split(",") : [];
|
let initValue = value ? value.split(",") : [];
|
||||||
layui.xmSelect.render({
|
layui.xmSelect.render({
|
||||||
@ -90,16 +90,13 @@
|
|||||||
name: "pid",
|
name: "pid",
|
||||||
initValue: initValue,
|
initValue: initValue,
|
||||||
tips: "无",
|
tips: "无",
|
||||||
data: res.data,
|
data: e.data,
|
||||||
toolbar: {show: true, list: ["CLEAR"]},
|
toolbar: {show: true, list: ["CLEAR"]},
|
||||||
model: {"icon":"hidden","label":{"type":"text"}},
|
model: {"icon":"hidden","label":{"type":"text"}},
|
||||||
clickClose: true,
|
clickClose: true,
|
||||||
radio: true,
|
radio: true,
|
||||||
tree: {show:true, strict:false, clickCheck:true, clickExpand:false},
|
tree: {show:true, strict:false, clickCheck:true, clickExpand:false},
|
||||||
});
|
})
|
||||||
if (res.code) {
|
|
||||||
return layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -125,6 +122,7 @@
|
|||||||
return layui.popup.failure(res.msg);
|
return layui.popup.failure(res.msg);
|
||||||
}
|
}
|
||||||
return layui.popup.success("操作成功", function () {
|
return layui.popup.success("操作成功", function () {
|
||||||
|
parent.refreshTable();
|
||||||
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<form class="layui-form" action="">
|
<form class="layui-form" action="">
|
||||||
|
|
||||||
<div class="mainBox">
|
<div class="mainBox">
|
||||||
<div class="main-container mr-5">
|
<div class="main-container">
|
||||||
<input type="hidden" name="table" value="<?=htmlspecialchars($table)?>">
|
<input type="hidden" name="table" value="<?=htmlspecialchars($table)?>">
|
||||||
<?= $form->html(5)?>
|
<?= $form->html(5)?>
|
||||||
</div>
|
</div>
|
||||||
@ -40,17 +40,6 @@
|
|||||||
<?=$form->js(3)?>
|
<?=$form->js(3)?>
|
||||||
|
|
||||||
layui.use(["form", "popup"], function () {
|
layui.use(["form", "popup"], function () {
|
||||||
|
|
||||||
// 字段验证允许为空
|
|
||||||
layui.form.verify({
|
|
||||||
phone: [/(^$)|^1\d{10}$/, "请输入正确的手机号"],
|
|
||||||
email: [/(^$)|^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/, "邮箱格式不正确"],
|
|
||||||
url: [/(^$)|(^#)|(^http(s*):\/\/[^\s]+\.[^\s]+)/, "链接格式不正确"],
|
|
||||||
number: [/(^$)|^\d+$/,'只能填写数字'],
|
|
||||||
date: [/(^$)|^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/, "日期格式不正确"],
|
|
||||||
identity: [/(^$)|(^\d{15}$)|(^\d{17}(x|X|\d)$)/, "请输入正确的身份证号"]
|
|
||||||
});
|
|
||||||
|
|
||||||
//提交事件
|
//提交事件
|
||||||
layui.form.on("submit(save)", function (data) {
|
layui.form.on("submit(save)", function (data) {
|
||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
|
@ -98,7 +98,7 @@
|
|||||||
|
|
||||||
<script type="text/html" id="col-type">
|
<script type="text/html" id="col-type">
|
||||||
<select name="columns[{{ d.LAY_INDEX-1 }}][type]" lay-verify="">
|
<select name="columns[{{ d.LAY_INDEX-1 }}][type]" lay-verify="">
|
||||||
{{# layui.each(["integer","string","text","date","enum","float","tinyInteger","smallInteger","mediumInteger","bigInteger","unsignedInteger","unsignedTinyInteger","unsignedSmallInteger","unsignedMediumInteger","unsignedBigInteger","decimal","double","mediumText","longText","dateTime","time","timestamp","char","binary","json"], function (index, item) { }}
|
{{# layui.each(["integer","string","text","date","enum","float","tinyInteger","smallInteger","mediumInteger","bigInteger","unsignedInteger","unsignedTinyInteger","unsignedSmallInteger","unsignedMediumInteger","unsignedBigInteger","decimal","double","mediumText","longText","dateTime","time","timestamp","char","binary"], function (index, item) { }}
|
||||||
<option value="{{ item }}" {{ d.type==item?'selected':''}}>{{ item }}</option>
|
<option value="{{ item }}" {{ d.type==item?'selected':''}}>{{ item }}</option>
|
||||||
{{# }); }}
|
{{# }); }}
|
||||||
</select>
|
</select>
|
||||||
@ -136,7 +136,7 @@
|
|||||||
|
|
||||||
<script type="text/html" id="form-control">
|
<script type="text/html" id="form-control">
|
||||||
<select name="forms[{{ d.LAY_INDEX-1 }}][control]" lay-verify="">
|
<select name="forms[{{ d.LAY_INDEX-1 }}][control]" lay-verify="">
|
||||||
{{# layui.each([["input", "文本框"],["inputNumber", "数字文本框"],["textArea", "多行文本"],["richText", "富文本"],["select", "下拉单选"],["selectMulti", "下拉多选"],["treeSelect", "树形单选"],["treeSelectMulti", "树形多选"],["datePicker", "日期选择"],["dateTimePicker", "日期时间选择"],["switch", "开关"],["upload", "上传文件"],["uploadImage", "上传图片"],["iconPicker", "图标选择"]], function (index, item) { }}
|
{{# layui.each([["input", "文本框"],["inputNumber", "数字文本框"],["textArea", "多行文本"],["select", "下拉单选"],["selectMulti", "下拉多选"],["treeSelect", "树形单选"],["treeSelectMulti", "树形多选"],["datePicker", "日期选择"],["dateTimePicker", "日期时间选择"],["switch", "开关"],["upload", "上传文件"],["uploadImage", "上传图片"],["iconPicker", "图标选择"]], function (index, item) { }}
|
||||||
<option value="{{ item[0] }}" {{ d.control.toLocaleLowerCase()==item[0].toLocaleLowerCase()?'selected':''}}>{{ item[1] }}</option>
|
<option value="{{ item[0] }}" {{ d.control.toLocaleLowerCase()==item[0].toLocaleLowerCase()?'selected':''}}>{{ item[1] }}</option>
|
||||||
{{# }); }}
|
{{# }); }}
|
||||||
</select>
|
</select>
|
||||||
@ -164,7 +164,7 @@
|
|||||||
|
|
||||||
<script type="text/html" id="form-search_type">
|
<script type="text/html" id="form-search_type">
|
||||||
<select name="forms[{{ d.LAY_INDEX-1 }}][search_type]" lay-verify="">
|
<select name="forms[{{ d.LAY_INDEX-1 }}][search_type]" lay-verify="">
|
||||||
{{# layui.each([["normal", "普通查询"], ["between", "范围查询"], ["like", "模糊查询"]], function (index, item) { }}
|
{{# layui.each([["normal", "普通查询"], ["between", "范围查询"]], function (index, item) { }}
|
||||||
<option value="{{ item[0] }}" {{ d.search_type==item[0]?'selected':''}}>{{ item[1] }}</option>
|
<option value="{{ item[0] }}" {{ d.search_type==item[0]?'selected':''}}>{{ item[1] }}</option>
|
||||||
{{# }); }}
|
{{# }); }}
|
||||||
</select>
|
</select>
|
||||||
@ -226,17 +226,12 @@
|
|||||||
const SCHEMA_API = "/app/admin/table/schema";
|
const SCHEMA_API = "/app/admin/table/schema";
|
||||||
const TABLE_NAME = "<?=htmlspecialchars($table)?>";
|
const TABLE_NAME = "<?=htmlspecialchars($table)?>";
|
||||||
|
|
||||||
layui.use(["popup"], function () {
|
layui.use(["jquery"], function () {
|
||||||
let $ = layui.$;
|
let $ = layui.$;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: SCHEMA_API + "?table=" + TABLE_NAME,
|
url: SCHEMA_API + "?table=" + TABLE_NAME,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
|
|
||||||
if (res.code) {
|
|
||||||
return layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 表信息
|
// 表信息
|
||||||
$('input[name="table"]').val(res.data.table.name);
|
$('input[name="table"]').val(res.data.table.name);
|
||||||
$('input[name="table_comment"]').val(res.data.table.comment);
|
$('input[name="table_comment"]').val(res.data.table.comment);
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<form class="layui-form">
|
<form class="layui-form">
|
||||||
|
|
||||||
<div class="mainBox">
|
<div class="mainBox">
|
||||||
<div class="main-container mr-5">
|
<div class="main-container">
|
||||||
|
|
||||||
<input type="hidden" name="<?=htmlspecialchars($primary_key)?>" value="<?=htmlspecialchars($value)?>">
|
<input type="hidden" name="<?=htmlspecialchars($primary_key)?>" value="<?=htmlspecialchars($value)?>">
|
||||||
<input type="hidden" name="table" value="<?=htmlspecialchars($table)?>">
|
<input type="hidden" name="table" value="<?=htmlspecialchars($table)?>">
|
||||||
@ -42,15 +42,14 @@
|
|||||||
const SELECT_API = "/app/admin/table/select" + location.search;
|
const SELECT_API = "/app/admin/table/select" + location.search;
|
||||||
const UPDATE_API = "/app/admin/table/update";
|
const UPDATE_API = "/app/admin/table/update";
|
||||||
|
|
||||||
layui.use(["form", "util", "popup"], function () {
|
layui.use(["form", "util"], function () {
|
||||||
let $ = layui.$;
|
let $ = layui.$;
|
||||||
let util = layui.util;
|
let util = layui.util;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: SELECT_API,
|
url: SELECT_API,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
|
layui.each(e.data[0], function (key, value) {
|
||||||
layui.each(res.data[0], function (key, value) {
|
|
||||||
let obj = $('*[name="'+key+'"]');
|
let obj = $('*[name="'+key+'"]');
|
||||||
if (key === "password") {
|
if (key === "password") {
|
||||||
obj.attr("placeholder", "不更新密码请留空");
|
obj.attr("placeholder", "不更新密码请留空");
|
||||||
@ -66,25 +65,11 @@
|
|||||||
|
|
||||||
<?=$form->js(6)?>
|
<?=$form->js(6)?>
|
||||||
|
|
||||||
// ajax返回失败
|
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
layui.use(["form", "popup"], function () {
|
layui.use(["form", "popup"], function () {
|
||||||
// 字段验证允许为空
|
|
||||||
layui.form.verify({
|
|
||||||
phone: [/(^$)|^1\d{10}$/, "请输入正确的手机号"],
|
|
||||||
email: [/(^$)|^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/, "邮箱格式不正确"],
|
|
||||||
url: [/(^$)|(^#)|(^http(s*):\/\/[^\s]+\.[^\s]+)/, "链接格式不正确"],
|
|
||||||
number: [/(^$)|^\d+$/,'只能填写数字'],
|
|
||||||
date: [/(^$)|^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/, "日期格式不正确"],
|
|
||||||
identity: [/(^$)|(^\d{15}$)|(^\d{17}(x|X|\d)$)/, "请输入正确的身份证号"]
|
|
||||||
});
|
|
||||||
//提交事件
|
//提交事件
|
||||||
layui.form.on("submit(save)", function (data) {
|
layui.form.on("submit(save)", function (data) {
|
||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
|
@ -80,11 +80,8 @@
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
url: SCHEMA_API,
|
url: SCHEMA_API,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
if (res.code) {
|
let forms = e.data.forms;
|
||||||
return layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
let forms = res.data.forms;
|
|
||||||
let cols = [{
|
let cols = [{
|
||||||
type: "checkbox"
|
type: "checkbox"
|
||||||
}];
|
}];
|
||||||
@ -176,10 +173,7 @@
|
|||||||
title: "刷新",
|
title: "刷新",
|
||||||
layEvent: "refresh",
|
layEvent: "refresh",
|
||||||
icon: "layui-icon-refresh",
|
icon: "layui-icon-refresh",
|
||||||
}, "filter", "print", "exports"],
|
}, "filter", "print", "exports"]
|
||||||
done: function () {
|
|
||||||
layer.photos({photos: 'div[lay-id="data-table"]', anim: 5});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,9 +185,6 @@
|
|||||||
url: url,
|
url: url,
|
||||||
dateType: "json",
|
dateType: "json",
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
if (res.code) {
|
|
||||||
return layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
function travel(items) {
|
function travel(items) {
|
||||||
for (let k in items) {
|
for (let k in items) {
|
||||||
let item = items[k];
|
let item = items[k];
|
||||||
@ -237,16 +228,6 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 字段验证允许为空
|
|
||||||
form.verify({
|
|
||||||
phone: [/(^$)|^1\d{10}$/, "请输入正确的手机号"],
|
|
||||||
email: [/(^$)|^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/, "邮箱格式不正确"],
|
|
||||||
url: [/(^$)|(^#)|(^http(s*):\/\/[^\s]+\.[^\s]+)/, "链接格式不正确"],
|
|
||||||
number: [/(^$)|^\d+$/,'只能填写数字'],
|
|
||||||
date: [/(^$)|^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/, "日期格式不正确"],
|
|
||||||
identity: [/(^$)|(^\d{15}$)|(^\d{17}(x|X|\d)$)/, "请输入正确的身份证号"]
|
|
||||||
});
|
|
||||||
|
|
||||||
form.on("submit(table-query)", function(data) {
|
form.on("submit(table-query)", function(data) {
|
||||||
table.reload("data-table", {
|
table.reload("data-table", {
|
||||||
where: data.field
|
where: data.field
|
||||||
|
@ -121,14 +121,14 @@
|
|||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
url: "/app/admin/dict/get/upload",
|
url: "/app/admin/dict/get/upload",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
let value = layui.$("#category").attr("value");
|
let value = layui.$("#category").attr("value");
|
||||||
let initValue = value ? value.split(",") : [];
|
let initValue = value ? value.split(",") : [];
|
||||||
layui.xmSelect.render({
|
layui.xmSelect.render({
|
||||||
el: "#category",
|
el: "#category",
|
||||||
name: "category",
|
name: "category",
|
||||||
initValue: initValue,
|
initValue: initValue,
|
||||||
data: res.data,
|
data: e.data,
|
||||||
model: {"icon":"hidden","label":{"type":"text"}},
|
model: {"icon":"hidden","label":{"type":"text"}},
|
||||||
clickClose: true,
|
clickClose: true,
|
||||||
radio: true,
|
radio: true,
|
||||||
@ -265,9 +265,6 @@
|
|||||||
url: url,
|
url: url,
|
||||||
dateType: "json",
|
dateType: "json",
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
if (res.code) {
|
|
||||||
return layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
function travel(items) {
|
function travel(items) {
|
||||||
for (let k in items) {
|
for (let k in items) {
|
||||||
let item = items[k];
|
let item = items[k];
|
||||||
@ -315,9 +312,6 @@
|
|||||||
// 表格顶部搜索事件
|
// 表格顶部搜索事件
|
||||||
form.on("submit(table-query)", function(data) {
|
form.on("submit(table-query)", function(data) {
|
||||||
table.reload("data-table", {
|
table.reload("data-table", {
|
||||||
page: {
|
|
||||||
curr: 1
|
|
||||||
},
|
|
||||||
where: data.field
|
where: data.field
|
||||||
})
|
})
|
||||||
return false;
|
return false;
|
||||||
|
@ -110,25 +110,22 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 字段 类别 category
|
// 字段 类别 category
|
||||||
layui.use(["jquery", "xmSelect", "popup"], function() {
|
layui.use(["jquery", "xmSelect"], function() {
|
||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
url: "/app/admin/dict/get/upload",
|
url: "/app/admin/dict/get/upload",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
let value = layui.$("#category").attr("value");
|
let value = layui.$("#category").attr("value");
|
||||||
let initValue = value ? value.split(",") : [];
|
let initValue = value ? value.split(",") : [];
|
||||||
layui.xmSelect.render({
|
layui.xmSelect.render({
|
||||||
el: "#category",
|
el: "#category",
|
||||||
name: "category",
|
name: "category",
|
||||||
initValue: initValue,
|
initValue: initValue,
|
||||||
data: res.data,
|
data: e.data,
|
||||||
model: {"icon":"hidden","label":{"type":"text"}},
|
model: {"icon":"hidden","label":{"type":"text"}},
|
||||||
clickClose: true,
|
clickClose: true,
|
||||||
radio: true,
|
radio: true,
|
||||||
});
|
})
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -257,9 +254,6 @@
|
|||||||
url: url,
|
url: url,
|
||||||
dateType: "json",
|
dateType: "json",
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
if (res.code) {
|
|
||||||
return layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
function travel(items) {
|
function travel(items) {
|
||||||
for (let k in items) {
|
for (let k in items) {
|
||||||
let item = items[k];
|
let item = items[k];
|
||||||
@ -305,9 +299,6 @@
|
|||||||
// 表格顶部搜索事件
|
// 表格顶部搜索事件
|
||||||
form.on("submit(table-query)", function(data) {
|
form.on("submit(table-query)", function(data) {
|
||||||
table.reload("data-table", {
|
table.reload("data-table", {
|
||||||
page: {
|
|
||||||
curr: 1
|
|
||||||
},
|
|
||||||
where: data.field
|
where: data.field
|
||||||
})
|
})
|
||||||
return false;
|
return false;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<form class="layui-form" action="">
|
<form class="layui-form" action="">
|
||||||
|
|
||||||
<div class="mainBox">
|
<div class="mainBox">
|
||||||
<div class="main-container mr-5">
|
<div class="main-container">
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">类别</label>
|
<label class="layui-form-label">类别</label>
|
||||||
@ -66,21 +66,18 @@
|
|||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
url: "/app/admin/dict/get/upload",
|
url: "/app/admin/dict/get/upload",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
let value = layui.$("#category").attr("value");
|
let value = layui.$("#category").attr("value");
|
||||||
let initValue = value ? value.split(",") : [];
|
let initValue = value ? value.split(",") : [];
|
||||||
layui.xmSelect.render({
|
layui.xmSelect.render({
|
||||||
el: "#category",
|
el: "#category",
|
||||||
name: "category",
|
name: "category",
|
||||||
initValue: initValue,
|
initValue: initValue,
|
||||||
data: res.data,
|
data: e.data,
|
||||||
model: {"icon":"hidden","label":{"type":"text"}},
|
model: {"icon":"hidden","label":{"type":"text"}},
|
||||||
clickClose: true,
|
clickClose: true,
|
||||||
radio: true,
|
radio: true,
|
||||||
});
|
})
|
||||||
if (res.code) {
|
|
||||||
return layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<form class="layui-form">
|
<form class="layui-form">
|
||||||
|
|
||||||
<div class="mainBox">
|
<div class="mainBox">
|
||||||
<div class="main-container mr-5">
|
<div class="main-container">
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label" style="width:inherit">类别</label>
|
<label class="layui-form-label" style="width:inherit">类别</label>
|
||||||
@ -47,15 +47,15 @@
|
|||||||
const UPDATE_API = "/app/admin/upload/update";
|
const UPDATE_API = "/app/admin/upload/update";
|
||||||
|
|
||||||
// 获取数据库记录
|
// 获取数据库记录
|
||||||
layui.use(["form", "util", "popup"], function () {
|
layui.use(["form", "util"], function () {
|
||||||
let $ = layui.$;
|
let $ = layui.$;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: SELECT_API,
|
url: SELECT_API,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
|
|
||||||
// 给表单初始化数据
|
// 给表单初始化数据
|
||||||
layui.each(res.data[0], function (key, value) {
|
layui.each(e.data[0], function (key, value) {
|
||||||
let obj = $('*[name="'+key+'"]');
|
let obj = $('*[name="'+key+'"]');
|
||||||
if (typeof obj[0] === "undefined" || !obj[0].nodeName) return;
|
if (typeof obj[0] === "undefined" || !obj[0].nodeName) return;
|
||||||
obj.attr("value", value);
|
obj.attr("value", value);
|
||||||
@ -78,33 +78,26 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 字段 类别 category
|
// 字段 类别 category
|
||||||
layui.use(["jquery", "xmSelect", "popup"], function() {
|
layui.use(["jquery", "xmSelect"], function() {
|
||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
url: "/app/admin/dict/get/upload",
|
url: "/app/admin/dict/get/upload",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
let value = layui.$("#category").attr("value");
|
let value = layui.$("#category").attr("value");
|
||||||
let initValue = value ? value.split(",") : [];
|
let initValue = value ? value.split(",") : [];
|
||||||
layui.xmSelect.render({
|
layui.xmSelect.render({
|
||||||
el: "#category",
|
el: "#category",
|
||||||
name: "category",
|
name: "category",
|
||||||
initValue: initValue,
|
initValue: initValue,
|
||||||
data: res.data,
|
data: e.data,
|
||||||
model: {"icon":"hidden","label":{"type":"text"}},
|
model: {"icon":"hidden","label":{"type":"text"}},
|
||||||
clickClose: true,
|
clickClose: true,
|
||||||
radio: true,
|
radio: true,
|
||||||
});
|
})
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// ajax产生错误
|
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -75,7 +75,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">余额(元)</label>
|
<label class="layui-form-label">余额(分)</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<input type="number" name="money" value="" class="layui-input">
|
<input type="number" name="money" value="" class="layui-input">
|
||||||
</div>
|
</div>
|
||||||
@ -179,25 +179,22 @@
|
|||||||
const UPDATE_URL = "/app/admin/user/update";
|
const UPDATE_URL = "/app/admin/user/update";
|
||||||
|
|
||||||
// 字段 性别 sex
|
// 字段 性别 sex
|
||||||
layui.use(["jquery", "xmSelect", "popup"], function() {
|
layui.use(["jquery", "xmSelect"], function() {
|
||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
url: "/app/admin/dict/get/sex",
|
url: "/app/admin/dict/get/sex",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
let value = layui.$("#sex").attr("value");
|
let value = layui.$("#sex").attr("value");
|
||||||
let initValue = value ? value.split(",") : [];
|
let initValue = value ? value.split(",") : [];
|
||||||
layui.xmSelect.render({
|
layui.xmSelect.render({
|
||||||
el: "#sex",
|
el: "#sex",
|
||||||
name: "sex",
|
name: "sex",
|
||||||
initValue: initValue,
|
initValue: initValue,
|
||||||
data: res.data,
|
data: e.data,
|
||||||
model: {"icon":"hidden","label":{"type":"text"}},
|
model: {"icon":"hidden","label":{"type":"text"}},
|
||||||
clickClose: true,
|
clickClose: true,
|
||||||
radio: true,
|
radio: true,
|
||||||
});
|
})
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -287,7 +284,7 @@
|
|||||||
field: "birthday",
|
field: "birthday",
|
||||||
hide: true,
|
hide: true,
|
||||||
},{
|
},{
|
||||||
title: "余额(元)",
|
title: "余额(分)",
|
||||||
field: "money",
|
field: "money",
|
||||||
hide: true,
|
hide: true,
|
||||||
},{
|
},{
|
||||||
@ -339,10 +336,7 @@
|
|||||||
$.post(UPDATE_API, postData, function (res) {
|
$.post(UPDATE_API, postData, function (res) {
|
||||||
layer.close(load);
|
layer.close(load);
|
||||||
if (res.code) {
|
if (res.code) {
|
||||||
return layui.popup.failure(res.msg, function () {
|
return layui.popup.failure(res.msg);
|
||||||
data.elem.checked = !data.elem.checked;
|
|
||||||
form.render();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return layui.popup.success("操作成功");
|
return layui.popup.success("操作成功");
|
||||||
})
|
})
|
||||||
@ -394,9 +388,6 @@
|
|||||||
url: url,
|
url: url,
|
||||||
dateType: "json",
|
dateType: "json",
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
if (res.code) {
|
|
||||||
return layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
function travel(items) {
|
function travel(items) {
|
||||||
for (let k in items) {
|
for (let k in items) {
|
||||||
let item = items[k];
|
let item = items[k];
|
||||||
@ -442,9 +433,6 @@
|
|||||||
// 表格顶部搜索事件
|
// 表格顶部搜索事件
|
||||||
form.on("submit(table-query)", function(data) {
|
form.on("submit(table-query)", function(data) {
|
||||||
table.reload("data-table", {
|
table.reload("data-table", {
|
||||||
page: {
|
|
||||||
curr: 1
|
|
||||||
},
|
|
||||||
where: data.field
|
where: data.field
|
||||||
})
|
})
|
||||||
return false;
|
return false;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<form class="layui-form" action="">
|
<form class="layui-form" action="">
|
||||||
|
|
||||||
<div class="mainBox">
|
<div class="mainBox">
|
||||||
<div class="main-container mr-5">
|
<div class="main-container">
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label required">用户名</label>
|
<label class="layui-form-label required">用户名</label>
|
||||||
@ -44,7 +44,7 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">头像</label>
|
<label class="layui-form-label">头像</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<img class="img-3" src=""/>
|
<img style="max-width:90px;max-height:90px;" src=""/>
|
||||||
<input type="text" style="display:none" name="avatar" value="" />
|
<input type="text" style="display:none" name="avatar" value="" />
|
||||||
<button type="button" class="pear-btn pear-btn-primary pear-btn-sm" id="avatar" permission="app.admin.upload.avatar">
|
<button type="button" class="pear-btn pear-btn-primary pear-btn-sm" id="avatar" permission="app.admin.upload.avatar">
|
||||||
<i class="layui-icon layui-icon-upload"></i>上传图片
|
<i class="layui-icon layui-icon-upload"></i>上传图片
|
||||||
@ -84,7 +84,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">余额(元)</label>
|
<label class="layui-form-label">余额(分)</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<input type="number" name="money" value="0" class="layui-input">
|
<input type="number" name="money" value="0" class="layui-input">
|
||||||
</div>
|
</div>
|
||||||
@ -163,22 +163,19 @@
|
|||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
url: "/app/admin/dict/get/sex",
|
url: "/app/admin/dict/get/sex",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
let value = layui.$("#sex").attr("value");
|
let value = layui.$("#sex").attr("value");
|
||||||
let initValue = value ? value.split(",") : [];
|
let initValue = value ? value.split(",") : [];
|
||||||
layui.xmSelect.render({
|
layui.xmSelect.render({
|
||||||
el: "#sex",
|
el: "#sex",
|
||||||
name: "sex",
|
name: "sex",
|
||||||
initValue: initValue,
|
initValue: initValue,
|
||||||
data: res.data,
|
data: e.data,
|
||||||
value: "1",
|
value: "1",
|
||||||
model: {"icon":"hidden","label":{"type":"text"}},
|
model: {"icon":"hidden","label":{"type":"text"}},
|
||||||
clickClose: true,
|
clickClose: true,
|
||||||
radio: true,
|
radio: true,
|
||||||
});
|
})
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<form class="layui-form">
|
<form class="layui-form">
|
||||||
|
|
||||||
<div class="mainBox">
|
<div class="mainBox">
|
||||||
<div class="main-container mr-5">
|
<div class="main-container">
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label required">用户名</label>
|
<label class="layui-form-label required">用户名</label>
|
||||||
@ -44,7 +44,7 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">头像</label>
|
<label class="layui-form-label">头像</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<img class="img-3" src=""/>
|
<img style="max-width:90px;max-height:90px;" src=""/>
|
||||||
<input type="text" style="display:none" name="avatar" value="" />
|
<input type="text" style="display:none" name="avatar" value="" />
|
||||||
<button type="button" class="pear-btn pear-btn-primary pear-btn-sm" id="avatar" permission="app.admin.upload.avatar">
|
<button type="button" class="pear-btn pear-btn-primary pear-btn-sm" id="avatar" permission="app.admin.upload.avatar">
|
||||||
<i class="layui-icon layui-icon-upload"></i>上传图片
|
<i class="layui-icon layui-icon-upload"></i>上传图片
|
||||||
@ -84,7 +84,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">余额(元)</label>
|
<label class="layui-form-label">余额(分)</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<input type="number" name="money" value="" class="layui-input">
|
<input type="number" name="money" value="" class="layui-input">
|
||||||
</div>
|
</div>
|
||||||
@ -160,15 +160,15 @@
|
|||||||
const UPDATE_API = "/app/admin/user/update";
|
const UPDATE_API = "/app/admin/user/update";
|
||||||
|
|
||||||
// 获取数据库记录
|
// 获取数据库记录
|
||||||
layui.use(["form", "util", "popup"], function () {
|
layui.use(["form", "util"], function () {
|
||||||
let $ = layui.$;
|
let $ = layui.$;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: SELECT_API,
|
url: SELECT_API,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
|
|
||||||
// 给表单初始化数据
|
// 给表单初始化数据
|
||||||
layui.each(res.data[0], function (key, value) {
|
layui.each(e.data[0], function (key, value) {
|
||||||
let obj = $('*[name="'+key+'"]');
|
let obj = $('*[name="'+key+'"]');
|
||||||
if (key === "password") {
|
if (key === "password") {
|
||||||
obj.attr("placeholder", "不更新密码请留空");
|
obj.attr("placeholder", "不更新密码请留空");
|
||||||
@ -183,25 +183,22 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 字段 性别 sex
|
// 字段 性别 sex
|
||||||
layui.use(["jquery", "xmSelect", "popup"], function() {
|
layui.use(["jquery", "xmSelect"], function() {
|
||||||
layui.$.ajax({
|
layui.$.ajax({
|
||||||
url: "/app/admin/dict/get/sex",
|
url: "/app/admin/dict/get/sex",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (e) {
|
||||||
let value = layui.$("#sex").attr("value");
|
let value = layui.$("#sex").attr("value");
|
||||||
let initValue = value ? value.split(",") : [];
|
let initValue = value ? value.split(",") : [];
|
||||||
layui.xmSelect.render({
|
layui.xmSelect.render({
|
||||||
el: "#sex",
|
el: "#sex",
|
||||||
name: "sex",
|
name: "sex",
|
||||||
initValue: initValue,
|
initValue: initValue,
|
||||||
data: res.data,
|
data: e.data,
|
||||||
model: {"icon":"hidden","label":{"type":"text"}},
|
model: {"icon":"hidden","label":{"type":"text"}},
|
||||||
clickClose: true,
|
clickClose: true,
|
||||||
radio: true,
|
radio: true,
|
||||||
});
|
})
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -266,11 +263,7 @@
|
|||||||
layui.$('input[name="status"]').val(this.checked ? 1 : 0);
|
layui.$('input[name="status"]').val(this.checked ? 1 : 0);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
// ajax产生错误
|
|
||||||
if (res.code) {
|
|
||||||
layui.popup.failure(res.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -17,5 +17,5 @@ return [
|
|||||||
'controller_suffix' => 'Controller',
|
'controller_suffix' => 'Controller',
|
||||||
'controller_reuse' => false,
|
'controller_reuse' => false,
|
||||||
'plugin_market_host' => 'https://www.workerman.net',
|
'plugin_market_host' => 'https://www.workerman.net',
|
||||||
'version' => '0.6.12'
|
'version' => '0.5.0'
|
||||||
];
|
];
|
||||||
|
@ -15,12 +15,10 @@
|
|||||||
use plugin\admin\app\controller\AccountController;
|
use plugin\admin\app\controller\AccountController;
|
||||||
use plugin\admin\app\controller\DictController;
|
use plugin\admin\app\controller\DictController;
|
||||||
use Webman\Route;
|
use Webman\Route;
|
||||||
use support\Request;
|
|
||||||
|
|
||||||
Route::any('/app/admin/account/captcha/{type}', [AccountController::class, 'captcha']);
|
Route::any('/app/admin/account/captcha/{type}', [AccountController::class, 'captcha']);
|
||||||
|
Route::any('/app/admin', function () {
|
||||||
|
return redirect('/app/admin/');
|
||||||
|
});
|
||||||
|
|
||||||
Route::any('/app/admin/dict/get/{name}', [DictController::class, 'get']);
|
Route::any('/app/admin/dict/get/{name}', [DictController::class, 'get']);
|
||||||
|
|
||||||
Route::fallback(function (Request $request) {
|
|
||||||
return response($request->uri() . ' not found' , 404);
|
|
||||||
}, 'admin');
|
|
@ -21,5 +21,5 @@ return [
|
|||||||
// Fallback language
|
// Fallback language
|
||||||
'fallback_locale' => ['zh_CN', 'en'],
|
'fallback_locale' => ['zh_CN', 'en'],
|
||||||
// Folder where language files are stored
|
// Folder where language files are stored
|
||||||
'path' => base_path() . '/plugin/admin/resource/translations'
|
'path' => base_path() . '/resource/translations',
|
||||||
];
|
];
|
File diff suppressed because one or more lines are too long
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
button {
|
button {
|
||||||
line-height: 100% !important;
|
line-height: 100% !important;
|
||||||
}
|
}
|
||||||
@ -95,61 +96,6 @@ a {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width:768px) {
|
|
||||||
/** **/
|
|
||||||
.layui-table-tool-self .layui-inline:nth-child(3){
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 右间隔 **/
|
|
||||||
.mr-1
|
|
||||||
{
|
|
||||||
margin-right: 4px;
|
|
||||||
}
|
|
||||||
.mr-2
|
|
||||||
{
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
.mr-3
|
|
||||||
{
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
.mr-4
|
|
||||||
{
|
|
||||||
margin-right: 24px;
|
|
||||||
}
|
|
||||||
.mr-5
|
|
||||||
{
|
|
||||||
margin-right: 48px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 图片尺寸 **/
|
|
||||||
.img-1
|
|
||||||
{
|
|
||||||
max-width: 16px;
|
|
||||||
max-height: 16px;
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
.img-2
|
|
||||||
{
|
|
||||||
max-width: 32px;
|
|
||||||
max-height: 32px;
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
.img-3
|
|
||||||
{
|
|
||||||
max-width: 64px;
|
|
||||||
max-height: 64px;
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
.img-4
|
|
||||||
{
|
|
||||||
max-width: 128px;
|
|
||||||
max-height: 128px;
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 左侧菜单 Start **/
|
/** 左侧菜单 Start **/
|
||||||
|
|
||||||
.pear-nav-tree .layui-nav-item a span {
|
.pear-nav-tree .layui-nav-item a span {
|
||||||
|
@ -6,7 +6,7 @@ function toggleSearchFormShow()
|
|||||||
let $ = layui.$;
|
let $ = layui.$;
|
||||||
let items = $('.top-search-from .layui-form-item');
|
let items = $('.top-search-from .layui-form-item');
|
||||||
if (items.length <= 2) {
|
if (items.length <= 2) {
|
||||||
if (items.length <= 1) $('.top-search-from').parent().parent().remove();
|
if (items.length <= 1) $('.top-search-from').remove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let btns = $('.top-search-from .toggle-btn a');
|
let btns = $('.top-search-from .toggle-btn a');
|
||||||
|
@ -4,24 +4,16 @@
|
|||||||
layui.$(function () {
|
layui.$(function () {
|
||||||
let $ = layui.$;
|
let $ = layui.$;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "/app/admin/rule/permission",
|
url: "/app/admin/rule/permission-codes",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
let style = '';
|
let style = '';
|
||||||
let codes = res.data || [];
|
let codes = res.data || [];
|
||||||
let isSupperAdmin = false;
|
|
||||||
// codes里有*,说明是超级管理员,拥有所有权限
|
// codes里有*,说明是超级管理员,拥有所有权限
|
||||||
if (codes.indexOf('*') !== -1) {
|
if (codes.indexOf('*') !== -1) {
|
||||||
$("head").append("<style>*[permission]{display: initial}</style>");
|
$("head").append("<style>*[permission]{display: initial}</style>");
|
||||||
isSupperAdmin = true;
|
return;
|
||||||
}
|
}
|
||||||
if (self !== top) {
|
|
||||||
top.Admin.Account.isSupperAdmin = isSupperAdmin;
|
|
||||||
} else {
|
|
||||||
window.Admin.Account.isSupperAdmin = isSupperAdmin;
|
|
||||||
}
|
|
||||||
if (isSupperAdmin) return;
|
|
||||||
|
|
||||||
// 细分权限
|
// 细分权限
|
||||||
layui.each(codes, function (k, code) {
|
layui.each(codes, function (k, code) {
|
||||||
codes[k] = '*[permission^="'+code+'"]';
|
codes[k] = '*[permission^="'+code+'"]';
|
||||||
|
@ -346,7 +346,7 @@ layui.define(['layer', 'form'], function(exports) {
|
|||||||
var html = ' <div class="layui-form-item">\n' +
|
var html = ' <div class="layui-form-item">\n' +
|
||||||
' <label class="layui-form-label">上传图片</label>\n' +
|
' <label class="layui-form-label">上传图片</label>\n' +
|
||||||
' <div class="layui-input-' + size + '">\n' +
|
' <div class="layui-input-' + size + '">\n' +
|
||||||
' <img class="img-3" src=""/>\n' +
|
' <img style="max-width:90px;max-height:90px;" src=""/>\n' +
|
||||||
' <input type="text" style="display:none" name="'+key+'" value="" />\n' +
|
' <input type="text" style="display:none" name="'+key+'" value="" />\n' +
|
||||||
' <button type="button" class="pear-btn pear-btn-primary pear-btn-sm" id="'+key+'" permission="app.admin.upload.image">\n' +
|
' <button type="button" class="pear-btn pear-btn-primary pear-btn-sm" id="'+key+'" permission="app.admin.upload.image">\n' +
|
||||||
' <i class="layui-icon layui-icon-upload"></i>'+uploadWords+'\n' +
|
' <i class="layui-icon layui-icon-upload"></i>'+uploadWords+'\n' +
|
||||||
|
@ -61,9 +61,7 @@ layui.define(["jquery","layer"], function (exports) {
|
|||||||
style += 'xm-select > .xm-body .xm-option.selected.hide-icon{background-color:'+color+'!important;}';//变更
|
style += 'xm-select > .xm-body .xm-option.selected.hide-icon{background-color:'+color+'!important;}';//变更
|
||||||
style += 'xm-select > .xm-body .xm-toolbar .toolbar-tag:hover{color:'+color+'!important;}';//变更
|
style += 'xm-select > .xm-body .xm-toolbar .toolbar-tag:hover{color:'+color+'!important;}';//变更
|
||||||
style += '.layui-layer-dialog .layui-layer-content .layui-icon-ok{color:'+color+'!important;}';//变更
|
style += '.layui-layer-dialog .layui-layer-content .layui-icon-ok{color:'+color+'!important;}';//变更
|
||||||
style += '.layui-layer-dialog .layui-layer-content .layui-icon-ok{color:'+color+'!important;}';//变更
|
style += '.layui-layer-loading-icon{color:'+color+'!important;}';//变更
|
||||||
style += 'a{color:'+color+';opacity:.8}';//变更
|
|
||||||
style += 'a:hover{color:'+color+';opacity:1}';//变更
|
|
||||||
style += '.pear-this,.pear-text{color:' + color + '!important}';
|
style += '.pear-this,.pear-text{color:' + color + '!important}';
|
||||||
style += '.pear-back{background-color:'+ color +'!important}';
|
style += '.pear-back{background-color:'+ color +'!important}';
|
||||||
style += '.pear-collapsed-pe{background-color:'+color+'!important}'
|
style += '.pear-collapsed-pe{background-color:'+color+'!important}'
|
||||||
|
@ -25,9 +25,9 @@ layui.define(['jquery'],function (exports) {
|
|||||||
}
|
}
|
||||||
, success: function (res, succFun, failFun) {//图片上传完成回调 根据自己需要修改
|
, success: function (res, succFun, failFun) {//图片上传完成回调 根据自己需要修改
|
||||||
if (res[this.response.statusName] == this.response.statusCode.ok) {
|
if (res[this.response.statusName] == this.response.statusCode.ok) {
|
||||||
succFun(res[this.response.dataName]["url"]);
|
succFun(res[this.response.dataName]);
|
||||||
} else {
|
} else {
|
||||||
failFun(res[this.response.msgName]["url"]);
|
failFun(res[this.response.msgName]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -49,7 +49,7 @@ layui.define(['layer', 'table'], function (exports) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*var sort = function (s_pid, data) {
|
var sort = function (s_pid, data) {
|
||||||
for (var i = 0; i < data.length; i++) {
|
for (var i = 0; i < data.length; i++) {
|
||||||
if (data[i].pid == s_pid) {
|
if (data[i].pid == s_pid) {
|
||||||
var len = mData.length;
|
var len = mData.length;
|
||||||
@ -61,41 +61,7 @@ layui.define(['layer', 'table'], function (exports) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
sort(param.treeSpid, tNodes);*/
|
sort(param.treeSpid, tNodes);
|
||||||
|
|
||||||
var map = {}; // 变更
|
|
||||||
for (var k in data) {
|
|
||||||
map[data[k].id] = data[k];
|
|
||||||
}
|
|
||||||
for (var j in map) {
|
|
||||||
if(map[j].pid && map[map[j].pid]) {
|
|
||||||
var parent = map[map[j].pid];
|
|
||||||
if (!parent.children) {
|
|
||||||
parent.children = [];
|
|
||||||
parent.isParent = true;
|
|
||||||
}
|
|
||||||
parent.children.push(map[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var tree = [];
|
|
||||||
for (var l in map) {
|
|
||||||
if (!map[l].pid || !map[map[l].pid]) {
|
|
||||||
map[l].isRoot = true;
|
|
||||||
tree.push(map[l]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function travel(item)
|
|
||||||
{
|
|
||||||
mData.push(item);
|
|
||||||
if (item.children) {
|
|
||||||
for (var g in item.children) {
|
|
||||||
travel(item.children[g]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (var h in tree) {
|
|
||||||
travel(tree[h]);
|
|
||||||
}
|
|
||||||
|
|
||||||
param.prevUrl = param.url;
|
param.prevUrl = param.url;
|
||||||
param.url = undefined;
|
param.url = undefined;
|
||||||
@ -228,10 +194,10 @@ layui.define(['layer', 'table'], function (exports) {
|
|||||||
},
|
},
|
||||||
// 检查参数
|
// 检查参数
|
||||||
checkParam: function (param) {
|
checkParam: function (param) {
|
||||||
/*if (!param.treeSpid && param.treeSpid != 0) {
|
if (!param.treeSpid && param.treeSpid != 0) {
|
||||||
layer.msg('参数treeSpid不能为空', {icon: 5});
|
layer.msg('参数treeSpid不能为空', {icon: 5});
|
||||||
return false;
|
return false;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
if (!param.treeIdName) {
|
if (!param.treeIdName) {
|
||||||
layer.msg('参数treeIdName不能为空', {icon: 5});
|
layer.msg('参数treeIdName不能为空', {icon: 5});
|
||||||
|
@ -92,6 +92,7 @@
|
|||||||
|
|
||||||
treetable.render({
|
treetable.render({
|
||||||
treeColIndex: 1,
|
treeColIndex: 1,
|
||||||
|
treeSpid: 0,
|
||||||
treeIdName: 'powerId',
|
treeIdName: 'powerId',
|
||||||
treePidName: 'parentId',
|
treePidName: 'parentId',
|
||||||
skin:'line',
|
skin:'line',
|
||||||
|
@ -104,6 +104,7 @@
|
|||||||
window.render = function(){
|
window.render = function(){
|
||||||
treetable.render({
|
treetable.render({
|
||||||
treeColIndex: 1,
|
treeColIndex: 1,
|
||||||
|
treeSpid: 0,
|
||||||
treeIdName: 'powerId',
|
treeIdName: 'powerId',
|
||||||
treePidName: 'parentId',
|
treePidName: 'parentId',
|
||||||
skin:'line',
|
skin:'line',
|
||||||
|
191
src/plugin/admin/webman-admin.sql
Normal file
191
src/plugin/admin/webman-admin.sql
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user