mirror of https://gitee.com/karson/fastadmin.git
新增CRUD生成回收站视图和JS文件
新增一键生成API文档排序功能 新增表格默认导出选项 新增buttons中text和title的function支持 修复buttons中visible和disable为false时的判断Bug 修复后台添加子管理员的权限错误pull/98/MERGE
parent
a329e5fbb2
commit
88226015a8
|
|
@ -15,7 +15,6 @@ use think\exception\PDOException;
|
||||||
|
|
||||||
class Addon extends Command
|
class Addon extends Command
|
||||||
{
|
{
|
||||||
|
|
||||||
protected function configure()
|
protected function configure()
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
|
|
@ -80,7 +79,6 @@ class Addon extends Command
|
||||||
$createTableSql = $result[0]['Create Table'];
|
$createTableSql = $result[0]['Create Table'];
|
||||||
}
|
}
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
|
|
@ -235,7 +233,8 @@ class Addon extends Command
|
||||||
$zip->open($addonFile, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
|
$zip->open($addonFile, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
|
||||||
|
|
||||||
$files = new \RecursiveIteratorIterator(
|
$files = new \RecursiveIteratorIterator(
|
||||||
new \RecursiveDirectoryIterator($addonDir), \RecursiveIteratorIterator::LEAVES_ONLY
|
new \RecursiveDirectoryIterator($addonDir),
|
||||||
|
\RecursiveIteratorIterator::LEAVES_ONLY
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach ($files as $name => $file) {
|
foreach ($files as $name => $file) {
|
||||||
|
|
@ -251,7 +250,7 @@ class Addon extends Command
|
||||||
$output->info("Package Successed!");
|
$output->info("Package Successed!");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default :
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -315,5 +314,4 @@ class Addon extends Command
|
||||||
{
|
{
|
||||||
return __DIR__ . '/Addon/stubs/' . $name . '.stub';
|
return __DIR__ . '/Addon/stubs/' . $name . '.stub';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ use think\Exception;
|
||||||
|
|
||||||
class Api extends Command
|
class Api extends Command
|
||||||
{
|
{
|
||||||
|
|
||||||
protected function configure()
|
protected function configure()
|
||||||
{
|
{
|
||||||
$site = Config::get('site');
|
$site = Config::get('site');
|
||||||
|
|
@ -84,7 +83,8 @@ class Api extends Command
|
||||||
|
|
||||||
$controllerDir = $moduleDir . Config::get('url_controller_layer') . DS;
|
$controllerDir = $moduleDir . Config::get('url_controller_layer') . DS;
|
||||||
$files = new \RecursiveIteratorIterator(
|
$files = new \RecursiveIteratorIterator(
|
||||||
new \RecursiveDirectoryIterator($controllerDir), \RecursiveIteratorIterator::LEAVES_ONLY
|
new \RecursiveDirectoryIterator($controllerDir),
|
||||||
|
\RecursiveIteratorIterator::LEAVES_ONLY
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach ($files as $name => $file) {
|
foreach ($files as $name => $file) {
|
||||||
|
|
@ -150,7 +150,7 @@ class Api extends Command
|
||||||
|
|
||||||
//Append the token's value to the name of the namespace
|
//Append the token's value to the name of the namespace
|
||||||
$namespace .= $token[1];
|
$namespace .= $token[1];
|
||||||
} else if ($token === ';') {
|
} elseif ($token === ';') {
|
||||||
|
|
||||||
//If the token is the semicolon, then we're done with the namespace declaration
|
//If the token is the semicolon, then we're done with the namespace declaration
|
||||||
$getting_namespace = false;
|
$getting_namespace = false;
|
||||||
|
|
@ -175,5 +175,4 @@ class Api extends Command
|
||||||
//Build the fully-qualified class name and return it
|
//Build the fully-qualified class name and return it
|
||||||
return $namespace ? $namespace . '\\' . $class : $class;
|
return $namespace ? $namespace . '\\' . $class : $class;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,16 +36,27 @@ class Builder
|
||||||
|
|
||||||
protected function extractAnnotations()
|
protected function extractAnnotations()
|
||||||
{
|
{
|
||||||
$st_output = [];
|
|
||||||
foreach ($this->classes as $class) {
|
foreach ($this->classes as $class) {
|
||||||
$classAnnotation = Extractor::getClassAnnotations($class);
|
$classAnnotation = Extractor::getClassAnnotations($class);
|
||||||
// 如果忽略
|
// 如果忽略
|
||||||
if (isset($classAnnotation['ApiInternal'])) {
|
if (isset($classAnnotation['ApiInternal'])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$st_output[] = Extractor::getAllClassAnnotations($class);
|
Extractor::getClassMethodAnnotations($class);
|
||||||
}
|
}
|
||||||
return end($st_output);
|
$allClassAnnotation = Extractor::getAllClassAnnotations();
|
||||||
|
$allClassMethodAnnotation = Extractor::getAllClassMethodAnnotations();
|
||||||
|
|
||||||
|
// 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)
|
protected function generateHeadersTemplate($docs)
|
||||||
|
|
@ -148,12 +159,19 @@ class Builder
|
||||||
|
|
||||||
public function parse()
|
public function parse()
|
||||||
{
|
{
|
||||||
$annotations = $this->extractAnnotations();
|
list($allClassAnnotations, $allClassMethodAnnotations) = $this->extractAnnotations();
|
||||||
|
|
||||||
|
$sectorArr = [];
|
||||||
|
foreach ($allClassAnnotations as $index => $allClassAnnotation) {
|
||||||
|
$sector = isset($allClassAnnotation['ApiSector']) ? $allClassAnnotation['ApiSector'][0] : $allClassAnnotation['ApiTitle'][0];
|
||||||
|
$sectorArr[$sector] = isset($allClassAnnotation['ApiWeigh']) ? $allClassAnnotation['ApiWeigh'][0] : 0;
|
||||||
|
}
|
||||||
|
arsort($sectorArr);
|
||||||
$counter = 0;
|
$counter = 0;
|
||||||
$section = null;
|
$section = null;
|
||||||
|
$weigh = 0;
|
||||||
$docslist = [];
|
$docslist = [];
|
||||||
foreach ($annotations as $class => $methods) {
|
foreach ($allClassMethodAnnotations as $class => $methods) {
|
||||||
foreach ($methods as $name => $docs) {
|
foreach ($methods as $name => $docs) {
|
||||||
if (isset($docs['ApiSector'][0])) {
|
if (isset($docs['ApiSector'][0])) {
|
||||||
$section = is_array($docs['ApiSector'][0]) ? $docs['ApiSector'][0]['data'] : $docs['ApiSector'][0];
|
$section = is_array($docs['ApiSector'][0]) ? $docs['ApiSector'][0]['data'] : $docs['ApiSector'][0];
|
||||||
|
|
@ -163,25 +181,36 @@ class Builder
|
||||||
if (0 === count($docs)) {
|
if (0 === count($docs)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
$docslist[$section][$name] = [
|
||||||
$docslist[$section][] = [
|
|
||||||
'id' => $counter,
|
'id' => $counter,
|
||||||
'method' => is_array($docs['ApiMethod'][0]) ? $docs['ApiMethod'][0]['data'] : $docs['ApiMethod'][0],
|
'method' => is_array($docs['ApiMethod'][0]) ? $docs['ApiMethod'][0]['data'] : $docs['ApiMethod'][0],
|
||||||
'method_label' => $this->generateBadgeForMethod($docs),
|
'method_label' => $this->generateBadgeForMethod($docs),
|
||||||
'section' => $section,
|
'section' => $section,
|
||||||
'route' => is_array($docs['ApiRoute'][0]) ? $docs['ApiRoute'][0]['data'] : $docs['ApiRoute'][0],
|
'route' => is_array($docs['ApiRoute'][0]) ? $docs['ApiRoute'][0]['data'] : $docs['ApiRoute'][0],
|
||||||
'title' => is_array($docs['ApiTitle'][0]) ? $docs['ApiTitle'][0]['data'] : $docs['ApiTitle'][0],
|
'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],
|
'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] : '',
|
'body' => isset($docs['ApiBody'][0]) ? is_array($docs['ApiBody'][0]) ? $docs['ApiBody'][0]['data'] : $docs['ApiBody'][0] : '',
|
||||||
'headerslist' => $this->generateHeadersTemplate($docs),
|
'headerslist' => $this->generateHeadersTemplate($docs),
|
||||||
'paramslist' => $this->generateParamsTemplate($docs),
|
'paramslist' => $this->generateParamsTemplate($docs),
|
||||||
'returnheaderslist' => $this->generateReturnHeadersTemplate($docs),
|
'returnheaderslist' => $this->generateReturnHeadersTemplate($docs),
|
||||||
'returnparamslist' => $this->generateReturnParamsTemplate($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] : '',
|
'return' => isset($docs['ApiReturn']) ? is_array($docs['ApiReturn'][0]) ? $docs['ApiReturn'][0]['data'] : $docs['ApiReturn'][0] : '',
|
||||||
];
|
];
|
||||||
$counter++;
|
$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;
|
return $docslist;
|
||||||
}
|
}
|
||||||
|
|
@ -203,5 +232,4 @@ class Builder
|
||||||
|
|
||||||
return $this->view->display(file_get_contents($template), array_merge($vars, ['docslist' => $docslist]));
|
return $this->view->display(file_get_contents($template), array_merge($vars, ['docslist' => $docslist]));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@ class Extractor
|
||||||
*/
|
*/
|
||||||
private static $annotationCache;
|
private static $annotationCache;
|
||||||
|
|
||||||
|
private static $classAnnotationCache;
|
||||||
|
|
||||||
|
private static $classMethodAnnotationCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that annotations should has strict behavior, 'false' by default
|
* Indicates that annotations should has strict behavior, 'false' by default
|
||||||
* @var boolean
|
* @var boolean
|
||||||
|
|
@ -63,27 +67,43 @@ class Extractor
|
||||||
* Gets all anotations with pattern @SomeAnnotation() from a given class
|
* Gets all anotations with pattern @SomeAnnotation() from a given class
|
||||||
*
|
*
|
||||||
* @param string $className class name to get annotations
|
* @param string $className class name to get annotations
|
||||||
* @return array self::$annotationCache all annotated elements
|
* @return array self::$classAnnotationCache all annotated elements
|
||||||
*/
|
*/
|
||||||
public static function getClassAnnotations($className)
|
public static function getClassAnnotations($className)
|
||||||
{
|
{
|
||||||
if (!isset(self::$annotationCache[$className])) {
|
if (!isset(self::$classAnnotationCache[$className])) {
|
||||||
$class = new \ReflectionClass($className);
|
$class = new \ReflectionClass($className);
|
||||||
self::$annotationCache[$className] = self::parseAnnotations($class->getDocComment());
|
self::$classAnnotationCache[$className] = self::parseAnnotations($class->getDocComment());
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$annotationCache[$className];
|
return self::$classAnnotationCache[$className];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getAllClassAnnotations($className)
|
/**
|
||||||
|
* 获取类所有方法的属性配置
|
||||||
|
* @param $className
|
||||||
|
* @return mixed
|
||||||
|
* @throws \ReflectionException
|
||||||
|
*/
|
||||||
|
public static function getClassMethodAnnotations($className)
|
||||||
{
|
{
|
||||||
$class = new \ReflectionClass($className);
|
$class = new \ReflectionClass($className);
|
||||||
|
|
||||||
foreach ($class->getMethods() as $object) {
|
foreach ($class->getMethods() as $object) {
|
||||||
self::$annotationCache['annotations'][$className][$object->name] = self::getMethodAnnotations($className, $object->name);
|
self::$classMethodAnnotationCache[$className][$object->name] = self::getMethodAnnotations($className, $object->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$annotationCache['annotations'];
|
return self::$classMethodAnnotationCache[$className];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getAllClassAnnotations()
|
||||||
|
{
|
||||||
|
return self::$classAnnotationCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getAllClassMethodAnnotations()
|
||||||
|
{
|
||||||
|
return self::$classMethodAnnotationCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -181,14 +201,14 @@ class Extractor
|
||||||
preg_match_all("/\*[\s]+(.*)(\\r\\n|\\r|\\n)/U", str_replace('/**', '', $docblockMethod), $methodArr);
|
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);
|
preg_match_all("/\*[\s]+(.*)(\\r\\n|\\r|\\n)/U", str_replace('/**', '', $dockblockClass), $classArr);
|
||||||
|
|
||||||
$methodTitle = isset($methodArr[1]) && isset($methodArr[1][0]) ? $methodArr[1][0] : '';
|
|
||||||
$classTitle = isset($classArr[1]) && isset($classArr[1][0]) ? $classArr[1][0] : '';
|
|
||||||
|
|
||||||
if (!isset($methodAnnotations['ApiMethod'])) {
|
if (!isset($methodAnnotations['ApiMethod'])) {
|
||||||
$methodAnnotations['ApiMethod'] = ['get'];
|
$methodAnnotations['ApiMethod'] = ['get'];
|
||||||
}
|
}
|
||||||
|
if (!isset($methodAnnotations['ApiWeigh'])) {
|
||||||
|
$methodAnnotations['ApiWeigh'] = [0];
|
||||||
|
}
|
||||||
if (!isset($methodAnnotations['ApiSummary'])) {
|
if (!isset($methodAnnotations['ApiSummary'])) {
|
||||||
$methodAnnotations['ApiSummary'] = [$methodTitle];
|
$methodAnnotations['ApiSummary'] = $methodAnnotations['ApiTitle'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($methodAnnotations) {
|
if ($methodAnnotations) {
|
||||||
|
|
@ -210,9 +230,6 @@ class Extractor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isset($methodAnnotations['ApiTitle'])) {
|
|
||||||
$methodAnnotations['ApiTitle'] = [$methodTitle];
|
|
||||||
}
|
|
||||||
if (!isset($methodAnnotations['ApiRoute'])) {
|
if (!isset($methodAnnotations['ApiRoute'])) {
|
||||||
$urlArr = [];
|
$urlArr = [];
|
||||||
$className = $class->getName();
|
$className = $class->getName();
|
||||||
|
|
@ -231,7 +248,7 @@ class Extractor
|
||||||
$methodAnnotations['ApiRoute'] = [implode('/', $urlArr)];
|
$methodAnnotations['ApiRoute'] = [implode('/', $urlArr)];
|
||||||
}
|
}
|
||||||
if (!isset($methodAnnotations['ApiSector'])) {
|
if (!isset($methodAnnotations['ApiSector'])) {
|
||||||
$methodAnnotations['ApiSector'] = isset($classAnnotations['ApiSector']) ? $classAnnotations['ApiSector'] : [$classTitle];
|
$methodAnnotations['ApiSector'] = isset($classAnnotations['ApiSector']) ? $classAnnotations['ApiSector'] : $classAnnotations['ApiTitle'];
|
||||||
}
|
}
|
||||||
if (!isset($methodAnnotations['ApiParams'])) {
|
if (!isset($methodAnnotations['ApiParams'])) {
|
||||||
$params = self::parseCustomAnnotations($docblockMethod, 'param');
|
$params = self::parseCustomAnnotations($docblockMethod, 'param');
|
||||||
|
|
@ -292,7 +309,7 @@ class Extractor
|
||||||
$argsParts = trim($matches['args'][$i]);
|
$argsParts = trim($matches['args'][$i]);
|
||||||
if ($name == 'ApiReturn') {
|
if ($name == 'ApiReturn') {
|
||||||
$value = $argsParts;
|
$value = $argsParts;
|
||||||
} else if ($matches['args'][$i] != '') {
|
} elseif ($matches['args'][$i] != '') {
|
||||||
$argsParts = preg_replace("/\{(\w+)\}/", '#$1#', $argsParts);
|
$argsParts = preg_replace("/\{(\w+)\}/", '#$1#', $argsParts);
|
||||||
$value = self::parseArgs($argsParts);
|
$value = self::parseArgs($argsParts);
|
||||||
if (is_string($value)) {
|
if (is_string($value)) {
|
||||||
|
|
@ -307,6 +324,11 @@ class Extractor
|
||||||
if (stripos($docblock, '@ApiInternal') !== false) {
|
if (stripos($docblock, '@ApiInternal') !== false) {
|
||||||
$annotations['ApiInternal'] = [true];
|
$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;
|
return $annotations;
|
||||||
}
|
}
|
||||||
|
|
@ -354,7 +376,9 @@ class Extractor
|
||||||
// close delimiter
|
// close delimiter
|
||||||
if ($c !== $nextDelimiter) {
|
if ($c !== $nextDelimiter) {
|
||||||
throw new Exception(sprintf(
|
throw new Exception(sprintf(
|
||||||
"Parse Error: enclosing error -> expected: [%s], given: [%s]", $nextDelimiter, $c
|
"Parse Error: enclosing error -> expected: [%s], given: [%s]",
|
||||||
|
$nextDelimiter,
|
||||||
|
$c
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -362,7 +386,8 @@ class Extractor
|
||||||
if ($i < $len) {
|
if ($i < $len) {
|
||||||
if (',' !== substr($content, $i, 1) && '\\' !== $prev_c) {
|
if (',' !== substr($content, $i, 1) && '\\' !== $prev_c) {
|
||||||
throw new Exception(sprintf(
|
throw new Exception(sprintf(
|
||||||
"Parse Error: missing comma separator near: ...%s<--", substr($content, ($i - 10), $i)
|
"Parse Error: missing comma separator near: ...%s<--",
|
||||||
|
substr($content, ($i - 10), $i)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -387,7 +412,9 @@ class Extractor
|
||||||
// it means that the string was not enclosed, so it is parsing error.
|
// it means that the string was not enclosed, so it is parsing error.
|
||||||
if ($composing === true && !empty($prevDelimiter) && !empty($nextDelimiter)) {
|
if ($composing === true && !empty($prevDelimiter) && !empty($nextDelimiter)) {
|
||||||
throw new Exception(sprintf(
|
throw new Exception(sprintf(
|
||||||
"Parse Error: enclosing error -> expected: [%s], given: [%s]", $nextDelimiter, $c
|
"Parse Error: enclosing error -> expected: [%s], given: [%s]",
|
||||||
|
$nextDelimiter,
|
||||||
|
$c
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -416,7 +443,8 @@ class Extractor
|
||||||
// if the string is composing yet means that the structure of var. never was enclosed with '}'
|
// if the string is composing yet means that the structure of var. never was enclosed with '}'
|
||||||
if ($subComposing) {
|
if ($subComposing) {
|
||||||
throw new Exception(sprintf(
|
throw new Exception(sprintf(
|
||||||
"Parse Error: Composite variable is not enclosed correctly. near: ...%s'", $subc
|
"Parse Error: Composite variable is not enclosed correctly. near: ...%s'",
|
||||||
|
$subc
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -479,5 +507,4 @@ class Extractor
|
||||||
|
|
||||||
return $val;
|
return $val;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,9 @@
|
||||||
padding-left:0px;
|
padding-left:0px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.label-primary {
|
||||||
|
background-color: #248aff;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
@ -547,6 +550,9 @@
|
||||||
contentType: false,
|
contentType: false,
|
||||||
processData: false,
|
processData: false,
|
||||||
headers: headers,
|
headers: headers,
|
||||||
|
xhrFields: {
|
||||||
|
withCredentials: true
|
||||||
|
},
|
||||||
success: function (data, textStatus, xhr) {
|
success: function (data, textStatus, xhr) {
|
||||||
if (typeof data === 'object') {
|
if (typeof data === 'object') {
|
||||||
var str = JSON.stringify(data, null, 2);
|
var str = JSON.stringify(data, null, 2);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ use think\Loader;
|
||||||
|
|
||||||
class Crud extends Command
|
class Crud extends Command
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $stubList = [];
|
protected $stubList = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -93,7 +92,7 @@ class Crud extends Command
|
||||||
/**
|
/**
|
||||||
* 保留字段
|
* 保留字段
|
||||||
*/
|
*/
|
||||||
protected $reservedField = ['admin_id', 'createtime', 'updatetime'];
|
protected $reservedField = ['admin_id'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 排除字段
|
* 排除字段
|
||||||
|
|
@ -111,6 +110,24 @@ class Crud extends Command
|
||||||
*/
|
*/
|
||||||
protected $headingFilterField = 'status';
|
protected $headingFilterField = 'status';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加时间字段
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $createTimeField = 'createtime';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间字段
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $updateTimeField = 'updatetime';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 软删除时间字段
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $deleteTimeField = 'deletetime';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编辑器的Class
|
* 编辑器的Class
|
||||||
*/
|
*/
|
||||||
|
|
@ -118,7 +135,7 @@ class Crud extends Command
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* langList的key最长字节数
|
* langList的key最长字节数
|
||||||
*/
|
*/
|
||||||
protected $fieldMaxLen = 0;
|
protected $fieldMaxLen = 0;
|
||||||
|
|
||||||
protected function configure()
|
protected function configure()
|
||||||
|
|
@ -215,32 +232,47 @@ class Crud extends Command
|
||||||
$headingfilterfield = $input->getOption('headingfilterfield');
|
$headingfilterfield = $input->getOption('headingfilterfield');
|
||||||
//编辑器Class
|
//编辑器Class
|
||||||
$editorclass = $input->getOption('editorclass');
|
$editorclass = $input->getOption('editorclass');
|
||||||
if ($setcheckboxsuffix)
|
if ($setcheckboxsuffix) {
|
||||||
$this->setCheckboxSuffix = $setcheckboxsuffix;
|
$this->setCheckboxSuffix = $setcheckboxsuffix;
|
||||||
if ($enumradiosuffix)
|
}
|
||||||
|
if ($enumradiosuffix) {
|
||||||
$this->enumRadioSuffix = $enumradiosuffix;
|
$this->enumRadioSuffix = $enumradiosuffix;
|
||||||
if ($imagefield)
|
}
|
||||||
|
if ($imagefield) {
|
||||||
$this->imageField = $imagefield;
|
$this->imageField = $imagefield;
|
||||||
if ($filefield)
|
}
|
||||||
|
if ($filefield) {
|
||||||
$this->fileField = $filefield;
|
$this->fileField = $filefield;
|
||||||
if ($intdatesuffix)
|
}
|
||||||
|
if ($intdatesuffix) {
|
||||||
$this->intDateSuffix = $intdatesuffix;
|
$this->intDateSuffix = $intdatesuffix;
|
||||||
if ($switchsuffix)
|
}
|
||||||
|
if ($switchsuffix) {
|
||||||
$this->switchSuffix = $switchsuffix;
|
$this->switchSuffix = $switchsuffix;
|
||||||
if ($citysuffix)
|
}
|
||||||
|
if ($citysuffix) {
|
||||||
$this->citySuffix = $citysuffix;
|
$this->citySuffix = $citysuffix;
|
||||||
if ($selectpagesuffix)
|
}
|
||||||
|
if ($selectpagesuffix) {
|
||||||
$this->selectpageSuffix = $selectpagesuffix;
|
$this->selectpageSuffix = $selectpagesuffix;
|
||||||
if ($selectpagessuffix)
|
}
|
||||||
|
if ($selectpagessuffix) {
|
||||||
$this->selectpagesSuffix = $selectpagessuffix;
|
$this->selectpagesSuffix = $selectpagessuffix;
|
||||||
if ($ignoreFields)
|
}
|
||||||
|
if ($ignoreFields) {
|
||||||
$this->ignoreFields = $ignoreFields;
|
$this->ignoreFields = $ignoreFields;
|
||||||
if ($editorclass)
|
}
|
||||||
|
if ($editorclass) {
|
||||||
$this->editorClass = $editorclass;
|
$this->editorClass = $editorclass;
|
||||||
if ($sortfield)
|
}
|
||||||
|
if ($sortfield) {
|
||||||
$this->sortField = $sortfield;
|
$this->sortField = $sortfield;
|
||||||
if ($headingfilterfield)
|
}
|
||||||
|
if ($headingfilterfield) {
|
||||||
$this->headingFilterField = $headingfilterfield;
|
$this->headingFilterField = $headingfilterfield;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->reservedField = array_merge($this->reservedField, [$this->createTimeField, $this->updateTimeField, $this->deleteTimeField]);
|
||||||
|
|
||||||
$dbname = Config::get('database.database');
|
$dbname = Config::get('database.database');
|
||||||
$prefix = Config::get('database.prefix');
|
$prefix = Config::get('database.prefix');
|
||||||
|
|
@ -254,11 +286,11 @@ class Crud extends Command
|
||||||
$modelName = $table = stripos($table, $prefix) === 0 ? substr($table, strlen($prefix)) : $table;
|
$modelName = $table = stripos($table, $prefix) === 0 ? substr($table, strlen($prefix)) : $table;
|
||||||
$modelTableType = 'table';
|
$modelTableType = 'table';
|
||||||
$modelTableTypeName = $modelTableName = $modelName;
|
$modelTableTypeName = $modelTableName = $modelName;
|
||||||
$modelTableInfo = Db::query("SHOW TABLE STATUS LIKE '{$modelTableName}'", [], TRUE);
|
$modelTableInfo = Db::query("SHOW TABLE STATUS LIKE '{$modelTableName}'", [], true);
|
||||||
if (!$modelTableInfo) {
|
if (!$modelTableInfo) {
|
||||||
$modelTableType = 'name';
|
$modelTableType = 'name';
|
||||||
$modelTableName = $prefix . $modelName;
|
$modelTableName = $prefix . $modelName;
|
||||||
$modelTableInfo = Db::query("SHOW TABLE STATUS LIKE '{$modelTableName}'", [], TRUE);
|
$modelTableInfo = Db::query("SHOW TABLE STATUS LIKE '{$modelTableName}'", [], true);
|
||||||
if (!$modelTableInfo) {
|
if (!$modelTableInfo) {
|
||||||
throw new Exception("table not found");
|
throw new Exception("table not found");
|
||||||
}
|
}
|
||||||
|
|
@ -275,11 +307,11 @@ class Crud extends Command
|
||||||
$relationName = stripos($relationTable, $prefix) === 0 ? substr($relationTable, strlen($prefix)) : $relationTable;
|
$relationName = stripos($relationTable, $prefix) === 0 ? substr($relationTable, strlen($prefix)) : $relationTable;
|
||||||
$relationTableType = 'table';
|
$relationTableType = 'table';
|
||||||
$relationTableTypeName = $relationTableName = $relationName;
|
$relationTableTypeName = $relationTableName = $relationName;
|
||||||
$relationTableInfo = Db::query("SHOW TABLE STATUS LIKE '{$relationTableName}'", [], TRUE);
|
$relationTableInfo = Db::query("SHOW TABLE STATUS LIKE '{$relationTableName}'", [], true);
|
||||||
if (!$relationTableInfo) {
|
if (!$relationTableInfo) {
|
||||||
$relationTableType = 'name';
|
$relationTableType = 'name';
|
||||||
$relationTableName = $prefix . $relationName;
|
$relationTableName = $prefix . $relationName;
|
||||||
$relationTableInfo = Db::query("SHOW TABLE STATUS LIKE '{$relationTableName}'", [], TRUE);
|
$relationTableInfo = Db::query("SHOW TABLE STATUS LIKE '{$relationTableName}'", [], true);
|
||||||
if (!$relationTableInfo) {
|
if (!$relationTableInfo) {
|
||||||
throw new Exception("relation table not found");
|
throw new Exception("relation table not found");
|
||||||
}
|
}
|
||||||
|
|
@ -338,6 +370,7 @@ class Crud extends Command
|
||||||
$addFile = $viewDir . 'add.html';
|
$addFile = $viewDir . 'add.html';
|
||||||
$editFile = $viewDir . 'edit.html';
|
$editFile = $viewDir . 'edit.html';
|
||||||
$indexFile = $viewDir . 'index.html';
|
$indexFile = $viewDir . 'index.html';
|
||||||
|
$recyclebinFile = $viewDir . 'recyclebin.html';
|
||||||
$langFile = $adminPath . 'lang' . DS . Lang::detect() . DS . $controllerBaseName . '.php';
|
$langFile = $adminPath . 'lang' . DS . Lang::detect() . DS . $controllerBaseName . '.php';
|
||||||
|
|
||||||
//是否为删除模式
|
//是否为删除模式
|
||||||
|
|
@ -355,12 +388,13 @@ class Crud extends Command
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach ($readyFiles as $k => $v) {
|
foreach ($readyFiles as $k => $v) {
|
||||||
if (file_exists($v))
|
if (file_exists($v)) {
|
||||||
unlink($v);
|
unlink($v);
|
||||||
|
}
|
||||||
//删除空文件夹
|
//删除空文件夹
|
||||||
if ($v == $modelFile) {
|
if ($v == $modelFile) {
|
||||||
$this->removeEmptyBaseDir($v, $modelArr);
|
$this->removeEmptyBaseDir($v, $modelArr);
|
||||||
} else if ($v == $validateFile) {
|
} elseif ($v == $validateFile) {
|
||||||
$this->removeEmptyBaseDir($v, $validateArr);
|
$this->removeEmptyBaseDir($v, $validateArr);
|
||||||
} else {
|
} else {
|
||||||
$this->removeEmptyBaseDir($v, $controllerArr);
|
$this->removeEmptyBaseDir($v, $controllerArr);
|
||||||
|
|
@ -434,7 +468,7 @@ class Crud extends Command
|
||||||
$langList = [];
|
$langList = [];
|
||||||
$field = 'id';
|
$field = 'id';
|
||||||
$order = 'id';
|
$order = 'id';
|
||||||
$priDefined = FALSE;
|
$priDefined = false;
|
||||||
$priKey = '';
|
$priKey = '';
|
||||||
$relationPrimaryKey = '';
|
$relationPrimaryKey = '';
|
||||||
foreach ($columnList as $k => $v) {
|
foreach ($columnList as $k => $v) {
|
||||||
|
|
@ -484,6 +518,7 @@ class Crud extends Command
|
||||||
$appendAttrList = [];
|
$appendAttrList = [];
|
||||||
$controllerAssignList = [];
|
$controllerAssignList = [];
|
||||||
$headingHtml = '{:build_heading()}';
|
$headingHtml = '{:build_heading()}';
|
||||||
|
$recyclebinHtml = '';
|
||||||
|
|
||||||
//循环所有字段,开始构造视图的HTML和JS信息
|
//循环所有字段,开始构造视图的HTML和JS信息
|
||||||
foreach ($columnList as $k => $v) {
|
foreach ($columnList as $k => $v) {
|
||||||
|
|
@ -506,7 +541,7 @@ class Crud extends Command
|
||||||
$langList[] = $this->getLangItem($field, $v['COLUMN_COMMENT']);
|
$langList[] = $this->getLangItem($field, $v['COLUMN_COMMENT']);
|
||||||
}
|
}
|
||||||
$inputType = '';
|
$inputType = '';
|
||||||
//createtime和updatetime是保留字段不能修改和添加
|
//保留字段不能修改和添加
|
||||||
if ($v['COLUMN_KEY'] != 'PRI' && !in_array($field, $this->reservedField) && !in_array($field, $this->ignoreFields)) {
|
if ($v['COLUMN_KEY'] != 'PRI' && !in_array($field, $this->reservedField) && !in_array($field, $this->ignoreFields)) {
|
||||||
$inputType = $this->getFieldType($v);
|
$inputType = $this->getFieldType($v);
|
||||||
|
|
||||||
|
|
@ -534,7 +569,7 @@ class Crud extends Command
|
||||||
|
|
||||||
$this->getEnum($getEnumArr, $controllerAssignList, $field, $itemArr, $v['DATA_TYPE'] == 'set' ? 'multiple' : 'select');
|
$this->getEnum($getEnumArr, $controllerAssignList, $field, $itemArr, $v['DATA_TYPE'] == 'set' ? 'multiple' : 'select');
|
||||||
|
|
||||||
$itemArr = $this->getLangArray($itemArr, FALSE);
|
$itemArr = $this->getLangArray($itemArr, false);
|
||||||
//添加一个获取器
|
//添加一个获取器
|
||||||
$this->getAttr($getAttrArr, $field, $v['DATA_TYPE'] == 'set' ? 'multiple' : 'select');
|
$this->getAttr($getAttrArr, $field, $v['DATA_TYPE'] == 'set' ? 'multiple' : 'select');
|
||||||
if ($v['DATA_TYPE'] == 'set') {
|
if ($v['DATA_TYPE'] == 'set') {
|
||||||
|
|
@ -543,28 +578,29 @@ class Crud extends Command
|
||||||
$this->appendAttr($appendAttrList, $field);
|
$this->appendAttr($appendAttrList, $field);
|
||||||
$formAddElement = $this->getReplacedStub('html/select', ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => $defaultValue]);
|
$formAddElement = $this->getReplacedStub('html/select', ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => $defaultValue]);
|
||||||
$formEditElement = $this->getReplacedStub('html/select', ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => "\$row.{$field}"]);
|
$formEditElement = $this->getReplacedStub('html/select', ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => "\$row.{$field}"]);
|
||||||
} else if ($inputType == 'datetime') {
|
} elseif ($inputType == 'datetime') {
|
||||||
$cssClassArr[] = 'datetimepicker';
|
$cssClassArr[] = 'datetimepicker';
|
||||||
$attrArr['class'] = implode(' ', $cssClassArr);
|
$attrArr['class'] = implode(' ', $cssClassArr);
|
||||||
$format = "YYYY-MM-DD HH:mm:ss";
|
$format = "YYYY-MM-DD HH:mm:ss";
|
||||||
$phpFormat = "Y-m-d H:i:s";
|
$phpFormat = "Y-m-d H:i:s";
|
||||||
$fieldFunc = '';
|
$fieldFunc = '';
|
||||||
switch ($v['DATA_TYPE']) {
|
switch ($v['DATA_TYPE']) {
|
||||||
case 'year';
|
case 'year':
|
||||||
$format = "YYYY";
|
$format = "YYYY";
|
||||||
$phpFormat = 'Y';
|
$phpFormat = 'Y';
|
||||||
break;
|
break;
|
||||||
case 'date';
|
case 'date':
|
||||||
$format = "YYYY-MM-DD";
|
$format = "YYYY-MM-DD";
|
||||||
$phpFormat = 'Y-m-d';
|
$phpFormat = 'Y-m-d';
|
||||||
break;
|
break;
|
||||||
case 'time';
|
case 'time':
|
||||||
$format = "HH:mm:ss";
|
$format = "HH:mm:ss";
|
||||||
$phpFormat = 'H:i:s';
|
$phpFormat = 'H:i:s';
|
||||||
break;
|
break;
|
||||||
case 'timestamp';
|
case 'timestamp':
|
||||||
$fieldFunc = 'datetime';
|
$fieldFunc = 'datetime';
|
||||||
case 'datetime';
|
// no break
|
||||||
|
case 'datetime':
|
||||||
$format = "YYYY-MM-DD HH:mm:ss";
|
$format = "YYYY-MM-DD HH:mm:ss";
|
||||||
$phpFormat = 'Y-m-d H:i:s';
|
$phpFormat = 'Y-m-d H:i:s';
|
||||||
break;
|
break;
|
||||||
|
|
@ -581,13 +617,13 @@ class Crud extends Command
|
||||||
$fieldFunc = $fieldFunc ? "|{$fieldFunc}" : "";
|
$fieldFunc = $fieldFunc ? "|{$fieldFunc}" : "";
|
||||||
$formAddElement = Form::text($fieldName, $defaultDateTime, $attrArr);
|
$formAddElement = Form::text($fieldName, $defaultDateTime, $attrArr);
|
||||||
$formEditElement = Form::text($fieldName, "{\$row.{$field}{$fieldFunc}}", $attrArr);
|
$formEditElement = Form::text($fieldName, "{\$row.{$field}{$fieldFunc}}", $attrArr);
|
||||||
} else if ($inputType == 'checkbox' || $inputType == 'radio') {
|
} elseif ($inputType == 'checkbox' || $inputType == 'radio') {
|
||||||
unset($attrArr['data-rule']);
|
unset($attrArr['data-rule']);
|
||||||
$fieldName = $inputType == 'checkbox' ? $fieldName .= "[]" : $fieldName;
|
$fieldName = $inputType == 'checkbox' ? $fieldName .= "[]" : $fieldName;
|
||||||
$attrArr['name'] = "row[{$fieldName}]";
|
$attrArr['name'] = "row[{$fieldName}]";
|
||||||
|
|
||||||
$this->getEnum($getEnumArr, $controllerAssignList, $field, $itemArr, $inputType);
|
$this->getEnum($getEnumArr, $controllerAssignList, $field, $itemArr, $inputType);
|
||||||
$itemArr = $this->getLangArray($itemArr, FALSE);
|
$itemArr = $this->getLangArray($itemArr, false);
|
||||||
//添加一个获取器
|
//添加一个获取器
|
||||||
$this->getAttr($getAttrArr, $field, $inputType);
|
$this->getAttr($getAttrArr, $field, $inputType);
|
||||||
if ($inputType == 'checkbox') {
|
if ($inputType == 'checkbox') {
|
||||||
|
|
@ -598,13 +634,13 @@ class Crud extends Command
|
||||||
|
|
||||||
$formAddElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => $defaultValue]);
|
$formAddElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => $defaultValue]);
|
||||||
$formEditElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => "\$row.{$field}"]);
|
$formEditElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => "\$row.{$field}"]);
|
||||||
} else if ($inputType == 'textarea') {
|
} elseif ($inputType == 'textarea') {
|
||||||
$cssClassArr[] = $this->isMatchSuffix($field, $this->editorSuffix) ? $this->editorClass : '';
|
$cssClassArr[] = $this->isMatchSuffix($field, $this->editorSuffix) ? $this->editorClass : '';
|
||||||
$attrArr['class'] = implode(' ', $cssClassArr);
|
$attrArr['class'] = implode(' ', $cssClassArr);
|
||||||
$attrArr['rows'] = 5;
|
$attrArr['rows'] = 5;
|
||||||
$formAddElement = Form::textarea($fieldName, $defaultValue, $attrArr);
|
$formAddElement = Form::textarea($fieldName, $defaultValue, $attrArr);
|
||||||
$formEditElement = Form::textarea($fieldName, $editValue, $attrArr);
|
$formEditElement = Form::textarea($fieldName, $editValue, $attrArr);
|
||||||
} else if ($inputType == 'switch') {
|
} elseif ($inputType == 'switch') {
|
||||||
unset($attrArr['data-rule']);
|
unset($attrArr['data-rule']);
|
||||||
if ($defaultValue === '1' || $defaultValue === 'Y') {
|
if ($defaultValue === '1' || $defaultValue === 'Y') {
|
||||||
$yes = $defaultValue;
|
$yes = $defaultValue;
|
||||||
|
|
@ -619,7 +655,7 @@ class Crud extends Command
|
||||||
$stateNoClass = 'fa-flip-horizontal text-gray';
|
$stateNoClass = 'fa-flip-horizontal text-gray';
|
||||||
$formAddElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldYes' => $yes, 'fieldNo' => $no, 'attrStr' => Form::attributes($attrArr), 'fieldValue' => $defaultValue, 'fieldSwitchClass' => $defaultValue == $no ? $stateNoClass : '']);
|
$formAddElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldYes' => $yes, 'fieldNo' => $no, 'attrStr' => Form::attributes($attrArr), 'fieldValue' => $defaultValue, 'fieldSwitchClass' => $defaultValue == $no ? $stateNoClass : '']);
|
||||||
$formEditElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldYes' => $yes, 'fieldNo' => $no, 'attrStr' => Form::attributes($attrArr), 'fieldValue' => "{\$row.{$field}}", 'fieldSwitchClass' => "{eq name=\"\$row.{$field}\" value=\"{$no}\"}fa-flip-horizontal text-gray{/eq}"]);
|
$formEditElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldYes' => $yes, 'fieldNo' => $no, 'attrStr' => Form::attributes($attrArr), 'fieldValue' => "{\$row.{$field}}", 'fieldSwitchClass' => "{eq name=\"\$row.{$field}\" value=\"{$no}\"}fa-flip-horizontal text-gray{/eq}"]);
|
||||||
} else if ($inputType == 'citypicker') {
|
} elseif ($inputType == 'citypicker') {
|
||||||
$attrArr['class'] = implode(' ', $cssClassArr);
|
$attrArr['class'] = implode(' ', $cssClassArr);
|
||||||
$attrArr['data-toggle'] = "city-picker";
|
$attrArr['data-toggle'] = "city-picker";
|
||||||
$formAddElement = sprintf("<div class='control-relative'>%s</div>", Form::input('text', $fieldName, $defaultValue, $attrArr));
|
$formAddElement = sprintf("<div class='control-relative'>%s</div>", Form::input('text', $fieldName, $defaultValue, $attrArr));
|
||||||
|
|
@ -692,9 +728,13 @@ class Crud extends Command
|
||||||
if ($v['DATA_TYPE'] != 'text') {
|
if ($v['DATA_TYPE'] != 'text') {
|
||||||
//主键
|
//主键
|
||||||
if ($v['COLUMN_KEY'] == 'PRI' && !$priDefined) {
|
if ($v['COLUMN_KEY'] == 'PRI' && !$priDefined) {
|
||||||
$priDefined = TRUE;
|
$priDefined = true;
|
||||||
$javascriptList[] = "{checkbox: true}";
|
$javascriptList[] = "{checkbox: true}";
|
||||||
}
|
}
|
||||||
|
if ($this->deleteTimeField == $field) {
|
||||||
|
$recyclebinHtml = $this->getReplacedStub('html/recyclebin-html', ['controllerUrl' => $controllerUrl]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!$fields || in_array($field, explode(',', $fields))) {
|
if (!$fields || in_array($field, explode(',', $fields))) {
|
||||||
//构造JS列信息
|
//构造JS列信息
|
||||||
$javascriptList[] = $this->getJsColumn($field, $v['DATA_TYPE'], $inputType && in_array($inputType, ['select', 'checkbox', 'radio']) ? '_text' : '', $itemArr);
|
$javascriptList[] = $this->getJsColumn($field, $v['DATA_TYPE'], $inputType && in_array($inputType, ['select', 'checkbox', 'radio']) ? '_text' : '', $itemArr);
|
||||||
|
|
@ -743,7 +783,7 @@ class Crud extends Command
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unset($line);
|
unset($line);
|
||||||
$langList = implode(",\n", array_filter($langList)). ",";
|
$langList = implode(",\n", array_filter($langList)) . ",";
|
||||||
|
|
||||||
//表注释
|
//表注释
|
||||||
$tableComment = $modelTableInfo['Comment'];
|
$tableComment = $modelTableInfo['Comment'];
|
||||||
|
|
@ -754,7 +794,6 @@ class Crud extends Command
|
||||||
$modelInit = $this->getReplacedStub('mixins' . DS . 'modelinit', ['order' => $order]);
|
$modelInit = $this->getReplacedStub('mixins' . DS . 'modelinit', ['order' => $order]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'controllerNamespace' => $controllerNamespace,
|
'controllerNamespace' => $controllerNamespace,
|
||||||
'modelNamespace' => $modelNamespace,
|
'modelNamespace' => $modelNamespace,
|
||||||
|
|
@ -777,14 +816,18 @@ class Crud extends Command
|
||||||
'editList' => $editList,
|
'editList' => $editList,
|
||||||
'javascriptList' => $javascriptList,
|
'javascriptList' => $javascriptList,
|
||||||
'langList' => $langList,
|
'langList' => $langList,
|
||||||
'modelAutoWriteTimestamp' => in_array('createtime', $fieldArr) || in_array('updatetime', $fieldArr) ? "'int'" : 'false',
|
'sofeDeleteClassPath' => in_array($this->deleteTimeField, $fieldArr) ? "use traits\model\SoftDelete;" : '',
|
||||||
'createTime' => in_array('createtime', $fieldArr) ? "'createtime'" : 'false',
|
'softDelete' => in_array($this->deleteTimeField, $fieldArr) ? "use SoftDelete;" : '',
|
||||||
'updateTime' => in_array('updatetime', $fieldArr) ? "'updatetime'" : 'false',
|
'modelAutoWriteTimestamp' => in_array($this->createTimeField, $fieldArr) || in_array($this->updateTimeField, $fieldArr) ? "'int'" : 'false',
|
||||||
|
'createTime' => in_array($this->createTimeField, $fieldArr) ? "'{$this->createTimeField}'" : 'false',
|
||||||
|
'updateTime' => in_array($this->updateTimeField, $fieldArr) ? "'{$this->updateTimeField}'" : 'false',
|
||||||
|
'deleteTime' => in_array($this->deleteTimeField, $fieldArr) ? "'{$this->deleteTimeField}'" : 'false',
|
||||||
'relationSearch' => $relations ? 'true' : 'false',
|
'relationSearch' => $relations ? 'true' : 'false',
|
||||||
'relationWithList' => '',
|
'relationWithList' => '',
|
||||||
'relationMethodList' => '',
|
'relationMethodList' => '',
|
||||||
'controllerIndex' => '',
|
'controllerIndex' => '',
|
||||||
'headingHtml' => $headingHtml,
|
'headingHtml' => $headingHtml,
|
||||||
|
'recyclebinHtml' => $recyclebinHtml,
|
||||||
'visibleFieldList' => $fields ? "\$row->visible(['" . implode("','", array_filter(explode(',', $fields))) . "']);" : '',
|
'visibleFieldList' => $fields ? "\$row->visible(['" . implode("','", array_filter(explode(',', $fields))) . "']);" : '',
|
||||||
'appendAttrList' => implode(",\n", $appendAttrList),
|
'appendAttrList' => implode(",\n", $appendAttrList),
|
||||||
'getEnumList' => implode("\n\n", $getEnumArr),
|
'getEnumList' => implode("\n\n", $getEnumArr),
|
||||||
|
|
@ -832,8 +875,7 @@ class Crud extends Command
|
||||||
|
|
||||||
//需要重写index方法
|
//需要重写index方法
|
||||||
$data['controllerIndex'] = $this->getReplacedStub('controllerindex', $data);
|
$data['controllerIndex'] = $this->getReplacedStub('controllerindex', $data);
|
||||||
|
} elseif ($fields) {
|
||||||
} else if ($fields) {
|
|
||||||
$data = array_merge($data, ['relationWithList' => '', 'relationMethodList' => '', 'relationVisibleFieldList' => '']);
|
$data = array_merge($data, ['relationWithList' => '', 'relationMethodList' => '', 'relationVisibleFieldList' => '']);
|
||||||
//需要重写index方法
|
//需要重写index方法
|
||||||
$data['controllerIndex'] = $this->getReplacedStub('controllerindex', $data);
|
$data['controllerIndex'] = $this->getReplacedStub('controllerindex', $data);
|
||||||
|
|
@ -852,7 +894,6 @@ class Crud extends Command
|
||||||
$result = $this->writeToFile('relationmodel', $relation, $relation['relationFile']);
|
$result = $this->writeToFile('relationmodel', $relation, $relation['relationFile']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// 生成验证文件
|
// 生成验证文件
|
||||||
$result = $this->writeToFile('validate', $data, $validateFile);
|
$result = $this->writeToFile('validate', $data, $validateFile);
|
||||||
|
|
@ -860,6 +901,12 @@ class Crud extends Command
|
||||||
$result = $this->writeToFile('add', $data, $addFile);
|
$result = $this->writeToFile('add', $data, $addFile);
|
||||||
$result = $this->writeToFile('edit', $data, $editFile);
|
$result = $this->writeToFile('edit', $data, $editFile);
|
||||||
$result = $this->writeToFile('index', $data, $indexFile);
|
$result = $this->writeToFile('index', $data, $indexFile);
|
||||||
|
if ($recyclebinHtml) {
|
||||||
|
$result = $this->writeToFile('recyclebin', $data, $recyclebinFile);
|
||||||
|
$recyclebinTitle = in_array('title', $fieldArr) ? 'title' : (in_array('name', $fieldArr) ? 'name' : '');
|
||||||
|
$recyclebinTitleJs = $recyclebinTitle ? "\n {field: '{$recyclebinTitle}', title: __('" . (ucfirst($recyclebinTitle)) . "'), align: 'left'}," : '';
|
||||||
|
$data['recyclebinJs'] = $this->getReplacedStub('mixins/recyclebinjs', ['recyclebinTitleJs' => $recyclebinTitleJs, 'controllerUrl' => $controllerUrl]);
|
||||||
|
}
|
||||||
// 生成JS文件
|
// 生成JS文件
|
||||||
$result = $this->writeToFile('javascript', $data, $javascriptFile);
|
$result = $this->writeToFile('javascript', $data, $javascriptFile);
|
||||||
// 生成语言文件
|
// 生成语言文件
|
||||||
|
|
@ -880,8 +927,9 @@ class Crud extends Command
|
||||||
|
|
||||||
protected function getEnum(&$getEnum, &$controllerAssignList, $field, $itemArr = '', $inputType = '')
|
protected function getEnum(&$getEnum, &$controllerAssignList, $field, $itemArr = '', $inputType = '')
|
||||||
{
|
{
|
||||||
if (!in_array($inputType, ['datetime', 'select', 'multiple', 'checkbox', 'radio']))
|
if (!in_array($inputType, ['datetime', 'select', 'multiple', 'checkbox', 'radio'])) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
$fieldList = $this->getFieldListName($field);
|
$fieldList = $this->getFieldListName($field);
|
||||||
$methodName = 'get' . ucfirst($fieldList);
|
$methodName = 'get' . ucfirst($fieldList);
|
||||||
foreach ($itemArr as $k => &$v) {
|
foreach ($itemArr as $k => &$v) {
|
||||||
|
|
@ -902,22 +950,24 @@ EOD;
|
||||||
|
|
||||||
protected function getAttr(&$getAttr, $field, $inputType = '')
|
protected function getAttr(&$getAttr, $field, $inputType = '')
|
||||||
{
|
{
|
||||||
if (!in_array($inputType, ['datetime', 'select', 'multiple', 'checkbox', 'radio']))
|
if (!in_array($inputType, ['datetime', 'select', 'multiple', 'checkbox', 'radio'])) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
$attrField = ucfirst($this->getCamelizeName($field));
|
$attrField = ucfirst($this->getCamelizeName($field));
|
||||||
$getAttr[] = $this->getReplacedStub("mixins" . DS . $inputType, ['field' => $field, 'methodName' => "get{$attrField}TextAttr", 'listMethodName' => "get{$attrField}List"]);
|
$getAttr[] = $this->getReplacedStub("mixins" . DS . $inputType, ['field' => $field, 'methodName' => "get{$attrField}TextAttr", 'listMethodName' => "get{$attrField}List"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function setAttr(&$setAttr, $field, $inputType = '')
|
protected function setAttr(&$setAttr, $field, $inputType = '')
|
||||||
{
|
{
|
||||||
if (!in_array($inputType, ['datetime', 'checkbox', 'select']))
|
if (!in_array($inputType, ['datetime', 'checkbox', 'select'])) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
$attrField = ucfirst($this->getCamelizeName($field));
|
$attrField = ucfirst($this->getCamelizeName($field));
|
||||||
if ($inputType == 'datetime') {
|
if ($inputType == 'datetime') {
|
||||||
$return = <<<EOD
|
$return = <<<EOD
|
||||||
return \$value && !is_numeric(\$value) ? strtotime(\$value) : \$value;
|
return \$value && !is_numeric(\$value) ? strtotime(\$value) : \$value;
|
||||||
EOD;
|
EOD;
|
||||||
} else if (in_array($inputType, ['checkbox', 'select'])) {
|
} elseif (in_array($inputType, ['checkbox', 'select'])) {
|
||||||
$return = <<<EOD
|
$return = <<<EOD
|
||||||
return is_array(\$value) ? implode(',', \$value) : \$value;
|
return is_array(\$value) ? implode(',', \$value) : \$value;
|
||||||
EOD;
|
EOD;
|
||||||
|
|
@ -1118,7 +1168,7 @@ EOD;
|
||||||
* @param boolean $withTpl
|
* @param boolean $withTpl
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function getLangArray($arr, $withTpl = TRUE)
|
protected function getLangArray($arr, $withTpl = true)
|
||||||
{
|
{
|
||||||
$langArr = [];
|
$langArr = [];
|
||||||
foreach ($arr as $k => $v) {
|
foreach ($arr as $k => $v) {
|
||||||
|
|
@ -1134,8 +1184,9 @@ EOD;
|
||||||
*/
|
*/
|
||||||
protected function getArrayString($arr)
|
protected function getArrayString($arr)
|
||||||
{
|
{
|
||||||
if (!is_array($arr))
|
if (!is_array($arr)) {
|
||||||
return $arr;
|
return $arr;
|
||||||
|
}
|
||||||
$stringArr = [];
|
$stringArr = [];
|
||||||
foreach ($arr as $k => $v) {
|
foreach ($arr as $k => $v) {
|
||||||
$is_var = in_array(substr($v, 0, 1), ['$', '_']);
|
$is_var = in_array(substr($v, 0, 1), ['$', '_']);
|
||||||
|
|
@ -1197,11 +1248,11 @@ EOD;
|
||||||
case 'tinytext':
|
case 'tinytext':
|
||||||
$inputType = 'textarea';
|
$inputType = 'textarea';
|
||||||
break;
|
break;
|
||||||
case 'year';
|
case 'year':
|
||||||
case 'date';
|
case 'date':
|
||||||
case 'time';
|
case 'time':
|
||||||
case 'datetime';
|
case 'datetime':
|
||||||
case 'timestamp';
|
case 'timestamp':
|
||||||
$inputType = 'datetime';
|
$inputType = 'datetime';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -1327,8 +1378,9 @@ EOD;
|
||||||
$formatter = 'label';
|
$formatter = 'label';
|
||||||
}
|
}
|
||||||
foreach ($itemArr as $k => &$v) {
|
foreach ($itemArr as $k => &$v) {
|
||||||
if (substr($v, 0, 3) !== '__(')
|
if (substr($v, 0, 3) !== '__(') {
|
||||||
$v = "__('" . mb_ucfirst($v) . "')";
|
$v = "__('" . mb_ucfirst($v) . "')";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
unset($v);
|
unset($v);
|
||||||
$searchList = json_encode($itemArr, JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE);
|
$searchList = json_encode($itemArr, JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE);
|
||||||
|
|
@ -1338,22 +1390,23 @@ EOD;
|
||||||
}
|
}
|
||||||
if (in_array($datatype, ['date', 'datetime']) || $formatter === 'datetime') {
|
if (in_array($datatype, ['date', 'datetime']) || $formatter === 'datetime') {
|
||||||
$html .= ", operate:'RANGE', addclass:'datetimerange'";
|
$html .= ", operate:'RANGE', addclass:'datetimerange'";
|
||||||
} else if (in_array($datatype, ['float', 'double', 'decimal'])) {
|
} elseif (in_array($datatype, ['float', 'double', 'decimal'])) {
|
||||||
$html .= ", operate:'BETWEEN'";
|
$html .= ", operate:'BETWEEN'";
|
||||||
}
|
}
|
||||||
if (in_array($datatype, ['set'])) {
|
if (in_array($datatype, ['set'])) {
|
||||||
$html .= ", operate:'FIND_IN_SET'";
|
$html .= ", operate:'FIND_IN_SET'";
|
||||||
}
|
}
|
||||||
if (in_array($formatter, ['image','images'])) {
|
if (in_array($formatter, ['image', 'images'])) {
|
||||||
$html .= ", events: Table.api.events.image";
|
$html .= ", events: Table.api.events.image";
|
||||||
}
|
}
|
||||||
if ($itemArr && !$formatter) {
|
if ($itemArr && !$formatter) {
|
||||||
$formatter = 'normal';
|
$formatter = 'normal';
|
||||||
}
|
}
|
||||||
if ($formatter)
|
if ($formatter) {
|
||||||
$html .= ", formatter: Table.api.formatter." . $formatter . "}";
|
$html .= ", formatter: Table.api.formatter." . $formatter . "}";
|
||||||
else
|
} else {
|
||||||
$html .= "}";
|
$html .= "}";
|
||||||
|
}
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1367,5 +1420,4 @@ EOD;
|
||||||
{
|
{
|
||||||
return $this->getCamelizeName($field) . 'List';
|
return $this->getCamelizeName($field) . 'List';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
<a class="btn btn-success btn-recyclebin btn-dialog" href="{%controllerUrl%}/recyclebin" title="{:__('Recycle bin')}"><i class="fa fa-recycle"></i> {:__('Recycle bin')}</a>
|
||||||
|
|
@ -19,6 +19,8 @@
|
||||||
<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>
|
<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>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{%recyclebinHtml%}
|
||||||
</div>
|
</div>
|
||||||
<table id="table" class="table table-striped table-bordered table-hover table-nowrap"
|
<table id="table" class="table table-striped table-bordered table-hover table-nowrap"
|
||||||
data-operate-edit="{:$auth->check('{%controllerUrl%}/edit')}"
|
data-operate-edit="{:$auth->check('{%controllerUrl%}/edit')}"
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
||||||
|
|
||||||
// 为表格绑定事件
|
// 为表格绑定事件
|
||||||
Table.api.bindevent(table);
|
Table.api.bindevent(table);
|
||||||
},
|
},{%recyclebinJs%}
|
||||||
add: function () {
|
add: function () {
|
||||||
Controller.api.bindevent();
|
Controller.api.bindevent();
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
|
||||||
|
recyclebin: function () {
|
||||||
|
// 初始化表格参数配置
|
||||||
|
Table.api.init({
|
||||||
|
extend: {
|
||||||
|
'dragsort_url': ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var table = $("#table");
|
||||||
|
|
||||||
|
// 初始化表格
|
||||||
|
table.bootstrapTable({
|
||||||
|
url: '{%controllerUrl%}/recyclebin',
|
||||||
|
pk: 'id',
|
||||||
|
sortName: 'id',
|
||||||
|
columns: [
|
||||||
|
[
|
||||||
|
{checkbox: true},
|
||||||
|
{field: 'id', title: __('Id')},{%recyclebinTitleJs%}
|
||||||
|
{
|
||||||
|
field: 'deletetime',
|
||||||
|
title: __('Deletetime'),
|
||||||
|
operate: 'RANGE',
|
||||||
|
addclass: 'datetimerange',
|
||||||
|
formatter: Table.api.formatter.datetime
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'operate',
|
||||||
|
width: '130px',
|
||||||
|
title: __('Operate'),
|
||||||
|
table: table,
|
||||||
|
events: Table.api.events.operate,
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
name: 'Restore',
|
||||||
|
text: __('Restore'),
|
||||||
|
classname: 'btn btn-xs btn-info btn-restoreit',
|
||||||
|
icon: 'fa fa-rotate-left',
|
||||||
|
url: '{%controllerUrl%}/restore'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Destroy',
|
||||||
|
text: __('Destroy'),
|
||||||
|
classname: 'btn btn-xs btn-danger btn-destroyit',
|
||||||
|
icon: 'fa fa-times',
|
||||||
|
url: '{%controllerUrl%}/destroy'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
formatter: Table.api.formatter.operate
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// 为表格绑定事件
|
||||||
|
Table.api.bindevent(table);
|
||||||
|
},
|
||||||
|
|
@ -3,9 +3,13 @@
|
||||||
namespace {%modelNamespace%};
|
namespace {%modelNamespace%};
|
||||||
|
|
||||||
use think\Model;
|
use think\Model;
|
||||||
|
{%sofeDeleteClassPath%}
|
||||||
|
|
||||||
class {%modelName%} extends Model
|
class {%modelName%} extends Model
|
||||||
{
|
{
|
||||||
|
|
||||||
|
{%softDelete%}
|
||||||
|
|
||||||
// 表名
|
// 表名
|
||||||
protected ${%modelTableType%} = '{%modelTableTypeName%}';
|
protected ${%modelTableType%} = '{%modelTableTypeName%}';
|
||||||
|
|
||||||
|
|
@ -15,7 +19,8 @@ class {%modelName%} extends Model
|
||||||
// 定义时间戳字段名
|
// 定义时间戳字段名
|
||||||
protected $createTime = {%createTime%};
|
protected $createTime = {%createTime%};
|
||||||
protected $updateTime = {%updateTime%};
|
protected $updateTime = {%updateTime%};
|
||||||
|
protected $deleteTime = {%deleteTime%};
|
||||||
|
|
||||||
// 追加属性
|
// 追加属性
|
||||||
protected $append = [
|
protected $append = [
|
||||||
{%appendAttrList%}
|
{%appendAttrList%}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -13,7 +13,6 @@ use think\Exception;
|
||||||
|
|
||||||
class Install extends Command
|
class Install extends Command
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $model = null;
|
protected $model = null;
|
||||||
|
|
||||||
protected function configure()
|
protected function configure()
|
||||||
|
|
@ -27,7 +26,7 @@ class Install extends Command
|
||||||
->addOption('prefix', 'r', Option::VALUE_OPTIONAL, 'table prefix', $config['prefix'])
|
->addOption('prefix', 'r', Option::VALUE_OPTIONAL, 'table prefix', $config['prefix'])
|
||||||
->addOption('username', 'u', Option::VALUE_OPTIONAL, 'mysql username', $config['username'])
|
->addOption('username', 'u', Option::VALUE_OPTIONAL, 'mysql username', $config['username'])
|
||||||
->addOption('password', 'p', Option::VALUE_OPTIONAL, 'mysql password', $config['password'])
|
->addOption('password', 'p', Option::VALUE_OPTIONAL, 'mysql password', $config['password'])
|
||||||
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override', FALSE)
|
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override', false)
|
||||||
->setDescription('New installation of FastAdmin');
|
->setDescription('New installation of FastAdmin');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,5 +92,4 @@ class Install extends Command
|
||||||
|
|
||||||
$output->info("Install Successed!");
|
$output->info("Install Successed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ use think\Exception;
|
||||||
|
|
||||||
class Menu extends Command
|
class Menu extends Command
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $model = null;
|
protected $model = null;
|
||||||
|
|
||||||
protected function configure()
|
protected function configure()
|
||||||
|
|
@ -32,7 +31,6 @@ class Menu extends Command
|
||||||
|
|
||||||
protected function execute(Input $input, Output $output)
|
protected function execute(Input $input, Output $output)
|
||||||
{
|
{
|
||||||
|
|
||||||
$this->model = new AuthRule();
|
$this->model = new AuthRule();
|
||||||
$adminPath = dirname(__DIR__) . DS;
|
$adminPath = dirname(__DIR__) . DS;
|
||||||
//控制器名
|
//控制器名
|
||||||
|
|
@ -54,10 +52,11 @@ class Menu extends Command
|
||||||
$ids = [];
|
$ids = [];
|
||||||
$list = $this->model->where(function ($query) use ($controller, $equal) {
|
$list = $this->model->where(function ($query) use ($controller, $equal) {
|
||||||
foreach ($controller as $index => $item) {
|
foreach ($controller as $index => $item) {
|
||||||
if ($equal)
|
if ($equal) {
|
||||||
$query->whereOr('name', 'eq', $item);
|
$query->whereOr('name', 'eq', $item);
|
||||||
else
|
} else {
|
||||||
$query->whereOr('name', 'like', strtolower($item) . "%");
|
$query->whereOr('name', 'like', strtolower($item) . "%");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})->select();
|
})->select();
|
||||||
foreach ($list as $k => $v) {
|
foreach ($list as $k => $v) {
|
||||||
|
|
@ -94,8 +93,11 @@ class Menu extends Command
|
||||||
}
|
}
|
||||||
$this->importRule($item);
|
$this->importRule($item);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
$authRuleList = AuthRule::select();
|
||||||
|
//生成权限规则备份文件
|
||||||
|
file_put_contents(RUNTIME_PATH . 'authrule.json', json_encode(collection($authRuleList)->toArray()));
|
||||||
|
|
||||||
$this->model->where('id', '>', 0)->delete();
|
$this->model->where('id', '>', 0)->delete();
|
||||||
$controllerDir = $adminPath . 'controller' . DS;
|
$controllerDir = $adminPath . 'controller' . DS;
|
||||||
// 扫描新的节点信息并导入
|
// 扫描新的节点信息并导入
|
||||||
|
|
@ -199,7 +201,7 @@ class Menu extends Command
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//忽略的类
|
//忽略的类
|
||||||
if (stripos($classComment, "@internal") !== FALSE) {
|
if (stripos($classComment, "@internal") !== false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
preg_match_all('#(@.*?)\n#s', $classComment, $annotations);
|
preg_match_all('#(@.*?)\n#s', $classComment, $annotations);
|
||||||
|
|
@ -208,10 +210,10 @@ class Menu extends Command
|
||||||
//判断注释中是否设置了icon值
|
//判断注释中是否设置了icon值
|
||||||
if (isset($annotations[1])) {
|
if (isset($annotations[1])) {
|
||||||
foreach ($annotations[1] as $tag) {
|
foreach ($annotations[1] as $tag) {
|
||||||
if (stripos($tag, '@icon') !== FALSE) {
|
if (stripos($tag, '@icon') !== false) {
|
||||||
$controllerIcon = substr($tag, stripos($tag, ' ') + 1);
|
$controllerIcon = substr($tag, stripos($tag, ' ') + 1);
|
||||||
}
|
}
|
||||||
if (stripos($tag, '@remark') !== FALSE) {
|
if (stripos($tag, '@remark') !== false) {
|
||||||
$controllerRemark = substr($tag, stripos($tag, ' ') + 1);
|
$controllerRemark = substr($tag, stripos($tag, ' ') + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -226,7 +228,13 @@ class Menu extends Command
|
||||||
$pid = 0;
|
$pid = 0;
|
||||||
foreach ($controllerArr as $k => $v) {
|
foreach ($controllerArr as $k => $v) {
|
||||||
$key = $k + 1;
|
$key = $k + 1;
|
||||||
$name = strtolower(implode('/', array_slice($controllerArr, 0, $key)));
|
//驼峰转下划线
|
||||||
|
$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 : '');
|
$title = (!isset($controllerArr[$key]) ? $controllerTitle : '');
|
||||||
$icon = (!isset($controllerArr[$key]) ? $controllerIcon : 'fa fa-list');
|
$icon = (!isset($controllerArr[$key]) ? $controllerIcon : 'fa fa-list');
|
||||||
$remark = (!isset($controllerArr[$key]) ? $controllerRemark : '');
|
$remark = (!isset($controllerArr[$key]) ? $controllerRemark : '');
|
||||||
|
|
@ -259,7 +267,7 @@ class Menu extends Command
|
||||||
}
|
}
|
||||||
$comment = $reflector->getMethod($n->name)->getDocComment();
|
$comment = $reflector->getMethod($n->name)->getDocComment();
|
||||||
//忽略的方法
|
//忽略的方法
|
||||||
if (stripos($comment, "@internal") !== FALSE) {
|
if (stripos($comment, "@internal") !== false) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//过滤掉其它字符
|
//过滤掉其它字符
|
||||||
|
|
@ -285,5 +293,4 @@ class Menu extends Command
|
||||||
return $id ? $id : null;
|
return $id ? $id : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,10 @@ class Min extends Command
|
||||||
$resource = $input->getOption('resource') ?: '';
|
$resource = $input->getOption('resource') ?: '';
|
||||||
$optimize = $input->getOption('optimize') ?: 'none';
|
$optimize = $input->getOption('optimize') ?: 'none';
|
||||||
|
|
||||||
if (!$module || !in_array($module, ['frontend', 'backend', 'all']))
|
if (!$module || !in_array($module, ['frontend', 'backend', 'all'])) {
|
||||||
{
|
|
||||||
throw new Exception('Please input correct module name');
|
throw new Exception('Please input correct module name');
|
||||||
}
|
}
|
||||||
if (!$resource || !in_array($resource, ['js', 'css', 'all']))
|
if (!$resource || !in_array($resource, ['js', 'css', 'all'])) {
|
||||||
{
|
|
||||||
throw new Exception('Please input correct resource name');
|
throw new Exception('Please input correct resource name');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,41 +53,31 @@ class Min extends Command
|
||||||
|
|
||||||
$nodeExec = '';
|
$nodeExec = '';
|
||||||
|
|
||||||
if (!$nodeExec)
|
if (!$nodeExec) {
|
||||||
{
|
if (IS_WIN) {
|
||||||
if (IS_WIN)
|
|
||||||
{
|
|
||||||
// Winsows下请手动配置配置该值,一般将该值配置为 '"C:\Program Files\nodejs\node.exe"',除非你的Node安装路径有变更
|
// Winsows下请手动配置配置该值,一般将该值配置为 '"C:\Program Files\nodejs\node.exe"',除非你的Node安装路径有变更
|
||||||
$nodeExec = 'C:\Program Files\nodejs\node.exe';
|
$nodeExec = 'C:\Program Files\nodejs\node.exe';
|
||||||
if (file_exists($nodeExec)){
|
if (file_exists($nodeExec)) {
|
||||||
$nodeExec = '"' . $nodeExec . '"';
|
$nodeExec = '"' . $nodeExec . '"';
|
||||||
}else{
|
} else {
|
||||||
// 如果 '"C:\Program Files\nodejs\node.exe"' 不存在,可能是node安装路径有变更
|
// 如果 '"C:\Program Files\nodejs\node.exe"' 不存在,可能是node安装路径有变更
|
||||||
// 但安装node会自动配置环境变量,直接执行 '"node.exe"' 提高第一次使用压缩打包的成功率
|
// 但安装node会自动配置环境变量,直接执行 '"node.exe"' 提高第一次使用压缩打包的成功率
|
||||||
$nodeExec = '"node.exe"';
|
$nodeExec = '"node.exe"';
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
try {
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$nodeExec = exec("which node");
|
$nodeExec = exec("which node");
|
||||||
if (!$nodeExec)
|
if (!$nodeExec) {
|
||||||
{
|
|
||||||
throw new Exception("node environment not found!please install node first!");
|
throw new Exception("node environment not found!please install node first!");
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
throw new Exception($e->getMessage());
|
throw new Exception($e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($moduleArr as $mod)
|
foreach ($moduleArr as $mod) {
|
||||||
{
|
foreach ($resourceArr as $res) {
|
||||||
foreach ($resourceArr as $res)
|
|
||||||
{
|
|
||||||
$data = [
|
$data = [
|
||||||
'publicPath' => $publicPath,
|
'publicPath' => $publicPath,
|
||||||
'jsBaseName' => str_replace('{module}', $mod, $this->options['jsBaseName']),
|
'jsBaseName' => str_replace('{module}', $mod, $this->options['jsBaseName']),
|
||||||
|
|
@ -104,17 +92,14 @@ class Min extends Command
|
||||||
|
|
||||||
//源文件
|
//源文件
|
||||||
$from = $data["{$res}BasePath"] . $data["{$res}BaseName"] . '.' . $res;
|
$from = $data["{$res}BasePath"] . $data["{$res}BaseName"] . '.' . $res;
|
||||||
if (!is_file($from))
|
if (!is_file($from)) {
|
||||||
{
|
|
||||||
$output->error("{$res} source file not found!file:{$from}");
|
$output->error("{$res} source file not found!file:{$from}");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ($res == "js")
|
if ($res == "js") {
|
||||||
{
|
|
||||||
$content = file_get_contents($from);
|
$content = file_get_contents($from);
|
||||||
preg_match("/require\.config\(\{[\r\n]?[\n]?+(.*?)[\r\n]?[\n]?}\);/is", $content, $matches);
|
preg_match("/require\.config\(\{[\r\n]?[\n]?+(.*?)[\r\n]?[\n]?}\);/is", $content, $matches);
|
||||||
if (!isset($matches[1]))
|
if (!isset($matches[1])) {
|
||||||
{
|
|
||||||
$output->error("js config not found!");
|
$output->error("js config not found!");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -128,16 +113,14 @@ class Min extends Command
|
||||||
|
|
||||||
// 执行压缩
|
// 执行压缩
|
||||||
$command = "{$nodeExec} \"{$minPath}r.js\" -o \"{$tempFile}\" >> \"{$minPath}node.log\"";
|
$command = "{$nodeExec} \"{$minPath}r.js\" -o \"{$tempFile}\" >> \"{$minPath}node.log\"";
|
||||||
if ($output->isDebug())
|
if ($output->isDebug()) {
|
||||||
{
|
|
||||||
$output->warning($command);
|
$output->warning($command);
|
||||||
}
|
}
|
||||||
echo exec($command);
|
echo exec($command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$output->isDebug())
|
if (!$output->isDebug()) {
|
||||||
{
|
|
||||||
@unlink($tempFile);
|
@unlink($tempFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,16 +137,14 @@ class Min extends Command
|
||||||
protected function writeToFile($name, $data, $pathname)
|
protected function writeToFile($name, $data, $pathname)
|
||||||
{
|
{
|
||||||
$search = $replace = [];
|
$search = $replace = [];
|
||||||
foreach ($data as $k => $v)
|
foreach ($data as $k => $v) {
|
||||||
{
|
|
||||||
$search[] = "{%{$k}%}";
|
$search[] = "{%{$k}%}";
|
||||||
$replace[] = $v;
|
$replace[] = $v;
|
||||||
}
|
}
|
||||||
$stub = file_get_contents($this->getStub($name));
|
$stub = file_get_contents($this->getStub($name));
|
||||||
$content = str_replace($search, $replace, $stub);
|
$content = str_replace($search, $replace, $stub);
|
||||||
|
|
||||||
if (!is_dir(dirname($pathname)))
|
if (!is_dir(dirname($pathname))) {
|
||||||
{
|
|
||||||
mkdir(strtolower(dirname($pathname)), 0755, true);
|
mkdir(strtolower(dirname($pathname)), 0755, true);
|
||||||
}
|
}
|
||||||
return file_put_contents($pathname, $content);
|
return file_put_contents($pathname, $content);
|
||||||
|
|
@ -178,5 +159,4 @@ class Min extends Command
|
||||||
{
|
{
|
||||||
return __DIR__ . DS . 'Min' . DS . 'stubs' . DS . $name . '.stub';
|
return __DIR__ . DS . 'Min' . DS . 'stubs' . DS . $name . '.stub';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ if (!function_exists('build_category_select')) {
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @param mixed $selected
|
* @param mixed $selected
|
||||||
* @param array $attr
|
* @param array $attr
|
||||||
|
* @param array $header
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function build_category_select($name, $type, $selected = null, $attr = [], $header = [])
|
function build_category_select($name, $type, $selected = null, $attr = [], $header = [])
|
||||||
|
|
@ -98,14 +99,14 @@ if (!function_exists('build_toolbar')) {
|
||||||
* @param array $attr 按钮属性值
|
* @param array $attr 按钮属性值
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function build_toolbar($btns = NULL, $attr = [])
|
function build_toolbar($btns = null, $attr = [])
|
||||||
{
|
{
|
||||||
$auth = \app\admin\library\Auth::instance();
|
$auth = \app\admin\library\Auth::instance();
|
||||||
$controller = str_replace('.', '/', strtolower(think\Request::instance()->controller()));
|
$controller = str_replace('.', '/', strtolower(think\Request::instance()->controller()));
|
||||||
$btns = $btns ? $btns : ['refresh', 'add', 'edit', 'del', 'import'];
|
$btns = $btns ? $btns : ['refresh', 'add', 'edit', 'del', 'import'];
|
||||||
$btns = is_array($btns) ? $btns : explode(',', $btns);
|
$btns = is_array($btns) ? $btns : explode(',', $btns);
|
||||||
$index = array_search('delete', $btns);
|
$index = array_search('delete', $btns);
|
||||||
if ($index !== FALSE) {
|
if ($index !== false) {
|
||||||
$btns[$index] = 'del';
|
$btns[$index] = 'del';
|
||||||
}
|
}
|
||||||
$btnAttr = [
|
$btnAttr = [
|
||||||
|
|
@ -140,7 +141,7 @@ if (!function_exists('build_toolbar')) {
|
||||||
}
|
}
|
||||||
$download .= empty($download) ? '' : "\n ";
|
$download .= empty($download) ? '' : "\n ";
|
||||||
if (!empty($download)) {
|
if (!empty($download)) {
|
||||||
$html[] = <<<EOT
|
$html[] = <<<EOT
|
||||||
<div class="btn-group">
|
<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" 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="下载批量导入模版">
|
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" title="下载批量导入模版">
|
||||||
|
|
@ -169,7 +170,7 @@ if (!function_exists('build_heading')) {
|
||||||
* @param string $path 指定的path
|
* @param string $path 指定的path
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function build_heading($path = NULL, $container = TRUE)
|
function build_heading($path = null, $container = true)
|
||||||
{
|
{
|
||||||
$title = $content = '';
|
$title = $content = '';
|
||||||
if (is_null($path)) {
|
if (is_null($path)) {
|
||||||
|
|
@ -183,8 +184,9 @@ if (!function_exists('build_heading')) {
|
||||||
$title = __($data['title']);
|
$title = __($data['title']);
|
||||||
$content = __($data['remark']);
|
$content = __($data['remark']);
|
||||||
}
|
}
|
||||||
if (!$content)
|
if (!$content) {
|
||||||
return '';
|
return '';
|
||||||
|
}
|
||||||
$result = '<div class="panel-lead"><em>' . $title . '</em>' . $content . '</div>';
|
$result = '<div class="panel-lead"><em>' . $title . '</em>' . $content . '</div>';
|
||||||
if ($container) {
|
if ($container) {
|
||||||
$result = '<div class="panel-heading">' . $result . '</div>';
|
$result = '<div class="panel-heading">' . $result . '</div>';
|
||||||
|
|
|
||||||
|
|
@ -37,21 +37,16 @@ class Group extends Backend
|
||||||
|
|
||||||
Tree::instance()->init($groupList);
|
Tree::instance()->init($groupList);
|
||||||
$result = [];
|
$result = [];
|
||||||
if ($this->auth->isSuperAdmin())
|
if ($this->auth->isSuperAdmin()) {
|
||||||
{
|
|
||||||
$result = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0));
|
$result = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$groups = $this->auth->getGroups();
|
$groups = $this->auth->getGroups();
|
||||||
foreach ($groups as $m => $n)
|
foreach ($groups as $m => $n) {
|
||||||
{
|
|
||||||
$result = array_merge($result, Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['pid'])));
|
$result = array_merge($result, Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['pid'])));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$groupName = [];
|
$groupName = [];
|
||||||
foreach ($result as $k => $v)
|
foreach ($result as $k => $v) {
|
||||||
{
|
|
||||||
$groupName[$v['id']] = $v['name'];
|
$groupName[$v['id']] = $v['name'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,20 +61,16 @@ class Group extends Backend
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
if ($this->request->isAjax())
|
if ($this->request->isAjax()) {
|
||||||
{
|
|
||||||
$list = AuthGroup::all(array_keys($this->groupdata));
|
$list = AuthGroup::all(array_keys($this->groupdata));
|
||||||
$list = collection($list)->toArray();
|
$list = collection($list)->toArray();
|
||||||
$groupList = [];
|
$groupList = [];
|
||||||
foreach ($list as $k => $v)
|
foreach ($list as $k => $v) {
|
||||||
{
|
|
||||||
$groupList[$v['id']] = $v;
|
$groupList[$v['id']] = $v;
|
||||||
}
|
}
|
||||||
$list = [];
|
$list = [];
|
||||||
foreach ($this->groupdata as $k => $v)
|
foreach ($this->groupdata as $k => $v) {
|
||||||
{
|
if (isset($groupList[$k])) {
|
||||||
if (isset($groupList[$k]))
|
|
||||||
{
|
|
||||||
$groupList[$k]['name'] = $v;
|
$groupList[$k]['name'] = $v;
|
||||||
$list[] = $groupList[$k];
|
$list[] = $groupList[$k];
|
||||||
}
|
}
|
||||||
|
|
@ -97,17 +88,14 @@ class Group extends Backend
|
||||||
*/
|
*/
|
||||||
public function add()
|
public function add()
|
||||||
{
|
{
|
||||||
if ($this->request->isPost())
|
if ($this->request->isPost()) {
|
||||||
{
|
|
||||||
$params = $this->request->post("row/a", [], 'strip_tags');
|
$params = $this->request->post("row/a", [], 'strip_tags');
|
||||||
$params['rules'] = explode(',', $params['rules']);
|
$params['rules'] = explode(',', $params['rules']);
|
||||||
if (!in_array($params['pid'], $this->childrenGroupIds))
|
if (!in_array($params['pid'], $this->childrenGroupIds)) {
|
||||||
{
|
|
||||||
$this->error(__('The parent group can not be its own child'));
|
$this->error(__('The parent group can not be its own child'));
|
||||||
}
|
}
|
||||||
$parentmodel = model("AuthGroup")->get($params['pid']);
|
$parentmodel = model("AuthGroup")->get($params['pid']);
|
||||||
if (!$parentmodel)
|
if (!$parentmodel) {
|
||||||
{
|
|
||||||
$this->error(__('The parent group can not found'));
|
$this->error(__('The parent group can not found'));
|
||||||
}
|
}
|
||||||
// 父级别的规则节点
|
// 父级别的规则节点
|
||||||
|
|
@ -120,8 +108,7 @@ class Group extends Backend
|
||||||
// 如果当前组别不是超级管理员则需要过滤规则节点,不能超当前组别的权限
|
// 如果当前组别不是超级管理员则需要过滤规则节点,不能超当前组别的权限
|
||||||
$rules = in_array('*', $currentrules) ? $rules : array_intersect($currentrules, $rules);
|
$rules = in_array('*', $currentrules) ? $rules : array_intersect($currentrules, $rules);
|
||||||
$params['rules'] = implode(',', $rules);
|
$params['rules'] = implode(',', $rules);
|
||||||
if ($params)
|
if ($params) {
|
||||||
{
|
|
||||||
$this->model->create($params);
|
$this->model->create($params);
|
||||||
$this->success();
|
$this->success();
|
||||||
}
|
}
|
||||||
|
|
@ -133,24 +120,22 @@ class Group extends Backend
|
||||||
/**
|
/**
|
||||||
* 编辑
|
* 编辑
|
||||||
*/
|
*/
|
||||||
public function edit($ids = NULL)
|
public function edit($ids = null)
|
||||||
{
|
{
|
||||||
$row = $this->model->get(['id' => $ids]);
|
$row = $this->model->get(['id' => $ids]);
|
||||||
if (!$row)
|
if (!$row) {
|
||||||
$this->error(__('No Results were found'));
|
$this->error(__('No Results were found'));
|
||||||
if ($this->request->isPost())
|
}
|
||||||
{
|
if ($this->request->isPost()) {
|
||||||
$params = $this->request->post("row/a", [], 'strip_tags');
|
$params = $this->request->post("row/a", [], 'strip_tags');
|
||||||
// 父节点不能是它自身的子节点
|
// 父节点不能是它自身的子节点
|
||||||
if (!in_array($params['pid'], $this->childrenGroupIds))
|
if (!in_array($params['pid'], $this->childrenGroupIds)) {
|
||||||
{
|
|
||||||
$this->error(__('The parent group can not be its own child'));
|
$this->error(__('The parent group can not be its own child'));
|
||||||
}
|
}
|
||||||
$params['rules'] = explode(',', $params['rules']);
|
$params['rules'] = explode(',', $params['rules']);
|
||||||
|
|
||||||
$parentmodel = model("AuthGroup")->get($params['pid']);
|
$parentmodel = model("AuthGroup")->get($params['pid']);
|
||||||
if (!$parentmodel)
|
if (!$parentmodel) {
|
||||||
{
|
|
||||||
$this->error(__('The parent group can not found'));
|
$this->error(__('The parent group can not found'));
|
||||||
}
|
}
|
||||||
// 父级别的规则节点
|
// 父级别的规则节点
|
||||||
|
|
@ -163,8 +148,7 @@ class Group extends Backend
|
||||||
// 如果当前组别不是超级管理员则需要过滤规则节点,不能超当前组别的权限
|
// 如果当前组别不是超级管理员则需要过滤规则节点,不能超当前组别的权限
|
||||||
$rules = in_array('*', $currentrules) ? $rules : array_intersect($currentrules, $rules);
|
$rules = in_array('*', $currentrules) ? $rules : array_intersect($currentrules, $rules);
|
||||||
$params['rules'] = implode(',', $rules);
|
$params['rules'] = implode(',', $rules);
|
||||||
if ($params)
|
if ($params) {
|
||||||
{
|
|
||||||
$row->save($params);
|
$row->save($params);
|
||||||
$this->success();
|
$this->success();
|
||||||
}
|
}
|
||||||
|
|
@ -180,11 +164,10 @@ class Group extends Backend
|
||||||
*/
|
*/
|
||||||
public function del($ids = "")
|
public function del($ids = "")
|
||||||
{
|
{
|
||||||
if ($ids)
|
if ($ids) {
|
||||||
{
|
|
||||||
$ids = explode(',', $ids);
|
$ids = explode(',', $ids);
|
||||||
$grouplist = $this->auth->getGroups();
|
$grouplist = $this->auth->getGroups();
|
||||||
$group_ids = array_map(function($group) {
|
$group_ids = array_map(function ($group) {
|
||||||
return $group['id'];
|
return $group['id'];
|
||||||
}, $grouplist);
|
}, $grouplist);
|
||||||
// 移除掉当前管理员所在组别
|
// 移除掉当前管理员所在组别
|
||||||
|
|
@ -193,30 +176,25 @@ class Group extends Backend
|
||||||
// 循环判断每一个组别是否可删除
|
// 循环判断每一个组别是否可删除
|
||||||
$grouplist = $this->model->where('id', 'in', $ids)->select();
|
$grouplist = $this->model->where('id', 'in', $ids)->select();
|
||||||
$groupaccessmodel = model('AuthGroupAccess');
|
$groupaccessmodel = model('AuthGroupAccess');
|
||||||
foreach ($grouplist as $k => $v)
|
foreach ($grouplist as $k => $v) {
|
||||||
{
|
|
||||||
// 当前组别下有管理员
|
// 当前组别下有管理员
|
||||||
$groupone = $groupaccessmodel->get(['group_id' => $v['id']]);
|
$groupone = $groupaccessmodel->get(['group_id' => $v['id']]);
|
||||||
if ($groupone)
|
if ($groupone) {
|
||||||
{
|
|
||||||
$ids = array_diff($ids, [$v['id']]);
|
$ids = array_diff($ids, [$v['id']]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 当前组别下有子组别
|
// 当前组别下有子组别
|
||||||
$groupone = $this->model->get(['pid' => $v['id']]);
|
$groupone = $this->model->get(['pid' => $v['id']]);
|
||||||
if ($groupone)
|
if ($groupone) {
|
||||||
{
|
|
||||||
$ids = array_diff($ids, [$v['id']]);
|
$ids = array_diff($ids, [$v['id']]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!$ids)
|
if (!$ids) {
|
||||||
{
|
|
||||||
$this->error(__('You can not delete group that contain child group and administrators'));
|
$this->error(__('You can not delete group that contain child group and administrators'));
|
||||||
}
|
}
|
||||||
$count = $this->model->where('id', 'in', $ids)->delete();
|
$count = $this->model->where('id', 'in', $ids)->delete();
|
||||||
if ($count)
|
if ($count) {
|
||||||
{
|
|
||||||
$this->success();
|
$this->success();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -235,7 +213,7 @@ class Group extends Backend
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取角色权限树
|
* 读取角色权限树
|
||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
public function roletree()
|
public function roletree()
|
||||||
|
|
@ -246,35 +224,32 @@ class Group extends Backend
|
||||||
$id = $this->request->post("id");
|
$id = $this->request->post("id");
|
||||||
$pid = $this->request->post("pid");
|
$pid = $this->request->post("pid");
|
||||||
$parentGroupModel = $model->get($pid);
|
$parentGroupModel = $model->get($pid);
|
||||||
$currentGroupModel = NULL;
|
$currentGroupModel = null;
|
||||||
if ($id)
|
if ($id) {
|
||||||
{
|
|
||||||
$currentGroupModel = $model->get($id);
|
$currentGroupModel = $model->get($id);
|
||||||
}
|
}
|
||||||
if (($pid || $parentGroupModel) && (!$id || $currentGroupModel))
|
if (($pid || $parentGroupModel) && (!$id || $currentGroupModel)) {
|
||||||
{
|
$id = $id ? $id : null;
|
||||||
$id = $id ? $id : NULL;
|
|
||||||
$ruleList = collection(model('AuthRule')->order('weigh', 'desc')->order('id', 'asc')->select())->toArray();
|
$ruleList = collection(model('AuthRule')->order('weigh', 'desc')->order('id', 'asc')->select())->toArray();
|
||||||
//读取父类角色所有节点列表
|
//读取父类角色所有节点列表
|
||||||
$parentRuleList = [];
|
$parentRuleList = [];
|
||||||
if (in_array('*', explode(',', $parentGroupModel->rules)))
|
if (in_array('*', explode(',', $parentGroupModel->rules))) {
|
||||||
{
|
|
||||||
$parentRuleList = $ruleList;
|
$parentRuleList = $ruleList;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$parentRuleIds = explode(',', $parentGroupModel->rules);
|
$parentRuleIds = explode(',', $parentGroupModel->rules);
|
||||||
foreach ($ruleList as $k => $v)
|
foreach ($ruleList as $k => $v) {
|
||||||
{
|
if (in_array($v['id'], $parentRuleIds)) {
|
||||||
if (in_array($v['id'], $parentRuleIds))
|
|
||||||
{
|
|
||||||
$parentRuleList[] = $v;
|
$parentRuleList[] = $v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$ruleTree = new Tree();
|
||||||
|
$groupTree = new Tree();
|
||||||
//当前所有正常规则列表
|
//当前所有正常规则列表
|
||||||
Tree::instance()->init($parentRuleList);
|
$ruleTree->init($parentRuleList);
|
||||||
|
//角色组列表
|
||||||
|
$groupTree->init(collection(model('AuthGroup')->where('id', 'in', $this->childrenGroupIds)->select())->toArray());
|
||||||
|
|
||||||
//读取当前角色下规则ID集合
|
//读取当前角色下规则ID集合
|
||||||
$adminRuleIds = $this->auth->getRuleIds();
|
$adminRuleIds = $this->auth->getRuleIds();
|
||||||
|
|
@ -283,39 +258,34 @@ class Group extends Backend
|
||||||
//当前拥有的规则ID集合
|
//当前拥有的规则ID集合
|
||||||
$currentRuleIds = $id ? explode(',', $currentGroupModel->rules) : [];
|
$currentRuleIds = $id ? explode(',', $currentGroupModel->rules) : [];
|
||||||
|
|
||||||
if (!$id || !in_array($pid, Tree::instance()->getChildrenIds($id, TRUE)))
|
if (!$id || !in_array($pid, $this->childrenGroupIds) || !in_array($pid, $groupTree->getChildrenIds($id, true))) {
|
||||||
{
|
$parentRuleList = $ruleTree->getTreeList($ruleTree->getTreeArray(0), 'name');
|
||||||
$parentRuleList = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0), 'name');
|
|
||||||
$hasChildrens = [];
|
$hasChildrens = [];
|
||||||
foreach ($parentRuleList as $k => $v)
|
foreach ($parentRuleList as $k => $v) {
|
||||||
{
|
if ($v['haschild']) {
|
||||||
if ($v['haschild'])
|
|
||||||
$hasChildrens[] = $v['id'];
|
$hasChildrens[] = $v['id'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$parentRuleIds = array_map(function($item) {
|
$parentRuleIds = array_map(function ($item) {
|
||||||
return $item['id'];
|
return $item['id'];
|
||||||
}, $parentRuleList);
|
}, $parentRuleList);
|
||||||
$nodeList = [];
|
$nodeList = [];
|
||||||
foreach ($parentRuleList as $k => $v)
|
foreach ($parentRuleList as $k => $v) {
|
||||||
{
|
if (!$superadmin && !in_array($v['id'], $adminRuleIds)) {
|
||||||
if (!$superadmin && !in_array($v['id'], $adminRuleIds))
|
|
||||||
continue;
|
continue;
|
||||||
if ($v['pid'] && !in_array($v['pid'], $parentRuleIds))
|
}
|
||||||
|
if ($v['pid'] && !in_array($v['pid'], $parentRuleIds)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
$state = array('selected' => in_array($v['id'], $currentRuleIds) && !in_array($v['id'], $hasChildrens));
|
$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);
|
$nodeList[] = array('id' => $v['id'], 'parent' => $v['pid'] ? $v['pid'] : '#', 'text' => __($v['title']), 'type' => 'menu', 'state' => $state);
|
||||||
}
|
}
|
||||||
$this->success('', null, $nodeList);
|
$this->success('', null, $nodeList);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->error(__('Can not change the parent to child'));
|
$this->error(__('Can not change the parent to child'));
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->error(__('Group not found'));
|
$this->error(__('Group not found'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,12 @@ return [
|
||||||
'%d year%s ago' => '%d年前',
|
'%d year%s ago' => '%d年前',
|
||||||
'Set to normal' => '设为正常',
|
'Set to normal' => '设为正常',
|
||||||
'Set to hidden' => '设为隐藏',
|
'Set to hidden' => '设为隐藏',
|
||||||
|
'Recycle bin' => '回收站',
|
||||||
|
'Restore' => '还原',
|
||||||
|
'Restore all' => '还原全部',
|
||||||
|
'Destroy' => '销毁',
|
||||||
|
'Destroy all' => '清空回收站',
|
||||||
|
'Nothing need restore' => '没有需要还原的数据',
|
||||||
//提示
|
//提示
|
||||||
'Go back' => '返回首页',
|
'Go back' => '返回首页',
|
||||||
'Jump now' => '立即跳转',
|
'Jump now' => '立即跳转',
|
||||||
|
|
@ -130,6 +136,7 @@ return [
|
||||||
'Are you sure you want to delete the %s selected item?' => '确定删除选中的 %s 项?',
|
'Are you sure you want to delete the %s selected item?' => '确定删除选中的 %s 项?',
|
||||||
'Are you sure you want to delete this item?' => '确定删除此项?',
|
'Are you sure you want to delete this item?' => '确定删除此项?',
|
||||||
'Are you sure you want to delete or turncate?' => '确定删除或清空?',
|
'Are you sure you want to delete or turncate?' => '确定删除或清空?',
|
||||||
|
'Are you sure you want to truncate?' => '确定清空?',
|
||||||
'You have no permission' => '你没有权限访问',
|
'You have no permission' => '你没有权限访问',
|
||||||
'Please enter your username' => '请输入你的用户名',
|
'Please enter your username' => '请输入你的用户名',
|
||||||
'Please enter your password' => '请输入你的密码',
|
'Please enter your password' => '请输入你的密码',
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||||
use PhpOffice\PhpSpreadsheet\Reader\Xls;
|
use PhpOffice\PhpSpreadsheet\Reader\Xls;
|
||||||
use PhpOffice\PhpSpreadsheet\Reader\Csv;
|
use PhpOffice\PhpSpreadsheet\Reader\Csv;
|
||||||
|
use think\Exception;
|
||||||
|
|
||||||
trait Backend
|
trait Backend
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -19,15 +21,12 @@ trait Backend
|
||||||
{
|
{
|
||||||
if (is_array($this->excludeFields)) {
|
if (is_array($this->excludeFields)) {
|
||||||
foreach ($this->excludeFields as $field) {
|
foreach ($this->excludeFields as $field) {
|
||||||
if (key_exists($field,$params))
|
if (key_exists($field, $params)) {
|
||||||
{
|
|
||||||
unset($params[$field]);
|
unset($params[$field]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (key_exists($this->excludeFields, $params)) {
|
||||||
if (key_exists($this->excludeFields,$params))
|
|
||||||
{
|
|
||||||
unset($params[$this->excludeFields]);
|
unset($params[$this->excludeFields]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -104,7 +103,6 @@ trait Backend
|
||||||
if ($this->request->isPost()) {
|
if ($this->request->isPost()) {
|
||||||
$params = $this->request->post("row/a");
|
$params = $this->request->post("row/a");
|
||||||
if ($params) {
|
if ($params) {
|
||||||
|
|
||||||
$params = $this->preExcludeFields($params);
|
$params = $this->preExcludeFields($params);
|
||||||
|
|
||||||
if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
|
if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
|
||||||
|
|
@ -137,11 +135,12 @@ trait Backend
|
||||||
/**
|
/**
|
||||||
* 编辑
|
* 编辑
|
||||||
*/
|
*/
|
||||||
public function edit($ids = NULL)
|
public function edit($ids = null)
|
||||||
{
|
{
|
||||||
$row = $this->model->get($ids);
|
$row = $this->model->get($ids);
|
||||||
if (!$row)
|
if (!$row) {
|
||||||
$this->error(__('No Results were found'));
|
$this->error(__('No Results were found'));
|
||||||
|
}
|
||||||
$adminIds = $this->getDataLimitAdminIds();
|
$adminIds = $this->getDataLimitAdminIds();
|
||||||
if (is_array($adminIds)) {
|
if (is_array($adminIds)) {
|
||||||
if (!in_array($row[$this->dataLimitField], $adminIds)) {
|
if (!in_array($row[$this->dataLimitField], $adminIds)) {
|
||||||
|
|
@ -151,7 +150,6 @@ trait Backend
|
||||||
if ($this->request->isPost()) {
|
if ($this->request->isPost()) {
|
||||||
$params = $this->request->post("row/a");
|
$params = $this->request->post("row/a");
|
||||||
if ($params) {
|
if ($params) {
|
||||||
|
|
||||||
$params = $this->preExcludeFields($params);
|
$params = $this->preExcludeFields($params);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -419,5 +417,4 @@ trait Backend
|
||||||
|
|
||||||
$this->success();
|
$this->success();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@
|
||||||
<input id="c-{$item.name}" class="form-control" size="50" name="row[{$item.name}]" type="text" value="{$item.value}" data-tip="{$item.tip}">
|
<input id="c-{$item.name}" class="form-control" size="50" name="row[{$item.name}]" type="text" value="{$item.value}" data-tip="{$item.tip}">
|
||||||
<span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}" data-preview-id="p-{$item.name}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
|
<span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}" data-preview-id="p-{$item.name}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
|
||||||
<span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
|
<span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
|
||||||
|
<span class="msg-box n-right" for="c-{$item.name}"></span>
|
||||||
<ul class="row list-inline plupload-preview" id="p-{$item.name}"></ul>
|
<ul class="row list-inline plupload-preview" id="p-{$item.name}"></ul>
|
||||||
</div>
|
</div>
|
||||||
{/case}
|
{/case}
|
||||||
|
|
@ -109,6 +110,7 @@
|
||||||
<input id="c-{$item.name}" class="form-control" size="50" name="row[{$item.name}]" type="text" value="{$item.value}" data-tip="{$item.tip}">
|
<input id="c-{$item.name}" class="form-control" size="50" name="row[{$item.name}]" type="text" value="{$item.value}" data-tip="{$item.tip}">
|
||||||
<span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
|
<span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
|
||||||
<span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
|
<span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
|
||||||
|
<span class="msg-box n-right" for="c-{$item.name}"></span>
|
||||||
</div>
|
</div>
|
||||||
{/case}
|
{/case}
|
||||||
{case switch}
|
{case switch}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="nickname" class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><small>{:__('Check all')}</small></label></span>
|
<span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><small>{:__('Check all')}</small></label></span>
|
||||||
<span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><small>{:__('Expand all')}</small></label></span>
|
<span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><small>{:__('Expand all')}</small></label></span>
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="c-status" class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
|
||||||
<div class="radio">
|
<div class="radio">
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="nickname" class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><small>{:__('Check all')}</small></label></span>
|
<span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><small>{:__('Check all')}</small></label></span>
|
||||||
<span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><small>{:__('Expand all')}</small></label></span>
|
<span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><small>{:__('Expand all')}</small></label></span>
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="c-status" class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
|
||||||
<div class="radio">
|
<div class="radio">
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
|
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="content" class="control-label col-xs-12 col-sm-2">{:__('Ismenu')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Ismenu')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
{:build_radios('row[ismenu]', ['1'=>__('Yes'), '0'=>__('No')])}
|
{:build_radios('row[ismenu]', ['1'=>__('Yes'), '0'=>__('No')])}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="c-pid" class="control-label col-xs-12 col-sm-2">{:__('Pid')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Pid')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
{:build_select('row[pid]', $ruledata, null, ['class'=>'form-control', 'required'=>''])}
|
{:build_select('row[pid]', $ruledata, null, ['class'=>'form-control', 'required'=>''])}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="content" class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
{:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')])}
|
{:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')])}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
|
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="content" class="control-label col-xs-12 col-sm-2">{:__('Ismenu')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Ismenu')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
{:build_radios('row[ismenu]', ['1'=>__('Yes'), '0'=>__('No')], $row['ismenu'])}
|
{:build_radios('row[ismenu]', ['1'=>__('Yes'), '0'=>__('No')], $row['ismenu'])}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="pid" class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
{:build_select('row[pid]', $ruledata, $row['pid'], ['class'=>'form-control', 'required'=>''])}
|
{:build_select('row[pid]', $ruledata, $row['pid'], ['class'=>'form-control', 'required'=>''])}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="content" class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
{:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')], $row['status'])}
|
{:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')], $row['status'])}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="c-password" class="control-label col-xs-12 col-sm-2">{:__('Password')}:</label>
|
<label for="c-password" class="control-label col-xs-12 col-sm-2">{:__('Password')}:</label>
|
||||||
<div class="col-xs-12 col-sm-4">
|
<div class="col-xs-12 col-sm-4">
|
||||||
<input id="c-password" data-rule="" class="form-control" name="row[password]" type="text" value="" placeholder="{:__('Leave password blank if dont want to change')}" autocomplete="new-password" />
|
<input id="c-password" data-rule="password" class="form-control" name="row[password]" type="text" value="" placeholder="{:__('Leave password blank if dont want to change')}" autocomplete="new-password" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ class User extends Api
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 会员登录
|
* 会员登录
|
||||||
*
|
*
|
||||||
* @param string $account 账号
|
* @param string $account 账号
|
||||||
* @param string $password 密码
|
* @param string $password 密码
|
||||||
*/
|
*/
|
||||||
|
|
@ -40,25 +40,21 @@ class User extends Api
|
||||||
{
|
{
|
||||||
$account = $this->request->request('account');
|
$account = $this->request->request('account');
|
||||||
$password = $this->request->request('password');
|
$password = $this->request->request('password');
|
||||||
if (!$account || !$password)
|
if (!$account || !$password) {
|
||||||
{
|
|
||||||
$this->error(__('Invalid parameters'));
|
$this->error(__('Invalid parameters'));
|
||||||
}
|
}
|
||||||
$ret = $this->auth->login($account, $password);
|
$ret = $this->auth->login($account, $password);
|
||||||
if ($ret)
|
if ($ret) {
|
||||||
{
|
|
||||||
$data = ['userinfo' => $this->auth->getUserinfo()];
|
$data = ['userinfo' => $this->auth->getUserinfo()];
|
||||||
$this->success(__('Logged in successful'), $data);
|
$this->success(__('Logged in successful'), $data);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->error($this->auth->getError());
|
$this->error($this->auth->getError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 手机验证码登录
|
* 手机验证码登录
|
||||||
*
|
*
|
||||||
* @param string $mobile 手机号
|
* @param string $mobile 手机号
|
||||||
* @param string $captcha 验证码
|
* @param string $captcha 验证码
|
||||||
*/
|
*/
|
||||||
|
|
@ -66,43 +62,34 @@ class User extends Api
|
||||||
{
|
{
|
||||||
$mobile = $this->request->request('mobile');
|
$mobile = $this->request->request('mobile');
|
||||||
$captcha = $this->request->request('captcha');
|
$captcha = $this->request->request('captcha');
|
||||||
if (!$mobile || !$captcha)
|
if (!$mobile || !$captcha) {
|
||||||
{
|
|
||||||
$this->error(__('Invalid parameters'));
|
$this->error(__('Invalid parameters'));
|
||||||
}
|
}
|
||||||
if (!Validate::regex($mobile, "^1\d{10}$"))
|
if (!Validate::regex($mobile, "^1\d{10}$")) {
|
||||||
{
|
|
||||||
$this->error(__('Mobile is incorrect'));
|
$this->error(__('Mobile is incorrect'));
|
||||||
}
|
}
|
||||||
if (!Sms::check($mobile, $captcha, 'mobilelogin'))
|
if (!Sms::check($mobile, $captcha, 'mobilelogin')) {
|
||||||
{
|
|
||||||
$this->error(__('Captcha is incorrect'));
|
$this->error(__('Captcha is incorrect'));
|
||||||
}
|
}
|
||||||
$user = \app\common\model\User::getByMobile($mobile);
|
$user = \app\common\model\User::getByMobile($mobile);
|
||||||
if ($user)
|
if ($user) {
|
||||||
{
|
|
||||||
//如果已经有账号则直接登录
|
//如果已经有账号则直接登录
|
||||||
$ret = $this->auth->direct($user->id);
|
$ret = $this->auth->direct($user->id);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$ret = $this->auth->register($mobile, Random::alnum(), '', $mobile, []);
|
$ret = $this->auth->register($mobile, Random::alnum(), '', $mobile, []);
|
||||||
}
|
}
|
||||||
if ($ret)
|
if ($ret) {
|
||||||
{
|
|
||||||
Sms::flush($mobile, 'mobilelogin');
|
Sms::flush($mobile, 'mobilelogin');
|
||||||
$data = ['userinfo' => $this->auth->getUserinfo()];
|
$data = ['userinfo' => $this->auth->getUserinfo()];
|
||||||
$this->success(__('Logged in successful'), $data);
|
$this->success(__('Logged in successful'), $data);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->error($this->auth->getError());
|
$this->error($this->auth->getError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册会员
|
* 注册会员
|
||||||
*
|
*
|
||||||
* @param string $username 用户名
|
* @param string $username 用户名
|
||||||
* @param string $password 密码
|
* @param string $password 密码
|
||||||
* @param string $email 邮箱
|
* @param string $email 邮箱
|
||||||
|
|
@ -114,26 +101,20 @@ class User extends Api
|
||||||
$password = $this->request->request('password');
|
$password = $this->request->request('password');
|
||||||
$email = $this->request->request('email');
|
$email = $this->request->request('email');
|
||||||
$mobile = $this->request->request('mobile');
|
$mobile = $this->request->request('mobile');
|
||||||
if (!$username || !$password)
|
if (!$username || !$password) {
|
||||||
{
|
|
||||||
$this->error(__('Invalid parameters'));
|
$this->error(__('Invalid parameters'));
|
||||||
}
|
}
|
||||||
if ($email && !Validate::is($email, "email"))
|
if ($email && !Validate::is($email, "email")) {
|
||||||
{
|
|
||||||
$this->error(__('Email is incorrect'));
|
$this->error(__('Email is incorrect'));
|
||||||
}
|
}
|
||||||
if ($mobile && !Validate::regex($mobile, "^1\d{10}$"))
|
if ($mobile && !Validate::regex($mobile, "^1\d{10}$")) {
|
||||||
{
|
|
||||||
$this->error(__('Mobile is incorrect'));
|
$this->error(__('Mobile is incorrect'));
|
||||||
}
|
}
|
||||||
$ret = $this->auth->register($username, $password, $email, $mobile, []);
|
$ret = $this->auth->register($username, $password, $email, $mobile, []);
|
||||||
if ($ret)
|
if ($ret) {
|
||||||
{
|
|
||||||
$data = ['userinfo' => $this->auth->getUserinfo()];
|
$data = ['userinfo' => $this->auth->getUserinfo()];
|
||||||
$this->success(__('Sign up successful'), $data);
|
$this->success(__('Sign up successful'), $data);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->error($this->auth->getError());
|
$this->error($this->auth->getError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -149,7 +130,7 @@ class User extends Api
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改会员个人信息
|
* 修改会员个人信息
|
||||||
*
|
*
|
||||||
* @param string $avatar 头像地址
|
* @param string $avatar 头像地址
|
||||||
* @param string $username 用户名
|
* @param string $username 用户名
|
||||||
* @param string $nickname 昵称
|
* @param string $nickname 昵称
|
||||||
|
|
@ -162,12 +143,13 @@ class User extends Api
|
||||||
$nickname = $this->request->request('nickname');
|
$nickname = $this->request->request('nickname');
|
||||||
$bio = $this->request->request('bio');
|
$bio = $this->request->request('bio');
|
||||||
$avatar = $this->request->request('avatar');
|
$avatar = $this->request->request('avatar');
|
||||||
$exists = \app\common\model\User::where('username', $username)->where('id', '<>', $this->auth->id)->find();
|
if ($username) {
|
||||||
if ($exists)
|
$exists = \app\common\model\User::where('username', $username)->where('id', '<>', $this->auth->id)->find();
|
||||||
{
|
if ($exists) {
|
||||||
$this->error(__('Username already exists'));
|
$this->error(__('Username already exists'));
|
||||||
|
}
|
||||||
|
$user->username = $username;
|
||||||
}
|
}
|
||||||
$user->username = $username;
|
|
||||||
$user->nickname = $nickname;
|
$user->nickname = $nickname;
|
||||||
$user->bio = $bio;
|
$user->bio = $bio;
|
||||||
$user->avatar = $avatar;
|
$user->avatar = $avatar;
|
||||||
|
|
@ -177,7 +159,7 @@ class User extends Api
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改邮箱
|
* 修改邮箱
|
||||||
*
|
*
|
||||||
* @param string $email 邮箱
|
* @param string $email 邮箱
|
||||||
* @param string $captcha 验证码
|
* @param string $captcha 验证码
|
||||||
*/
|
*/
|
||||||
|
|
@ -186,21 +168,17 @@ class User extends Api
|
||||||
$user = $this->auth->getUser();
|
$user = $this->auth->getUser();
|
||||||
$email = $this->request->post('email');
|
$email = $this->request->post('email');
|
||||||
$captcha = $this->request->request('captcha');
|
$captcha = $this->request->request('captcha');
|
||||||
if (!$email || !$captcha)
|
if (!$email || !$captcha) {
|
||||||
{
|
|
||||||
$this->error(__('Invalid parameters'));
|
$this->error(__('Invalid parameters'));
|
||||||
}
|
}
|
||||||
if (!Validate::is($email, "email"))
|
if (!Validate::is($email, "email")) {
|
||||||
{
|
|
||||||
$this->error(__('Email is incorrect'));
|
$this->error(__('Email is incorrect'));
|
||||||
}
|
}
|
||||||
if (\app\common\model\User::where('email', $email)->where('id', '<>', $user->id)->find())
|
if (\app\common\model\User::where('email', $email)->where('id', '<>', $user->id)->find()) {
|
||||||
{
|
|
||||||
$this->error(__('Email already exists'));
|
$this->error(__('Email already exists'));
|
||||||
}
|
}
|
||||||
$result = Ems::check($email, $captcha, 'changeemail');
|
$result = Ems::check($email, $captcha, 'changeemail');
|
||||||
if (!$result)
|
if (!$result) {
|
||||||
{
|
|
||||||
$this->error(__('Captcha is incorrect'));
|
$this->error(__('Captcha is incorrect'));
|
||||||
}
|
}
|
||||||
$verification = $user->verification;
|
$verification = $user->verification;
|
||||||
|
|
@ -215,7 +193,7 @@ class User extends Api
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改手机号
|
* 修改手机号
|
||||||
*
|
*
|
||||||
* @param string $email 手机号
|
* @param string $email 手机号
|
||||||
* @param string $captcha 验证码
|
* @param string $captcha 验证码
|
||||||
*/
|
*/
|
||||||
|
|
@ -224,21 +202,17 @@ class User extends Api
|
||||||
$user = $this->auth->getUser();
|
$user = $this->auth->getUser();
|
||||||
$mobile = $this->request->request('mobile');
|
$mobile = $this->request->request('mobile');
|
||||||
$captcha = $this->request->request('captcha');
|
$captcha = $this->request->request('captcha');
|
||||||
if (!$mobile || !$captcha)
|
if (!$mobile || !$captcha) {
|
||||||
{
|
|
||||||
$this->error(__('Invalid parameters'));
|
$this->error(__('Invalid parameters'));
|
||||||
}
|
}
|
||||||
if (!Validate::regex($mobile, "^1\d{10}$"))
|
if (!Validate::regex($mobile, "^1\d{10}$")) {
|
||||||
{
|
|
||||||
$this->error(__('Mobile is incorrect'));
|
$this->error(__('Mobile is incorrect'));
|
||||||
}
|
}
|
||||||
if (\app\common\model\User::where('mobile', $mobile)->where('id', '<>', $user->id)->find())
|
if (\app\common\model\User::where('mobile', $mobile)->where('id', '<>', $user->id)->find()) {
|
||||||
{
|
|
||||||
$this->error(__('Mobile already exists'));
|
$this->error(__('Mobile already exists'));
|
||||||
}
|
}
|
||||||
$result = Sms::check($mobile, $captcha, 'changemobile');
|
$result = Sms::check($mobile, $captcha, 'changemobile');
|
||||||
if (!$result)
|
if (!$result) {
|
||||||
{
|
|
||||||
$this->error(__('Captcha is incorrect'));
|
$this->error(__('Captcha is incorrect'));
|
||||||
}
|
}
|
||||||
$verification = $user->verification;
|
$verification = $user->verification;
|
||||||
|
|
@ -253,7 +227,7 @@ class User extends Api
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 第三方登录
|
* 第三方登录
|
||||||
*
|
*
|
||||||
* @param string $platform 平台名称
|
* @param string $platform 平台名称
|
||||||
* @param string $code Code码
|
* @param string $code Code码
|
||||||
*/
|
*/
|
||||||
|
|
@ -263,18 +237,15 @@ class User extends Api
|
||||||
$platform = $this->request->request("platform");
|
$platform = $this->request->request("platform");
|
||||||
$code = $this->request->request("code");
|
$code = $this->request->request("code");
|
||||||
$config = get_addon_config('third');
|
$config = get_addon_config('third');
|
||||||
if (!$config || !isset($config[$platform]))
|
if (!$config || !isset($config[$platform])) {
|
||||||
{
|
|
||||||
$this->error(__('Invalid parameters'));
|
$this->error(__('Invalid parameters'));
|
||||||
}
|
}
|
||||||
$app = new \addons\third\library\Application($config);
|
$app = new \addons\third\library\Application($config);
|
||||||
//通过code换access_token和绑定会员
|
//通过code换access_token和绑定会员
|
||||||
$result = $app->{$platform}->getUserInfo(['code' => $code]);
|
$result = $app->{$platform}->getUserInfo(['code' => $code]);
|
||||||
if ($result)
|
if ($result) {
|
||||||
{
|
|
||||||
$loginret = \addons\third\library\Service::connect($platform, $result);
|
$loginret = \addons\third\library\Service::connect($platform, $result);
|
||||||
if ($loginret)
|
if ($loginret) {
|
||||||
{
|
|
||||||
$data = [
|
$data = [
|
||||||
'userinfo' => $this->auth->getUserinfo(),
|
'userinfo' => $this->auth->getUserinfo(),
|
||||||
'thirdinfo' => $result
|
'thirdinfo' => $result
|
||||||
|
|
@ -287,7 +258,7 @@ class User extends Api
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置密码
|
* 重置密码
|
||||||
*
|
*
|
||||||
* @param string $mobile 手机号
|
* @param string $mobile 手机号
|
||||||
* @param string $newpassword 新密码
|
* @param string $newpassword 新密码
|
||||||
* @param string $captcha 验证码
|
* @param string $captcha 验证码
|
||||||
|
|
@ -299,42 +270,32 @@ class User extends Api
|
||||||
$email = $this->request->request("email");
|
$email = $this->request->request("email");
|
||||||
$newpassword = $this->request->request("newpassword");
|
$newpassword = $this->request->request("newpassword");
|
||||||
$captcha = $this->request->request("captcha");
|
$captcha = $this->request->request("captcha");
|
||||||
if (!$newpassword || !$captcha)
|
if (!$newpassword || !$captcha) {
|
||||||
{
|
|
||||||
$this->error(__('Invalid parameters'));
|
$this->error(__('Invalid parameters'));
|
||||||
}
|
}
|
||||||
if ($type == 'mobile')
|
if ($type == 'mobile') {
|
||||||
{
|
if (!Validate::regex($mobile, "^1\d{10}$")) {
|
||||||
if (!Validate::regex($mobile, "^1\d{10}$"))
|
|
||||||
{
|
|
||||||
$this->error(__('Mobile is incorrect'));
|
$this->error(__('Mobile is incorrect'));
|
||||||
}
|
}
|
||||||
$user = \app\common\model\User::getByMobile($mobile);
|
$user = \app\common\model\User::getByMobile($mobile);
|
||||||
if (!$user)
|
if (!$user) {
|
||||||
{
|
|
||||||
$this->error(__('User not found'));
|
$this->error(__('User not found'));
|
||||||
}
|
}
|
||||||
$ret = Sms::check($mobile, $captcha, 'resetpwd');
|
$ret = Sms::check($mobile, $captcha, 'resetpwd');
|
||||||
if (!$ret)
|
if (!$ret) {
|
||||||
{
|
|
||||||
$this->error(__('Captcha is incorrect'));
|
$this->error(__('Captcha is incorrect'));
|
||||||
}
|
}
|
||||||
Sms::flush($mobile, 'resetpwd');
|
Sms::flush($mobile, 'resetpwd');
|
||||||
}
|
} else {
|
||||||
else
|
if (!Validate::is($email, "email")) {
|
||||||
{
|
|
||||||
if (!Validate::is($email, "email"))
|
|
||||||
{
|
|
||||||
$this->error(__('Email is incorrect'));
|
$this->error(__('Email is incorrect'));
|
||||||
}
|
}
|
||||||
$user = \app\common\model\User::getByEmail($email);
|
$user = \app\common\model\User::getByEmail($email);
|
||||||
if (!$user)
|
if (!$user) {
|
||||||
{
|
|
||||||
$this->error(__('User not found'));
|
$this->error(__('User not found'));
|
||||||
}
|
}
|
||||||
$ret = Ems::check($email, $captcha, 'resetpwd');
|
$ret = Ems::check($email, $captcha, 'resetpwd');
|
||||||
if (!$ret)
|
if (!$ret) {
|
||||||
{
|
|
||||||
$this->error(__('Captcha is incorrect'));
|
$this->error(__('Captcha is incorrect'));
|
||||||
}
|
}
|
||||||
Ems::flush($email, 'resetpwd');
|
Ems::flush($email, 'resetpwd');
|
||||||
|
|
@ -342,12 +303,9 @@ class User extends Api
|
||||||
//模拟一次登录
|
//模拟一次登录
|
||||||
$this->auth->direct($user->id);
|
$this->auth->direct($user->id);
|
||||||
$ret = $this->auth->changepwd($newpassword, '', true);
|
$ret = $this->auth->changepwd($newpassword, '', true);
|
||||||
if ($ret)
|
if ($ret) {
|
||||||
{
|
|
||||||
$this->success(__('Reset password successful'));
|
$this->success(__('Reset password successful'));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->error($this->auth->getError());
|
$this->error($this->auth->getError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ class Frontend extends Controller
|
||||||
$this->auth->init($token);
|
$this->auth->init($token);
|
||||||
//检测是否登录
|
//检测是否登录
|
||||||
if (!$this->auth->isLogin()) {
|
if (!$this->auth->isLogin()) {
|
||||||
$this->error(__('Please login first'), 'user/login');
|
$this->error(__('Please login first'), 'index/user/login');
|
||||||
}
|
}
|
||||||
// 判断是否需要验证权限
|
// 判断是否需要验证权限
|
||||||
if (!$this->auth->match($this->noNeedRight)) {
|
if (!$this->auth->match($this->noNeedRight)) {
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,9 @@
|
||||||
padding-left:0px;
|
padding-left:0px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.label-primary {
|
||||||
|
background-color: #248aff;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
@ -3727,7 +3730,7 @@
|
||||||
|
|
||||||
<div class="row mt0 footer">
|
<div class="row mt0 footer">
|
||||||
<div class="col-md-6" align="left">
|
<div class="col-md-6" align="left">
|
||||||
Generated on 2018-10-19 17:00:36 </div>
|
Generated on 2019-02-26 17:13:43 </div>
|
||||||
<div class="col-md-6" align="right">
|
<div class="col-md-6" align="right">
|
||||||
<a href="https://www.fastadmin.net" target="_blank">FastAdmin</a>
|
<a href="https://www.fastadmin.net" target="_blank">FastAdmin</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3929,6 +3932,9 @@
|
||||||
contentType: false,
|
contentType: false,
|
||||||
processData: false,
|
processData: false,
|
||||||
headers: headers,
|
headers: headers,
|
||||||
|
xhrFields: {
|
||||||
|
withCredentials: true
|
||||||
|
},
|
||||||
success: function (data, textStatus, xhr) {
|
success: function (data, textStatus, xhr) {
|
||||||
if (typeof data === 'object') {
|
if (typeof data === 'object') {
|
||||||
var str = JSON.stringify(data, null, 2);
|
var str = JSON.stringify(data, null, 2);
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -92,7 +92,7 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin
|
||||||
'click .btn-chooseone': function (e, value, row, index) {
|
'click .btn-chooseone': function (e, value, row, index) {
|
||||||
var multiple = Backend.api.query('multiple');
|
var multiple = Backend.api.query('multiple');
|
||||||
multiple = multiple == 'true' ? true : false;
|
multiple = multiple == 'true' ? true : false;
|
||||||
Fast.api.close({url: row.url, multiple: false});
|
Fast.api.close({url: row.url, multiple: multiple});
|
||||||
},
|
},
|
||||||
}, formatter: function () {
|
}, formatter: function () {
|
||||||
return '<a href="javascript:;" class="btn btn-danger btn-chooseone btn-xs"><i class="fa fa-check"></i> ' + __('Choose') + '</a>';
|
return '<a href="javascript:;" class="btn btn-danger btn-chooseone btn-xs"><i class="fa fa-check"></i> ' + __('Choose') + '</a>';
|
||||||
|
|
@ -110,7 +110,7 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin
|
||||||
});
|
});
|
||||||
var multiple = Backend.api.query('multiple');
|
var multiple = Backend.api.query('multiple');
|
||||||
multiple = multiple == 'true' ? true : false;
|
multiple = multiple == 'true' ? true : false;
|
||||||
Fast.api.close({url: urlArr.join(","), multiple: true});
|
Fast.api.close({url: urlArr.join(","), multiple: multiple});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 为表格绑定事件
|
// 为表格绑定事件
|
||||||
|
|
|
||||||
|
|
@ -350,7 +350,7 @@
|
||||||
var searchQuery = getSearchQuery(this);
|
var searchQuery = getSearchQuery(this);
|
||||||
this.trigger('common-search', this, searchQuery);
|
this.trigger('common-search', this, searchQuery);
|
||||||
this.options.pageNumber = 1;
|
this.options.pageNumber = 1;
|
||||||
this.options.pageSize = $.fn.bootstrapTable.defaults.pageSize;
|
//this.options.pageSize = $.fn.bootstrapTable.defaults.pageSize;
|
||||||
this.refresh({});
|
this.refresh({});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, undefine
|
||||||
},
|
},
|
||||||
//打开一个弹出窗口
|
//打开一个弹出窗口
|
||||||
open: function (url, title, options) {
|
open: function (url, title, options) {
|
||||||
title = title ? title : "";
|
title = options && options.title ? options.title : (title ? title : "");
|
||||||
url = Fast.api.fixurl(url);
|
url = Fast.api.fixurl(url);
|
||||||
url = url + (url.indexOf("?") > -1 ? "&" : "?") + "dialog=1";
|
url = url + (url.indexOf("?") > -1 ? "&" : "?") + "dialog=1";
|
||||||
var area = [$(window).width() > 800 ? '800px' : '95%', $(window).height() > 600 ? '600px' : '95%'];
|
var area = [$(window).width() > 800 ? '800px' : '95%', $(window).height() > 600 ? '600px' : '95%'];
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -16,6 +16,10 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
|
||||||
showExport: true,
|
showExport: true,
|
||||||
exportDataType: "all",
|
exportDataType: "all",
|
||||||
exportTypes: ['json', 'xml', 'csv', 'txt', 'doc', 'excel'],
|
exportTypes: ['json', 'xml', 'csv', 'txt', 'doc', 'excel'],
|
||||||
|
exportOptions: {
|
||||||
|
fileName: 'export_' + Moment().format("YYYY-MM-DD"),
|
||||||
|
ignoreColumn: [0, 'operate'] //默认不导出第一列(checkbox)与操作(operate)列
|
||||||
|
},
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
pageList: [10, 25, 50, 'All'],
|
pageList: [10, 25, 50, 'All'],
|
||||||
pagination: true,
|
pagination: true,
|
||||||
|
|
@ -62,6 +66,10 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
|
||||||
multibtn: '.btn-multi',
|
multibtn: '.btn-multi',
|
||||||
disabledbtn: '.btn-disabled',
|
disabledbtn: '.btn-disabled',
|
||||||
editonebtn: '.btn-editone',
|
editonebtn: '.btn-editone',
|
||||||
|
restoreonebtn: '.btn-restoreone',
|
||||||
|
destroyonebtn: '.btn-destroyone',
|
||||||
|
restoreallbtn: '.btn-restoreall',
|
||||||
|
destroyallbtn: '.btn-destroyall',
|
||||||
dragsortfield: 'weigh',
|
dragsortfield: 'weigh',
|
||||||
},
|
},
|
||||||
api: {
|
api: {
|
||||||
|
|
@ -203,6 +211,29 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
|
||||||
Fast.api.open(url, __('Edit'), $(that).data() || {});
|
Fast.api.open(url, __('Edit'), $(that).data() || {});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
//清空回收站
|
||||||
|
$(document).on('click', Table.config.destroyallbtn, function () {
|
||||||
|
var that = this;
|
||||||
|
Layer.confirm(__('Are you sure you want to truncate?'), function () {
|
||||||
|
var url = $(that).data("url") ? $(that).data("url") : $(that).attr("href");
|
||||||
|
Fast.api.ajax(url, function () {
|
||||||
|
Layer.closeAll();
|
||||||
|
table.bootstrapTable('refresh');
|
||||||
|
}, function () {
|
||||||
|
Layer.closeAll();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
//还原或删除
|
||||||
|
$(document).on('click', Table.config.restoreallbtn + ',' + Table.config.restoreonebtn + ',' + Table.config.destroyonebtn, function () {
|
||||||
|
var that = this;
|
||||||
|
var url = $(that).data("url") ? $(that).data("url") : $(that).attr("href");
|
||||||
|
Fast.api.ajax(url, function () {
|
||||||
|
table.bootstrapTable('refresh');
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
// 批量操作按钮事件
|
// 批量操作按钮事件
|
||||||
$(toolbar).on('click', Table.config.multibtn, function () {
|
$(toolbar).on('click', Table.config.multibtn, function () {
|
||||||
var ids = Table.api.selectedids(table);
|
var ids = Table.api.selectedids(table);
|
||||||
|
|
@ -369,14 +400,14 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
|
||||||
},//单元格图片预览
|
},//单元格图片预览
|
||||||
image: {
|
image: {
|
||||||
'click .img-center': function (e, value, row, index) {
|
'click .img-center': function (e, value, row, index) {
|
||||||
data = [];
|
var data = [];
|
||||||
value= value.split(",");
|
value = value.split(",");
|
||||||
$.each(value, function (index, value) {
|
$.each(value, function (index, value) {
|
||||||
data.push({
|
data.push({
|
||||||
src: Fast.api.cdnurl(value),
|
src: Fast.api.cdnurl(value),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
layer.photos({
|
Layer.photos({
|
||||||
photos: {
|
photos: {
|
||||||
"data": data
|
"data": data
|
||||||
},
|
},
|
||||||
|
|
@ -558,7 +589,8 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
|
||||||
type = typeof type === 'undefined' ? 'buttons' : type;
|
type = typeof type === 'undefined' ? 'buttons' : type;
|
||||||
var options = table ? table.bootstrapTable('getOptions') : {};
|
var options = table ? table.bootstrapTable('getOptions') : {};
|
||||||
var html = [];
|
var html = [];
|
||||||
var hidden, visible, disable, url, classname, icon, text, title, refresh, confirm, extend, click, dropdown, link;
|
var hidden, visible, disable, url, classname, icon, text, title, refresh, confirm, extend,
|
||||||
|
dropdown, link;
|
||||||
var fieldIndex = column.fieldIndex;
|
var fieldIndex = column.fieldIndex;
|
||||||
var dropdowns = {};
|
var dropdowns = {};
|
||||||
|
|
||||||
|
|
@ -573,11 +605,11 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
|
||||||
}
|
}
|
||||||
var attr = table.data(type + "-" + j.name);
|
var attr = table.data(type + "-" + j.name);
|
||||||
if (typeof attr === 'undefined' || attr) {
|
if (typeof attr === 'undefined' || attr) {
|
||||||
hidden = typeof j.hidden === 'function' ? j.hidden.call(table, row, j) : (j.hidden ? j.hidden : false);
|
hidden = typeof j.hidden === 'function' ? j.hidden.call(table, row, j) : (typeof j.hidden !== 'undefined' ? j.hidden : false);
|
||||||
if (hidden) {
|
if (hidden) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
visible = typeof j.visible === 'function' ? j.visible.call(table, row, j) : (j.visible ? j.visible : true);
|
visible = typeof j.visible === 'function' ? j.visible.call(table, row, j) : (typeof j.visible !== 'undefined' ? j.visible : true);
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -586,12 +618,12 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
|
||||||
url = typeof url === 'function' ? url.call(table, row, j) : (url ? Fast.api.fixurl(Table.api.replaceurl(url, row, table)) : 'javascript:;');
|
url = typeof url === 'function' ? url.call(table, row, j) : (url ? Fast.api.fixurl(Table.api.replaceurl(url, row, table)) : 'javascript:;');
|
||||||
classname = j.classname ? j.classname : 'btn-primary btn-' + name + 'one';
|
classname = j.classname ? j.classname : 'btn-primary btn-' + name + 'one';
|
||||||
icon = j.icon ? j.icon : '';
|
icon = j.icon ? j.icon : '';
|
||||||
text = j.text ? j.text : '';
|
text = typeof j.text === 'function' ? j.text.call(table, row, j) : j.text ? j.text : '';
|
||||||
title = j.title ? j.title : text;
|
title = typeof j.title === 'function' ? j.title.call(table, row, j) : j.title ? j.title : text;
|
||||||
refresh = j.refresh ? 'data-refresh="' + j.refresh + '"' : '';
|
refresh = j.refresh ? 'data-refresh="' + j.refresh + '"' : '';
|
||||||
confirm = j.confirm ? 'data-confirm="' + j.confirm + '"' : '';
|
confirm = j.confirm ? 'data-confirm="' + j.confirm + '"' : '';
|
||||||
extend = j.extend ? j.extend : '';
|
extend = j.extend ? j.extend : '';
|
||||||
disable = typeof j.disable === 'function' ? j.disable.call(table, row, j) : (j.disable ? j.disable : false);
|
disable = typeof j.disable === 'function' ? j.disable.call(table, row, j) : (typeof j.disable !== 'undefined' ? j.disable : false);
|
||||||
if (disable) {
|
if (disable) {
|
||||||
classname = classname + ' disabled';
|
classname = classname + ' disabled';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue