second name

This commit is contained in:
jinzh 2024-12-20 12:29:51 +08:00
parent 7694b7ebfc
commit 5d238771c6
1040 changed files with 179312 additions and 0 deletions

11
.bowerrc Normal file
View File

@ -0,0 +1,11 @@
{
"directory": "public/assets/libs",
"ignoredDependencies": [
"es6-promise",
"file-saver",
"html2canvas",
"jspdf",
"jspdf-autotable",
"pdfmake"
]
}

11
.env.sample Normal file
View File

@ -0,0 +1,11 @@
[app]
debug = false
trace = false
[database]
hostname = 127.0.0.1
database = fastadmin
username = root
password = root
hostport = 3306
prefix = fa_

18
.gitignore vendored Normal file
View File

@ -0,0 +1,18 @@
/nbproject/
/thinkphp/
/vendor/
/runtime/*
/addons/*
/public/assets/libs/
/public/assets/addons/*
/public/uploads/*
.idea
composer.lock
*.log
*.css.map
!.gitkeep
.env
.svn
.vscode
node_modules
.user.ini

191
LICENSE Normal file
View File

@ -0,0 +1,191 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, "control" means (i) the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
2. Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
3. Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
4. Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of
this License; and
You must cause any modified files to carry prominent notices stating that You
changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
5. Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
6. Trademarks.
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
7. Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
8. Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "{}" replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same "printed page" as the copyright notice for easier identification within
third-party archives.
Copyright 2017 Karson
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

1
addons/.gitkeep Normal file
View File

@ -0,0 +1 @@

1
application/.htaccess Normal file
View File

@ -0,0 +1 @@
deny from all

View File

@ -0,0 +1,14 @@
<?php
namespace app\admin\behavior;
class AdminLog
{
public function run(&$params)
{
//只记录POST请求的日志
if (request()->isPost() && config('fastadmin.auto_record_log')) {
\app\admin\model\AdminLog::record();
}
}
}

View File

@ -0,0 +1,344 @@
<?php
namespace app\admin\command;
use think\addons\AddonException;
use think\addons\Service;
use think\Config;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\Db;
use think\Exception;
use think\exception\PDOException;
class Addon extends Command
{
protected function configure()
{
$this
->setName('addon')
->addOption('name', 'a', Option::VALUE_REQUIRED, 'addon name', null)
->addOption('action', 'c', Option::VALUE_REQUIRED, 'action(create/enable/disable/uninstall/refresh/package/move)', 'create')
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override', null)
->addOption('release', 'r', Option::VALUE_OPTIONAL, 'addon release version', null)
->addOption('uid', 'u', Option::VALUE_OPTIONAL, 'fastadmin uid', null)
->addOption('token', 't', Option::VALUE_OPTIONAL, 'fastadmin token', null)
->addOption('domain', 'd', Option::VALUE_OPTIONAL, 'domain', null)
->addOption('local', 'l', Option::VALUE_OPTIONAL, 'local package', null)
->setDescription('Addon manager');
}
protected function execute(Input $input, Output $output)
{
$name = $input->getOption('name') ?: '';
$action = $input->getOption('action') ?: '';
if (stripos($name, 'addons' . DS) !== false) {
$name = explode(DS, $name)[1];
}
//强制覆盖
$force = $input->getOption('force');
//版本
$release = $input->getOption('release') ?: '';
//uid
$uid = $input->getOption('uid') ?: '';
//token
$token = $input->getOption('token') ?: '';
include dirname(__DIR__) . DS . 'common.php';
if (!$name && !in_array($action, ['refresh'])) {
throw new Exception('Addon name could not be empty');
}
if (!$action || !in_array($action, ['create', 'disable', 'enable', 'install', 'uninstall', 'refresh', 'upgrade', 'package', 'move'])) {
throw new Exception('Please input correct action name');
}
// 查询一次SQL,判断连接是否正常
Db::execute("SELECT 1");
$addonDir = ADDON_PATH . $name . DS;
switch ($action) {
case 'create':
//非覆盖模式时如果存在则报错
if (is_dir($addonDir) && !$force) {
throw new Exception("addon already exists!\nIf you need to create again, use the parameter --force=true ");
}
//如果存在先移除
if (is_dir($addonDir)) {
rmdirs($addonDir);
}
mkdir($addonDir, 0755, true);
mkdir($addonDir . DS . 'controller', 0755, true);
$menuList = \app\common\library\Menu::export($name);
$createMenu = $this->getCreateMenu($menuList);
$prefix = Config::get('database.prefix');
$createTableSql = '';
try {
$result = Db::query("SHOW CREATE TABLE `" . $prefix . $name . "`;");
if (isset($result[0]) && isset($result[0]['Create Table'])) {
$createTableSql = $result[0]['Create Table'];
}
} catch (PDOException $e) {
}
$data = [
'name' => $name,
'addon' => $name,
'addonClassName' => ucfirst($name),
'addonInstallMenu' => $createMenu ? "\$menu = " . var_export_short($createMenu) . ";\n\tMenu::create(\$menu);" : '',
'addonUninstallMenu' => $menuList ? 'Menu::delete("' . $name . '");' : '',
'addonEnableMenu' => $menuList ? 'Menu::enable("' . $name . '");' : '',
'addonDisableMenu' => $menuList ? 'Menu::disable("' . $name . '");' : '',
];
$this->writeToFile("addon", $data, $addonDir . ucfirst($name) . '.php');
$this->writeToFile("config", $data, $addonDir . 'config.php');
$this->writeToFile("info", $data, $addonDir . 'info.ini');
$this->writeToFile("controller", $data, $addonDir . 'controller' . DS . 'Index.php');
if ($createTableSql) {
$createTableSql = str_replace("`" . $prefix, '`__PREFIX__', $createTableSql);
file_put_contents($addonDir . 'install.sql', $createTableSql);
}
$output->info("Create Successed!");
break;
case 'disable':
case 'enable':
try {
//调用启用、禁用的方法
Service::$action($name, 0);
} catch (AddonException $e) {
if ($e->getCode() != -3) {
throw new Exception($e->getMessage());
}
if (!$force) {
//如果有冲突文件则提醒
$data = $e->getData();
foreach ($data['conflictlist'] as $k => $v) {
$output->warning($v);
}
$output->info("Are you sure you want to " . ($action == 'enable' ? 'override' : 'delete') . " all those files? Type 'yes' to continue: ");
$line = fgets(defined('STDIN') ? STDIN : fopen('php://stdin', 'r'));
if (trim($line) != 'yes') {
throw new Exception("Operation is aborted!");
}
}
//调用启用、禁用的方法
Service::$action($name, 1);
} catch (Exception $e) {
throw new Exception($e->getMessage());
}
$output->info(ucfirst($action) . " Successed!");
break;
case 'uninstall':
//非覆盖模式时如果存在则报错
if (!$force) {
throw new Exception("If you need to uninstall addon, use the parameter --force=true ");
}
try {
Service::uninstall($name, 0);
} catch (AddonException $e) {
if ($e->getCode() != -3) {
throw new Exception($e->getMessage());
}
if (!$force) {
//如果有冲突文件则提醒
$data = $e->getData();
foreach ($data['conflictlist'] as $k => $v) {
$output->warning($v);
}
$output->info("Are you sure you want to delete all those files? Type 'yes' to continue: ");
$line = fgets(defined('STDIN') ? STDIN : fopen('php://stdin', 'r'));
if (trim($line) != 'yes') {
throw new Exception("Operation is aborted!");
}
}
Service::uninstall($name, 1);
} catch (Exception $e) {
throw new Exception($e->getMessage());
}
$output->info("Uninstall Successed!");
break;
case 'refresh':
Service::refresh();
$output->info("Refresh Successed!");
break;
case 'package':
$infoFile = $addonDir . 'info.ini';
if (!is_file($infoFile)) {
throw new Exception(__('Addon info file was not found'));
}
$info = get_addon_info($name);
if (!$info) {
throw new Exception(__('Addon info file data incorrect'));
}
$infoname = isset($info['name']) ? $info['name'] : '';
if (!$infoname || !preg_match("/^[a-z]+$/i", $infoname) || $infoname != $name) {
throw new Exception(__('Addon info name incorrect'));
}
$infoversion = isset($info['version']) ? $info['version'] : '';
if (!$infoversion || !preg_match("/^\d+\.\d+\.\d+$/i", $infoversion)) {
throw new Exception(__('Addon info version incorrect'));
}
$addonTmpDir = RUNTIME_PATH . 'addons' . DS;
if (!is_dir($addonTmpDir)) {
@mkdir($addonTmpDir, 0755, true);
}
$addonFile = $addonTmpDir . $infoname . '-' . $infoversion . '.zip';
if (!class_exists('ZipArchive')) {
throw new Exception(__('ZinArchive not install'));
}
$zip = new \ZipArchive;
$zip->open($addonFile, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
$files = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($addonDir), \RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $name => $file) {
if (!$file->isDir()) {
$filePath = $file->getRealPath();
$relativePath = str_replace(DS, '/', substr($filePath, strlen($addonDir)));
if (!in_array($file->getFilename(), ['.git', '.DS_Store', 'Thumbs.db'])) {
$zip->addFile($filePath, $relativePath);
}
}
}
$zip->close();
$output->info("Package Successed!");
break;
case 'move':
$movePath = [
'adminOnlySelfDir' => ['admin/behavior', 'admin/controller', 'admin/library', 'admin/model', 'admin/validate', 'admin/view'],
'adminAllSubDir' => ['admin/lang'],
'publicDir' => ['public/assets/addons', 'public/assets/js/backend']
];
$paths = [];
$appPath = str_replace('/', DS, APP_PATH);
$rootPath = str_replace('/', DS, ROOT_PATH);
foreach ($movePath as $k => $items) {
switch ($k) {
case 'adminOnlySelfDir':
foreach ($items as $v) {
$v = str_replace('/', DS, $v);
$oldPath = $appPath . $v . DS . $name;
$newPath = $rootPath . "addons" . DS . $name . DS . "application" . DS . $v . DS . $name;
$paths[$oldPath] = $newPath;
}
break;
case 'adminAllSubDir':
foreach ($items as $v) {
$v = str_replace('/', DS, $v);
$vPath = $appPath . $v;
$list = scandir($vPath);
foreach ($list as $_v) {
if (!in_array($_v, ['.', '..']) && is_dir($vPath . DS . $_v)) {
$oldPath = $appPath . $v . DS . $_v . DS . $name;
$newPath = $rootPath . "addons" . DS . $name . DS . "application" . DS . $v . DS . $_v . DS . $name;
$paths[$oldPath] = $newPath;
}
}
}
break;
case 'publicDir':
foreach ($items as $v) {
$v = str_replace('/', DS, $v);
$oldPath = $rootPath . $v . DS . $name;
$newPath = $rootPath . 'addons' . DS . $name . DS . $v . DS . $name;
$paths[$oldPath] = $newPath;
}
break;
}
}
foreach ($paths as $oldPath => $newPath) {
if (is_dir($oldPath)) {
if ($force) {
if (is_dir($newPath)) {
$list = scandir($newPath);
foreach ($list as $_v) {
if (!in_array($_v, ['.', '..'])) {
$file = $newPath . DS . $_v;
@chmod($file, 0777);
@unlink($file);
}
}
@rmdir($newPath);
}
}
copydirs($oldPath, $newPath);
}
}
break;
default:
break;
}
}
/**
* 获取创建菜单的数组
* @param array $menu
* @return array
*/
protected function getCreateMenu($menu)
{
$result = [];
foreach ($menu as $k => & $v) {
$arr = [
'name' => $v['name'],
'title' => $v['title'],
];
if ($v['icon'] != 'fa fa-circle-o') {
$arr['icon'] = $v['icon'];
}
if ($v['ismenu']) {
$arr['ismenu'] = $v['ismenu'];
}
if (isset($v['childlist']) && $v['childlist']) {
$arr['sublist'] = $this->getCreateMenu($v['childlist']);
}
$result[] = $arr;
}
return $result;
}
/**
* 写入到文件
* @param string $name
* @param array $data
* @param string $pathname
* @return mixed
*/
protected function writeToFile($name, $data, $pathname)
{
$search = $replace = [];
foreach ($data as $k => $v) {
$search[] = "{%{$k}%}";
$replace[] = $v;
}
$stub = file_get_contents($this->getStub($name));
$content = str_replace($search, $replace, $stub);
if (!is_dir(dirname($pathname))) {
mkdir(strtolower(dirname($pathname)), 0755, true);
}
return file_put_contents($pathname, $content);
}
/**
* 获取基础模板
* @param string $name
* @return string
*/
protected function getStub($name)
{
return __DIR__ . '/Addon/stubs/' . $name . '.stub';
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace addons\{%name%};
use app\common\library\Menu;
use think\Addons;
/**
* 插件
*/
class {%addonClassName%} extends Addons
{
/**
* 插件安装方法
* @return bool
*/
public function install()
{
{%addonInstallMenu%}
return true;
}
/**
* 插件卸载方法
* @return bool
*/
public function uninstall()
{
{%addonUninstallMenu%}
return true;
}
/**
* 插件启用方法
* @return bool
*/
public function enable()
{
{%addonEnableMenu%}
return true;
}
/**
* 插件禁用方法
* @return bool
*/
public function disable()
{
{%addonDisableMenu%}
return true;
}
}

View File

@ -0,0 +1,44 @@
<?php
return [
[
//配置唯一标识
'name' => 'usernmae',
//显示的标题
'title' => '用户名',
//类型
'type' => 'string',
//分组
'group' => '',
//动态显示
'visible' => '',
//数据字典
'content' => [
],
//值
'value' => '',
//验证规则
'rule' => 'required',
//错误消息
'msg' => '',
//提示消息
'tip' => '',
//成功消息
'ok' => '',
//扩展信息
'extend' => ''
],
[
'name' => 'password',
'title' => '密码',
'type' => 'string',
'content' => [
],
'value' => '',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => ''
],
];

View File

@ -0,0 +1,15 @@
<?php
namespace addons\{%addon%}\controller;
use think\addons\Controller;
class Index extends Controller
{
public function index()
{
$this->error("当前插件暂无前台页面");
}
}

View File

@ -0,0 +1,7 @@
name = {%name%}
title = 插件名称{%name%}
intro = 插件介绍
author = yourname
website = https://www.fastadmin.net
version = 1.0.0
state = 1

View File

@ -0,0 +1,195 @@
<?php
namespace app\admin\command;
use app\admin\command\Api\library\Builder;
use think\Config;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\Exception;
class Api extends Command
{
protected function configure()
{
$site = Config::get('site');
$this
->setName('api')
->addOption('url', 'u', Option::VALUE_OPTIONAL, 'default api url', '')
->addOption('module', 'm', Option::VALUE_OPTIONAL, 'module name(admin/index/api)', 'api')
->addOption('output', 'o', Option::VALUE_OPTIONAL, 'output index file name', 'api.html')
->addOption('template', 'e', Option::VALUE_OPTIONAL, '', 'index.html')
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override general file', false)
->addOption('title', 't', Option::VALUE_OPTIONAL, 'document title', $site['name'] ?? '')
->addOption('class', 'c', Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'extend class', null)
->addOption('language', 'l', Option::VALUE_OPTIONAL, 'language', 'zh-cn')
->addOption('addon', 'a', Option::VALUE_OPTIONAL, 'addon name', null)
->addOption('controller', 'r', Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, 'controller name', null)
->setDescription('Build Api document from controller');
}
protected function execute(Input $input, Output $output)
{
$apiDir = __DIR__ . DS . 'Api' . DS;
$force = $input->getOption('force');
$url = $input->getOption('url');
$language = $input->getOption('language');
$template = $input->getOption('template');
if (!preg_match("/^([a-z0-9]+)\.html\$/i", $template)) {
throw new Exception('template file not correct');
}
$language = $language ? $language : 'zh-cn';
$langFile = $apiDir . 'lang' . DS . $language . '.php';
if (!is_file($langFile)) {
throw new Exception('language file not found');
}
$lang = include_once $langFile;
// 目标目录
$output_dir = ROOT_PATH . 'public' . DS;
$output_file = $output_dir . $input->getOption('output');
if (is_file($output_file) && !$force) {
throw new Exception("api index file already exists!\nIf you need to rebuild again, use the parameter --force=true ");
}
// 模板文件
$template_dir = $apiDir . 'template' . DS;
$template_file = $template_dir . $template;
if (!is_file($template_file)) {
throw new Exception('template file not found');
}
// 额外的类
$classes = $input->getOption('class');
// 标题
$title = $input->getOption('title');
// 模块
$module = $input->getOption('module');
// 插件
$addon = $input->getOption('addon');
$moduleDir = $addonDir = '';
if ($addon) {
$addonInfo = get_addon_info($addon);
if (!$addonInfo) {
throw new Exception('addon not found');
}
$moduleDir = ADDON_PATH . $addon . DS;
} else {
$moduleDir = APP_PATH . $module . DS;
}
if (!is_dir($moduleDir)) {
throw new Exception('module not found');
}
if (version_compare(PHP_VERSION, '7.0.0', '<')) {
throw new Exception("Requires PHP version 7.0 or newer");
}
//控制器名
$controller = $input->getOption('controller') ?: [];
if (!$controller) {
$controllerDir = $moduleDir . Config::get('url_controller_layer') . DS;
$files = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($controllerDir),
\RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $name => $file) {
if (!$file->isDir() && $file->getExtension() == 'php') {
$filePath = $file->getRealPath();
$classes[] = $this->get_class_from_file($filePath);
}
}
} else {
foreach ($controller as $index => $item) {
$filePath = $moduleDir . Config::get('url_controller_layer') . DS . $item . '.php';
$classes[] = $this->get_class_from_file($filePath);
}
}
$classes = array_unique(array_filter($classes));
$config = [
'sitename' => config('site.name'),
'title' => $title,
'author' => config('site.name'),
'description' => '',
'apiurl' => $url,
'language' => $language,
];
$builder = new Builder($classes);
$content = $builder->render($template_file, ['config' => $config, 'lang' => $lang]);
if (!file_put_contents($output_file, $content)) {
throw new Exception('Cannot save the content to ' . $output_file);
}
$output->info("Build Successed!");
}
/**
* get full qualified class name
*
* @param string $path_to_file
* @return string
* @author JBYRNE http://jarretbyrne.com/2015/06/197/
*/
protected function get_class_from_file($path_to_file)
{
//Grab the contents of the file
$contents = file_get_contents($path_to_file);
//Start with a blank namespace and class
$namespace = $class = "";
//Set helper values to know that we have found the namespace/class token and need to collect the string values after them
$getting_namespace = $getting_class = false;
//Go through each token and evaluate it as necessary
foreach (token_get_all($contents) as $token) {
//If this token is the namespace declaring, then flag that the next tokens will be the namespace name
if (is_array($token) && $token[0] == T_NAMESPACE) {
$getting_namespace = true;
}
//If this token is the class declaring, then flag that the next tokens will be the class name
if (is_array($token) && $token[0] == T_CLASS) {
$getting_class = true;
}
//While we're grabbing the namespace name...
if ($getting_namespace === true) {
//If the token is a string or the namespace separator...
if (is_array($token) && in_array($token[0], [T_STRING, T_NS_SEPARATOR])) {
//Append the token's value to the name of the namespace
$namespace .= $token[1];
} elseif ($token === ';') {
//If the token is the semicolon, then we're done with the namespace declaration
$getting_namespace = false;
}
}
//While we're grabbing the class name...
if ($getting_class === true) {
//If the token is a string, it's the name of the class
if (is_array($token) && $token[0] == T_STRING) {
//Store the token's value as the class name
$class = $token[1];
//Got what we need, stope here
break;
}
}
}
//Build the fully-qualified class name and return it
return $namespace ? $namespace . '\\' . $class : $class;
}
}

View File

@ -0,0 +1,25 @@
<?php
return [
'Info' => '基础信息',
'Sandbox' => '在线测试',
'Sampleoutput' => '返回示例',
'Headers' => 'Headers',
'Parameters' => '参数',
'Body' => '正文',
'Name' => '名称',
'Type' => '类型',
'Required' => '必选',
'Description' => '描述',
'Send' => '提交',
'Reset' => '重置',
'Tokentips' => 'Token在会员注册或登录后都会返回,WEB端同时存在于Cookie中',
'Apiurltips' => 'API接口URL',
'Savetips' => '点击保存后Token和Api url都将保存在本地Localstorage中',
'Authorization' => '权限',
'NeedLogin' => '登录',
'NeedRight' => '鉴权',
'ReturnHeaders' => '响应头',
'ReturnParameters' => '返回参数',
'Response' => '响应输出',
];

View File

@ -0,0 +1,253 @@
<?php
namespace app\admin\command\Api\library;
use think\Config;
/**
* @website https://github.com/calinrada/php-apidoc
* @author Calin Rada <rada.calin@gmail.com>
* @author Karson <karson@fastadmin.net>
*/
class Builder
{
/**
*
* @var \think\View
*/
public $view = null;
/**
* parse classes
* @var array
*/
protected $classes = [];
/**
*
* @param array $classes
*/
public function __construct($classes = [])
{
$this->classes = array_merge($this->classes, $classes);
$this->view = new \think\View(Config::get('template'), Config::get('view_replace_str'));
}
protected function extractAnnotations()
{
foreach ($this->classes as $class) {
$classAnnotation = Extractor::getClassAnnotations($class);
// 如果忽略
if (isset($classAnnotation['ApiInternal'])) {
continue;
}
Extractor::getClassMethodAnnotations($class);
//Extractor::getClassPropertyValues($class);
}
$allClassAnnotation = Extractor::getAllClassAnnotations();
$allClassMethodAnnotation = Extractor::getAllClassMethodAnnotations();
//$allClassPropertyValue = Extractor::getAllClassPropertyValues();
// foreach ($allClassMethodAnnotation as $className => &$methods) {
// foreach ($methods as &$method) {
// //权重判断
// if ($method && !isset($method['ApiWeigh']) && isset($allClassAnnotation[$className]['ApiWeigh'])) {
// $method['ApiWeigh'] = $allClassAnnotation[$className]['ApiWeigh'];
// }
// }
// }
// unset($methods);
return [$allClassAnnotation, $allClassMethodAnnotation];
}
protected function generateHeadersTemplate($docs)
{
if (!isset($docs['ApiHeaders'])) {
return [];
}
$headerslist = array();
foreach ($docs['ApiHeaders'] as $params) {
$tr = array(
'name' => $params['name'] ?? '',
'type' => $params['type'] ?? 'string',
'sample' => $params['sample'] ?? '',
'required' => $params['required'] ?? false,
'description' => $params['description'] ?? '',
);
$headerslist[] = $tr;
}
return $headerslist;
}
protected function generateParamsTemplate($docs)
{
if (!isset($docs['ApiParams'])) {
return [];
}
$paramslist = array();
foreach ($docs['ApiParams'] as $params) {
$tr = array(
'name' => $params['name'],
'type' => $params['type'] ?? 'string',
'sample' => $params['sample'] ?? '',
'required' => $params['required'] ?? true,
'description' => $params['description'] ?? '',
);
$paramslist[] = $tr;
}
return $paramslist;
}
protected function generateReturnHeadersTemplate($docs)
{
if (!isset($docs['ApiReturnHeaders'])) {
return [];
}
$headerslist = array();
foreach ($docs['ApiReturnHeaders'] as $params) {
$tr = array(
'name' => $params['name'] ?? '',
'type' => 'string',
'sample' => $params['sample'] ?? '',
'required' => isset($params['required']) && $params['required'] ? 'Yes' : 'No',
'description' => $params['description'] ?? '',
);
$headerslist[] = $tr;
}
return $headerslist;
}
protected function generateReturnParamsTemplate($st_params)
{
if (!isset($st_params['ApiReturnParams'])) {
return [];
}
$paramslist = array();
foreach ($st_params['ApiReturnParams'] as $params) {
$tr = array(
'name' => $params['name'] ?? '',
'type' => $params['type'] ?? 'string',
'sample' => $params['sample'] ?? '',
'description' => $params['description'] ?? '',
);
$paramslist[] = $tr;
}
return $paramslist;
}
protected function generateBadgeForMethod($data)
{
$method = strtoupper(is_array($data['ApiMethod'][0]) ? $data['ApiMethod'][0]['data'] : $data['ApiMethod'][0]);
$labes = array(
'POST' => 'label-primary',
'GET' => 'label-success',
'PUT' => 'label-warning',
'DELETE' => 'label-danger',
'PATCH' => 'label-default',
'OPTIONS' => 'label-info'
);
return isset($labes[$method]) ? $labes[$method] : $labes['GET'];
}
public function parse()
{
list($allClassAnnotations, $allClassMethodAnnotations) = $this->extractAnnotations();
$sectorArr = [];
foreach ($allClassAnnotations as $index => &$allClassAnnotation) {
// 如果设置隐藏,则不显示在文档
if (isset($allClassAnnotation['ApiInternal'])) {
continue;
}
$sector = isset($allClassAnnotation['ApiSector']) ? $allClassAnnotation['ApiSector'][0] : $allClassAnnotation['ApiTitle'][0];
$sectorArr[$sector] = isset($allClassAnnotation['ApiWeigh']) ? $allClassAnnotation['ApiWeigh'][0] : 0;
}
unset($allClassAnnotation);
arsort($sectorArr);
$routes = include_once CONF_PATH . 'route.php';
$subdomain = false;
if (config('url_domain_deploy') && isset($routes['__domain__']) && isset($routes['__domain__']['api']) && $routes['__domain__']['api']) {
$subdomain = true;
}
$counter = 0;
$section = null;
$weigh = 0;
$docsList = [];
foreach ($allClassMethodAnnotations as $class => $methods) {
foreach ($methods as $name => $docs) {
if (isset($docs['ApiSector'][0])) {
$section = is_array($docs['ApiSector'][0]) ? $docs['ApiSector'][0]['data'] : $docs['ApiSector'][0];
} else {
$section = $class;
}
if (0 === count($docs)) {
continue;
}
$route = is_array($docs['ApiRoute'][0]) ? $docs['ApiRoute'][0]['data'] : $docs['ApiRoute'][0];
if ($subdomain) {
$route = substr($route, 4);
}
$docsList[$section][$name] = [
'id' => $counter,
'method' => is_array($docs['ApiMethod'][0]) ? $docs['ApiMethod'][0]['data'] : $docs['ApiMethod'][0],
'methodLabel' => $this->generateBadgeForMethod($docs),
'section' => $section,
'route' => $route,
'title' => is_array($docs['ApiTitle'][0]) ? $docs['ApiTitle'][0]['data'] : $docs['ApiTitle'][0],
'summary' => is_array($docs['ApiSummary'][0]) ? $docs['ApiSummary'][0]['data'] : $docs['ApiSummary'][0],
'body' => isset($docs['ApiBody'][0]) ? (is_array($docs['ApiBody'][0]) ? $docs['ApiBody'][0]['data'] : $docs['ApiBody'][0]) : '',
'headersList' => $this->generateHeadersTemplate($docs),
'paramsList' => $this->generateParamsTemplate($docs),
'returnHeadersList' => $this->generateReturnHeadersTemplate($docs),
'returnParamsList' => $this->generateReturnParamsTemplate($docs),
'weigh' => is_array($docs['ApiWeigh'][0]) ? $docs['ApiWeigh'][0]['data'] : $docs['ApiWeigh'][0],
'return' => isset($docs['ApiReturn']) ? (is_array($docs['ApiReturn'][0]) ? $docs['ApiReturn'][0]['data'] : $docs['ApiReturn'][0]) : '',
'needLogin' => $docs['ApiPermissionLogin'][0],
'needRight' => $docs['ApiPermissionRight'][0],
];
$counter++;
}
}
//重建排序
foreach ($docsList as $index => &$methods) {
$methodSectorArr = [];
foreach ($methods as $name => $method) {
$methodSectorArr[$name] = isset($method['weigh']) ? $method['weigh'] : 0;
}
arsort($methodSectorArr);
$methods = array_merge(array_flip(array_keys($methodSectorArr)), $methods);
}
$docsList = array_merge(array_flip(array_keys($sectorArr)), $docsList);
return $docsList;
}
public function getView()
{
return $this->view;
}
/**
* 渲染
* @param string $template
* @param array $vars
* @return string
*/
public function render($template, $vars = [])
{
$docsList = $this->parse();
return $this->view->display(file_get_contents($template), array_merge($vars, ['docsList' => $docsList]));
}
}

View File

@ -0,0 +1,544 @@
<?php
namespace app\admin\command\Api\library;
use Exception;
/**
* Class imported from https://github.com/eriknyk/Annotations
* @author Erik Amaru Ortiz https://github.com/eriknyk
*
* @license http://opensource.org/licenses/bsd-license.php The BSD License
* @author Calin Rada <rada.calin@gmail.com>
*/
class Extractor
{
/**
* Static array to store already parsed annotations
* @var array
*/
private static $annotationCache;
private static $classAnnotationCache;
private static $classMethodAnnotationCache;
private static $classPropertyValueCache;
/**
* Indicates that annotations should has strict behavior, 'false' by default
* @var boolean
*/
private $strict = false;
/**
* Stores the default namespace for Objects instance, usually used on methods like getMethodAnnotationsObjects()
* @var string
*/
public $defaultNamespace = '';
/**
* Sets strict variable to true/false
* @param bool $value boolean value to indicate that annotations to has strict behavior
*/
public function setStrict($value)
{
$this->strict = (bool)$value;
}
/**
* Sets default namespace to use in object instantiation
* @param string $namespace default namespace
*/
public function setDefaultNamespace($namespace)
{
$this->defaultNamespace = $namespace;
}
/**
* Gets default namespace used in object instantiation
* @return string $namespace default namespace
*/
public function getDefaultAnnotationNamespace()
{
return $this->defaultNamespace;
}
/**
* Gets all anotations with pattern @SomeAnnotation() from a given class
*
* @param string $className class name to get annotations
* @return array self::$classAnnotationCache all annotated elements
*/
public static function getClassAnnotations($className)
{
if (!isset(self::$classAnnotationCache[$className])) {
$class = new \ReflectionClass($className);
$annotationArr = self::parseAnnotations($class->getDocComment());
$annotationArr['ApiTitle'] = !isset($annotationArr['ApiTitle'][0]) || !trim($annotationArr['ApiTitle'][0]) ? [$class->getShortName()] : $annotationArr['ApiTitle'];
self::$classAnnotationCache[$className] = $annotationArr;
}
return self::$classAnnotationCache[$className];
}
/**
* 获取类所有方法的属性配置
* @param $className
* @return mixed
* @throws \ReflectionException
*/
public static function getClassMethodAnnotations($className)
{
$class = new \ReflectionClass($className);
foreach ($class->getMethods() as $object) {
self::$classMethodAnnotationCache[$className][$object->name] = self::getMethodAnnotations($className, $object->name);
}
return self::$classMethodAnnotationCache[$className];
}
public static function getClassPropertyValues($className)
{
$class = new \ReflectionClass($className);
foreach ($class->getProperties() as $object) {
self::$classPropertyValueCache[$className][$object->name] = self::getClassPropertyValue($className, $object->name);
}
return self::$classMethodAnnotationCache[$className];
}
public static function getAllClassAnnotations()
{
return self::$classAnnotationCache;
}
public static function getAllClassMethodAnnotations()
{
return self::$classMethodAnnotationCache;
}
public static function getAllClassPropertyValues()
{
return self::$classPropertyValueCache;
}
public static function getClassPropertyValue($className, $property)
{
$_SERVER['REQUEST_METHOD'] = 'GET';
$reflectionClass = new \ReflectionClass($className);
$reflectionProperty = $reflectionClass->getProperty($property);
$reflectionProperty->setAccessible(true);
return $reflectionProperty->getValue($reflectionClass->newInstanceWithoutConstructor());
}
/**
* Gets all anotations with pattern @SomeAnnotation() from a determinated method of a given class
*
* @param string $className class name
* @param string $methodName method name to get annotations
* @return array self::$annotationCache all annotated elements of a method given
*/
public static function getMethodAnnotations($className, $methodName)
{
if (!isset(self::$annotationCache[$className . '::' . $methodName])) {
try {
$method = new \ReflectionMethod($className, $methodName);
$class = new \ReflectionClass($className);
if (!$method->isPublic() || $method->isConstructor()) {
$annotations = array();
} else {
$annotations = self::consolidateAnnotations($method, $class);
}
} catch (\ReflectionException $e) {
$annotations = array();
}
self::$annotationCache[$className . '::' . $methodName] = $annotations;
}
return self::$annotationCache[$className . '::' . $methodName];
}
/**
* Gets all anotations with pattern @SomeAnnotation() from a determinated method of a given class
* and instance its abcAnnotation class
*
* @param string $className class name
* @param string $methodName method name to get annotations
* @return array self::$annotationCache all annotated objects of a method given
*/
public function getMethodAnnotationsObjects($className, $methodName)
{
$annotations = $this->getMethodAnnotations($className, $methodName);
$objects = array();
$i = 0;
foreach ($annotations as $annotationClass => $listParams) {
$annotationClass = ucfirst($annotationClass);
$class = $this->defaultNamespace . $annotationClass . 'Annotation';
// verify is the annotation class exists, depending if Annotations::strict is true
// if not, just skip the annotation instance creation.
if (!class_exists($class)) {
if ($this->strict) {
throw new Exception(sprintf('Runtime Error: Annotation Class Not Found: %s', $class));
} else {
// silent skip & continue
continue;
}
}
if (empty($objects[$annotationClass])) {
$objects[$annotationClass] = new $class();
}
foreach ($listParams as $params) {
if (is_array($params)) {
foreach ($params as $key => $value) {
$objects[$annotationClass]->set($key, $value);
}
} else {
$objects[$annotationClass]->set($i++, $params);
}
}
}
return $objects;
}
private static function consolidateAnnotations($method, $class)
{
$dockblockClass = $class->getDocComment();
$docblockMethod = $method->getDocComment();
$methodName = $method->getName();
$methodAnnotations = self::parseAnnotations($docblockMethod);
$methodAnnotations['ApiTitle'] = !isset($methodAnnotations['ApiTitle'][0]) || !trim($methodAnnotations['ApiTitle'][0]) ? [$method->getName()] : $methodAnnotations['ApiTitle'];
$classAnnotations = self::parseAnnotations($dockblockClass);
$classAnnotations['ApiTitle'] = !isset($classAnnotations['ApiTitle'][0]) || !trim($classAnnotations['ApiTitle'][0]) ? [$class->getShortName()] : $classAnnotations['ApiTitle'];
if (isset($methodAnnotations['ApiInternal']) || $methodName == '_initialize' || $methodName == '_empty') {
return [];
}
$properties = $class->getDefaultProperties();
$noNeedLogin = isset($properties['noNeedLogin']) ? (is_array($properties['noNeedLogin']) ? $properties['noNeedLogin'] : [$properties['noNeedLogin']]) : [];
$noNeedRight = isset($properties['noNeedRight']) ? (is_array($properties['noNeedRight']) ? $properties['noNeedRight'] : [$properties['noNeedRight']]) : [];
preg_match_all("/\*[\s]+(.*)(\\r\\n|\\r|\\n)/U", str_replace('/**', '', $docblockMethod), $methodArr);
preg_match_all("/\*[\s]+(.*)(\\r\\n|\\r|\\n)/U", str_replace('/**', '', $dockblockClass), $classArr);
if (!isset($methodAnnotations['ApiMethod'])) {
$methodAnnotations['ApiMethod'] = ['get'];
}
if (!isset($methodAnnotations['ApiWeigh'])) {
$methodAnnotations['ApiWeigh'] = [0];
}
if (!isset($methodAnnotations['ApiSummary'])) {
$methodAnnotations['ApiSummary'] = $methodAnnotations['ApiTitle'];
}
if ($methodAnnotations) {
foreach ($classAnnotations as $name => $valueClass) {
if (count($valueClass) !== 1) {
continue;
}
if ($name === 'ApiRoute') {
if (isset($methodAnnotations[$name])) {
$methodAnnotations[$name] = [rtrim($valueClass[0], '/') . $methodAnnotations[$name][0]];
} else {
$methodAnnotations[$name] = [rtrim($valueClass[0], '/') . '/' . $method->getName()];
}
}
if ($name === 'ApiSector') {
$methodAnnotations[$name] = $valueClass;
}
}
}
if (!isset($methodAnnotations['ApiRoute'])) {
$urlArr = [];
$className = $class->getName();
list($prefix, $suffix) = explode('\\' . \think\Config::get('url_controller_layer') . '\\', $className);
$prefixArr = explode('\\', $prefix);
$suffixArr = explode('\\', $suffix);
if ($prefixArr[0] == \think\Config::get('app_namespace')) {
$prefixArr[0] = '';
}
$urlArr = array_merge($urlArr, $prefixArr);
$urlArr[] = implode('.', array_map(function ($item) {
return \think\Loader::parseName($item);
}, $suffixArr));
$urlArr[] = $method->getName();
$methodAnnotations['ApiRoute'] = [implode('/', $urlArr)];
}
if (!isset($methodAnnotations['ApiSector'])) {
$methodAnnotations['ApiSector'] = isset($classAnnotations['ApiSector']) ? $classAnnotations['ApiSector'] : $classAnnotations['ApiTitle'];
}
if (!isset($methodAnnotations['ApiParams'])) {
$params = self::parseCustomAnnotations($docblockMethod, 'param');
foreach ($params as $k => $v) {
$arr = explode(' ', preg_replace("/[\s]+/", " ", $v));
$methodAnnotations['ApiParams'][] = [
'name' => isset($arr[1]) ? str_replace('$', '', $arr[1]) : '',
'nullable' => false,
'type' => isset($arr[0]) ? $arr[0] : 'string',
'description' => isset($arr[2]) ? $arr[2] : ''
];
}
}
$methodAnnotations['ApiPermissionLogin'] = [!in_array('*', $noNeedLogin) && !in_array($methodName, $noNeedLogin)];
$methodAnnotations['ApiPermissionRight'] = !$methodAnnotations['ApiPermissionLogin'][0] ? [false] : [!in_array('*', $noNeedRight) && !in_array($methodName, $noNeedRight)];
return $methodAnnotations;
}
/**
* Parse annotations
*
* @param string $docblock
* @param string $name
* @return array parsed annotations params
*/
private static function parseCustomAnnotations($docblock, $name = 'param')
{
$annotations = array();
$docblock = substr($docblock, 3, -2);
if (preg_match_all('/@' . $name . '(?:\s*(?:\(\s*)?(.*?)(?:\s*\))?)??\s*(?:\n|\*\/)/', $docblock, $matches)) {
foreach ($matches[1] as $k => $v) {
$annotations[] = $v;
}
}
return $annotations;
}
/**
* Parse annotations
*
* @param string $docblock
* @return array parsed annotations params
*/
private static function parseAnnotations($docblock)
{
$annotations = array();
// Strip away the docblock header and footer to ease parsing of one line annotations
$docblock = substr($docblock, 3, -2);
if (preg_match_all('/@(?<name>[A-Za-z_-]+)[\s\t]*\((?<args>(?:(?!\)).)*)\)\r?/s', $docblock, $matches)) {
$numMatches = count($matches[0]);
for ($i = 0; $i < $numMatches; ++$i) {
$name = $matches['name'][$i];
$value = '';
// annotations has arguments
if (isset($matches['args'][$i])) {
$argsParts = trim($matches['args'][$i]);
if ($name == 'ApiReturn') {
$value = $argsParts;
} elseif ($matches['args'][$i] != '') {
$argsParts = preg_replace("/\{(\w+)\}/", '#$1#', $argsParts);
$value = self::parseArgs($argsParts);
if (is_string($value)) {
$value = preg_replace("/\#(\w+)\#/", '{$1}', $argsParts);
}
}
}
$annotations[$name][] = $value;
}
}
if (stripos($docblock, '@ApiInternal') !== false) {
$annotations['ApiInternal'] = [true];
}
if (!isset($annotations['ApiTitle'])) {
preg_match_all("/\*[\s]+(.*)(\\r\\n|\\r|\\n)/U", str_replace('/**', '', $docblock), $matchArr);
$title = isset($matchArr[1]) && isset($matchArr[1][0]) ? $matchArr[1][0] : '';
$annotations['ApiTitle'] = [$title];
}
return $annotations;
}
/**
* Parse individual annotation arguments
*
* @param string $content arguments string
* @return array annotated arguments
*/
private static function parseArgs($content)
{
// Replace initial stars
$content = preg_replace('/^\s*\*/m', '', $content);
$data = array();
$len = strlen($content);
$i = 0;
$var = '';
$val = '';
$level = 1;
$prevDelimiter = '';
$nextDelimiter = '';
$nextToken = '';
$composing = false;
$type = 'plain';
$delimiter = null;
$quoted = false;
$tokens = array('"', '"', '{', '}', ',', '=');
while ($i <= $len) {
$prev_c = substr($content, $i - 1, 1);
$c = substr($content, $i++, 1);
if ($c === '"' && $prev_c !== "\\") {
$delimiter = $c;
//open delimiter
if (!$composing && empty($prevDelimiter) && empty($nextDelimiter)) {
$prevDelimiter = $nextDelimiter = $delimiter;
$val = '';
$composing = true;
$quoted = true;
} else {
// close delimiter
if ($c !== $nextDelimiter) {
throw new Exception(sprintf(
"Parse Error: enclosing error -> expected: [%s], given: [%s]",
$nextDelimiter,
$c
));
}
// validating syntax
if ($i < $len) {
if (',' !== substr($content, $i, 1) && '\\' !== $prev_c) {
throw new Exception(sprintf(
"Parse Error: missing comma separator near: ...%s<--",
substr($content, ($i - 10), $i)
));
}
}
$prevDelimiter = $nextDelimiter = '';
$composing = false;
$delimiter = null;
}
} elseif (!$composing && in_array($c, $tokens)) {
switch ($c) {
case '=':
$prevDelimiter = $nextDelimiter = '';
$level = 2;
$composing = false;
$type = 'assoc';
$quoted = false;
break;
case ',':
$level = 3;
// If composing flag is true yet,
// it means that the string was not enclosed, so it is parsing error.
if ($composing === true && !empty($prevDelimiter) && !empty($nextDelimiter)) {
throw new Exception(sprintf(
"Parse Error: enclosing error -> expected: [%s], given: [%s]",
$nextDelimiter,
$c
));
}
$prevDelimiter = $nextDelimiter = '';
break;
case '{':
$subc = '';
$subComposing = true;
while ($i <= $len) {
$c = substr($content, $i++, 1);
if (isset($delimiter) && $c === $delimiter) {
throw new Exception(sprintf(
"Parse Error: Composite variable is not enclosed correctly."
));
}
if ($c === '}') {
$subComposing = false;
break;
}
$subc .= $c;
}
// if the string is composing yet means that the structure of var. never was enclosed with '}'
if ($subComposing) {
throw new Exception(sprintf(
"Parse Error: Composite variable is not enclosed correctly. near: ...%s'",
$subc
));
}
$val = self::parseArgs($subc);
break;
}
} else {
if ($level == 1) {
$var .= $c;
} elseif ($level == 2) {
$val .= $c;
}
}
if ($level === 3 || $i === $len) {
if ($type == 'plain' && $i === $len) {
$data = self::castValue($var);
} else {
$data[trim($var)] = self::castValue($val, !$quoted);
}
$level = 1;
$var = $val = '';
$composing = false;
$quoted = false;
}
}
return $data;
}
/**
* Try determinate the original type variable of a string
*
* @param string $val string containing possibles variables that can be cast to bool or int
* @param boolean $trim indicate if the value passed should be trimmed after to try cast
* @return mixed returns the value converted to original type if was possible
*/
private static function castValue($val, $trim = false)
{
if (is_array($val)) {
foreach ($val as $key => $value) {
$val[$key] = self::castValue($value);
}
} elseif (is_string($val)) {
if ($trim) {
$val = trim($val);
}
$val = stripslashes($val);
$tmp = strtolower($val);
if ($tmp === 'false' || $tmp === 'true') {
$val = $tmp === 'true';
} elseif (is_numeric($val)) {
return $val + 0;
}
unset($tmp);
}
return $val;
}
}

View File

@ -0,0 +1,654 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<title>{$config.title}</title>
<!-- Bootstrap Core CSS -->
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<!-- Plugin CSS -->
<link href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://cdn.staticfile.org/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<style type="text/css">
body {
padding-top: 70px; margin-bottom: 15px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-family: "Roboto", "SF Pro SC", "SF Pro Display", "SF Pro Icons", "PingFang SC", BlinkMacSystemFont, -apple-system, "Segoe UI", "Microsoft Yahei", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
font-weight: 400;
}
h2 { font-size: 1.2em; }
hr { margin-top: 10px; }
.tab-pane { padding-top: 10px; }
.mt0 { margin-top: 0px; }
.footer { font-size: 12px; color: #666; }
.docs-list .label { display: inline-block; min-width: 65px; padding: 0.3em 0.6em 0.3em; }
.string { color: green; }
.number { color: darkorange; }
.boolean { color: blue; }
.null { color: magenta; }
.key { color: red; }
.popover { max-width: 400px; max-height: 400px; overflow-y: auto;}
.list-group.panel > .list-group-item {
}
.list-group-item:last-child {
border-radius:0;
}
h4.panel-title a {
font-weight:normal;
font-size:14px;
}
h4.panel-title a .text-muted {
font-size:12px;
font-weight:normal;
font-family: 'Verdana';
}
#sidebar {
width: 220px;
position: fixed;
margin-left: -240px;
overflow-y:auto;
}
#sidebar > .list-group {
margin-bottom:0;
}
#sidebar > .list-group > a{
text-indent:0;
}
#sidebar .child > a .tag{
position: absolute;
right: 10px;
top: 11px;
}
#sidebar .child > a .pull-right{
margin-left:3px;
}
#sidebar .child {
border:1px solid #ddd;
border-bottom:none;
}
#sidebar .child:last-child {
border-bottom:1px solid #ddd;
}
#sidebar .child > a {
border:0;
min-height: 40px;
}
#sidebar .list-group a.current {
background:#f5f5f5;
}
@media (max-width: 1620px){
#sidebar {
margin:0;
}
#accordion {
padding-left:235px;
}
}
@media (max-width: 768px){
#sidebar {
display: none;
}
#accordion {
padding-left:0px;
}
}
.label-primary {
background-color: #248aff;
}
.docs-list .panel .panel-body .table {
margin-bottom: 0;
}
</style>
</head>
<body>
<!-- Fixed navbar -->
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="./" target="_blank">{$config.title}</a>
</div>
<div class="navbar-collapse collapse">
<form class="navbar-form navbar-right">
<div class="form-group">
Token:
</div>
<div class="form-group">
<input type="text" class="form-control input-sm" data-toggle="tooltip" title="{$lang.Tokentips}" placeholder="token" id="token" />
</div>
<div class="form-group">
Apiurl:
</div>
<div class="form-group">
<input id="apiUrl" type="text" class="form-control input-sm" data-toggle="tooltip" title="{$lang.Apiurltips}" placeholder="https://api.mydomain.com" value="{$config.apiurl}" />
</div>
<div class="form-group">
<button type="button" class="btn btn-success btn-sm" data-toggle="tooltip" title="{$lang.Savetips}" id="save_data">
<span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>
</button>
</div>
</form>
</div><!--/.nav-collapse -->
</div>
</div>
<div class="container">
<!-- menu -->
<div id="sidebar">
<div class="list-group panel">
{foreach name="docsList" id="docs"}
<a href="#{$key}" class="list-group-item" data-toggle="collapse" data-parent="#sidebar">{$key} <i class="fa fa-caret-down"></i></a>
<div class="child collapse" id="{$key}">
{foreach name="docs" id="api" }
<a href="javascript:;" data-id="{$api.id}" class="list-group-item">{$api.title}
<span class="tag">
{if $api.needRight}
<span class="label label-danger pull-right"></span>
{/if}
{if $api.needLogin}
<span class="label label-success pull-right noneedlogin"></span>
{/if}
</span>
</a>
{/foreach}
</div>
{/foreach}
</div>
</div>
<div class="panel-group docs-list" id="accordion">
{foreach name="docsList" id="docs"}
<h2>{$key}</h2>
<hr>
{foreach name="docs" id="api" }
<div class="panel panel-default">
<div class="panel-heading" id="heading-{$api.id}">
<h4 class="panel-title">
<span class="label {$api.methodLabel}">{$api.method|strtoupper}</span>
<a data-toggle="collapse" data-parent="#accordion{$api.id}" href="#collapseOne{$api.id}"> {$api.title} <span class="text-muted">{$api.route}</span></a>
</h4>
</div>
<div id="collapseOne{$api.id}" class="panel-collapse collapse">
<div class="panel-body">
<!-- Nav tabs -->
<ul class="nav nav-tabs" id="doctab{$api.id}">
<li class="active"><a href="#info{$api.id}" data-toggle="tab">{$lang.Info}</a></li>
<li><a href="#sandbox{$api.id}" data-toggle="tab">{$lang.Sandbox}</a></li>
<li><a href="#sample{$api.id}" data-toggle="tab">{$lang.Sampleoutput}</a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="info{$api.id}">
<div class="well">
{$api.summary}
</div>
<div class="panel panel-default">
<div class="panel-heading"><strong>{$lang.Authorization}</strong></div>
<div class="panel-body">
<table class="table table-hover">
<tbody>
<tr>
<td>{$lang.NeedLogin}</td>
<td>{$api.needLogin?'是':'否'}</td>
</tr>
<tr>
<td>{$lang.NeedRight}</td>
<td>{$api.needRight?'是':'否'}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading"><strong>{$lang.Headers}</strong></div>
<div class="panel-body">
{if $api.headersList}
<table class="table table-hover">
<thead>
<tr>
<th>{$lang.Name}</th>
<th>{$lang.Type}</th>
<th>{$lang.Required}</th>
<th>{$lang.Description}</th>
</tr>
</thead>
<tbody>
{foreach name="api['headersList']" id="header"}
<tr>
<td>{$header.name}</td>
<td>{$header.type}</td>
<td>{$header.required?'是':'否'}</td>
<td>{$header.description}</td>
</tr>
{/foreach}
</tbody>
</table>
{else /}
{/if}
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading"><strong>{$lang.Parameters}</strong></div>
<div class="panel-body">
{if $api.paramsList}
<table class="table table-hover">
<thead>
<tr>
<th>{$lang.Name}</th>
<th>{$lang.Type}</th>
<th>{$lang.Required}</th>
<th>{$lang.Description}</th>
</tr>
</thead>
<tbody>
{foreach name="api['paramsList']" id="param"}
<tr>
<td>{$param.name}</td>
<td>{$param.type}</td>
<td>{:$param.required?'是':'否'}</td>
<td>{$param.description}</td>
</tr>
{/foreach}
</tbody>
</table>
{else /}
{/if}
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading"><strong>{$lang.Body}</strong></div>
<div class="panel-body">
{$api.body|default='无'}
</div>
</div>
</div><!-- #info -->
<div class="tab-pane" id="sandbox{$api.id}">
<div class="row">
<div class="col-md-12">
{if $api.headersList}
<div class="panel panel-default">
<div class="panel-heading"><strong>{$lang.Headers}</strong></div>
<div class="panel-body">
<div class="headers">
{foreach name="api['headersList']" id="param"}
<div class="form-group">
<label class="control-label" for="{$param.name}">{$param.name}</label>
<input type="{$param.type}" class="form-control input-sm" id="{$param.name}" {if $param.required}required{/if} placeholder="{$param.description} - Ex: {$param.sample}" name="{$param.name}">
</div>
{/foreach}
</div>
</div>
</div>
{/if}
<div class="panel panel-default">
<div class="panel-heading"><strong>{$lang.Parameters}</strong>
<div class="pull-right">
<a href="javascript:" class="btn btn-xs btn-info btn-append">追加</a>
</div>
</div>
<div class="panel-body">
<form enctype="application/x-www-form-urlencoded" role="form" action="{$api.route}" method="{$api.method}" name="form{$api.id}" id="form{$api.id}">
{if $api.paramsList}
{foreach name="api['paramsList']" id="param"}
<div class="form-group">
<label class="control-label" for="{$param.name}">{$param.name}</label>
<input type="{$param.type}" class="form-control input-sm" id="{$param.name}" {if $param.required}required{/if} placeholder="{$param.description}{if $param.sample} - 例: {$param.sample}{/if}" name="{$param.name}">
</div>
{/foreach}
{else /}
<div class="form-group">
</div>
{/if}
<div class="form-group form-group-submit">
<button type="submit" class="btn btn-success send" rel="{$api.id}">{$lang.Send}</button>
<button type="reset" class="btn btn-info" rel="{$api.id}">{$lang.Reset}</button>
</div>
</form>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading"><strong>{$lang.Response}</strong></div>
<div class="panel-body">
<div class="row">
<div class="col-md-12" style="overflow-x:auto">
<pre id="response_headers{$api.id}"></pre>
<pre id="response{$api.id}"></pre>
</div>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading"><strong>{$lang.ReturnParameters}</strong></div>
<div class="panel-body">
{if $api.returnParamsList}
<table class="table table-hover">
<thead>
<tr>
<th>{$lang.Name}</th>
<th>{$lang.Type}</th>
<th>{$lang.Description}</th>
</tr>
</thead>
<tbody>
{foreach name="api['returnParamsList']" id="param"}
<tr>
<td>{$param.name}</td>
<td>{$param.type}</td>
<td>{$param.description}</td>
</tr>
{/foreach}
</tbody>
</table>
{else /}
{/if}
</div>
</div>
</div>
</div>
</div><!-- #sandbox -->
<div class="tab-pane" id="sample{$api.id}">
<div class="row">
<div class="col-md-12">
<pre id="sample_response{$api.id}">{$api.return|default='无'}</pre>
</div>
</div>
</div><!-- #sample -->
</div><!-- .tab-content -->
</div>
</div>
</div>
{/foreach}
{/foreach}
</div>
<hr>
<div class="row mt0 footer">
<div class="col-md-6" align="left">
</div>
<div class="col-md-6" align="right">
Generated on {:date('Y-m-d H:i:s')} <a href="./" target="_blank">{$config.sitename}</a>
</div>
</div>
</div> <!-- /container -->
<!-- jQuery -->
<script src="https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script type="text/javascript">
function syntaxHighlight(json) {
if (typeof json != 'string') {
json = JSON.stringify(json, undefined, 2);
}
json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';
} else {
cls = 'string';
}
} else if (/true|false/.test(match)) {
cls = 'boolean';
} else if (/null/.test(match)) {
cls = 'null';
}
return '<span class="' + cls + '">' + match + '</span>';
});
}
function prepareStr(str) {
try {
return syntaxHighlight(JSON.stringify(JSON.parse(str.replace(/'/g, '"')), null, 2));
} catch (e) {
return str;
}
}
var storage = (function () {
var uid = new Date;
var storage;
var result;
try {
(storage = window.localStorage).setItem(uid, uid);
result = storage.getItem(uid) == uid;
storage.removeItem(uid);
return result && storage;
} catch (exception) {
}
}());
$.fn.serializeObject = function ()
{
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (!this.value) {
return;
}
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
$(document).ready(function () {
if (storage) {
storage.getItem('token') && $('#token').val(storage.getItem('token'));
storage.getItem('apiUrl') && $('#apiUrl').val(storage.getItem('apiUrl'));
}
$('[data-toggle="tooltip"]').tooltip({
placement: 'bottom'
});
$(window).on("resize", function(){
$("#sidebar").css("max-height", $(window).height()-80);
});
$(window).trigger("resize");
$(document).on("click", "#sidebar .list-group > .list-group-item", function(){
$("#sidebar .list-group > .list-group-item").removeClass("current");
$(this).addClass("current");
});
$(document).on("click", "#sidebar .child a", function(){
var heading = $("#heading-"+$(this).data("id"));
if(!heading.next().hasClass("in")){
$("a", heading).trigger("click");
}
$("html,body").animate({scrollTop:heading.offset().top-70});
});
$('code[id^=response]').hide();
$.each($('pre[id^=sample_response],pre[id^=sample_post_body]'), function () {
if ($(this).html() == 'NA') {
return;
}
var str = prepareStr($(this).html());
$(this).html(str);
});
$("[data-toggle=popover]").popover({placement: 'right'});
$('[data-toggle=popover]').on('shown.bs.popover', function () {
var $sample = $(this).parent().find(".popover-content"),
str = $(this).data('content');
if (typeof str == "undefined" || str === "") {
return;
}
var str = prepareStr(str);
$sample.html('<pre>' + str + '</pre>');
});
$(document).on('click', '#save_data', function (e) {
if (storage) {
storage.setItem('token', $('#token').val());
storage.setItem('apiUrl', $('#apiUrl').val());
} else {
alert('Your browser does not support local storage');
}
});
$(document).on('click', '.btn-append', function (e) {
$($("#appendtpl").html()).insertBefore($(this).closest(".panel").find(".form-group-submit"));
return false;
});
$(document).on('click', '.btn-remove', function (e) {
$(this).closest(".form-group").remove();
return false;
});
$(document).on('keyup', '.input-custom-name', function (e) {
$(this).closest(".row").find(".input-custom-value").attr("name", $(this).val());
return false;
});
$(document).on('click', '.send', function (e) {
e.preventDefault();
var form = $(this).closest('form');
//added /g to get all the matched params instead of only first
var matchedParamsInRoute = $(form).attr('action').match(/[^{]+(?=\})/g);
var theId = $(this).attr('rel');
//keep a copy of action attribute in order to modify the copy
//instead of the initial attribute
var url = $(form).attr('action');
var method = $(form).prop('method').toLowerCase() || 'get';
var formData = new FormData();
$(form).find('input').each(function (i, input) {
if ($(input).attr('type').toLowerCase() == 'file') {
formData.append($(input).attr('name'), $(input)[0].files[0]);
method = 'post';
} else {
formData.append($(input).attr('name'), $(input).val())
}
});
var index, key, value;
if (matchedParamsInRoute) {
var params = {};
formData.forEach(function(value, key){
params[key] = value;
});
for (index = 0; index < matchedParamsInRoute.length; ++index) {
try {
key = matchedParamsInRoute[index];
value = params[key];
if (typeof value == "undefined")
value = "";
url = url.replace("\{" + key + "\}", value);
formData.delete(key);
} catch (err) {
console.log(err);
}
}
}
var headers = {};
var token = $('#token').val();
if (token.length > 0) {
headers['token'] = token;
}
$("#sandbox" + theId + " .headers input[type=text]").each(function () {
val = $(this).val();
if (val.length > 0) {
headers[$(this).prop('name')] = val;
}
});
$.ajax({
url: $('#apiUrl').val() + url,
data: method == 'get' ? $(form).serialize() : formData,
type: method,
dataType: 'json',
contentType: false,
processData: false,
headers: headers,
xhrFields: {
withCredentials: true
},
success: function (data, textStatus, xhr) {
if (typeof data === 'object') {
var str = JSON.stringify(data, null, 2);
$('#response' + theId).html(syntaxHighlight(str));
} else {
$('#response' + theId).html(data || '');
}
$('#response_headers' + theId).html('HTTP ' + xhr.status + ' ' + xhr.statusText + '<br/><br/>' + xhr.getAllResponseHeaders());
$('#response' + theId).show();
},
error: function (xhr, textStatus, error) {
try {
var str = JSON.stringify($.parseJSON(xhr.responseText), null, 2);
} catch (e) {
var str = xhr.responseText;
}
$('#response_headers' + theId).html('HTTP ' + xhr.status + ' ' + xhr.statusText + '<br/><br/>' + xhr.getAllResponseHeaders());
$('#response' + theId).html(syntaxHighlight(str));
$('#response' + theId).show();
}
});
return false;
});
});
</script>
<script type="text/html" id="appendtpl">
<div class="form-group">
<label class="control-label">自定义</label>
<div class="row">
<div class="col-xs-4">
<input type="text" class="form-control input-sm input-custom-name" placeholder="名称">
</div>
<div class="col-xs-6">
<input type="text" class="form-control input-sm input-custom-value" placeholder="值">
</div>
<div class="col-xs-2 text-center">
<a href="javascript:" class="btn btn-sm btn-danger btn-remove">删除</a>
</div>
</div>
</div>
</script>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
{%addList%}
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>
</form>

View File

@ -0,0 +1,37 @@
<?php
namespace {%controllerNamespace%};
use app\common\controller\Backend;
/**
* {%tableComment%}
*
* @icon {%iconName%}
*/
class {%controllerName%} extends Backend
{
/**
* {%modelName%}模型对象
* @var \{%modelNamespace%}\{%modelName%}
*/
protected $model = null;
public function _initialize()
{
parent::_initialize();
$this->model = new \{%modelNamespace%}\{%modelName%};
{%controllerAssignList%}
}
{%controllerImport%}
/**
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
*/
{%controllerIndex%}
}

View File

@ -0,0 +1,34 @@
/**
* 查看
*/
public function index()
{
//当前是否为关联查询
$this->relationSearch = {%relationSearch%};
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$list = $this->model
{%relationWithList%}
->where($where)
->order($sort, $order)
->paginate($limit);
foreach ($list as $row) {
{%visibleFieldList%}
{%relationVisibleFieldList%}
}
$result = array("total" => $list->total(), "rows" => $list->items());
return json($result);
}
return $this->view->fetch();
}

View File

@ -0,0 +1,11 @@
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
{%editList%}
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>
</form>

View File

@ -0,0 +1,6 @@
<div class="checkbox">
{foreach name="{%fieldList%}" item="vo"}
<label for="{%fieldName%}-{$key}"><input id="{%fieldName%}-{$key}" name="{%fieldName%}" type="checkbox" value="{$key}" {in name="key" value="{%selectedValue%}"}checked{/in} /> {$vo}</label>
{/foreach}
</div>

View File

@ -0,0 +1,20 @@
<table class="table fieldlist" data-name="{%fieldName%}" data-template="{%fieldName%}tpl">
<tr>
{%theadList%}
<td width="90">{:__('Operate')}</td>
</tr>
<tr><td colspan="{%colspan%}">
<a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {:__('Append')}</a>
<textarea name="{%fieldName%}" class="form-control hide" cols="30" rows="5">{%fieldValue%}</textarea>
</td></tr>
</table>
<script type="text/html" id="{%fieldName%}tpl">
<tr>
{%tbodyList%}
<td width="90">
<span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span>
<span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span>
</td>
</tr>
</script>

View File

@ -0,0 +1,10 @@
<dl class="fieldlist" data-name="{%fieldName%}">
<dd>
<ins>{:__('{%itemKey%}')}</ins>
<ins>{:__('{%itemValue%}')}</ins>
</dd>
<dd><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {:__('Append')}</a></dd>
<textarea name="{%fieldName%}" class="form-control hide" cols="30" rows="5">{%fieldValue%}</textarea>
</dl>

View File

@ -0,0 +1,10 @@
<div class="panel-heading">
{:build_heading(null,FALSE)}
<ul class="nav nav-tabs" data-field="{%field%}">
<li class="{:$Think.get.{%field%} === null ? 'active' : ''}"><a href="#t-all" data-value="" data-toggle="tab">{:__('All')}</a></li>
{foreach name="{%fieldName%}List" item="vo"}
<li class="{:$Think.get.{%field%} === (string)$key ? 'active' : ''}"><a href="#t-{$key}" data-value="{$key}" data-toggle="tab">{$vo}</a></li>
{/foreach}
</ul>
</div>

View File

@ -0,0 +1,6 @@
<div class="radio">
{foreach name="{%fieldList%}" item="vo"}
<label for="{%fieldName%}-{$key}"><input id="{%fieldName%}-{$key}" name="{%fieldName%}" type="radio" value="{$key}" {in name="key" value="{%selectedValue%}"}checked{/in} /> {$vo}</label>
{/foreach}
</div>

View File

@ -0,0 +1 @@
<a class="btn btn-success btn-recyclebin btn-dialog {:$auth->check('{%controllerUrl%}/recyclebin')?'':'hide'}" href="{%controllerUrl%}/recyclebin" title="{:__('Recycle bin')}"><i class="fa fa-recycle"></i> {:__('Recycle bin')}</a>

View File

@ -0,0 +1,6 @@
<select {%attrStr%}>
{foreach name="{%fieldList%}" item="vo"}
<option value="{$key}" {in name="key" value="{%selectedValue%}"}selected{/in}>{$vo}</option>
{/foreach}
</select>

View File

@ -0,0 +1,5 @@
<input {%attrStr%} name="{%fieldName%}" type="hidden" value="{%fieldValue%}">
<a href="javascript:;" data-toggle="switcher" class="btn-switcher" data-input-id="c-{%field%}" data-yes="{%fieldYes%}" data-no="{%fieldNo%}" >
<i class="fa fa-toggle-on text-success {%fieldSwitchClass%} fa-2x"></i>
</a>

View File

@ -0,0 +1,35 @@
<div class="panel panel-default panel-intro">
{%headingHtml%}
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
<a href="javascript:;" class="btn btn-success btn-add {:$auth->check('{%controllerUrl%}/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
<a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('{%controllerUrl%}/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
<a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('{%controllerUrl%}/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
{%importHtml%}
<div class="dropdown btn-group {:$auth->check('{%controllerUrl%}/multi')?'':'hide'}">
<a class="btn btn-primary btn-more dropdown-toggle btn-disabled disabled" data-toggle="dropdown"><i class="fa fa-cog"></i> {:__('More')}</a>
<ul class="dropdown-menu text-left" role="menu">
<li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=normal"><i class="fa fa-eye"></i> {:__('Set to normal')}</a></li>
<li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=hidden"><i class="fa fa-eye-slash"></i> {:__('Set to hidden')}</a></li>
</ul>
</div>
{%recyclebinHtml%}
</div>
<table id="table" class="table table-striped table-bordered table-hover table-nowrap"
data-operate-edit="{:$auth->check('{%controllerUrl%}/edit')}"
data-operate-del="{:$auth->check('{%controllerUrl%}/del')}"
width="100%">
</table>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,48 @@
define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
var Controller = {
index: function () {
// 初始化表格参数配置
Table.api.init({
extend: {
index_url: '{%controllerUrl%}/index' + location.search,
add_url: '{%controllerUrl%}/add',
edit_url: '{%controllerUrl%}/edit',
del_url: '{%controllerUrl%}/del',
multi_url: '{%controllerUrl%}/multi',
import_url: '{%controllerUrl%}/import',
table: '{%table%}',
}
});
var table = $("#table");
// 初始化表格
table.bootstrapTable({
url: $.fn.bootstrapTable.defaults.extend.index_url,
pk: '{%pk%}',
sortName: '{%order%}',{%fixedColumnsJs%}
columns: [
[
{%javascriptList%}
]
]
});
// 为表格绑定事件
Table.api.bindevent(table);
},{%recyclebinJs%}
add: function () {
Controller.api.bindevent();
},
edit: function () {
Controller.api.bindevent();
},
api: {
bindevent: function () {
Form.api.bindevent($("form[role=form]"));
}
}
};
return Controller;
});

View File

@ -0,0 +1,5 @@
<?php
return [
{%langList%}
];

View File

@ -0,0 +1,8 @@
public function {%methodName%}($value, $data)
{
$value = $value ? $value : (isset($data['{%field%}']) ? $data['{%field%}'] : '');
$valueArr = explode(',', $value);
$list = $this->{%listMethodName%}();
return implode(',', array_intersect_key($list, array_flip($valueArr)));
}

View File

@ -0,0 +1,6 @@
public function {%methodName%}($value, $data)
{
$value = $value ? $value : (isset($data['{%field%}']) ? $data['{%field%}'] : '');
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
}

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,4 @@
public function import()
{
parent::import();
}

View File

@ -0,0 +1,8 @@
protected static function init()
{
self::afterInsert(function ($row) {
$pk = $row->getPk();
$row->getQuery()->where($pk, $row[$pk])->update(['{%order%}' => $row[$pk]]);
});
}

View File

@ -0,0 +1,5 @@
public function {%relationMethod%}s()
{
return $this->{%relationMode%}('{%relationClassName%}', '{%relationForeignKey%}', '{%relationPrimaryKey%}');
}

View File

@ -0,0 +1,5 @@
public function {%relationMethod%}()
{
return $this->{%relationMode%}('{%relationClassName%}', '{%relationForeignKey%}', '{%relationPrimaryKey%}', [], 'LEFT')->setEagerlyType(0);
}

View File

@ -0,0 +1,8 @@
public function {%methodName%}($value, $data)
{
$value = $value ? $value : (isset($data['{%field%}']) ? $data['{%field%}'] : '');
$valueArr = explode(',', $value);
$list = $this->{%listMethodName%}();
return implode(',', array_intersect_key($list, array_flip($valueArr)));
}

View File

@ -0,0 +1,7 @@
public function {%methodName%}($value, $data)
{
$value = $value ? $value : (isset($data['{%field%}']) ? $data['{%field%}'] : '');
$list = $this->{%listMethodName%}();
return isset($list[$value]) ? $list[$value] : '';
}

View File

@ -0,0 +1,60 @@
recyclebin: function () {
// 初始化表格参数配置
Table.api.init({
extend: {
'dragsort_url': ''
}
});
var table = $("#table");
// 初始化表格
table.bootstrapTable({
url: '{%controllerUrl%}/recyclebin' + location.search,
pk: 'id',
sortName: 'id',
columns: [
[
{checkbox: true},
{field: 'id', title: __('Id')},{%recyclebinTitleJs%}
{
field: '{%deleteTimeField%}',
title: __('Deletetime'),
operate: 'RANGE',
addclass: 'datetimerange',
formatter: Table.api.formatter.datetime
},
{
field: 'operate',
width: '140px',
title: __('Operate'),
table: table,
events: Table.api.events.operate,
buttons: [
{
name: 'Restore',
text: __('Restore'),
classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
icon: 'fa fa-rotate-left',
url: '{%controllerUrl%}/restore',
refresh: true
},
{
name: 'Destroy',
text: __('Destroy'),
classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
icon: 'fa fa-times',
url: '{%controllerUrl%}/destroy',
refresh: true
}
],
formatter: Table.api.formatter.operate
}
]
]
});
// 为表格绑定事件
Table.api.bindevent(table);
},

View File

@ -0,0 +1,7 @@
public function {%methodName%}($value, $data)
{
$value = $value ? $value : (isset($data['{%field%}']) ? $data['{%field%}'] : '');
$list = $this->{%listMethodName%}();
return isset($list[$value]) ? $list[$value] : '';
}

View File

@ -0,0 +1,40 @@
<?php
namespace {%modelNamespace%};
use think\Model;
{%softDeleteClassPath%}
class {%modelName%} extends Model
{
{%softDelete%}
{%modelConnection%}
// 表名
protected ${%modelTableType%} = '{%modelTableTypeName%}';
// 自动写入时间戳字段
protected $autoWriteTimestamp = {%modelAutoWriteTimestamp%};
// 定义时间戳字段名
protected $createTime = {%createTime%};
protected $updateTime = {%updateTime%};
protected $deleteTime = {%deleteTime%};
// 追加属性
protected $append = [
{%appendAttrList%}
];
{%modelInit%}
{%getEnumList%}
{%getAttrList%}
{%setAttrList%}
{%relationMethodList%}
}

View File

@ -0,0 +1,25 @@
<div class="panel panel-default panel-intro">
{:build_heading()}
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
{:build_toolbar('refresh')}
<a class="btn btn-info btn-multi btn-disabled disabled {:$auth->check('{%controllerUrl%}/restore')?'':'hide'}" href="javascript:;" data-url="{%controllerUrl%}/restore" data-action="restore"><i class="fa fa-rotate-left"></i> {:__('Restore')}</a>
<a class="btn btn-danger btn-multi btn-disabled disabled {:$auth->check('{%controllerUrl%}/destroy')?'':'hide'}" href="javascript:;" data-url="{%controllerUrl%}/destroy" data-action="destroy"><i class="fa fa-times"></i> {:__('Destroy')}</a>
<a class="btn btn-success btn-restoreall {:$auth->check('{%controllerUrl%}/restore')?'':'hide'}" href="javascript:;" data-url="{%controllerUrl%}/restore" title="{:__('Restore all')}"><i class="fa fa-rotate-left"></i> {:__('Restore all')}</a>
<a class="btn btn-danger btn-destroyall {:$auth->check('{%controllerUrl%}/destroy')?'':'hide'}" href="javascript:;" data-url="{%controllerUrl%}/destroy" title="{:__('Destroy all')}"><i class="fa fa-times"></i> {:__('Destroy all')}</a>
</div>
<table id="table" class="table table-striped table-bordered table-hover"
data-operate-restore="{:$auth->check('{%controllerUrl%}/restore')}"
data-operate-destroy="{:$auth->check('{%controllerUrl%}/destroy')}"
width="100%">
</table>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,12 @@
<?php
namespace {%modelNamespace%};
use think\Model;
class {%relationName%} extends Model
{
// 表名
protected ${%relationTableType%} = '{%relationTableTypeName%}';
}

View File

@ -0,0 +1,27 @@
<?php
namespace {%validateNamespace%};
use think\Validate;
class {%validateName%} extends Validate
{
/**
* 验证规则
*/
protected $rule = [
];
/**
* 提示消息
*/
protected $message = [
];
/**
* 验证场景
*/
protected $scene = [
'add' => [],
'edit' => [],
];
}

View File

@ -0,0 +1,329 @@
<?php
namespace app\admin\command;
use fast\Random;
use PDO;
use think\Config;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\Db;
use think\Exception;
use think\Lang;
use think\Request;
use think\View;
class Install extends Command
{
protected $model = null;
/**
* @var \think\View 视图类实例
*/
protected $view;
/**
* @var \think\Request Request 实例
*/
protected $request;
protected function configure()
{
$config = Config::get('database');
$this
->setName('install')
->addOption('hostname', 'a', Option::VALUE_OPTIONAL, 'mysql hostname', $config['hostname'])
->addOption('hostport', 'o', Option::VALUE_OPTIONAL, 'mysql hostport', $config['hostport'])
->addOption('database', 'd', Option::VALUE_OPTIONAL, 'mysql database', $config['database'])
->addOption('prefix', 'r', Option::VALUE_OPTIONAL, 'table prefix', $config['prefix'])
->addOption('username', 'u', Option::VALUE_OPTIONAL, 'mysql username', $config['username'])
->addOption('password', 'p', Option::VALUE_OPTIONAL, 'mysql password', $config['password'])
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override', false)
->setDescription('New installation of FastAdmin');
}
/**
* 命令行安装
*/
protected function execute(Input $input, Output $output)
{
define('INSTALL_PATH', APP_PATH . 'admin' . DS . 'command' . DS . 'Install' . DS);
// 覆盖安装
$force = $input->getOption('force');
$hostname = $input->getOption('hostname');
$hostport = $input->getOption('hostport');
$database = $input->getOption('database');
$prefix = $input->getOption('prefix');
$username = $input->getOption('username');
$password = $input->getOption('password');
$installLockFile = INSTALL_PATH . "install.lock";
if (is_file($installLockFile) && !$force) {
throw new Exception("\nFastAdmin already installed!\nIf you need to reinstall again, use the parameter --force=true ");
}
$adminUsername = 'admin';
$adminPassword = Random::alnum(10);
$adminEmail = 'admin@admin.com';
$siteName = __('My Website');
$adminName = $this->installation($hostname, $hostport, $database, $username, $password, $prefix, $adminUsername, $adminPassword, $adminEmail, $siteName);
if ($adminName) {
$output->highlight("Admin url:http://www.yoursite.com/{$adminName}");
}
$output->highlight("Admin username:{$adminUsername}");
$output->highlight("Admin password:{$adminPassword}");
\think\Cache::rm('__menu__');
$output->info("Install Successed!");
}
/**
* PC端安装
*/
public function index()
{
$this->view = View::instance(Config::get('template'), Config::get('view_replace_str'));
$this->request = Request::instance();
define('INSTALL_PATH', APP_PATH . 'admin' . DS . 'command' . DS . 'Install' . DS);
$lang = $this->request->langset();
$lang = preg_match("/^([a-zA-Z\-_]{2,10})\$/i", $lang) ? $lang : 'zh-cn';
if (!$lang || in_array($lang, ['zh-cn', 'zh-hans-cn'])) {
Lang::load(INSTALL_PATH . 'zh-cn.php');
}
$installLockFile = INSTALL_PATH . "install.lock";
if (is_file($installLockFile)) {
echo __('The system has been installed. If you need to reinstall, please remove %s first', 'install.lock');
exit;
}
$output = function ($code, $msg, $url = null, $data = null) {
return json(['code' => $code, 'msg' => $msg, 'url' => $url, 'data' => $data]);
};
if ($this->request->isPost()) {
$mysqlHostname = $this->request->post('mysqlHostname', '127.0.0.1');
$mysqlHostport = $this->request->post('mysqlHostport', '3306');
$hostArr = explode(':', $mysqlHostname);
if (count($hostArr) > 1) {
$mysqlHostname = $hostArr[0];
$mysqlHostport = $hostArr[1];
}
$mysqlUsername = $this->request->post('mysqlUsername', 'root');
$mysqlPassword = $this->request->post('mysqlPassword', '');
$mysqlDatabase = $this->request->post('mysqlDatabase', '');
$mysqlPrefix = $this->request->post('mysqlPrefix', 'fa_');
$adminUsername = $this->request->post('adminUsername', 'admin');
$adminPassword = $this->request->post('adminPassword', '');
$adminPasswordConfirmation = $this->request->post('adminPasswordConfirmation', '');
$adminEmail = $this->request->post('adminEmail', 'admin@admin.com');
$siteName = $this->request->post('siteName', __('My Website'));
if ($adminPassword !== $adminPasswordConfirmation) {
return $output(0, __('The two passwords you entered did not match'));
}
$adminName = '';
try {
$adminName = $this->installation($mysqlHostname, $mysqlHostport, $mysqlDatabase, $mysqlUsername, $mysqlPassword, $mysqlPrefix, $adminUsername, $adminPassword, $adminEmail, $siteName);
} catch (\PDOException $e) {
throw new Exception($e->getMessage());
} catch (\Exception $e) {
return $output(0, $e->getMessage());
}
return $output(1, __('Install Successed'), null, ['adminName' => $adminName]);
}
$errInfo = '';
try {
$this->checkenv();
} catch (\Exception $e) {
$errInfo = $e->getMessage();
}
return $this->view->fetch(INSTALL_PATH . "install.html", ['errInfo' => $errInfo]);
}
/**
* 执行安装
*/
protected function installation($mysqlHostname, $mysqlHostport, $mysqlDatabase, $mysqlUsername, $mysqlPassword, $mysqlPrefix, $adminUsername, $adminPassword, $adminEmail = null, $siteName = null)
{
$this->checkenv();
if ($mysqlDatabase == '') {
throw new Exception(__('Please input correct database'));
}
if (!preg_match("/^\w{3,12}$/", $adminUsername)) {
throw new Exception(__('Please input correct username'));
}
if (!preg_match("/^[\S]{6,16}$/", $adminPassword)) {
throw new Exception(__('Please input correct password'));
}
$weakPasswordArr = ['123456', '12345678', '123456789', '654321', '111111', '000000', 'password', 'qwerty', 'abc123', '1qaz2wsx'];
if (in_array($adminPassword, $weakPasswordArr)) {
throw new Exception(__('Password is too weak'));
}
if ($siteName == '' || preg_match("/fast" . "admin/i", $siteName)) {
throw new Exception(__('Please input correct website'));
}
$sql = file_get_contents(INSTALL_PATH . 'fastadmin.sql');
$sql = str_replace("`fa_", "`{$mysqlPrefix}", $sql);
// 先尝试能否自动创建数据库
$config = Config::get('database');
try {
$pdo = new PDO("{$config['type']}:host={$mysqlHostname}" . ($mysqlHostport ? ";port={$mysqlHostport}" : ''), $mysqlUsername, $mysqlPassword);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->query("CREATE DATABASE IF NOT EXISTS `{$mysqlDatabase}` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;");
// 连接install命令中指定的数据库
$instance = Db::connect([
'type' => "{$config['type']}",
'hostname' => "{$mysqlHostname}",
'hostport' => "{$mysqlHostport}",
'database' => "{$mysqlDatabase}",
'username' => "{$mysqlUsername}",
'password' => "{$mysqlPassword}",
'prefix' => "{$mysqlPrefix}",
]);
// 查询一次SQL,判断连接是否正常
$instance->execute("SELECT 1");
// 调用原生PDO对象进行批量查询
$instance->getPdo()->exec($sql);
} catch (\PDOException $e) {
throw new Exception($e->getMessage());
}
// 后台入口文件
$adminFile = ROOT_PATH . 'public' . DS . 'admin.php';
// 数据库配置文件
$dbConfigFile = APP_PATH . 'database.php';
$dbConfigText = @file_get_contents($dbConfigFile);
$callback = function ($matches) use ($mysqlHostname, $mysqlHostport, $mysqlUsername, $mysqlPassword, $mysqlDatabase, $mysqlPrefix) {
$field = "mysql" . ucfirst($matches[1]);
$replace = $$field;
if ($matches[1] == 'hostport' && $mysqlHostport == 3306) {
$replace = '';
}
return "'{$matches[1]}'{$matches[2]}=>{$matches[3]}Env::get('database.{$matches[1]}', '{$replace}'),";
};
$dbConfigText = preg_replace_callback("/'(hostname|database|username|password|hostport|prefix)'(\s+)=>(\s+)Env::get\((.*)\)\,/", $callback, $dbConfigText);
// 检测能否成功写入数据库配置
$result = @file_put_contents($dbConfigFile, $dbConfigText);
if (!$result) {
throw new Exception(__('The current permissions are insufficient to write the file %s', 'application/database.php'));
}
// 设置新的Token随机密钥key
$oldTokenKey = config('token.key');
$newTokenKey = \fast\Random::alnum(32);
$coreConfigFile = CONF_PATH . 'config.php';
$coreConfigText = @file_get_contents($coreConfigFile);
$coreConfigText = preg_replace("/'key'(\s+)=>(\s+)'{$oldTokenKey}'/", "'key'\$1=>\$2'{$newTokenKey}'", $coreConfigText);
$result = @file_put_contents($coreConfigFile, $coreConfigText);
if (!$result) {
throw new Exception(__('The current permissions are insufficient to write the file %s', 'application/config.php'));
}
$avatar = request()->domain() . '/assets/img/avatar.png';
// 变更默认管理员密码
$adminPassword = $adminPassword ? $adminPassword : Random::alnum(8);
$adminEmail = $adminEmail ? $adminEmail : "admin@admin.com";
$newSalt = substr(md5(uniqid(true)), 0, 6);
$newPassword = md5(md5($adminPassword) . $newSalt);
$data = ['username' => $adminUsername, 'email' => $adminEmail, 'avatar' => $avatar, 'password' => $newPassword, 'salt' => $newSalt];
$instance->name('admin')->where('username', 'admin')->update($data);
// 变更前台默认用户的密码,随机生成
$newSalt = substr(md5(uniqid(true)), 0, 6);
$newPassword = md5(md5(Random::alnum(8)) . $newSalt);
$instance->name('user')->where('username', 'admin')->update(['avatar' => $avatar, 'password' => $newPassword, 'salt' => $newSalt]);
// 修改后台入口
$adminName = '';
if (is_file($adminFile)) {
$adminName = Random::alpha(10) . '.php';
rename($adminFile, ROOT_PATH . 'public' . DS . $adminName);
}
//修改站点名称
if ($siteName != config('site.name')) {
$instance->name('config')->where('name', 'name')->update(['value' => $siteName]);
$siteConfigFile = CONF_PATH . 'extra' . DS . 'site.php';
$siteConfig = include $siteConfigFile;
$configList = $instance->name("config")->select();
foreach ($configList as $k => $value) {
if (in_array($value['type'], ['selects', 'checkbox', 'images', 'files'])) {
$value['value'] = is_array($value['value']) ? $value['value'] : explode(',', $value['value']);
}
if ($value['type'] == 'array') {
$value['value'] = (array)json_decode($value['value'], true);
}
$siteConfig[$value['name']] = $value['value'];
}
$siteConfig['name'] = $siteName;
file_put_contents($siteConfigFile, '<?php' . "\n\nreturn " . var_export_short($siteConfig) . ";\n");
}
$installLockFile = INSTALL_PATH . "install.lock";
//检测能否成功写入lock文件
$result = @file_put_contents($installLockFile, 1);
if (!$result) {
throw new Exception(__('The current permissions are insufficient to write the file %s', 'application/admin/command/Install/install.lock'));
}
try {
//删除安装脚本
@unlink(ROOT_PATH . 'public' . DS . 'install.php');
} catch (\Exception $e) {
}
return $adminName;
}
/**
* 检测环境
*/
protected function checkenv()
{
// 检测目录是否存在
$checkDirs = [
'thinkphp',
'vendor',
'public' . DS . 'assets' . DS . 'libs'
];
//数据库配置文件
$dbConfigFile = APP_PATH . 'database.php';
if (version_compare(PHP_VERSION, '7.2.0', '<')) {
throw new Exception(__("The current version %s is too low, please use PHP 7.2 or higher", PHP_VERSION));
}
if (!extension_loaded("PDO")) {
throw new Exception(__("PDO is not currently installed and cannot be installed"));
}
if (!is_really_writable($dbConfigFile)) {
throw new Exception(__('The current permissions are insufficient to write the configuration file application/database.php'));
}
foreach ($checkDirs as $k => $v) {
if (!is_dir(ROOT_PATH . $v)) {
throw new Exception(__('Please go to the official website to download the full package or resource package and try to install'));
break;
}
}
return true;
}
}

View File

@ -0,0 +1,605 @@
/*
FastAdmin Install SQL
Date: 2020-06-11 22:11:09
*/
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for fa_admin
-- ----------------------------
DROP TABLE IF EXISTS `fa_admin`;
CREATE TABLE `fa_admin` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`username` varchar(20) DEFAULT '' COMMENT '用户名',
`nickname` varchar(50) DEFAULT '' COMMENT '昵称',
`password` varchar(32) DEFAULT '' COMMENT '密码',
`salt` varchar(30) DEFAULT '' COMMENT '密码盐',
`avatar` varchar(255) DEFAULT '' COMMENT '头像',
`email` varchar(100) DEFAULT '' COMMENT '电子邮箱',
`mobile` varchar(11) DEFAULT '' COMMENT '手机号码',
`loginfailure` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '失败次数',
`logintime` bigint(16) DEFAULT NULL COMMENT '登录时间',
`loginip` varchar(50) DEFAULT NULL COMMENT '登录IP',
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
`token` varchar(59) DEFAULT '' COMMENT 'Session标识',
`status` varchar(30) NOT NULL DEFAULT 'normal' COMMENT '状态',
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='管理员表';
-- ----------------------------
-- Records of fa_admin
-- ----------------------------
BEGIN;
INSERT INTO `fa_admin` VALUES (1, 'admin', 'Admin', '', '', '/assets/img/avatar.png', 'admin@admin.com', '', 0, 1491635035, '127.0.0.1',1491635035, 1491635035, '', 'normal');
COMMIT;
-- ----------------------------
-- Table structure for fa_admin_log
-- ----------------------------
DROP TABLE IF EXISTS `fa_admin_log`;
CREATE TABLE `fa_admin_log` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`admin_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '管理员ID',
`username` varchar(30) DEFAULT '' COMMENT '管理员名字',
`url` varchar(1500) DEFAULT '' COMMENT '操作页面',
`title` varchar(100) DEFAULT '' COMMENT '日志标题',
`content` longtext NOT NULL COMMENT '内容',
`ip` varchar(50) DEFAULT '' COMMENT 'IP',
`useragent` varchar(255) DEFAULT '' COMMENT 'User-Agent',
`createtime` bigint(16) DEFAULT NULL COMMENT '操作时间',
PRIMARY KEY (`id`),
KEY `name` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='管理员日志表';
-- ----------------------------
-- Table structure for fa_area
-- ----------------------------
DROP TABLE IF EXISTS `fa_area`;
CREATE TABLE `fa_area` (
`id` int(10) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`pid` int(10) DEFAULT NULL COMMENT '父id',
`shortname` varchar(100) DEFAULT NULL COMMENT '简称',
`name` varchar(100) DEFAULT NULL COMMENT '名称',
`mergename` varchar(255) DEFAULT NULL COMMENT '全称',
`level` tinyint(4) DEFAULT NULL COMMENT '层级:1=省,2=市,3=区/县',
`pinyin` varchar(100) DEFAULT NULL COMMENT '拼音',
`code` varchar(100) DEFAULT NULL COMMENT '长途区号',
`zip` varchar(100) DEFAULT NULL COMMENT '邮编',
`first` varchar(50) DEFAULT NULL COMMENT '首字母',
`lng` varchar(100) DEFAULT NULL COMMENT '经度',
`lat` varchar(100) DEFAULT NULL COMMENT '纬度',
PRIMARY KEY (`id`),
KEY `pid` (`pid`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='地区表';
-- ----------------------------
-- Table structure for fa_attachment
-- ----------------------------
DROP TABLE IF EXISTS `fa_attachment`;
CREATE TABLE `fa_attachment` (
`id` int(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`category` varchar(50) DEFAULT '' COMMENT '类别',
`admin_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '管理员ID',
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '会员ID',
`url` varchar(255) DEFAULT '' COMMENT '物理路径',
`imagewidth` varchar(30) DEFAULT '' COMMENT '宽度',
`imageheight` varchar(30) DEFAULT '' COMMENT '高度',
`imagetype` varchar(30) DEFAULT '' COMMENT '图片类型',
`imageframes` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '图片帧数',
`filename` varchar(100) DEFAULT '' COMMENT '文件名称',
`filesize` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '文件大小',
`mimetype` varchar(100) DEFAULT '' COMMENT 'mime类型',
`extparam` varchar(255) DEFAULT '' COMMENT '透传数据',
`createtime` bigint(16) DEFAULT NULL COMMENT '创建日期',
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
`uploadtime` bigint(16) DEFAULT NULL COMMENT '上传时间',
`storage` varchar(100) NOT NULL DEFAULT 'local' COMMENT '存储位置',
`sha1` varchar(40) DEFAULT '' COMMENT '文件 sha1编码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='附件表';
-- ----------------------------
-- Records of fa_attachment
-- ----------------------------
BEGIN;
INSERT INTO `fa_attachment` VALUES (1, '', 1, 0, '/assets/img/qrcode.png', '150', '150', 'png', 0, 'qrcode.png', 21859, 'image/png', '', 1491635035, 1491635035, 1491635035, 'local', '17163603d0263e4838b9387ff2cd4877e8b018f6');
COMMIT;
-- ----------------------------
-- Table structure for fa_auth_group
-- ----------------------------
DROP TABLE IF EXISTS `fa_auth_group`;
CREATE TABLE `fa_auth_group` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父组别',
`name` varchar(100) DEFAULT '' COMMENT '组名',
`rules` text NOT NULL COMMENT '规则ID',
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
`status` varchar(30) DEFAULT '' COMMENT '状态',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='分组表';
-- ----------------------------
-- Records of fa_auth_group
-- ----------------------------
BEGIN;
INSERT INTO `fa_auth_group` VALUES (1, 0, 'Admin group', '*', 1491635035, 1491635035, 'normal');
INSERT INTO `fa_auth_group` VALUES (2, 1, 'Second group', '13,14,16,15,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,40,41,42,43,44,45,46,47,48,49,50,55,56,57,58,59,60,61,62,63,64,65,1,9,10,11,7,6,8,2,4,5', 1491635035, 1491635035, 'normal');
INSERT INTO `fa_auth_group` VALUES (3, 2, 'Third group', '1,4,9,10,11,13,14,15,16,17,40,41,42,43,44,45,46,47,48,49,50,55,56,57,58,59,60,61,62,63,64,65,5', 1491635035, 1491635035, 'normal');
INSERT INTO `fa_auth_group` VALUES (4, 1, 'Second group 2', '1,4,13,14,15,16,17,55,56,57,58,59,60,61,62,63,64,65', 1491635035, 1491635035, 'normal');
INSERT INTO `fa_auth_group` VALUES (5, 2, 'Third group 2', '1,2,6,7,8,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34', 1491635035, 1491635035, 'normal');
COMMIT;
-- ----------------------------
-- Table structure for fa_auth_group_access
-- ----------------------------
DROP TABLE IF EXISTS `fa_auth_group_access`;
CREATE TABLE `fa_auth_group_access` (
`uid` int(10) unsigned NOT NULL COMMENT '会员ID',
`group_id` int(10) unsigned NOT NULL COMMENT '级别ID',
UNIQUE KEY `uid_group_id` (`uid`,`group_id`),
KEY `uid` (`uid`),
KEY `group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='权限分组表';
-- ----------------------------
-- Records of fa_auth_group_access
-- ----------------------------
BEGIN;
INSERT INTO `fa_auth_group_access` VALUES (1, 1);
COMMIT;
-- ----------------------------
-- Table structure for fa_auth_rule
-- ----------------------------
DROP TABLE IF EXISTS `fa_auth_rule`;
CREATE TABLE `fa_auth_rule` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`type` enum('menu','file') NOT NULL DEFAULT 'file' COMMENT 'menu为菜单,file为权限节点',
`pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父ID',
`name` varchar(100) DEFAULT '' COMMENT '规则名称',
`title` varchar(50) DEFAULT '' COMMENT '规则名称',
`icon` varchar(50) DEFAULT '' COMMENT '图标',
`url` varchar(255) DEFAULT '' COMMENT '规则URL',
`condition` varchar(255) DEFAULT '' COMMENT '条件',
`remark` varchar(255) DEFAULT '' COMMENT '备注',
`ismenu` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否为菜单',
`menutype` enum('addtabs','blank','dialog','ajax') DEFAULT NULL COMMENT '菜单类型',
`extend` varchar(255) DEFAULT '' COMMENT '扩展属性',
`py` varchar(30) DEFAULT '' COMMENT '拼音首字母',
`pinyin` varchar(100) DEFAULT '' COMMENT '拼音',
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
`weigh` int(10) NOT NULL DEFAULT '0' COMMENT '权重',
`status` varchar(30) DEFAULT '' COMMENT '状态',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`) USING BTREE,
KEY `pid` (`pid`),
KEY `weigh` (`weigh`)
) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='节点表';
-- ----------------------------
-- Records of fa_auth_rule
-- ----------------------------
BEGIN;
INSERT INTO `fa_auth_rule` VALUES (1, 'file', 0, 'dashboard', 'Dashboard', 'fa fa-dashboard', '', '', 'Dashboard tips', 1, NULL, '', 'kzt', 'kongzhitai', 1491635035, 1491635035, 143, 'normal');
INSERT INTO `fa_auth_rule` VALUES (2, 'file', 0, 'general', 'General', 'fa fa-cogs', '', '', '', 1, NULL, '', 'cggl', 'changguiguanli', 1491635035, 1491635035, 137, 'normal');
INSERT INTO `fa_auth_rule` VALUES (3, 'file', 0, 'category', 'Category', 'fa fa-leaf', '', '', 'Category tips', 0, NULL, '', 'flgl', 'fenleiguanli', 1491635035, 1491635035, 119, 'normal');
INSERT INTO `fa_auth_rule` VALUES (4, 'file', 0, 'addon', 'Addon', 'fa fa-rocket', '', '', 'Addon tips', 1, NULL, '', 'cjgl', 'chajianguanli', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (5, 'file', 0, 'auth', 'Auth', 'fa fa-group', '', '', '', 1, NULL, '', 'qxgl', 'quanxianguanli', 1491635035, 1491635035, 99, 'normal');
INSERT INTO `fa_auth_rule` VALUES (6, 'file', 2, 'general/config', 'Config', 'fa fa-cog', '', '', 'Config tips', 1, NULL, '', 'xtpz', 'xitongpeizhi', 1491635035, 1491635035, 60, 'normal');
INSERT INTO `fa_auth_rule` VALUES (7, 'file', 2, 'general/attachment', 'Attachment', 'fa fa-file-image-o', '', '', 'Attachment tips', 1, NULL, '', 'fjgl', 'fujianguanli', 1491635035, 1491635035, 53, 'normal');
INSERT INTO `fa_auth_rule` VALUES (8, 'file', 2, 'general/profile', 'Profile', 'fa fa-user', '', '', '', 1, NULL, '', 'grzl', 'gerenziliao', 1491635035, 1491635035, 34, 'normal');
INSERT INTO `fa_auth_rule` VALUES (9, 'file', 5, 'auth/admin', 'Admin', 'fa fa-user', '', '', 'Admin tips', 1, NULL, '', 'glygl', 'guanliyuanguanli', 1491635035, 1491635035, 118, 'normal');
INSERT INTO `fa_auth_rule` VALUES (10, 'file', 5, 'auth/adminlog', 'Admin log', 'fa fa-list-alt', '', '', 'Admin log tips', 1, NULL, '', 'glyrz', 'guanliyuanrizhi', 1491635035, 1491635035, 113, 'normal');
INSERT INTO `fa_auth_rule` VALUES (11, 'file', 5, 'auth/group', 'Group', 'fa fa-group', '', '', 'Group tips', 1, NULL, '', 'jsz', 'juesezu', 1491635035, 1491635035, 109, 'normal');
INSERT INTO `fa_auth_rule` VALUES (12, 'file', 5, 'auth/rule', 'Rule', 'fa fa-bars', '', '', 'Rule tips', 1, NULL, '', 'cdgz', 'caidanguize', 1491635035, 1491635035, 104, 'normal');
INSERT INTO `fa_auth_rule` VALUES (13, 'file', 1, 'dashboard/index', 'View', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 136, 'normal');
INSERT INTO `fa_auth_rule` VALUES (14, 'file', 1, 'dashboard/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 135, 'normal');
INSERT INTO `fa_auth_rule` VALUES (15, 'file', 1, 'dashboard/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 133, 'normal');
INSERT INTO `fa_auth_rule` VALUES (16, 'file', 1, 'dashboard/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 134, 'normal');
INSERT INTO `fa_auth_rule` VALUES (17, 'file', 1, 'dashboard/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 132, 'normal');
INSERT INTO `fa_auth_rule` VALUES (18, 'file', 6, 'general/config/index', 'View', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 52, 'normal');
INSERT INTO `fa_auth_rule` VALUES (19, 'file', 6, 'general/config/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 51, 'normal');
INSERT INTO `fa_auth_rule` VALUES (20, 'file', 6, 'general/config/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 50, 'normal');
INSERT INTO `fa_auth_rule` VALUES (21, 'file', 6, 'general/config/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 49, 'normal');
INSERT INTO `fa_auth_rule` VALUES (22, 'file', 6, 'general/config/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 48, 'normal');
INSERT INTO `fa_auth_rule` VALUES (23, 'file', 7, 'general/attachment/index', 'View', 'fa fa-circle-o', '', '', 'Attachment tips', 0, NULL, '', '', '', 1491635035, 1491635035, 59, 'normal');
INSERT INTO `fa_auth_rule` VALUES (24, 'file', 7, 'general/attachment/select', 'Select attachment', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 58, 'normal');
INSERT INTO `fa_auth_rule` VALUES (25, 'file', 7, 'general/attachment/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 57, 'normal');
INSERT INTO `fa_auth_rule` VALUES (26, 'file', 7, 'general/attachment/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 56, 'normal');
INSERT INTO `fa_auth_rule` VALUES (27, 'file', 7, 'general/attachment/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 55, 'normal');
INSERT INTO `fa_auth_rule` VALUES (28, 'file', 7, 'general/attachment/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 54, 'normal');
INSERT INTO `fa_auth_rule` VALUES (29, 'file', 8, 'general/profile/index', 'View', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 33, 'normal');
INSERT INTO `fa_auth_rule` VALUES (30, 'file', 8, 'general/profile/update', 'Update profile', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 32, 'normal');
INSERT INTO `fa_auth_rule` VALUES (31, 'file', 8, 'general/profile/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 31, 'normal');
INSERT INTO `fa_auth_rule` VALUES (32, 'file', 8, 'general/profile/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 30, 'normal');
INSERT INTO `fa_auth_rule` VALUES (33, 'file', 8, 'general/profile/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 29, 'normal');
INSERT INTO `fa_auth_rule` VALUES (34, 'file', 8, 'general/profile/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 28, 'normal');
INSERT INTO `fa_auth_rule` VALUES (35, 'file', 3, 'category/index', 'View', 'fa fa-circle-o', '', '', 'Category tips', 0, NULL, '', '', '', 1491635035, 1491635035, 142, 'normal');
INSERT INTO `fa_auth_rule` VALUES (36, 'file', 3, 'category/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 141, 'normal');
INSERT INTO `fa_auth_rule` VALUES (37, 'file', 3, 'category/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 140, 'normal');
INSERT INTO `fa_auth_rule` VALUES (38, 'file', 3, 'category/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 139, 'normal');
INSERT INTO `fa_auth_rule` VALUES (39, 'file', 3, 'category/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 138, 'normal');
INSERT INTO `fa_auth_rule` VALUES (40, 'file', 9, 'auth/admin/index', 'View', 'fa fa-circle-o', '', '', 'Admin tips', 0, NULL, '', '', '', 1491635035, 1491635035, 117, 'normal');
INSERT INTO `fa_auth_rule` VALUES (41, 'file', 9, 'auth/admin/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 116, 'normal');
INSERT INTO `fa_auth_rule` VALUES (42, 'file', 9, 'auth/admin/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 115, 'normal');
INSERT INTO `fa_auth_rule` VALUES (43, 'file', 9, 'auth/admin/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 114, 'normal');
INSERT INTO `fa_auth_rule` VALUES (44, 'file', 10, 'auth/adminlog/index', 'View', 'fa fa-circle-o', '', '', 'Admin log tips', 0, NULL, '', '', '', 1491635035, 1491635035, 112, 'normal');
INSERT INTO `fa_auth_rule` VALUES (45, 'file', 10, 'auth/adminlog/detail', 'Detail', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 111, 'normal');
INSERT INTO `fa_auth_rule` VALUES (46, 'file', 10, 'auth/adminlog/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 110, 'normal');
INSERT INTO `fa_auth_rule` VALUES (47, 'file', 11, 'auth/group/index', 'View', 'fa fa-circle-o', '', '', 'Group tips', 0, NULL, '', '', '', 1491635035, 1491635035, 108, 'normal');
INSERT INTO `fa_auth_rule` VALUES (48, 'file', 11, 'auth/group/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 107, 'normal');
INSERT INTO `fa_auth_rule` VALUES (49, 'file', 11, 'auth/group/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 106, 'normal');
INSERT INTO `fa_auth_rule` VALUES (50, 'file', 11, 'auth/group/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 105, 'normal');
INSERT INTO `fa_auth_rule` VALUES (51, 'file', 12, 'auth/rule/index', 'View', 'fa fa-circle-o', '', '', 'Rule tips', 0, NULL, '', '', '', 1491635035, 1491635035, 103, 'normal');
INSERT INTO `fa_auth_rule` VALUES (52, 'file', 12, 'auth/rule/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 102, 'normal');
INSERT INTO `fa_auth_rule` VALUES (53, 'file', 12, 'auth/rule/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 101, 'normal');
INSERT INTO `fa_auth_rule` VALUES (54, 'file', 12, 'auth/rule/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 100, 'normal');
INSERT INTO `fa_auth_rule` VALUES (55, 'file', 4, 'addon/index', 'View', 'fa fa-circle-o', '', '', 'Addon tips', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (56, 'file', 4, 'addon/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (57, 'file', 4, 'addon/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (58, 'file', 4, 'addon/del', 'Delete', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (59, 'file', 4, 'addon/downloaded', 'Local addon', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (60, 'file', 4, 'addon/state', 'Update state', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (63, 'file', 4, 'addon/config', 'Setting', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (64, 'file', 4, 'addon/refresh', 'Refresh', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (65, 'file', 4, 'addon/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (66, 'file', 0, 'user', 'User', 'fa fa-user-circle', '', '', '', 1, NULL, '', 'hygl', 'huiyuanguanli', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (67, 'file', 66, 'user/user', 'User', 'fa fa-user', '', '', '', 1, NULL, '', 'hygl', 'huiyuanguanli', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (68, 'file', 67, 'user/user/index', 'View', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (69, 'file', 67, 'user/user/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (70, 'file', 67, 'user/user/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (71, 'file', 67, 'user/user/del', 'Del', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (72, 'file', 67, 'user/user/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (73, 'file', 66, 'user/group', 'User group', 'fa fa-users', '', '', '', 1, NULL, '', 'hyfz', 'huiyuanfenzu', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (74, 'file', 73, 'user/group/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (75, 'file', 73, 'user/group/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (76, 'file', 73, 'user/group/index', 'View', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (77, 'file', 73, 'user/group/del', 'Del', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (78, 'file', 73, 'user/group/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (79, 'file', 66, 'user/rule', 'User rule', 'fa fa-circle-o', '', '', '', 1, NULL, '', 'hygz', 'huiyuanguize', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (80, 'file', 79, 'user/rule/index', 'View', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (81, 'file', 79, 'user/rule/del', 'Del', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (82, 'file', 79, 'user/rule/add', 'Add', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (83, 'file', 79, 'user/rule/edit', 'Edit', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
INSERT INTO `fa_auth_rule` VALUES (84, 'file', 79, 'user/rule/multi', 'Multi', 'fa fa-circle-o', '', '', '', 0, NULL, '', '', '', 1491635035, 1491635035, 0, 'normal');
COMMIT;
-- ----------------------------
-- Table structure for fa_category
-- ----------------------------
DROP TABLE IF EXISTS `fa_category`;
CREATE TABLE `fa_category` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父ID',
`type` varchar(30) DEFAULT '' COMMENT '栏目类型',
`name` varchar(30) DEFAULT '',
`nickname` varchar(50) DEFAULT '',
`flag` set('hot','index','recommend') DEFAULT '',
`image` varchar(100) DEFAULT '' COMMENT '图片',
`keywords` varchar(255) DEFAULT '' COMMENT '关键字',
`description` varchar(255) DEFAULT '' COMMENT '描述',
`diyname` varchar(30) DEFAULT '' COMMENT '自定义名称',
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
`weigh` int(10) NOT NULL DEFAULT '0' COMMENT '权重',
`status` varchar(30) DEFAULT '' COMMENT '状态',
PRIMARY KEY (`id`),
KEY `weigh` (`weigh`,`id`),
KEY `pid` (`pid`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='分类表';
-- ----------------------------
-- Records of fa_category
-- ----------------------------
BEGIN;
INSERT INTO `fa_category` VALUES (1, 0, 'page', '官方新闻', 'news', 'recommend', '/assets/img/qrcode.png', '', '', 'news', 1491635035, 1491635035, 1, 'normal');
INSERT INTO `fa_category` VALUES (2, 0, 'page', '移动应用', 'mobileapp', 'hot', '/assets/img/qrcode.png', '', '', 'mobileapp', 1491635035, 1491635035, 2, 'normal');
INSERT INTO `fa_category` VALUES (3, 2, 'page', '微信公众号', 'wechatpublic', 'index', '/assets/img/qrcode.png', '', '', 'wechatpublic', 1491635035, 1491635035, 3, 'normal');
INSERT INTO `fa_category` VALUES (4, 2, 'page', 'Android开发', 'android', 'recommend', '/assets/img/qrcode.png', '', '', 'android', 1491635035, 1491635035, 4, 'normal');
INSERT INTO `fa_category` VALUES (5, 0, 'page', '软件产品', 'software', 'recommend', '/assets/img/qrcode.png', '', '', 'software', 1491635035, 1491635035, 5, 'normal');
INSERT INTO `fa_category` VALUES (6, 5, 'page', '网站建站', 'website', 'recommend', '/assets/img/qrcode.png', '', '', 'website', 1491635035, 1491635035, 6, 'normal');
INSERT INTO `fa_category` VALUES (7, 5, 'page', '企业管理软件', 'company', 'index', '/assets/img/qrcode.png', '', '', 'company', 1491635035, 1491635035, 7, 'normal');
INSERT INTO `fa_category` VALUES (8, 6, 'page', 'PC端', 'website-pc', 'recommend', '/assets/img/qrcode.png', '', '', 'website-pc', 1491635035, 1491635035, 8, 'normal');
INSERT INTO `fa_category` VALUES (9, 6, 'page', '移动端', 'website-mobile', 'recommend', '/assets/img/qrcode.png', '', '', 'website-mobile', 1491635035, 1491635035, 9, 'normal');
INSERT INTO `fa_category` VALUES (10, 7, 'page', 'CRM系统 ', 'company-crm', 'recommend', '/assets/img/qrcode.png', '', '', 'company-crm', 1491635035, 1491635035, 10, 'normal');
INSERT INTO `fa_category` VALUES (11, 7, 'page', 'SASS平台软件', 'company-sass', 'recommend', '/assets/img/qrcode.png', '', '', 'company-sass', 1491635035, 1491635035, 11, 'normal');
INSERT INTO `fa_category` VALUES (12, 0, 'test', '测试1', 'test1', 'recommend', '/assets/img/qrcode.png', '', '', 'test1', 1491635035, 1491635035, 12, 'normal');
INSERT INTO `fa_category` VALUES (13, 0, 'test', '测试2', 'test2', 'recommend', '/assets/img/qrcode.png', '', '', 'test2', 1491635035, 1491635035, 13, 'normal');
COMMIT;
-- ----------------------------
-- Table structure for fa_config
-- ----------------------------
DROP TABLE IF EXISTS `fa_config`;
CREATE TABLE `fa_config` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(30) DEFAULT '' COMMENT '变量名',
`group` varchar(30) DEFAULT '' COMMENT '分组',
`title` varchar(100) DEFAULT '' COMMENT '变量标题',
`tip` varchar(100) DEFAULT '' COMMENT '变量描述',
`type` varchar(30) DEFAULT '' COMMENT '类型:string,text,int,bool,array,datetime,date,file',
`visible` varchar(255) DEFAULT '' COMMENT '可见条件',
`value` text COMMENT '变量值',
`content` text COMMENT '变量字典数据',
`rule` varchar(100) DEFAULT '' COMMENT '验证规则',
`extend` varchar(255) DEFAULT '' COMMENT '扩展属性',
`setting` varchar(255) DEFAULT '' COMMENT '配置',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='系统配置';
-- ----------------------------
-- Records of fa_config
-- ----------------------------
BEGIN;
INSERT INTO `fa_config` VALUES (1, 'name', 'basic', 'Site name', '请填写站点名称', 'string', '', '我的网站', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (2, 'beian', 'basic', 'Beian', '粤ICP备15000000号-1', 'string', '', '', '', '', '', '');
INSERT INTO `fa_config` VALUES (3, 'cdnurl', 'basic', 'Cdn url', '如果全站静态资源使用第三方云储存请配置该值', 'string', '', '', '', '', '', '');
INSERT INTO `fa_config` VALUES (4, 'version', 'basic', 'Version', '如果静态资源有变动请重新配置该值', 'string', '', '1.0.1', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (5, 'timezone', 'basic', 'Timezone', '', 'string', '', 'Asia/Shanghai', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (6, 'forbiddenip', 'basic', 'Forbidden ip', '一行一条记录', 'text', '', '', '', '', '', '');
INSERT INTO `fa_config` VALUES (7, 'languages', 'basic', 'Languages', '', 'array', '', '{\"backend\":\"zh-cn\",\"frontend\":\"zh-cn\"}', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (8, 'fixedpage', 'basic', 'Fixed page', '请尽量输入左侧菜单栏存在的链接', 'string', '', 'dashboard', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (9, 'categorytype', 'dictionary', 'Category type', '', 'array', '', '{\"default\":\"Default\",\"page\":\"Page\",\"article\":\"Article\",\"test\":\"Test\"}', '', '', '', '');
INSERT INTO `fa_config` VALUES (10, 'configgroup', 'dictionary', 'Config group', '', 'array', '', '{\"basic\":\"Basic\",\"email\":\"Email\",\"dictionary\":\"Dictionary\",\"user\":\"User\",\"example\":\"Example\"}', '', '', '', '');
INSERT INTO `fa_config` VALUES (11, 'mail_type', 'email', 'Mail type', '选择邮件发送方式', 'select', '', '1', '[\"请选择\",\"SMTP\"]', '', '', '');
INSERT INTO `fa_config` VALUES (12, 'mail_smtp_host', 'email', 'Mail smtp host', '错误的配置发送邮件会导致服务器超时', 'string', '', 'smtp.qq.com', '', '', '', '');
INSERT INTO `fa_config` VALUES (13, 'mail_smtp_port', 'email', 'Mail smtp port', '(不加密默认25,SSL默认465,TLS默认587)', 'string', '', '465', '', '', '', '');
INSERT INTO `fa_config` VALUES (14, 'mail_smtp_user', 'email', 'Mail smtp user', '(填写完整用户名)', 'string', '', '10000', '', '', '', '');
INSERT INTO `fa_config` VALUES (15, 'mail_smtp_pass', 'email', 'Mail smtp password', '(填写您的密码或授权码)', 'string', '', 'password', '', '', '', '');
INSERT INTO `fa_config` VALUES (16, 'mail_verify_type', 'email', 'Mail vertify type', 'SMTP验证方式[推荐SSL]', 'select', '', '2', '[\"无\",\"TLS\",\"SSL\"]', '', '', '');
INSERT INTO `fa_config` VALUES (17, 'mail_from', 'email', 'Mail from', '', 'string', '', '10000@qq.com', '', '', '', '');
INSERT INTO `fa_config` VALUES (18, 'attachmentcategory', 'dictionary', 'Attachment category', '', 'array', '', '{\"category1\":\"Category1\",\"category2\":\"Category2\",\"custom\":\"Custom\"}', '', '', '', '');
COMMIT;
-- ----------------------------
-- Table structure for fa_ems
-- ----------------------------
DROP TABLE IF EXISTS `fa_ems`;
CREATE TABLE `fa_ems` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
`event` varchar(30) DEFAULT '' COMMENT '事件',
`email` varchar(100) DEFAULT '' COMMENT '邮箱',
`code` varchar(10) DEFAULT '' COMMENT '验证码',
`times` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '验证次数',
`ip` varchar(30) DEFAULT '' COMMENT 'IP',
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='邮箱验证码表';
-- ----------------------------
-- Table structure for fa_sms
-- ----------------------------
DROP TABLE IF EXISTS `fa_sms`;
CREATE TABLE `fa_sms` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`event` varchar(30) DEFAULT '' COMMENT '事件',
`mobile` varchar(20) DEFAULT '' COMMENT '手机号',
`code` varchar(10) DEFAULT '' COMMENT '验证码',
`times` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '验证次数',
`ip` varchar(30) DEFAULT '' COMMENT 'IP',
`createtime` bigint(16) unsigned DEFAULT '0' COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='短信验证码表';
-- ----------------------------
-- Table structure for fa_test
-- ----------------------------
DROP TABLE IF EXISTS `fa_test`;
CREATE TABLE `fa_test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`user_id` int(10) DEFAULT '0' COMMENT '会员ID',
`admin_id` int(10) DEFAULT '0' COMMENT '管理员ID',
`category_id` int(10) unsigned DEFAULT '0' COMMENT '分类ID(单选)',
`category_ids` varchar(100) COMMENT '分类ID(多选)',
`tags` varchar(255) DEFAULT '' COMMENT '标签',
`week` enum('monday','tuesday','wednesday') COMMENT '星期(单选):monday=星期一,tuesday=星期二,wednesday=星期三',
`flag` set('hot','index','recommend') DEFAULT '' COMMENT '标志(多选):hot=热门,index=首页,recommend=推荐',
`genderdata` enum('male','female') DEFAULT 'male' COMMENT '性别(单选):male=男,female=女',
`hobbydata` set('music','reading','swimming') COMMENT '爱好(多选):music=音乐,reading=读书,swimming=游泳',
`title` varchar(100) DEFAULT '' COMMENT '标题',
`content` text COMMENT '内容',
`image` varchar(100) DEFAULT '' COMMENT '图片',
`images` varchar(1500) DEFAULT '' COMMENT '图片组',
`attachfile` varchar(100) DEFAULT '' COMMENT '附件',
`keywords` varchar(255) DEFAULT '' COMMENT '关键字',
`description` varchar(255) DEFAULT '' COMMENT '描述',
`city` varchar(100) DEFAULT '' COMMENT '省市',
`json` varchar(255) DEFAULT NULL COMMENT '配置:key=名称,value=值',
`multiplejson` varchar(1500) DEFAULT '' COMMENT '二维数组:title=标题,intro=介绍,author=作者,age=年龄',
`price` decimal(10,2) unsigned DEFAULT '0.00' COMMENT '价格',
`views` int(10) unsigned DEFAULT '0' COMMENT '点击',
`workrange` varchar(100) DEFAULT '' COMMENT '时间区间',
`startdate` date DEFAULT NULL COMMENT '开始日期',
`activitytime` datetime DEFAULT NULL COMMENT '活动时间(datetime)',
`year` year(4) DEFAULT NULL COMMENT '',
`times` time DEFAULT NULL COMMENT '时间',
`refreshtime` bigint(16) DEFAULT NULL COMMENT '刷新时间',
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
`deletetime` bigint(16) DEFAULT NULL COMMENT '删除时间',
`weigh` int(10) DEFAULT '0' COMMENT '权重',
`switch` tinyint(1) DEFAULT '0' COMMENT '开关',
`status` enum('normal','hidden') DEFAULT 'normal' COMMENT '状态',
`state` enum('0','1','2') DEFAULT '1' COMMENT '状态值:0=禁用,1=正常,2=推荐',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='测试表';
-- ----------------------------
-- Records of fa_test
-- ----------------------------
BEGIN;
INSERT INTO `fa_test` VALUES (1, 1, 1, 12, '12,13', '互联网,计算机', 'monday', 'hot,index', 'male', 'music,reading', '我是一篇测试文章', '<p>我是测试内容</p>', '/assets/img/avatar.png', '/assets/img/avatar.png,/assets/img/qrcode.png', '/assets/img/avatar.png', '关键字', '描述', '广西壮族自治区/百色市/平果县', '{\"a\":\"1\",\"b\":\"2\"}', '[{\"title\":\"标题一\",\"intro\":\"介绍一\",\"author\":\"小明\",\"age\":\"21\"}]', 0.00, 0, '2020-10-01 00:00:00 - 2021-10-31 23:59:59', '2017-07-10', '2017-07-10 18:24:45', 2017, '18:24:45', 1491635035, 1491635035, 1491635035, NULL, 0, 1, 'normal', '1');
COMMIT;
-- ----------------------------
-- Table structure for fa_user
-- ----------------------------
DROP TABLE IF EXISTS `fa_user`;
CREATE TABLE `fa_user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`group_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '组别ID',
`username` varchar(32) DEFAULT '' COMMENT '用户名',
`nickname` varchar(50) DEFAULT '' COMMENT '昵称',
`password` varchar(32) DEFAULT '' COMMENT '密码',
`salt` varchar(30) DEFAULT '' COMMENT '密码盐',
`email` varchar(100) DEFAULT '' COMMENT '电子邮箱',
`mobile` varchar(11) DEFAULT '' COMMENT '手机号',
`avatar` varchar(255) DEFAULT '' COMMENT '头像',
`level` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '等级',
`gender` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '性别',
`birthday` date DEFAULT NULL COMMENT '生日',
`bio` varchar(100) DEFAULT '' COMMENT '格言',
`money` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '余额',
`score` int(10) NOT NULL DEFAULT '0' COMMENT '积分',
`successions` int(10) unsigned NOT NULL DEFAULT '1' COMMENT '连续登录天数',
`maxsuccessions` int(10) unsigned NOT NULL DEFAULT '1' COMMENT '最大连续登录天数',
`prevtime` bigint(16) DEFAULT NULL COMMENT '上次登录时间',
`logintime` bigint(16) DEFAULT NULL COMMENT '登录时间',
`loginip` varchar(50) DEFAULT '' COMMENT '登录IP',
`loginfailure` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '失败次数',
`joinip` varchar(50) DEFAULT '' COMMENT '加入IP',
`jointime` bigint(16) DEFAULT NULL COMMENT '加入时间',
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
`token` varchar(50) DEFAULT '' COMMENT 'Token',
`status` varchar(30) DEFAULT '' COMMENT '状态',
`verification` varchar(255) DEFAULT '' COMMENT '验证',
PRIMARY KEY (`id`),
KEY `username` (`username`),
KEY `email` (`email`),
KEY `mobile` (`mobile`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='会员表';
-- ----------------------------
-- Records of fa_user
-- ----------------------------
BEGIN;
INSERT INTO `fa_user` VALUES (1, 1, 'admin', 'admin', '', '', 'admin@163.com', '13888888888', '', 0, 0, '2017-04-08', '', 0, 0, 1, 1, 1491635035, 1491635035, '127.0.0.1', 0, '127.0.0.1', 1491635035, 0, 1491635035, '', 'normal','');
COMMIT;
-- ----------------------------
-- Table structure for fa_user_group
-- ----------------------------
DROP TABLE IF EXISTS `fa_user_group`;
CREATE TABLE `fa_user_group` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT '' COMMENT '组名',
`rules` text COMMENT '权限节点',
`createtime` bigint(16) DEFAULT NULL COMMENT '添加时间',
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
`status` enum('normal','hidden') DEFAULT NULL COMMENT '状态',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='会员组表';
-- ----------------------------
-- Records of fa_user_group
-- ----------------------------
BEGIN;
INSERT INTO `fa_user_group` VALUES (1, '默认组', '1,2,3,4,5,6,7,8,9,10,11,12', 1491635035, 1491635035, 'normal');
COMMIT;
-- ----------------------------
-- Table structure for fa_user_money_log
-- ----------------------------
DROP TABLE IF EXISTS `fa_user_money_log`;
CREATE TABLE `fa_user_money_log` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '会员ID',
`money` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '变更余额',
`before` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '变更前余额',
`after` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '变更后余额',
`memo` varchar(255) DEFAULT '' COMMENT '备注',
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='会员余额变动表';
-- ----------------------------
-- Table structure for fa_user_rule
-- ----------------------------
DROP TABLE IF EXISTS `fa_user_rule`;
CREATE TABLE `fa_user_rule` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`pid` int(10) DEFAULT NULL COMMENT '父ID',
`name` varchar(50) DEFAULT NULL COMMENT '名称',
`title` varchar(50) DEFAULT '' COMMENT '标题',
`remark` varchar(100) DEFAULT NULL COMMENT '备注',
`ismenu` tinyint(1) DEFAULT NULL COMMENT '是否菜单',
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
`weigh` int(10) DEFAULT '0' COMMENT '权重',
`status` enum('normal','hidden') DEFAULT NULL COMMENT '状态',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='会员规则表';
-- ----------------------------
-- Records of fa_user_rule
-- ----------------------------
BEGIN;
INSERT INTO `fa_user_rule` VALUES (1, 0, 'index', 'Frontend', '', 1, 1491635035, 1491635035, 1, 'normal');
INSERT INTO `fa_user_rule` VALUES (2, 0, 'api', 'API Interface', '', 1, 1491635035, 1491635035, 2, 'normal');
INSERT INTO `fa_user_rule` VALUES (3, 1, 'user', 'User Module', '', 1, 1491635035, 1491635035, 12, 'normal');
INSERT INTO `fa_user_rule` VALUES (4, 2, 'user', 'User Module', '', 1, 1491635035, 1491635035, 11, 'normal');
INSERT INTO `fa_user_rule` VALUES (5, 3, 'index/user/login', 'Login', '', 0, 1491635035, 1491635035, 5, 'normal');
INSERT INTO `fa_user_rule` VALUES (6, 3, 'index/user/register', 'Register', '', 0, 1491635035, 1491635035, 7, 'normal');
INSERT INTO `fa_user_rule` VALUES (7, 3, 'index/user/index', 'User Center', '', 0, 1491635035, 1491635035, 9, 'normal');
INSERT INTO `fa_user_rule` VALUES (8, 3, 'index/user/profile', 'Profile', '', 0, 1491635035, 1491635035, 4, 'normal');
INSERT INTO `fa_user_rule` VALUES (9, 4, 'api/user/login', 'Login', '', 0, 1491635035, 1491635035, 6, 'normal');
INSERT INTO `fa_user_rule` VALUES (10, 4, 'api/user/register', 'Register', '', 0, 1491635035, 1491635035, 8, 'normal');
INSERT INTO `fa_user_rule` VALUES (11, 4, 'api/user/index', 'User Center', '', 0, 1491635035, 1491635035, 10, 'normal');
INSERT INTO `fa_user_rule` VALUES (12, 4, 'api/user/profile', 'Profile', '', 0, 1491635035, 1491635035, 3, 'normal');
COMMIT;
-- ----------------------------
-- Table structure for fa_user_score_log
-- ----------------------------
DROP TABLE IF EXISTS `fa_user_score_log`;
CREATE TABLE `fa_user_score_log` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '会员ID',
`score` int(10) NOT NULL DEFAULT '0' COMMENT '变更积分',
`before` int(10) NOT NULL DEFAULT '0' COMMENT '变更前积分',
`after` int(10) NOT NULL DEFAULT '0' COMMENT '变更后积分',
`memo` varchar(255) DEFAULT '' COMMENT '备注',
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='会员积分变动表';
-- ----------------------------
-- Table structure for fa_user_token
-- ----------------------------
DROP TABLE IF EXISTS `fa_user_token`;
CREATE TABLE `fa_user_token` (
`token` varchar(50) NOT NULL COMMENT 'Token',
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '会员ID',
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
`expiretime` bigint(16) DEFAULT NULL COMMENT '过期时间',
PRIMARY KEY (`token`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='会员Token表';
-- ----------------------------
-- Table structure for fa_version
-- ----------------------------
DROP TABLE IF EXISTS `fa_version`;
CREATE TABLE `fa_version` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`oldversion` varchar(30) DEFAULT '' COMMENT '旧版本号',
`newversion` varchar(30) DEFAULT '' COMMENT '新版本号',
`packagesize` varchar(30) DEFAULT '' COMMENT '包大小',
`content` varchar(500) DEFAULT '' COMMENT '升级内容',
`downloadurl` varchar(255) DEFAULT '' COMMENT '下载地址',
`enforce` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '强制更新',
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
`weigh` int(10) NOT NULL DEFAULT 0 COMMENT '权重',
`status` varchar(30) DEFAULT '' COMMENT '状态',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='版本表';
SET FOREIGN_KEY_CHECKS = 1;

View File

@ -0,0 +1,316 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>{:__('Installing FastAdmin')}</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
<meta name="renderer" content="webkit">
<style>
body {
background: #f1f6fd;
margin: 0;
padding: 0;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body, input, button {
font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, 'Microsoft Yahei', Arial, sans-serif;
font-size: 14px;
color: #7E96B3;
}
.container {
max-width: 480px;
margin: 0 auto;
padding: 20px;
text-align: center;
}
a {
color: #4e73df;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
h1 {
margin-top: 0;
margin-bottom: 10px;
}
h2 {
font-size: 28px;
font-weight: normal;
color: #3C5675;
margin-bottom: 0;
margin-top: 0;
}
form {
margin-top: 40px;
}
.form-group {
margin-bottom: 20px;
}
.form-group .form-field:first-child input {
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.form-group .form-field:last-child input {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
.form-field input {
background: #fff;
margin: 0 0 2px;
border: 2px solid transparent;
transition: background 0.2s, border-color 0.2s, color 0.2s;
width: 100%;
padding: 15px 15px 15px 180px;
box-sizing: border-box;
}
.form-field input:focus {
border-color: #4e73df;
background: #fff;
color: #444;
outline: none;
}
.form-field label {
float: left;
width: 160px;
text-align: right;
margin-right: -160px;
position: relative;
margin-top: 15px;
font-size: 14px;
pointer-events: none;
opacity: 0.7;
}
button, .btn {
background: #3C5675;
color: #fff;
border: 0;
font-weight: bold;
border-radius: 4px;
cursor: pointer;
padding: 15px 30px;
-webkit-appearance: none;
}
button[disabled] {
opacity: 0.5;
}
.form-buttons {
height: 52px;
line-height: 52px;
}
.form-buttons .btn {
margin-right: 5px;
}
#error, .error, #success, .success, #warmtips, .warmtips {
background: #D83E3E;
color: #fff;
padding: 15px 20px;
border-radius: 4px;
margin-bottom: 20px;
}
#success {
background: #3C5675;
}
#error a, .error a {
color: white;
text-decoration: underline;
}
#warmtips {
background: #ffcdcd;
font-size: 14px;
color: #e74c3c;
}
#warmtips a {
background: #ffffff7a;
display: block;
height: 30px;
line-height: 30px;
margin-top: 10px;
color: #e21a1a;
border-radius: 3px;
}
</style>
</head>
<body>
<div class="container">
<h1>
<svg width="80px" height="96px" viewBox="0 0 768 830" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="logo" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M64.433651,605.899968 C20.067302,536.265612 0,469.698785 0,389.731348 C0,174.488668 171.922656,0 384,0 C596.077344,0 768,174.488668 768,389.731348 C768,469.698785 747.932698,536.265612 703.566349,605.899968 C614.4,753.480595 441.6,870.4 384,870.4 C326.4,870.4 153.6,753.480595 64.433651,605.899968 L64.433651,605.899968 Z"
id="body" fill="#4e73df"></path>
<path d="M429.648991,190.816 L430.160991,190.816 L429.648991,190.816 L429.648991,190.816 Z M429.648991,156 L427.088991,156 C419.408991,157.024 411.728991,160.608 404.560991,168.8 L403.024991,170.848 L206.928991,429.92 C198.736991,441.184 197.712991,453.984 204.368991,466.784 C210.512991,478.048 222.288991,485.728 235.600991,485.728 L336.464991,486.24 L304.208991,673.632 C301.648991,689.504 310.352991,705.376 325.200991,712.032 C329.808991,714.08 334.416991,714.592 339.536991,714.592 C349.776991,714.592 358.992991,709.472 366.160991,700.256 L561.744991,419.168 C569.936991,407.904 570.960991,395.104 564.304991,382.304 C557.648991,369.504 547.408991,363.36 533.072991,363.36 L432.208991,363.36 L463.952991,199.008 C464.464991,196.448 464.976991,193.376 464.976991,190.816 C464.976991,171.872 449.104991,156 431.184991,156 L429.648991,156 L429.648991,156 Z"
id="flash" fill="#FFFFFF"></path>
</g>
</svg>
</h1>
<h2>{:__('Installing FastAdmin')}</h2>
<div>
<form method="post">
{if $errInfo}
<div class="error">
{$errInfo}
</div>
{/if}
<div id="error" style="display:none"></div>
<div id="success" style="display:none"></div>
<div id="warmtips" style="display:none"></div>
<div class="form-group">
<div class="form-field">
<label>{:__('Mysql Hostname')}</label>
<input type="text" name="mysqlHostname" value="127.0.0.1" required="">
</div>
<div class="form-field">
<label>{:__('Mysql Database')}</label>
<input type="text" name="mysqlDatabase" value="" required="">
</div>
<div class="form-field">
<label>{:__('Mysql Username')}</label>
<input type="text" name="mysqlUsername" value="root" required="">
</div>
<div class="form-field">
<label>{:__('Mysql Password')}</label>
<input type="password" name="mysqlPassword">
</div>
<div class="form-field">
<label>{:__('Mysql Prefix')}</label>
<input type="text" name="mysqlPrefix" value="fa_">
</div>
<div class="form-field">
<label>{:__('Mysql Hostport')}</label>
<input type="number" name="mysqlHostport" value="3306">
</div>
</div>
<div class="form-group">
<div class="form-field">
<label>{:__('Admin Username')}</label>
<input name="adminUsername" value="admin" required=""/>
</div>
<div class="form-field">
<label>{:__('Admin Email')}</label>
<input name="adminEmail" value="admin@admin.com" required="">
</div>
<div class="form-field">
<label>{:__('Admin Password')}</label>
<input type="password" name="adminPassword" required="">
</div>
<div class="form-field">
<label>{:__('Repeat Password')}</label>
<input type="password" name="adminPasswordConfirmation" required="">
</div>
</div>
<div class="form-group">
<div class="form-field">
<label>{:__('Website')}</label>
<input type="text" name="siteName" value="{:__('My Website')}" required=""/>
</div>
</div>
<div class="form-buttons">
<!--@formatter:off-->
<button type="submit" {:$errInfo?'disabled':''}>{:__('Install now')}</button>
<!--@formatter:on-->
</div>
</form>
<!-- jQuery -->
<script src="https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js"></script>
<script>
$(function () {
$('form :input:first').select();
$('form').on('submit', function (e) {
e.preventDefault();
var form = this;
var $error = $("#error");
var $success = $("#success");
var $button = $(this).find('button')
.text("{:__('Installing')}")
.prop('disabled', true);
$.ajax({
url: "",
type: "POST",
dataType: "json",
data: $(this).serialize(),
success: function (ret) {
if (ret.code == 1) {
var data = ret.data;
$error.hide();
$(".form-group", form).remove();
$button.remove();
$("#success").text(ret.msg).show();
$buttons = $(".form-buttons", form);
$("<a class='btn' href='./'>{:__('Home')}</a>").appendTo($buttons);
if (typeof data.adminName !== 'undefined') {
var url = location.href.replace(/install\.php/, data.adminName);
$("#warmtips").html("{:__('Security tips')}" + '<a href="' + url + '">' + url + '</a>').show();
$('<a class="btn" href="' + url + '" id="btn-admin" style="background:#4e73df">' + "{:__('Dashboard')}" + '</a>').appendTo($buttons);
}
localStorage.setItem("fastep", "installed");
} else {
$error.show().text(ret.msg);
$button.prop('disabled', false).text("{:__('Install now')}");
$("html,body").animate({
scrollTop: 0
}, 500);
}
},
error: function (xhr) {
$error.show().text(xhr.responseText);
$button.prop('disabled', false).text("{:__('Install now')}");
$("html,body").animate({
scrollTop: 0
}, 500);
}
});
return false;
});
});
</script>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,35 @@
<?php
return [
'Warning' => '温馨提示',
'Installing FastAdmin' => '安装FastAdmin',
'Mysql Hostname' => 'MySQL 数据库地址',
'Mysql Database' => 'MySQL 数据库名',
'Mysql Username' => 'MySQL 用户名',
'Mysql Password' => 'MySQL 密码',
'Mysql Prefix' => 'MySQL 数据表前缀',
'Mysql Hostport' => 'MySQL 端口号',
'Admin Username' => '管理员用户名',
'Admin Email' => '管理员Email',
'Admin Password' => '管理员密码',
'Repeat Password' => '重复管理员密码',
'Website' => '网站名称',
'My Website' => '我的网站',
'Install now' => '点击安装',
'Installing' => '安装中...',
'Home' => '访问首页',
'Dashboard' => '进入后台',
'Go back' => '返回上一页',
'Install Successed' => '安装成功!',
'Security tips' => '温馨提示:请将以下后台登录入口添加到你的收藏夹,为了你的安全,不要泄漏或发送给他人!如有泄漏请及时修改!',
'Please input correct database' => '请输入正确的数据库名',
'Please input correct username' => '用户名只能由3-30位数字、字母、下划线组合',
'Please input correct password' => '密码长度必须在6-30位之间不能包含空格',
'Password is too weak' => '密码太简单,请重新输入',
'The two passwords you entered did not match' => '两次输入的密码不一致',
'Please input correct website' => '网站名称输入不正确',
'The current version %s is too low, please use PHP 7.1 or higher' => '当前版本%s过低请使用PHP7.1以上版本',
'PDO is not currently installed and cannot be installed' => '当前未开启PDO无法进行安装',
'The current permissions are insufficient to write the file %s' => '当前权限不足,无法写入文件%s',
'Please go to the official website to download the full package or resource package and try to install' => '当前代码仅包含核心代码,请前往官网下载完整包或资源包覆盖后再尝试安装',
'The system has been installed. If you need to reinstall, please remove %s first' => '当前已经安装成功,如果需要重新安装,请手动移除%s文件',
];

View File

@ -0,0 +1,327 @@
<?php
namespace app\admin\command;
use app\admin\model\AuthRule;
use ReflectionClass;
use ReflectionMethod;
use think\Cache;
use think\Config;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\Exception;
use think\Loader;
class Menu extends Command
{
protected $model = null;
protected function configure()
{
$this
->setName('menu')
->addOption('controller', 'c', Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, 'controller name,use \'all-controller\' when build all menu', null)
->addOption('delete', 'd', Option::VALUE_OPTIONAL, 'delete the specified menu', '')
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force delete menu,without tips', null)
->addOption('equal', 'e', Option::VALUE_OPTIONAL, 'the controller must be equal', null)
->setDescription('Build auth menu from controller');
//要执行的controller必须一样不适用模糊查询
}
protected function execute(Input $input, Output $output)
{
$this->model = new AuthRule();
$adminPath = dirname(__DIR__) . DS;
//控制器名
$controller = $input->getOption('controller') ?: '';
if (!$controller) {
throw new Exception("please input controller name");
}
$force = $input->getOption('force');
//是否为删除模式
$delete = $input->getOption('delete');
//是否控制器完全匹配
$equal = $input->getOption('equal');
if ($delete) {
if (in_array('all-controller', $controller)) {
throw new Exception("could not delete all menu");
}
$ids = [];
$list = $this->model->where(function ($query) use ($controller, $equal) {
foreach ($controller as $index => $item) {
if (stripos($item, '_') !== false) {
$item = Loader::parseName($item, 1);
}
if (stripos($item, '/') !== false) {
$controllerArr = explode('/', $item);
end($controllerArr);
$key = key($controllerArr);
$controllerArr[$key] = Loader::parseName($controllerArr[$key]);
} else {
$controllerArr = [Loader::parseName($item)];
}
$item = str_replace('_', '\_', implode('/', $controllerArr));
if ($equal) {
$query->whereOr('name', 'eq', $item);
} else {
$query->whereOr('name', 'like', strtolower($item) . "%");
}
}
})->select();
foreach ($list as $k => $v) {
$output->warning($v->name);
$ids[] = $v->id;
}
if (!$ids) {
throw new Exception("There is no menu to delete");
}
if (!$force) {
$output->info("Are you sure you want to delete all those menu? Type 'yes' to continue: ");
$line = fgets(defined('STDIN') ? STDIN : fopen('php://stdin', 'r'));
if (trim($line) != 'yes') {
throw new Exception("Operation is aborted!");
}
}
AuthRule::destroy($ids);
Cache::rm("__menu__");
$output->info("Delete Successed");
return;
}
if (!in_array('all-controller', $controller)) {
foreach ($controller as $index => $item) {
if (stripos($item, '_') !== false) {
$item = Loader::parseName($item, 1);
}
if (stripos($item, '/') !== false) {
$controllerArr = explode('/', $item);
end($controllerArr);
$key = key($controllerArr);
$controllerArr[$key] = ucfirst($controllerArr[$key]);
} else {
$controllerArr = [ucfirst($item)];
}
$adminPath = dirname(__DIR__) . DS . 'controller' . DS . implode(DS, $controllerArr) . '.php';
if (!is_file($adminPath)) {
$output->error("controller not found");
return;
}
$this->importRule($item);
}
} else {
$authRuleList = AuthRule::select();
//生成权限规则备份文件
file_put_contents(RUNTIME_PATH . 'authrule.json', json_encode(collection($authRuleList)->toArray()));
$this->model->where('id', '>', 0)->delete();
$controllerDir = $adminPath . 'controller' . DS;
// 扫描新的节点信息并导入
$treelist = $this->import($this->scandir($controllerDir));
}
Cache::rm("__menu__");
$output->info("Build Successed!");
}
/**
* 递归扫描文件夹
* @param string $dir
* @return array
*/
public function scandir($dir)
{
$result = [];
$cdir = scandir($dir);
foreach ($cdir as $value) {
if (!in_array($value, array(".", ".."))) {
if (is_dir($dir . DS . $value)) {
$result[$value] = $this->scandir($dir . DS . $value);
} else {
$result[] = $value;
}
}
}
return $result;
}
/**
* 导入规则节点
* @param array $dirarr
* @param array $parentdir
* @return array
*/
public function import($dirarr, $parentdir = [])
{
$menuarr = [];
foreach ($dirarr as $k => $v) {
if (is_array($v)) {
//当前是文件夹
$nowparentdir = array_merge($parentdir, [$k]);
$this->import($v, $nowparentdir);
} else {
//只匹配PHP文件
if (!preg_match('/^(\w+)\.php$/', $v, $matchone)) {
continue;
}
//导入文件
$controller = ($parentdir ? implode('/', $parentdir) . '/' : '') . $matchone[1];
$this->importRule($controller);
}
}
return $menuarr;
}
protected function importRule($controller)
{
$controller = str_replace('\\', '/', $controller);
if (stripos($controller, '/') !== false) {
$controllerArr = explode('/', $controller);
end($controllerArr);
$key = key($controllerArr);
$controllerArr[$key] = ucfirst($controllerArr[$key]);
} else {
$key = 0;
$controllerArr = [ucfirst($controller)];
}
$classSuffix = Config::get('controller_suffix') ? ucfirst(Config::get('url_controller_layer')) : '';
$className = "\\app\\admin\\controller\\" . implode("\\", $controllerArr) . $classSuffix;
$pathArr = $controllerArr;
array_unshift($pathArr, '', 'application', 'admin', 'controller');
$classFile = ROOT_PATH . implode(DS, $pathArr) . $classSuffix . ".php";
$classContent = file_get_contents($classFile);
$uniqueName = uniqid("FastAdmin") . $classSuffix;
$classContent = str_replace("class " . $controllerArr[$key] . $classSuffix . " ", 'class ' . $uniqueName . ' ', $classContent);
$classContent = preg_replace("/namespace\s(.*);/", 'namespace ' . __NAMESPACE__ . ";", $classContent);
//临时的类文件
$tempClassFile = __DIR__ . DS . $uniqueName . ".php";
file_put_contents($tempClassFile, $classContent);
$className = "\\app\\admin\\command\\" . $uniqueName;
//删除临时文件
register_shutdown_function(function () use ($tempClassFile) {
if ($tempClassFile) {
//删除临时文件
@unlink($tempClassFile);
}
});
//反射机制调用类的注释和方法名
$reflector = new ReflectionClass($className);
//只匹配公共的方法
$methods = $reflector->getMethods(ReflectionMethod::IS_PUBLIC);
$classComment = $reflector->getDocComment();
//判断是否有启用软删除
$softDeleteMethods = ['destroy', 'restore', 'recyclebin'];
$withSofeDelete = false;
$modelRegexArr = ["/\\\$this\->model\s*=\s*model\(['|\"](\w+)['|\"]\);/", "/\\\$this\->model\s*=\s*new\s+([a-zA-Z\\\]+);/"];
$modelRegex = preg_match($modelRegexArr[0], $classContent) ? $modelRegexArr[0] : $modelRegexArr[1];
preg_match_all($modelRegex, $classContent, $matches);
if (isset($matches[1]) && isset($matches[1][0]) && $matches[1][0]) {
\think\Request::instance()->module('admin');
$model = model($matches[1][0]);
if (in_array('trashed', get_class_methods($model))) {
$withSofeDelete = true;
}
}
//忽略的类
if (stripos($classComment, "@internal") !== false) {
return;
}
preg_match_all('#(@.*?)\n#s', $classComment, $annotations);
$controllerIcon = 'fa fa-circle-o';
$controllerRemark = '';
//判断注释中是否设置了icon值
if (isset($annotations[1])) {
foreach ($annotations[1] as $tag) {
if (stripos($tag, '@icon') !== false) {
$controllerIcon = substr($tag, stripos($tag, ' ') + 1);
}
if (stripos($tag, '@remark') !== false) {
$controllerRemark = substr($tag, stripos($tag, ' ') + 1);
}
}
}
//过滤掉其它字符
$controllerTitle = trim(preg_replace(array('/^\/\*\*(.*)[\n\r\t]/u', '/[\s]+\*\//u', '/\*\s@(.*)/u', '/[\s|\*]+/u'), '', $classComment));
//导入中文语言包
\think\Lang::load(dirname(__DIR__) . DS . 'lang/zh-cn.php');
//先导入菜单的数据
$pid = 0;
foreach ($controllerArr as $k => $v) {
$key = $k + 1;
//驼峰转下划线
$controllerNameArr = array_slice($controllerArr, 0, $key);
foreach ($controllerNameArr as &$val) {
$val = strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $val), "_"));
}
unset($val);
$name = implode('/', $controllerNameArr);
$title = (!isset($controllerArr[$key]) ? $controllerTitle : '');
$icon = (!isset($controllerArr[$key]) ? $controllerIcon : 'fa fa-list');
$remark = (!isset($controllerArr[$key]) ? $controllerRemark : '');
$title = $title ? $title : $v;
$rulemodel = $this->model->get(['name' => $name]);
if (!$rulemodel) {
$this->model
->data(['pid' => $pid, 'name' => $name, 'title' => $title, 'icon' => $icon, 'remark' => $remark, 'ismenu' => 1, 'status' => 'normal'])
->isUpdate(false)
->save();
$pid = $this->model->id;
} else {
$pid = $rulemodel->id;
}
}
$ruleArr = [];
foreach ($methods as $m => $n) {
//过滤特殊的类
if (substr($n->name, 0, 2) == '__' || $n->name == '_initialize') {
continue;
}
//未启用软删除时过滤相关方法
if (!$withSofeDelete && in_array($n->name, $softDeleteMethods)) {
continue;
}
//只匹配符合的方法
if (!preg_match('/^(\w+)' . Config::get('action_suffix') . '/', $n->name, $matchtwo)) {
unset($methods[$m]);
continue;
}
$comment = $reflector->getMethod($n->name)->getDocComment();
//忽略的方法
if (stripos($comment, "@internal") !== false) {
continue;
}
//过滤掉其它字符
$comment = preg_replace(array('/^\/\*\*(.*)[\n\r\t]/u', '/[\s]+\*\//u', '/\*\s@(.*)/u', '/[\s|\*]+/u'), '', $comment);
$title = $comment ? $comment : ucfirst($n->name);
//获取主键作为AuthRule更新依据
$id = $this->getAuthRulePK($name . "/" . strtolower($n->name));
$ruleArr[] = array('id' => $id, 'pid' => $pid, 'name' => $name . "/" . strtolower($n->name), 'icon' => 'fa fa-circle-o', 'title' => $title, 'ismenu' => 0, 'status' => 'normal');
}
$this->model->isUpdate(false)->saveAll($ruleArr);
}
//获取主键
protected function getAuthRulePK($name)
{
if (!empty($name)) {
$id = $this->model
->where('name', $name)
->value('id');
return $id ? $id : null;
}
}
}

View File

@ -0,0 +1,162 @@
<?php
namespace app\admin\command;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\Exception;
class Min extends Command
{
/**
* 路径和文件名配置
*/
protected $options = [
'cssBaseUrl' => 'public/assets/css/',
'cssBaseName' => '{module}',
'jsBaseUrl' => 'public/assets/js/',
'jsBaseName' => 'require-{module}',
];
protected function configure()
{
$this
->setName('min')
->addOption('module', 'm', Option::VALUE_REQUIRED, 'module name(frontend or backend),use \'all\' when build all modules', null)
->addOption('resource', 'r', Option::VALUE_REQUIRED, 'resource name(js or css),use \'all\' when build all resources', null)
->addOption('optimize', 'o', Option::VALUE_OPTIONAL, 'optimize type(uglify|closure|none)', 'none')
->setDescription('Compress js and css file');
}
protected function execute(Input $input, Output $output)
{
$module = $input->getOption('module') ?: '';
$resource = $input->getOption('resource') ?: '';
$optimize = $input->getOption('optimize') ?: 'none';
if (!$module || !in_array($module, ['frontend', 'backend', 'all'])) {
throw new Exception('Please input correct module name');
}
if (!$resource || !in_array($resource, ['js', 'css', 'all'])) {
throw new Exception('Please input correct resource name');
}
$moduleArr = $module == 'all' ? ['frontend', 'backend'] : [$module];
$resourceArr = $resource == 'all' ? ['js', 'css'] : [$resource];
$minPath = __DIR__ . DS . 'Min' . DS;
$publicPath = ROOT_PATH . 'public' . DS;
$tempFile = $minPath . 'temp.js';
$nodeExec = '';
if (!$nodeExec) {
if (IS_WIN) {
// Winsows下请手动配置配置该值,一般将该值配置为 '"C:\Program Files\nodejs\node.exe"'除非你的Node安装路径有变更
$nodeExec = 'C:\Program Files\nodejs\node.exe';
if (file_exists($nodeExec)) {
$nodeExec = '"' . $nodeExec . '"';
} else {
// 如果 '"C:\Program Files\nodejs\node.exe"' 不存在可能是node安装路径有变更
// 但安装node会自动配置环境变量直接执行 '"node.exe"' 提高第一次使用压缩打包的成功率
$nodeExec = '"node.exe"';
}
} else {
try {
$nodeExec = exec("which node");
if (!$nodeExec) {
throw new Exception("node environment not found!please install node first!");
}
} catch (Exception $e) {
throw new Exception($e->getMessage());
}
}
}
foreach ($moduleArr as $mod) {
foreach ($resourceArr as $res) {
$data = [
'publicPath' => $publicPath,
'jsBaseName' => str_replace('{module}', $mod, $this->options['jsBaseName']),
'jsBaseUrl' => $this->options['jsBaseUrl'],
'cssBaseName' => str_replace('{module}', $mod, $this->options['cssBaseName']),
'cssBaseUrl' => $this->options['cssBaseUrl'],
'jsBasePath' => str_replace(DS, '/', ROOT_PATH . $this->options['jsBaseUrl']),
'cssBasePath' => str_replace(DS, '/', ROOT_PATH . $this->options['cssBaseUrl']),
'optimize' => $optimize,
'ds' => DS,
];
//源文件
$from = $data["{$res}BasePath"] . $data["{$res}BaseName"] . '.' . $res;
if (!is_file($from)) {
$output->error("{$res} source file not found!file:{$from}");
continue;
}
if ($res == "js") {
$content = file_get_contents($from);
preg_match("/require\.config\(\{[\r\n]?[\n]?+(.*?)[\r\n]?[\n]?}\);/is", $content, $matches);
if (!isset($matches[1])) {
$output->error("js config not found!");
continue;
}
$config = preg_replace("/(urlArgs|baseUrl):(.*)\n/", '', $matches[1]);
$data['config'] = $config;
}
// 生成压缩文件
$this->writeToFile($res, $data, $tempFile);
$output->info("Compress " . $data["{$res}BaseName"] . ".{$res}");
// 执行压缩
$command = "{$nodeExec} \"{$minPath}r.js\" -o \"{$tempFile}\" >> \"{$minPath}node.log\"";
if ($output->isDebug()) {
$output->warning($command);
}
echo exec($command);
}
}
if (!$output->isDebug()) {
@unlink($tempFile);
}
$output->info("Build Successed!");
}
/**
* 写入到文件
* @param string $name
* @param array $data
* @param string $pathname
* @return mixed
*/
protected function writeToFile($name, $data, $pathname)
{
$search = $replace = [];
foreach ($data as $k => $v) {
$search[] = "{%{$k}%}";
$replace[] = $v;
}
$stub = file_get_contents($this->getStub($name));
$content = str_replace($search, $replace, $stub);
if (!is_dir(dirname($pathname))) {
mkdir(strtolower(dirname($pathname)), 0755, true);
}
return file_put_contents($pathname, $content);
}
/**
* 获取基础模板
* @param string $name
* @return string
*/
protected function getStub($name)
{
return __DIR__ . DS . 'Min' . DS . 'stubs' . DS . $name . '.stub';
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,6 @@
({
cssIn: "{%cssBasePath%}{%cssBaseName%}.css",
out: "{%cssBasePath%}{%cssBaseName%}.min.css",
optimizeCss: "default",
optimize: "{%optimize%}"
})

View File

@ -0,0 +1,11 @@
({
{%config%}
,
optimizeCss: "standard",
optimize: "{%optimize%}", //可使用uglify|closure|none
preserveLicenseComments: false,
removeCombined: false,
baseUrl: "{%jsBasePath%}", //JS文件所在的基础目录
name: "{%jsBaseName%}", //来源文件,不包含后缀
out: "{%jsBasePath%}{%jsBaseName%}.min.js" //目标文件
});

View File

@ -0,0 +1,197 @@
<?php
use app\common\model\Category;
use fast\Form;
use fast\Tree;
use think\Db;
use think\Loader;
if (!function_exists('build_select')) {
/**
* 生成下拉列表
* @param string $name
* @param mixed $options
* @param mixed $selected
* @param mixed $attr
* @return string
*/
function build_select($name, $options, $selected = [], $attr = [])
{
$options = is_array($options) ? $options : explode(',', $options);
$selected = is_array($selected) ? $selected : explode(',', $selected);
return Form::select($name, $options, $selected, $attr);
}
}
if (!function_exists('build_radios')) {
/**
* 生成单选按钮组
* @param string $name
* @param array $list
* @param mixed $selected
* @return string
*/
function build_radios($name, $list = [], $selected = null)
{
$html = [];
$selected = is_null($selected) ? key($list) : $selected;
$selected = is_array($selected) ? $selected : explode(',', $selected);
foreach ($list as $k => $v) {
$html[] = sprintf(Form::label("{$name}-{$k}", "%s {$v}"), Form::radio($name, $k, in_array($k, $selected), ['id' => "{$name}-{$k}"]));
}
return '<div class="radio">' . implode(' ', $html) . '</div>';
}
}
if (!function_exists('build_checkboxs')) {
/**
* 生成复选按钮组
* @param string $name
* @param array $list
* @param mixed $selected
* @return string
*/
function build_checkboxs($name, $list = [], $selected = null)
{
$html = [];
$selected = is_null($selected) ? [] : $selected;
$selected = is_array($selected) ? $selected : explode(',', $selected);
foreach ($list as $k => $v) {
$html[] = sprintf(Form::label("{$name}-{$k}", "%s {$v}"), Form::checkbox($name, $k, in_array($k, $selected), ['id' => "{$name}-{$k}"]));
}
return '<div class="checkbox">' . implode(' ', $html) . '</div>';
}
}
if (!function_exists('build_category_select')) {
/**
* 生成分类下拉列表框
* @param string $name
* @param string $type
* @param mixed $selected
* @param array $attr
* @param array $header
* @return string
*/
function build_category_select($name, $type, $selected = null, $attr = [], $header = [])
{
$tree = Tree::instance();
$tree->init(Category::getCategoryArray($type), 'pid');
$categorylist = $tree->getTreeList($tree->getTreeArray(0), 'name');
$categorydata = $header ? $header : [];
foreach ($categorylist as $k => $v) {
$categorydata[$v['id']] = $v['name'];
}
$attr = array_merge(['id' => "c-{$name}", 'class' => 'form-control selectpicker'], $attr);
return build_select($name, $categorydata, $selected, $attr);
}
}
if (!function_exists('build_toolbar')) {
/**
* 生成表格操作按钮栏
* @param array $btns 按钮组
* @param array $attr 按钮属性值
* @return string
*/
function build_toolbar($btns = null, $attr = [])
{
$auth = \app\admin\library\Auth::instance();
$controller = str_replace('.', '/', Loader::parseName(request()->controller()));
$btns = $btns ? $btns : ['refresh', 'add', 'edit', 'del', 'import'];
$btns = is_array($btns) ? $btns : explode(',', $btns);
$index = array_search('delete', $btns);
if ($index !== false) {
$btns[$index] = 'del';
}
$btnAttr = [
'refresh' => ['javascript:;', 'btn btn-primary btn-refresh', 'fa fa-refresh', '', __('Refresh')],
'add' => ['javascript:;', 'btn btn-success btn-add', 'fa fa-plus', __('Add'), __('Add')],
'edit' => ['javascript:;', 'btn btn-success btn-edit btn-disabled disabled', 'fa fa-pencil', __('Edit'), __('Edit')],
'del' => ['javascript:;', 'btn btn-danger btn-del btn-disabled disabled', 'fa fa-trash', __('Delete'), __('Delete')],
'import' => ['javascript:;', 'btn btn-info btn-import', 'fa fa-upload', __('Import'), __('Import')],
];
$btnAttr = array_merge($btnAttr, $attr);
$html = [];
foreach ($btns as $k => $v) {
//如果未定义或没有权限
if (!isset($btnAttr[$v]) || ($v !== 'refresh' && !$auth->check("{$controller}/{$v}"))) {
continue;
}
list($href, $class, $icon, $text, $title) = $btnAttr[$v];
//$extend = $v == 'import' ? 'id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"' : '';
//$html[] = '<a href="' . $href . '" class="' . $class . '" title="' . $title . '" ' . $extend . '><i class="' . $icon . '"></i> ' . $text . '</a>';
if ($v == 'import') {
$template = str_replace('/', '_', $controller);
$download = '';
if (file_exists("./template/{$template}.xlsx")) {
$download .= "<li><a href=\"/template/{$template}.xlsx\" target=\"_blank\">XLSX模版</a></li>";
}
if (file_exists("./template/{$template}.xls")) {
$download .= "<li><a href=\"/template/{$template}.xls\" target=\"_blank\">XLS模版</a></li>";
}
if (file_exists("./template/{$template}.csv")) {
$download .= empty($download) ? '' : "<li class=\"divider\"></li>";
$download .= "<li><a href=\"/template/{$template}.csv\" target=\"_blank\">CSV模版</a></li>";
}
$download .= empty($download) ? '' : "\n ";
if (!empty($download)) {
$html[] = <<<EOT
<div class="btn-group">
<button type="button" href="{$href}" class="btn btn-info btn-import" title="{$title}" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="{$icon}"></i> {$text}</button>
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" title="下载批量导入模版">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" role="menu">{$download}</ul>
</div>
EOT;
} else {
$html[] = '<a href="' . $href . '" class="' . $class . '" title="' . $title . '" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="' . $icon . '"></i> ' . $text . '</a>';
}
} else {
$html[] = '<a href="' . $href . '" class="' . $class . '" title="' . $title . '"><i class="' . $icon . '"></i> ' . $text . '</a>';
}
}
return implode(' ', $html);
}
}
if (!function_exists('build_heading')) {
/**
* 生成页面Heading
*
* @param string $path 指定的path
* @return string
*/
function build_heading($path = null, $container = true)
{
$title = $content = '';
if (is_null($path)) {
$action = request()->action();
$controller = str_replace('.', '/', Loader::parseName(request()->controller()));
$path = strtolower($controller . ($action && $action != 'index' ? '/' . $action : ''));
}
// 根据当前的URI自动匹配父节点的标题和备注
$data = Db::name('auth_rule')->where('name', $path)->field('title,remark')->find();
if ($data) {
$title = __($data['title']);
$content = __($data['remark']);
}
if (!$content) {
return '';
}
$result = '<div class="panel-lead"><em>' . $title . '</em>' . $content . '</div>';
if ($container) {
$result = '<div class="panel-heading">' . $result . '</div>';
}
return $result;
}
}

View File

@ -0,0 +1,8 @@
<?php
//配置文件
return [
'url_common_param' => true,
'url_html_suffix' => '',
'controller_auto_search' => true,
];

View File

@ -0,0 +1,454 @@
<?php
namespace app\admin\controller;
use app\common\controller\Backend;
use fast\Http;
use think\addons\AddonException;
use think\addons\Service;
use think\Cache;
use think\Config;
use think\Db;
use think\Exception;
/**
* 插件管理
*
* @icon fa fa-cube
* @remark 可在线安装、卸载、禁用、启用、配置、升级插件,插件升级前请做好备份。
*/
class Addon extends Backend
{
protected $model = null;
protected $noNeedRight = ['get_table_list'];
public function _initialize()
{
parent::_initialize();
if (!$this->auth->isSuperAdmin() && in_array($this->request->action(), ['install', 'uninstall', 'local', 'upgrade', 'authorization', 'testdata'])) {
$this->error(__('Access is allowed only to the super management group'));
}
}
/**
* 插件列表
*/
public function index()
{
$addons = get_addon_list();
foreach ($addons as $k => &$v) {
$config = get_addon_config($v['name']);
$v['config'] = $config ? 1 : 0;
$v['url'] = str_replace($this->request->server('SCRIPT_NAME'), '', $v['url']);
}
$this->assignconfig(['addons' => $addons, 'api_url' => config('fastadmin.api_url'), 'faversion' => config('fastadmin.version'), 'domain' => request()->host(true)]);
return $this->view->fetch();
}
/**
* 配置
*/
public function config($name = null)
{
$name = $name ? $name : $this->request->get("name");
if (!$name) {
$this->error(__('Parameter %s can not be empty', 'name'));
}
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
$this->error(__('Addon name incorrect'));
}
$info = get_addon_info($name);
$config = get_addon_fullconfig($name);
if (!$info) {
$this->error(__('Addon not exists'));
}
if ($this->request->isPost()) {
$params = $this->request->post("row/a", [], 'trim');
if ($params) {
foreach ($config as $k => &$v) {
if (isset($params[$v['name']])) {
if ($v['type'] == 'array') {
$params[$v['name']] = is_array($params[$v['name']]) ? $params[$v['name']] : (array)json_decode($params[$v['name']], true);
$value = $params[$v['name']];
} else {
$value = is_array($params[$v['name']]) ? implode(',', $params[$v['name']]) : $params[$v['name']];
}
$v['value'] = $value;
}
}
try {
$addon = get_addon_instance($name);
//插件自定义配置实现逻辑
if (method_exists($addon, 'config')) {
$addon->config($name, $config);
} else {
//更新配置文件
set_addon_fullconfig($name, $config);
Service::refresh();
}
} catch (Exception $e) {
$this->error(__($e->getMessage()));
}
$this->success();
}
$this->error(__('Parameter %s can not be empty', ''));
}
$tips = [];
$groupList = [];
foreach ($config as $index => &$item) {
//如果有设置分组
if (isset($item['group']) && $item['group']) {
if (!in_array($item['group'], $groupList)) {
$groupList["custom" . (count($groupList) + 1)] = $item['group'];
}
}
if ($item['name'] == '__tips__') {
$tips = $item;
unset($config[$index]);
}
}
$groupList['other'] = '其它';
$this->view->assign("groupList", $groupList);
$this->view->assign("addon", ['info' => $info, 'config' => $config, 'tips' => $tips]);
$configFile = ADDON_PATH . $name . DS . 'config.html';
$viewFile = is_file($configFile) ? $configFile : '';
return $this->view->fetch($viewFile);
}
/**
* 安装
*/
public function install()
{
$name = $this->request->post("name");
$force = (int)$this->request->post("force");
if (!$name) {
$this->error(__('Parameter %s can not be empty', 'name'));
}
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
$this->error(__('Addon name incorrect'));
}
$info = [];
try {
$uid = $this->request->post("uid");
$token = $this->request->post("token");
$version = $this->request->post("version");
$faversion = $this->request->post("faversion");
$extend = [
'uid' => $uid,
'token' => $token,
'version' => $version,
'faversion' => $faversion
];
$info = Service::install($name, $force, $extend);
} catch (AddonException $e) {
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
} catch (Exception $e) {
$this->error(__($e->getMessage()), $e->getCode());
}
$this->success(__('Install successful'), '', ['addon' => $info]);
}
/**
* 卸载
*/
public function uninstall()
{
$name = $this->request->post("name");
$force = (int)$this->request->post("force");
$droptables = (int)$this->request->post("droptables");
if (!$name) {
$this->error(__('Parameter %s can not be empty', 'name'));
}
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
$this->error(__('Addon name incorrect'));
}
//只有开启调试且为超级管理员才允许删除相关数据库
$tables = [];
if ($droptables && Config::get("app_debug") && $this->auth->isSuperAdmin()) {
$tables = get_addon_tables($name);
}
try {
Service::uninstall($name, $force);
if ($tables) {
$prefix = Config::get('database.prefix');
//删除插件关联表
foreach ($tables as $index => $table) {
//忽略非插件标识的表名
if (!preg_match("/^{$prefix}{$name}/", $table)) {
continue;
}
Db::execute("DROP TABLE IF EXISTS `{$table}`");
}
}
} catch (AddonException $e) {
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
} catch (Exception $e) {
$this->error(__($e->getMessage()));
}
$this->success(__('Uninstall successful'));
}
/**
* 禁用启用
*/
public function state()
{
$name = $this->request->post("name");
$action = $this->request->post("action");
$force = (int)$this->request->post("force");
if (!$name) {
$this->error(__('Parameter %s can not be empty', 'name'));
}
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
$this->error(__('Addon name incorrect'));
}
try {
$action = $action == 'enable' ? $action : 'disable';
//调用启用、禁用的方法
Service::$action($name, $force);
Cache::rm('__menu__');
} catch (AddonException $e) {
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
} catch (Exception $e) {
$this->error(__($e->getMessage()));
}
$this->success(__('Operate successful'));
}
/**
* 本地上传
*/
public function local()
{
Config::set('default_return_type', 'json');
$info = [];
$file = $this->request->file('file');
try {
$uid = $this->request->post("uid");
$token = $this->request->post("token");
$faversion = $this->request->post("faversion");
if (!$uid || !$token) {
throw new Exception(__('Please login and try to install'));
}
$extend = [
'uid' => $uid,
'token' => $token,
'faversion' => $faversion
];
$info = Service::local($file, $extend);
} catch (AddonException $e) {
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
} catch (Exception $e) {
$this->error(__($e->getMessage()));
}
$this->success(__('Offline installed tips'), '', ['addon' => $info]);
}
/**
* 更新插件
*/
public function upgrade()
{
$name = $this->request->post("name");
$addonTmpDir = RUNTIME_PATH . 'addons' . DS;
if (!$name) {
$this->error(__('Parameter %s can not be empty', 'name'));
}
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
$this->error(__('Addon name incorrect'));
}
if (!is_dir($addonTmpDir)) {
@mkdir($addonTmpDir, 0755, true);
}
$info = [];
try {
$info = get_addon_info($name);
$uid = $this->request->post("uid");
$token = $this->request->post("token");
$version = $this->request->post("version");
$faversion = $this->request->post("faversion");
$extend = [
'uid' => $uid,
'token' => $token,
'version' => $version,
'oldversion' => $info['version'] ?? '',
'faversion' => $faversion
];
//调用更新的方法
$info = Service::upgrade($name, $extend);
Cache::rm('__menu__');
} catch (AddonException $e) {
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
} catch (Exception $e) {
$this->error(__($e->getMessage()));
}
$this->success(__('Operate successful'), '', ['addon' => $info]);
}
/**
* 测试数据
*/
public function testdata()
{
$name = $this->request->post("name");
if (!$name) {
$this->error(__('Parameter %s can not be empty', 'name'));
}
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
$this->error(__('Addon name incorrect'));
}
try {
Service::importsql($name, 'testdata.sql');
} catch (AddonException $e) {
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
} catch (Exception $e) {
$this->error(__($e->getMessage()), $e->getCode());
}
$this->success(__('Import successful'), '');
}
/**
* 已装插件
*/
public function downloaded()
{
$offset = (int)$this->request->get("offset");
$limit = (int)$this->request->get("limit");
$filter = $this->request->get("filter");
$search = $this->request->get("search");
$search = htmlspecialchars(strip_tags($search));
$onlineaddons = $this->getAddonList();
$filter = (array)json_decode($filter, true);
$addons = get_addon_list();
$list = [];
foreach ($addons as $k => $v) {
if ($search && stripos($v['name'], $search) === false && stripos($v['title'], $search) === false && stripos($v['intro'], $search) === false) {
continue;
}
if (isset($onlineaddons[$v['name']])) {
$v = array_merge($v, $onlineaddons[$v['name']]);
$v['price'] = '-';
} else {
$v['category_id'] = 0;
$v['flag'] = '';
$v['banner'] = '';
$v['image'] = '';
$v['demourl'] = '';
$v['price'] = __('None');
$v['screenshots'] = [];
$v['releaselist'] = [];
$v['url'] = addon_url($v['name']);
$v['url'] = str_replace($this->request->server('SCRIPT_NAME'), '', $v['url']);
}
$v['createtime'] = filemtime(ADDON_PATH . $v['name']);
if ($filter && isset($filter['category_id']) && is_numeric($filter['category_id']) && $filter['category_id'] != $v['category_id']) {
continue;
}
$list[] = $v;
}
$total = count($list);
if ($limit) {
$list = array_slice($list, $offset, $limit);
}
$result = array("total" => $total, "rows" => $list);
$callback = $this->request->get('callback') ? "jsonp" : "json";
return $callback($result);
}
/**
* 检测
*/
public function isbuy()
{
$name = $this->request->post("name");
$uid = $this->request->post("uid");
$token = $this->request->post("token");
$version = $this->request->post("version");
$faversion = $this->request->post("faversion");
$extend = [
'uid' => $uid,
'token' => $token,
'version' => $version,
'faversion' => $faversion
];
try {
$result = Service::isBuy($name, $extend);
} catch (Exception $e) {
$this->error(__($e->getMessage()));
}
return json($result);
}
/**
* 刷新授权
*/
public function authorization()
{
$params = [
'uid' => $this->request->post('uid'),
'token' => $this->request->post('token'),
'faversion' => $this->request->post('faversion'),
];
try {
Service::authorization($params);
} catch (Exception $e) {
$this->error(__($e->getMessage()));
}
$this->success(__('Operate successful'));
}
/**
* 获取插件相关表
*/
public function get_table_list()
{
$name = $this->request->post("name");
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
$this->error(__('Addon name incorrect'));
}
$tables = get_addon_tables($name);
$prefix = Config::get('database.prefix');
foreach ($tables as $index => $table) {
//忽略非插件标识的表名
if (!preg_match("/^{$prefix}{$name}/", $table)) {
unset($tables[$index]);
}
}
$tables = array_values($tables);
$this->success('', null, ['tables' => $tables]);
}
protected function getAddonList()
{
$onlineaddons = Cache::get("onlineaddons");
if (!is_array($onlineaddons) && config('fastadmin.api_url')) {
$onlineaddons = [];
$params = [
'uid' => $this->request->post('uid'),
'token' => $this->request->post('token'),
'version' => config('fastadmin.version'),
'faversion' => config('fastadmin.version'),
];
$json = [];
try {
$json = Service::addons($params);
} catch (\Exception $e) {
}
$rows = isset($json['rows']) ? $json['rows'] : [];
foreach ($rows as $index => $row) {
$onlineaddons[$row['name']] = $row;
}
Cache::set("onlineaddons", $onlineaddons, 600);
}
return $onlineaddons;
}
}

View File

@ -0,0 +1,313 @@
<?php
namespace app\admin\controller;
use app\common\controller\Backend;
use app\common\exception\UploadException;
use app\common\library\Upload;
use fast\Random;
use think\addons\Service;
use think\Cache;
use think\Config;
use think\Db;
use think\Lang;
use think\Response;
use think\Validate;
/**
* Ajax异步请求接口
* @internal
*/
class Ajax extends Backend
{
protected $noNeedLogin = ['lang','wipecache'];
protected $noNeedRight = ['*'];
protected $layout = '';
public function _initialize()
{
parent::_initialize();
//设置过滤方法
$this->request->filter(['trim', 'strip_tags', 'htmlspecialchars']);
}
/**
* 加载语言包
*/
public function lang()
{
$this->request->get(['callback' => 'define']);
$header = ['Content-Type' => 'application/javascript'];
if (!config('app_debug')) {
$offset = 30 * 60 * 60 * 24; // 缓存一个月
$header['Cache-Control'] = 'public';
$header['Pragma'] = 'cache';
$header['Expires'] = gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
}
$controllername = input("controllername");
//默认只加载了控制器对应的语言名,你还根据控制器名来加载额外的语言包
$this->loadlang($controllername);
return jsonp(Lang::get(), 200, $header, ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
}
/**
* 上传文件
*/
public function upload()
{
Config::set('default_return_type', 'json');
//必须设定cdnurl为空,否则cdnurl函数计算错误
Config::set('upload.cdnurl', '');
$chunkid = $this->request->post("chunkid");
if ($chunkid) {
if (!Config::get('upload.chunking')) {
$this->error(__('Chunk file disabled'));
}
$action = $this->request->post("action");
$chunkindex = $this->request->post("chunkindex/d");
$chunkcount = $this->request->post("chunkcount/d");
$filename = $this->request->post("filename");
$method = $this->request->method(true);
if ($action == 'merge') {
$attachment = null;
//合并分片文件
try {
$upload = new Upload();
$attachment = $upload->merge($chunkid, $chunkcount, $filename);
} catch (UploadException $e) {
$this->error($e->getMessage());
}
$this->success(__('Uploaded successful'), '', ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
} elseif ($method == 'clean') {
//删除冗余的分片文件
try {
$upload = new Upload();
$upload->clean($chunkid);
} catch (UploadException $e) {
$this->error($e->getMessage());
}
$this->success();
} else {
//上传分片文件
//默认普通上传文件
$file = $this->request->file('file');
try {
$upload = new Upload($file);
$upload->chunk($chunkid, $chunkindex, $chunkcount);
} catch (UploadException $e) {
$this->error($e->getMessage());
}
$this->success();
}
} else {
$attachment = null;
//默认普通上传文件
$file = $this->request->file('file');
try {
$upload = new Upload($file);
$attachment = $upload->upload();
} catch (UploadException $e) {
$this->error($e->getMessage());
}
$this->success(__('Uploaded successful'), '', ['url' => $attachment->url, 'fullurl' => $attachment->url]);
}
}
/**
* 通用排序
*/
public function weigh()
{
//排序的数组
$ids = $this->request->post("ids");
//拖动的记录ID
$changeid = $this->request->post("changeid");
//操作字段
$field = $this->request->post("field");
//操作的数据表
$table = $this->request->post("table");
if (!Validate::is($table, "alphaDash")) {
$this->error();
}
//主键
$pk = $this->request->post("pk");
//排序的方式
$orderway = strtolower($this->request->post("orderway", ""));
$orderway = $orderway == 'asc' ? 'ASC' : 'DESC';
$sour = $weighdata = [];
$ids = explode(',', $ids);
$prikey = $pk && preg_match("/^[a-z0-9\-_]+$/i", $pk) ? $pk : (Db::name($table)->getPk() ?: 'id');
$pid = $this->request->post("pid", "");
//限制更新的字段
$field = in_array($field, ['weigh']) ? $field : 'weigh';
// 如果设定了pid的值,此时只匹配满足条件的ID,其它忽略
if ($pid !== '') {
$hasids = [];
$list = Db::name($table)->where($prikey, 'in', $ids)->where('pid', 'in', $pid)->field("{$prikey},pid")->select();
foreach ($list as $k => $v) {
$hasids[] = $v[$prikey];
}
$ids = array_values(array_intersect($ids, $hasids));
}
$list = Db::name($table)->field("$prikey,$field")->where($prikey, 'in', $ids)->order($field, $orderway)->select();
foreach ($list as $k => $v) {
$sour[] = $v[$prikey];
$weighdata[$v[$prikey]] = $v[$field];
}
$position = array_search($changeid, $ids);
$desc_id = isset($sour[$position]) ? $sour[$position] : end($sour); //移动到目标的ID值,取出所处改变前位置的值
$sour_id = $changeid;
$weighids = array();
$temp = array_values(array_diff_assoc($ids, $sour));
foreach ($temp as $m => $n) {
if ($n == $sour_id) {
$offset = $desc_id;
} else {
if ($sour_id == $temp[0]) {
$offset = isset($temp[$m + 1]) ? $temp[$m + 1] : $sour_id;
} else {
$offset = isset($temp[$m - 1]) ? $temp[$m - 1] : $sour_id;
}
}
if (!isset($weighdata[$offset])) {
continue;
}
$weighids[$n] = $weighdata[$offset];
Db::name($table)->where($prikey, $n)->update([$field => $weighdata[$offset]]);
}
$this->success();
}
/**
* 清空系统缓存
*/
public function wipecache()
{
try {
$type = $this->request->request("type");
switch ($type) {
case 'all':
// no break
case 'content':
//内容缓存
rmdirs(CACHE_PATH, false);
Cache::clear();
if ($type == 'content') {
break;
}
case 'template':
// 模板缓存
rmdirs(TEMP_PATH, false);
if ($type == 'template') {
break;
}
case 'addons':
// 插件缓存
Service::refresh();
if ($type == 'addons') {
break;
}
case 'browser':
// 浏览器缓存
// 只有生产环境下才修改
if (!config('app_debug')) {
$version = config('site.version');
$newversion = preg_replace_callback("/(.*)\.([0-9]+)\$/", function ($match) {
return $match[1] . '.' . ($match[2] + 1);
}, $version);
if ($newversion && $newversion != $version) {
Db::startTrans();
try {
\app\common\model\Config::where('name', 'version')->update(['value' => $newversion]);
\app\common\model\Config::refreshFile();
Db::commit();
} catch (\Exception $e) {
Db::rollback();
exception($e->getMessage());
}
}
}
if ($type == 'browser') {
break;
}
}
} catch (\Exception $e) {
$this->error($e->getMessage());
}
\think\Hook::listen("wipecache_after");
$this->success();
}
/**
* 读取分类数据,联动列表
*/
public function category()
{
$type = $this->request->get('type', '');
$pid = $this->request->get('pid', '');
$where = ['status' => 'normal'];
$categorylist = null;
if ($pid || $pid === '0') {
$where['pid'] = $pid;
}
if ($type) {
$where['type'] = $type;
}
$categorylist = Db::name('category')->where($where)->field('id as value,name')->order('weigh desc,id desc')->select();
$this->success('', '', $categorylist);
}
/**
* 读取省市区数据,联动列表
*/
public function area()
{
$params = $this->request->get("row/a");
if (!empty($params)) {
$province = isset($params['province']) ? $params['province'] : null;
$city = isset($params['city']) ? $params['city'] : null;
} else {
$province = $this->request->get('province');
$city = $this->request->get('city');
}
$where = ['pid' => 0, 'level' => 1];
$provincelist = null;
if ($province !== null) {
$where['pid'] = $province;
$where['level'] = 2;
if ($city !== null) {
$where['pid'] = $city;
$where['level'] = 3;
}
}
$provincelist = Db::name('area')->where($where)->field('id as value,name')->select();
$this->success('', '', $provincelist);
}
/**
* 生成后缀图标
*/
public function icon()
{
$suffix = $this->request->request("suffix");
$suffix = $suffix ? $suffix : "FILE";
$data = build_suffix_image($suffix);
$header = ['Content-Type' => 'image/svg+xml'];
$offset = 30 * 60 * 60 * 24; // 缓存一个月
$header['Cache-Control'] = 'public';
$header['Pragma'] = 'cache';
$header['Expires'] = gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
$response = Response::create($data, '', 200, $header);
return $response;
}
}

View File

@ -0,0 +1,158 @@
<?php
namespace app\admin\controller;
use app\common\controller\Backend;
use app\common\model\Category as CategoryModel;
use fast\Tree;
/**
* 分类管理
*
* @icon fa fa-list
* @remark 用于管理网站的所有分类,分类可进行无限级分类,分类类型请在常规管理->系统配置->字典配置中添加
*/
class Category extends Backend
{
/**
* @var \app\common\model\Category
*/
protected $model = null;
protected $categorylist = [];
protected $noNeedRight = ['selectpage'];
public function _initialize()
{
parent::_initialize();
$this->model = model('app\common\model\Category');
$tree = Tree::instance();
$tree->init(collection($this->model->order('weigh desc,id desc')->select())->toArray(), 'pid');
$this->categorylist = $tree->getTreeList($tree->getTreeArray(0), 'name');
$categorydata = [0 => ['type' => 'all', 'name' => __('None')]];
foreach ($this->categorylist as $k => $v) {
$categorydata[$v['id']] = $v;
}
$typeList = CategoryModel::getTypeList();
$this->view->assign("flagList", $this->model->getFlagList());
$this->view->assign("typeList", $typeList);
$this->view->assign("parentList", $categorydata);
$this->assignconfig('typeList', $typeList);
}
/**
* 查看
*/
public function index()
{
//设置过滤方法
$this->request->filter(['strip_tags']);
if ($this->request->isAjax()) {
$search = $this->request->request("search");
$type = $this->request->request("type");
//构造父类select列表选项数据
$list = [];
foreach ($this->categorylist as $k => $v) {
if ($search) {
if ($v['type'] == $type && stripos($v['name'], $search) !== false || stripos($v['nickname'], $search) !== false) {
if ($type == "all" || $type == null) {
$list = $this->categorylist;
} else {
$list[] = $v;
}
}
} else {
if ($type == "all" || $type == null) {
$list = $this->categorylist;
} elseif ($v['type'] == $type) {
$list[] = $v;
}
}
}
$total = count($list);
$result = array("total" => $total, "rows" => $list);
return json($result);
}
return $this->view->fetch();
}
/**
* 添加
*/
public function add()
{
if ($this->request->isPost()) {
$this->token();
}
return parent::add();
}
/**
* 编辑
*/
public function edit($ids = null)
{
$row = $this->model->get($ids);
if (!$row) {
$this->error(__('No Results were found'));
}
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
if (!in_array($row[$this->dataLimitField], $adminIds)) {
$this->error(__('You have no permission'));
}
}
if ($this->request->isPost()) {
$this->token();
$params = $this->request->post("row/a");
if ($params) {
$params = $this->preExcludeFields($params);
if ($params['pid'] != $row['pid']) {
$childrenIds = Tree::instance()->init(collection(\app\common\model\Category::select())->toArray())->getChildrenIds($row['id'], true);
if (in_array($params['pid'], $childrenIds)) {
$this->error(__('Can not change the parent to child or itself'));
}
}
try {
//是否采用模型验证
if ($this->modelValidate) {
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
$row->validate($validate);
}
$result = $row->allowField(true)->save($params);
if ($result !== false) {
$this->success();
} else {
$this->error($row->getError());
}
} catch (\think\exception\PDOException $e) {
$this->error($e->getMessage());
} catch (\think\Exception $e) {
$this->error($e->getMessage());
}
}
$this->error(__('Parameter %s can not be empty', ''));
}
$this->view->assign("row", $row);
return $this->view->fetch();
}
/**
* Selectpage搜索
*
* @internal
*/
public function selectpage()
{
return parent::selectpage();
}
}

View File

@ -0,0 +1,248 @@
<?php
namespace app\admin\controller;
use app\common\controller\Backend;
use think\Config;
use think\console\Input;
use think\Db;
use think\Exception;
/**
* 在线命令管理
*
* @icon fa fa-circle-o
*/
class Command extends Backend
{
/**
* Command模型对象
*/
protected $model = null;
protected $noNeedRight = ['get_controller_list', 'get_field_list'];
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\Command;
$this->view->assign("statusList", $this->model->getStatusList());
}
/**
* 添加
*/
public function add()
{
$tableList = [];
$list = \think\Db::query("SHOW TABLES");
foreach ($list as $key => $row) {
$tableList[reset($row)] = reset($row);
}
$this->view->assign("tableList", $tableList);
return $this->view->fetch();
}
/**
* 获取字段列表
* @internal
*/
public function get_field_list()
{
$dbname = Config::get('database.database');
$prefix = Config::get('database.prefix');
$table = $this->request->request('table');
//从数据库中获取表字段信息
$sql = "SELECT * FROM `information_schema`.`columns` "
. "WHERE TABLE_SCHEMA = ? AND table_name = ? "
. "ORDER BY ORDINAL_POSITION";
//加载主表的列
$columnList = Db::query($sql, [$dbname, $table]);
$fieldlist = [];
foreach ($columnList as $index => $item) {
$fieldlist[] = $item['COLUMN_NAME'];
}
$this->success("", null, ['fieldlist' => $fieldlist]);
}
/**
* 获取控制器列表
* @internal
*/
public function get_controller_list()
{
//搜索关键词,客户端输入以空格分开,这里接收为数组
$word = (array)$this->request->request("q_word/a");
$word = implode('', $word);
$adminPath = dirname(__DIR__) . DS;
$controllerDir = $adminPath . 'controller' . DS;
$files = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($controllerDir), \RecursiveIteratorIterator::LEAVES_ONLY
);
$list = [];
foreach ($files as $name => $file) {
if (!$file->isDir()) {
$filePath = $file->getRealPath();
$name = str_replace($controllerDir, '', $filePath);
$name = str_replace(DS, "/", $name);
if (!preg_match("/(.*)\.php\$/", $name)) {
continue;
}
if (!$word || stripos($name, $word) !== false) {
$list[] = ['id' => $name, 'name' => $name];
}
}
}
$pageNumber = $this->request->request("pageNumber");
$pageSize = $this->request->request("pageSize");
return json(['list' => array_slice($list, ($pageNumber - 1) * $pageSize, $pageSize), 'total' => count($list)]);
}
/**
* 详情
*/
public function detail($ids)
{
$row = $this->model->get($ids);
if (!$row) {
$this->error(__('No Results were found'));
}
$this->view->assign("row", $row);
return $this->view->fetch();
}
/**
* 执行
*/
public function execute($ids)
{
$row = $this->model->get($ids);
if (!$row) {
$this->error(__('No Results were found'));
}
$result = $this->doexecute($row['type'], json_decode($row['params'], true));
$this->success("", null, ['result' => $result]);
}
/**
* 生成命令
*/
public function command($action = '')
{
$commandtype = $this->request->request("commandtype");
$params = $this->request->request();
$allowfields = [
'crud' => 'table,controller,model,fields,force,local,delete,menu',
'menu' => 'controller,delete',
'min' => 'module,resource,optimize',
'api' => 'url,module,output,template,force,title,author,class,language,addon',
];
$argv = [];
$allowfields = isset($allowfields[$commandtype]) ? explode(',', $allowfields[$commandtype]) : [];
$allowfields = array_filter(array_intersect_key($params, array_flip($allowfields)));
if (isset($params['local']) && !$params['local']) {
$allowfields['local'] = $params['local'];
} else {
unset($allowfields['local']);
}
foreach ($allowfields as $key => $param) {
$argv[] = "--{$key}=" . (is_array($param) ? implode(',', $param) : $param);
}
if ($commandtype == 'crud') {
$extend = 'setcheckboxsuffix,enumradiosuffix,imagefield,filefield,intdatesuffix,switchsuffix,citysuffix,selectpagesuffix,selectpagessuffix,ignorefields,sortfield,editorsuffix,headingfilterfield,tagsuffix,jsonsuffix,fixedcolumns';
$extendArr = explode(',', $extend);
foreach ($params as $index => $item) {
if (in_array($index, $extendArr)) {
foreach (explode(',', $item) as $key => $value) {
if ($value) {
$argv[] = "--{$index}={$value}";
}
}
}
}
$isrelation = (int)$this->request->request('isrelation');
if ($isrelation && isset($params['relation'])) {
foreach ($params['relation'] as $index => $relation) {
foreach ($relation as $key => $value) {
$argv[] = "--{$key}=" . (is_array($value) ? implode(',', $value) : $value);
}
}
}
} else {
if ($commandtype == 'menu') {
if (isset($params['allcontroller']) && $params['allcontroller']) {
$argv[] = "--controller=all-controller";
} else {
foreach (explode(',', $params['controllerfile']) as $index => $param) {
if ($param) {
$argv[] = "--controller=" . substr($param, 0, -4);
}
}
}
} else {
if ($commandtype == 'min') {
} else {
if ($commandtype == 'api') {
} else {
}
}
}
}
if ($action == 'execute') {
if (stripos(implode(' ', $argv), '--controller=all-controller') !== false) {
$this->error("只允许在命令行执行该命令,执行前请做好菜单规则备份!!!");
}
if (config('app_debug')) {
$result = $this->doexecute($commandtype, $argv);
$this->success("", null, ['result' => $result]);
} else {
$this->error("只允许在开发环境下执行命令");
}
} else {
$this->success("", null, ['command' => "php think {$commandtype} " . implode(' ', $argv)]);
}
return;
}
protected function doexecute($commandtype, $argv)
{
if (!config('app_debug')) {
$this->error("只允许在开发环境下执行命令");
}
if (preg_match("/([;\|&]+)/", implode(' ', $argv))) {
$this->error("不支持的命令参数");
}
$commandName = "\\app\\admin\\command\\" . ucfirst($commandtype);
$input = new Input($argv);
$output = new \addons\command\library\Output();
$command = new $commandName($commandtype);
$data = [
'type' => $commandtype,
'params' => json_encode($argv),
'command' => "php think {$commandtype} " . implode(' ', $argv),
'executetime' => time(),
];
$this->model->save($data);
try {
$command->run($input, $output);
$result = implode("\n", $output->getMessage());
$this->model->status = 'successed';
} catch (Exception $e) {
$result = implode("\n", $output->getMessage()) . "\n";
$result .= $e->getMessage();
$this->model->status = 'failured';
}
$result = trim($result);
$this->model->content = $result;
$this->model->save();
return $result;
}
}

View File

@ -0,0 +1,329 @@
<?php
/**
* @Created by PhpStorm.
* @Author:Soar
* @Time:2023/7/19 14:44
*/
namespace app\admin\controller;
use addons\cms\model\Player;
use app\admin\model\cms\Archives;
use app\admin\model\MatchContestant;
use app\admin\model\MessageLog;
use app\admin\model\Players;
use app\common\controller\Backend;
use think\Db;
use app\admin\model\Club;
use app\common\model\User;
use app\admin\model\shopro\ClubThirdOauth;
use app\index\controller\Wxmb;
class Contestants extends Backend
{
/**
* @var \app\admin\model\cms\Archives
*/
protected $model = null;
public function _initialize()
{
parent::_initialize();
$this->model = new MatchContestant();
}
public function check_leagueuser()
{
$Club = new Club();
$User = new User();
$Wxmb = new Wxmb();
$archives = new Archives();
$ClubThirdOauth = new ClubThirdOauth();
$type = $this->request->param('type');
$id = $this->request->param('ids');
$mark = $this->request->param('mark');
$apply_res = $this->model->field('match_id,club_id')->where('id', 'eq', $id)->find();
$club_info = $Club->where("id", $apply_res['club_id'])->find();
$user_info = $User->where('id',$club_info['user_id'])->find();
// $matchId = $apply_res['match_id'];
// var_dump($matchId['match_id']);exit;
// $apply_allplayer = $this->model->where(['club_id'=>$apply_res['club_id'],'match_id'=>$apply_res['match_id'],'club_status'=>1])->find();
$apply_allplayer = $this->model->where(['club_id'=>$apply_res['club_id'],'match_id'=>$apply_res['match_id']])->select();
$info = $this->model->find($id);
if (empty($apply_res)){
$this->error(__("信息出错,请刷新后重试!"));
}
if ($type == "pass"){
// 启动事务
Db::startTrans();
try{
// var_dump($apply_allplayer);exit;
foreach ($apply_allplayer as $value){
$data = array('status'=>2,'updated_at' => date("Y-m-d H:i:s", time()));
$this->model->where('id', $value['id'])->data($data,true)->update();
}
// 提交事务
Db::commit();
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
$this->error(__("操作失败!"));
}
$oauth_res = $ClubThirdOauth->where('user_id',$club_info['user_id'])->find();
if(!empty($oauth_res)){
$oauth_res = $oauth_res->toArray();
$push_arr = array('title'=>'赛事报名审核通过','username'=> $club_info['name_short'],'type'=>'系统通知');
$Wxmb->leaguepush($push_arr,$oauth_res['openid']);
}
#发短信
if (!empty($user_info->mobile)) {
// $user_info->mobile = '13626832346';
$match_info = $archives->find($info->match_id);
$alisms = new \addons\alisms\library\Alisms();
$config = get_addon_config('alisms');
$template = "SMS_466345112";
// $sign = $config['sign'];
$sign = '中国无人机竞速联赛';
$param = [
'name' => $club_info->name_short,
'content' => "" . $match_info->title . ""
];
$res = $alisms->mobile($user_info->mobile)
->template($template)
->sign($sign)
->param($param)
->send();
}
$this->success(__("审核成功!"));
}
if ($type == "refuse"){
//获取飞手信息
if (!empty($user_info->mobile)) {
// $user_info->mobile = '13626832346';
// var_dump($user_info->mobile);exit;
//获取赛事信息
$match_info = $archives->find($info->match_id);
$alisms = new \addons\alisms\library\Alisms();
$config = get_addon_config('alisms');
$template = "SMS_466440085";
$sign = '中国无人机竞速联赛';
$param = [
'name' => $club_info->name_short,
'content' => "" . $match_info->title . ""
];
// var_dump($club_info->name_short);exit;
$res = $alisms->mobile($user_info->mobile)
->template($template)
->sign($sign)
->param($param)
->send();
// var_dump($res);exit;
Db::startTrans();
try{
// var_dump($apply_allplayer);exit;
foreach ($apply_allplayer as $value){
$data = array('status'=> -1,'updated_at' => date("Y-m-d H:i:s", time()));
$this->model->where('id', $value['id'])->data($data,true)->update();
}
// exit;
// 提交事务
Db::commit();
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
$this->error(__("操作失败2"));
}
$this->success(__("驳回成功!"));
$messageLogModel = new MessageLog();
$message_log_id = $messageLogModel->insertGetId(
[
'phone' => $user_info->mobile,
'code' => $param['content'],
'code2' => $mark,
'type' => 4,
'used' => 0,
'template_id' => $template,
'created_at' => date("Y-m-d H:i:s", time())
]
);
}
$info->save(['message_logs_id' => $message_log_id]);
if ($info->save(['status' => -1, 'updated_at' => date("Y-m-d H:i:s", time()), 'mark' => $mark])){
$this->success(__("审核成功!"));
}
$this->error(__("审核失败!"));
}
}
public function check_user()
{
$type = $this->request->param('type');
$id = $this->request->param('ids');
$mark = $this->request->param('mark');
$info = $this->model->find($id);
if (empty($info)){
$this->error(__("信息出错,请刷新后重试!"));
}
if ($type == "pass"){
if ($info->save(['status' => 2, 'updated_at' => date("Y-m-d H:i:s", time())])){
$this->success(__("审核成功!"));
}
$this->error(__("审核失败!"));
}
if ($type == "refuse"){
//获取飞手信息
$playerModel = new Players();
$player_info = $playerModel->with('member')->find($info->player_id);
if (!empty($player_info->phone)) {
//获取赛事信息
$archives = new Archives();
$match_info = $archives->find($info->match_id);
$alisms = new \addons\alisms\library\Alisms();
$config = get_addon_config('alisms');
$template = "SMS_463726010";
$sign = $config['sign'];
$param = [
'name' => $player_info->real_name,
'content' => "" . $match_info->title . ""
];
$alisms->mobile($player_info->phone)
->template($template)
->sign($sign)
->param($param)
->send();
$messageLogModel = new MessageLog();
$message_log_id = $messageLogModel->insertGetId(
[
'phone' => $player_info->phone,
'code' => $param['content'],
'code2' => $mark,
'type' => 4,
'used' => 0,
'template_id' => $template,
'created_at' => date("Y-m-d H:i:s", time())
]
);
}
$info->save(['message_logs_id' => $message_log_id]);
if ($info->save(['status' => -1, 'updated_at' => date("Y-m-d H:i:s", time()), 'mark' => $mark])){
$this->success(__("审核成功!"));
}
$this->error(__("审核失败!"));
}
}
public function sendSMS()
{
$id = $this->request->param('ids');
//获取飞手信息
$match_contestants_info = $this->model->find($id);
if (empty($match_contestants_info)){
$this->error(__("信息出错,请刷新后重试!"));
}
if ($match_contestants_info->status != 2){
$this->error(__("无法给审核未通过的选手发送短信!"));
}
//获取飞手信息
$playerModel = new Players();
$player_info = $playerModel->with('member')->find($match_contestants_info->player_id);
$archives = new Archives();
$match_info = $archives->find($match_contestants_info->match_id);
if (empty($player_info) || empty($player_info->member)){
$this->error(__("获取用户信息出错!"));
}
$mobile = $player_info->phone ? $player_info->phone : $player_info->member->mobile;
if (empty($mobile) || !isset($mobile)){
$this->error(__("获取用户手机号出错!"));
}
$alisms = new \addons\alisms\library\Alisms();
$config = get_addon_config('alisms');
$template = $config['template']['notice'];
$sign = $config['sign'];
$param = [
'name' => $player_info->real_name,
'matchTitle' => "" . $match_info->title . ""
];
$ret = $alisms->mobile($mobile)
->template($template)
->sign($sign)
->param($param)
->send();
$messageLogModel = new MessageLog();
$message_log_id = $messageLogModel->insertGetId(
[
'phone' => $mobile,
'type' => 4,
'used' => 0,
'template_id' => $template,
'created_at' => date("Y-m-d H:i:s", time())
]
);
if ($ret && $message_log_id && $match_contestants_info->save(['message_logs_id' => $message_log_id])){
$this->success(__("发送成功!"));
}
}
/**
* 删除
* @param mixed $ids
*/
public function del($ids = "")
{
$res = $this->model->where('id',intval($ids))->find();
// var_dump($res);exit;
if($res['club_id']){
$contes_res = $this->model->where('club_id',$res['club_id'])->where('match_id',$res['match_id'])->select();
$str = '';
foreach ($contes_res as $val){
$str = $str.','.$val['id'];
}
parent::del($str);
}else{
parent::del($ids);
}
}
}

View File

@ -0,0 +1,75 @@
<?php
namespace app\admin\controller;
use app\common\controller\Backend;
use think\Db;
/**
*
*
* @icon fa fa-circle-o
*/
class Countryflag extends Backend
{
/**
* Countryflag模型对象
* @var \app\admin\model\Countryflag
*/
protected $model = null;
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\Countryflag;
}
public function add()
{
if (false === $this->request->isPost()) {
return $this->view->fetch();
}
$params = $this->request->post('row/a');
if (empty($params)) {
$this->error(__('Parameter %s can not be empty', ''));
}
// var_dump($params);exit;
$params = $this->preExcludeFields($params);
// var_dump($params);exit;
if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
$params[$this->dataLimitField] = $this->auth->id;
}
$country_res = $this->model->where('country',$params['country'])->find();
if($country_res){
$this->error('国籍已存在');
}
$result = false;
Db::startTrans();
try {
//是否采用模型验证
if ($this->modelValidate) {
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
$this->model->validateFailException()->validate($validate);
}
$result = $this->model->allowField(true)->save($params);
Db::commit();
} catch (ValidateException|PDOException|Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result === false) {
$this->error(__('No rows were inserted'));
}
$this->success();
}
/**
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
*/
}

View File

@ -0,0 +1,84 @@
<?php
namespace app\admin\controller;
use app\admin\model\Admin;
use app\admin\model\User;
use app\common\controller\Backend;
use app\common\model\Attachment;
use fast\Date;
use think\Db;
/**
* 控制台
*
* @icon fa fa-dashboard
* @remark 用于展示当前系统中的统计数据、统计报表及重要实时数据
*/
class Dashboard extends Backend
{
/**
* 查看
*/
public function index()
{
try {
\think\Db::execute("SET @@sql_mode='';");
} catch (\Exception $e) {
}
$column = [];
$starttime = Date::unixtime('day', -6);
$endtime = Date::unixtime('day', 0, 'end');
$joinlist = Db("user")->where('jointime', 'between time', [$starttime, $endtime])
->field('jointime, status, COUNT(*) AS nums, DATE_FORMAT(FROM_UNIXTIME(jointime), "%Y-%m-%d") AS join_date')
->group('join_date')
->select();
for ($time = $starttime; $time <= $endtime;) {
$column[] = date("Y-m-d", $time);
$time += 86400;
}
$userlist = array_fill_keys($column, 0);
foreach ($joinlist as $k => $v) {
$userlist[$v['join_date']] = $v['nums'];
}
$dbTableList = Db::query("SHOW TABLE STATUS");
$addonList = get_addon_list();
$totalworkingaddon = 0;
$totaladdon = count($addonList);
foreach ($addonList as $index => $item) {
if ($item['state']) {
$totalworkingaddon += 1;
}
}
$this->view->assign([
'totaluser' => User::count(),
'totaladdon' => $totaladdon,
'totaladmin' => Admin::count(),
'totalcategory' => \app\common\model\Category::count(),
'todayusersignup' => User::whereTime('jointime', 'today')->count(),
'todayuserlogin' => User::whereTime('logintime', 'today')->count(),
'sevendau' => User::whereTime('jointime|logintime|prevtime', '-7 days')->count(),
'thirtydau' => User::whereTime('jointime|logintime|prevtime', '-30 days')->count(),
'threednu' => User::whereTime('jointime', '-3 days')->count(),
'sevendnu' => User::whereTime('jointime', '-7 days')->count(),
'dbtablenums' => count($dbTableList),
'dbsize' => array_sum(array_map(function ($item) {
return $item['Data_length'] + $item['Index_length'];
}, $dbTableList)),
'totalworkingaddon' => $totalworkingaddon,
'attachmentnums' => Attachment::count(),
'attachmentsize' => Attachment::sum('filesize'),
'picturenums' => Attachment::where('mimetype', 'like', 'image/%')->count(),
'picturesize' => Attachment::where('mimetype', 'like', 'image/%')->sum('filesize'),
]);
$this->assignconfig('column', array_keys($userlist));
$this->assignconfig('userdata', array_values($userlist));
return $this->view->fetch();
}
}

View File

@ -0,0 +1,432 @@
<?php
namespace app\admin\controller;
use addons\docs\library\Service;
use app\common\controller\Backend;
use fast\Http;
use fast\Tree;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use think\Exception;
use think\Validate;
use ZipArchive;
/**
*
* 文档管理
* @icon fa fa-circle-o
*/
class Docs extends Backend
{
protected $docs = [];
protected $docsdata = [];
protected $typeList = [];
protected $typeColor = [];
protected $noNeedRight = ["selectpage_type", "get_parent_options"];
public function _initialize()
{
parent::_initialize();
$this->docsdata = Service::getDocsData(false);
$config = get_addon_config('docs');
$this->typeList = $this->typeColor = [];
$langs = $config['lang'];
$colors = ["primary", "success", "danger", "warning", "info"];
foreach ($this->docsdata as $type => $pages) {
$this->typeList[$type] = $langs[$type] ?? $type;
$this->typeColor[$type] = array_pop($colors);
}
$this->view->assign('typeList', $this->typeList);
$this->assignconfig('typeList', $this->typeList);
$this->view->assign('typeColor', $this->typeColor);
$this->assignconfig('typeColor', $this->typeColor);
$this->assignconfig('htmlDetect', (bool)($config['htmldetect'] ?? false));
}
/**
* 查看
*/
public function index()
{
//设置过滤方法
$this->request->filter(['strip_tags']);
if ($this->request->isAjax()) {
$filter = $this->request->request('filter', '');
$filter = (array)json_decode($filter, true);
$filter['type'] = isset($filter['type']) && $filter['type'] ? $filter['type'] : '';
$search = $this->request->request("search");
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$list = [];
$docsdata = $this->docsdata;
if ($filter['type']) {
$docsdata = isset($docsdata[$filter['type']]) ? [$filter['type'] => $docsdata[$filter['type']]] : [];
}
foreach ($docsdata as $index => $docsdatum) {
$tree = Tree::instance();
$data = $tree->init($docsdatum, 'parent')->getTreeArray('');
$list = array_merge($list, $tree->getTreeList($data, 'title'));
}
$ids = [];
foreach ($list as $index => $item) {
$ids[] = $item['id'];
}
foreach ($docsdata as $index => $docsdatum) {
foreach ($docsdatum as $key => $item) {
if (!in_array($item['id'], $ids)) {
$list[] = $item;
}
}
}
//foreach ($this->docsdata as $type => $pages) {
// if ($filter['type'] && $type != $filter['type']) {
// continue;
// }
// foreach ($pages as $index => $page) {
// if (!$search || stripos($page['relative'], $search) !== false || stripos($page['title'], $search) !== false) {
// $list[] = $page;
// }
// }
//}
$total = count($list);
$result = array("total" => $total, "rows" => array_slice($list, $offset, $limit));
return json($result);
}
return $this->view->fetch();
}
/**
* 添加
*/
public function add()
{
if ($this->request->isPost()) {
$params = $this->request->post("row/a");
if ($params) {
try {
if (!$params['md']) {
throw new Exception("MD文件不能为空");
}
$config = get_addon_config('docs');
$params['md'] = trim($params['md']);
//未设置后缀
if (stripos($params['md'], ".{$config['suffix']}") === false) {
$params['md'] .= ".{$config['suffix']}";
}
if (mb_substr_count($params['md'], "/") > 1) {
throw new Exception("MD文件中只能包含一个/字符");
}
if (mb_substr_count($params['md'], ".") > 1) {
throw new Exception("MD文件中只能包含一个.字符");
}
if (!Validate::is($params['md'], "/^[A-Za-z0-9\-\_\.\/]+$/")) {
throw new Exception("MD文件只能是字母数字下划线");
}
$exist = Service::getMarkdownData($params['md']);
if ($exist) {
throw new Exception("对应的MD文件已经存在");
}
$parent = $params['parent'] ?? '';
$type = $params['type'] ?? '';
if ($parent) {
if ($parent == str_replace(".md", "", $params['md'])) {
$this->error("父级不能为当前文件");
}
if (!isset($this->docsdata[$type])) {
$this->error("未找到指定分类");
}
$nameArr = [];
foreach ($this->docsdata[$type] as $index => $docsdatum) {
$nameArr[] = $docsdatum['name'];
}
if (!in_array($parent, $nameArr)) {
$this->error("未找到指定父级数据");
}
}
Service::setMarkdownData($params['md'], $params);
} catch (Exception $e) {
$this->error($e->getMessage());
}
$this->success();
}
$this->error(__('Parameter %s can not be empty', ''));
}
return $this->view->fetch();
}
/**
* 编辑
*/
public function edit($ids = null)
{
$ids = $ids ? $ids : $this->request->request('ids');
$row = Service::getMarkdownData($ids, true, false);
if (!$row) {
$this->error(__('No Results were found'));
}
if ($this->request->isPost()) {
$params = $this->request->post("row/a");
if ($params) {
$config = get_addon_config('docs');
$params['md'] = trim(isset($params['md']) && $params['md'] ? $params['md'] : $row['relative']);
$md = $params['md'];
$parent = $params['parent'] ?? '';
$type = $params['type'] ?? '';
if ($parent) {
if ($parent == str_replace(".md", "", $ids)) {
$this->error("父级不能为当前文件");
}
if (!isset($this->docsdata[$type])) {
$this->error("未找到指定分类");
}
$nameArr = [];
foreach ($this->docsdata[$type] as $index => $docsdatum) {
$nameArr[] = $docsdatum['name'];
}
if (!in_array($parent, $nameArr)) {
$this->error("未找到指定父级数据");
}
}
//如果文件名有变更,删除原文件
if ($md != $row['relative']) {
//未设置后缀
if (stripos($params['md'], ".{$config['suffix']}") === false) {
$params['md'] .= ".{$config['suffix']}";
}
if (mb_substr_count($params['md'], "/") > 1) {
throw new Exception("MD文件中只能包含一个/字符");
}
if (mb_substr_count($params['md'], ".") > 1) {
throw new Exception("MD文件中只能包含一个.字符");
}
if (!Validate::is($params['md'], "/^[A-Za-z0-9\-\_\.\/]+$/")) {
throw new Exception("MD文件只能是字母数字下划线");
}
$exist = Service::getMarkdownData($params['md']);
if ($exist) {
throw new Exception("对应的MD文件已经存在");
}
}
try {
//如果变更了分类,则所有子文档分类都需要变更
if ($type != $row['type']) {
$docs = $this->docsdata[$row['type']] ?? [];
$childrenList = Tree::instance()->init($docs, 'parent')->getChildren($row['id']);
foreach ($childrenList as $index => $item) {
$data = Service::getMarkdownData($item['relative'], true);
$data['type'] = $type;
Service::setMarkdownData($item['relative'], $data);
}
}
Service::setMarkdownData($md, $params);
//如果文件名有变更,删除原文件
if ($md != $row['relative']) {
unlink(Service::getDocsSourceDir() . $row['relative']);
}
} catch (Exception $e) {
$this->error($e->getMessage());
}
$this->success();
}
$this->error(__('Parameter %s can not be empty', ''));
}
$allowEditName = true;
$parentList = isset($this->docsdata[$row['type']]) ? $this->docsdata[$row['type']] : [];
foreach ($parentList as $index => $item) {
if ($item['parent'] == $row['name']) {
$allowEditName = false;
break;
}
}
$parentOptions = $this->getParentList($row['type'], $row['id'], $row['parent']);
$this->view->assign("parentOptions", $parentOptions);
$this->view->assign("allowEditName", $allowEditName);
$this->view->assign("row", $row);
return $this->view->fetch();
}
/**
* 删除
*/
public function del($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
if ($ids) {
if (stripos($ids, ',') !== false) {
$this->error("文档不支持批量删除");
}
$row = Service::getMarkdownData($ids, false, false);
if (!$row) {
$this->error(__('No Results were found'));
}
try {
unlink(Service::getDocsSourceDir() . $row['relative']);
Service::refreshDocsData();
} catch (Exception $e) {
$this->error($e->getMessage());
}
$this->success();
}
$this->error(__('Parameter %s can not be empty', 'ids'));
}
/**
* 刷新
*/
public function refresh()
{
Service::refreshDocsData();
$this->success();
}
/**
* 导出
*/
public function export()
{
try {
//重新生成一次文档
Service::build();
} catch (\Exception $e) {
$this->error($e->getMessage());
}
$distDir = Service::getDocsDistDir();
$zipFile = RUNTIME_PATH . 'addons' . DS . 'export-docs-' . date('YmdHis') . '.zip';
$rootPath = realpath($distDir);
$zip = new ZipArchive();
$zip->open($zipFile, ZipArchive::CREATE | ZipArchive::OVERWRITE);
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($rootPath),
RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $name => $file) {
if (!$file->isDir()) {
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen($rootPath) + 1);
$relativePath = str_replace('\\', '/', $relativePath);
$zip->addFile($filePath, $relativePath);
}
}
$zip->close();
Http::sendToBrowser($zipFile);
}
/**
* 批量更新
* @internal
*/
public function status($ids = "")
{
$ids = $ids ? $ids : $this->request->param("ids");
if ($ids) {
if ($this->request->has('params')) {
parse_str($this->request->post("params"), $values);
if ($values && isset($values['isnew'])) {
$row = Service::getMarkdownData($ids, true, false);
$row = array_merge($row, $values);
try {
Service::setMarkdownData($ids, $row);
} catch (Exception $e) {
$this->error($e->getMessage());
}
$this->success();
} else {
$this->error(__('You have no permission'));
}
}
}
$this->error(__('Parameter %s can not be empty', 'ids'));
}
/**
* 批量更新
* @internal
*/
public function multi($ids = "")
{
return;
}
/**
* 动态下拉选择类型
* @internal
*/
public function selectpage_type()
{
$list = [];
$word = (array)$this->request->request("q_word/a");
$field = $this->request->request('showField');
$keyValue = $this->request->request('keyValue');
$config = get_addon_config('docs');
$typeList = [];
$langs = $config['lang'];
foreach ($this->docsdata as $type => $pages) {
$typeList[$type] = isset($langs[$type]) ? $langs[$type] : $type;
}
$typeArr = $typeList;
if (!$keyValue) {
if (array_filter($word)) {
foreach ($word as $k => $v) {
$list[] = ['id' => $v, $field => $v];
}
}
foreach ($typeArr as $index => $item) {
$list[] = ['id' => $index, $field => $item];
}
} else {
$list[] = ['id' => $keyValue, $field => $typeArr[$keyValue] ?? $keyValue];
}
return json(['total' => count($list), 'list' => $list]);
}
/**
* 获取父级options
* @internal
*/
public function get_parent_options()
{
$type = $this->request->request('type');
$origintype = $this->request->request('origintype');
$id = $parent = null;
if ($type == $origintype) {
$id = $this->request->request('id');
$parent = $this->request->request('parent');
}
$parentOptions = '<option value="">无</option>';
if ($type) {
$parentOptions .= $this->getParentList($type, $id, $parent);
}
$this->success("", '', ['options' => $parentOptions]);
}
protected function getParentList($type, $id = null, $parent = null)
{
$parentList = [];
$parentOptions = '';
if (!isset($this->docsdata[$type])) {
return $parentOptions;
}
foreach ($this->docsdata[$type] as $index => $item) {
$parentList[] = ['id' => $item['id'], 'pid' => $item['parent'], 'name' => $item['title']];
}
if ($parentList) {
$tree = Tree::instance()->init($parentList);
$disableIds = $id ? $tree->getChildrenIds($id, true) : [];
$selectIds = $parent ? [$parent] : [];
$parentOptions = $tree->getTree('', '<option value=@id @selected @disabled>@spacer@name</option>', $selectIds, $disableIds);
}
return $parentOptions;
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace app\admin\controller;
use app\common\controller\Backend;
use think\Config;
class Epay extends Backend
{
protected $noNeedRight = ['upload'];
/**
* 上传本地证书
* @return void
*/
public function upload()
{
Config::set('default_return_type', 'json');
$certname = $this->request->post('certname', '');
$certPathArr = [
'cert_client' => '/addons/epay/certs/apiclient_cert.pem', //微信支付api
'cert_key' => '/addons/epay/certs/apiclient_key.pem', //微信支付api
'app_cert_public_key' => '/addons/epay/certs/appCertPublicKey.crt',//应用公钥证书路径
'alipay_root_cert' => '/addons/epay/certs/alipayRootCert.crt', //支付宝根证书路径
'ali_public_key' => '/addons/epay/certs/alipayCertPublicKey.crt', //支付宝公钥证书路径
];
if (!isset($certPathArr[$certname])) {
$this->error("证书错误");
}
$url = $certPathArr[$certname];
$file = $this->request->file('file');
if (!$file) {
$this->error("未上传文件");
}
$file->move(dirname(ROOT_PATH . $url), basename(ROOT_PATH . $url), true);
$this->success(__('上传成功'), '', ['url' => $url]);
}
}

View File

@ -0,0 +1,138 @@
<?php
namespace app\admin\controller;
use app\admin\model\AdminLog;
use app\common\controller\Backend;
use think\Config;
use think\Hook;
use think\Session;
use think\Validate;
/**
* 后台首页
* @internal
*/
class Index extends Backend
{
protected $noNeedLogin = ['login'];
protected $noNeedRight = ['index', 'logout'];
protected $layout = '';
public function _initialize()
{
parent::_initialize();
//移除HTML标签
$this->request->filter('trim,strip_tags,htmlspecialchars');
}
/**
* 后台首页
*/
public function index()
{
$cookieArr = ['adminskin' => "/^skin\-([a-z\-]+)\$/i", 'multiplenav' => "/^(0|1)\$/", 'multipletab' => "/^(0|1)\$/", 'show_submenu' => "/^(0|1)\$/"];
foreach ($cookieArr as $key => $regex) {
$cookieValue = $this->request->cookie($key);
if (!is_null($cookieValue) && preg_match($regex, $cookieValue)) {
config('fastadmin.' . $key, $cookieValue);
}
}
//左侧菜单
list($menulist, $navlist, $fixedmenu, $referermenu) = $this->auth->getSidebar([
'dashboard' => 'hot',
'addon' => ['new', 'red', 'badge'],
'auth/rule' => __('Menu'),
'general' => ['new', 'purple'],
], $this->view->site['fixedpage']);
$action = $this->request->request('action');
if ($this->request->isPost()) {
if ($action == 'refreshmenu') {
$this->success('', null, ['menulist' => $menulist, 'navlist' => $navlist]);
}
}
$this->assignconfig('cookie', ['prefix' => config('cookie.prefix')]);
$this->view->assign('menulist', $menulist);
$this->view->assign('navlist', $navlist);
$this->view->assign('fixedmenu', $fixedmenu);
$this->view->assign('referermenu', $referermenu);
$this->view->assign('title', __('Home'));
return $this->view->fetch();
}
/**
* 管理员登录
*/
public function login()
{
$url = $this->request->get('url', 'index/index');
if ($this->auth->isLogin()) {
$this->success(__("You've logged in, do not login again"), $url);
}
if ($this->request->isPost()) {
$username = $this->request->post('username');
$password = $this->request->post('password');
$keeplogin = $this->request->post('keeplogin');
$token = $this->request->post('__token__');
$rule = [
'username' => 'require|length:3,30',
'password' => 'require|length:3,30',
'__token__' => 'require|token',
];
$data = [
'username' => $username,
'password' => $password,
'__token__' => $token,
];
if (Config::get('fastadmin.login_captcha')) {
$rule['captcha'] = 'require|captcha';
$data['captcha'] = $this->request->post('captcha');
}
$validate = new Validate($rule, [], ['username' => __('Username'), 'password' => __('Password'), 'captcha' => __('Captcha')]);
$result = $validate->check($data);
if (!$result) {
$this->error($validate->getError(), $url, ['token' => $this->request->token()]);
}
AdminLog::setTitle(__('Login'));
$result = $this->auth->login($username, $password, $keeplogin ? 86400 : 0);
if ($result === true) {
Hook::listen("admin_login_after", $this->request);
$this->success(__('Login successful'), $url, ['url' => $url, 'id' => $this->auth->id, 'username' => $username, 'avatar' => $this->auth->avatar]);
} else {
$msg = $this->auth->getError();
$msg = $msg ? $msg : __('Username or password is incorrect');
$this->error($msg, $url, ['token' => $this->request->token()]);
}
}
// 根据客户端的cookie,判断是否可以自动登录
if ($this->auth->autologin()) {
Session::delete("referer");
$this->redirect($url);
}
$background = Config::get('fastadmin.login_background');
$background = $background ? (stripos($background, 'http') === 0 ? $background : config('site.cdnurl') . $background) : '';
$this->view->assign('background', $background);
$this->view->assign('title', __('Login'));
Hook::listen("admin_login_init", $this->request);
return $this->view->fetch();
}
/**
* 退出登录
*/
public function logout()
{
if ($this->request->isPost()) {
$this->auth->logout();
Hook::listen("admin_logout_after", $this->request);
$this->success(__('Logout successful'), 'index/login');
}
$html = "<form id='logout_submit' name='logout_submit' action='' method='post'>" . token() . "<input type='submit' value='ok' style='display:none;'></form>";
$html .= "<script>document.forms['logout_submit'].submit();</script>";
return $html;
}
}

View File

@ -0,0 +1,28 @@
<?php
/**
* @Created by PhpStorm.
* @Author:Soar
* @Time:2023/7/19 14:44
*/
namespace app\admin\controller;
use app\common\controller\Backend;
class Contestants extends Backend
{
/**
* @var \app\admin\model\cms\Archives
*/
protected $model = null;
public function _initialize()
{
parent::_initialize();
$this->model = model('Archives');
}
public function chechkUser()
{
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace app\admin\controller;
use app\common\controller\Backend;
/**
*
*
* @icon fa fa-circle-o
*/
class Renzheng extends Backend
{
/**
* Renzheng模型对象
* @var \app\admin\model\Renzheng
*/
protected $model = null;
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\Renzheng;
$this->view->assign("statusList", $this->model->getStatusList());
}
/**
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
*/
}

View File

@ -0,0 +1,37 @@
<?php
namespace app\admin\controller\Renzheng;
use app\common\controller\Backend;
/**
*
*
* @icon fa fa-circle-o
*/
class Php extends Backend
{
/**
* Php模型对象
* @var \app\admin\model\Renzheng\Php
*/
protected $model = null;
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\Renzheng\Php;
$this->view->assign("statusList", $this->model->getStatusList());
}
/**
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
*/
}

View File

View File

@ -0,0 +1,215 @@
<?php
/**
* @Created by PhpStorm.
* @Author:Soar
* @Time:2023/11/21 15:11
*/
namespace app\admin\controller;
use app\admin\service\ScheduleService;
use app\common\controller\Backend;
use think\Validate;
class Schedule extends Backend
{
protected $noNeedLogin = ["*"];
public function _initialize()
{
parent::_initialize(); // TODO: Change the autogenerated stub
$this->scheduleService = new ScheduleService();
}
public function getSchedule()
{
$param['match_id'] = $this->request->param("match_id");
$rule = [
'match_id' => 'require',
];
$msg = [
'match_id.require' => '赛事ID不可为空',
];
$validate = new Validate($rule, $msg);
$result = $validate->check($param);
if (!$result) {
$this->error(__($validate->getError()), null, ['token' => $this->request->token()]);
}
$res = $this->scheduleService->getByWhere($param);
if ($res) {
$resule['data'] = $res;
$resule['code'] = 1;
$resule['msg'] = "获取成功";
} else {
$resule['data'] = [];
$resule['code'] = 1;
$resule['msg'] = "获取失败";
}
return json($resule);
}
public function getOneSchedule()
{
$param['id'] = $this->request->param("id");
$rule = [
'id' => 'require',
];
$msg = [
'id.require' => 'id不可为空',
];
$validate = new Validate($rule, $msg);
$result = $validate->check($param);
if (!$result) {
$this->error(__($validate->getError()), null, ['token' => $this->request->token()]);
}
$res = $this->scheduleService->getOne($param['id']);
if ($res) {
$resule['data'] = $res;
$resule['code'] = 1;
$resule['msg'] = "获取成功";
} else {
$resule['data'] = [];
$resule['code'] = 1;
$resule['msg'] = "获取失败";
}
return json($resule);
}
public function delete()
{
$param['id'] = $this->request->param("id");
$rule = [
'id' => 'require',
];
$msg = [
'id.require' => 'id不可为空',
];
$validate = new Validate($rule, $msg);
$result = $validate->check($param);
if (!$result) {
$this->error(__($validate->getError()), null, ['token' => $this->request->token()]);
}
$res = $this->scheduleService->delSchedule($param['id']);
if ($res) {
$resule['data'] = [];
$resule['code'] = 1;
$resule['msg'] = "删除成功";
} else {
$resule['data'] = [];
$resule['code'] = 1;
$resule['msg'] = "删除失败";
}
return json($resule);
}
public function add()
{
$param['match_id'] = $this->request->param("match_id");
$param['title'] = $this->request->param("title");
$param['content'] = $this->request->param("content");
$param['date'] = $this->request->param("date");
$param['weigh'] = $this->request->param("weigh");
$rule = [
'title' => 'require',
'match_id' => 'require',
'content' => 'require',
'date' => 'require',
];
$msg = [
'title.require' => '标题不可为空',
'match_id.require' => '赛程数据不可为空',
'date.require' => '日期不可为空',
'content.require' => '日程内容不可为空',
];
$validate = new Validate($rule, $msg);
$result = $validate->check($param);
if (!$result) {
$this->error(__($validate->getError()), null, ['token' => $this->request->token()]);
}
$res = $this->scheduleService->addSchedule($param);
if ($res) {
$resule['data'] = [];
$resule['code'] = 1;
$resule['msg'] = "添加成功";
} else {
$resule['data'] = [];
$resule['code'] = 1;
$resule['msg'] = "添加失败";
}
return json($resule);
}
public function editSchedule()
{
$param['match_id'] = $this->request->param("match_id");
$param['title'] = $this->request->param("title");
$param['content'] = $this->request->param("content");
$param['date'] = $this->request->param("date");
$param['weigh'] = $this->request->param("weigh");
$param['id'] = $this->request->param("id");
$rule = [
'title' => 'require',
'match_id' => 'require',
'content' => 'require',
'date' => 'require',
'id' => 'require',
];
$msg = [
'title.require' => '标题不可为空',
'match_id.require' => '赛程数据不可为空',
'date.require' => '日期不可为空',
'content.require' => '日程内容不可为空',
'id.require' => '修改日程ID不可为空',
];
$validate = new Validate($rule, $msg);
$result = $validate->check($param);
if (!$result) {
$this->error(__($validate->getError()), null, ['token' => $this->request->token()]);
}
$res = $this->scheduleService->editSchedule($param);
if ($res) {
$resule['data'] = [];
$resule['code'] = 1;
$resule['msg'] = "修改成功";
} else {
$resule['data'] = [];
$resule['code'] = 1;
$resule['msg'] = "修改失败";
}
return json($resule);
}
}

View File

@ -0,0 +1,88 @@
<?php
/**
* @Created by PhpStorm.
* @Author:Soar
* @Time:2023/11/17 10:56
*/
namespace app\admin\controller;
use app\admin\service\ScreenService;
use app\common\controller\Backend;
use think\Db;
use think\Validate;
class Screen extends Backend
{
protected $noNeedLogin = ["*"];
protected $noNeedRight = ["*"];
protected $layout = '';
public function _initialize()
{
parent::_initialize();
$this->screenService = new ScreenService();
}
public function addScreen()
{
$param['title'] = $this->request->param("title");
$param['look_pwd'] = $this->request->param("password");
$param['match_id'] = $this->request->param("match_id");
$param['backound_img'] = $this->request->param("backound_img", "");
$param['nopass'] = $this->request->param("nopass");
$param['font_rgb'] = $this->request->param("font_rgb");
$param['type'] = $this->request->param("type");
$rule = [
'title' => 'require',
'match_id' => 'require',
];
$msg = [
'title.require' => '标题不可为空',
'match_id.require' => '赛程数据不可为空',
];
$validate = new Validate($rule, $msg);
$result = $validate->check($param);
if (!$result) {
$this->error(__($validate->getError()), null, ['token' => $this->request->token()]);
}
$res = $this->screenService->addScreen($param);
if (!empty($res)) {
$row['code'] = 1;
$row['data'] = [];
$row['msg'] = "保存成功";
} else {
$row['code'] = 0;
$row['data'] = [];
$row['msg'] = "保存失败";
}
return json($row);
}
public function getScreen()
{
$param['match_id'] = $this->request->param("match_id");
$param['type'] = $this->request->param("type");
$res = $this->screenService->getScreen($param);
if (!empty($res)) {
$row['code'] = 1;
$row['data'] = $res;
$row['msg'] = "获取成功";
} else {
$row['code'] = 0;
$row['data'] = [];
$row['msg'] = "获取失败";
}
return json($row);
}
}

View File

@ -0,0 +1,66 @@
<?php
namespace app\admin\controller;
use app\common\controller\Backend;
/**
* 第三方登录管理
*
* @icon fa fa-circle-o
*/
class Third extends Backend
{
/**
* Third模型对象
* @var \app\admin\model\Third
*/
protected $model = null;
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\Third;
}
/**
* 查看
*/
public function index()
{
$this->relationSearch = true;
//设置过滤方法
$this->request->filter(['strip_tags']);
if ($this->request->isAjax()) {
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$total = $this->model
->with(['user'])
->where($where)
->order($sort, $order)
->count();
$list = $this->model
->with(['user'])
->where($where)
->order($sort, $order)
->limit($offset, $limit)
->select();
foreach ($list as $index => $item) {
if ($item->user) {
$item->user->visible(['nickname']);
}
}
$list = collection($list)->toArray();
$result = array("total" => $total, "rows" => $list);
return json($result);
}
return $this->view->fetch();
}
}

View File

@ -0,0 +1,297 @@
<?php
namespace app\admin\controller\auth;
use app\admin\model\AuthGroup;
use app\admin\model\AuthGroupAccess;
use app\common\controller\Backend;
use fast\Random;
use fast\Tree;
use think\Db;
use think\Validate;
/**
* 管理员管理
*
* @icon fa fa-users
* @remark 一个管理员可以有多个角色组,左侧的菜单根据管理员所拥有的权限进行生成
*/
class Admin extends Backend
{
/**
* @var \app\admin\model\Admin
*/
protected $model = null;
protected $selectpageFields = 'id,username,nickname,avatar';
protected $searchFields = 'id,username,nickname';
protected $childrenGroupIds = [];
protected $childrenAdminIds = [];
public function _initialize()
{
parent::_initialize();
$this->model = model('Admin');
$this->childrenAdminIds = $this->auth->getChildrenAdminIds($this->auth->isSuperAdmin());
$this->childrenGroupIds = $this->auth->getChildrenGroupIds($this->auth->isSuperAdmin());
$groupList = collection(AuthGroup::where('id', 'in', $this->childrenGroupIds)->select())->toArray();
Tree::instance()->init($groupList);
$groupdata = [];
if ($this->auth->isSuperAdmin()) {
$result = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0));
foreach ($result as $k => $v) {
$groupdata[$v['id']] = $v['name'];
}
} else {
$result = [];
$groups = $this->auth->getGroups();
foreach ($groups as $m => $n) {
$childlist = Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['id']));
$temp = [];
foreach ($childlist as $k => $v) {
$temp[$v['id']] = $v['name'];
}
$result[__($n['name'])] = $temp;
}
$groupdata = $result;
}
$this->view->assign('groupdata', $groupdata);
$this->assignconfig("admin", ['id' => $this->auth->id]);
}
/**
* 查看
*/
public function index()
{
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
$childrenGroupIds = $this->childrenGroupIds;
$groupName = AuthGroup::where('id', 'in', $childrenGroupIds)
->column('id,name');
$authGroupList = AuthGroupAccess::where('group_id', 'in', $childrenGroupIds)
->field('uid,group_id')
->select();
$adminGroupName = [];
foreach ($authGroupList as $k => $v) {
if (isset($groupName[$v['group_id']])) {
$adminGroupName[$v['uid']][$v['group_id']] = $groupName[$v['group_id']];
}
}
$groups = $this->auth->getGroups();
foreach ($groups as $m => $n) {
$adminGroupName[$this->auth->id][$n['id']] = $n['name'];
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$list = $this->model
->where($where)
->where('id', 'in', $this->childrenAdminIds)
->field(['password', 'salt', 'token'], true)
->order($sort, $order)
->paginate($limit);
foreach ($list as $k => &$v) {
$groups = isset($adminGroupName[$v['id']]) ? $adminGroupName[$v['id']] : [];
$v['groups'] = implode(',', array_keys($groups));
$v['groups_text'] = implode(',', array_values($groups));
}
unset($v);
$result = array("total" => $list->total(), "rows" => $list->items());
return json($result);
}
return $this->view->fetch();
}
/**
* 添加
*/
public function add()
{
if ($this->request->isPost()) {
$this->token();
$params = $this->request->post("row/a");
if ($params) {
Db::startTrans();
try {
if (!Validate::is($params['password'], '\S{6,30}')) {
exception(__("Please input correct password"));
}
$params['salt'] = Random::alnum();
$params['password'] = md5(md5($params['password']) . $params['salt']);
$params['avatar'] = '/assets/img/avatar.png'; //设置新管理员默认头像。
$result = $this->model->validate('Admin.add')->save($params);
if ($result === false) {
exception($this->model->getError());
}
$group = $this->request->post("group/a");
//过滤不允许的组别,避免越权
$group = array_intersect($this->childrenGroupIds, $group);
if (!$group) {
exception(__('The parent group exceeds permission limit'));
}
$dataset = [];
foreach ($group as $value) {
$dataset[] = ['uid' => $this->model->id, 'group_id' => $value];
}
model('AuthGroupAccess')->saveAll($dataset);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success();
}
$this->error(__('Parameter %s can not be empty', ''));
}
return $this->view->fetch();
}
/**
* 编辑
*/
public function edit($ids = null)
{
$row = $this->model->get(['id' => $ids]);
if (!$row) {
$this->error(__('No Results were found'));
}
if (!in_array($row->id, $this->childrenAdminIds)) {
$this->error(__('You have no permission'));
}
if ($this->request->isPost()) {
$this->token();
$params = $this->request->post("row/a");
if ($params) {
Db::startTrans();
try {
if ($params['password']) {
if (!Validate::is($params['password'], '\S{6,30}')) {
exception(__("Please input correct password"));
}
$params['salt'] = Random::alnum();
$params['password'] = md5(md5($params['password']) . $params['salt']);
} else {
unset($params['password'], $params['salt']);
}
//这里需要针对username和email做唯一验证
$adminValidate = \think\Loader::validate('Admin');
$adminValidate->rule([
'username' => 'require|regex:\w{3,30}|unique:admin,username,' . $row->id,
'email' => 'require|email|unique:admin,email,' . $row->id,
'mobile' => 'regex:1[3-9]\d{9}|unique:admin,mobile,' . $row->id,
'password' => 'regex:\S{32}',
]);
$result = $row->validate('Admin.edit')->save($params);
if ($result === false) {
exception($row->getError());
}
// 先移除所有权限
model('AuthGroupAccess')->where('uid', $row->id)->delete();
$group = $this->request->post("group/a");
// 过滤不允许的组别,避免越权
$group = array_intersect($this->childrenGroupIds, $group);
if (!$group) {
exception(__('The parent group exceeds permission limit'));
}
$dataset = [];
foreach ($group as $value) {
$dataset[] = ['uid' => $row->id, 'group_id' => $value];
}
model('AuthGroupAccess')->saveAll($dataset);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success();
}
$this->error(__('Parameter %s can not be empty', ''));
}
$grouplist = $this->auth->getGroups($row['id']);
$groupids = [];
foreach ($grouplist as $k => $v) {
$groupids[] = $v['id'];
}
$this->view->assign("row", $row);
$this->view->assign("groupids", $groupids);
return $this->view->fetch();
}
/**
* 删除
*/
public function del($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
if ($ids) {
$ids = array_intersect($this->childrenAdminIds, array_filter(explode(',', $ids)));
// 避免越权删除管理员
$childrenGroupIds = $this->childrenGroupIds;
$adminList = $this->model->where('id', 'in', $ids)->where('id', 'in', function ($query) use ($childrenGroupIds) {
$query->name('auth_group_access')->where('group_id', 'in', $childrenGroupIds)->field('uid');
})->select();
if ($adminList) {
$deleteIds = [];
foreach ($adminList as $k => $v) {
$deleteIds[] = $v->id;
}
$deleteIds = array_values(array_diff($deleteIds, [$this->auth->id]));
if ($deleteIds) {
Db::startTrans();
try {
$this->model->destroy($deleteIds);
model('AuthGroupAccess')->where('uid', 'in', $deleteIds)->delete();
Db::commit();
} catch (\Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success();
}
$this->error(__('No rows were deleted'));
}
}
$this->error(__('You have no permission'));
}
/**
* 批量更新
* @internal
*/
public function multi($ids = "")
{
// 管理员禁止批量操作
$this->error();
}
/**
* 下拉搜索
*/
public function selectpage()
{
$this->dataLimit = 'auth';
$this->dataLimitField = 'id';
return parent::selectpage();
}
}

View File

@ -0,0 +1,133 @@
<?php
namespace app\admin\controller\auth;
use app\admin\model\AuthGroup;
use app\common\controller\Backend;
/**
* 管理员日志
*
* @icon fa fa-users
* @remark 管理员可以查看自己所拥有的权限的管理员日志
*/
class Adminlog extends Backend
{
/**
* @var \app\admin\model\AdminLog
*/
protected $model = null;
protected $childrenGroupIds = [];
protected $childrenAdminIds = [];
public function _initialize()
{
parent::_initialize();
$this->model = model('AdminLog');
$this->childrenAdminIds = $this->auth->getChildrenAdminIds(true);
$this->childrenGroupIds = $this->auth->getChildrenGroupIds(true);
$groupName = AuthGroup::where('id', 'in', $this->childrenGroupIds)
->column('id,name');
$this->view->assign('groupdata', $groupName);
}
/**
* 查看
*/
public function index()
{
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$list = $this->model
->where($where)
->where('admin_id', 'in', $this->childrenAdminIds)
->order($sort, $order)
->paginate($limit);
$result = array("total" => $list->total(), "rows" => $list->items());
return json($result);
}
return $this->view->fetch();
}
/**
* 详情
*/
public function detail($ids)
{
$row = $this->model->get(['id' => $ids]);
if (!$row) {
$this->error(__('No Results were found'));
}
if (!$row['admin_id'] || !in_array($row['admin_id'], $this->childrenAdminIds)) {
$this->error(__('You have no permission'));
}
$this->view->assign("row", $row->toArray());
return $this->view->fetch();
}
/**
* 添加
* @internal
*/
public function add()
{
$this->error();
}
/**
* 编辑
* @internal
*/
public function edit($ids = null)
{
$this->error();
}
/**
* 删除
*/
public function del($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
if ($ids) {
$adminList = $this->model->where('id', 'in', $ids)->where('admin_id', 'in', $this->childrenAdminIds)->select();
if ($adminList) {
$deleteIds = [];
foreach ($adminList as $k => $v) {
$deleteIds[] = $v->id;
}
if ($deleteIds) {
$this->model->destroy($deleteIds);
$this->success();
}
}
}
$this->error();
}
/**
* 批量更新
* @internal
*/
public function multi($ids = "")
{
// 管理员禁止批量操作
$this->error();
}
public function selectpage()
{
return parent::selectpage();
}
}

View File

@ -0,0 +1,317 @@
<?php
namespace app\admin\controller\auth;
use app\admin\model\AuthGroup;
use app\common\controller\Backend;
use fast\Tree;
use think\Db;
use think\Exception;
/**
* 角色组
*
* @icon fa fa-group
* @remark 角色组可以有多个,角色有上下级层级关系,如果子角色有角色组和管理员的权限则可以派生属于自己组别下级的角色组或管理员
*/
class Group extends Backend
{
/**
* @var \app\admin\model\AuthGroup
*/
protected $model = null;
//当前登录管理员所有子组别
protected $childrenGroupIds = [];
//当前组别列表数据
protected $grouplist = [];
protected $groupdata = [];
//无需要权限判断的方法
protected $noNeedRight = ['roletree'];
public function _initialize()
{
parent::_initialize();
$this->model = model('AuthGroup');
$this->childrenGroupIds = $this->auth->getChildrenGroupIds(true);
$groupList = collection(AuthGroup::where('id', 'in', $this->childrenGroupIds)->select())->toArray();
Tree::instance()->init($groupList);
$groupList = [];
if ($this->auth->isSuperAdmin()) {
$groupList = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0));
} else {
$groups = $this->auth->getGroups();
$groupIds = [];
foreach ($groups as $m => $n) {
if (in_array($n['id'], $groupIds) || in_array($n['pid'], $groupIds)) {
continue;
}
$groupList = array_merge($groupList, Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['pid'])));
foreach ($groupList as $index => $item) {
$groupIds[] = $item['id'];
}
}
}
$groupName = [];
foreach ($groupList as $k => $v) {
$groupName[$v['id']] = $v['name'];
}
$this->grouplist = $groupList;
$this->groupdata = $groupName;
$this->assignconfig("admin", ['id' => $this->auth->id, 'group_ids' => $this->auth->getGroupIds()]);
$this->view->assign('groupdata', $this->groupdata);
}
/**
* 查看
*/
public function index()
{
if ($this->request->isAjax()) {
$list = $this->grouplist;
$total = count($list);
$result = array("total" => $total, "rows" => $list);
return json($result);
}
return $this->view->fetch();
}
/**
* 添加
*/
public function add()
{
if ($this->request->isPost()) {
$this->token();
$params = $this->request->post("row/a", [], 'strip_tags');
$params['rules'] = explode(',', $params['rules']);
if (!in_array($params['pid'], $this->childrenGroupIds)) {
$this->error(__('The parent group exceeds permission limit'));
}
$parentmodel = model("AuthGroup")->get($params['pid']);
if (!$parentmodel) {
$this->error(__('The parent group can not found'));
}
// 父级别的规则节点
$parentrules = explode(',', $parentmodel->rules);
// 当前组别的规则节点
$currentrules = $this->auth->getRuleIds();
$rules = $params['rules'];
// 如果父组不是超级管理员则需要过滤规则节点,不能超过父组别的权限
$rules = in_array('*', $parentrules) ? $rules : array_intersect($parentrules, $rules);
// 如果当前组别不是超级管理员则需要过滤规则节点,不能超当前组别的权限
$rules = in_array('*', $currentrules) ? $rules : array_intersect($currentrules, $rules);
$params['rules'] = implode(',', $rules);
if ($params) {
$this->model->create($params);
$this->success();
}
$this->error();
}
return $this->view->fetch();
}
/**
* 编辑
*/
public function edit($ids = null)
{
if (!in_array($ids, $this->childrenGroupIds)) {
$this->error(__('You have no permission'));
}
$row = $this->model->get(['id' => $ids]);
if (!$row) {
$this->error(__('No Results were found'));
}
if ($this->request->isPost()) {
$this->token();
$params = $this->request->post("row/a", [], 'strip_tags');
//父节点不能是非权限内节点
if (!in_array($params['pid'], $this->childrenGroupIds)) {
$this->error(__('The parent group exceeds permission limit'));
}
// 父节点不能是它自身的子节点或自己本身
if (in_array($params['pid'], Tree::instance()->getChildrenIds($row->id, true))) {
$this->error(__('The parent group can not be its own child or itself'));
}
$params['rules'] = explode(',', $params['rules']);
$parentmodel = model("AuthGroup")->get($params['pid']);
if (!$parentmodel) {
$this->error(__('The parent group can not found'));
}
// 父级别的规则节点
$parentrules = explode(',', $parentmodel->rules);
// 当前组别的规则节点
$currentrules = $this->auth->getRuleIds();
$rules = $params['rules'];
// 如果父组不是超级管理员则需要过滤规则节点,不能超过父组别的权限
$rules = in_array('*', $parentrules) ? $rules : array_intersect($parentrules, $rules);
// 如果当前组别不是超级管理员则需要过滤规则节点,不能超当前组别的权限
$rules = in_array('*', $currentrules) ? $rules : array_intersect($currentrules, $rules);
$params['rules'] = implode(',', $rules);
if ($params) {
Db::startTrans();
try {
$row->save($params);
$children_auth_groups = model("AuthGroup")->all(['id' => ['in', implode(',', (Tree::instance()->getChildrenIds($row->id)))]]);
$childparams = [];
foreach ($children_auth_groups as $key => $children_auth_group) {
$childparams[$key]['id'] = $children_auth_group->id;
$childparams[$key]['rules'] = implode(',', array_intersect(explode(',', $children_auth_group->rules), $rules));
}
model("AuthGroup")->saveAll($childparams);
Db::commit();
$this->success();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
}
$this->error();
return;
}
$this->view->assign("row", $row);
return $this->view->fetch();
}
/**
* 删除
*/
public function del($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
if ($ids) {
$ids = explode(',', $ids);
$grouplist = $this->auth->getGroups();
$group_ids = array_map(function ($group) {
return $group['id'];
}, $grouplist);
// 移除掉当前管理员所在组别
$ids = array_diff($ids, $group_ids);
// 循环判断每一个组别是否可删除
$grouplist = $this->model->where('id', 'in', $ids)->select();
$groupaccessmodel = model('AuthGroupAccess');
foreach ($grouplist as $k => $v) {
// 当前组别下有管理员
$groupone = $groupaccessmodel->get(['group_id' => $v['id']]);
if ($groupone) {
$ids = array_diff($ids, [$v['id']]);
continue;
}
// 当前组别下有子组别
$groupone = $this->model->get(['pid' => $v['id']]);
if ($groupone) {
$ids = array_diff($ids, [$v['id']]);
continue;
}
}
if (!$ids) {
$this->error(__('You can not delete group that contain child group and administrators'));
}
$count = $this->model->where('id', 'in', $ids)->delete();
if ($count) {
$this->success();
}
}
$this->error();
}
/**
* 批量更新
* @internal
*/
public function multi($ids = "")
{
// 组别禁止批量操作
$this->error();
}
/**
* 读取角色权限树
*
* @internal
*/
public function roletree()
{
$this->loadlang('auth/group');
$model = model('AuthGroup');
$id = $this->request->post("id");
$pid = $this->request->post("pid");
$parentGroupModel = $model->get($pid);
$currentGroupModel = null;
if ($id) {
$currentGroupModel = $model->get($id);
}
if (($pid || $parentGroupModel) && (!$id || $currentGroupModel)) {
$id = $id ? $id : null;
$ruleList = collection(model('AuthRule')->order('weigh', 'desc')->order('id', 'asc')->select())->toArray();
//读取父类角色所有节点列表
$parentRuleList = [];
if (in_array('*', explode(',', $parentGroupModel->rules))) {
$parentRuleList = $ruleList;
} else {
$parentRuleIds = explode(',', $parentGroupModel->rules);
foreach ($ruleList as $k => $v) {
if (in_array($v['id'], $parentRuleIds)) {
$parentRuleList[] = $v;
}
}
}
$ruleTree = new Tree();
$groupTree = new Tree();
//当前所有正常规则列表
$ruleTree->init($parentRuleList);
//角色组列表
$groupTree->init(collection(model('AuthGroup')->where('id', 'in', $this->childrenGroupIds)->select())->toArray());
//读取当前角色下规则ID集合
$adminRuleIds = $this->auth->getRuleIds();
//是否是超级管理员
$superadmin = $this->auth->isSuperAdmin();
//当前拥有的规则ID集合
$currentRuleIds = $id ? explode(',', $currentGroupModel->rules) : [];
if (!$id || !in_array($pid, $this->childrenGroupIds) || !in_array($pid, $groupTree->getChildrenIds($id, true))) {
$parentRuleList = $ruleTree->getTreeList($ruleTree->getTreeArray(0), 'name');
$hasChildrens = [];
foreach ($parentRuleList as $k => $v) {
if ($v['haschild']) {
$hasChildrens[] = $v['id'];
}
}
$parentRuleIds = array_map(function ($item) {
return $item['id'];
}, $parentRuleList);
$nodeList = [];
foreach ($parentRuleList as $k => $v) {
if (!$superadmin && !in_array($v['id'], $adminRuleIds)) {
continue;
}
if ($v['pid'] && !in_array($v['pid'], $parentRuleIds)) {
continue;
}
$state = array('selected' => in_array($v['id'], $currentRuleIds) && !in_array($v['id'], $hasChildrens));
$nodeList[] = array('id' => $v['id'], 'parent' => $v['pid'] ? $v['pid'] : '#', 'text' => __($v['title']), 'type' => 'menu', 'state' => $state);
}
$this->success('', null, $nodeList);
} else {
$this->error(__('Can not change the parent to child'));
}
} else {
$this->error(__('Group not found'));
}
}
}

View File

@ -0,0 +1,159 @@
<?php
namespace app\admin\controller\auth;
use app\admin\model\AuthRule;
use app\common\controller\Backend;
use fast\Tree;
use think\Cache;
/**
* 规则管理
*
* @icon fa fa-list
* @remark 规则通常对应一个控制器的方法,同时左侧的菜单栏数据也从规则中体现,通常建议通过控制台进行生成规则节点
*/
class Rule extends Backend
{
/**
* @var \app\admin\model\AuthRule
*/
protected $model = null;
protected $rulelist = [];
protected $multiFields = 'ismenu,status';
public function _initialize()
{
parent::_initialize();
if (!$this->auth->isSuperAdmin()) {
$this->error(__('Access is allowed only to the super management group'));
}
$this->model = model('AuthRule');
// 必须将结果集转换为数组
$ruleList = \think\Db::name("auth_rule")->field('type,condition,remark,createtime,updatetime', true)->order('weigh DESC,id ASC')->select();
foreach ($ruleList as $k => &$v) {
$v['title'] = __($v['title']);
}
unset($v);
Tree::instance()->init($ruleList);
$this->rulelist = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0), 'title');
$ruledata = [0 => __('None')];
foreach ($this->rulelist as $k => &$v) {
if (!$v['ismenu']) {
continue;
}
$ruledata[$v['id']] = $v['title'];
unset($v['spacer']);
}
unset($v);
$this->view->assign('ruledata', $ruledata);
$this->view->assign("menutypeList", $this->model->getMenutypeList());
}
/**
* 查看
*/
public function index()
{
if ($this->request->isAjax()) {
$list = $this->rulelist;
$total = count($this->rulelist);
$result = array("total" => $total, "rows" => $list);
return json($result);
}
return $this->view->fetch();
}
/**
* 添加
*/
public function add()
{
if ($this->request->isPost()) {
$this->token();
$params = $this->request->post("row/a", [], 'strip_tags');
if ($params) {
if (!$params['ismenu'] && !$params['pid']) {
$this->error(__('The non-menu rule must have parent'));
}
$result = $this->model->validate()->save($params);
if ($result === false) {
$this->error($this->model->getError());
}
Cache::rm('__menu__');
$this->success();
}
$this->error();
}
return $this->view->fetch();
}
/**
* 编辑
*/
public function edit($ids = null)
{
$row = $this->model->get(['id' => $ids]);
if (!$row) {
$this->error(__('No Results were found'));
}
if ($this->request->isPost()) {
$this->token();
$params = $this->request->post("row/a", [], 'strip_tags');
if ($params) {
if (!$params['ismenu'] && !$params['pid']) {
$this->error(__('The non-menu rule must have parent'));
}
if ($params['pid'] == $row['id']) {
$this->error(__('Can not change the parent to self'));
}
if ($params['pid'] != $row['pid']) {
$childrenIds = Tree::instance()->init(collection(AuthRule::select())->toArray())->getChildrenIds($row['id']);
if (in_array($params['pid'], $childrenIds)) {
$this->error(__('Can not change the parent to child'));
}
}
//这里需要针对name做唯一验证
$ruleValidate = \think\Loader::validate('AuthRule');
$ruleValidate->rule([
'name' => 'require|unique:AuthRule,name,' . $row->id,
]);
$result = $row->validate()->save($params);
if ($result === false) {
$this->error($row->getError());
}
Cache::rm('__menu__');
$this->success();
}
$this->error();
}
$this->view->assign("row", $row);
return $this->view->fetch();
}
/**
* 删除
*/
public function del($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
if ($ids) {
$delIds = [];
foreach (explode(',', $ids) as $k => $v) {
$delIds = array_merge($delIds, Tree::instance()->getChildrenIds($v, true));
}
$delIds = array_unique($delIds);
$count = $this->model->where('id', 'in', $delIds)->delete();
if ($count) {
Cache::rm('__menu__');
$this->success();
}
}
$this->error();
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace app\admin\controller\club;
use app\common\controller\Backend;
/**
*
*
* @icon fa fa-circle-o
*/
class Complain extends Backend
{
/**
* Complain模型对象
* @var \app\admin\model\club\Complain
*/
protected $model = null;
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\club\Complain;
}
/**
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
*/
}

View File

@ -0,0 +1,189 @@
<?php
namespace app\admin\controller\club;
use app\common\controller\Backend;
use app\admin\model\club\Invate as InvateModel;
use think\Db;
use app\common\model\Players;
use app\admin\model\Club;
use app\index\controller\Wxmb;
use app\admin\model\shopro\ClubThirdOauth;
use app\admin\model\User;
/**
*
*
* @icon fa fa-circle-o
*/
class Invate extends Backend
{
/**
* Invate模型对象
* @var \app\admin\model\club\Invate
*/
protected $model = null;
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\club\Invate;
$this->view->assign("statusList", $this->model->getStatusList());
}
//更新旧数据
public function updatename(){
$res = $this->model->where(['deletetime' =>null,'status'=>1,'name_short'=>null])->select();
var_dump($res);exit;
// 启动事务
Db::startTrans();
try{
foreach ($res as $val){
$User = new User();
$players = new Players();
$club = new Club();
$player_info = $players->where('id',$val['player_id'])->find();
$user_info = $User->where('id',$player_info['member_id'])->find();
$club_info = $club->where('id',$val['club_id'])->find();
$this->model->where('id',$val['id'])->update([
'name_short' => $club_info['name_short'],
'member_number' => $user_info['member_number'],
]);
}
// 提交事务
Db::commit();
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
var_dump($e);exit;
}
// var_dump($res);exit;
}
public function index()
{
$user = new User();
$players = new Players();
//设置过滤方法
$club = new Club();
$this->request->filter(['strip_tags', 'trim']);
if (false === $this->request->isAjax()) {
return $this->view->fetch();
}
//如果发送的来源是 Selectpage则转发到 Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
[$where, $sort, $order, $offset, $limit] = $this->buildparams();
$sort = 'a.status,a.id desc';
// var_dump($order);exit;
$list = $this->model
->alias('a')
// ->join('peewee_players b','a.player_id = b.id','RIGHT')
->where($where)
->where('a.status in (5,6,7,8,9)')
->order($sort, $order)
->paginate($limit);
// var_dump($list->items());exit;
$i = 0;
foreach ($list->items() as &$val){
$player_res = $players->where('id',$val['player_id'])->find();
$club_info = $club->where('id',$val['club_id'])->find();
// if(empty($player_res)){var_dump($val);exit;}
if(!empty($player_res)){
$user_res = $user->where('id',$player_res['member_id'])->find();
// if(empty($user_res)){var_dump($val);exit;}
//用户信息不存在
// if(!empty($user_res)){
$val['phone'] = $player_res['phone'];
$val['player_name'] = $player_res['real_name'];
$val['gender'] = $player_res['gender'];
$val['province'] = $player_res['province'];
$val['name_short'] = !empty($club_info['name_short']) ? $club_info['name_short'] : '';
$val['member_number'] = $val['member_number'];
// }
}
}
$result = ['total' => $list->total(), 'rows' => $list->items()];
return json($result);
}
/**
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
*/
public function edit($ids = null)
{
$row = $this->model->get($ids);
if (!$row) {
$this->error(__('No Results were found'));
}
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
$this->error(__('You have no permission'));
}
if (false === $this->request->isPost()) {
$this->view->assign('row', $row);
return $this->view->fetch();
}
$params = $this->request->post('row/a');
if (empty($params)) {
$this->error(__('Parameter %s can not be empty', ''));
}
$params = $this->preExcludeFields($params);
// var_dump($params);exit;
// if($params['status'] == 7){
// $params['deletetime'] = time();
// }
// elseif($params['check_status'] == 2){
// $params['deletetime'] = time();
// }
$result = false;
Db::startTrans();
try {
//是否采用模型验证
if ($this->modelValidate) {
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
$row->validateFailException()->validate($validate);
}
$result = $row->allowField(true)->save($params);
Db::commit();
} catch (ValidateException|PDOException|Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if (false === $result) {
$this->error(__('No rows were updated'));
}
if($params['status'] == 6){
$players = new Players();
$club = new Club();
$clubThirdOauth = new ClubThirdOauth();
$Wxmb = new Wxmb();
$player_info = $players->where('id',$row['player_id'])->find();
$club_info = $club->where('id',$row['club_id'])->find();
$player_oauth = $clubThirdOauth->where('user_id',$player_info['member_id'])->find();
$club_oauth = $clubThirdOauth->where('user_id',$club_info['user_id'])->find();
// var_dump($player_oauth);exit;
if(!empty($player_oauth)){
$player_oauth = $player_oauth->toArray();
$push_arr = array('title'=>$club_info['name_short'].'队伍与飞手'.$player_info['real_name'].'关联已通过','username'=> '系统','type'=>'系统通知');
$Wxmb->leaguepush($push_arr,$player_oauth['openid']);
}
if(!empty($club_oauth)){
// var_dump($club_oauth);exit;
$club_oauth = $club_oauth->toArray();
$push_arr = array('title'=>$club_info['name_short'].'队伍与飞手'.$player_info['real_name'].'关联已通过','username'=> '系统','type'=>'系统通知');
$Wxmb->leaguepush($push_arr,$club_oauth['openid']);
}
// $params['deletetime'] = time();
}
$this->success();
}
}

View File

@ -0,0 +1,300 @@
<?php
namespace app\admin\controller\cms;
use addons\cms\library\aip\AipContentCensor;
use addons\cms\library\SensitiveHelper;
use addons\cms\library\Service;
use app\common\controller\Backend;
use think\Config;
use think\Db;
/**
* Ajax
*
* @icon fa fa-circle-o
* @internal
*/
class Ajax extends Backend
{
/**
* 模型对象
*/
protected $model = null;
protected $noNeedRight = ['*'];
/**
* 获取模板列表
* @internal
*/
public function get_template_list()
{
$files = [];
$keyValue = $this->request->request("keyValue");
if (!$keyValue) {
$type = $this->request->request("type");
$name = $this->request->request("name");
if ($name) {
//$files[] = ['name' => $name . '.html'];
}
//设置过滤方法
$this->request->filter(['strip_tags']);
$config = get_addon_config('cms');
$themeDir = ADDON_PATH . 'cms' . DS . 'view' . DS . $config['theme'] . DS;
$dh = opendir($themeDir);
while (false !== ($filename = readdir($dh))) {
if ($filename == '.' || $filename == '..') {
continue;
}
if ($type) {
$rule = $type == 'channel' ? '(channel|list)' : $type;
if (!preg_match("/^{$rule}(.*)/i", $filename)) {
continue;
}
}
$files[] = ['name' => $filename];
}
} else {
$files[] = ['name' => $keyValue];
}
return $result = ['total' => count($files), 'list' => $files];
}
/**
* 检查内容是否包含违禁词
* @throws \Exception
*/
public function check_content_islegal()
{
$config = get_addon_config('cms');
$content = $this->request->post('content');
if (!$content) {
$this->error(__('Please input your content'));
}
if ($config['audittype'] == 'local') {
// 敏感词过滤
$handle = SensitiveHelper::init()->setTreeByFile(ADDON_PATH . 'cms/data/words.dic');
//首先检测是否合法
$arr = $handle->getBadWord($content);
if ($arr) {
$this->error(__('The content is not legal'), null, $arr);
} else {
$this->success(__('The content is legal'));
}
} else {
$client = new AipContentCensor($config['aip_appid'], $config['aip_apikey'], $config['aip_secretkey']);
$result = $client->textCensorUserDefined($content);
if (isset($result['conclusionType']) && $result['conclusionType'] > 1) {
$msg = [];
foreach ($result['data'] as $index => $datum) {
$msg[] = $datum['msg'];
}
$this->error(implode("<br>", $msg), null, []);
} else {
$this->success(__('The content is legal'));
}
}
}
/**
* 获取关键字
* @throws \Exception
*/
public function get_content_keywords()
{
$config = get_addon_config('cms');
$title = $this->request->post('title');
$tags = $this->request->post('tags', '');
$content = $this->request->post('content');
if (!$content) {
$this->error(__('Please input your content'));
}
$keywords = Service::getContentTags($title);
$keywords = in_array($title, $keywords) ? [] : $keywords;
$keywords = array_filter(array_merge([$tags], $keywords));
$description = mb_substr(strip_tags($content), 0, 200);
$data = [
"keywords" => implode(',', $keywords),
"description" => $description
];
$this->success("提取成功", null, $data);
}
/**
* 获取标题拼音
*/
public function get_title_pinyin()
{
$config = get_addon_config('cms');
$title = $this->request->post("title");
//分隔符
$delimiter = $this->request->post("delimiter", "");
$pinyin = new \Overtrue\Pinyin\Pinyin('Overtrue\Pinyin\MemoryFileDictLoader');
if ($title) {
if ($config['autopinyin']) {
$result = $pinyin->permalink($title, $delimiter);
$this->success("", null, ['pinyin' => $result]);
} else {
$this->error();
}
} else {
$this->error(__('Parameter %s can not be empty', 'name'));
}
}
/**
* 获取表字段列表
* @internal
*/
public function get_fields_list()
{
$table = $this->request->request('table');
$fieldList = Service::getTableFields($table);
$this->success("", null, ['fieldList' => $fieldList]);
}
/**
* 获取自定义字段列表HTML
* @internal
*/
public function get_fields_html()
{
$this->view->engine->layout(false);
$source = $this->request->post('source');
$id = $this->request->post('id/d');
if (in_array($source, ['channel', 'page', 'special'])) {
$values = \think\Db::name("cms_{$source}")->where('id', $id)->find();
$values = $values ? $values : [];
$fields = \addons\cms\library\Service::getCustomFields($source, 0, $values);
$this->view->assign('fields', $fields);
$this->view->assign('values', $values);
$this->success('', null, ['html' => $this->view->fetch('cms/common/fields')]);
} else {
$this->error(__('Please select type'));
}
$this->error(__('Parameter %s can not be empty', 'ids'));
}
public function get_link_list()
{
if ($this->request->isAjax()) {
$filter = $this->request->request("filter", '', 'trim');
$filter = (array)json_decode($filter, true);
$pageList = \app\admin\model\cms\Page::all();
$specialList = \app\admin\model\cms\Special::all();
$diyformList = \app\admin\model\cms\Diyform::all();
$rows = [];
if (!isset($filter['type']) || $filter['type'] == 'page') {
foreach ($pageList as $index => $item) {
$rows[] = ['type' => 'page', 'url' => $item['url'], 'title' => $item['title'], 'source_id' => $item['id']];
}
}
if (!isset($filter['type']) || $filter['type'] == 'special') {
foreach ($specialList as $index => $item) {
$rows[] = ['type' => 'special', 'url' => $item['url'], 'title' => $item['title'], 'source_id' => $item['id']];
}
}
if (!isset($filter['type']) || $filter['type'] == 'diyform') {
foreach ($diyformList as $index => $item) {
$rows[] = ['type' => 'diyform', 'url' => $item['url'], 'title' => $item['name'] . ' - 列表页', 'source_id' => $item['id']];
$rows[] = ['type' => 'diyform', 'url' => $item['post_url'], 'title' => $item['name'] . " - 投稿页", 'source_id' => $item['id']];
}
}
foreach ($rows as $index => $row) {
if (isset($filter['url']) && stripos($row['url'], $filter['url']) === false) {
unset($rows[$index]);
continue;
}
if (isset($filter['title']) && stripos($row['title'], $filter['title']) === false) {
unset($rows[$index]);
continue;
}
}
return [
'rows' => array_values($rows),
'total' => count($rows)
];
}
$typeList = [
'special' => '专题',
'page' => '单页',
'diyform' => '自定义表单',
];
$this->view->assign('typeList', $typeList);
return $this->view->fetch('cms/common/links');
}
public function config()
{
$name = $this->request->get('name');
if ($name == 'sms') {
$config = config('addons.hooks');
if (isset($config['sms_send']) && $config['sms_send']) {
$name = reset($config['sms_send']);
} else {
$this->error("请在插件管理中安装一款短信验证插件", "");
}
} elseif ($name == 'oss') {
$config = config('addons.hooks');
if (isset($config['upload_config_init']) && $config['upload_config_init']) {
$availableArr = array_intersect($config['upload_config_init'], ['alioss', 'bos', 'cos', 'upyun', 'ucloud', 'hwobs', 'qiniu']);
if ($availableArr) {
$name = reset($availableArr);
}
}
if (!$name || $name == 'oss') {
$this->error("请在插件管理中安装一款云存储插件", "");
}
} else {
$info = get_addon_info($name);
$addonArr = [
'third' => '第三方登录',
'signin' => '会员签到',
'epay' => '微信支付宝整合',
];
if (!$info) {
$this->error('请检查对应插件' . (isset($addonArr[$name]) ? "{$addonArr[$name]}" : "") . '是否安装且启动', "");
}
}
$this->redirect('addon/config?name=' . $name . '&dialog=1');
}
/**
* 检测元素是否可用
* @internal
*/
public function check_config_available()
{
$name = $this->request->request('name');
$value = $this->request->request('value');
$name = substr($name, 4, -1);
if (!$name) {
$this->error(__('Parameter %s can not be empty', 'name'));
}
if ($name == 'theme') {
if (!preg_match("/^([a-zA-Z0-9\-_]+)$/i", $value)) {
$this->error("只支持字母数字下划线");
}
if (!is_dir(ADDON_PATH . 'cms' . DS . 'view' . DS . $value . DS)) {
$this->error("皮肤目录不存在");
}
} elseif ($name == 'archivesratio') {
$valueArr = explode(':', $value);
if (!isset($valueArr[1])) {
$this->error('格式不正确');
}
if (bcadd($valueArr[0], $valueArr[1], 2) != 1) {
$this->error('分成占比相加必须等于1');
}
} elseif ($name == 'cachelifetime') {
if (!is_numeric($value) && !in_array($value, ['true', 'false'])) {
$this->error("格式不正确,只支持 数字/true");
}
}
$this->success();
}
}

View File

@ -0,0 +1,993 @@
<?php
namespace app\admin\controller\cms;
use addons\cms\library\FulltextSearch;
use app\admin\model\cms\Channel;
use app\admin\model\cms\ChannelAdmin;
use app\admin\model\cms\Modelx;
use app\common\controller\Backend;
use app\common\model\User;
use app\admin\model\ClubMatchApply;
use app\admin\model\Club;
use fast\Tree;
use think\Db;
use think\db\Query;
use think\Hook;
use think\Request;
/**
* 内容表
*
* @icon fa fa-file-text-o
*/
class Archives extends Backend
{
/**
* Archives模型对象
*/
protected $model = null;
protected $noNeedRight = ['get_fields_html', 'check_element_available', 'suggestion', 'copy', 'special', 'tags', 'move', 'flag'];
protected $channelIds = [];
protected $isSuperAdmin = false;
protected $searchFields = 'id,title';
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\cms\Archives;
$this->MatchContestantModel = model('MatchContestant');
$this->UserModel = model('User');
$config = get_addon_config('cms');
if ($config['archivesdatalimit'] != 'all') {
$this->dataLimit = $config['archivesdatalimit'];
}
//复制/加入专题/修改标签均检测编辑权限
if (in_array($this->request->action(), ['copy', 'special', 'tags', 'move', 'flag']) && !$this->auth->check('cms/archives/edit')) {
Hook::listen('admin_nopermission', $this);
$this->error(__('You have no permission'), '');
}
//是否超级管理员
$this->isSuperAdmin = $this->auth->isSuperAdmin();
$channelList = [];
$disabledIds = [];
$all = collection(Channel::order("weigh desc,id desc")->select())->toArray();
//允许的栏目
$this->channelIds = $this->isSuperAdmin || !$config['channelallocate'] ? Channel::column('id') : ChannelAdmin::getAdminChanneIds();
$parentChannelIds = Channel::where('id', 'in', $this->channelIds)->column('parent_id');
$parentChannelIds = array_unique($parentChannelIds);
$parentChannelList = \think\Db::name('cms_channel')->where('id', 'in', $parentChannelIds)->where('parent_id', '<>', 0)->field('id,parent_id,name')->select();
$tree = Tree::instance()->init($all, 'parent_id');
foreach ($parentChannelList as $index => $channel) {
$parentChannelIds = array_merge($parentChannelIds, $tree->getParentsIds($channel['parent_id'], true));
}
$this->channelIds = array_merge($parentChannelIds, $this->channelIds);
foreach ($all as $k => $v) {
$state = ['opened' => true];
if ($v['type'] == 'link') {
$disabledIds[] = $v['id'];
}
if ($v['type'] == 'link') {
$state['checkbox_disabled'] = true;
}
if (!$this->isSuperAdmin) {
if (!in_array($v['id'], $parentChannelIds) && !in_array($v['id'], $this->channelIds)) {
unset($all[$k]);
continue;
}
}
$channelList[] = [
'id' => $v['id'],
'parent' => $v['parent_id'] ? $v['parent_id'] : '#',
'text' => __($v['name']),
'type' => $v['type'],
'state' => $state
];
}
$tree = Tree::instance()->init($all, 'parent_id');
$channelOptions = $tree->getTree(0, "<option model='@model_id' value=@id @selected @disabled>@spacer@name</option>", '', $disabledIds);
$secondChannelOptions = $tree->getTree(0, "<option model='@model_id' value=@id disabled>@spacer@name</option>", '', $disabledIds);
$this->view->assign('channelOptions', $channelOptions);
$this->view->assign('secondChannelOptions', $secondChannelOptions);
$this->assignconfig('channelList', $channelList);
$this->assignconfig('spiderRecord', intval($config['spiderrecord'] ?? 0));
$this->assignconfig("flagList", $this->model->getFlagList());
$this->view->assign("flagList", $this->model->getFlagList());
$this->view->assign("statusList", $this->model->getStatusList());
$this->assignconfig('cms', ['archiveseditmode' => $config['archiveseditmode']]);
}
/**
* 查看
*/
public function index()
{
//设置过滤方法
$this->request->filter(['strip_tags']);
if ($this->request->isAjax()) {
$this->relationSearch = true;
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
if (!$this->auth->isSuperAdmin()) {
$this->model->where('channel_id', 'in', $this->channelIds);
}
$total = $this->model
->with('Channel')
->where($where)
->order($sort, $order)
->count();
if (!$this->auth->isSuperAdmin()) {
$this->model->where('channel_id', 'in', $this->channelIds);
}
$list = $this->model
->with(['Channel'])
->where($where)
->order($sort, $order)
->limit($offset, $limit)
->select();
addtion($list, [
[
'field' => 'channel_ids',
'display' => 'channel_ids',
'model' => Channel::class,
],
]);
\app\admin\model\cms\SpiderLog::render($list, 'archives');
$result = array("total" => $total, "rows" => $list);
return json($result);
}
$modelList = \app\admin\model\cms\Modelx::all();
$specialList = \app\admin\model\cms\Special::where('status', 'normal')->select();
$this->view->assign('modelList', $modelList);
$this->view->assign('specialList', $specialList);
return $this->view->fetch();
}
/**
* 副表内容
*/
public function content($model_id = null)
{
$model = \app\admin\model\cms\Modelx::get($model_id);
if (!$model) {
$this->error('未找到对应模型');
}
$fieldsList = \app\admin\model\cms\Fields::where('source', 'model')->where('source_id', $model['id'])->where('type', '<>', 'text')->select();
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
$fields = [];
foreach ($fieldsList as $index => $item) {
$fields[] = "addon." . $item['name'];
}
$filter = $this->request->request('filter');
$op = $this->request->request('op');
if ($filter && $op) {
$filterArr = json_decode($filter, true);
$opArr = json_decode($op, true);
foreach ($filterArr as $index => $item) {
if (in_array("addon." . $index, $fields)) {
$filterArr["addon." . $index] = $item;
$opArr["addon." . $index] = $opArr[$index];
unset($filterArr[$index], $opArr[$index]);
}
}
$this->request->get(['filter' => json_encode($filterArr), 'op' => json_encode($opArr)]);
}
$this->searchFields = "archives.id,archives.title";
$this->relationSearch = true;
$table = $this->model->getTable();
list($where, $sort, $order, $offset, $limit, $page, $alias) = $this->buildparams();
$sort = 'archives.id';
$isSuperAdmin = $this->isSuperAdmin;
$channelIds = $this->channelIds;
// var_dump(['0'=>36,'1'=>80]);exit;
$customWhere = function ($query) use ($isSuperAdmin, $channelIds, $model_id) {
if (!$isSuperAdmin) {
$query->where('archives.channel_id', 'in', $channelIds);
}
if ($model_id) {
$query->where('archives.model_id', $model_id);
if ($model_id == 2){
$res = $query->where('archives.channel_id', 36)->whereOr('archives.channel_id', 80);
// var_dump($res);exit;
}
// if ($model_id == 6){
// $res = $query->where('archives.channel_id', 73);
// // var_dump($res);exit;
// }
}
};
$list = $this->model
->alias($alias)
->alias('archives')
->join('cms_channel channel', 'channel.id=archives.channel_id', 'LEFT')
->join($model['table'] . ' addon', 'addon.id=archives.id', 'LEFT')
->field('archives.*,channel.name as channel_name,addon.id as aid' . ($fields ? ',' . implode(',', $fields) : ''))
->where($customWhere)
->whereNull('deletetime')
->where($where)
->order($sort, $order)
->paginate($limit);
// var_dump($list);exit;
$result = array("total" => $list->total(), "rows" => $list->items());
return json($result);
}
$fields = [];
foreach ($fieldsList as $index => $item) {
$fields[] = ['field' => $item['name'], 'title' => $item['title'], 'type' => $item['type'], 'content' => $item['content_list']];
}
$this->assignconfig('fields', $fields);
$this->view->assign('fieldsList', $fieldsList);
$this->view->assign('model', $model);
$this->assignconfig('model_id', $model_id);
$modelList = \app\admin\model\cms\Modelx::all();
$this->view->assign('modelList', $modelList);
return $this->view->fetch();
}
/**
* 编辑
*
* @param mixed $ids
* @return string
*/
public function edit($ids = null)
{
$row = $this->model->get($ids);
if (!$row) {
$this->error(__('No Results were found'));
}
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
if (!in_array($row[$this->dataLimitField], $adminIds)) {
$this->error(__('You have no permission'));
}
}
if (!$this->isSuperAdmin && !in_array($row['channel_id'], $this->channelIds)) {
$this->error(__('You have no permission'));
}
if ($this->request->isPost()) {
return parent::edit($ids);
}
$channel = Channel::get($row['channel_id']);
if (!$channel) {
$this->error(__('No specified channel found'));
}
$model = \app\admin\model\cms\Modelx::get($channel['model_id']);
if (!$model) {
$this->error(__('No specified model found'));
}
$addon = db($model['table'])->where('id', $row['id'])->find();
if ($addon) {
$row->setData($addon);
}
$disabledIds = [];
$all = collection(Channel::order("weigh desc,id desc")->select())->toArray();
foreach ($all as $k => $v) {
if ($v['type'] == 'link' || $v['model_id'] != $channel['model_id']) {
$disabledIds[] = $v['id'];
}
}
$disabledIds = array_diff($disabledIds, [$row['channel_id']]);
$tree = Tree::instance()->init($all, 'parent_id');
$channelOptions = $tree->getTree(0, "<option model='@model_id' value=@id @selected @disabled>@spacer@name</option>", $row['channel_id'], $disabledIds);
$secondChannelOptions = $tree->getTree(0, "<option model='@model_id' value=@id @selected @disabled>@spacer@name</option>", explode(',', $row['channel_ids']), $disabledIds);
$this->view->assign('channelOptions', $channelOptions);
$this->view->assign('secondChannelOptions', $secondChannelOptions);
$this->view->assign("row", $row);
return $this->view->fetch();
}
/**
* 删除
* @param mixed $ids
*/
public function del($ids = "")
{
parent::del($ids);
}
/**
* 销毁
* @param string $ids
*/
public function destroy($ids = "")
{
\app\admin\model\cms\Archives::event('after_delete', function ($row) {
//删除副表
$channel = Channel::get($row->channel_id);
if ($channel) {
$model = Modelx::get($channel['model_id']);
if ($model) {
db($model['table'])->where("id", $row['id'])->delete();
}
}
});
parent::destroy($ids);
}
/**
* 还原
* @param mixed $ids
*/
public function restore($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$pk = $this->model->getPk();
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
$this->model->where($this->dataLimitField, 'in', $adminIds);
}
if ($ids) {
$this->model->where($pk, 'in', $ids);
}
$config = get_addon_config('cms');
$list = $this->model->onlyTrashed()->select();
if ($list) {
$ids = [];
$refreshIds = [];
foreach ($list as $index => $item) {
if ($item['status'] == 'normal') {
User::score($config['score']['postarchives'], $item['user_id'], '发布文章');
}
$ids[] = $item['id'];
$refreshIds = array_merge([$item['channel_id']], explode(',', $item['channel_ids']));
$refreshIds = array_filter(array_unique($refreshIds));
}
$this->model->where('id', 'in', $ids);
$this->model->restore('1=1');
Channel::refreshItems($refreshIds);
$this->success();
}
$this->error(__('No rows were updated'));
}
/**
* 移动
* @param string $ids
*/
public function move($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
if ($ids) {
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$channel_id = $this->request->post('channel_id');
$pk = $this->model->getPk();
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
$this->model->where($this->dataLimitField, 'in', $adminIds);
}
$this->model->where($pk, 'in', $ids);
$channel = Channel::get($channel_id);
if ($channel && $channel['type'] === 'list') {
$channelNums = \app\admin\model\cms\Archives::
with('channel')
->where('archives.' . $pk, 'in', $ids)
->where('channel_id', '<>', $channel['id'])
->field('channel_id,COUNT(*) AS nums')
->group('channel_id')
->select();
$result = $this->model
->where('model_id', '=', $channel['model_id'])
->where('channel_id', '<>', $channel['id'])
->update(['channel_id' => $channel_id]);
if ($result) {
$this->success();
} else {
$this->error(__('No rows were updated'));
}
} else {
$this->error(__('No rows were updated'));
}
$this->error(__('Parameter %s can not be empty', 'ids'));
}
}
/**
* 复制选择行
* @param string $ids
*/
public function copy($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
if ($ids) {
$pk = $this->model->getPk();
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
$this->model->where($this->dataLimitField, 'in', $adminIds);
}
$archivesList = $this->model->where('id', 'in', $ids)->select();
foreach ($archivesList as $index => $item) {
try {
$model = Modelx::get($item['model_id']);
$addon = \think\Db::name($model['table'])->find($item['id']);
$data = $item->toArray();
$data = array_merge($data, $addon ?? []);
$data['title'] = $data['title'] . "_copy";
$data['status'] = 'hidden';
unset($data['id']);
\app\admin\model\cms\Archives::create($data, true);
} catch (\Exception $e) {
//
}
}
$this->success();
$this->error(__('Parameter %s can not be empty', 'ids'));
}
}
/**
* 加入专题
* @param string $ids
*/
public function special($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
if ($ids) {
$special_id = $this->request->post('special_id');
$pk = $this->model->getPk();
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
$this->model->where($this->dataLimitField, 'in', $adminIds);
}
$special = \app\admin\model\cms\Special::get($special_id);
if ($special) {
$archivesList = $this->model->where($pk, 'in', $ids)->select();
foreach ($archivesList as $index => $item) {
$special_ids = explode(',', $item['special_ids']);
if (!in_array($special['id'], $special_ids)) {
$special_ids[] = $special['id'];
$item->save(['special_ids' => implode(',', array_unique(array_filter($special_ids)))]);
}
}
$this->success();
} else {
$this->error(__('No rows were updated'));
}
}
$this->error(__('Please select at least one row'));
}
/**
* 加入标签
* @param string $ids
*/
public function tags($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
if ($ids) {
$tags = $this->request->post('tags');
$newTagsArr = array_filter(explode(',', $tags));
if ($newTagsArr) {
$pk = $this->model->getPk();
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
$this->model->where($this->dataLimitField, 'in', $adminIds);
}
$archivesList = $this->model->where($pk, 'in', $ids)->select();
foreach ($archivesList as $index => $item) {
$tagsArr = explode(',', $item['tags']);
$tagsArr = array_merge($tagsArr, $newTagsArr);
$item->save(['tags' => implode(',', array_unique(array_filter($tagsArr)))]);
}
$this->success();
} else {
$this->error(__('标签数据不能为空'));
}
}
$this->error(__('Please select at least one row'));
}
/**
* 修改标志
* @param string $ids
*/
public function flag($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
if ($ids) {
$type = $this->request->post('type');
$flag = $this->request->post('flag');
$changeFlagArr = array_filter(explode(',', $flag));
if ($changeFlagArr) {
$pk = $this->model->getPk();
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
$this->model->where($this->dataLimitField, 'in', $adminIds);
}
$archivesList = $this->model->where($pk, 'in', $ids)->select();
foreach ($archivesList as $index => $item) {
$flagArr = explode(',', $item['flag']);
if ($type == 'add') {
$flagArr = array_merge($flagArr, $changeFlagArr);
} else {
$flagArr = array_diff($flagArr, $changeFlagArr);
}
$item->save(['flag' => implode(',', array_unique(array_filter($flagArr)))]);
}
$this->success();
} else {
$this->error(__('标志数据不能为空'));
}
}
$this->error(__('Please select at least one row'));
}
/**
* 获取栏目列表
* @internal
*/
public function get_fields_html()
{
$this->view->engine->layout(false);
$channel_id = $this->request->post('channel_id');
$archives_id = $this->request->post('archives_id');
$channel = Channel::get($channel_id, 'model');
if ($channel) {
$model_id = $channel['model_id'];
$values = [];
if ($archives_id) {
$values = db($channel['model']['table'])->where('id', $archives_id)->find();
//优先从栏目获取模型ID再从文档获取
$archives = \app\admin\model\cms\Archives::get($archives_id);
$model_id = $archives ? $archives['model_id'] : $model_id;
}
$fields = \addons\cms\library\Service::getCustomFields('model', $model_id, $values);
$model = Modelx::get($model_id);
$setting = $model['setting'];
$publishfields = isset($setting['publishfields']) ? $setting['publishfields'] : [];
$titlelist = isset($setting['titlelist']) ? $setting['titlelist'] : [];
$this->view->assign('channel', $channel);
$this->view->assign('fields', $fields);
$this->view->assign('values', $values);
$this->success('', null, ['html' => $this->view->fetch('cms/common/fields'), 'publishfields' => $publishfields, 'titlelist' => $titlelist]);
} else {
$this->error(__('Please select channel'));
}
$this->error(__('Parameter %s can not be empty', 'ids'));
}
/**
* 检测元素是否可用
* @internal
*/
public function check_element_available()
{
$id = $this->request->request('id');
$name = $this->request->request('name');
$value = $this->request->request('value');
$name = substr($name, 4, -1);
if (!$name) {
$this->error(__('Parameter %s can not be empty', 'name'));
}
if ($id) {
$this->model->where('id', '<>', $id);
}
$exist = $this->model->where($name, $value)->find();
if ($exist) {
$this->error(__('The data already exist'));
} else {
$this->success();
}
}
/**
* 搜索建议
* @internal
*/
public function suggestion()
{
$config = get_addon_config('cms');
$q = trim($this->request->request("q"));
$id = trim($this->request->request("id/d"));
$list = [];
if ($config['searchtype'] == 'xunsearch') {
$result = FulltextSearch::search($q, 1, 10);
} else {
$result = $this->model->where("title|keywords|description", "like", "%{$q}%")->where('id', '<>', $id)->limit(10)->order("id", "desc")->select();
foreach ($result as $index => $item) {
$item['image'] = $item['image'] ? $item['image'] : '/assets/addons/cms/img/noimage.png';
$list[] = ['id' => $item['id'], 'url' => $item['fullurl'], 'image' => cdnurl($item['image']), 'title' => $item['title'], 'create_date' => datetime($item['createtime']), 'status' => $item['status'], 'status_text' => $item['status_text'], 'deletetime' => $item['deletetime']];
}
}
return json($list);
}
/**
* Created by PhpStorm.
* Author:Soar
* Time:2023/7/12 11:54
* @return string
* @throws \think\Exception
* @DESC 赛事页面飞手列表
*/
public function league_allplayer()
{
return $this->view->fetch();
}
public function league_wholeplayer()
{
return $this->view->fetch();
}
public function leaguecontestant()
{
return $this->view->fetch();
}
public function contestant()
{
return $this->view->fetch();
}
public function club_match_list()
{
return $this->view->fetch();
}
public function uploadfile()
{
return $this->view->fetch();
}
public function test()
{
return $this->view->fetch();
}
public function course()
{
return $this->view->fetch();
}
public function visualization()
{
return $this->view->fetch();
}
public function league(){
return $this->view->fetch();
}
public function league_course(){
return $this->view->fetch();
}
public function getleagueList()
{
$ClubMatchApply = new ClubMatchApply();
$club = new Club();
// $this->relationSearch = true;
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
// 拦截部分信息修改
if (!empty($this->request->get("op", '', 'trim'))) {
$op = json_decode($this->request->get("op", '', 'trim'), true);
$filter = json_decode($this->request->get("filter", '', 'trim'), true);
$matchId = trim($this->request->request("ids/d"));
// var_dump($op);exit;
if (!empty($filter['club.name'])) {
$club_list = $this->MatchContestantModel
// ->where($where)
->field('club_id')
->where('match_id', 'eq', $matchId)
->group('club_id')
// ->fetchSql(true)
->select();
foreach ($club_list as $v){
$new_arr[] = $v['club_id'];
}
$res = $club->field('id')->where('id','in',$new_arr)->where('name','like','%'.$filter['club.name'].'%')->select();
// var_dump($res);exit;
foreach ($res as $v){
$new_arrs[] = $v['id'];
}
unset($op['club.name']);
unset($filter['club.name']);
$filter['club_id'] = empty($new_arrs) ? 1: $new_arrs;
$op['club_id'] = "in";
$this->request->get(["op" => json_encode($op)])["op"] = json_encode($op);
$this->request->get(["filter" => json_encode($filter)]);
}
}
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
// $res = $this->buildparams();
// var_dump($res);exit;
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$matchId = trim($this->request->request("ids/d"));
// $list = $ClubMatchApply->where($where)
// ->where('match_id', 'eq', $matchId)
// ->order($sort, $order)
// ->paginate($limit);
// var_dump($where);exit;
$sort = 'status,id desc';
$club_list = $this->MatchContestantModel
->with('club')
// ->alias('a')
// ->join('club club','a.club_id = club.id')
->where($where)
->where('match_id', 'eq', $matchId)
->order($sort, $order)
->group('club_id')
// ->fetchSql(true)
->paginate($limit);
// var_dump($club_list);exit;
// var_dump($list->toArray()['data']);exit;
// $lists = $list->toArray()['data'];
foreach ($club_list as &$val){
$val->club = $club->where('id',$val['club_id'])->find();
// if(!empty($res)) $res = $res->toArray();
// $val['clubs'] = $res;
}
// $a = $club_list->items();
// foreach ($a as &$val){
// $val = $val->toArray();
// }
// var_dump($a);exit;
$result = array("total" => $club_list->total(), "rows" => $club_list->items());
return json($result);
}
}
public function getmatch_wholeList()
{
$ClubMatchApply = new ClubMatchApply();
$club = new Club();
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
// 拦截部分信息修改
if (!empty($this->request->get("op", '', 'trim'))) {
$op = json_decode($this->request->get("op", '', 'trim'), true);
$filter = json_decode($this->request->get("filter", '', 'trim'), true);
// var_dump($filter);exit;
if (!empty($filter['user.member_number'])) {
// 获取用户信息
$players = $this->UserModel->where('member_number', $filter['user.member_number'])->find();
// var_dump($players);exit;
if (!empty($players)) {
unset($op['user.member_number']);
unset($filter['user.member_number']);
$filter['players.member_id'] = $players->id;
$op['players.member_id'] = "LIKE";
$this->request->get(["op" => json_encode($op)])["op"] = json_encode($op);
$this->request->get(["filter" => json_encode($filter)]);
}
}
}
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$ids = trim($this->request->request("ids/d"));
// var_dump($ids);exit;
$matchId = $this->MatchContestantModel
->field('match_id')->where('match_id', 'eq', $ids)->where('club_status',null)->find();
// var_dump($matchId);exit;
// $list = $ClubMatchApply->where($where)
// ->where('match_id', 'eq', $matchId)
// ->order($sort, $order)
// ->paginate($limit);
$list = $this->MatchContestantModel
->with('players')
->where($where)
->where('match_id', 'eq', $matchId['match_id'])
->where('club_status',null)
->order($sort, $order)
// ->distinct(true)
->paginate($limit);
// var_dump($list->toArray()['data']);exit;
// $lists = $list->toArray()['data'];
foreach ($list as &$val){
if(empty($val->players->member_id)){
continue;
}
if(strpos($val->players->player_pic, 'aliyuncs') === false){
// $val->players->player_pic = 'https://www.fpvone.cn'.$val->players->player_pic;
}
$val->user = $this->UserModel->find($val->players->member_id);
$val->club = $club->where('id',$val['club_id'])->find();
}
$result = array("total" => $list->total(), "rows" => $list->items());
// var_dump($result);exit;
return json($result);
}
}
public function getmatch_idsList()
{
$ClubMatchApply = new ClubMatchApply();
$club = new Club();
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
// 拦截部分信息修改
if (!empty($this->request->get("op", '', 'trim'))) {
$op = json_decode($this->request->get("op", '', 'trim'), true);
$filter = json_decode($this->request->get("filter", '', 'trim'), true);
// var_dump($filter);exit;
if (!empty($filter['user.member_number'])) {
// 获取用户信息
$players = $this->UserModel->where('member_number', $filter['user.member_number'])->find();
// var_dump($players);exit;
if (!empty($players)) {
unset($op['user.member_number']);
unset($filter['user.member_number']);
$filter['players.member_id'] = $players->id;
$op['players.member_id'] = "LIKE";
$this->request->get(["op" => json_encode($op)])["op"] = json_encode($op);
$this->request->get(["filter" => json_encode($filter)]);
}
}
}
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$ids = trim($this->request->request("ids/d"));
// var_dump($ids);exit;
$matchId = $this->MatchContestantModel
->field('match_id,club_id')->where('id', 'eq', $ids)->find();
// var_dump($matchId['club_id']);exit;
// $list = $ClubMatchApply->where($where)
// ->where('match_id', 'eq', $matchId)
// ->order($sort, $order)
// ->paginate($limit);
// var_dump($where);exit;
$list = $this->MatchContestantModel
->with('player')
->where($where)
->where('match_id', 'eq', $matchId['match_id'])
->where('club_id','eq',$matchId['club_id'])
->where('club_status',null)
->order($sort, $order)
// ->distinct(true)
->paginate($limit);
// var_dump($list->toArray()['data']);exit;
// $lists = $list->toArray()['data'];
foreach ($list as &$val){
if(empty($val->players->member_id)){
continue;
}
$val->user = $this->UserModel->find($val->players->member_id);
$val->club = $club->where('id',$val['club_id'])->find();
}
$result = array("total" => $list->total(), "rows" => $list->items());
// var_dump($result);exit;
return json($result);
}
}
public function getplayersList()
{
$ClubMatchApply = new ClubMatchApply();
$club = new Club();
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
// 拦截部分信息修改
if (!empty($this->request->get("op", '', 'trim'))) {
$op = json_decode($this->request->get("op", '', 'trim'), true);
$filter = json_decode($this->request->get("filter", '', 'trim'), true);
// var_dump($filter);exit;
if (!empty($filter['user.member_number'])) {
// 获取用户信息
$players = $this->UserModel->where('member_number', $filter['user.member_number'])->find();
// var_dump($players);exit;
if (!empty($players)) {
unset($op['user.member_number']);
unset($filter['user.member_number']);
$filter['players.member_id'] = $players->id;
$op['players.member_id'] = "LIKE";
$this->request->get(["op" => json_encode($op)])["op"] = json_encode($op);
$this->request->get(["filter" => json_encode($filter)]);
}
}
}
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
// var_dump($where);exit;
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$matchId = trim($this->request->request("ids/d"));
// var_dump($where);exit;
// $list = $ClubMatchApply->where($where)
// ->where('match_id', 'eq', $matchId)
// ->order($sort, $order)
// ->paginate($limit);
$list = $this->MatchContestantModel
->with('players')
->where($where)
->where('match_id', 'eq', $matchId)
->order($sort, $order)
// ->distinct(true)
->paginate($limit);
// var_dump($list->toArray()['data']);exit;
// $lists = $list->toArray()['data'];
foreach ($list as &$val){
if(empty($val->players->member_id)){
continue;
}
// var_dump($val['club_id']);exit;
// $club->where('id',$val->club_id);
$val->user = $this->UserModel->find($val->players->member_id);
$val->club = $club->where('id',$val['club_id'])->find();
// if(!empty($res)) $res = $res->toArray();
// $val['clubs'] = $res;
}
$result = array("total" => $list->total(), "rows" => $list->items());
// var_dump($result);exit;
return json($result);
}
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace app\admin\controller\cms;
use app\common\controller\Backend;
/**
* 自动链接管理
*
* @icon fa fa-circle-o
*/
class Autolink extends Backend
{
/**
* Autolink模型对象
* @var \app\admin\model\cms\Autolink
*/
protected $model = null;
protected $searchFields = 'id,title,url';
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\cms\Autolink;
$this->view->assign("targetList", $this->model->getTargetList());
$this->view->assign("statusList", $this->model->getStatusList());
}
public function import()
{
parent::import();
}
}

View File

@ -0,0 +1,104 @@
<?php
namespace app\admin\controller\cms;
use app\common\controller\Backend;
/**
* 区块表
*
* @icon fa fa-th-large
*/
class Block extends Backend
{
/**
* Block模型对象
*/
protected $model = null;
protected $searchFields = 'id,name,type,title,url';
protected $noNeedRight = ['selectpage_type'];
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\cms\Block;
$this->view->assign("statusList", $this->model->getStatusList());
$this->view->assign("nameList", $this->model->getNameList());
}
public function index()
{
$typeArr = \app\admin\model\cms\Block::distinct('type')->column('type');
$this->view->assign('typeList', $typeArr);
$this->assignconfig('typeList', $typeArr);
return parent::index();
}
public function selectpage_type()
{
$list = [];
$word = (array)$this->request->request("q_word/a");
$field = $this->request->request('showField');
$keyValue = $this->request->request('keyValue');
if (!$keyValue) {
if (array_filter($word)) {
foreach ($word as $k => $v) {
$list[] = ['id' => $v, $field => $v];
}
}
$typeArr = \app\admin\model\cms\Block::column('type');
$typeArr = array_unique($typeArr);
foreach ($typeArr as $index => $item) {
$list[] = ['id' => $item, $field => $item];
}
} else {
$list[] = ['id' => $keyValue, $field => $keyValue];
}
return json(['total' => count($list), 'list' => $list]);
}
/**
* 添加
*/
public function add()
{
if ($this->request->isPost()) {
$row = $this->request->post("row/a", []);
if (isset($row['parsetpl']) && $row['parsetpl']) {
$this->token();
}
}
$values = [];
$fields = \addons\cms\library\Service::getCustomFields('block', 0, $values);
$this->view->assign('fields', $fields);
$this->view->assign('values', $values);
return parent::add();
}
public function edit($ids = null)
{
if ($this->request->isPost()) {
$row = $this->request->post("row/a", []);
if (isset($row['parsetpl']) && $row['parsetpl']) {
$this->token();
}
}
$values = \app\admin\model\cms\Block::get($ids);
if (!$values) {
$this->error(__('No Results were found'));
}
$values = $values->toArray();
$fields = \addons\cms\library\Service::getCustomFields('block', 0, $values);
$this->view->assign('fields', $fields);
$this->view->assign('values', $values);
return parent::edit($ids);
}
public function import()
{
return parent::import();
}
}

View File

@ -0,0 +1,111 @@
<?php
namespace app\admin\controller\cms;
use addons\cms\library\Service;
use app\admin\model\cms\Channel;
use app\admin\model\cms\Modelx;
use app\common\controller\Backend;
use app\common\model\User;
use fast\Tree;
use think\Db;
use think\db\Query;
/**
* 标签生成器
*
* @icon fa fa-file-text-o
*/
class Builder extends Backend
{
protected $model = null;
protected $noNeedRight = [];
protected $channelIds = [];
protected $isSuperAdmin = false;
protected $searchFields = 'id,title';
/**
* 查看
*/
public function index()
{
$tree = Tree::instance();
$tree->init(collection(Channel::where('status', 'normal')->order('weigh desc,id desc')->select())->toArray(), 'parent_id');
$channelList = $tree->getTreeList($tree->getTreeArray(0), 'name');
$modelList = \app\admin\model\cms\Modelx::order('id asc')->select();
$prefix = \think\Config::get('database.prefix');
$fieldList = Service::getTableFields("{$prefix}cms_archives");
$channelFieldList = Service::getTableFields("{$prefix}cms_channel");
$userFieldList = Service::getTableFields("{$prefix}user");
$specialFieldList = Service::getTableFields("{$prefix}cms_special");
$pageFieldList = Service::getTableFields("{$prefix}cms_page");
$pageTypeList = \app\admin\model\cms\Page::distinct('type')->column("type");
$blockTypeList = \app\admin\model\cms\Block::distinct('type')->column("type");
$blockNameList = \app\admin\model\cms\Block::distinct('name')->column("name");
$blockFieldList = Service::getTableFields("{$prefix}cms_block");
$diyformList = \app\admin\model\cms\Diyform::all();
$diyformFieldList = [];
foreach ($diyformList as $index => $item) {
$diyformFieldList[$item['id']] = Service::getTableFields($prefix . $item['table']);
}
$this->view->assign("configList", get_addon_fullconfig("cms"));
$this->view->assign("fieldList", $fieldList);
$this->view->assign("channelFieldList", $channelFieldList);
$this->view->assign("pageFieldList", $pageFieldList);
$this->view->assign("pageTypeList", $pageTypeList);
$this->view->assign("specialFieldList", $specialFieldList);
$this->view->assign("blockFieldList", $blockFieldList);
$this->view->assign("blockTypeList", $blockTypeList);
$this->view->assign("blockNameList", $blockNameList);
$this->view->assign("userFieldList", $userFieldList);
$this->view->assign("diyformList", $diyformList);
$this->view->assign("diyformFieldList", $diyformFieldList);
$this->view->assign("channelList", $channelList);
$this->view->assign("modelList", $modelList);
return $this->view->fetch();
}
/**
* 解析模板标签
* @return string
*/
public function parse()
{
$this->view->engine->layout(false);
$tag = $this->request->post('tag');
if (!config('app_debug')) {
$this->error("只在开发模式下才可渲染");
}
$html = '';
try {
$html = $this->view->display($tag);
} catch (\Exception $e) {
$this->error("模板标签解析错误:" . $e->getMessage());
}
$this->success("", null, $html);
return $this->view->fetch();
}
/**
* 获取自定义字段列表HTML
* @internal
*/
public function get_model_fields()
{
$this->view->engine->layout(false);
$id = $this->request->post('id/d');
$model = Modelx::get($id);
if ($model) {
$fields = \app\admin\model\cms\Fields::where('source', 'model')->where('source_id', $model['id'])->column("id,name,title");
$this->success('', null, ['fields' => array_values($fields)]);
} else {
$this->error(__('Please select model'));
}
$this->error(__('Parameter %s can not be empty', 'ids'));
}
}

View File

@ -0,0 +1,316 @@
<?php
namespace app\admin\controller\cms;
use addons\vip\library\Service;
use app\admin\model\Admin;
use app\admin\model\AuthGroupAccess;
use app\admin\model\cms\ChannelAdmin;
use app\common\controller\Backend;
use app\admin\model\cms\Channel as ChannelModel;
use fast\Tree;
use think\Exception;
/**
* 栏目表
*
* @icon fa fa-list
*/
class Channel extends Backend
{
protected $channelList = [];
protected $modelList = [];
protected $multiFields = ['weigh', 'status', 'iscontribute', 'isnav'];
/**
* Channel模型对象
*/
protected $model = null;
protected $noNeedRight = ['get_fields_html', 'check_element_available'];
/**
* @var Tree
*/
protected $tree = null;
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\cms\Channel;
$this->tree = Tree::instance();
$this->tree->init(collection($this->model->order('weigh desc,id desc')->select())->toArray(), 'parent_id');
$this->channelList = $this->tree->getTreeList($this->tree->getTreeArray(0), 'name');
$this->modelList = \app\admin\model\cms\Modelx::order('id asc')->select();
$config = get_addon_config('cms');
$this->assignconfig('spiderRecord', intval($config['spiderrecord']?? 0));
$this->view->assign("modelList", $this->modelList);
$this->view->assign("channelList", $this->channelList);
$this->view->assign("typeList", ChannelModel::getTypeList());
$this->assignconfig("flagList", $this->model->getFlagList());
$this->view->assign("flagList", $this->model->getFlagList());
$this->view->assign("statusList", ChannelModel::getStatusList());
$this->view->assign("listtypeList", ChannelModel::getListtypeList());
$this->view->assign("vipList", get_addon_info('vip') ? Service::getVipList() : []);
}
/**
* 查看
*/
public function index()
{
//设置过滤方法
$this->request->filter(['strip_tags']);
if ($this->request->isAjax()) {
$search = $this->request->request("search");
$model_id = $this->request->request("model_id");
//构造父类select列表选项数据
$list = [];
if ($search) {
foreach ($this->channelList as $k => $v) {
if (stripos($v['name'], $search) !== false || stripos($v['nickname'], $search) !== false) {
$list[] = $v;
}
}
} else {
$list = $this->channelList;
}
foreach ($list as $index => $item) {
if ($model_id && $model_id != $item['model_id']) {
unset($list[$index]);
}
}
$list = array_values($list);
$modelNameArr = [];
foreach ($this->modelList as $k => $v) {
$modelNameArr[$v['id']] = $v['name'];
}
foreach ($list as $k => &$v) {
$v['pid'] = $v['parent_id'];
$v['model_name'] = $v['model_id'] && isset($modelNameArr[$v['model_id']]) ? $modelNameArr[$v['model_id']] : __('None');
}
$total = count($list);
\app\admin\model\cms\SpiderLog::render($list, 'channel');
$result = array("total" => $total, "rows" => $list);
return json($result);
}
return $this->view->fetch();
}
/**
* 添加
*/
public function add()
{
if ($this->request->isPost()) {
$params = $this->request->post("row/a");
if ($params) {
if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
$params[$this->dataLimitField] = $this->auth->id;
}
try {
//是否采用模型验证
if ($this->modelValidate) {
$name = basename(str_replace('\\', '/', get_class($this->model)));
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : true) : $this->modelValidate;
$this->model->validate($validate);
}
$nameArr = array_filter(explode("\n", str_replace("\r\n", "\n", $params['name'])));
if (count($nameArr) > 1) {
foreach ($nameArr as $index => $item) {
$itemArr = array_filter(explode('|', $item));
$params['name'] = $itemArr[0];
$params['diyname'] = isset($itemArr[1]) ? $itemArr[1] : '';
$result = $this->model->allowField(true)->isUpdate(false)->data($params)->save();
}
} else {
$result = $this->model->allowField(true)->save($params);
}
if ($result !== false) {
$this->success();
} else {
$this->error($this->model->getError());
}
} catch (\think\exception\PDOException $e) {
$this->error($e->getMessage());
} catch (\think\Exception $e) {
$this->error($e->getMessage());
}
}
$this->error(__('Parameter %s can not be empty', ''));
}
$values = [];
$fields = \addons\cms\library\Service::getCustomFields('channel', 0, $values);
$this->view->assign('fields', $fields);
$this->view->assign('values', $values);
return $this->view->fetch();
}
/**
* 编辑
*/
public function edit($ids = null)
{
$channel = \app\admin\model\cms\Channel::get($ids);
if (!$channel) {
$this->error(__('No Results were found'));
}
$linkdata = $channel['linkdata'];
$channel = $channel->toArray();
$fields = \addons\cms\library\Service::getCustomFields('channel', 0, $channel);
$childrenIds = $this->tree->getChildrenIds($channel['id'], true);
$hasArchives = \app\admin\model\cms\Archives::withTrashed()->where('channel_id', $channel['id'])->whereOr('FIND_IN_SET(:id, `channel_ids`)', ['id' => $channel['id']])->count();
$this->view->assign('hasArchives', $hasArchives);
$this->view->assign('fields', $fields);
$this->view->assign('values', $channel);
$this->view->assign('childrenIds', $childrenIds);
$this->assignconfig('linkdata', $linkdata);
return parent::edit($ids);
}
/**
* 栏目授权
*/
public function admin()
{
$act = $this->request->param('act');
$ids = $this->request->param('ids');
if ($act && $ids) {
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
if ($act == 'remove') {
ChannelAdmin::where('admin_id', $ids)->delete();
$this->success('删除成功!');
} elseif ($act == 'authorization') {
$selected = ChannelAdmin::getAdminChanneIds($ids);
$all = collection(ChannelModel::order("weigh desc,id desc")->select())->toArray();
foreach ($all as $k => $v) {
$state = ['opened' => true];
if ($v['type'] == 'link') {
$disabledIds[] = $v['id'];
}
if ($v['type'] == 'link') {
$state['checkbox_disabled'] = true;
}
$state['selected'] = in_array($v['id'], $selected);
$channelList[] = [
'id' => $v['id'],
'parent' => $v['parent_id'] ? $v['parent_id'] : '#',
'text' => __($v['name']),
'type' => $v['type'],
'state' => $state
];
}
$this->success('成功', '', $channelList);
} elseif ($act == 'save') {
\think\Db::startTrans();
try {
ChannelAdmin::where('admin_id', $ids)->delete();
$channelIds = explode(",", $this->request->post("ids"));
if ($channelIds) {
$listChannelIds = ChannelModel::where('type', 'list')->column('id');
$channelIds = array_intersect($channelIds, $listChannelIds);
$data = [];
foreach ($channelIds as $key => $item) {
$data[] = ['admin_id' => $ids, 'channel_id' => $item];
}
$model = new ChannelAdmin();
$model->saveAll($data, true);
}
\think\Db::commit();
} catch (Exception $e) {
\think\Db::rollback();
$this->error($e->getMessage());
}
$this->success("保存成功!");
}
}
if ($this->request->isAjax()) {
$list = \think\Db::name("cms_channel_admin")
->group("admin_id")
->field("COUNT(*) as channels,admin_id")
->select();
$adminChannelList = [];
foreach ($list as $index => $item) {
$adminChannelList[$item['admin_id']] = $item['channels'];
}
$superAdminIds = AuthGroupAccess::where('group_id', 1)->column('uid');
$adminList = Admin::order('id', 'desc')->field('id,username,nickname')->select();
foreach ($adminList as $index => $item) {
$item->channels = isset($adminChannelList[$item['id']]) ? $adminChannelList[$item['id']] : 0;
$item->superadmin = in_array($item['id'], $superAdminIds);
}
$total = count($adminList);
$result = array("total" => $total, "rows" => $adminList);
return json($result);
}
$config = get_addon_config('cms');
$this->view->assign("isChannelAllocate", $config['channelallocate']);
return $this->view->fetch();
}
/**
* Selectpage搜索
*
* @internal
*/
public function selectpage()
{
return parent::selectpage();
}
/**
* 检测元素是否可用
* @internal
*/
public function check_element_available()
{
$id = $this->request->request('id');
$name = $this->request->request('name');
$value = $this->request->request('value');
$name = substr($name, 4, -1);
if (!$name) {
$this->error(__('Parameter %s can not be empty', 'name'));
}
if ($name == 'diyname') {
if ($id) {
$this->model->where('id', '<>', $id);
}
$exist = $this->model->where($name, $value)->find();
if ($exist) {
$this->error(__('The data already exist'));
} else {
$this->success();
}
} elseif ($name == 'name') {
$nameArr = array_filter(explode("\n", str_replace("\r\n", "\n", $value)));
if (count($nameArr) > 1) {
foreach ($nameArr as $index => $item) {
$itemArr = array_filter(explode('|', $item));
if (!isset($itemArr[1])) {
$this->error('格式:分类名称|自定义名称');
}
$exist = \app\admin\model\cms\Channel::getByDiyname($itemArr[1]);
if ($exist) {
$this->error('自定义名称[' . $itemArr[1] . ']已经存在');
}
}
$this->success();
} else {
$this->success();
}
}
}
}

View File

@ -0,0 +1,138 @@
<?php
namespace app\admin\controller\cms;
use app\common\controller\Backend;
use app\common\model\User;
use think\Db;
use think\exception\PDOException;
/**
* 评论管理
*
* @icon fa fa-comment
*/
class Comment extends Backend
{
/**
* Comment模型对象
*/
protected $model = null;
protected $searchFields = 'id,aid,content';
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\cms\Comment;
$this->view->assign("typeList", $this->model->getTypeList());
$this->view->assign("statusList", $this->model->getStatusList());
}
/**
* 查看
*/
public function index()
{
$this->relationSearch = true;
//设置过滤方法
$this->request->filter(['strip_tags']);
if ($this->request->isAjax()) {
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$total = $this->model
->where($where)
->order($sort, $order)
->count();
$list = $this->model
->where($where)
->order($sort, $order)
->limit($offset, $limit)
->select();
foreach ($list as $index => $item) {
$item->user->visible(['id', 'username', 'nickname', 'avatar']);
$item->source = $item->source;
}
$list = collection($list)->toArray();
$result = array("total" => $total, "rows" => $list);
return json($result);
}
$this->assignconfig("typeList", $this->model->getTypeList());
return $this->view->fetch();
}
public function recyclebin()
{
//设置过滤方法
$this->request->filter(['strip_tags']);
if ($this->request->isAjax()) {
$this->relationSearch = true;
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$total = $this->model
->onlyTrashed()
->with(['archives', 'spage', 'user'])
->where($where)
->order($sort, $order)
->count();
$list = $this->model
->onlyTrashed()
->with(['archives', 'spage', 'user'])
->where($where)
->order($sort, $order)
->limit($offset, $limit)
->select();
foreach ($list as $index => $item) {
$item->user->visible(['id', 'username', 'nickname', 'avatar']);
$type = $item['type'] == 'page' ? 'spage' : $item['type'];
$item->url = $item->{$type} ? $item->{$type}->url : 'javascript:';
}
$list = collection($list)->toArray();
$result = array("total" => $total, "rows" => $list);
return json($result);
}
return $this->view->fetch();
}
public function restore($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$pk = $this->model->getPk();
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
$this->model->where($this->dataLimitField, 'in', $adminIds);
}
if ($ids) {
$this->model->where($pk, 'in', $ids);
}
$config = get_addon_config('cms');
$list = $this->model->onlyTrashed()->select();
if ($list) {
$ids = [];
foreach ($list as $index => $item) {
if ($item['status'] == 'normal') {
User::score($config['score']['postcomment'], $item['user_id'], '发表评论');
}
$ids[] = $item['id'];
}
$this->model->where('id', 'in', $ids);
$this->model->restore('1=1');
foreach ($list as $index => $item) {
\app\admin\model\cms\Comment::refreshSourceComments($item['id']);
}
$this->success();
}
$this->error(__('No rows were updated'));
}
}

View File

@ -0,0 +1,70 @@
<?php
namespace app\admin\controller\cms;
use app\admin\model\Admin;
use app\admin\model\AuthGroupAccess;
use app\admin\model\cms\ChannelAdmin;
use app\common\controller\Backend;
use app\admin\model\cms\Channel as ChannelModel;
use fast\Tree;
use think\addons\Service;
use think\Exception;
/**
* 系统配置
*
* @icon fa fa-gears
*/
class Config extends Backend
{
/**
* 查看
*/
public function index()
{
$name = 'cms';
$info = get_addon_info($name);
$config = get_addon_fullconfig($name);
if (!$info) {
$this->error(__('No Results were found'));
}
if ($this->request->isPost()) {
$params = $this->request->post("row/a", [], 'trim');
if ($params) {
foreach ($config as $k => &$v) {
if (isset($params[$v['name']])) {
if ($v['type'] == 'array') {
$params[$v['name']] = is_array($params[$v['name']]) ? $params[$v['name']] : (array)json_decode($params[$v['name']], true);
$value = $params[$v['name']];
} else {
$value = is_array($params[$v['name']]) ? implode(',', $params[$v['name']]) : $params[$v['name']];
}
$v['value'] = $value;
}
}
try {
//更新配置文件
set_addon_fullconfig($name, $config);
Service::refresh();
$this->success();
} catch (Exception $e) {
$this->error(__($e->getMessage()));
}
}
$this->error(__('Parameter %s can not be empty', ''));
}
$tips = [];
foreach ($config as $index => &$item) {
if ($item['name'] == '__tips__') {
$tips = $item;
unset($config[$index]);
}
}
$this->view->assign("addon", ['info' => $info, 'config' => $config, 'tips' => $tips]);
$configFile = ADDON_PATH . $name . DS . 'config.html';
$viewFile = is_file($configFile) ? $configFile : '';
return $this->view->fetch($viewFile);
}
}

View File

@ -0,0 +1,174 @@
<?php
namespace app\admin\controller\cms;
use addons\cms\library\Service;
use app\common\controller\Backend;
/**
* 自定义表单数据表
*
* @icon fa fa-circle-o
*/
class Diydata extends Backend
{
/**
* 自定义表单模型对象
*/
protected $diyform = null;
/**
* 定义表单数据表模型
* @var null
*/
protected $model = null;
public function _initialize()
{
parent::_initialize();
$diyform_id = $this->request->param('diyform_id');
$this->diyform = \app\admin\model\cms\Diyform::get($diyform_id);
if (!$this->diyform) {
$this->error('未找到对应自定义表单');
}
$this->model = new \addons\cms\model\Diydata([], $this->diyform);
$this->assignconfig('diyform_id', $diyform_id);
}
/**
* 查看
*/
public function index()
{
$fieldsList = \app\admin\model\cms\Fields::where('source', 'diyform')->where('source_id', $this->diyform['id'])->where('type', '<>', 'text')->select();
$fields = [];
foreach ($fieldsList as $index => $item) {
$fields[] = ['field' => $item['name'], 'title' => $item['title'], 'type' => $item['type'], 'content' => $item['content_list']];
}
$this->assignconfig('fields', $fields);
$where = [];
$config = get_addon_config('cms');
if ($config['diyformdatalimit'] != 'all') {
$this->dataLimit = $config['diyformdatalimit'];
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
$where[$this->dataLimitField] = ['in', $adminIds];
}
$this->dataLimit = false;
}
$diyformList = \app\admin\model\cms\Diyform::where($where)->select();
$this->view->assign('diyform', $this->diyform);
$this->view->assign('diyformList', $diyformList);
return parent::index();
}
/**
* 添加
*/
public function add()
{
$this->assignFields();
if ($this->request->isPost()) {
$params = $this->request->post("row/a");
if ($params) {
if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
$params[$this->dataLimitField] = $this->auth->id;
}
try {
$result = $this->model->save($params);
if ($result !== false) {
$this->success();
} else {
$this->error($this->model->getError());
}
} catch (\think\exception\PDOException $e) {
$this->error($e->getMessage());
} catch (\think\Exception $e) {
$this->error($e->getMessage());
}
}
$this->error(__('Parameter %s can not be empty', ''));
}
return $this->view->fetch();
}
/**
* 编辑
*/
public function edit($ids = null)
{
$row = $this->model->where('id', $ids)->find();
if (!$row) {
$this->error(__('No Results were found'));
}
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
if (!in_array($row[$this->dataLimitField], $adminIds)) {
$this->error(__('You have no permission'));
}
}
if ($this->request->isPost()) {
$params = $this->request->post("row/a");
if ($params) {
try {
$result = $this->model->update($params, ['id' => $ids]);
if ($result !== false) {
$this->success();
} else {
$this->error($row->getError());
}
} catch (\think\exception\PDOException $e) {
$this->error($e->getMessage());
} catch (\think\Exception $e) {
$this->error($e->getMessage());
}
}
$this->error(__('Parameter %s can not be empty', ''));
}
$this->assignFields($ids);
$this->view->assign("row", $row);
return $this->view->fetch();
}
/**
* 删除
*/
public function del($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
if ($ids) {
$pk = $this->model->getPk();
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
$count = $this->model->where($this->dataLimitField, 'in', $adminIds);
}
$count = $this->model->where($pk, 'in', $ids)->delete();
if ($count) {
$this->success();
} else {
$this->error(__('No rows were deleted'));
}
}
$this->error(__('Parameter %s can not be empty', 'ids'));
}
private function assignFields($diydata_id = 0)
{
$values = [];
if ($diydata_id) {
$values = db($this->diyform['table'])->where('id', $diydata_id)->find();
}
$fields = Service::getCustomFields('diyform', $this->diyform['id'], $values);
$this->view->assign('fields', $fields);
$this->view->assign('values', $values);
}
}

View File

@ -0,0 +1,117 @@
<?php
namespace app\admin\controller\cms;
use app\common\controller\Backend;
/**
* 自定义表单表
*
* @icon fa fa-list
*/
class Diyform extends Backend
{
/**
* Model模型对象
*/
protected $model = null;
protected $searchFields = 'id,name,title,table';
protected $noNeedRight = ['check_element_available'];
public function _initialize()
{
parent::_initialize();
$config = get_addon_config('cms');
if ($config['diyformdatalimit'] != 'all') {
$this->dataLimit = $config['diyformdatalimit'];
}
$this->assignconfig('spiderRecord', intval($config['spiderrecord']?? 0));
$this->model = new \app\admin\model\cms\Diyform;
$this->view->assign("statusList", $this->model->getStatusList());
}
/**
* 查看
*/
public function index()
{
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$list = $this->model
->where($where)
->order($sort, $order)
->paginate($limit);
\app\admin\model\cms\SpiderLog::render($list, 'diyform');
$result = array("total" => $list->total(), "rows" => $list->items());
return json($result);
}
return $this->view->fetch();
}
public function add()
{
if ($this->request->isAjax()){
$params = $this->request->post('row/a');
if ($params['notice'] == 1 && empty($params['notice_mobile'])){
$this->error("通知人手机号不能为空!");
}
parent::add();
}
return $this->view->fetch();
}
public function edit($ids = null)
{
if ($this->request->isAjax()){
$params = $this->request->post('row/a');
if ($params['notice'] == 1 && empty($params['notice_mobile'])){
$this->error("通知人手机号不能为空!");
}
}
parent::edit($ids);
return $this->view->fetch();
}
/**
* 检测元素是否可用
* @internal
*/
public function check_element_available()
{
$id = $this->request->request('id');
$name = $this->request->request('name');
$value = $this->request->request('value');
$name = substr($name, 4, -1);
if (!$name) {
$this->error(__('Parameter %s can not be empty', 'name'));
}
if ($id) {
$this->model->where('id', '<>', $id);
}
$exist = $this->model->where($name, $value)->find();
if ($exist) {
$this->error(__('The data already exist'));
} else {
$this->success();
}
}
}

View File

@ -0,0 +1,403 @@
<?php
namespace app\admin\controller\cms;
use addons\cms\library\Service;
use app\common\controller\Backend;
use app\common\model\Config;
/**
* 模型字段表
*
* @icon fa fa-circle-o
*/
class Fields extends Backend
{
/**
* Fields模型对象
*/
protected $model = null;
protected $modelValidate = true;
protected $modelSceneValidate = true;
protected $noNeedRight = ['rulelist'];
protected $multiFields = 'isfilter,iscontribute';
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\cms\Fields;
$this->view->assign("statusList", $this->model->getStatusList());
$this->view->assign('typeList', Config::getTypeList());
$this->view->assign('regexList', Config::getRegexList());
$this->assignconfig('withoutModelList', ['channel', 'page', 'special', 'block']);
$this->assignconfig('contributeFields', \app\admin\model\cms\Fields::getContributeFields());
$this->assignconfig('publishFields', \app\admin\model\cms\Fields::getPublishFields());
}
/**
* 查看
*/
public function index()
{
$source = $this->request->param('source', '');
$source_id = $this->request->param('source_id', 0);
$condition = ['source' => $source, 'source_id' => $source_id];
$prefix = \think\Config::get('database.prefix');
//设置过滤方法
$this->request->filter(['strip_tags']);
if ($this->request->isAjax()) {
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$total = $this->model
->where($condition)
->where($where)
->order($sort, $order)
->count();
$list = $this->model
->where($condition)
->where($where)
->order($sort, $order)
->limit($offset, $limit)
->select();
if ($source == 'model') {
$fieldList = Service::getTableFields("{$prefix}cms_archives");
$model = \app\admin\model\cms\Modelx::get($source_id);
if (!$model) {
$this->error("模型未找到");
}
$setting = $model->setting;
$titles = isset($setting['titlelist']) ? $setting['titlelist'] : [];
$list = collection($list)->toArray();
array_unshift($fieldList, ['name' => 'content', 'title' => __('Content'), 'type' => 'text']);
foreach ($fieldList as $field) {
$item = [
'id' => $field['name'],
'state' => false,
'source_id' => $source_id,
'source' => '-',
'name' => $field['name'],
'title' => $field['title'] . (isset($titles[$field['name']]) && $titles[$field['name']] != $field['title'] ? "({$titles[$field['name']]})" : ''),
'type' => $field['type'],
'issystem' => true,
'isfilter' => isset($setting['filterfields']) && is_array($setting['filterfields']) && in_array($field['name'], $setting['filterfields']) ? 1 : 0,
'iscontribute' => isset($setting['contributefields']) && is_array($setting['contributefields']) && in_array($field['name'], $setting['contributefields']) ? 1 : 0,
'ispublish' => isset($setting['publishfields']) && is_array($setting['publishfields']) && in_array($field['name'], $setting['publishfields']) ? 1 : 0,
'isorder' => isset($setting['orderfields']) && is_array($setting['orderfields']) && in_array($field['name'], $setting['orderfields']) ? 1 : 0,
'status' => 'normal',
'createtime' => 0,
'updatetime' => 0
];
$list[] = $item;
}
} elseif (in_array($source, ['channel', 'page', 'special', 'block'])) {
$fieldList = Service::getTableFields("{$prefix}cms_" . $source);
$fields = [];
foreach ($list as $index => $item) {
$fields[] = $item['name'];
}
foreach ($fieldList as $index => $field) {
if (in_array($field['name'], $fields)) {
continue;
}
$item = [
'id' => $field['name'],
'state' => false,
'source_id' => $source_id,
'source' => '-',
'name' => $field['name'],
'title' => $field['title'],
'type' => $field['type'],
'issystem' => true,
'isfilter' => 0,
'iscontribute' => 0,
'ispublish' => 0,
'isorder' => 0,
'status' => 'normal',
'createtime' => 0,
'updatetime' => 0
];
$list[] = $item;
}
} elseif ($source == 'diyform') {
$diyform = \app\admin\model\cms\Diyform::get($source_id);
if (!$diyform) {
$this->error("表单未找到");
}
$setting = $diyform->setting;
$titles = isset($setting['titlelist']) ? $setting['titlelist'] : [];
$fieldList = [
['name' => 'id', 'title' => 'ID', 'type' => 'int'],
['name' => 'memo', 'title' => __('Memo'), 'type' => 'string'],
['name' => 'createtime', 'title' => __('Createtime'), 'type' => 'int'],
['name' => 'updatetime', 'title' => __('Updatetime'), 'type' => 'int'],
['name' => 'status', 'title' => __('Status'), 'type' => 'enum'],
];
foreach ($fieldList as $index => $field) {
$item = [
'id' => $field['name'],
'state' => false,
'source_id' => $source_id,
'source' => '-',
'name' => $field['name'],
'title' => $field['title'] . (isset($titles[$field['name']]) && $titles[$field['name']] != $field['title'] ? "({$titles[$field['name']]})" : ''),
'type' => $field['type'],
'issystem' => true,
'isfilter' => isset($setting['filterfields']) && is_array($setting['filterfields']) && in_array($field['name'], $setting['filterfields']) ? 1 : 0,
'iscontribute' => 0,
'ispublish' => 0,
'isorder' => isset($setting['orderfields']) && is_array($setting['orderfields']) && in_array($field['name'], $setting['orderfields']) ? 1 : 0,
'status' => 'normal',
'createtime' => 0,
'updatetime' => 0
];
$list[] = $item;
}
}
$result = array("total" => $total, "rows" => $list);
return json($result);
}
$this->assignconfig('params', "/source/{$source}/source_id/{$source_id}");
$this->assignconfig('source', $source);
$this->view->assign('source', $source);
$this->view->assign('source_id', $source_id);
if (in_array($source, ['model', 'diyform'])) {
$model = $source == 'model' ? \app\admin\model\cms\Modelx::get($source_id) : \app\admin\model\cms\Diyform::get($source_id);
$this->view->assign('model', $model);
$modelList = $source == 'model' ? \app\admin\model\cms\Modelx::all() : \app\admin\model\cms\Diyform::all();
$this->view->assign('modelList', $modelList);
}
return $this->view->fetch();
}
/**
* 添加
*/
public function add()
{
$source = $this->request->param('source', '');
$source_id = $this->request->param('source_id', 0);
$this->view->assign('source', $source);
$this->view->assign('source_id', $source_id);
$this->renderTable();
return parent::add();
}
/**
* 编辑
*/
public function edit($ids = null)
{
if (is_numeric($ids)) {
$this->renderTable();
return parent::edit($ids);
} else {
$source = $this->request->param('source');
$source_id = $this->request->param('source_id');
$prefix = \think\Config::get('database.prefix');
$fieldList = Service::getTableFields("{$prefix}cms_archives");
$model = $source == 'model' ? \app\admin\model\cms\Modelx::get($source_id) : \app\admin\model\cms\Diyform::get($source_id);
if (!$model) {
$this->error("模型未找到");
}
$setting = $model->setting;
$name = $ids;
$title = '';
foreach ($fieldList as $index => $item) {
if ($item['name'] == $name) {
$title = $item['title'];
break;
}
}
$setting['filterlist'] = isset($setting['filterlist']) ? $setting['filterlist'] : [];
$setting['titlelist'] = isset($setting['titlelist']) ? $setting['titlelist'] : [];
$title = isset($setting['titlelist'][$name]) ? $setting['titlelist'][$name] : $title;
if ($this->request->isPost()) {
$row = $this->request->post("row/a");
foreach (['filter', 'contribute', 'order'] as $index => $item) {
if ($source == 'diyform' && $item == 'contribute') {
continue;
}
$field = $item . 'fields';
$setting[$field] = isset($setting[$field]) ? $setting[$field] : [];
$setting[$field] = array_diff($setting[$field], [$name]);
if (isset($row['is' . $item]) && $row['is' . $item]) {
$setting[$field] = array_merge($setting[$field], [$name]);
}
if ($item == 'filter') {
if (isset($row['is' . $item]) && $row['is' . $item]) {
$setting['filterlist'][$name] = $row['filterlist'];
}
}
}
$setting['titlelist'][$name] = $row['title'];
$model->save(['setting' => $setting]);
$this->success();
}
$row = [
'source' => $this->request->param('source'),
'source_id' => $this->request->param('source_id'),
'name' => $name,
'title' => $title,
'isfilter' => isset($setting['filterfields']) && in_array($name, $setting['filterfields']),
'iscontribute' => isset($setting['contributefields']) && in_array($name, $setting['contributefields']),
'isorder' => isset($setting['orderfields']) && in_array($name, $setting['orderfields']),
'filterlist' => isset($setting['filterlist']) && isset($setting['filterlist'][$name]) ? $setting['filterlist'][$name] : '',
];
$this->view->assign("row", $row);
return $this->view->fetch('cms/fields/archives');
}
}
/**
* 渲染表
*/
protected function renderTable()
{
$tableList = [];
$dbname = \think\Config::get('database.database');
$list = \think\Db::query("SELECT `TABLE_NAME`,`TABLE_COMMENT` FROM `information_schema`.`TABLES` where `TABLE_SCHEMA` = '{$dbname}';");
foreach ($list as $key => $row) {
$tableList[$row['TABLE_NAME']] = $row['TABLE_COMMENT'];
}
$this->view->assign("tableList", $tableList);
}
/**
* 批量操作
* @param string $ids
*/
public function multi($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$params = $this->request->request('params');
parse_str($params, $paramsArr);
if (isset($paramsArr['iscontribute']) && !is_numeric($ids)) {
if (!$ids || !in_array($ids, \app\admin\model\cms\Fields::getContributeFields())) {
$this->error('参数错误');
}
$source_id = $this->request->param('source_id', 0);
$model = \app\admin\model\cms\Modelx::get($source_id);
if (!$model) {
$this->error("模型未找到");
}
$setting = $model['setting'];
$contributefields = isset($setting['contributefields']) ? $setting['contributefields'] : [];
if ($paramsArr['iscontribute']) {
$contributefields[] = $ids;
} else {
$contributefields = array_values(array_diff($contributefields, [$ids]));
}
$setting['contributefields'] = $contributefields;
$model->setting = $setting;
$model->save();
$this->success("");
}
if (isset($paramsArr['ispublish']) && !is_numeric($ids)) {
if (!$ids || !in_array($ids, \app\admin\model\cms\Fields::getPublishFields())) {
$this->error('参数错误');
}
$source_id = $this->request->param('source_id', 0);
$model = \app\admin\model\cms\Modelx::get($source_id);
if (!$model) {
$this->error("模型未找到");
}
$setting = $model['setting'];
$publishfields = isset($setting['publishfields']) ? $setting['publishfields'] : [];
if ($paramsArr['ispublish']) {
$publishfields[] = $ids;
} else {
$publishfields = array_values(array_diff($publishfields, [$ids]));
}
$setting['publishfields'] = $publishfields;
$model->setting = $setting;
$model->save();
$this->success("");
}
if (isset($paramsArr['isorder']) && !is_numeric($ids)) {
if (!$ids) {
$this->error('参数错误');
}
$source = $this->request->param('source', '');
$source_id = $this->request->param('source_id', 0);
$model = $source == 'model' ? \app\admin\model\cms\Modelx::get($source_id) : \app\admin\model\cms\Diyform::get($source_id);
if (!$model) {
$this->error("模型未找到");
}
$setting = $model['setting'];
$orderfields = isset($setting['orderfields']) ? $setting['orderfields'] : [];
if ($paramsArr['isorder']) {
$orderfields[] = $ids;
} else {
$orderfields = array_values(array_diff($orderfields, [$ids]));
}
$setting['orderfields'] = $orderfields;
$model->setting = $setting;
$model->save();
$this->success("");
}
if (isset($paramsArr['isfilter']) && !is_numeric($ids)) {
if (!$ids) {
$this->error('参数错误');
}
$source = $this->request->param('source', '');
$source_id = $this->request->param('source_id', 0);
$model = $source == 'model' ? \app\admin\model\cms\Modelx::get($source_id) : \app\admin\model\cms\Diyform::get($source_id);
if (!$model) {
$this->error("模型未找到");
}
$setting = $model['setting'];
$filterfields = isset($setting['filterfields']) ? $setting['filterfields'] : [];
if ($paramsArr['isfilter']) {
$filterfields[] = $ids;
} else {
$filterfields = array_values(array_diff($filterfields, [$ids]));
}
$setting['filterfields'] = $filterfields;
$model->setting = $setting;
$model->save();
$this->success("");
}
return parent::multi($ids);
}
/**
* 规则列表
* @internal
*/
public function rulelist()
{
//主键
$primarykey = $this->request->request("keyField");
//主键值
$keyValue = $this->request->request("keyValue", "");
$keyValueArr = array_filter(explode(',', $keyValue));
$regexList = Config::getRegexList();
$list = [];
foreach ($regexList as $k => $v) {
if ($keyValueArr) {
if (in_array($k, $keyValueArr)) {
$list[] = ['id' => $k, 'name' => $v];
}
} else {
$list[] = ['id' => $k, 'name' => $v];
}
}
return json(['list' => $list]);
}
}

View File

@ -0,0 +1,690 @@
<?php
namespace app\admin\controller\cms;
use app\admin\model\MatchContestant;
use app\admin\model\MatchRanking;
use app\admin\model\MatchScreen;
use app\admin\model\Players;
use app\admin\model\User;
use app\common\controller\Backend;
use app\admin\service\LeagueService;
use app\common\exception\UploadException;
use app\common\library\Upload;
use fast\Random;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use think\Cookie;
use think\Session;
use app\admin\controller\cms\Leaguexport;
use app\admin\controller\cms\Leagueround;
use app\admin\model\LeagueIntegral;
class League extends Backend
{
protected $noNeedLogin = ['*'];
public function _initialize()
{
parent::_initialize();
$this->leagueService = new LeagueService();
$this->leagueRound = new Leagueround();
}
public function export()
{
$matchranking = new MatchRanking();
$user = new User();
$players = new Players();
$this->exportmatch_id = $this->request->param("match_id");
$this->exportcourse = $this->request->param("course"); // 赛程
$this->exportround = $this->request->param("other_round");
$this->exportsorting = $this->request->param("sorting");
$this->birthday = $this->request->param("birthday");
// if ($this->exportsorting == "false") {
// $this->exportsorting = false;
// }
if (empty($this->exportmatch_id)) {
$this->error("赛事id不能为空");
} else if (empty($this->exportcourse)) {
$this->error("赛程不可为空!");
}
// $row = $this->rankingService->getRankingForCourse($this->exportmatch_id, $this->exportcourse, $this->exportsorting, "最佳成绩");
if($this->exportcourse == 101 || $this->exportcourse == 102 ){
$row = $this->leagueService->bestplayerqua($this->exportmatch_id, $this->exportcourse ,true);
if($this->exportcourse == 101 && $this->exportround != 'best'){
$row = $this->leagueService->getrank_course($this->exportmatch_id, $this->exportcourse,$this->exportround);
// var_dump($row);exit;
}
// $round = $matchranking->where("match_id", "eq", $this->exportmatch_id)
// ->where("course", "eq", $this->exportcourse)
// ->max("other_round");
// var_dump($this->exportround);exit;
}
if($this->exportcourse == 103){
$Leaguexport = new Leaguexport();
$row = $this->leagueRound->group_round2($this->exportmatch_id, $this->exportcourse,$this->exportround,true);
// var_dump($row);exit;
}
if($this->exportcourse == 104){
$Leaguexport = new Leaguexport();
$row = $this->leagueRound->final_rank($this->exportmatch_id);
}
if($this->exportcourse == 'all'){
$LeagueIntegral = new LeagueIntegral();
$row = $LeagueIntegral->where('match_id',$this->exportmatch_id)->select();
if(empty($row)) $this->error('请先生成积分');
}
$archives = new \app\admin\model\cms\Archives();
$PDOStatement = $archives->find($this->exportmatch_id);
if (empty($PDOStatement)) {
$this->error('导出数据为空');
}
$cellTitles = [
'player_id' => '编号',
'player_name' => '姓名',
'gender' => '性别',
// 'position' => '号位',
'name_short' => '所属队伍',
'first_round_time1' => '第一圈',
'first_round_time2' => '第二圈',
'first_round_time3' => '第三圈',
'second_round_time1' => '第一圈',
'second_round_time2' => '第二圈',
'second_round_time3' => '第三圈',
'third_round_time1' => '第一圈',
'third_round_time2' => '第二圈',
'third_round_time3' => '第三圈',
'fourth_round_time1' => '第一圈',
'fourth_round_time2' => '第二圈',
'fourth_round_time3' => '第三圈',
'best_time1' => '第一圈',
'best_time2' => '第二圈',
'best_time3' => '第三圈',
// 'fly_num' => '圈数',
'times' => '平均用时',
'num' => '排名',
'channel' => '频道',
'led_color' => 'LED颜色',
'grouping' => '组别',
'is_young' => '是否满足青少年组',
];
if($this->exportcourse == 101 && $this->exportround != 'best'){
$cellTitles = [
'grouping' => '组别',
'player_id' => '编号',
'player_name' => '姓名',
'gender' => '性别',
'position' => '号位',
'name_short' => '所属队伍',
'first_round_time1' => '第一圈',
'first_round_time2' => '第二圈',
'first_round_time3' => '第三圈',
'second_round_time1' => '第一圈',
'second_round_time2' => '第二圈',
'second_round_time3' => '第三圈',
'third_round_time1' => '第一圈',
'third_round_time2' => '第二圈',
'third_round_time3' => '第三圈',
'fourth_round_time1' => '第一圈',
'fourth_round_time2' => '第二圈',
'fourth_round_time3' => '第三圈',
// 'best_time1' => '第一圈',
// 'best_time2' => '第二圈',
// 'best_time3' => '第三圈',
// 'fly_num' => '圈数',
// 'times' => '平均用时',
// 'num' => '排名',
'channel' => '频道',
'led_color' => 'LED颜色',
'is_young' => '是否满足青少年组',
];
}
if($this->exportcourse == 102){
$cellTitles = [
'num' => '序号',
'player_id' => '编号',
'player_name' => '姓名',
'first_round_time1' => '第一圈',
'first_round_time2' => '第二圈',
'first_round_time3' => '第三圈',
'second_round_time1' => '第一圈',
'second_round_time2' => '第二圈',
'second_round_time3' => '第三圈',
'fly_num' => '总圈数',
'times' => '总时间',
'grouping' => '组别',
'channel' => '频道',
'led_color' => 'LED颜色',
];
}
if($this->exportcourse == 103 || $this->exportcourse == 104){
$cellTitles = [
'grouping' => '组别',
'player_id' => '编号',
'player_name' => '姓名',
'gender' => '性别',
'fly_num' => '总圈数',
'times' => '总时间',
'group_sort' => '小组排名',
'channel' => '频道',
'led_color' => 'LED颜色',
'is_young' => '是否满足青少年组',
];
}
if($this->exportcourse == 'all'){
$cellTitles = [
'num' => '排名',
'player_id' => '编号',
'player_name' => '姓名',
'gender' => '性别',
'name_short' => '所属队伍',
'is_young' => '是否满足青少年组',
];
}
// var_dump($cellTitles);exit;
// if($round == 3){
// $cellTitles['third_round_time1'] = '第一圈';
// $cellTitles['third_round_time2'] = '第二圈';
// $cellTitles['third_round_time3'] = '第三圈';
// }
// if($round == 4){
// $cellTitles['third_round_time1'] = '第一圈';
// $cellTitles['third_round_time2'] = '第二圈';
// $cellTitles['third_round_time3'] = '第三圈';
// $cellTitles['fourth_round_time1'] = '第一圈';
// $cellTitles['fourth_round_time2'] = '第二圈';
// $cellTitles['fourth_round_time3'] = '第三圈';
// }
// $cellTitles['fly_num'] = '圈数';
// $cellTitles['times'] = '时间';
// $cellTitles['grouping'] = '组别';
// $cellTitles['channel'] = '频道';
// $cellTitles['led_color'] = 'LED颜色';
// var_dump($cellTitles);exit;
// var_dump($row);exit;
// 数据总条数
// var_dump($row);exit;
$total = count($row);
if ($total <= 0) {
$this->error('导出数据为空');
}
switch ($this->exportcourse) {
case 101:
$PDOStatement->title = $PDOStatement->title."资格赛成绩";
break;
case 102:
$PDOStatement->title = $PDOStatement->title."排位赛";
break;
case 103:
$which_round = $this->win_or_lose_group($this->exportround);
$PDOStatement->title = $PDOStatement->title."淘汰赛【第".$this->exportround.'轮'.$which_round['which_round'].'组】'.$which_round['status'].'-(成绩公布)';
break;
case 104:
$PDOStatement->title = $PDOStatement->title."决赛成绩";
break;
case 'all':
$PDOStatement->title = $PDOStatement->title."最终排名";
break;
default:
if ($this->exportsorting == false) {
$PDOStatement->title = $PDOStatement->title."【决赛】-未排序";
} else {
$PDOStatement->title = $PDOStatement->title."【决赛】-已排序";
}
break;
}
//计算资格赛每组人数
$export = new \addons\shopro\library\Export();
$params = [
'file_name' => $PDOStatement->title,
'cell_titles' => $cellTitles,
'total' => $total,
'is_sub_cell' => false,
'group_people' =>4,
];
if( $this->exportcourse != 'all'){
$group_people = $this->leagueService->group_people($this->exportmatch_id, $this->exportcourse);
$params['group_people'] = $group_people;
}
$total_commission = 0;
$config = $export->getConfig();
if($this->exportcourse == 101 && $this->exportround == 'best'){
$result = $export->exportRank_bestcourse($params, function ($pages) use (&$total_commission, $total) {
$datas = $this->leagueService->bestplayerqua($this->exportmatch_id, $this->exportcourse ,true);
// var_dump($datas);exit;
$user = new User();
$players = new Players();
// var_dump($datas);exit;
$newDatas = [];
$nums = 0;
foreach ($datas as &$reward) {
// var_dump($reward);exit;
// var_dump(json_encode($reward['round1']['first_fly_time']));exit;
// if(!array_key_exists($reward['round1']['first_fly_time'],$reward)) var_dump($reward['round1']);exit;
$user_info = $user->where('member_number',$reward['info']['player_id'])->find();
$player_info = $players->where('member_id',$user_info['id'])->find();
$data = [
'name_short' => $reward['info']['name_short'],
'is_young' => $player_info['birthday'] >= $this->birthday ? '是' : '否',
'gender' => $player_info['gender'],
'num' => ++$nums,
'player_id' => $reward['info']['player_id'] ? $reward['info']['player_id'] : 0,
'player_name' => $reward['info']['player_name'],
// 'fly_num' => $reward['fly_num'],
'times' => $reward['avg'],
'grouping' => $reward['info']['grouping'],
'channel' => $reward['info']['channel'],
'led_color' => $reward['info']['led_color'],
'first_round_time1' => $reward['round1']['first_fly_time'] ? $reward['round1']['first_fly_time'] : '',
'first_round_time2' => $reward['round1']['second_fly_time'] ? $reward['round1']['second_fly_time'] : '',
'first_round_time3' => $reward['round1']['third_fly_time'] ? $reward['round1']['third_fly_time']:'',
'second_round_time1' => $reward['round2']['first_fly_time'] ? $reward['round2']['first_fly_time'] : '',
'second_round_time2' => $reward['round2']['second_fly_time']? $reward['round2']['second_fly_time'] : '',
'second_round_time3' => $reward['round2']['third_fly_time']? $reward['round2']['third_fly_time']:'',
'third_round_time1' => array_key_exists('round3',$reward) ? $reward['round3']['first_fly_time'] : '',
'third_round_time2' => array_key_exists('round3',$reward) ? $reward['round3']['second_fly_time'] : '',
'third_round_time3' => array_key_exists('round3',$reward) ? $reward['round3']['third_fly_time'] : '',
'fourth_round_time1' => array_key_exists('round4',$reward) ? $reward['round4']['first_fly_time'] : '',
'fourth_round_time2' => array_key_exists('round4',$reward) ? $reward['round4']['second_fly_time'] : '',
'fourth_round_time3' => array_key_exists('round4',$reward) ? $reward['round4']['third_fly_time'] : '',
'best_time1' => $this->getAllSeconds($reward['first']),
'best_time2' => $this->getAllSeconds($reward['second']),
'best_time3' => $this->getAllSeconds($reward['third']),
];
$newDatas[] = $data;
}
$total_commission += array_sum(array_column($newDatas, 'commission'));
return $newDatas;
});
}
if($this->exportcourse == 101 && $this->exportround != 'best'){
$result = $export->exportRank_course($params, function ($pages) use (&$total_commission, $total) {
// var_dump(123);exit;
// $datas = $this->leagueService->bestplayerqua($this->exportmatch_id, $this->exportcourse ,true);
$datas = $this->leagueService->qqq($this->exportmatch_id, $this->exportcourse);
$group_people = $this->leagueService->group_people($this->exportmatch_id, $this->exportcourse);
// var_dump($group_people);exit;
$user = new User();
$players = new Players();
// var_dump($datas);exit;
$newDatas = [];
$nums = 0;$j = 0;
foreach ($datas as &$reward) {
// var_dump($reward);exit;
if($j == $group_people) {$j = 0;}
$user_info = $user->where('member_number',$reward['info']['player_id'])->find();
$player_info = $players->where('member_id',$user_info['id'])->find();
$data = [
'position' => $j= $j + 1,
'name_short' => $reward['info']['name_short'],
'is_young' => $player_info['birthday'] >= $this->birthday ? '是' : '否',
'gender' => $player_info['gender'],
'player_id' => $reward['info']['player_id'] ? $reward['info']['player_id'] : 0,
'player_name' => $reward['info']['player_name'],
// 'fly_num' => $reward['fly_num'],
// 'times' => $reward['avg'],
'grouping' => $reward['info']['grouping'],
'channel' => $reward['info']['channel'],
'led_color' => $reward['info']['led_color'],
'first_round_time1' => $reward['round1']['first_fly_time'] ? $reward['round1']['first_fly_time'] : '',
'first_round_time2' => $reward['round1']['second_fly_time'] ? $reward['round1']['second_fly_time'] : '',
'first_round_time3' => $reward['round1']['third_fly_time'] ? $reward['round1']['third_fly_time']:'',
'second_round_time1' => $reward['round2']['first_fly_time']? $reward['round2']['first_fly_time'] : '',
'second_round_time2' => $reward['round2']['second_fly_time']? $reward['round2']['second_fly_time'] : '',
'second_round_time3' => $reward['round2']['third_fly_time']? $reward['round2']['third_fly_time']:'',
'third_round_time1' => array_key_exists('round3',$reward) ? $reward['round3']['first_fly_time'] : '',
'third_round_time2' => array_key_exists('round3',$reward) ? $reward['round3']['second_fly_time'] : '',
'third_round_time3' => array_key_exists('round3',$reward) ? $reward['round3']['third_fly_time'] : '',
'fourth_round_time1' => array_key_exists('round4',$reward) ? $reward['round4']['first_fly_time'] : '',
'fourth_round_time2' => array_key_exists('round4',$reward) ? $reward['round4']['second_fly_time'] : '',
'fourth_round_time3' => array_key_exists('round4',$reward) ? $reward['round4']['third_fly_time'] : '',
];
$newDatas[] = $data;
}
$total_commission += array_sum(array_column($newDatas, 'commission'));
return $newDatas;
});
}
if($this->exportcourse == 102){
$result = $export->exportRank_sen($params, function ($pages) use (&$total_commission, $total) {
$datas = $this->leagueService->bestplayersen($this->exportmatch_id, $this->exportcourse ,true);
$newDatas = [];
$nums = 0;
foreach ($datas as &$reward) {
// var_dump(json_encode($reward['round1']['first_fly_time']));exit;
// if(!array_key_exists($reward['round1']['first_fly_time'],$reward)) var_dump($reward['round1']);exit;
$data = [
'num' => ++$nums,
'player_id' => $reward['info']['player_id'] ? $reward['info']['player_id'] : 0,
'player_name' => $reward['info']['player_name'],
'fly_num' => $reward['fly_num'],
'times' => $reward['sum'],
'grouping' => $reward['info']['grouping'],
'channel' => $reward['info']['channel'],
'led_color' => $reward['info']['led_color'],
'first_round_time1' => $reward['round1']['first_fly_time'] ? $reward['round1']['first_fly_time'] : 0,
'first_round_time2' => $reward['round1']['second_fly_time'] ? $reward['round1']['second_fly_time'] : 0,
'first_round_time3' => $reward['round1']['third_fly_time'] ? $reward['round1']['third_fly_time']:0,
'second_round_time1' => $reward['round2']['first_fly_time'],
'second_round_time2' => $reward['round2']['second_fly_time'],
'second_round_time3' => $reward['round2']['third_fly_time'],
];
$newDatas[] = $data;
}
$total_commission += array_sum(array_column($newDatas, 'commission'));
return $newDatas;
});
}
if($this->exportcourse == 103){
$result = $export->exportRank_tao($params, function ($pages) use (&$total_commission, $total) {
$Leaguexport = new Leaguexport();
$Leagueround = new Leagueround();
$user = new User();
$players = new Players();
if($this->exportround == 1){
$datas = $Leagueround->group_round2($this->exportmatch_id, $this->exportcourse,$this->exportround,true);
}elseif(in_array($this->exportround,array(2,3,5,6,8,9,11,12))){
$datas = $Leagueround->group_round4($this->exportmatch_id, $this->exportcourse,$this->exportround,true);
}elseif(in_array($this->exportround,array(4,7,10,13))){
// var_dump(1234);exit;
$datas = $Leagueround->group_round5($this->exportmatch_id, $this->exportcourse,$this->exportround,true);
// var_dump($datas);exit;
}
// var_dump($datas);exit;
$newDatas = [];
$nums = 0;
foreach ($datas as &$reward) {
$user_info = $user->where('member_number',$reward['player_id'])->find();
$player_info = $players->where('member_id',$user_info['id'])->find();
$data = [
'is_young' => $player_info['birthday'] >= $this->birthday ? '是' : '否',
'gender' => $player_info['gender'],
// 'num' => ++$nums,
'player_id' => $reward['player_id'] ? $reward['player_id'] : 0,
'player_name' => $reward['player_name'],
'fly_num' => $reward['fly_num'],
'times' => $reward['times'],
'group_sort' => $reward['group_sort'],
'grouping' => $reward['grouping'],
'channel' => $reward['channel'],
'led_color' => $reward['led_color'],
];
$newDatas[] = $data;
}
$total_commission += array_sum(array_column($newDatas, 'commission'));
return $newDatas;
});
}
if($this->exportcourse == 104){
$result = $export->exportRank_tao($params, function ($pages) use (&$total_commission, $total) {
$Leagueround = new Leagueround();
$datas = $Leagueround->final_rank($this->exportmatch_id);
// var_dump($datas);exit;
$newDatas = [];
$nums = 0;
foreach ($datas as &$reward) {
$data = [
'num' => ++$nums,
'player_id' => $reward['player_id'] ? $reward['player_id'] : 0,
'player_name' => $reward['player_name'],
'fly_num' => $reward['fly_num'],
'times' => $reward['times'],
'group_sort' => $reward['group_sort'],
'grouping' => $reward['grouping'],
'channel' => $reward['channel'],
'led_color' => $reward['led_color'],
];
$newDatas[] = $data;
}
$total_commission += array_sum(array_column($newDatas, 'commission'));
return $newDatas;
});
}
if($this->exportcourse == 'all'){
$result = $export->export_finalRank($params, function ($pages) use (&$total_commission, $total) {
$LeagueIntegral = new LeagueIntegral();
$datas = $LeagueIntegral->where('match_id',$this->exportmatch_id)->select();
if(empty($datas)) $this->error('请先生成积分');
// $datas = $Leagueround->final_rank($this->exportmatch_id);
// var_dump($datas);exit;
$user = new User();
$players = new Players();
// var_dump($datas);exit;
$newDatas = [];
$nums = 0;
foreach ($datas as &$reward) {
// $user_info = $user->where('member_number',$reward['player_id'])->find();
// $player_info = $players->where('member_id',$user_info['id'])->find();
// if(empty($player_info['gender'])){
// var_dump($user_info);exit;
// }
$data = [
'num' => ++$nums,
'player_id' => $reward['player_id'] ? $reward['player_id'] : 0,
'player_name' => $reward['player_name'],
'gender' => $reward['gender'],
'name_short' => $reward['name_short'],
'is_young' => $reward['birthday'] >= $this->birthday ? '是' : '否',
];
$newDatas[] = $data;
}
$total_commission += array_sum(array_column($newDatas, 'commission'));
return $newDatas;
});
}
$this->success('导出成功' . (isset($result['file_path']) && $result['file_path'] ? ',请在服务器: “' . $result['file_path'] . '” 查看' : ''), null, $result);
}
public function win_or_lose_group($other_round){
switch ($other_round) {
case 1: $which_round['which_round'] = '1-16';$which_round['status'] = '胜者组';break;
case 2: $which_round['which_round'] = '17-24';$which_round['status'] = '胜者组';break;
case 3: $which_round['which_round'] = '25-32';$which_round['status'] = '败者组';break;
case 4: $which_round['which_round'] = '33-40';$which_round['status'] = '败者组';break;
case 5: $which_round['which_round'] = '41-44';$which_round['status'] = '败者组';break;
case 6: $which_round['which_round'] = '45-48';$which_round['status'] = '胜者组';break;
case 7: $which_round['which_round'] = '49-52';$which_round['status'] = '败者组';break;
case 8: $which_round['which_round'] = '53-54';$which_round['status'] = '败者组';break;
case 9: $which_round['which_round'] = '55-56';$which_round['status'] = '胜者组';break;
case 10: $which_round['which_round'] = '57-58';$which_round['status'] = '败者组';break;
case 11: $which_round['which_round'] = '59';$which_round['status'] = '败者组';break;
case 12: $which_round['which_round'] = '60';$which_round['status'] = '胜者组';break;
case 13: $which_round['which_round'] = '61';$which_round['status'] = '败者组';break;
}
return $which_round;
}
public function getrank_course()
{
header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Methods:*');
header('Access-Control-Allow-Headers:x-requested-with,content-type');
$matchranking = new MatchRanking();
$match_id = $this->request->param("match_id");
$course = $this->request->param("course"); // 赛程
// $where['sorting'] = $this->request->param("sorting", false);
$other_round = $this->request->param("other_round", false); // 轮次
$is_pic = $this->request->param("is_pic", 0); // 轮次
if (empty($match_id)) {
$this->error("赛事id不能为空");
}
$round = $matchranking->where("match_id", "eq", $match_id)
->where("course", "eq", $course)
->max("other_round");
if($other_round == 'bestsen'){
$res_data = $this->leagueService->bestplayersen($match_id,$course);
if (!empty($res_data)) {
$res['code'] = 1;
$res['data'] = $res_data;
$res['round'] = $round;
$res['msg'] = "获取成功";
} else {
$res['code'] = 0;
$res['data'] = [];
$res['round'] = '';
$res['msg'] = "获取失败";
}
return json($res);
}elseif($other_round == 'best'){
// var_dump($other_round);exit;
$res_data = $this->leagueService->bestplayerqua($match_id,$course);
// var_dump($res_data);exit;
if (!empty($res_data)) {
$res['code'] = 1;
$res['data'] = $res_data;
$res['round'] = $round;
$res['msg'] = "获取成功";
} else {
$res['code'] = 0;
$res['data'] = [];
$res['round'] = '';
$res['msg'] = "获取失败";
}
// var_dump($res);exit;
return json($res);
}
if($other_round == '总积分'){
// $res_data = $this->leagueService->bestplayersen($match_id,$course);
$res_data = $this->leagueService->get_final_integral($match_id,$course);
if (!empty($res_data)) {
$res['code'] = 1;
$res['data'] = $res_data;
$res['round'] = $round;
$res['msg'] = "获取成功";
} else {
$res['code'] = 0;
$res['data'] = [];
$res['round'] = '';
$res['msg'] = "获取失败";
}
return json($res);
}
// var_dump($is_pic);exit;
$row = $this->leagueService->getrank_course($match_id,$course,$other_round,false,$is_pic);
// $row = $this->rankingService->getRankingForCourse($param['match_id'], $param['course'], $param['sorting'], $param['other_round']);
// $row = $matchranking->where($where)->select();
$result = $matchranking->where('match_id',$match_id)->where('course',104)->where('other_round',1)->find();
if(!empty($result)){
if( $result['is_extra'] == 1) {
$res['is_extra'] = 1;
}else{
$res['is_extra'] = 0;
}
}
if (!empty($row)) {
$res['code'] = 1;
$res['data'] = $row;
$res['round'] = $round;
$res['msg'] = "获取成功";
} else {
$res['code'] = 0;
$res['data'] = [];
$res['round'] = $round;
$res['msg'] = "获取失败1";
}
return json($res);
}
public function setPlayerRanking()
{
$param['id'] = $this->request->param("id"); // id
$param['player_id'] = $this->request->param("player_id", 0); // 飞手id
$param['match_id'] = $this->request->param("match_id", 0); // 赛事id
$param['course'] = $this->request->param("course", 32); // 赛程
$param['group'] = $this->request->param("group"); // 分组
$param['times'] = $this->request->param("times"); // 成绩
$param['achievement'] = $this->request->param("achievement"); // 成绩
$param['integral'] = $this->request->param("integral", 0); // 积分
$param['fly_num'] = $this->request->param("fly_num"); // 飞行圈数
$param['is_finals'] = $this->request->param("is_finals", 0); // 是否是决赛
$param['finals_round'] = $this->request->param("finals_round"); // 决赛轮次
$param['player_name'] = $this->request->param("player_name"); // 选手姓名
$param['led_color'] = $this->request->param("led_color"); // 选手姓名
$param['channel'] = $this->request->param("channel"); // 选手姓名
$param['other_round'] = $this->request->param("other_round"); // 选手姓名
$param['first_fly_time'] = $this->request->param("first_fly_time"); // 选手姓名
$param['second_fly_time'] = $this->request->param("second_fly_time"); // 选手姓名
$param['third_fly_time'] = $this->request->param("third_fly_time"); // 选手姓名
// $param = $this->request->param();
// var_dump($param);exit;
$res = $this->leagueService->setPlayerScore($param);
if (!empty($res)) {
$result['code'] = 1;
$result['data'] = [];
$result['msg'] = "成功";
} else {
$result['code'] = 0;
$result['data'] = [];
$result['msg'] = "失败";
}
return json($result);
}
private function getAllSeconds($seconds){
// var_dump($seconds);
$lastTwoDigits = substr((string)$seconds, -3);
$newStr = substr((string)$seconds, 0, -3);
// var_dump(floor($newStr / 60));exit;
$minutes = floor($newStr / 60);
$remainingSeconds = $newStr % 60;
$res = sprintf("%02d:%02d", $minutes, $remainingSeconds);
// var_dump($res.'.'.$lastTwoDigits);exit;
return $res.'.'.$lastTwoDigits;
}
}

View File

@ -0,0 +1,563 @@
<?php
/**
* @Created by PhpStorm.
* @Author:Soar
* @Time:2023/11/15 15:13
*/
namespace app\admin\controller\cms;
use app\admin\model\MatchContestant;
use app\admin\model\MatchRanking;
use app\admin\model\MatchScreen;
use app\admin\model\Players;
use app\admin\model\User;
use app\common\controller\Backend;
use app\admin\service\RankingService;
use app\admin\controller\cms\Leagueround;
use app\admin\service\LeagueService;
use app\admin\model\LeagueMaster as LeagueMasterModel;
use think\Db;
class Leaguemaster extends Backend
{
protected $noNeedLogin = [];
public function _initialize()
{
parent::_initialize();
$this->rankingService = new RankingService();
$this->leagueRound = new Leagueround();
$this->leagueService = new LeagueService();
}
public function export()
{
$matchranking = new MatchRanking();
$user = new User();
$players = new Players();
$this->exportmatch_id = $this->request->param("match_id");
$this->exportcourse = $this->request->param("course"); // 赛程
$this->exportround = $this->request->param("other_round");
$this->exportsorting = $this->request->param("sorting");
$this->birthday = $this->request->param("birthday");
if (empty($this->exportmatch_id)) {
$this->error("赛事id不能为空");
} else if (empty($this->exportcourse)) {
$this->error("赛程不可为空!");
}
if($this->exportcourse == 'all'){
$MatchRanking = new MatchRanking();
$master_info = $MatchRanking->where(['match_id'=>$this->exportmatch_id,'course'=>104,'other_round'=>$this->exportround])->select();
// var_dump($master_info[0]['times']);exit;
foreach($master_info as $va){
if(empty($va['times'])){
$this->error('比赛还未结束');
}
}
// $LeagueMasterModel = new LeagueMasterModel();
// $master_info = $LeagueMasterModel->where('final_type',0)->select();
// if(empty($master_info)) $this->error('比赛还未结束');
}
$archives = new \app\admin\model\cms\Archives();
$PDOStatement = $archives->find($this->exportmatch_id);
if (empty($PDOStatement)) {
$this->error('导出数据为空');
}
if($this->exportcourse == 'all'){
$cellTitles = [
'num' => '排名',
'player_id' => '编号',
'player_name' => '姓名',
'gender' => '性别',
'is_young' => '是否满足青少年组',
];
}
// 数据总条数
// var_dump($row);exit;
// $total = 200;
$total = count($master_info) + 4;
if ($total <= 0) {
$this->error('导出数据为空');
}
switch ($this->exportround) {
case 1:
$PDOStatement->title = $PDOStatement->title."公开组最终排名";
break;
case 2:
$PDOStatement->title = $PDOStatement->title."青少年组最终排名";
break;
case 3:
$PDOStatement->title = $PDOStatement->title."女子组最终排名";
break;
}
//计算资格赛每组人数
$export = new \addons\shopro\library\Export();
$params = [
'file_name' => $PDOStatement->title,
'cell_titles' => $cellTitles,
'total' => $total,
'is_sub_cell' => false,
'group_people' =>4,
];
if( $this->exportcourse != 'all'){
$group_people = $this->leagueService->group_people($this->exportmatch_id, $this->exportcourse);
$params['group_people'] = $group_people;
}
$total_commission = 0;
$config = $export->getConfig();
if($this->exportcourse == 'all'){
$result = $export->export_finalRank($params, function ($pages) use (&$total_commission, $total) {
$LeagueMasterModel = new LeagueMasterModel();
// $master_info = $LeagueMasterModel->where('number',1)->where('final_type',$this->exportround)->find();
// $MatchRanking = new MatchRanking();
// $datas = $MatchRanking->where(['match_id'=>$this->exportmatch_id,'course'=>104,'other_round'=>$this->exportround])->select();
// $LeagueIntegral = new LeagueIntegral();
// $datas = $LeagueIntegral->where('match_id',$this->exportmatch_id)->select();
// var_dump($this->exportround);exit;
$res = $this->final_master_rank($this->exportmatch_id,$this->exportround);
if($this->exportround == 1){
// var_dump($this->exportround);exit;
$datas = $LeagueMasterModel->where('final_type',$this->exportround)->select();
var_dump($datas);exit;
$other_data = $LeagueMasterModel->where('final_type',0)->select();
$datas = array_merge($datas,$other_data);
var_dump($datas);exit;
}
if($this->exportround == 2){
// var_dump($this->exportround);exit;
$datas = $LeagueMasterModel->where('final_type',$this->exportround)->select();
$other_data = $LeagueMasterModel->where('final_type',0)->where('birthday','>=',$this->birthday)->select();
foreach ($other_data as $k =>$value){
foreach ($datas as $val){
if($value['player_id'] == $val['player_id']){
unset($other_data[$k]);
}
}
}
$datas = array_merge($datas,$other_data);
// var_dump($datas);exit;
}
if($this->exportround == 3){
$datas = $LeagueMasterModel->where('final_type',$this->exportround)->select();
$other_data = $LeagueMasterModel->where('final_type',0)->where('gender','女')->select();
foreach ($other_data as $k =>$value){
foreach ($datas as $val){
if($value['player_id'] == $val['player_id']){
unset($other_data[$k]);
}
}
}
$datas = array_merge($datas,$other_data);
}
// $datas = array_merge($datas,$res);
// var_dump($datas);exit;
// $datas = $Leagueround->final_rank($this->exportmatch_id);
// var_dump($datas);exit;
$user = new User();
$players = new Players();
// var_dump($this->exportround);exit;
$newDatas = [];
$nums = 0;
foreach ($datas as &$reward) {
// $user_info = $user->where('member_number',$reward['player_id'])->find();
// $player_info = $players->where('member_id',$user_info['id'])->find();
// if(empty($player_info['gender'])){
// var_dump($user_info);exit;
// }
$data = [
'num' => ++$nums,
'player_id' => $reward['player_id'] ? $reward['player_id'] : 0,
'player_name' => $reward['player_name'],
'gender' => $reward['gender'],
'is_young' => $reward['birthday'] >= $this->birthday ? '是' : '否',
];
$newDatas[] = $data;
}
$total_commission += array_sum(array_column($newDatas, 'commission'));
return $newDatas;
});
}
$this->success('导出成功' . (isset($result['file_path']) && $result['file_path'] ? ',请在服务器: “' . $result['file_path'] . '” 查看' : ''), null, $result);
}
//生成大师赛公开组决赛分组
public function final_public_group(){
$match_id = $this->request->param('match_id');
$this->leagueRound->final_groups($match_id,104,false,1);
$array= ['code'=>200,'msg'=>'success'];
return json($array);
}
//生成大师赛青少年/女子决赛分组
public function final_young_group(){
// $array= ['code'=>200,'msg'=>'success'];
// return json($array);
$match_id = $this->request->param('match_id');
$birthday = $this->request->param('birthday');
$women = $this->request->param('women');
$LeagueMasterModel = new LeagueMasterModel();
$MatchRanking = new MatchRanking();
// var_dump($group_info);exit;
if($women != '1'){
$match_rank_info = $MatchRanking->where(['match_id'=>$match_id,'course'=>104,'other_round'=>2])->find();
}else{
$match_rank_info = $MatchRanking->where(['match_id'=>$match_id,'course'=>104,'other_round'=>3])->find();
}
if(!empty($match_rank_info)){
$array= ['code'=>400,'msg'=>'已生成分组'];
return json($array);
}
$master_info = $LeagueMasterModel->where('number',5)->find();
if(true){
$res = $this->integral($match_id);
}else{
$array= ['code'=>400,'msg'=>'fail'];
return json($array);
}
// var_dump($birthday);exit;
if($women != '1'){
$other_round = 2;
$group_info = $LeagueMasterModel->where('birthday','>=',$birthday)->limit(4)->order('number')->select();
// var_dump($group_info);exit;
}else{
$other_round = 3;
$group_info = $LeagueMasterModel->where('gender','女')->limit(4)->order('number')->select();
}
// $LeagueMasterModelModel->where('gender','女')->limit(4)->order('number')->select();
// $young_info = $LeagueMasterModel->where('birthday','>=',$birthday)->limit(4)->order('number')->select();
$u = 0;
for($i = 1;$i <=5 ;$i++){
foreach ($group_info as &$b){
if($u == 0){
$b['grouping'] = '1';
$b['channel'] = 'R1';
$b['led_color'] = '红';
}
if($u == 1){
$b['grouping'] = '1';
$b['channel'] = 'R2';
$b['led_color'] = '黄';
}
if($u == 2){
$b['grouping'] = '1';
$b['channel'] = 'R6';
$b['led_color'] = '蓝';
}
if($u == 3){
$b['grouping'] = '1';
$b['channel'] = 'R8';
$b['led_color'] = '绿';
}
$u++;
}
// var_dump($young_info);exit;
$this->insert_group($group_info,$match_id,104,$other_round);
}
$array= ['code'=>200,'msg'=>'success'];
return json($array);
// $this->success('build success');
}
//生成大师赛公开组/青少年/女子决赛成绩排名
public function final_master_rank($match_id,$other_round){
$user = new User();
$palyer = new Players();
$LeagueMasterModel = new LeagueMasterModel();
$MatchRanking = new MatchRanking();
$LeagueMasterModel->where('match_id',$match_id)->where('final_type',$other_round)->delete();
// var_dump($res);exit;
// $mess_arr = array('code'=>0,'message'=>'该赛事已生成过排名');
// if($inte_exsit) return json($mess_arr);
// var_dump($other_round);exit;
$result = $MatchRanking->where(['match_id'=>$match_id,'course'=>104,'other_round'=>$other_round])->find();
// var_dump($result);exit;
if(empty($result)) $this->error('比赛未结束1');
// var_dump($other_round);exit;
$res1 = $this->leagueRound->group_rank_sort($match_id,104,$other_round);
var_dump($res1);exit;
//前四名
$i = 1;
foreach ($res1 as $v){
$user_res = $user->where('member_number',$v['player_id'])->find();
$player_res = $palyer->where('member_id',$user_res['id'])->find();
// var_dump($club_res);exit;
$LeagueMasterModel->insert([
'match_id' => $match_id,
'player_id' => $v['player_id'],
'player_name' => $v['player_name'],
'qua_rank' =>$v['qua_rank'],
'country' =>$v['country'],
'national_flag' =>$v['national_flag'],
'gender' => $player_res['gender'],
'birthday' => $player_res['birthday'],
'number' => $i,
'createtime' => time(),
'final_type'=> $other_round,
]);
$i++;
}
return true;
}
public function integral($match_id){
// return json($success);
// var_dump($res_sen);exit;
$user = new User();
$palyer = new Players();
$LeagueMasterModel = new LeagueMasterModel();
$MatchRanking = new MatchRanking();
// $match_id = $this->request->param('match_id');
// $inte_exsit = $LeagueIntegral->where('match_id',$match_id)->find();
// $res_sen = $this->leagueService->bestplayerqua($match_id,101);
// $res_sen = array_slice($res_sen,64);
// $res13 = $this->leagueRound->group_rank_sort($match_id,103,13);
// // $res = $this->extra_match($new_arr,$match_id,103);
// var_dump($res13);exit;
$res = $LeagueMasterModel->where('match_id',$match_id)->delete();
// var_dump($res);exit;
// $mess_arr = array('code'=>0,'message'=>'该赛事已生成过排名');
// if($inte_exsit) return json($mess_arr);
// $result = $MatchRanking->where(['match_id'=>$match_id,'course'=>104,'other_round'=>1])->find();
// if(empty($result)) $this->error('已清空积分');
// var_dump($result['is_extra']);exit;
$res13 = $this->leagueRound->group_rank_sort($match_id,103,13);
$res11 = $this->leagueRound->group_rank_sort($match_id,103,11);
$res10 = $this->leagueRound->group_rank_sort($match_id,103,10);
$res8 = $this->leagueRound->group_rank_sort($match_id,103,8);
$res7 = $this->leagueRound->group_rank_sort($match_id,103,7);
$res5 = $this->leagueRound->group_rank_sort($match_id,103,5);
$res4 = $this->leagueRound->group_rank_sort($match_id,103,4);
$res3 = $this->leagueRound->group_rank_sort($match_id,103,3);
// var_dump($res13);exit;
//5-8名
$eve_arr = [$res13,$res11];
$i = 5;
foreach($eve_arr as $val){
$new_arr = [];
foreach ($val as $value) {
if(in_array($value['group_sort'],array(3,4))){
$new_arr[] = $value;
}
}
// $res = $this->extra_match($new_arr,$match_id,103);
// exit;
foreach ($new_arr as $v){
$user_res = $user->where('member_number',$v['player_id'])->find();
$player_res = $palyer->where('member_id',$user_res['id'])->find();
$LeagueMasterModel->insert([
'match_id' => $match_id,
'player_id' => $v['player_id'],
'player_name' => $v['player_name'],
'qua_rank' =>$v['qua_rank'],
'country' =>$v['country'],
'national_flag' =>$v['national_flag'],
'gender' => $player_res['gender'],
'birthday' => $player_res['birthday'],
'number' => $i,
'createtime' => time(),
'final_type' => 0,
]);
$i++;
}
}
//9-64名
$com_arr = [$res10,$res8,$res7,$res5,$res4,$res3];
$i = 9;
foreach($com_arr as $val){
$new_arr = [];
foreach ($val as $value) {
if(in_array($value['group_sort'],array(3,4))){
$new_arr[] = $value;
}
}
$res = $this->extra_match($new_arr,$match_id,103);
// exit;
foreach ($res as $v){
$user_res = $user->where('member_number',$v['player_id'])->find();
$player_res = $palyer->where('member_id',$user_res['id'])->find();
$LeagueMasterModel->insert([
'match_id' => $match_id,
'player_id' => $v['player_id'],
'player_name' => $v['player_name'],
'qua_rank' =>$v['qua_rank'],
'country' =>$v['country'],
'national_flag' =>$v['national_flag'],
'gender' => $player_res['gender'],
'birthday' => $player_res['birthday'],
'number' => $i,
'createtime' => time(),
'final_type' => 0,
]);
$i++;
}
}
$i = 65;
//64名之后排位赛有1轮成绩的积1分
$res_sen = $this->leagueService->bestplayerqua($match_id,101);
$res_sen = array_slice($res_sen,64);
//TODO先循环拿出fly_num=0 再查组合老数组
foreach($res_sen as $vvv){
// if($vvv['fly_num'] >= 3){
// var_dump($vvv);exit;
if($vvv['fly_num'] > 0 || $vvv['fly_num'] == 'DNF'){
$user_res = $user->where('member_number',$vvv['info']['player_id'])->find();
if(empty($user_res['id'])){var_dump($vvv);exit;}
$player_res = $palyer->where('member_id',$user_res['id'])->find();
$LeagueMasterModel->insert([
'match_id' => $match_id,
'player_id' => $vvv['info']['player_id'],
'player_name' => $vvv['info']['player_name'],
'qua_rank' =>$v['qua_rank'],
'country' =>$v['country'],
'national_flag' =>$v['national_flag'],
'gender' => $player_res['gender'],
'birthday' => $player_res['birthday'],
'number' => $i,
'createtime' => time(),
'final_type' => 0,
]);
$i++;
}
}
// var_dump($res);exit;
$success = array('code'=>1,'message'=>'success');
return json($success);
}
public function insert_group($data,$match_id,$course,$other_round){
$matchranking = new MatchRanking();
Db::startTrans();
try{
foreach ($data as $val){
// var_dump($val);exit;
$match_rank_res = $matchranking->where([
'match_id' => $match_id,
'course' => $course,
'other_round' => $other_round,
'player_id' => $val['player_id'],
])->find();
$player['match_id'] = $match_id;
$player['course'] = $course;
$player['other_round'] = $other_round;
$player['player_id'] = $val['player_id'];
$player['player_name'] = $val['player_name'];
$player['channel'] = $val['channel'];
$player['led_color'] = $val['led_color'];
$player['grouping'] = $val['grouping'];
$player['qua_rank'] = $val['qua_rank'];
$player['country'] = $val['country'];
$player['national_flag'] = $val['national_flag'];
if(empty($match_rank_res)){
$matchranking->insert($player);
}
}
// 提交事务
Db::commit();
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
}
}
//决赛是否有加赛
public function is_extra(){
$match_id = $this->request->param('match_id');
$is_open = $this->request->param('is_open');
$MatchRanking = new MatchRanking();
$result = $MatchRanking->where(['match_id'=>$match_id,'course'=>104,'other_round' => 1,])->select();
foreach ($result as $v){
$MatchRanking->where('id', $v['id'])
->update(['is_extra'=>$is_open]);
}
if(true){
$data = ['code'=>1,'message'=>'success'];
return json($data);
}else{
$data = ['code'=>0,'message'=>'fail'];
return json($data);
}
}
public function custom_rank(){
$MatchRanking = new MatchRanking();
// var_dump($_POST);exit;
if(empty($_POST['data']) || empty($_POST['match_id']))$this->error('lack param');
foreach ($_POST['data'] as $v){
// var_dump($v);exit;
$MatchRanking->where(['match_id'=> $_POST['match_id'],'course'=>104,'other_round'=>1,'is_extra'=>1,'player_id'=>$v['player_id']])
->update(['custom_sorting'=>$v['custom_sorting']]);
}
$data = ['code'=>1,'message'=>'success'];
return json($data);
}
public function find_sort($match_id,$course,$other_round){
$res = $this->leagueRound->group_rank_sort($match_id,$course,$other_round);
foreach ($res as $value) {
if(in_array($value['group_sort'],array(3,4))){
$new_arr[] = $value;
}
}
$res = $this->extra_match($new_arr,$match_id,$course);
//存表 差俱乐部id
}
//加赛
public function extra_match($data,$match_id,$course){
$res1 = $this->find_quarank($match_id,$course);
// var_dump($res1);exit;
foreach ($res1 as $vvvv){
foreach ($data as $va){
if($va['player_id'] == $vvvv){
$obj_arr[] = $va;
}
}
}
// var_dump($obj_arr);exit;
// var_dump($obj_arr);exit;
return $obj_arr;
}
public function find_quarank($match_id,$course){
// $match_id = 606;$course = 101;
$res = $this->leagueService->bestplayerqua($match_id,$course);
foreach ($res as $val){
$new_arr[] = $val['info']['player_id'];
}
// var_dump($new_arr);exit;
return $new_arr;
}
}

View File

@ -0,0 +1,831 @@
<?php
namespace app\admin\controller\cms;
use app\admin\model\MatchContestant;
use app\admin\model\MatchRanking;
use app\admin\model\MatchScreen;
use app\admin\model\Players;
use app\admin\model\User;
use app\common\controller\Backend;
use app\admin\service\LeagueService;
use app\common\exception\UploadException;
use app\common\library\Upload;
use fast\Random;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use think\Cookie;
use think\Session;
use think\Db;
class Leagueround extends Backend
{
protected $noNeedLogin = ['*'];
public function _initialize()
{
parent::_initialize();
$this->leagueService = new LeagueService();
}
public function final_rank($match_id){
if(empty($match_id)) $this->error('缺少参数');
$matchranking = new MatchRanking();
$oldarr = $matchranking->where([
'match_id' => $match_id,
'course' => 104,
'other_round' => 1,])
->orderRaw("CASE fly_num
WHEN '3' THEN 1
WHEN '2' THEN 2
WHEN '1' THEN 3
WHEN 'DNF' THEN 4
ELSE 5 END,datetime_value asc,CAST(qua_rank AS UNSIGNED)
")
->select();
$j = 1;
if(!empty($oldarr)){
foreach ($oldarr as $v){
$q = $v->toArray();
$q['group_sort'] = $j;
$obj_arr[] = $q;
$j++;
}
}
return $obj_arr;
}
public function final_group(){
$match_id = $this->request->param("match_id");
$this->final_groups($match_id,104);
}
//决赛分组
public function final_groups($match_id,$course,$export = false,$times = 5){
$matchranking = new MatchRanking();
$round13 = $matchranking->where([
'match_id' => $match_id,
'course' => 103,
'other_round' => 13,])
->orderRaw("CASE fly_num
WHEN '3' THEN 1
WHEN '2' THEN 2
WHEN '1' THEN 3
WHEN 'DNF' THEN 4
ELSE 5 END,datetime_value asc,CAST(qua_rank AS UNSIGNED)
")
->select();
$j = 1;
if(!empty($round13)){
foreach ($round13 as $v){
$q = $v->toArray();
$q['group_sort'] = $j;
$arr13[] = $q;
$j++;
}
}
// var_dump($arr13);exit;
$round12 = $matchranking->where([
'match_id' => $match_id,
'course' => 103,
'other_round' => 12,])
->orderRaw("CASE fly_num
WHEN '3' THEN 1
WHEN '2' THEN 2
WHEN '1' THEN 3
WHEN 'DNF' THEN 4
ELSE 5 END,datetime_value asc,CAST(qua_rank AS UNSIGNED)
")
->select();
if(!empty($round12)){
foreach ($round12 as $v){
$q = $v->toArray();
$q['group_sort'] = $j;
$arr12[] = $q;
$j++;
}
}
// $final_arr = $this->specify_order(1,$arr1,$arr2,'','',true);
$final_arr[] = $arr13[1];
$final_arr[] = $arr12[1];
$final_arr[] = $arr12[0];
$final_arr[] = $arr13[0];
$u = 0;
for($i = 1;$i <=$times ;$i++){
foreach ($final_arr as &$b){
if($u == 0){
$b['grouping'] = '1';
$b['channel'] = 'R1';
$b['led_color'] = '红';
}
if($u == 1){
$b['grouping'] = '1';
$b['channel'] = 'R2';
$b['led_color'] = '黄';
}
if($u == 2){
$b['grouping'] = '1';
$b['channel'] = 'R6';
$b['led_color'] = '蓝';
}
if($u == 3){
$b['grouping'] = '1';
$b['channel'] = 'R8';
$b['led_color'] = '绿';
}
$u++;
}
// var_dump($final_arr);exit;
$this->insert_group($final_arr,$match_id,104,$i);
}
$this->success('build success');
}
public function group_round2($match_id,$course,$other_round,$export = false){
$matchranking = new MatchRanking();
$this->exportmatch_id = $match_id;
$this->exportcourse = $course; // 赛程
// var_dump($other_round);exit;
$this->other_round = $other_round; // 赛程
if($other_round == 3 && $export === false) $other_round = 2;
if($export === true) {$other_round = $other_round + 1;}
if(empty($this->other_round) || empty($this->exportmatch_id) || empty($this->exportcourse)) $this->error('缺少参数');
$obj_arr = $this->group_rank_sort($this->exportmatch_id,$this->exportcourse,$other_round - 1);
// var_dump($obj_arr);exit;
if($export === true) return $obj_arr;
// var_dump($this->other_round);exit;
$t = 0;$h1 = 0;$h2 = 0;$h3 = 0;$h4 = 0;$g = 0;
// $group_arr = ['A','B','C','D','E','F','G','H'];
$group_arr = ['17','18','19','20','21','22','23','24'];
// if($this->other_round == 3){
// $group_arr = ['25','26','27','28','29','30','31','32'];
// }
// var_dump($group_arr);exit;
foreach ($obj_arr as $vv){
// if($h == 4) $t++;
if($g == 8) {$g = 0; $t++;}
$vv['grouping'] = $group_arr[$t];
if($vv['group_sort'] == 1){
$arr1[$h1] = $vv;
$h1++;
}
if($vv['group_sort'] == 2){
$arr2[$h2] = $vv;
$h2++;
}
if($vv['group_sort'] == 3){
$arr3[$h3] = $vv;
$h3++;
}
if($vv['group_sort'] == 4){
$arr4[$h4] = $vv;
$h4++;
}
$g++;
}
// var_dump($arr4);exit;
// var_dump($arr2);exit;
//胜者组
for($u = 0;$u < 16;$u++){
if($u % 2 == 0){
$arr2[$u]['channel'] = 'R1';
$arr2[$u]['led_color'] = '红';
// $arr2[$u]['grouping'] = $group_arr[$u];
$arr1[$u]['channel'] = 'R2';
$arr1[$u]['led_color'] = '黄';
// $arr1[$u]['grouping'] = $group_arr[$u];
$win_arr[] = $arr2[$u];
$win_arr[] = $arr1[$u];
}else{
$arr1[$u]['channel'] = 'R6';
$arr1[$u]['led_color'] = '蓝';
// $arr1[$u]['grouping'] = $group_arr[$u];
$arr2[$u]['channel'] = 'R8';
$arr2[$u]['led_color'] = '绿';
// $arr2[$u]['grouping'] = $group_arr[$u];
$win_arr[] = $arr1[$u];
$win_arr[] = $arr2[$u];
}
}
// var_dump($arr3);exit;
//败者组
$lose_arr = $this->specify_order(3,'','',$arr3,$arr4);
// var_dump($win_arr);exit;
// var_dump($lose_arr);exit;
// if($this->other_round == 2) $win_or_lose = $win_arr;
// if($this->other_round == 3) $win_or_lose = $lose_arr;
// var_dump($win_or_lose);exit;
$this->insert_group($win_arr,$this->exportmatch_id,$this->exportcourse,$this->other_round);
$this->insert_group($lose_arr,$this->exportmatch_id,$this->exportcourse,3);
$this->success('build success');
}
public function group_round6($match_id,$course,$other_round,$export = false){
$matchranking = new MatchRanking();
$this->exportmatch_id = $match_id;
$this->exportcourse = $course; // 赛程
// var_dump($other_round);exit;
$other_round = 4;
$this->other_round = $other_round; // 赛程
if($other_round == 4){
$calculate_win_round = $other_round - 2;
}
// $this->exportmatch_id = 606;$this->exportcourse= 103;$this->other_round = 1;
if(empty($this->other_round) || empty($this->exportmatch_id) || empty($this->exportcourse)) $this->error('缺少参数');
$obj_arr = $this->group_rank_sort($this->exportmatch_id,$this->exportcourse,$calculate_win_round);
// var_dump($obj_arr);exit;
if($export === true ){return $obj_arr;}
// var_dump($obj_arr);exit;
$h1 = 0;$h2 = 0;
foreach ($obj_arr as $vv){
// var_dump($vv['group_sort']);exit;
if($vv['group_sort'] == 1){
$arrwin1[$h1] = $vv;
$h1++;
}
if($vv['group_sort'] == 2){
$arrwin2[$h2] = $vv;
$h2++;
}
}
if($other_round == 4) {$fortimes = 8; $group_arr = ['45','46','47','48'];}
// var_dump($fortimes);exit;
for($u = 0,$j = 0,$h = 0;$u < $fortimes;$u++){
if($u % 2 == 0){
$arrwin2[$u]['channel'] = 'R1';
$arrwin2[$u]['led_color'] = '红';
$arrwin2[$u]['grouping'] = $group_arr[$j];
$arrwin1[$u]['channel'] = 'R2';
$arrwin1[$u]['led_color'] = '黄';
$arrwin1[$u]['grouping'] = $group_arr[$j];
$win_arr[] = $arrwin2[$u];
$win_arr[] = $arrwin1[$u];
$h = $h + 0.5;
}else{
$arrwin1[$u]['channel'] = 'R6';
$arrwin1[$u]['led_color'] = '蓝';
$arrwin1[$u]['grouping'] = $group_arr[$j];
$arrwin2[$u]['channel'] = 'R8';
$arrwin2[$u]['led_color'] = '绿';
$arrwin2[$u]['grouping'] = $group_arr[$j];
$win_arr[] = $arrwin1[$u];
$win_arr[] = $arrwin2[$u];
$h = $h + 0.5;
// var_dump($h == ($j + 1));exit;
if($h == ($j + 1)) {$j++;}
}
// var_dump($h);exit;
}
// var_dump($win_arr);exit;
if($other_round != 13){
$this->insert_group($win_arr,$this->exportmatch_id,$this->exportcourse,$other_round + 2);
}
$this->success('build success');
}
public function group_round4($match_id,$course,$other_round,$export = false){
$matchranking = new MatchRanking();
$this->exportmatch_id = $match_id;
$this->exportcourse = $course; // 赛程
// var_dump($other_round);exit;
$this->other_round = $other_round; // 赛程
if($other_round == 4){
$calculate_round = $other_round - 1;
$calculate_win_round = $other_round - 2;
}
if($other_round == 7 || $other_round == 10 || $other_round == 13){
$calculate_round = $other_round - 2;
$calculate_win_round = $other_round - 1;
}
if($export === true){$calculate_round = $other_round;$calculate_win_round = $other_round;}
// $this->exportmatch_id = 606;$this->exportcourse= 103;$this->other_round = 1;
if(empty($this->other_round) || empty($this->exportmatch_id) || empty($this->exportcourse)) $this->error('缺少参数');
$obj_arr = $this->group_rank_sort($this->exportmatch_id,$this->exportcourse,$calculate_round);
// if($export === true && $other_round == 3){return $obj_arr;}
// var_dump($calculate_win_round);exit;
$h1 = 0;$h2 = 0;$h3 = 0;$h4 = 0;
// $group_arr = ['A','B','C','D','E','F','G','H'];
$group_arr = ['33','34','35','36','37','38','39','40'];
foreach ($obj_arr as $vv){
if($vv['group_sort'] == 1){
$arr1[$h1] = $vv;
$h1++;
}
if($vv['group_sort'] == 2){
$arr2[$h2] = $vv;
$h2++;
}
}
$obj_arr = $this->group_rank_sort($this->exportmatch_id,$this->exportcourse,$calculate_win_round);
// var_dump($calculate_win_round);exit;
// var_dump($obj_arr);exit;
if($export === true ){return $obj_arr;}
// var_dump($obj_arr);exit;
$h1 = 0;$h2 = 0;$h3 = 0;$h4 = 0;
foreach ($obj_arr as $vv){
// var_dump($vv['group_sort']);exit;
if($vv['group_sort'] == 1){
$arrwin1[$h1] = $vv;
$h1++;
}
if($vv['group_sort'] == 2){
$arrwin2[$h2] = $vv;
$h2++;
}
if($vv['group_sort'] == 3){
$arr3[$h3] = $vv;
$h3++;
}
if($vv['group_sort'] == 4){
$arr4[$h4] = $vv;
$h4++;
}
}
// var_dump($arrwin1);exit;
$final_arr = $this->specify_order($this->other_round,$arr1,$arr2,$arr3,$arr4);
// var_dump($final_arr);exit;
if($other_round == 4) {$fortimes = 8; $group_arr = ['45','46','47','48'];}
if($other_round == 7) {$fortimes = 4; $group_arr = ['55','56'];}
if($other_round == 10) {$fortimes = 2; $group_arr = ['60'];}
if($other_round == 13) {$fortimes = 1; $group_arr = ['61'];}
// var_dump($fortimes);exit;
for($u = 0,$j = 0,$h = 0;$u < $fortimes;$u++){
if($u % 2 == 0){
$arrwin2[$u]['channel'] = 'R1';
$arrwin2[$u]['led_color'] = '红';
$arrwin2[$u]['grouping'] = $group_arr[$j];
$arrwin1[$u]['channel'] = 'R2';
$arrwin1[$u]['led_color'] = '黄';
$arrwin1[$u]['grouping'] = $group_arr[$j];
$win_arr[] = $arrwin2[$u];
$win_arr[] = $arrwin1[$u];
$h = $h + 0.5;
}else{
$arrwin1[$u]['channel'] = 'R6';
$arrwin1[$u]['led_color'] = '蓝';
$arrwin1[$u]['grouping'] = $group_arr[$j];
$arrwin2[$u]['channel'] = 'R8';
$arrwin2[$u]['led_color'] = '绿';
$arrwin2[$u]['grouping'] = $group_arr[$j];
$win_arr[] = $arrwin1[$u];
$win_arr[] = $arrwin2[$u];
$h = $h + 0.5;
// var_dump($h == ($j + 1));exit;
if($h == ($j + 1)) {$j++;}
}
// var_dump($h);exit;
}
// var_dump($win_arr);exit;
$this->insert_group($final_arr,$this->exportmatch_id,$this->exportcourse,$this->other_round);
if($other_round != 13 && $other_round != 4){
$this->insert_group($win_arr,$this->exportmatch_id,$this->exportcourse,$other_round + 2);
}
$this->success('build success');
}
public function group_round5($match_id,$course,$other_round,$export = false){
$matchranking = new MatchRanking();
$this->exportmatch_id = $match_id;
$this->exportcourse = $course; // 赛程
// var_dump($other_round);exit;
if($export === true ) {$other_round = $other_round + 1;}
$this->other_round = $other_round; // 赛程
// $this->exportmatch_id = 606;$this->exportcourse= 103;$this->other_round = 1;
if(empty($this->other_round) || empty($this->exportmatch_id) || empty($this->exportcourse)) $this->error('缺少参数');
$obj_arr = $this->group_rank_sort($this->exportmatch_id,$this->exportcourse,$other_round - 1);
// var_dump($obj_arr);exit;
if( $export === true) {return $obj_arr;}
// var_dump($obj_arr);exit;
$h1 = 0;$h2 = 0;$h3 = 0;$h4 = 0;
// $group_arr = ['A','B','C','D','E','F','G','H'];
$group_arr = ['41','42','43','44'];
foreach ($obj_arr as $vv){
if($vv['group_sort'] == 1){
$arrwin1[$h1] = $vv;
$h1++;
}
if($vv['group_sort'] == 2){
$arrwin2[$h2] = $vv;
$h2++;
}
}
$final_arr = $this->specify_order($this->other_round,$arrwin1,$arrwin2,'','');
// var_dump($final_arr);exit;
//插入数据
$this->insert_group($final_arr,$this->exportmatch_id,$this->exportcourse,$this->other_round);
$this->success('build success');
}
public function specify_order($round,$arr1,$arr2,$arr3,$arr4,$is_final = false){
if($round == 3){
$final_arr[] = $arr4[0];
$final_arr[] = $arr3[1];
$final_arr[] = $arr3[2];
$final_arr[] = $arr4[3];
$final_arr[] = $arr4[4];
$final_arr[] = $arr3[5];
$final_arr[] = $arr3[6];
$final_arr[] = $arr4[7];
$final_arr[] = $arr4[1];
$final_arr[] = $arr3[0];
$final_arr[] = $arr3[3];
$final_arr[] = $arr4[2];
$final_arr[] = $arr4[5];
$final_arr[] = $arr3[4];
$final_arr[] = $arr3[7];
$final_arr[] = $arr4[6];
$final_arr[] = $arr4[8];
$final_arr[] = $arr3[9];
$final_arr[] = $arr3[10];
$final_arr[] = $arr4[11];
$final_arr[] = $arr4[12];
$final_arr[] = $arr3[13];
$final_arr[] = $arr3[14];
$final_arr[] = $arr4[15];
$final_arr[] = $arr4[9];
$final_arr[] = $arr3[8];
$final_arr[] = $arr3[11];
$final_arr[] = $arr4[10];
$final_arr[] = $arr4[13];
$final_arr[] = $arr3[12];
$final_arr[] = $arr3[15];
$final_arr[] = $arr4[14];
// var_dump($final_arr);exit;
}
if($round == 11){
$final_arr[] = $arr2[0];
$final_arr[] = $arr1[0];
$final_arr[] = $arr1[1];
$final_arr[] = $arr2[1];
}
if($round == 8){
$final_arr[] = $arr2[2];
$final_arr[] = $arr1[0];
$final_arr[] = $arr1[1];
$final_arr[] = $arr2[3];
$final_arr[] = $arr2[0];
$final_arr[] = $arr1[2];
$final_arr[] = $arr1[3];
$final_arr[] = $arr2[1];
}
if($round == 5){
$final_arr[] = $arr2[2];
$final_arr[] = $arr1[0];
$final_arr[] = $arr1[1];
$final_arr[] = $arr2[3];
$final_arr[] = $arr2[0];
$final_arr[] = $arr1[2];
$final_arr[] = $arr1[3];
$final_arr[] = $arr2[1];
$final_arr[] = $arr2[6];
$final_arr[] = $arr1[4];
$final_arr[] = $arr1[5];
$final_arr[] = $arr2[7];
$final_arr[] = $arr2[4];
$final_arr[] = $arr1[6];
$final_arr[] = $arr1[7];
$final_arr[] = $arr2[5];
}
if($round == 4){
$final_arr[] = $arr3[0];
$final_arr[] = $arr2[6];
$final_arr[] = $arr1[7];
$final_arr[] = $arr4[1];
$final_arr[] = $arr3[2];
$final_arr[] = $arr2[4];
$final_arr[] = $arr1[5];
$final_arr[] = $arr4[3];
$final_arr[] = $arr3[1];
$final_arr[] = $arr2[7];
$final_arr[] = $arr1[6];
$final_arr[] = $arr4[0];
$final_arr[] = $arr3[3];
$final_arr[] = $arr2[5];
$final_arr[] = $arr1[4];
$final_arr[] = $arr4[2];
$final_arr[] = $arr3[4];
$final_arr[] = $arr2[1];
$final_arr[] = $arr1[0];
$final_arr[] = $arr4[5];
$final_arr[] = $arr3[6];
$final_arr[] = $arr2[3];
$final_arr[] = $arr1[2];
$final_arr[] = $arr4[7];
$final_arr[] = $arr3[5];
$final_arr[] = $arr2[0];
$final_arr[] = $arr1[1];
$final_arr[] = $arr4[4];
$final_arr[] = $arr3[7];
$final_arr[] = $arr2[2];
$final_arr[] = $arr1[3];
$final_arr[] = $arr4[6];
}
if($round == 7){
$final_arr[] = $arr3[0];
$final_arr[] = $arr2[2];
$final_arr[] = $arr1[3];
$final_arr[] = $arr4[1];
$final_arr[] = $arr3[2];
$final_arr[] = $arr2[0];
$final_arr[] = $arr1[1];
$final_arr[] = $arr4[3];
$final_arr[] = $arr3[1];
$final_arr[] = $arr2[3];
$final_arr[] = $arr1[2];
$final_arr[] = $arr4[0];
$final_arr[] = $arr3[3];
$final_arr[] = $arr2[1];
$final_arr[] = $arr1[0];
$final_arr[] = $arr4[2];
}
if($round == 10){
$final_arr[] = $arr3[0];
$final_arr[] = $arr1[0];
$final_arr[] = $arr2[1];
$final_arr[] = $arr4[1];
$final_arr[] = $arr3[1];
$final_arr[] = $arr1[1];
$final_arr[] = $arr2[0];
$final_arr[] = $arr4[0];
}
if($round == 13){
$final_arr[] = $arr3[0];
$final_arr[] = $arr1[0];
$final_arr[] = $arr2[0];
$final_arr[] = $arr4[0];
}
// $group_arr = ['A','B','C','D','E','F','G','H'];
$group_arr = ['1','2','3','4','5','6','7','8'];
if($round == 3){
$group_arr = ['25','26','27','28','29','30','31','32'];
}elseif($round == 4){
$group_arr = ['33','34','35','36','37','38','39','40'];
}elseif($round == 5){
$group_arr = ['41','42','43','44'];
}elseif($round == 7){
$group_arr = ['49','50','51','52'];
}elseif($round == 8){
$group_arr = ['53','54'];
}elseif($round == 10){
$group_arr = ['57','58'];
}elseif($round == 11){
$group_arr = ['59'];
}elseif($round == 13){
$group_arr = ['61'];
}
$u = 0;$j = 0;
foreach ($final_arr as &$b){
if($u == 4){ $u = 0; $j++;}
if($u == 0){
$b['grouping'] = $group_arr[$j];
$b['channel'] = 'R1';
$b['led_color'] = '红';
}
if($u == 1){
$b['grouping'] = $group_arr[$j];
$b['channel'] = 'R2';
$b['led_color'] = '黄';
}
if($u == 2){
$b['grouping'] = $group_arr[$j];
$b['channel'] = 'R6';
$b['led_color'] = '蓝';
}
if($u == 3){
$b['grouping'] = $group_arr[$j];
$b['channel'] = 'R8';
$b['led_color'] = '绿';
}
$u++;
}
return $final_arr;
}
//加赛
public function extra_match($duplicates,$obj_exist,$obj_old_arr,$match_id,$course,$obj_arr){
$duplicateElements = array_keys($duplicates);
// var_dump($duplicateElements);exit;
$res = $this->search_array($obj_old_arr,$duplicateElements[0]);
// var_dump($res);exit;
$obj_arr1 = $obj_exist;
foreach (array_keys($res) as $vv){
unset($obj_exist[$vv]);
}
// var_dump($obj_unset);exit;
$res1 = $this->find_quarank($match_id,$course);
$i = 0;$array = [];
// var_dump($res1);exit;
foreach ($res as $k => $vvv){
$result = $this->search_array($res1,$obj_arr1[$k]['player_id']);
$array = $array + $result;
$i++;
}
// var_dump($array);exit;
ksort($array);
$ccc = array_keys($res);
// var_dump($array);exit;
$i = 0;
foreach ($array as $vvvv){
foreach ($obj_arr1 as $va){
if($va['player_id'] == $vvvv){
$obj_exist[$ccc[$i]] = $va;
$i++;
}
}
}
ksort($obj_exist);$j = 1;
// var_dump($obj_exist);exit;
foreach ($obj_exist as &$val){
$val['group_sort'] = $j;
$obj_arr[] = $val;
$j++;
}
// var_dump($obj_arr);exit;
return $obj_arr;
}
public function find_quarank($match_id,$course){
// $match_id = 606;$course = 101;
$res = $this->leagueService->bestplayerqua($match_id,$course);
foreach ($res as $val){
$new_arr[] = $val['info']['player_id'];
}
// var_dump($new_arr);exit;
return $new_arr;
}
public function search_array($array, $value) {
return array_filter($array, function($item) use ($value) {
return $item == $value;
});
}
public function group_rank_sort($match_id,$course,$other_round){
$matchranking = new MatchRanking();
$all_group = $matchranking->field('grouping,times')->where([
'match_id' => $match_id,
'course' => $course,
'other_round' => $other_round,])->group('grouping')->orderRaw('CAST(grouping AS UNSIGNED)')->select();
$new_group = [];
// if($all_group['times'])
// var_dump($all_group);exit;
foreach($all_group as $value){
$new_group[] = ($value->toArray())['grouping'];
if(empty(($value->toArray())['times'])) {
return '缺少数据1';
}
}
// var_dump($new_times);exit;
$i = 0;$newarr = [];$obj_arr = [];
//组内排序
foreach ($new_group as $val){
// if($i == 1) {var_dump($val);exit;}
$oldarr = $matchranking->where([
'grouping' => $val,
'match_id' => $match_id,
'course' => $course,
'other_round' => $other_round,])
->orderRaw("CASE fly_num
WHEN '3' THEN 1
WHEN '2' THEN 2
WHEN '1' THEN 3
WHEN 'DNF' THEN 4
ELSE 5 END
")
->orderRaw('datetime_value asc,CAST(qua_rank AS UNSIGNED)')->select();
// var_dump($oldarr);exit;
$j = 1;$obj_old_arr= [];$obj_exist=[];
if(!empty($oldarr)){
foreach ($oldarr as $v){
$q = $v->toArray();
$q['group_sort'] = $j;
// $o = $q['times'];
$obj_arr[] = $q;
// $obj_exist[] = $q;
// $obj_old_arr[] = $o;
// $obj_fly_arr[] = $q['fly_num'];
$j++;
}
}
// var_dump(123);exit;
// $obj_arrs = array_count_values($obj_old_arr);
// $duplicates = array_filter($obj_arrs, function($count) {
// return $count > 1;
// });
// var_dump($obj_arrs);exit;
// if(!empty($duplicates)){
// // var_dump($obj_exist);exit;
// array_splice($obj_arr,-4);
// $obj_arr = $this->extra_match($duplicates,$obj_exist,$obj_old_arr,$match_id,$course,$obj_arr);
// }
$i++;
// var_dump($newarr);exit;
}
return $obj_arr;
}
public function insert_group($data,$match_id,$course,$other_round){
$matchranking = new MatchRanking();
Db::startTrans();
try{
foreach ($data as $val){
// var_dump($val);exit;
$match_rank_res = $matchranking->where([
'match_id' => $match_id,
'course' => $course,
'other_round' => $other_round,
'player_id' => $val['player_id'],
])->find();
$player['match_id'] = $match_id;
$player['course'] = $course;
$player['other_round'] = $other_round;
$player['player_id'] = $val['player_id'];
$player['player_name'] = $val['player_name'];
$player['channel'] = $val['channel'];
$player['led_color'] = $val['led_color'];
$player['grouping'] = $val['grouping'];
$player['name_short'] = $val['name_short'];
$player['qua_rank'] = $val['qua_rank'];
if($match_id = '1888'){
$player['country'] = $val['country'];
$player['national_flag'] = $val['national_flag'];
}
if(empty($match_rank_res)){
$matchranking->insert($player);
}
}
// 提交事务
Db::commit();
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
}
}
}

View File

@ -0,0 +1,322 @@
<?php
/**
* @Created by PhpStorm.
* @Author:Soar
* @Time:2023/11/15 15:13
*/
namespace app\admin\controller\cms;
use app\admin\model\LeagueClubIntegral;
use app\admin\model\ClubInvate;
use app\admin\model\LeagueIntegral;
use app\admin\model\MatchContestant;
use app\admin\model\MatchRanking;
use app\admin\model\MatchScreen;
use app\admin\model\Players;
use app\admin\model\User;
use app\common\controller\Backend;
use app\admin\service\RankingService;
use app\admin\controller\cms\Leagueround;
use app\admin\service\LeagueService;
class Leaguesort extends Backend
{
protected $noNeedLogin = [];
public function _initialize()
{
parent::_initialize();
$this->rankingService = new RankingService();
$this->leagueRound = new Leagueround();
$this->leagueService = new LeagueService();
}
public function integral(){
// return json($success);
// var_dump($res_sen);exit;
$user = new User();
$palyer = new Players();
$ClubInvate = new ClubInvate();
$LeagueIntegral = new LeagueIntegral();
$MatchRanking = new MatchRanking();
$LeagueClubIntegral = new LeagueClubIntegral();
$match_id = $this->request->param('match_id');
$inte_exsit = $LeagueIntegral->where('match_id',$match_id)->find();
// $res_sen = $this->leagueService->bestplayerqua($match_id,101);
// $res_sen = array_slice($res_sen,64);
// $res13 = $this->leagueRound->group_rank_sort($match_id,103,13);
// // $res = $this->extra_match($new_arr,$match_id,103);
// var_dump($res13);exit;
$res = $LeagueIntegral->where('match_id',$match_id)->delete();
$res1 = $LeagueClubIntegral->where('match_id',$match_id)->delete();
// var_dump($res);exit;
// $mess_arr = array('code'=>0,'message'=>'该赛事已生成过排名');
// if($inte_exsit) return json($mess_arr);
$result = $MatchRanking->where(['match_id'=>$match_id,'course'=>104,'other_round'=>1])->find();
if(empty($result)) $this->error('已清空积分');
// var_dump($result['is_extra']);exit;
if($result['is_extra'] == 1){
$res = $MatchRanking->where(['match_id'=>$match_id,'course'=>104,'other_round'=>1])->order('custom_sorting')->select();
}else{
// $res = $this->leagueRound->final_rank($match_id);
$res = $this->leagueService->get_final_integral_rank($match_id,104);
}
$res13 = $this->leagueRound->group_rank_sort($match_id,103,13);
$res11 = $this->leagueRound->group_rank_sort($match_id,103,11);
$res10 = $this->leagueRound->group_rank_sort($match_id,103,10);
$res8 = $this->leagueRound->group_rank_sort($match_id,103,8);
$res7 = $this->leagueRound->group_rank_sort($match_id,103,7);
$res5 = $this->leagueRound->group_rank_sort($match_id,103,5);
$res4 = $this->leagueRound->group_rank_sort($match_id,103,4);
$res3 = $this->leagueRound->group_rank_sort($match_id,103,3);
// var_dump($res);exit;
//前四名
$i = 1;
foreach ($res as $v){
$user_res = $user->where('member_number',$v['player_id'])->find();
$player_res = $palyer->where('member_id',$user_res['id'])->find();
$club_res = $ClubInvate->where('player_id',$player_res['id'])->where('status',6)->where('deletetime',null)->find();
// var_dump($club_res);exit;
$LeagueIntegral->insert([
'match_id' => $match_id,
'player_id' => $v['player_id'],
'player_name' => $v['player_name'],
'club_id' => !empty($club_res) ? $club_res['club_id'] : '',
'club_name' => !empty($club_res) ? $club_res['club_name'] : '',
'gender' => $player_res['gender'],
'birthday' => $player_res['birthday'],
'name_short' => $club_res['name_short'],
'number' => $i,
'grade' => $this->numtograde($i),
'createtime' => time(),
]);
$i++;
}
// var_dump($res);exit;
//5-8名
$eve_arr = [$res13,$res11];
$i = 5;
foreach($eve_arr as $val){
$new_arr = [];
foreach ($val as $value) {
if(in_array($value['group_sort'],array(3,4))){
$new_arr[] = $value;
}
}
// $res = $this->extra_match($new_arr,$match_id,103);
// exit;
foreach ($new_arr as $v){
$user_res = $user->where('member_number',$v['player_id'])->find();
$player_res = $palyer->where('member_id',$user_res['id'])->find();
$club_res = $ClubInvate->where('player_id',$player_res['id'])->where('status',6)->where('deletetime',null)->find();
$LeagueIntegral->insert([
'match_id' => $match_id,
'player_id' => $v['player_id'],
'player_name' => $v['player_name'],
'club_id' => !empty($club_res) ? $club_res['club_id'] : '',
'club_name' => !empty($club_res) ? $club_res['club_name'] : '',
'gender' => $player_res['gender'],
'birthday' => $player_res['birthday'],
'name_short' => $club_res['name_short'],
'number' => $i,
'grade' => $this->numtograde($i),
'createtime' => time(),
]);
$i++;
}
}
//9-64名
$com_arr = [$res10,$res8,$res7,$res5,$res4,$res3];
$i = 9;
foreach($com_arr as $val){
$new_arr = [];
foreach ($val as $value) {
if(in_array($value['group_sort'],array(3,4))){
$new_arr[] = $value;
}
}
$res = $this->extra_match($new_arr,$match_id,103);
// exit;
foreach ($res as $v){
$user_res = $user->where('member_number',$v['player_id'])->find();
$player_res = $palyer->where('member_id',$user_res['id'])->find();
$club_res = $ClubInvate->where('player_id',$player_res['id'])->where('status',6)->where('deletetime',null)->find();
$LeagueIntegral->insert([
'match_id' => $match_id,
'player_id' => $v['player_id'],
'player_name' => $v['player_name'],
'club_id' => !empty($club_res) ? $club_res['club_id'] : '',
'club_name' => !empty($club_res) ? $club_res['club_name'] : '',
'gender' => $player_res['gender'],
'birthday' => $player_res['birthday'],
'name_short' => $club_res['name_short'],
'number' => $i,
'grade' => $this->numtograde($i),
'createtime' => time(),
]);
$i++;
}
}
$i = 65;
//64名之后排位赛有1轮成绩的积1分
$res_sen = $this->leagueService->bestplayerqua($match_id,101);
$res_sen = array_slice($res_sen,64);
//TODO先循环拿出fly_num=0 再查组合老数组
foreach($res_sen as $vvv){
// if($vvv['fly_num'] >= 3){
// var_dump($vvv);exit;
if($vvv['fly_num'] > 0 || $vvv['fly_num'] == 'DNF'){
$user_res = $user->where('member_number',$vvv['info']['player_id'])->find();
if(empty($user_res['id'])){var_dump($vvv);exit;}
$player_res = $palyer->where('member_id',$user_res['id'])->find();
$club_res = $ClubInvate->where('player_id',$player_res['id'])->where('status',6)->where('deletetime',null)->find();
$LeagueIntegral->insert([
'match_id' => $match_id,
'player_id' => $vvv['info']['player_id'],
'player_name' => $vvv['info']['player_name'],
'club_id' => !empty($club_res) ? $club_res['club_id'] : '',
'club_name' => !empty($club_res) ? $club_res['club_name'] : '',
'gender' => $player_res['gender'],
'birthday' => $player_res['birthday'],
'name_short' => $club_res['name_short'],
'number' => $i,
'grade' => ($vvv['fly_num'] >= 3) ? 1 : 0,
'createtime' => time(),
]);
$i++;
}
}
//分站赛队伍总积分
$all_club = $LeagueIntegral->where('match_id',$match_id)->where('club_id','>',0)->group('club_id')->select();
foreach ($all_club as $val){
$signle_club = $LeagueIntegral->where('match_id',$match_id)->where('club_id',$val['club_id'])->order('grade desc')->limit(4)->select();
// var_dump($signle_club[0]['sum_grade']);exit;
$all_grade = 0;
foreach ($signle_club as $va){
$all_grade = $va['grade'] + $all_grade;
}
$LeagueClubIntegral->insert([
'match_id' => $match_id,
'club_id'=>$val['club_id'],
'club_name'=>$val['club_name'],
'name_short' => $val['name_short'],
'sum_grade'=>$all_grade,
'createtime' => time(),
]);
}
//分站赛队伍总积分排序
$integral_club_res1 = $LeagueClubIntegral->where(['match_id' => $match_id])->order('sum_grade desc')->select();
$previousValue = null;$i = 1;
foreach ( $integral_club_res1 as $val){
if ($previousValue !== null) {
if($val['sum_grade'] != $previousValue){
$i = $i + 1;
}
}
$LeagueClubIntegral->where('id',$val['id'])->update([
'number' => $i,
]);
$previousValue = $val['sum_grade'];
}
// var_dump($res);exit;
$success = array('code'=>1,'message'=>'success');
return json($success);
}
public function numtograde($number){
if($number == 1) $grade = 20;
if($number == 2) $grade = 17;
if($number == 3) $grade = 15;
if($number == 4) $grade = 13;
if($number>= 5 && $number<= 8) $grade = 12;
if($number>= 9 && $number<= 16) $grade = 10;
if($number>= 17 && $number<= 32) $grade = 8;
if($number>= 33 && $number<= 48) $grade = 6;
if($number>= 49 && $number<= 64) $grade = 4;
// if($number>= 5 && $number<= 8) $grade = 12;
return $grade;
}
//决赛是否有加赛
public function is_extra(){
$match_id = $this->request->param('match_id');
$is_open = $this->request->param('is_open');
$MatchRanking = new MatchRanking();
$result = $MatchRanking->where(['match_id'=>$match_id,'course'=>104,'other_round' => 1,])->select();
foreach ($result as $v){
$MatchRanking->where('id', $v['id'])
->update(['is_extra'=>$is_open]);
}
if(true){
$data = ['code'=>1,'message'=>'success'];
return json($data);
}else{
$data = ['code'=>0,'message'=>'fail'];
return json($data);
}
}
public function custom_rank(){
$MatchRanking = new MatchRanking();
// var_dump($_POST);exit;
if(empty($_POST['data']) || empty($_POST['match_id']))$this->error('lack param');
foreach ($_POST['data'] as $v){
// var_dump($v);exit;
$MatchRanking->where(['match_id'=> $_POST['match_id'],'course'=>104,'other_round'=>1,'is_extra'=>1,'player_id'=>$v['player_id']])
->update(['custom_sorting'=>$v['custom_sorting']]);
}
$data = ['code'=>1,'message'=>'success'];
return json($data);
}
public function find_sort($match_id,$course,$other_round){
$res = $this->leagueRound->group_rank_sort($match_id,$course,$other_round);
foreach ($res as $value) {
if(in_array($value['group_sort'],array(3,4))){
$new_arr[] = $value;
}
}
$res = $this->extra_match($new_arr,$match_id,$course);
//存表 差俱乐部id
}
public function aaa(){
$match_id = 606;$course = 101;
$res = $this->leagueService->bestplayerqua($match_id,$course);
var_dump($res);exit;
}
//加赛
public function extra_match($data,$match_id,$course){
$res1 = $this->find_quarank($match_id,$course);
// var_dump($res1);exit;
foreach ($res1 as $vvvv){
foreach ($data as $va){
if($va['player_id'] == $vvvv){
$obj_arr[] = $va;
}
}
}
// var_dump($obj_arr);exit;
// var_dump($obj_arr);exit;
return $obj_arr;
}
public function find_quarank($match_id,$course){
// $match_id = 606;$course = 101;
$res = $this->leagueService->bestplayerqua($match_id,$course);
foreach ($res as $val){
$new_arr[] = $val['info']['player_id'];
}
// var_dump($new_arr);exit;
return $new_arr;
}
}

View File

@ -0,0 +1,296 @@
<?php
namespace app\admin\controller\cms;
use app\admin\model\MatchContestant;
use app\admin\model\MatchRanking;
use app\admin\model\MatchScreen;
use app\admin\model\Players;
use app\admin\model\User;
use app\common\controller\Backend;
use app\admin\service\LeagueService;
use app\common\exception\UploadException;
use app\common\library\Upload;
use fast\Random;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use think\Cookie;
use think\Session;
use think\Db;
use app\admin\controller\cms\Leagueround;
class Leaguexport extends Backend
{
protected $noNeedLogin = ['*'];
public function _initialize()
{
parent::_initialize();
$this->leagueService = new LeagueService();
}
public function arr(){
$a=array("a"=>"red","b"=>"green","c"=>"blue",'d'=>"red");
foreach ($a as $k => $v){
if($v == 'red')
$key[] = $k;
}
var_dump($key);exit;
// echo array_search("red",$a);exit;
// $array[0] = '王一博';
// $array[3] = '贾乃亮';
// $array[1] = '王梓烨';
// $array[2] = '金传博';
// var_dump($array);
// ksort($array);
// var_dump($array);exit;
}
//生成分组
public function click_group(){
$matchranking = new MatchRanking();
$match_id = $this->request->param("match_id");
$course = $this->request->param("course"); // 赛程
$other_round = $this->request->param("other_round"); // 赛程
$result = $matchranking->where('match_id',$match_id)->where('course',103)->where('other_round',$other_round)->find();
if(!empty($result)) {$this->error('该分组已生成过');}
if($other_round == 1) $this->click_groups($match_id,$course,$other_round);
if($other_round == 2 || $other_round == 3 ) {
$leagueround = new Leagueround();
$leagueround->group_round2($match_id,$course,$other_round);
}
if($other_round == 6 ) {
$leagueround = new Leagueround();
$leagueround->group_round6($match_id,$course,$other_round);
}
if($other_round == 4 || $other_round == 7 || $other_round == 10 || $other_round == 13) {
$leagueround = new Leagueround();
$leagueround->group_round4($match_id,$course,$other_round);
}
if($other_round == 5 || $other_round == 8 || $other_round == 11) {
$leagueround = new Leagueround();
$leagueround->group_round5($match_id,$course,$other_round);
}
}
//淘汰赛第一轮
public function click_groups($match_id,$course,$other_round){
$matchranking = new MatchRanking();
$this->exportmatch_id = $match_id;
$this->exportcourse = $course; // 赛程
$this->other_round = $other_round; // 赛程
// $this->exportmatch_id = 606;$this->exportcourse= 103;
if(empty($this->other_round) || empty($this->exportmatch_id) || empty($this->exportcourse)) $this->error('缺少参数');
$res = $this->export_group($this->exportmatch_id, $this->exportcourse);
// var_dump($res);exit;
// 启动事务
Db::startTrans();
try{
foreach ($res as $val){
// var_dump($val);exit;
$match_rank_res = $matchranking->where([
'match_id' => $this->exportmatch_id,
'course' => $this->exportcourse,
'other_round' => $this->other_round,
'player_id' => $val['info']['player_id'],
])->find();
$player['match_id'] = $this->exportmatch_id;
$player['course'] = $this->exportcourse;
$player['other_round'] = $this->other_round;
$player['player_id'] = $val['info']['player_id'];
$player['player_name'] = $val['info']['player_name'];
$player['channel'] = $val['info']['channel'];
$player['led_color'] = $val['info']['led_color'];
$player['grouping'] = $val['info']['grouping'];
$player['name_short'] = $val['info']['name_short'];
$player['qua_rank'] = $val['info']['qua_rank'];
$player['country'] = $val['info']['country'];
$player['national_flag'] = $val['info']['national_flag'];
if(empty($match_rank_res)){
$matchranking->insert($player);
}
}
// 提交事务
Db::commit();
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
}
$this->success('build success');
}
//导出分组
public function export_wash()
{
$matchranking = new MatchRanking();
$this->exportmatch_id = $this->request->param("match_id");
$this->exportcourse = $this->request->param("course"); // 赛程
$this->other_round = $this->request->param("other_round"); // 赛程
// $this->exportcourse = 101;
$archives = new \app\admin\model\cms\Archives();
$PDOStatement = $archives->find($this->exportmatch_id);
$row = $matchranking->where([
'match_id' =>$this->exportmatch_id,
'course' => $this->exportcourse,
'other_round' => $this->other_round,
])->select();
// var_dump($this->exportmatch_id);exit;
if (empty($PDOStatement)) {
$this->error('导出数据为空');
}
$cellTitles = [
'grouping' => '组别',
'player_id' => '编号',
'player_name' => '姓名',
'name_short' => '所属队伍',
'channel' => '频道',
'led_color' => 'LED颜色',
];
// 数据总条数
$total = count($row);
if ($total <= 0) {
$this->error('导出数据为空');
}
$which_round = $this->win_or_lose_group($this->other_round);
switch ($this->exportcourse) {
case 103:
$PDOStatement->title = $PDOStatement->title."淘汰赛【第".$this->other_round.'轮'.$which_round['which_round'].'组】'.$which_round['status'].'分组名单';
break;
case 104:
$PDOStatement->title = $PDOStatement->title."决赛分组名单";
break;
}
$export = new \addons\shopro\library\Export();
// var_dump($PDOStatement->title);exit;
$params = [
'file_name' => $PDOStatement->title,
'cell_titles' => $cellTitles,
'total' => $total,
'is_sub_cell' => false,
];
$total_commission = 0;
$config = $export->getConfig();
$result = $export->export_group_wash($params, function ($pages) use (&$total_commission, $total) {
$matchranking = new MatchRanking();
$res = $matchranking->where([
'match_id' =>$this->exportmatch_id,
'course' => $this->exportcourse,
'other_round' => $this->other_round,
])
->orderRaw('CAST(grouping AS UNSIGNED),CASE led_color
WHEN "" THEN 1
WHEN "" THEN 2
WHEN "" THEN 3
WHEN "绿" THEN 4
ELSE 5 END')->select();
// var_dump($res);exit;
foreach ($res as &$val){
$val = $val->toArray();
}
$datas = $res;
$newDatas = [];
foreach ($datas as &$reward) {
$data = [
'player_id' => $reward['player_id'] ? $reward['player_id'] : 0,
'player_name' => $reward['player_name'],
'name_short' => $reward['name_short'],
'grouping' => $reward['grouping'],
'channel' => $reward['channel'],
'led_color' => $reward['led_color'],
];
$newDatas[] = $data;
}
// }
$total_commission += array_sum(array_column($newDatas, 'commission'));
return $newDatas;
});
$this->success('导出成功' . (isset($result['file_path']) && $result['file_path'] ? ',请在服务器: “' . $result['file_path'] . '” 查看' : ''), null, $result);
}
public function win_or_lose_group($other_round){
switch ($other_round) {
case 1: $which_round['which_round'] = '1-16';$which_round['status'] = '胜者组';break;
case 2: $which_round['which_round'] = '17-24';$which_round['status'] = '胜者组';break;
case 3: $which_round['which_round'] = '25-32';$which_round['status'] = '败者组';break;
case 4: $which_round['which_round'] = '33-40';$which_round['status'] = '败者组';break;
case 5: $which_round['which_round'] = '41-44';$which_round['status'] = '败者组';break;
case 6: $which_round['which_round'] = '45-48';$which_round['status'] = '胜者组';break;
case 7: $which_round['which_round'] = '49-52';$which_round['status'] = '败者组';break;
case 8: $which_round['which_round'] = '53-54';$which_round['status'] = '败者组';break;
case 9: $which_round['which_round'] = '55-56';$which_round['status'] = '胜者组';break;
case 10: $which_round['which_round'] = '57-58';$which_round['status'] = '败者组';break;
case 11: $which_round['which_round'] = '59';$which_round['status'] = '败者组';break;
case 12: $which_round['which_round'] = '60';$which_round['status'] = '胜者组';break;
case 13: $which_round['which_round'] = '61';$which_round['status'] = '败者组';break;
}
return $which_round;
}
private function taotaiorder(){
$arr = ['0' => 1,'4'=>16,'8'=>8,'12'=>14,'16'=>4,'20'=>12,'24'=>6,'28'=>10,'32'=>9,'36'=>5,'40'=>11,'44'=>3,'48'=>13,'52'=>7,'56'=>15,'60'=>2];
foreach ($arr as $k => $val){
$arr[$k + 1] = $val + 16;
$arr[$k + 2] = $val + 32;
$arr[$k + 3] = $val + 48;
}
ksort($arr);
return $arr;
// var_dump($arr);exit;
}
public function export_group($match_id,$course){
// $match_id = $this->request->param("match_id");
// $course = $this->request->param("course"); // 赛程
// $match_id = 606;$course = 101;
$group_arr = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P'];
$group_arr = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16'];
$res_data = $this->leagueService->bestplayerqua($match_id,$course);
if(count($res_data) < 64) $this->error('资格赛人数小于64');
// var_dump($res_data);exit;
$arr = $this->taotaiorder();
// var_dump($arr);exit;
$i = 0; $a = 0; $b = 0;
foreach ($arr as $val){
if($a == 4) {$a = 0;$b = $b + 1;}
$new_arr[$i] = $res_data[$val - 1];
if($a == 0){
$new_arr[$i]['info']['channel'] = 'R1';
$new_arr[$i]['info']['led_color'] = '红';
$new_arr[$i]['info']['grouping'] = $group_arr[$b];
}elseif($a == 1){
$new_arr[$i]['info']['channel'] = 'R2';
$new_arr[$i]['info']['led_color'] = '黄';
$new_arr[$i]['info']['grouping'] = $group_arr[$b];
}elseif($a == 2){
$new_arr[$i]['info']['channel'] = 'R6';
$new_arr[$i]['info']['led_color'] = '蓝';
$new_arr[$i]['info']['grouping'] = $group_arr[$b];
}elseif($a == 3){
$new_arr[$i]['info']['channel'] = 'R8';
$new_arr[$i]['info']['led_color'] = '绿';
$new_arr[$i]['info']['grouping'] = $group_arr[$b];
}
$new_arr[$i]['info']['qua_rank'] = $val;
$i++;
$a++;
}
return $new_arr;
// var_dump($new_arr);exit;
}
}

View File

@ -0,0 +1,85 @@
<?php
namespace app\admin\controller\cms;
use addons\cms\library\Service;
use app\common\controller\Backend;
use think\Db;
use think\Exception;
/**
* 内容模型表
*
* @icon fa fa-th
*/
class Modelx extends Backend
{
/**
* Model模型对象
*/
protected $model = null;
protected $searchFields = 'id,name,table,channeltpl,listtpl,showtpl';
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\cms\Modelx;
}
/**
* 复制模型
*/
public function duplicate($ids = "")
{
$row = $this->model->get($ids);
if (!$row) {
$this->error(__('No Results were found'));
}
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
if (!in_array($row[$this->dataLimitField], $adminIds)) {
$this->error(__('You have no permission'));
}
}
if ($this->request->isPost()) {
$table = $this->request->request("table");
$tableInfo = null;
try {
$tableInfo = \think\Db::name($table)->getTableInfo();
} catch (\Exception $e) {
}
if ($tableInfo) {
$this->error("模型表名已经存在");
}
Db::startTrans();
try {
$data = [
'name' => $row->getData('name') . '_copy',
'table' => $table,
'fields' => $row->fields,
'channeltpl' => $row->channeltpl,
'listtpl' => $row->listtpl,
'showtpl' => $row->showtpl,
'setting' => $row->setting,
];
$modelx = \app\admin\model\cms\Modelx::create($data, true);
$fieldsList = \app\admin\model\cms\Fields::where('source', 'model')->where('source_id', $row['id'])->select();
foreach ($fieldsList as $index => $item) {
$data = $item->toArray();
$data['source_id'] = $modelx->id;
unset($data['id'], $data['createtime'], $data['updatetime']);
\app\admin\model\cms\Fields::create($data, true);
}
Db::commit();
} catch (\Exception $e) {
Db::rollback();
$this->error("复制失败,错误:" . $e->getMessage());
}
$this->success();
}
$this->view->assign("row", $row);
return $this->view->fetch();
}
}

Some files were not shown because too many files have changed in this diff Show More