将最新的代码合并到当前开发分支中

This commit is contained in:
2022-12-14 16:40:11 +08:00
23 changed files with 145 additions and 221 deletions

6
.gitignore vendored
View File

@@ -10,5 +10,7 @@ vendor
runtime
ul.db
/app/tools/controller/Install.php
/build
/composer.lock
/app/common/command/curd/migrate_output.php
/dist
/composer.lock
/public/storage

View File

@@ -8,12 +8,5 @@ return [
// 路由中间件
'middleware' => [
// // 后台视图初始化
// \app\admin\middleware\ViewInit::class,
// 检测用户是否登录
// \app\admin\middleware\CheckAdmin::class,
],
];

View File

@@ -11,11 +11,4 @@ return [
// Csrf安全校验
\app\admin\middleware\CsrfMiddleware::class,
// 后台视图初始化
// \app\admin\middleware\ViewInit::class,
// 检测用户是否登录
// \app\admin\middleware\CheckAdmin::class,
];

View File

@@ -1,58 +0,0 @@
<?php
namespace app\admin\middleware;
use app\common\service\AuthService;
use think\Request;
/**
* @deprecated 废弃新版TP不支持在中间件获取控制器相关信息
* 检测用户登录和节点权限
* Class CheckAdmin
* @package app\admin\middleware
*/
class CheckAdmin
{
use \app\common\traits\JumpTrait;
public function handle(Request $request, \Closure $next)
{
$adminConfig = config('admin');
$adminId = session('admin.id');
$expireTime = session('admin.expire_time');
/** @var AuthService $authService */
$authService = app(AuthService::class, ['adminId' => $adminId]);
$currentNode = $authService->getCurrentNode();
$currentController = parse_name($request->controller());
// 验证登录
if (!in_array($currentController, $adminConfig['no_login_controller']) &&
!in_array($currentNode, $adminConfig['no_login_node'])) {
empty($adminId) && $this->error('请先登录后台', [], __url('admin/login/index'));
// 判断是否登录过期
if ($expireTime !== true && time() > $expireTime) {
session('admin', null);
$this->error('登录已过期,请重新登录', [], __url('admin/login/index'));
}
}
// 验证权限
if (!in_array($currentController, $adminConfig['no_auth_controller']) &&
!in_array($currentNode, $adminConfig['no_auth_node'])) {
$check = $authService->checkNode($currentNode);
!$check && $this->error('无权限访问');
// 判断是否为演示环境
if(env('adminsystem.is_demo', false) && $request->isPost()){
$this->error('演示环境下不允许修改');
}
}
return $next($request);
}
}

View File

@@ -1,49 +0,0 @@
<?php
namespace app\admin\middleware;
use app\admin\service\ConfigService;
use app\common\constants\AdminConstant;
use think\App;
use think\facade\Request;
use think\facade\View;
/**
* @deprecated 废弃新版TP不支持在中间件获取控制器相关信息
* Class ViewInit
* @package app\admin\middleware
*/
class ViewInit
{
public function handle(\app\Request $request, \Closure $next)
{
list($thisModule, $thisController, $thisAction) = [app('http')->getName(), Request::controller(), $request->action()];
list($thisControllerArr, $jsPath) = [explode('.', $thisController), null];
foreach ($thisControllerArr as $vo) {
empty($jsPath) ? $jsPath = parse_name($vo) : $jsPath .= '/' . parse_name($vo);
}
$autoloadJs = file_exists(root_path('public')."static/{$thisModule}/js/{$jsPath}.js") ? true : false;
$thisControllerJsPath = "{$thisModule}/js/{$jsPath}.js";
$adminModuleName = config('app.admin_alias_name');
$isSuperAdmin = session('admin.id') == AdminConstant::SUPER_ADMIN_ID ? true : false;
$data = [
'adminModuleName' => $adminModuleName,
'thisController' => parse_name($thisController),
'thisAction' => $thisAction,
'thisRequest' => parse_name("{$thisModule}/{$thisController}/{$thisAction}"),
'thisControllerJsPath' => "{$thisControllerJsPath}",
'autoloadJs' => $autoloadJs,
'isSuperAdmin' => $isSuperAdmin,
'version' => env('app_debug') ? time() : ConfigService::getVersion(),
];
View::assign($data);
$request->adminModuleName = $adminModuleName;
return $next($request);
}
}

View File

