Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88bc6441e5 | ||
|
|
0efb70b3b7 | ||
|
|
c22be8ac76 | ||
|
|
ebce7f3b0e | ||
|
|
f8b6d847d5 | ||
|
|
55a9b13e69 | ||
|
|
5d58248cf4 | ||
|
|
bbd0320a35 | ||
|
|
d62a67aafe | ||
|
|
c6cc9d4164 | ||
|
|
add8c5144c | ||
|
|
62f591045e | ||
|
|
7470790657 | ||
|
|
11fa69afaf | ||
|
|
8983705ce4 | ||
|
|
95ccd4071b | ||
|
|
09f3ea7e54 | ||
|
|
9cadb27c9e | ||
|
|
2772034a93 | ||
|
|
08ea79033c | ||
|
|
e7f09d9c68 | ||
|
|
e2effb762c | ||
|
|
0e18825808 | ||
|
|
c031b09422 | ||
|
|
231fd48e2f | ||
|
|
53772badd4 | ||
|
|
34354837d5 |
38
README.md
38
README.md
@@ -1,27 +1,31 @@
|
|||||||
<div align="center" dir="auto">
|
<div align="center" dir="auto">
|
||||||
<img alt="log" src="/public/static/common/images/logo-8.png" />
|
<img alt="log" src="/public/static/common/images/logo-8.png" />
|
||||||
|
|
||||||
<span><img src="https://img.shields.io/badge/php-%3E=8.0.0-brightgreen.svg?style=for-the-badge&logo=php&colorB=ff69b4" alt="php"></span>
|
<p>
|
||||||
<span><img src="https://img.shields.io/badge/mysql-%3E=5.7-brightgreen.svg?style=for-the-badge&logo=mysql&colorB=blue" alt="MySQL"></span>
|
<img src="https://img.shields.io/badge/php-%3E=8.1.0-brightgreen.svg?style=for-the-badge&logo=php&colorB=ff69b4" alt="php">
|
||||||
<span><img src="https://img.shields.io/badge/thinkphp-%3E=8.0.0-brightgreen.svg?style=for-the-badge&logo=thinkphp" alt="ThinkPHP"></span>
|
<img src="https://img.shields.io/badge/mysql-%3E=5.7-brightgreen.svg?style=for-the-badge&logo=mysql&colorB=blue" alt="MySQL">
|
||||||
<span><img src="https://img.shields.io/badge/layui-%3E=2.9.0-brightgreen.svg?style=for-the-badge&logo=layui&colorB=orange" alt="layui"></span>
|
<img src="https://img.shields.io/badge/thinkphp-%3E=8.0.0-brightgreen.svg?style=for-the-badge&logo=thinkphp" alt="ThinkPHP">
|
||||||
<span><img src="https://img.shields.io/badge/license-MIT-green?style=for-the-badge&logo=license&colorB=purple" alt="License"></span>
|
<img src="https://img.shields.io/badge/layui-%3E=2.9.0-brightgreen.svg?style=for-the-badge&logo=layui&colorB=orange" alt="layui">
|
||||||
|
<img src="https://img.shields.io/badge/license-MIT-green?style=for-the-badge&logo=license&colorB=purple" alt="License">
|
||||||
|
</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## `EasyAdmin8`所有版本 (当前项目为`ThinkPHP`版本)
|
## `EasyAdmin8`所有版本 (当前项目为`ThinkPHP`版本)
|
||||||
|
|
||||||
| | Github | Gitee |
|
| | Github | Gitee |
|
||||||
|----------|:--------------------------------------------------------------------:|:-----------------------------------------------------------------:|
|
|----------|:----------------------------------------------------------------------:|:---------------------------------------------------------------------:|
|
||||||
| ThinkPHP | [EasyAdmin8](https://github.com/wolf-leo/EasyAdmin8) | [EasyAdmin8](https://gitee.com/wolf18/EasyAdmin8) |
|
| ThinkPHP | [EasyAdmin8](https://github.com/EasyAdmin8/EasyAdmin8) | [EasyAdmin8](https://gitee.com/EasyAdmin8/EasyAdmin8) |
|
||||||
| Laravel | [EasyAdmin8-Laravel](https://github.com/wolf-leo/EasyAdmin8-Laravel) | [EasyAdmin8-Laravel](https://gitee.com/wolf18/EasyAdmin8-Laravel) |
|
| Laravel | [EasyAdmin8-Laravel](https://github.com/EasyAdmin8/EasyAdmin8-Laravel) | [EasyAdmin8-Laravel](https://gitee.com/EasyAdmin8/EasyAdmin8-Laravel) |
|
||||||
| webman | [EasyAdmin8-webman](https://github.com/wolf-leo/EasyAdmin8-webman) | [EasyAdmin8-webman](https://gitee.com/wolf18/EasyAdmin8-webman) |
|
| webman | [EasyAdmin8-webman](https://github.com/EasyAdmin8/EasyAdmin8-webman) | [EasyAdmin8-webman](https://gitee.com/EasyAdmin8/EasyAdmin8-webman) |
|
||||||
|
|
||||||
## 项目介绍
|
## 项目介绍
|
||||||
|
|
||||||
> `EasyAdmin8` 在 [`EasyAdmin`](https://gitee.com/zhongshaofa/easyadmin) 的基础上更新 ThinkPHP 框架到 8.0 ,PHP 最低版本要求不低于 8.0
|
> `EasyAdmin8` 在 [`EasyAdmin`](https://gitee.com/zhongshaofa/easyadmin) 的基础上更新 ThinkPHP 框架到 8.0+ ,PHP 最低版本要求不低于 8.1
|
||||||
|
>
|
||||||
|
> 2025年起 `PHP` 版本要求提升到 `8.1+`, 如果需要 `8.0` 到分支 `v8.0` 中下载
|
||||||
>
|
>
|
||||||
> ThinkPHP v8.0 和 Layui v2.9.x 的快速开发的后台管理系统。
|
> ThinkPHP v8.0+ 和 Layui v2.9.x 的快速开发的后台管理系统。
|
||||||
>
|
>
|
||||||
> 项目地址:[http://easyadmin8.top](http://easyadmin8.top)
|
> 项目地址:[http://easyadmin8.top](http://easyadmin8.top)
|
||||||
>
|
>
|
||||||
@@ -50,13 +54,13 @@ if [ -f /usr/bin/curl ];then curl -sSO https://easyadmin8.top/auto-install-EasyA
|
|||||||
```
|
```
|
||||||
1.下载安装包
|
1.下载安装包
|
||||||
|
|
||||||
git clone https://github.com/wolf-leo/EasyAdmin8
|
git clone https://github.com/EasyAdmin8/EasyAdmin8
|
||||||
|
|
||||||
或者
|
或者
|
||||||
|
|
||||||
git clone https://gitee.com/wolf18/EasyAdmin8
|
git clone https://gitee.com/EasyAdmin8/EasyAdmin8
|
||||||
|
|
||||||
2.安装依赖包(确保 PHP 版本 >= 8.0)
|
2.安装依赖包(确保 PHP 版本 >= 8.1)
|
||||||
|
|
||||||
在根目录下 composer install ,如果有报错信息可以使用命令 composer install --ignore-platform-reqs
|
在根目录下 composer install ,如果有报错信息可以使用命令 composer install --ignore-platform-reqs
|
||||||
|
|
||||||
@@ -75,7 +79,7 @@ if [ -f /usr/bin/curl ];then curl -sSO https://easyadmin8.top/auto-install-EasyA
|
|||||||
|
|
||||||
## CURD命令大全
|
## CURD命令大全
|
||||||
|
|
||||||
> 参考 [CURD命令大全](CURD.md)
|
> 参考 [CURD命令大全](https://edocs.easyadmin8.top/curd/command.html)
|
||||||
|
|
||||||
## 常见问题
|
## 常见问题
|
||||||
|
|
||||||
@@ -97,7 +101,7 @@ if [ -f /usr/bin/curl ];then curl -sSO https://easyadmin8.top/auto-install-EasyA
|
|||||||
|
|
||||||
## 相关文档
|
## 相关文档
|
||||||
|
|
||||||
* [ThinkPHP 8.0](https://doc.thinkphp.cn/v8_0)
|
* [ThinkPHP 8.1](https://doc.thinkphp.cn)
|
||||||
|
|
||||||
* [EasyAdmin](http://easyadmin.99php.cn/docs)
|
* [EasyAdmin](http://easyadmin.99php.cn/docs)
|
||||||
|
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ class Index extends AdminController
|
|||||||
$old_secret = $row->ga_secret;
|
$old_secret = $row->ga_secret;
|
||||||
$secret = $ga->createSecret(32);
|
$secret = $ga->createSecret(32);
|
||||||
$ga_title = $this->isDemo ? 'EasyAdmin8演示环境' : '可自定义修改显示标题';
|
$ga_title = $this->isDemo ? 'EasyAdmin8演示环境' : '可自定义修改显示标题';
|
||||||
$dataUri = $ga->getQRCode($ga_title, $secret)->getDataUri();
|
$dataUri = $ga->getQRCode($ga_title, $secret);
|
||||||
$this->assign(compact('row', 'dataUri', 'old_secret', 'secret'));
|
$this->assign(compact('row', 'dataUri', 'old_secret', 'secret'));
|
||||||
return $this->fetch();
|
return $this->fetch();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,12 @@ use think\response\Json;
|
|||||||
class Goods extends AdminController
|
class Goods extends AdminController
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过滤不需要生成的权限节点 默认 CURD 中会自动生成部分节点 可以在此处过滤
|
||||||
|
* @var array[]
|
||||||
|
*/
|
||||||
|
protected array $ignoreNode = ['export'];
|
||||||
|
|
||||||
public function __construct(App $app)
|
public function __construct(App $app)
|
||||||
{
|
{
|
||||||
parent::__construct($app);
|
parent::__construct($app);
|
||||||
|
|||||||
@@ -150,9 +150,10 @@ class Admin extends AdminController
|
|||||||
/**
|
/**
|
||||||
* @NodeAnnotation(title="删除")
|
* @NodeAnnotation(title="删除")
|
||||||
*/
|
*/
|
||||||
public function delete($id): void
|
public function delete(Request $request): void
|
||||||
{
|
{
|
||||||
$this->checkPostRequest();
|
$this->checkPostRequest();
|
||||||
|
$id = $request->param('id');
|
||||||
$row = $this->model->whereIn('id', $id)->select();
|
$row = $this->model->whereIn('id', $id)->select();
|
||||||
$row->isEmpty() && $this->error('数据不存在');
|
$row->isEmpty() && $this->error('数据不存在');
|
||||||
$id == AdminConstant::SUPER_ADMIN_ID && $this->error('超级管理员不允许修改');
|
$id == AdminConstant::SUPER_ADMIN_ID && $this->error('超级管理员不允许修改');
|
||||||
|
|||||||
@@ -132,9 +132,10 @@ class Menu extends AdminController
|
|||||||
/**
|
/**
|
||||||
* @NodeAnnotation(title="删除")
|
* @NodeAnnotation(title="删除")
|
||||||
*/
|
*/
|
||||||
public function delete($id): void
|
public function delete(Request $request): void
|
||||||
{
|
{
|
||||||
$this->checkPostRequest();
|
$this->checkPostRequest();
|
||||||
|
$id = $request->param('id');
|
||||||
$row = $this->model->whereIn('id', $id)->select();
|
$row = $this->model->whereIn('id', $id)->select();
|
||||||
empty($row) && $this->error('数据不存在');
|
empty($row) && $this->error('数据不存在');
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ class SystemLog
|
|||||||
$pathInfoExp = explode('.', $pathInfoExp[0] ?? '');
|
$pathInfoExp = explode('.', $pathInfoExp[0] ?? '');
|
||||||
$_name = $pathInfoExp[0] ?? '';
|
$_name = $pathInfoExp[0] ?? '';
|
||||||
$_controller = ucfirst($pathInfoExp[1] ?? '');
|
$_controller = ucfirst($pathInfoExp[1] ?? '');
|
||||||
if ($_name && $_controller && $_action) {
|
$className = $_controller ? "app\admin\controller\\{$_name}\\{$_controller}" : "app\admin\controller\\{$_name}";
|
||||||
$className = "app\admin\controller\\{$_name}\\{$_controller}";
|
if ($_name && $_action) {
|
||||||
$reflectionClass = new \ReflectionClass($className);
|
$reflectionClass = new \ReflectionClass($className);
|
||||||
$properties = $reflectionClass->getDefaultProperties();
|
$properties = $reflectionClass->getDefaultProperties();
|
||||||
$ignoreLog = $properties['ignoreLog'] ?? [];
|
$ignoreLog = $properties['ignoreLog'] ?? [];
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace app\admin\service;
|
|||||||
|
|
||||||
use app\admin\model\SystemUploadfile;
|
use app\admin\model\SystemUploadfile;
|
||||||
use OSS\Core\OssException;
|
use OSS\Core\OssException;
|
||||||
|
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
|
||||||
use OSS\OssClient;
|
use OSS\OssClient;
|
||||||
use think\facade\Env;
|
use think\facade\Env;
|
||||||
use think\file\UploadedFile;
|
use think\file\UploadedFile;
|
||||||
@@ -112,10 +113,21 @@ class UploadService
|
|||||||
$accessKeySecret = $config['oss_access_key_secret'];
|
$accessKeySecret = $config['oss_access_key_secret'];
|
||||||
$endpoint = $config['oss_endpoint'];
|
$endpoint = $config['oss_endpoint'];
|
||||||
$bucket = $config['oss_bucket'];
|
$bucket = $config['oss_bucket'];
|
||||||
|
// 升级 aliyuncs/oss-sdk-php 到 v2.7.2 以上, 使用签名 v4 版本
|
||||||
|
putenv('OSS_ACCESS_KEY_ID=' . $accessKeyId);
|
||||||
|
putenv('OSS_ACCESS_KEY_SECRET=' . $accessKeySecret);
|
||||||
|
$region = str_replace(['http://oss-', 'https://oss-', 'oss-'], '', explode('.aliyuncs.com', $endpoint)[0] ?? '');
|
||||||
|
$provider = new EnvironmentVariableCredentialsProvider();
|
||||||
|
$args = [
|
||||||
|
"provider" => $provider,
|
||||||
|
"endpoint" => $endpoint,
|
||||||
|
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
|
||||||
|
"region" => $region
|
||||||
|
];
|
||||||
if ($file->isValid()) {
|
if ($file->isValid()) {
|
||||||
$object = $this->setFilePath($file, Env::get('EASYADMIN.OSS_STATIC_PREFIX', 'easyadmin8') . '/');
|
$object = $this->setFilePath($file, Env::get('EASYADMIN.OSS_STATIC_PREFIX', 'easyadmin8') . '/');
|
||||||
try {
|
try {
|
||||||
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
|
$ossClient = new OssClient($args);
|
||||||
$_rs = $ossClient->putObject($bucket, $object, file_get_contents($file->getRealPath()));
|
$_rs = $ossClient->putObject($bucket, $object, file_get_contents($file->getRealPath()));
|
||||||
$oss_request_url = $_rs['oss-request-url'] ?? '';
|
$oss_request_url = $_rs['oss-request-url'] ?? '';
|
||||||
if (empty($oss_request_url)) return ['code' => 0, 'data' => '上传至OSS失败'];
|
if (empty($oss_request_url)) return ['code' => 0, 'data' => '上传至OSS失败'];
|
||||||
@@ -164,7 +176,7 @@ class UploadService
|
|||||||
if (empty($location)) return ['code' => 0, 'data' => '上传至COS失败'];
|
if (empty($location)) return ['code' => 0, 'data' => '上传至COS失败'];
|
||||||
$location = 'https://' . $location;
|
$location = 'https://' . $location;
|
||||||
$this->setSaveData($file);
|
$this->setSaveData($file);
|
||||||
} catch (Exception $e) {
|
}catch (Exception $e) {
|
||||||
return ['code' => 0, 'data' => $e->getMessage()];
|
return ['code' => 0, 'data' => $e->getMessage()];
|
||||||
}
|
}
|
||||||
$data = ['url' => $location];
|
$data = ['url' => $location];
|
||||||
|
|||||||
@@ -67,6 +67,12 @@ class Node
|
|||||||
|
|
||||||
// 遍历读取所有方法的注释的参数信息
|
// 遍历读取所有方法的注释的参数信息
|
||||||
foreach ($methods as $method) {
|
foreach ($methods as $method) {
|
||||||
|
|
||||||
|
// 忽略的节点
|
||||||
|
$properties = $reflectionClass->getDefaultProperties();
|
||||||
|
$ignoreNode = $properties['ignoreNode'] ?? [];
|
||||||
|
if (!empty($ignoreNode)) if (in_array($method->name, $ignoreNode)) continue;
|
||||||
|
|
||||||
// 读取NodeAnnotation的注解
|
// 读取NodeAnnotation的注解
|
||||||
$nodeAnnotation = $reader->getMethodAnnotation($method, NodeAnnotation::class);
|
$nodeAnnotation = $reader->getMethodAnnotation($method, NodeAnnotation::class);
|
||||||
if (!empty($nodeAnnotation)) {
|
if (!empty($nodeAnnotation)) {
|
||||||
|
|||||||
@@ -392,7 +392,7 @@ class BuildCurd
|
|||||||
if (!empty($bindSelectField)) {
|
if (!empty($bindSelectField)) {
|
||||||
$relationArray = explode('\\', $modelFilename);
|
$relationArray = explode('\\', $modelFilename);
|
||||||
$this->tableColumns[$foreignKey]['bindSelectField'] = $bindSelectField;
|
$this->tableColumns[$foreignKey]['bindSelectField'] = $bindSelectField;
|
||||||
$this->tableColumns[$foreignKey]['bindRelation'] = end($relationArray);
|
$this->tableColumns[$foreignKey]['bindRelation'] = lcfirst(end($relationArray)) . ucfirst($bindSelectField);
|
||||||
}
|
}
|
||||||
$this->relationArray[$relationTable] = $relation;
|
$this->relationArray[$relationTable] = $relation;
|
||||||
$this->selectFields[] = $foreignKey;
|
$this->selectFields[] = $foreignKey;
|
||||||
@@ -1027,7 +1027,8 @@ class BuildCurd
|
|||||||
*/
|
*/
|
||||||
protected function renderController(): static
|
protected function renderController(): static
|
||||||
{
|
{
|
||||||
$controllerFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}controller{$this->DS}{$this->controllerFilename}.php";
|
$controllerFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}controller{$this->DS}{$this->controllerFilename}.php";
|
||||||
|
$constructRelation = '';
|
||||||
if (empty($this->relationArray)) {
|
if (empty($this->relationArray)) {
|
||||||
$controllerIndexMethod = '';
|
$controllerIndexMethod = '';
|
||||||
}else {
|
}else {
|
||||||
@@ -1035,6 +1036,9 @@ class BuildCurd
|
|||||||
foreach ($this->relationArray as $key => $val) {
|
foreach ($this->relationArray as $key => $val) {
|
||||||
$relation = CommonTool::lineToHump($key);
|
$relation = CommonTool::lineToHump($key);
|
||||||
$relationCode = "->withJoin('{$relation}', 'LEFT')\r";
|
$relationCode = "->withJoin('{$relation}', 'LEFT')\r";
|
||||||
|
if (!empty($val['bindSelectField']) && !empty($val['primaryKey'])) {
|
||||||
|
$constructRelation = '$notes["' . lcfirst($val['modelFilename']) . ucfirst($val['bindSelectField']) . '"] = \app\admin\model\\' . $val['modelFilename'] . '::column("' . $val['bindSelectField'] . '", "' . $val['primaryKey'] . '");';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$controllerIndexMethod = CommonTool::replaceTemplate(
|
$controllerIndexMethod = CommonTool::replaceTemplate(
|
||||||
$this->getTemplate("controller{$this->DS}indexMethod"),
|
$this->getTemplate("controller{$this->DS}indexMethod"),
|
||||||
@@ -1066,6 +1070,7 @@ class BuildCurd
|
|||||||
'modelFilename' => "\app\admin\model\\{$modelFilenameExtend}",
|
'modelFilename' => "\app\admin\model\\{$modelFilenameExtend}",
|
||||||
'indexMethod' => $controllerIndexMethod,
|
'indexMethod' => $controllerIndexMethod,
|
||||||
'selectList' => $selectList,
|
'selectList' => $selectList,
|
||||||
|
'constructRelation' => $constructRelation,
|
||||||
]);
|
]);
|
||||||
$this->fileList[$controllerFile] = $controllerValue;
|
$this->fileList[$controllerFile] = $controllerValue;
|
||||||
return $this;
|
return $this;
|
||||||
@@ -1082,16 +1087,16 @@ class BuildCurd
|
|||||||
$relationList = '';
|
$relationList = '';
|
||||||
if (!empty($this->relationArray)) {
|
if (!empty($this->relationArray)) {
|
||||||
foreach ($this->relationArray as $key => $val) {
|
foreach ($this->relationArray as $key => $val) {
|
||||||
$relation = CommonTool::lineToHump($key);
|
$relation = CommonTool::lineToHump($key);
|
||||||
$relationCode = CommonTool::replaceTemplate(
|
// $relationCode = CommonTool::replaceTemplate(
|
||||||
$this->getTemplate("model{$this->DS}relation"),
|
// $this->getTemplate("model{$this->DS}relation"),
|
||||||
[
|
// [
|
||||||
'relationMethod' => $relation,
|
// 'relationMethod' => $relation,
|
||||||
'relationModel' => "\app\admin\model\\{$val['modelFilename']}",
|
// 'relationModel' => "\app\admin\model\\{$val['modelFilename']}",
|
||||||
'foreignKey' => $val['foreignKey'],
|
// 'foreignKey' => $val['foreignKey'],
|
||||||
'primaryKey' => $val['primaryKey'],
|
// 'primaryKey' => $val['primaryKey'],
|
||||||
]);
|
// ]);
|
||||||
$relationList .= $relationCode;
|
// $relationList .= $relationCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1126,6 +1131,7 @@ class BuildCurd
|
|||||||
'selectArrays' => CommonTool::replaceArrayString(var_export($selectArrays, true)),
|
'selectArrays' => CommonTool::replaceArrayString(var_export($selectArrays, true)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
$this->fileList[$modelFile] = $modelValue;
|
$this->fileList[$modelFile] = $modelValue;
|
||||||
|
|
||||||
// 关联模型
|
// 关联模型
|
||||||
@@ -1153,10 +1159,12 @@ class BuildCurd
|
|||||||
[
|
[
|
||||||
'modelName' => $val['modelName'],
|
'modelName' => $val['modelName'],
|
||||||
'modelNamespace' => "app\admin\model{$extendNamespace}",
|
'modelNamespace' => "app\admin\model{$extendNamespace}",
|
||||||
|
'prefix_table' => $this->tablePrefix == config('database.connections.mysql.prefix') ? "" : $this->tablePrefix . $this->table,
|
||||||
'table' => $key,
|
'table' => $key,
|
||||||
'deleteTime' => $val['delete'] ? '"delete_time"' : 'false',
|
'deleteTime' => $val['delete'] ? '"delete_time"' : 'false',
|
||||||
'relationList' => '',
|
'relationList' => '',
|
||||||
'selectList' => '',
|
'selectList' => '',
|
||||||
|
'selectArrays' => "[]",
|
||||||
]);
|
]);
|
||||||
$this->fileList[$relationModelFile] = $relationModelValue;
|
$this->fileList[$relationModelFile] = $relationModelValue;
|
||||||
}
|
}
|
||||||
@@ -1302,7 +1310,6 @@ class BuildCurd
|
|||||||
$templateFile = "view{$this->DS}module{$this->DS}textarea";
|
$templateFile = "view{$this->DS}module{$this->DS}textarea";
|
||||||
$value = '{$row.' . $field . '|raw|default=\'\'}';
|
$value = '{$row.' . $field . '|raw|default=\'\'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
$editFormList .= CommonTool::replaceTemplate(
|
$editFormList .= CommonTool::replaceTemplate(
|
||||||
$this->getTemplate($templateFile),
|
$this->getTemplate($templateFile),
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
namespace EasyAdmin\curd\exceptions;
|
namespace app\admin\service\curd\exceptions;
|
||||||
|
|
||||||
class CurdException extends \Exception
|
class CurdException extends \Exception
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
namespace EasyAdmin\curd\exceptions;
|
namespace app\admin\service\curd\exceptions;
|
||||||
|
|
||||||
class FileException extends \Exception
|
class FileException extends \Exception
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
namespace app\admin\service\curd\exceptions;
|
namespace app\admin\service\curd\exceptions;
|
||||||
|
|
||||||
class TableException extends \Exception
|
class TableException extends \Exception
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -20,6 +20,7 @@ class {{controllerName}} extends AdminController
|
|||||||
parent::__construct($app);
|
parent::__construct($app);
|
||||||
$this->model = new {{modelFilename}}();
|
$this->model = new {{modelFilename}}();
|
||||||
$this->notes = $notes = $this->model->notes;
|
$this->notes = $notes = $this->model->notes;
|
||||||
|
{{constructRelation}}
|
||||||
$this->assign(compact('notes'));
|
$this->assign(compact('notes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
|
|
||||||
/**
|
|
||||||
* @NodeAnnotation(title="列表")
|
|
||||||
*/
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
if ($this->request->isAjax()) {
|
|
||||||
if (input('selectFields')) {
|
|
||||||
return $this->selectList();
|
|
||||||
}
|
|
||||||
list($page, $limit, $where) = $this->buildTableParams();
|
|
||||||
$count = $this->model{{relationIndexMethod}}->where($where)->count();
|
|
||||||
$list = $this->model{{relationIndexMethod}}->where($where)->page($page, $limit)->order($this->sort)->select()->toArray();
|
|
||||||
$data = [
|
|
||||||
'code' => 0,
|
|
||||||
'msg' => '',
|
|
||||||
'count' => $count,
|
|
||||||
'data' => $list,
|
|
||||||
];
|
|
||||||
return json($data);
|
|
||||||
}
|
|
||||||
return $this->fetch();
|
|
||||||
}
|
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
data-auth-edit="{:auth('{{controllerUrl}}/edit')}"
|
data-auth-edit="{:auth('{{controllerUrl}}/edit')}"
|
||||||
data-auth-delete="{:auth('{{controllerUrl}}/delete')}"
|
data-auth-delete="{:auth('{{controllerUrl}}/delete')}"
|
||||||
lay-filter="currentTable">
|
lay-filter="currentTable">
|
||||||
|
<!-- searchTableShow="false" 隐藏搜索框 -->
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -88,8 +88,10 @@ trait Curd
|
|||||||
/**
|
/**
|
||||||
* @NodeAnnotation(title="删除")
|
* @NodeAnnotation(title="删除")
|
||||||
*/
|
*/
|
||||||
public function delete($id): void
|
public function delete(Request $request): void
|
||||||
{
|
{
|
||||||
|
// 如果不是id作为主键 请在对应的控制器中覆盖重写
|
||||||
|
$id = $request->param('id', []);
|
||||||
$this->checkPostRequest();
|
$this->checkPostRequest();
|
||||||
$row = $this->model->whereIn('id', $id)->select();
|
$row = $this->model->whereIn('id', $id)->select();
|
||||||
$row->isEmpty() && $this->error('数据不存在');
|
$row->isEmpty() && $this->error('数据不存在');
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
<a href="javascript:" class="forget-password">忘记密码?</a>
|
<a href="javascript:" class="forget-password">忘记密码?</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item" style="text-align:center; width:100%;height:100%;margin:0px;">
|
<div class="layui-form-item" style="text-align:center; width:100%;height:100%;margin:0px;">
|
||||||
<button class="login-btn" lay-submit>立即登录</button>
|
<button type="button" class="login-btn" lay-submit>立即登录</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ if (!function_exists('__url')) {
|
|||||||
*/
|
*/
|
||||||
function __url(string $url = '', array $vars = [], bool $suffix = true, bool $domain = false): string
|
function __url(string $url = '', array $vars = [], bool $suffix = true, bool $domain = false): string
|
||||||
{
|
{
|
||||||
|
if (filter_var($url, FILTER_VALIDATE_URL)) return $url;
|
||||||
return url($url, $vars, $suffix, $domain)->build();
|
return url($url, $vars, $suffix, $domain)->build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,6 +168,12 @@ class Curd extends Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (PHP_SAPI == 'cli') {
|
||||||
|
$output->info(">>>>>>>>>>>>>>>");
|
||||||
|
$output->info('执行成功');
|
||||||
|
}else {
|
||||||
|
$output->writeln('执行成功');
|
||||||
|
}
|
||||||
}catch (\Exception $e) {
|
}catch (\Exception $e) {
|
||||||
if (PHP_SAPI == 'cli')
|
if (PHP_SAPI == 'cli')
|
||||||
CliEcho::error($e->getMessage());
|
CliEcho::error($e->getMessage());
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace app\common\command;
|
|
||||||
|
|
||||||
use EasyAdmin\console\CliEcho;
|
|
||||||
use EasyAdmin\tool\CommonTool;
|
|
||||||
use EasyAdmin\upload\driver\alioss\Oss;
|
|
||||||
use think\console\Command;
|
|
||||||
use think\console\Input;
|
|
||||||
use think\console\input\Option;
|
|
||||||
use think\console\Output;
|
|
||||||
|
|
||||||
class OssStatic extends Command
|
|
||||||
{
|
|
||||||
|
|
||||||
protected function configure()
|
|
||||||
{
|
|
||||||
$this->setName('OssStatic')
|
|
||||||
->setDescription('将静态资源上传到oss上');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function execute(Input $input, Output $output)
|
|
||||||
{
|
|
||||||
$output->writeln("========正在上传静态资源到OSS上:========" . date('Y-m-d H:i:s'));
|
|
||||||
$dir = root_path() . 'public' . DIRECTORY_SEPARATOR . 'static';
|
|
||||||
$list = CommonTool::readDirAllFiles($dir);
|
|
||||||
$uploadConfig = sysConfig('upload');
|
|
||||||
$uploadPrefix = config('app.oss_static_prefix', 'oss_static_prefix');
|
|
||||||
foreach ($list as $key => $val) {
|
|
||||||
list($objectName, $filePath) = [$uploadPrefix . DIRECTORY_SEPARATOR . $key, $val];
|
|
||||||
try {
|
|
||||||
$upload = Oss::instance($uploadConfig)
|
|
||||||
->save($objectName, $filePath);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
CliEcho::error('文件上传失败:' . $filePath . '。错误信息:' . $e->getMessage());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ($upload['save'] == true) {
|
|
||||||
CliEcho::success('文件上传成功:' . $filePath . '。上传地址:' . $upload['url']);
|
|
||||||
} else {
|
|
||||||
CliEcho::error('文件上传失败:' . $filePath . '。错误信息:' . $upload['msg']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$output->writeln("========已完成静态资源上传到OSS上:========" . date('Y-m-d H:i:s'));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
namespace app\common\service;
|
namespace app\common\service;
|
||||||
|
|
||||||
use app\common\constants\AdminConstant;
|
use app\common\constants\AdminConstant;
|
||||||
use EasyAdmin\tool\CommonTool;
|
|
||||||
use think\facade\Db;
|
use think\facade\Db;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -91,12 +91,11 @@ class Install extends BaseController
|
|||||||
$installPath = config_path() . DIRECTORY_SEPARATOR . 'install' . DIRECTORY_SEPARATOR;
|
$installPath = config_path() . DIRECTORY_SEPARATOR . 'install' . DIRECTORY_SEPARATOR;
|
||||||
$sqlPath = file_get_contents($installPath . 'sql' . DIRECTORY_SEPARATOR . 'install.sql');
|
$sqlPath = file_get_contents($installPath . 'sql' . DIRECTORY_SEPARATOR . 'install.sql');
|
||||||
$sqlArray = $this->parseSql($sqlPath, $config['prefix'], 'ea_');
|
$sqlArray = $this->parseSql($sqlPath, $config['prefix'], 'ea_');
|
||||||
$conn = mysqli_connect($config['host'], $config['username'], $config['password'], null, $config['port']);
|
$dsn = $this->pdoDsn($config, true);
|
||||||
try {
|
try {
|
||||||
mysqli_set_charset($conn, $config['charset']);
|
$pdo = new \PDO($dsn, $config['username'] ?? 'root', $config['password'] ?? '');
|
||||||
mysqli_select_db($conn, $config['database']);
|
|
||||||
foreach ($sqlArray as $sql) {
|
foreach ($sqlArray as $sql) {
|
||||||
mysqli_query($conn, $sql);
|
$pdo->query($sql);
|
||||||
}
|
}
|
||||||
$_password = password($password);
|
$_password = password($password);
|
||||||
$tableName = 'system_admin';
|
$tableName = 'system_admin';
|
||||||
@@ -108,9 +107,8 @@ class Install extends BaseController
|
|||||||
'update_time' => time()
|
'update_time' => time()
|
||||||
];
|
];
|
||||||
foreach ($update as $_k => $_up) {
|
foreach ($update as $_k => $_up) {
|
||||||
mysqli_query($conn, "UPDATE {$config['prefix']}{$tableName} SET {$_k} = '{$_up}' WHERE id = 1");
|
$pdo->query("UPDATE {$config['prefix']}{$tableName} SET {$_k} = '{$_up}' WHERE id = 1");
|
||||||
}
|
}
|
||||||
mysqli_close($conn);
|
|
||||||
// 处理安装文件
|
// 处理安装文件
|
||||||
!is_dir($installPath) && @mkdir($installPath);
|
!is_dir($installPath) && @mkdir($installPath);
|
||||||
!is_dir($installPath . 'lock' . DIRECTORY_SEPARATOR) && @mkdir($installPath . 'lock' . DIRECTORY_SEPARATOR);
|
!is_dir($installPath . 'lock' . DIRECTORY_SEPARATOR) && @mkdir($installPath . 'lock' . DIRECTORY_SEPARATOR);
|
||||||
@@ -161,11 +159,11 @@ class Install extends BaseController
|
|||||||
|
|
||||||
protected function createDatabase($database, $config): bool
|
protected function createDatabase($database, $config): bool
|
||||||
{
|
{
|
||||||
|
$dsn = $this->pdoDsn($config);
|
||||||
try {
|
try {
|
||||||
$con = mysqli_connect($config['host'] ?? '127.0.0.1', $config['username'] ?? 'root', $config['password'] ?? '', null, $config['port'] ?? '');
|
$pdo = new \PDO($dsn, $config['username'] ?? 'root', $config['password'] ?? '');
|
||||||
mysqli_query($con, "CREATE DATABASE IF NOT EXISTS `{$database}` DEFAULT CHARACTER SET {$config['charset']} COLLATE=utf8mb4_general_ci");
|
$pdo->query("CREATE DATABASE IF NOT EXISTS `{$database}` DEFAULT CHARACTER SET {$config['charset']} COLLATE=utf8mb4_general_ci");
|
||||||
mysqli_close($con);
|
}catch (\PDOException $e) {
|
||||||
}catch (\Throwable $e) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -187,19 +185,32 @@ class Install extends BaseController
|
|||||||
|
|
||||||
protected function checkConnect(array $config): ?bool
|
protected function checkConnect(array $config): ?bool
|
||||||
{
|
{
|
||||||
|
$dsn = $this->pdoDsn($config);
|
||||||
try {
|
try {
|
||||||
$con = mysqli_connect($config['host'] ?? '127.0.0.1', $config['username'] ?? 'root', $config['password'] ?? '', null, $config['port'] ?? '');
|
$pdo = new \PDO($dsn, $config['username'] ?? 'root', $config['password'] ?? '');
|
||||||
$res = mysqli_query($con, 'select VERSION()');
|
$res = $pdo->query('select VERSION()');
|
||||||
$mysqlVersion = mysqli_fetch_row($res);
|
$_version = $res->fetch()[0] ?? 0;
|
||||||
mysqli_close($con);
|
|
||||||
$_version = $mysqlVersion[0] ?? 0;
|
|
||||||
if (version_compare($_version, '5.7.0', '<')) {
|
if (version_compare($_version, '5.7.0', '<')) {
|
||||||
$this->error('mysql版本最低要求 5.7.x');
|
$this->error('mysql版本最低要求 5.7.x');
|
||||||
}
|
}
|
||||||
}catch (\mysqli_sql_exception $e) {
|
}catch (\PDOException $e) {
|
||||||
$this->error($e->getMessage());
|
$this->error($e->getMessage());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $config
|
||||||
|
* @param bool $needDatabase
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function pdoDsn(array $config, bool $needDatabase = false): string
|
||||||
|
{
|
||||||
|
$host = $config['host'] ?? '127.0.0.1';
|
||||||
|
$database = $config['database'] ?? '';
|
||||||
|
$port = $config['port'] ?? '3306';
|
||||||
|
$charset = $config['charset'] ?? 'utf8mb4';
|
||||||
|
if ($needDatabase) return "mysql:host=$host;port=$port;dbname=$database;charset=$charset";
|
||||||
|
return "mysql:host=$host;port=$port;charset=$charset";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -20,10 +20,10 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.0.0",
|
"php": ">=8.1.0",
|
||||||
"topthink/framework": "^8.0",
|
"topthink/framework": "^8.0",
|
||||||
"topthink/think-orm": "^3.0",
|
"topthink/think-orm": "^3.0",
|
||||||
"topthink/think-multi-app": "^1.0",
|
"topthink/think-multi-app": "^1.1.0",
|
||||||
"topthink/think-view": "^2.0",
|
"topthink/think-view": "^2.0",
|
||||||
"topthink/think-captcha": "^3.0",
|
"topthink/think-captcha": "^3.0",
|
||||||
"topthink/think-filesystem": "^2.0",
|
"topthink/think-filesystem": "^2.0",
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
"ext-mysqli": "*",
|
"ext-mysqli": "*",
|
||||||
"ext-pdo": "*",
|
"ext-pdo": "*",
|
||||||
"wolf-leo/phplogviewer": "^0.11.3",
|
"wolf-leo/phplogviewer": "^0.11.3",
|
||||||
"wolfcode/authenticator": "^0.0.3"
|
"wolfcode/authenticator": "^0.0.6"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/var-dumper": ">=4.2",
|
"symfony/var-dumper": ">=4.2",
|
||||||
|
|||||||
@@ -42,4 +42,6 @@ return [
|
|||||||
'default_jsonp_handler' => 'jsonpReturn',
|
'default_jsonp_handler' => 'jsonpReturn',
|
||||||
// 默认JSONP处理方法
|
// 默认JSONP处理方法
|
||||||
'var_jsonp_handler' => 'callback',
|
'var_jsonp_handler' => 'callback',
|
||||||
|
// 操作方法的参数绑定方式 route get param
|
||||||
|
'action_bind_param' => 'param',
|
||||||
];
|
];
|
||||||
|
|||||||
1
log.md
1
log.md
@@ -1,2 +1,3 @@
|
|||||||
|
> 2025年01月01日 `PHP` 要求升级到 `8.1+`
|
||||||
>
|
>
|
||||||
> 2024年05月 更新 `EasyAdmin8` 重置版,多处语法、写法进行变更
|
> 2024年05月 更新 `EasyAdmin8` 重置版,多处语法、写法进行变更
|
||||||
@@ -57,6 +57,10 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
|||||||
templet: ea.table.tool,
|
templet: ea.table.tool,
|
||||||
operat: [
|
operat: [
|
||||||
[{
|
[{
|
||||||
|
templet: function (d) {
|
||||||
|
return `<button type="button" class="layui-btn layui-btn-xs">自定义 ${d.id}</button>`
|
||||||
|
}
|
||||||
|
}, {
|
||||||
text: '编辑',
|
text: '编辑',
|
||||||
url: init.edit_url,
|
url: init.edit_url,
|
||||||
method: 'open',
|
method: 'open',
|
||||||
|
|||||||
@@ -399,6 +399,15 @@ define(["jquery", "tableSelect"], function ($, tableSelect) {
|
|||||||
'</div>\n' +
|
'</div>\n' +
|
||||||
'</div>';
|
'</div>';
|
||||||
break;
|
break;
|
||||||
|
case 'date':
|
||||||
|
d.searchOp = '=';
|
||||||
|
formHtml += `<div class="layui-form-item layui-inline">
|
||||||
|
<label class="layui-form-label">${d.title}</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<input data-date data-date-type="date" id="c-${d.fieldAlias}" name="${d.fieldAlias}" data-search-op="${d.searchOp}" value="${d.searchValue}" placeholder="${d.searchTip}" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
newCols.push(d);
|
newCols.push(d);
|
||||||
}
|
}
|
||||||
@@ -663,6 +672,12 @@ define(["jquery", "tableSelect"], function ($, tableSelect) {
|
|||||||
|
|
||||||
$.each(item, function (i, operat) {
|
$.each(item, function (i, operat) {
|
||||||
if (typeof operat !== 'object') return
|
if (typeof operat !== 'object') return
|
||||||
|
|
||||||
|
if ('function' === typeof operat.templet) {
|
||||||
|
html += operat.templet(data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
operat.class = operat.class || '';
|
operat.class = operat.class || '';
|
||||||
operat.icon = operat.icon || '';
|
operat.icon = operat.icon || '';
|
||||||
operat.auth = operat.auth || '';
|
operat.auth = operat.auth || '';
|
||||||
|
|||||||
2
public/static/plugs/easymde/easymde.min.js
vendored
2
public/static/plugs/easymde/easymde.min.js
vendored
@@ -8184,7 +8184,7 @@
|
|||||||
if (!1 === e.autoDownloadFontAwesome && (t = !1), !0 !== e.autoDownloadFontAwesome) for (var n = document.styleSheets, i = 0; i < n.length; i++) n[i].href && n[i].href.indexOf("//maxcdn.bootstrapcdn.com/font-awesome/") > -1 && (t = !1);
|
if (!1 === e.autoDownloadFontAwesome && (t = !1), !0 !== e.autoDownloadFontAwesome) for (var n = document.styleSheets, i = 0; i < n.length; i++) n[i].href && n[i].href.indexOf("//maxcdn.bootstrapcdn.com/font-awesome/") > -1 && (t = !1);
|
||||||
if (t) {
|
if (t) {
|
||||||
var r = document.createElement("link");
|
var r = document.createElement("link");
|
||||||
r.rel = "stylesheet", r.href = "https://maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css", document.getElementsByTagName("head")[0].appendChild(r)
|
r.rel = "stylesheet", r.href = "/static/plugs/font-awesome-4.7.0/css/font-awesome.min.css", document.getElementsByTagName("head")[0].appendChild(r)
|
||||||
}
|
}
|
||||||
if (e.element) this.element = e.element; else if (null === e.element) return void console.log("EasyMDE: Error. No element was found.");
|
if (e.element) this.element = e.element; else if (null === e.element) return void console.log("EasyMDE: Error. No element was found.");
|
||||||
if (void 0 === e.toolbar) for (var o in e.toolbar = [], te) Object.prototype.hasOwnProperty.call(te, o) && (-1 != o.indexOf("separator-") && e.toolbar.push("|"), (!0 === te[o].default || e.showIcons && e.showIcons.constructor === Array && -1 != e.showIcons.indexOf(o)) && e.toolbar.push(o));
|
if (void 0 === e.toolbar) for (var o in e.toolbar = [], te) Object.prototype.hasOwnProperty.call(te, o) && (-1 != o.indexOf("separator-") && e.toolbar.push("|"), (!0 === te[o].default || e.showIcons && e.showIcons.constructor === Array && -1 != e.showIcons.indexOf(o)) && e.toolbar.push(o));
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user