@@ -1,22 +0,0 @@
<?php
namespace app\admin\service;
use think\facade\Cache;
class ConfigService
{
public static function getVersion()
{
$version = Cache('version');
if (empty($version)) {
$version = sysconfig('site', 'site_version');
cache('site_version', $version);
Cache::set('version', $version, 3600);
}
return $version;
}
}

View File

@@ -21,5 +21,11 @@
$content = \app\common\tools\ExportTools::excel($this->model, $where, $fields, $image_fields, $select_fields, $date_fields);
return download($content, $this->model->getName() . date('YmdHis') . '.xlsx', true);
$export_file_name = $this->exportFileName;
if (empty($export_file_name)) {
$export_file_name = $this->model->getName();
}
return download($content, $export_file_name . date('YmdHis') . '.xlsx', true);
}

View File

@@ -1,6 +1,7 @@
<div class="layuimini-container">
<div class="layuimini-main">
<table id="currentTable" class="layui-table layui-hide"
data-auth-index="{:auth('{{controllerUrl}}/index')}"
data-auth-add="{:auth('{{controllerUrl}}/add')}"
data-auth-edit="{:auth('{{controllerUrl}}/edit')}"
data-auth-delete="{:auth('{{controllerUrl}}/delete')}"

View File

@@ -24,7 +24,7 @@ $ul_system_config = array(
array(
"name" => "upload_allow_ext",
"group" => "upload",
"value" => "jpg,jpeg,png,gif,bmp,doc,docx,xls,xlsx,ppt,pptx,pdf,zip,rar,7z,txt,mp3,wma,wav,mid,m4a,mp4,avi,wmv,3gp,flv,webp,svg",
"value" => "jpg,jpeg,png,gif,bmp,doc,docx,xls,xlsx,ppt,pptx,pdf,zip,rar,7z,txt,mp3,wma,wav,mid,m4a,mp4,avi,wmv,3gp,flv,webp,svg,ico",
"remark" => "允许上传的文件类型",
"sort" => 0,
),
@@ -231,6 +231,13 @@ $ul_system_config = array(
"remark" => "访问域名",
"sort" => 0,
),
array(
"name" => "txcos_appid",
"group" => "upload",
"value" => "填你的",
"remark" => "APPID",
"sort" => 0,
),
array(
"name" => "file",
"group" => "site",

View File

@@ -71,6 +71,13 @@
</div>
</div>
<div class="layui-form-item show-type-item txcos">
<label class="layui-form-label required">APPID</label>
<div class="layui-input-block">
<input type="text" name="txcos_appid" class="layui-input" lay-verify="required" lay-reqtext="请输入APPID" placeholder="请输入APPID" value="{:sysconfig('upload','txcos_appid')}">
<tip>开发者访问 COS 服务时拥有的用户维度唯一资源标识,用以标识资源,可在 API 密钥管理 页面获取</tip>
</div>
</div>
<div class="layui-form-item show-type-item txcos">
<label class="layui-form-label required">公钥信息</label>
<div class="layui-input-block">

View File

@@ -49,7 +49,13 @@
{/foreach}
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">权限标志</label>
<div class="layui-input-block">
<input type="text" name="auth_node" class="layui-input" placeholder="请输入权限标志" value="">
<tip>明确指定一个权限标志,判断权限时按照该值判断。默认按照菜单链接判断权限。</tip>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">菜单排序</label>
<div class="layui-input-block">

View File

@@ -57,7 +57,13 @@
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">权限标志</label>
<div class="layui-input-block">
<input type="text" name="auth_node" class="layui-input" placeholder="请输入权限标志" value="{$row.auth_node|default=''}">
<tip>明确指定一个权限标志,判断权限时按照该值判断。默认按照菜单链接判断权限。</tip>
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">备注信息</label>
<div class="layui-input-block">

View File

@@ -15,19 +15,23 @@ use think\facade\App;
class Version extends Command
{
const VERSION = 'v2.0.21';
const VERSION = 'v2.0.22';
const LAYUI_VERSION = '2.7.6';
const COMMENT = [
'优化多处细节,继续提升开发体验',
'升级为最新的echart扩展',
'后台使用增加基类全局状态',
'修改默认头像为中性头像',
'优化上传增加svg扩展',
'优化上传,增加设置扩展名分组的用法',
'优化上传,增加检测上传代码注入的用法',
'增加配置系统默认密码,并修改了表结构',
'升级ThinkPHP6.1',
'升级第三方flysystem组件',
'调整表格重载特性',
'完善CURD模板',
'修改table.operat.field特性',
'清理技术债务',
'增加权限菜单的权限标志',
'修复导出方法文件名获取方式',
'优化时间范围和数字范围的placeholder',
'优化版本设置有效性',
'优化表格导出按照字段字数设置宽度',
'默认允许icon上传',
];
protected function configure()

View File

@@ -5,7 +5,6 @@
namespace app\common\controller;
use app\admin\model\SystemAdmin;
use app\admin\service\ConfigService;
use app\BaseController;
use app\common\constants\AdminConstant;
use app\common\service\AuthService;
@@ -331,7 +330,7 @@ class AdminController extends BaseController
'thisControllerJsPath' => "{$thisControllerJsPath}",
'autoloadJs' => $autoloadJs,
'isSuperAdmin' => $isSuperAdmin,
'version' => env('app_debug') ? time() : ConfigService::getVersion(),
'version' => env('app_debug') ? time() : sysconfig('site', 'site_version')
];
View::assign($data);

View File

@@ -57,7 +57,15 @@ class MenuService
{
$treeList = [];
foreach ($menuList as &$v) {
$check = empty($v['href']) ? true : $authServer->checkNode($v['href']);
$check = false;
if (!empty($v['auth_node'])) {
$check = $authServer->checkNode($v['auth_node']);
} else if (!empty($v['href'])) {
$check = $authServer->checkNode($v['href']);
} else {
$check = true;
}
!empty($v['href']) && $v['href'] = __url($v['href']);
if ($pid == $v['pid'] && $check) {
$node = $v;

View File

@@ -17,6 +17,7 @@ class ExportTools
foreach ($fields as $field_key => $field_name) {
$col_key = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($write_col);
$sheet->setCellValue($col_key . $write_line, $field_name);
$sheet->getColumnDimension($col_key)->setWidth(mb_strlen($field_name) * 3);
$write_col++;
}

View File

@@ -27,11 +27,11 @@
"guzzlehttp/guzzle": "^7.4",
"phpoffice/phpspreadsheet": "^1.22",
"topthink/think-migration": "^3.0",
"overtrue/flysystem-qiniu": "*",
"xxtime/flysystem-aliyun-oss": "^1.5",
"chunpat/flysystem-tencent-cos": "^0.0.1",
"doctrine/annotations": "^1.13",
"nikic/php-parser": "^4.15"
"topthink/think-filesystem": "^2.0",
"overtrue/flysystem-qiniu": "^2.0",
"overtrue/flysystem-cos": "^4.0",
"iidestiny/flysystem-oss": "^3.0"
},
"require-dev": {
"symfony/var-dumper": "^4.2"

View File

@@ -33,13 +33,16 @@ return [
'visibility' => 'public',
],
'qnoss' => [
'type' => 'Qiniu'
'type' => 'Qiniu',
'visibility' => 'public',
],
'alioss' => [
'type' => 'Alioss'
'type' => 'Alioss',
'visibility' => 'public',
],
'txcos' => [
'type' => 'Txcos'
'type' => 'Txcos',
'visibility' => 'public',
],
// 更多的磁盘配置信息
],

View File

@@ -34,6 +34,7 @@ class SystemMenu extends Migrator
->addColumn(Column::char('title', 100)->setDefault('')->setComment('名称'))
->addColumn(Column::char('icon', 100)->setDefault('')->setComment('菜单图标'))
->addColumn(Column::char('href', 100)->setDefault('')->setComment('链接'))
->addColumn(Column::char('auth_node', 100)->setDefault('')->setComment('权限标志'))
->addColumn(Column::text('params')->setComment('链接参数'))
->addColumn(Column::char('target', 20)->setDefault('_self')->setComment('链接打开方式'))
->addColumn(Column::integer('sort')->setDefault(0)->setComment('排序'))

View File

@@ -2,24 +2,21 @@
namespace think\filesystem\driver;
use League\Flysystem\AdapterInterface;
use Iidestiny\Flysystem\Oss\OssAdapter;
use League\Flysystem\FilesystemAdapter;
use think\filesystem\Driver;
use Xxtime\Flysystem\Aliyun\OssAdapter;
class Alioss extends Driver
{
protected function createAdapter(): AdapterInterface
protected function createAdapter(): FilesystemAdapter
{
$config = [
'accessId' => sysconfig('upload', 'alioss_access_key_id'),
'accessSecret' => sysconfig('upload', 'alioss_access_key_secret'),
'endpoint' => sysconfig('upload', 'alioss_endpoint'),
'bucket' => sysconfig('upload', 'alioss_bucket'),
];
return new OssAdapter(
$config
sysconfig('upload', 'alioss_access_key_id'),
sysconfig('upload', 'alioss_access_key_secret'),
sysconfig('upload', 'alioss_endpoint'),
sysconfig('upload', 'alioss_bucket')
);
}

View File

@@ -1,19 +1,20 @@
<?php
namespace think\filesystem\driver;
use League\Flysystem\AdapterInterface;
use League\Flysystem\FilesystemAdapter;
use think\filesystem\Driver;
use Overtrue\Flysystem\Qiniu\QiniuAdapter;
class Qiniu extends Driver
{
protected function createAdapter(): AdapterInterface
protected function createAdapter(): FilesystemAdapter
{
return new QiniuAdapter(
sysconfig('upload','qnoss_access_key'),
sysconfig('upload','qnoss_secret_key'),
sysconfig('upload','qnoss_bucket'),
sysconfig('upload','qnoss_domain')
sysconfig('upload', 'qnoss_access_key'),
sysconfig('upload', 'qnoss_secret_key'),
sysconfig('upload', 'qnoss_bucket'),
sysconfig('upload', 'qnoss_domain')
);
}
@@ -22,4 +23,3 @@ class Qiniu extends Driver
return $this->concatPathToUrl(sysconfig('upload', 'qnoss_domain'), $path);
}
}

View File

@@ -2,33 +2,38 @@
namespace think\filesystem\driver;;
use League\Flysystem\AdapterInterface;
use Qcloud\Cos\Client;
use League\Flysystem\FilesystemAdapter;
use think\filesystem\Driver;
use Overtrue\Flysystem\Cos\CosAdapter;
class Txcos extends Driver
{
protected function createAdapter(): AdapterInterface
protected function createAdapter(): FilesystemAdapter
{
$appid = sysconfig('upload', 'txcos_appid');
$secretId = sysconfig('upload', 'txcos_secret_id');
$secretKey = sysconfig('upload', 'txcos_secret_key');
$region = sysconfig('upload', 'txcos_region'); //set a default bucket region 设置一个默认的存储桶地域
$cosClient = new Client(
array(
'region' => $region,
'schema' => 'https', //协议头部默认为http
'credentials' => array(
'secretId' => $secretId,
'secretKey' => $secretKey
),
'signHost' => false
)
);
$bucket = sysconfig('upload', 'txcos_bucket'); //存储桶名称 格式BucketName-APPID
$config = [
// 必填app_id、secret_id、secret_key
// 可在个人秘钥管理页查看https://console.cloud.tencent.com/capi
'app_id' => $appid,
'secret_id' => $secretId,
'secret_key' => $secretKey,
'region' => $region,
'bucket' => $bucket,
// 可选,如果 bucket 为私有访问请打开此项
'signed_url' => false,
// 可选,是否使用 https默认 false
'use_https' => true,
];
$adapter = new CosAdapter($config);
$adapter = new \Chunpat\FlysystemTencentCos\Adapter($cosClient, $bucket);
return $adapter;
}

View File

@@ -584,8 +584,8 @@ define(["jquery", "tableSelect", "ckeditor", 'miniTheme', 'tableData', 'citypick
formHtml += '\t<div class="layui-form-item form-item-time-limit layui-inline ' + formSearchHideClass + ' ">\n' +
'<label class="layui-form-label">' + d.title + '</label>\n' +
'<div class="layui-input-inline">\n' +
'<input id="c-' + d.elemIdName + '-min_date" name="[' + d.fieldAlias + ']min_date" data-search-op="min_date" value="' + d.searchValue + '" placeholder="' + d.searchTip + '最小值" class="layui-input">\n' +
'<input id="c-' + d.elemIdName + '-max_date" name="[' + d.fieldAlias + ']max_date" data-search-op="max_date" value="' + d.searchValue + '" placeholder="' + d.searchTip + '最大值" class="layui-input">\n' +
'<input id="c-' + d.elemIdName + '-min_date" name="[' + d.fieldAlias + ']min_date" data-search-op="min_date" value="' + d.searchValue + '" placeholder="最小值" class="layui-input">\n' +
'<input id="c-' + d.elemIdName + '-max_date" name="[' + d.fieldAlias + ']max_date" data-search-op="max_date" value="' + d.searchValue + '" placeholder="最大值" class="layui-input">\n' +
'</div>\n' +
'</div>';
break;
@@ -594,8 +594,8 @@ define(["jquery", "tableSelect", "ckeditor", 'miniTheme', 'tableData', 'citypick
formHtml += '\t<div class="layui-form-item form-item-number-limit layui-inline ' + formSearchHideClass + ' ">\n' +
'<label class="layui-form-label">' + d.title + '</label>\n' +
'<div class="layui-input-inline">\n' +
'<input id="c-' + d.elemIdName + '-min" name="[' + d.fieldAlias + ']min" data-search-op="min" type="text" value="' + d.searchValue + '" placeholder="' + d.searchTip + '最小值" class="layui-input">\n' +
'<input id="c-' + d.elemIdName + '-max" name="[' + d.fieldAlias + ']max" data-search-op="max" type="text" value="' + d.searchValue + '" placeholder="' + d.searchTip + '最大值" class="layui-input">\n' +
'<input id="c-' + d.elemIdName + '-min" name="[' + d.fieldAlias + ']min" data-search-op="min" type="text" value="' + d.searchValue + '" placeholder="最小值" class="layui-input">\n' +
'<input id="c-' + d.elemIdName + '-max" name="[' + d.fieldAlias + ']max" data-search-op="max" type="text" value="' + d.searchValue + '" placeholder="最大值" class="layui-input">\n' +
'</div>\n' +
'</div>';
break;
@@ -1003,14 +1003,20 @@ define(["jquery", "tableSelect", "ckeditor", 'miniTheme', 'tableData', 'citypick
operat.url = admin.table.toolSpliceUrl(operat.url, operat.field, data);
} else {
var querys = '';
if (operat.url.indexOf("?") !== -1) {
querys = '&'
var fieldParam = operat.field(data, operat);
if (typeof fieldParam == 'string') {
operat.url = fieldParam
} else {
querys = '?'
var querys = '';
if (operat.url.indexOf("?") !== -1) {
querys = '&'
} else {
querys = '?'
}
operat.url += querys + $.param(fieldParam)
}
operat.url += querys + $.param(operat.field(data, operat))
}
if (admin.checkAuth(operat.auth, elem)) {
@@ -1194,15 +1200,7 @@ define(["jquery", "tableSelect", "ckeditor", 'miniTheme', 'tableData', 'citypick
if (val !== '') {
formatFilter[key] = val;
var elemId = key;
if (key.indexOf('[') == 0) {
var keyArr = key.replace('[', '').split(']');
elemId = keyArr[0] + '-' + keyArr[1];
}
elemId = elemId.replace('.', '-');
var elemId = admin.table.renderSearchFormItemElementId(key)
var op = $('#c-' + elemId).attr('data-search-op');
op = op || '%*%';
@@ -1398,7 +1396,10 @@ define(["jquery", "tableSelect", "ckeditor", 'miniTheme', 'tableData', 'citypick
$.each(dataField, function (key, val) {
if (val !== '') {
formatFilter[key] = val;
var op = $('#c-' + key).attr('data-search-op');
var elemId = admin.table.renderSearchFormItemElementId(key)
var op = $('#c-' + elemId).attr('data-search-op');
op = op || '%*%';
formatOp[key] = op;
}
@@ -1430,6 +1431,19 @@ define(["jquery", "tableSelect", "ckeditor", 'miniTheme', 'tableData', 'citypick
layer.close(index);
});
});
},
renderSearchFormItemElementId(key) {
var elemId = key;
if (key.indexOf('[') == 0) {
var keyArr = key.replace('[', '').split(']');
elemId = keyArr[0] + '-' + keyArr[1];
}
elemId = elemId.replace('.', '-');
return elemId;
}
},
checkMobile: function () {
@@ -1716,7 +1730,7 @@ define(["jquery", "tableSelect", "ckeditor", 'miniTheme', 'tableData', 'citypick
admin.msg.success(res.msg, function () {
if (endMethod == 'reload-table') {
tableId = tableId || init.table_render_id;
table.reload(tableId);
table.reloadData(tableId);
} else if (endMethod == 'refresh-page') {
location.reload();
}