安装插件后的基础文件
This commit is contained in:
47
plugin/developer/Developer.php
Normal file
47
plugin/developer/Developer.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace plugin\developer;
|
||||
|
||||
use app\PluginController;
|
||||
/**
|
||||
* 开发助手插件
|
||||
*/
|
||||
class Developer extends PluginController
|
||||
{
|
||||
/**
|
||||
* 插件安装方法
|
||||
* @return bool
|
||||
*/
|
||||
public function install()
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件卸载方法
|
||||
* @return bool
|
||||
*/
|
||||
public function uninstall()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件启用方法
|
||||
* @return bool
|
||||
*/
|
||||
public function enabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件禁用方法
|
||||
* @return bool
|
||||
*/
|
||||
public function disabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
32
plugin/developer/README.md
Normal file
32
plugin/developer/README.md
Normal file
@@ -0,0 +1,32 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | swiftAdmin 极速开发框架 [基于 WebMan 开发]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2020-2099 http://www.swiftadmin.net
|
||||
// +----------------------------------------------------------------------
|
||||
// | swiftAdmin.net High Speed Development Framework
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: meystack <coolsec@foxmail.com> Apache2
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
* app 文件夹下所有文件将复制到根目录
|
||||
|
||||
* public 文件夹下所有文件将复制到根目录
|
||||
|
||||
* data 附加文件,menu.php文件插件后台菜单,menu.html为插件前台菜单
|
||||
|
||||
* Developer.php 为插件的核心安装文件,请务必按要求书写代码
|
||||
请注意钩子函数为public类型,如需非钩子函数可使用protected类型
|
||||
|
||||
* function.php 为当前插件的函数库文件
|
||||
|
||||
* config.php 为当前插件的配置信息文件
|
||||
|
||||
* config.html 为当前配置模板,存在才会出现配置按钮
|
||||
|
||||
* install.sql 插件的数据库安装文件,不需要可删除!!
|
||||
|
||||
* uninstall.sql 插件的数据库卸载文件,不需要可删除!!
|
||||
|
||||
* library 该目录下为第三方类库文件,如果你的类库文件存在命名空间问题,
|
||||
可手动修改或自行实现install方法将第三方类库复制到extend文件夹下!
|
||||
|
||||
22
plugin/developer/Upgrade.php
Normal file
22
plugin/developer/Upgrade.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace plugin\developer;
|
||||
|
||||
/**
|
||||
* 开发助手
|
||||
* 升级脚本
|
||||
*/
|
||||
class Upgrade
|
||||
{
|
||||
/**
|
||||
* 插件升级方法
|
||||
* @access public
|
||||
* @param $oldVersion
|
||||
* @param $newVersion
|
||||
* @return bool
|
||||
*/
|
||||
public function execute($oldVersion, $newVersion): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
804
plugin/developer/app/admin/controller/developer/Curd.php
Normal file
804
plugin/developer/app/admin/controller/developer/Curd.php
Normal file
@@ -0,0 +1,804 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
// +----------------------------------------------------------------------
|
||||
// | swiftAdmin 极速开发框架 [基于WebMan开发]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
|
||||
// +----------------------------------------------------------------------
|
||||
// | swiftAdmin.net High Speed Development Framework
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\admin\controller\developer;
|
||||
|
||||
use app\admin\model\developer\Generate;
|
||||
use app\AdminController;
|
||||
use app\common\model\system\AdminRules;
|
||||
use system\Form;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
use think\facade\Db;
|
||||
use think\helper\Str;
|
||||
|
||||
/**
|
||||
* 一键CURD管理
|
||||
* <!--Developer-->
|
||||
* Class Curd
|
||||
* @package app\admin\controller\developer
|
||||
*/
|
||||
class Curd extends AdminController
|
||||
{
|
||||
/**
|
||||
* 数据表前缀
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public mixed $prefix = 'sa_';
|
||||
|
||||
/**
|
||||
* 获取菜单
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public array $menus = [];
|
||||
|
||||
/**
|
||||
* 关联表信息
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public array $relation = [];
|
||||
|
||||
/**
|
||||
* 函数体
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public array $methods = [];
|
||||
|
||||
/**
|
||||
* 模板路径
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public string $templatePath = '';
|
||||
|
||||
/**
|
||||
* 模板文件
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public array $templateFiles = [];
|
||||
|
||||
/**
|
||||
* 添加时间字段
|
||||
* @var string
|
||||
*/
|
||||
protected string $createTimeField = 'create_time';
|
||||
|
||||
/**
|
||||
* 更新时间字段
|
||||
* @var string
|
||||
*/
|
||||
protected string $updateTimeField = 'update_time';
|
||||
|
||||
/**
|
||||
* 软删除时间字段
|
||||
* @var string
|
||||
*/
|
||||
protected string $deleteTimeField = 'delete_time';
|
||||
|
||||
/**
|
||||
* 过滤默认模板
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public array $filterMethod = ['index', 'add', 'edit', 'del', 'status'];
|
||||
|
||||
/**
|
||||
* 限定特定组件
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public array $mustbeComponent = ['set', 'text', 'json'];
|
||||
|
||||
/**
|
||||
* 修改器字段
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public array $modifyFieldAttr = ['set', 'text', 'json'];
|
||||
|
||||
/**
|
||||
* 保留字段
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public string $keepField = 'status';
|
||||
|
||||
/**
|
||||
* 查询字段[SELECT]
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public array $dropdown = ['radio', 'checkbox', 'select'];
|
||||
|
||||
/**
|
||||
* COLS换行符
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public string $commaEol = ',' . PHP_EOL;
|
||||
|
||||
/**
|
||||
* 受保护的表
|
||||
* 禁止CURD操作
|
||||
* @var array
|
||||
*/
|
||||
protected array $protectTable = [
|
||||
"admin", "admin_access", "admin_group", "admin_rules", "company", "department",
|
||||
"dictionary", "generate", "jobs", "user", "user_group", "user_third", "user_validate"
|
||||
];
|
||||
|
||||
/**
|
||||
* 类保留关键字
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected array $internalKeywords = [
|
||||
'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch',
|
||||
'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else',
|
||||
'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile',
|
||||
'eval', 'exit', 'extends', 'final', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements',
|
||||
'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new',
|
||||
'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch',
|
||||
'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor', 'yield', 'readonly', 'match', 'fn'
|
||||
];
|
||||
|
||||
// 初始化操作
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->model = new Generate();
|
||||
$this->prefix = function_exists('get_env') ? get_env('DATABASE_PREFIX') : getenv('DATABASE_PREFIX');
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成CURD代码
|
||||
* @return \support\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function build(): \support\Response
|
||||
{
|
||||
$id = input('id');
|
||||
$data = $this->model->find($id);
|
||||
|
||||
if ($data['status'] && !$data['force']) {
|
||||
return $this->error('该表已经生成过了');
|
||||
}
|
||||
|
||||
$table = str_replace($this->prefix, '', $data['table']);
|
||||
if ($this->filterSystemTable($table)) {
|
||||
return $this->error('禁止操作系统表');
|
||||
}
|
||||
|
||||
// 命名空间
|
||||
$replaces = [];
|
||||
$controller = $data['controller'];
|
||||
$module = $data['global'] ? 'common' : 'admin';
|
||||
$element = ['controller', 'model', 'validate'];
|
||||
|
||||
try {
|
||||
|
||||
foreach ($element as $key => $item) {
|
||||
$result = $this->parseNameData($item == 'controller' ? 'admin' : $module, $controller, $key ? $table : '', $item);
|
||||
list($replaces[$item . 'Name'], $replaces[$item . 'Namespace'], $replaces[$item . 'File']) = $result;
|
||||
}
|
||||
|
||||
$this->getTemplatePath($controller);
|
||||
list($this->menus, $this->methods, $this->templateFiles) = $this->getMenuMethods($data->toArray());
|
||||
|
||||
// 获取字段
|
||||
$adviceField = [];
|
||||
$adviceSearch = [];
|
||||
$everySearch = [];
|
||||
|
||||
// 字段属性值
|
||||
$colsFields = [];
|
||||
$fieldAttrArr = [];
|
||||
|
||||
// 表单设计
|
||||
$formDesign = [];
|
||||
$formItem = [];
|
||||
$formType = $data['formType'];
|
||||
if (!empty($data['formDesign'])) {
|
||||
$formDesign = json_decode($data['formDesign'], true);
|
||||
}
|
||||
|
||||
$this->tableFields = Db::name($table)->getFields();
|
||||
$listFields = explode(',', $data['listField']);
|
||||
foreach ($this->tableFields as $key => $value) {
|
||||
$field = $value['name'];
|
||||
$comment = str_replace(':', ';', $value['comment']);
|
||||
if (empty($comment)) {
|
||||
return $this->error($field . " 字段注释不能为空");
|
||||
}
|
||||
|
||||
$this->tableFields[$key]['title'] = explode(';', $comment)[0];
|
||||
|
||||
// 是否存在状态字段
|
||||
if ($field == $this->keepField) {
|
||||
$adviceSearch[] = $field;
|
||||
}
|
||||
|
||||
// 获取字段类型
|
||||
$everySearch[] = $field;
|
||||
$type = explode('(', $value['type'])[0];
|
||||
|
||||
// 限定组件类型
|
||||
if (in_array($type, $this->mustbeComponent)) {
|
||||
$this->validComponent($field, $type, $formDesign);
|
||||
}
|
||||
|
||||
if (in_array($type, $this->modifyFieldAttr)) {
|
||||
$fieldAttrArr[] = $this->getFieldAttrArr($field, $type);
|
||||
}
|
||||
|
||||
if (empty($adviceField)
|
||||
|| ($adviceField['type'] != 'varchar' && $type == 'varchar')) {
|
||||
$adviceField = [
|
||||
'field' => $field,
|
||||
'type' => $type,
|
||||
];
|
||||
}
|
||||
|
||||
if (in_array($field, $listFields)) {
|
||||
$colsFields[] = [
|
||||
'field' => $field,
|
||||
'title' => '{:__("' . $this->tableFields[$key]['title'] . '")}',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// 推荐搜索片段
|
||||
$adviceSearch[] = $adviceField['field'];
|
||||
$adviceSearchHtml = $this->getAdviceSearch($adviceSearch, $formDesign);
|
||||
|
||||
// 获取全部搜索字段
|
||||
$everySearch = array_diff($everySearch, $adviceSearch);
|
||||
$everySearchHtml = $this->getAdviceSearch($everySearch, $formDesign);
|
||||
$controller = substr($controller, 0, (strrpos($controller, '/') + 1));
|
||||
$colsListArr = $this->getColsListFields($colsFields, $formDesign);
|
||||
|
||||
$replaces['table'] = $table;
|
||||
$replaces['title'] = $data['title'];
|
||||
$replaces['pluginClass'] = $data['plugin'];
|
||||
$replaces['controller'] = $controller;
|
||||
$replaces['controllerDiy'] = $this->getMethodString($this->methods);
|
||||
$replaces['colsListArr'] = $colsListArr;
|
||||
$replaces['fieldAttrArr'] = implode(PHP_EOL . PHP_EOL, $fieldAttrArr);
|
||||
$replaces['adviceSearchHtml'] = $adviceSearchHtml;
|
||||
$replaces['everySearchHtml'] = $everySearchHtml;
|
||||
$replaces['relationMethodList'] = $this->getRelationMethodList($data['relation']);
|
||||
$replaces['FormArea'] = $data['width'] . ',' . $data['height'];
|
||||
$replaces['softDelete'] = array_key_exists($this->deleteTimeField, $this->tableFields) ? "use SoftDelete;" : '';
|
||||
$replaces['softDeleteClassPath'] = array_key_exists($this->deleteTimeField, $this->tableFields) ? "use think\model\concern\SoftDelete;" : '';
|
||||
$replaces['createTime'] = array_key_exists($this->createTimeField, $this->tableFields) ? "'$this->createTimeField'" : 'false';
|
||||
$replaces['updateTime'] = array_key_exists($this->updateTimeField, $this->tableFields) ? "'$this->updateTimeField'" : 'false';
|
||||
$replaces['deleteTime'] = array_key_exists($this->deleteTimeField, $this->tableFields) ? "'$this->deleteTimeField'" : 'false';
|
||||
|
||||
// 生成控制器/模型/验证器规则
|
||||
foreach ($element as $index => $item) {
|
||||
if ($index == 0
|
||||
&& (!$data['create'] || !$data['listField'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$code = read_file($this->getStubTpl($item));
|
||||
foreach ($replaces as $key => $value) {
|
||||
$code = str_replace("{%$key%}", $value, $code);
|
||||
}
|
||||
|
||||
write_file($replaces[$item . 'File'], $code);
|
||||
}
|
||||
|
||||
// 生成表单元素
|
||||
$template = $formType ? 'add' : 'inside';
|
||||
$formHtml = read_file($this->getStubTpl($template));
|
||||
if (!empty($formDesign) && $data['listField']) {
|
||||
|
||||
foreach ($formDesign as $key => $value) {
|
||||
$formItem[$key] = Form::itemElem($value, $formType);
|
||||
}
|
||||
|
||||
$formItem = implode(PHP_EOL, $formItem);
|
||||
$formHtml = str_replace(['{formItems}', '{pluginClass}'], [$formItem, $replaces['pluginClass']], $formHtml);
|
||||
$formType && write_file($this->templatePath . 'add.html', $formHtml);
|
||||
}
|
||||
|
||||
// 生成首页模板
|
||||
$indexHtml = read_file($this->getStubTpl($formType ? 'index' : 'index_inside'));
|
||||
if (!empty($data['listField'])) {
|
||||
$replaces['editforms'] = $formType ? '' : $formHtml;
|
||||
foreach ($replaces as $key => $value) {
|
||||
$indexHtml = str_replace("{%$key%}", $value, $indexHtml);
|
||||
}
|
||||
if (empty($formDesign)) {
|
||||
$indexHtml = preg_replace('/<!--formBegin-->(.*)<!--formEnd-->/isU', '', $indexHtml);
|
||||
}
|
||||
write_file($this->templatePath . 'index.html', str_replace('{pluginClass}', $replaces['pluginClass'], $indexHtml));
|
||||
}
|
||||
|
||||
// 生成扩展模板
|
||||
$extendHtml = read_file($this->getStubTpl('extend'));
|
||||
$extendHtml = str_replace('{pluginClass}', $replaces['pluginClass'], $extendHtml);
|
||||
foreach ($this->methods as $method) {
|
||||
write_file($this->templatePath . Str::snake($method) . '.html', $extendHtml);
|
||||
}
|
||||
|
||||
// 生成CURD菜单
|
||||
if ($data['create'] && !empty($data['listField'])) {
|
||||
AdminRules::createMenu([$this->menus], $replaces['pluginClass'] ?: $table, $data['pid']);
|
||||
}
|
||||
|
||||
// 更新生成状态
|
||||
$data->save(['status' => 1]);
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
|
||||
return $this->success('生成成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理内容
|
||||
* @return mixed|void
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$id = input('id');
|
||||
if (request()->isAjax()) {
|
||||
|
||||
$data = $this->model->find($id);
|
||||
$table = str_replace($this->prefix, '', $data['table']);
|
||||
$controller = $data['controller'];
|
||||
try {
|
||||
|
||||
$module = $data['global'] ? 'common' : 'admin';
|
||||
$element = ['controller', 'model', 'validate'];
|
||||
foreach ($element as $key => $item) {
|
||||
$result = $this->parseNameData($item == 'controller' ? 'admin' : $module, $controller, $key ? $table : '', $item);
|
||||
$file = end($result);
|
||||
if (file_exists($file)) {
|
||||
unlink($file);
|
||||
}
|
||||
// 删除空文件夹
|
||||
remove_empty_dir(dirname($file));
|
||||
}
|
||||
|
||||
list($this->menus, $this->methods, $this->templateFiles) = $this->getMenuMethods($data->toArray());
|
||||
recursive_delete($this->getTemplatePath($controller));
|
||||
AdminRules::disabled($table, true);
|
||||
$data->save(['status' => 0]);
|
||||
} catch (\Throwable $th) {
|
||||
return $this->error($th->getMessage());
|
||||
}
|
||||
|
||||
return $this->success('删除成功');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列表字段
|
||||
* @param array $colsFields
|
||||
* @param array $formDesign
|
||||
* @return string
|
||||
*/
|
||||
public function getColsListFields(array $colsFields = [], array $formDesign = []): string
|
||||
{
|
||||
$colsListArr = [];
|
||||
foreach ($colsFields as $key => $value) {
|
||||
|
||||
// 过滤删除字段
|
||||
$colsLine = [];
|
||||
$colsField = $value['field'];
|
||||
$colsTitle = $value['title'];
|
||||
if ($colsField == $this->deleteTimeField) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取每一列参数合集
|
||||
$colsLine[] = "field:'$colsField'";
|
||||
if ($colsField == $this->keepField) {
|
||||
$colsLine[] = "templet: '#columnStatus'";
|
||||
}
|
||||
|
||||
$item = $this->recursiveComponent($colsField, $formDesign);
|
||||
if (!empty($item) && is_array($item)) {
|
||||
$colsArr = '';
|
||||
$colsTag = $item['tag'];
|
||||
if (in_array($colsTag, $this->dropdown)) {
|
||||
$colsArr = $item['options'];
|
||||
foreach ($colsArr as $index => $elem) {
|
||||
$colsArr[$index]['title'] = "{:__('" . $elem['title'] . "')}";
|
||||
}
|
||||
$colsArr = json_encode($colsArr, JSON_UNESCAPED_UNICODE);
|
||||
$colsTpl = read_file($this->getStubTpl('list/' . $colsTag));
|
||||
} else if ($colsTag == 'upload') {
|
||||
$colsTpl = read_file($this->getStubTpl('list/' . $item['uploadtype']));
|
||||
} else {
|
||||
$colsTpl = read_file($this->getStubTpl('list/' . $colsTag));
|
||||
}
|
||||
if (!empty($colsTpl)) {
|
||||
$colsLine[] = str_replace(['{colsArr}', '{field}'], [$colsArr, $colsField], $colsTpl);
|
||||
}
|
||||
}
|
||||
|
||||
$colsLine[] = "title:'$colsTitle'";
|
||||
$colsListArr[$key] = '{' . implode(',', $colsLine) . '}';
|
||||
}
|
||||
|
||||
$colsListArr = implode($this->commaEol, $colsListArr);
|
||||
return $colsListArr ? $colsListArr . ',' : $colsListArr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取修改器
|
||||
* @param string|null $field
|
||||
* @param string|null $type
|
||||
* @param string $subTpl
|
||||
* @return array|false|string|string[]
|
||||
*/
|
||||
public function getFieldAttrArr(string $field = null, string $type = null, string $subTpl = 'change')
|
||||
{
|
||||
$tplPath = $subTpl . '/' . $type;
|
||||
$methods = read_file($this->getStubTpl($tplPath));
|
||||
|
||||
if (!empty($methods)) {
|
||||
$methods = str_replace('{%field%}', ucfirst($field), $methods);
|
||||
}
|
||||
|
||||
return $methods;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证组件
|
||||
* @param string|null $field
|
||||
* @param string|null $type
|
||||
* @param array $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function validComponent(string $field, string $type, array $data = [])
|
||||
{
|
||||
if (!$field || !$data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = $this->recursiveComponent($field, $data);
|
||||
|
||||
if (!empty($result)) {
|
||||
|
||||
$tag = strtolower($result['tag']);
|
||||
switch ($type) {
|
||||
case 'set':
|
||||
if ($tag != 'checkbox') {
|
||||
return $this->error($field . ' 组件类型限定为checkbox');
|
||||
}
|
||||
break;
|
||||
case 'json':
|
||||
if ($tag != 'json') {
|
||||
return $this->error($field . ' 组件类型限定为json');
|
||||
}
|
||||
break;
|
||||
case 'text': // 限定TEXT字段类型必须为多文件上传
|
||||
if ($tag != 'upload' || $result['uploadtype'] != 'multiple') {
|
||||
return $this->error($field . ' 字段类型为text时,组件类型限定为多文件上传');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找组件
|
||||
* @param string $field
|
||||
* @param array $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function recursiveComponent(string $field = '', array $data = [])
|
||||
{
|
||||
foreach ($data as $value) {
|
||||
|
||||
if ($field == $value['name']) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (isset($value['children']) && $value['children']) {
|
||||
$subElem = $value['children'];
|
||||
foreach ($subElem as $child) {
|
||||
$item = $this->recursiveComponent($field, $child['children']);
|
||||
if (!empty($item)) {
|
||||
return $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索模板
|
||||
* @param array $searchArr
|
||||
* @param array $formArr
|
||||
* @return false|string
|
||||
*/
|
||||
public function getAdviceSearch(array $searchArr = [], array $formArr = [])
|
||||
{
|
||||
if (!$searchArr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$varData = '';
|
||||
$searchHtml = [];
|
||||
foreach ($searchArr as $searchField) {
|
||||
|
||||
if ($searchField == $this->deleteTimeField) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($searchField == $this->keepField) {
|
||||
$rhtml = read_file($this->getStubTpl('search/status'));
|
||||
} else if (in_array($searchField, [$this->createTimeField, $this->updateTimeField])) {
|
||||
$rhtml = read_file($this->getStubTpl('search/datetime'));
|
||||
} else {
|
||||
|
||||
$result = $this->recursiveComponent($searchField, $formArr);
|
||||
if ($result && in_array($result['tag'], $this->dropdown)) {
|
||||
$varData = Form::validOptions($result['options']);
|
||||
$rhtml = read_file($this->getStubTpl('search/select'));
|
||||
} else if ($result && in_array($result['tag'], ['slider'])) {
|
||||
$rhtml = read_file($this->getStubTpl('search/slider'));
|
||||
$rhtml = str_replace(
|
||||
['{default}', '{theme}', '{step}', '{max}', '{min}'],
|
||||
[$result['data_default'], $result['data_theme'], $result['data_step'], $result['data_max'], $result['data_min']],
|
||||
$rhtml
|
||||
);
|
||||
} else if ($result && $result['tag'] == 'cascader') {
|
||||
$rhtml = read_file($this->getStubTpl('search/cascader'));
|
||||
} else if ($result && $result['tag'] == 'date') {
|
||||
$rhtml = read_file($this->getStubTpl('search/datetime'));
|
||||
} else if ($result && $result['tag'] == 'rate') {
|
||||
$rhtml = read_file($this->getStubTpl('search/rate'));
|
||||
$rhtml = str_replace(['{theme}', '{length}'], [$result['data_theme'], $result['data_length']], $rhtml);
|
||||
} else {
|
||||
$rhtml = read_file($this->getStubTpl('search/input'));
|
||||
}
|
||||
}
|
||||
|
||||
$replace = [
|
||||
'field' => $searchField,
|
||||
'title' => $this->tableFields[$searchField]['title'],
|
||||
'varlist' => ucfirst($searchField) . '_list',
|
||||
'vardata' => $varData,
|
||||
];
|
||||
|
||||
foreach ($replace as $key => $value) {
|
||||
$rhtml = str_replace("{%$key%}", $value, $rhtml);
|
||||
}
|
||||
|
||||
$searchHtml[] = $rhtml;
|
||||
}
|
||||
|
||||
return implode(PHP_EOL . PHP_EOL, $searchHtml);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单函数
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function getMenuMethods(array $data = []): array
|
||||
{
|
||||
if (empty($data) || !is_array($data)) {
|
||||
throw new \Exception("Error Params Request", 1);
|
||||
}
|
||||
|
||||
if (!is_array($data['menus'])) {
|
||||
$data['menus'] = unserialize($data['menus']);
|
||||
}
|
||||
|
||||
$MenuRules = [
|
||||
'title' => $data['title'],
|
||||
'router' => $data['controller'],
|
||||
'icon' => $data['icon'] ?: '',
|
||||
'pid' => $data['pid'],
|
||||
'auth' => $data['auth'],
|
||||
];
|
||||
|
||||
foreach ($data['menus'] as $key => $value) {
|
||||
$MenuRules['children'][$key] = [
|
||||
'title' => $value['title'],
|
||||
'router' => $value['router'],
|
||||
'auth' => $value['auth'],
|
||||
'type' => $value['type'],
|
||||
];
|
||||
$parse = explode(':', $value['route']);
|
||||
$parse = end($parse);
|
||||
if (!in_array($parse, $this->filterMethod)) {
|
||||
$this->methods[$key] = $parse;
|
||||
$this->templateFiles[$key] = Str::snake($parse);
|
||||
}
|
||||
}
|
||||
|
||||
return [$MenuRules, $this->methods, $this->templateFiles];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取其他函数
|
||||
* @param array $methods
|
||||
* @return string
|
||||
*/
|
||||
protected function getMethodString(array $methods = []): string
|
||||
{
|
||||
$outsMethod = PHP_EOL;
|
||||
foreach ($methods as $method) {
|
||||
if (!in_array($method, $this->filterMethod)) {
|
||||
$outsMethod .= str_replace('method', $method, read_file($this->getStubTpl('method')));
|
||||
}
|
||||
}
|
||||
return $outsMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取关联表信息
|
||||
* id style KEY
|
||||
* @param $relation
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function getRelationMethodList($relation): string
|
||||
{
|
||||
$relationString = PHP_EOL;
|
||||
if (!empty($relation) && !is_array($relation)) {
|
||||
|
||||
$relation = unserialize($relation);
|
||||
foreach ($relation as $value) {
|
||||
|
||||
if (!$value) {
|
||||
continue;
|
||||
}
|
||||
$table = str_replace($this->prefix, '', $value['table']);
|
||||
$schema = Db::query("SHOW TABLE STATUS LIKE '$table'");
|
||||
$studly = Str::studly($table);
|
||||
|
||||
// 直接判断是否存在
|
||||
// 可提交遍历命名空间PR
|
||||
if (in_array($table,$this->protectTable)) {
|
||||
$studly = '\\app\\common\\model\\system\\' . $studly;
|
||||
} else {
|
||||
$namespace = '\\app\\admin\\model\\'.$studly;
|
||||
if (class_exists($namespace)) {
|
||||
$studly = $namespace;
|
||||
}
|
||||
}
|
||||
|
||||
// 拼接关联语句
|
||||
$localKey = $value['localKey'];
|
||||
$foreignKey = $value['foreignKey'];
|
||||
$str_relation = '$this->' . $value['style'] . '(' . $studly . '::Class,' . "'$foreignKey','$localKey')";
|
||||
|
||||
$bindField = [];
|
||||
if ($value['relationField']) {
|
||||
$bindField = explode(',', $value['relationField']);
|
||||
$bindField = array_unique(array_filter($bindField));
|
||||
$str_relation .= '->bind(' . str_replace('"', '\'', json_encode($bindField)) . ')';
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$Comment = $schema[0]['Comment'] ?? $value['table'];
|
||||
$table = Str::camel($table);
|
||||
$relationString .= ' /**';
|
||||
$relationString .= PHP_EOL . ' * 定义 ' . $Comment . ' 关联模型';
|
||||
$relationString .= PHP_EOL . ' * @localKey ' . $localKey;
|
||||
$relationString .= PHP_EOL . ' * @bind ' . implode(',', $bindField);
|
||||
$relationString .= PHP_EOL . ' */';
|
||||
$relationString .= PHP_EOL . ' public function ' . $table . '()';
|
||||
$relationString .= PHP_EOL . ' {';
|
||||
$relationString .= PHP_EOL . ' return ' . $str_relation . ';';
|
||||
$relationString .= PHP_EOL . ' }';
|
||||
$relationString .= PHP_EOL;
|
||||
} catch (\Throwable $th) {
|
||||
throw new \Exception($th->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $relationString;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件信息
|
||||
* @param string $module
|
||||
* @param string $name
|
||||
* @param string $table
|
||||
* @param string $type
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function parseNameData(string $module, string $name, string $table = '', string $type = 'controller'): array
|
||||
{
|
||||
$array = str_replace(['.', '/', '\\'], '/', $name);
|
||||
$array = array_filter(explode('/', $array));
|
||||
if (substr($name, 0 - strlen('/')) != '/') {
|
||||
array_pop($array);
|
||||
}
|
||||
|
||||
$parseName = $type == 'controller' ? ucfirst(end($array)) : Str::studly($table);
|
||||
if (in_array(strtolower($parseName), $this->internalKeywords)) {
|
||||
throw new \Exception('类名称不能使用内置关键字' . $parseName);
|
||||
}
|
||||
|
||||
array_pop($array);
|
||||
$appNamespace = "app\\{$module}\\$type" . ($array ? "\\" . implode("\\", $array) : "");
|
||||
$parseFile = root_path() . $appNamespace . DIRECTORY_SEPARATOR . $parseName . '.php';
|
||||
$parseFile = str_replace('\\', '/', $parseFile);
|
||||
return [$parseName, $appNamespace, $parseFile];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $table
|
||||
* @return bool
|
||||
*/
|
||||
protected function filterSystemTable($table): bool
|
||||
{
|
||||
if (in_array($table, $this->protectTable)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模板文件
|
||||
* @param [type] $name
|
||||
* @return string
|
||||
*/
|
||||
protected function getStubTpl($name): string
|
||||
{
|
||||
return __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . $name . '.stub';
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取代码模板
|
||||
* @param [type] $name
|
||||
* @return string
|
||||
*/
|
||||
protected function getTemplatePath($name): string
|
||||
{
|
||||
$this->templatePath = root_path('app/admin/view');
|
||||
$array = str_replace(['.', '/', '\\'], '/', $name);
|
||||
$array = array_filter(explode('/', $array));
|
||||
if (substr($name, 0 - strlen('/')) != '/') {
|
||||
array_pop($array);
|
||||
}
|
||||
|
||||
foreach ($array as $value) {
|
||||
$value = Str::snake($value);
|
||||
$this->templatePath .= $value . DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
return $this->templatePath;
|
||||
}
|
||||
}
|
||||
88
plugin/developer/app/admin/controller/developer/Example.php
Normal file
88
plugin/developer/app/admin/controller/developer/Example.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
// +----------------------------------------------------------------------
|
||||
// | swiftAdmin 极速开发框架 [基于WebMan开发]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
|
||||
// +----------------------------------------------------------------------
|
||||
// | swiftAdmin.net High Speed Development Framework
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\admin\controller\developer;
|
||||
|
||||
use app\AdminController;
|
||||
use Webman\Http\Request;
|
||||
|
||||
/**
|
||||
* 开发示例
|
||||
* <!--Developer-->
|
||||
* Class Example
|
||||
* @package app\admin\controller\developer
|
||||
*/
|
||||
class Example extends AdminController
|
||||
{
|
||||
/**
|
||||
* 首页
|
||||
* @return \support\Response
|
||||
*/
|
||||
public function index():\support\Response
|
||||
{
|
||||
return parent::index(); // TODO: Change the autogenerated stub
|
||||
}
|
||||
|
||||
/**
|
||||
* echarts图标
|
||||
* @return \support\Response
|
||||
*/
|
||||
public function echarts() : \support\Response
|
||||
{
|
||||
return view('/developer/example/echarts');
|
||||
}
|
||||
|
||||
/**
|
||||
* echarts图标
|
||||
* @return \support\Response
|
||||
*/
|
||||
public function table(): \support\Response
|
||||
{
|
||||
return view('/developer/example/table');
|
||||
}
|
||||
|
||||
/**
|
||||
* echarts图标
|
||||
* @return \support\Response
|
||||
*/
|
||||
public function card(): \support\Response
|
||||
{
|
||||
return view('/developer/example/card');
|
||||
}
|
||||
|
||||
/**
|
||||
* echarts图标
|
||||
* @return \support\Response
|
||||
*/
|
||||
public function component(): \support\Response
|
||||
{
|
||||
return view('/developer/example/component');
|
||||
}
|
||||
|
||||
/**
|
||||
* echarts图标
|
||||
* @return \support\Response
|
||||
*/
|
||||
public function editor(): \support\Response
|
||||
{
|
||||
return view('/developer/example/editor');
|
||||
}
|
||||
|
||||
/**
|
||||
* 常规辅助元素
|
||||
* @return \support\Response
|
||||
*/
|
||||
public function auxiliar(): \support\Response
|
||||
{
|
||||
return view('/developer/example/auxiliar');
|
||||
}
|
||||
|
||||
}
|
||||
274
plugin/developer/app/admin/controller/developer/Generate.php
Normal file
274
plugin/developer/app/admin/controller/developer/Generate.php
Normal file
@@ -0,0 +1,274 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\admin\controller\developer;
|
||||
|
||||
use app\AdminController;
|
||||
use support\Response;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
use think\facade\Db;
|
||||
|
||||
/**
|
||||
* 代码生成器
|
||||
* <!--Developer-->
|
||||
* Class Generate
|
||||
* @package app\admin\controller\developer
|
||||
*/
|
||||
class Generate extends AdminController
|
||||
{
|
||||
/**
|
||||
* 数据表前缀
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public mixed $prefix = 'sa_';
|
||||
|
||||
/**
|
||||
* 插件列表
|
||||
* @var mixed
|
||||
*/
|
||||
public mixed $pluginList = [];
|
||||
|
||||
/**
|
||||
* 过滤字段
|
||||
* @var array
|
||||
*/
|
||||
public array $filterField = ['id', 'update_time', 'create_time', 'delete_time'];
|
||||
|
||||
// 初始化操作
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->model = new \app\admin\model\developer\Generate();
|
||||
$this->prefix = function_exists('get_env') ? get_env('DATABASE_PREFIX') : getenv('DATABASE_PREFIX');
|
||||
$this->pluginList = \app\admin\model\developer\Plugin::select();
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示列表
|
||||
*
|
||||
* @return Response
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function index(): Response
|
||||
{
|
||||
if (request()->isAjax()) {
|
||||
|
||||
$param = \request()->all();
|
||||
$param['page'] = (int)input('page');
|
||||
$param['limit'] = (int)input('limit');
|
||||
// 查询条件
|
||||
$where = array();
|
||||
if (!empty($param['title'])) {
|
||||
$where[] = ['title', 'like', '%' . $param['title'] . '%'];
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
$count = $this->model->where($where)->count();
|
||||
$limit = is_empty($param['limit']) ? 10 : $param['limit'];
|
||||
$page = ($count <= $limit) ? 1 : $param['page'];
|
||||
$list = $this->model->where($where)->order("id desc")->limit($limit)->page($page)->select()->toArray();
|
||||
return $this->success('查询成功', null, $list, $count);
|
||||
}
|
||||
|
||||
return view('/developer/generate/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加生成数据
|
||||
*
|
||||
* @return \support\Response
|
||||
*/
|
||||
public function add(): \support\Response
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
|
||||
$post = $this->insert_before(\request()->post());
|
||||
|
||||
if ($this->model->create($post)) {
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
return $this->error();
|
||||
}
|
||||
|
||||
return view('/developer/generate/add', [
|
||||
'data' => $this->getTableFields(),
|
||||
'tables' => Db::getTables(),
|
||||
'pluginList' => $this->pluginList,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑生成数据
|
||||
* @return \support\Response
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function edit(): \support\Response
|
||||
{
|
||||
|
||||
if (request()->isPost()) {
|
||||
|
||||
$post = $this->insert_before(\request()->post());
|
||||
$post = request_validate_rules($post, get_class($this->model));
|
||||
if (empty($post) || !is_array($post)) {
|
||||
return $this->error($post);
|
||||
}
|
||||
$variable = ['force', 'create', 'auth', 'global', 'delete'];
|
||||
foreach ($variable as $value) {
|
||||
if (!isset($post[$value])) {
|
||||
$post[$value] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->model->update($post)) {
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
return $this->error();
|
||||
}
|
||||
|
||||
$id = input('id');
|
||||
$data = $this->model->find($id);
|
||||
if (!$data) {
|
||||
return $this->error('not found');
|
||||
}
|
||||
|
||||
// 查询当前表
|
||||
$table = str_replace($this->prefix, '', $data['table']);
|
||||
$data['localFields'] = $this->queryFields($table);
|
||||
$data['listField'] = $data['listField'] ? json_encode(explode(',', $data['listField'])) : json_encode([]);
|
||||
|
||||
if ($data['relation']) {
|
||||
$data['relation'] = unserialize($data['relation']);
|
||||
}
|
||||
if ($data['menus']) {
|
||||
$data['menus'] = unserialize($data['menus']);
|
||||
}
|
||||
|
||||
// 渲染模板
|
||||
return view('/developer/generate/edit', [
|
||||
'data' => $data,
|
||||
'tables' => Db::getTables(),
|
||||
'pluginList' => $this->pluginList,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据预处理
|
||||
*
|
||||
* @param array $post
|
||||
* @return array
|
||||
*/
|
||||
public function insert_before(array $post = []): array
|
||||
{
|
||||
// 是否存在关联表
|
||||
if (isset($post['relation_table'])) {
|
||||
|
||||
foreach ($post['relation_table'] as $key => $value) {
|
||||
if (empty($value)) {
|
||||
continue;
|
||||
}
|
||||
$post['relation'][$key]['table'] = $value;
|
||||
$post['relation'][$key]['style'] = $post['relation_style'][$key];
|
||||
$post['relation'][$key]['foreignKey'] = $post['foreignKey'][$key];
|
||||
$post['relation'][$key]['localKey'] = $post['localKey'][$key];
|
||||
$post['relation'][$key]['relationField'] = $post['relationField'][$key];
|
||||
}
|
||||
|
||||
if (!empty($post['relation'])) {
|
||||
$post['relation'] = serialize($post['relation']);
|
||||
}
|
||||
} else {
|
||||
$post['relation'] = '';
|
||||
}
|
||||
|
||||
// 处理菜单项
|
||||
$menuParams = [];
|
||||
foreach ($post['menus']['title'] as $key => $value) {
|
||||
$menuParams[$key]['title'] = $value;
|
||||
$menuParams[$key]['route'] = $post['menus']['route'][$key];
|
||||
$menuParams[$key]['router'] = $post['menus']['router'][$key];
|
||||
$menuParams[$key]['template'] = $post['menus']['template'][$key];
|
||||
$menuParams[$key]['auth'] = $post['menus']['auth'][$key];
|
||||
$menuParams[$key]['type'] = $post['menus']['type'][$key];
|
||||
}
|
||||
|
||||
$post['menus'] = $menuParams ? serialize($menuParams) : '';
|
||||
return $post ?: [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单设计器
|
||||
* @return Response
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function formDesign(): \support\Response
|
||||
{
|
||||
$id = input('id');
|
||||
|
||||
if (request()->isPost()) {
|
||||
$post['id'] = $id;
|
||||
$post['formName'] = input('formName');
|
||||
$post['width'] = input('width');
|
||||
$post['height'] = input('height');
|
||||
$post['formType'] = input('formType');
|
||||
$post['formDesign'] = input('formDesign');
|
||||
if ($this->model->update($post)) {
|
||||
return $this->success();
|
||||
}
|
||||
return $this->error();
|
||||
}
|
||||
|
||||
$data = $this->model->find($id);
|
||||
if (!$data) {
|
||||
return $this->error('not found');
|
||||
}
|
||||
|
||||
$tableInfo = [];
|
||||
$table = str_replace($this->prefix, '', $data['table']);
|
||||
$tableFields = Db::name($table)->getFields();
|
||||
foreach ($tableFields as $key => $value) {
|
||||
if (!in_array($key, $this->filterField)) {
|
||||
$info = explode(';', $value['comment']);
|
||||
if ($info) {
|
||||
$tableInfo[$key] = current($info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return view('/developer/generate/form_design', [
|
||||
'data' => $data,
|
||||
'table' => json_encode($tableInfo, JSON_UNESCAPED_UNICODE),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询表字段
|
||||
* @param string $name
|
||||
* @return false|string
|
||||
*/
|
||||
public function queryFields(string $name = '')
|
||||
{
|
||||
$list = [];
|
||||
$table = input('table');
|
||||
if (empty($table)) {
|
||||
$table = $name;
|
||||
}
|
||||
|
||||
$field = Db::name($table)->getTableFields();
|
||||
var_dump($field);
|
||||
foreach ($field as $key => $value) {
|
||||
$list[$key]['value'] = $value;
|
||||
$list[$key]['name'] = $value;
|
||||
}
|
||||
|
||||
return json_encode($list ?: []);
|
||||
}
|
||||
}
|
||||
431
plugin/developer/app/admin/controller/developer/Plugin.php
Normal file
431
plugin/developer/app/admin/controller/developer/Plugin.php
Normal file
@@ -0,0 +1,431 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\admin\controller\developer;
|
||||
|
||||
use app\AdminController;
|
||||
use app\common\model\system\AdminRules;
|
||||
use Exception;
|
||||
use FilesystemIterator;
|
||||
use Psr\SimpleCache\InvalidArgumentException;
|
||||
use support\Response;
|
||||
use system\File;
|
||||
use system\ZipArchives;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
use app\admin\controller\system\Plugin as PluginService;
|
||||
|
||||
/**
|
||||
* 插件开发
|
||||
* <!--Developer-->
|
||||
* Class Plugin
|
||||
* @package app\admin\controller\developer
|
||||
*/
|
||||
class Plugin extends AdminController
|
||||
{
|
||||
|
||||
// 初始化操作
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->model = new \app\admin\model\developer\Plugin();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取资源
|
||||
* @return Response
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function index(): \support\Response
|
||||
{
|
||||
if (request()->isAjax()) {
|
||||
|
||||
$param = \request()->post();
|
||||
$param['page'] = (int)input('page');
|
||||
$param['limit'] = (int)('limit');
|
||||
$count = $this->model->count();
|
||||
$limit = empty($param['limit']) ? 10 : $param['limit'];
|
||||
$page = ($count <= $limit) ? 1 : $param['page'];
|
||||
$list = $this->model->order("id desc")->limit($limit)->page($page)->select()->toArray();
|
||||
return $this->success('查询成功', null, $list, $count);
|
||||
}
|
||||
|
||||
return view('/developer/plugin/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传插件
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function parseFile(): array
|
||||
{
|
||||
try {
|
||||
|
||||
$file = \request()->file('file');
|
||||
if (empty($file)) {
|
||||
throw new \Exception('插件上传失败');
|
||||
}
|
||||
|
||||
$uploadName = $file->getUploadName();
|
||||
$filePath = plugin_path() . $uploadName;
|
||||
if (!$file->move($filePath)) {
|
||||
throw new \Exception('插件上传失败');
|
||||
}
|
||||
|
||||
$uploadName = pathinfo($uploadName)['filename'];
|
||||
$uploadName = explode('-', $uploadName);
|
||||
$fileName = current($uploadName);
|
||||
|
||||
} catch (\Throwable $th) {
|
||||
throw new \Exception($th->getMessage());
|
||||
}
|
||||
|
||||
return [strtolower($fileName), $filePath];
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行本地安装测试
|
||||
* @return Response
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function install(): Response
|
||||
{
|
||||
try {
|
||||
list($name, $filePath) = $this->parseFile();
|
||||
if (is_dir(plugin_path($name))) {
|
||||
throw new \Exception('插件已存在');
|
||||
}
|
||||
ZipArchives::unzip($filePath, plugin_path(), '', true);
|
||||
$pluginClass = get_plugin_instance($name);
|
||||
$pluginClass->install();
|
||||
PluginService::pluginMenu($name);
|
||||
PluginService::executeSql($name);
|
||||
PluginService::enabled($name);
|
||||
|
||||
} catch (\Throwable $th) {
|
||||
return $this->error($th->getMessage());
|
||||
}
|
||||
|
||||
return $this->success('插件安装成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 升级插件
|
||||
* @return \support\Response
|
||||
* @throws Exception|\Psr\SimpleCache\InvalidArgumentException
|
||||
*/
|
||||
public function upgrade(): \support\Response
|
||||
{
|
||||
try {
|
||||
|
||||
list($name, $filePath) = $this->parseFile();
|
||||
$pluginPath = plugin_path($name);
|
||||
$pluginInfo = get_plugin_config($name, true);
|
||||
if (!$pluginInfo) {
|
||||
throw new \Exception('插件不存在');
|
||||
}
|
||||
|
||||
if ($pluginInfo['status']) {
|
||||
throw new \Exception('插件已启用,请先禁用插件');
|
||||
}
|
||||
|
||||
$formIndex = ZipArchives::unzip($filePath, plugin_path(), 'config.json');
|
||||
$upgradeInfo = json_decode($formIndex, true);
|
||||
if (version_compare($upgradeInfo['version'], $pluginInfo['version'], "<=")) {
|
||||
throw new \Exception('升级版本不能低于已安装版本');
|
||||
}
|
||||
|
||||
$backupDir = root_path() . $name . '_' . $pluginInfo['version'] . '.zip';
|
||||
ZipArchives::compression($backupDir, $pluginPath, plugin_path());
|
||||
ZipArchives::unzip($filePath, plugin_path(), '', true);
|
||||
|
||||
$pluginClass = get_plugin_instance($name, 'upgrade');
|
||||
$pluginClass->execute($pluginInfo['version'], $upgradeInfo['version']);
|
||||
$data = array_merge($upgradeInfo, [
|
||||
'extends' => $pluginInfo['extends'],
|
||||
'rewrite' => $pluginInfo['rewrite'],
|
||||
]);
|
||||
|
||||
write_file($pluginPath . 'config.json', json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
||||
PluginService::pluginMenu($name);
|
||||
PluginService::executeSql($name);
|
||||
PluginService::enabled($name);
|
||||
|
||||
} catch (\Exception $th) {
|
||||
return $this->error($th->getMessage());
|
||||
}
|
||||
|
||||
return $this->success('插件升级成功', null, $pluginInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入本地插件
|
||||
* @return Response
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function import(): \support\Response
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
|
||||
$name = input('dir');
|
||||
$pluginInfo = get_plugin_config($name, true);
|
||||
if (empty($pluginInfo)) {
|
||||
return $this->error('插件信息获取失败');
|
||||
}
|
||||
|
||||
// 是否已经导入
|
||||
$result = $this->model->where('name', $name)->findOrEmpty();
|
||||
if (!$result->isEmpty()) {
|
||||
return $this->error('请勿重复导入插件');
|
||||
}
|
||||
|
||||
try {
|
||||
$pluginInfo['import'] = time();
|
||||
$this->model->create($pluginInfo);
|
||||
} catch (\Throwable $th) {
|
||||
return $this->error($th->getMessage());
|
||||
}
|
||||
|
||||
return $this->success('导入成功');
|
||||
}
|
||||
|
||||
$dirs = [];
|
||||
$iterator = new FilesystemIterator(plugin_path(), FilesystemIterator::SKIP_DOTS);
|
||||
foreach ($iterator as $item) {
|
||||
if ($item->isDir()) {
|
||||
// 是否已经导入
|
||||
$find = $this->model->where('name', $item->getBasename())->find();
|
||||
if (empty($find)) {
|
||||
$name = $item->getBasename();
|
||||
$info = get_plugin_config($name);
|
||||
$dirs[] = [
|
||||
'name' => $name,
|
||||
'title' => $info['title'] ?? '',
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return view('/developer/plugin/import', ['dirs' => $dirs]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件生成
|
||||
* @return \support\Response
|
||||
* @throws \Psr\SimpleCache\InvalidArgumentException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function build(): \support\Response
|
||||
{
|
||||
$id = input('id');
|
||||
$data = $this->model->where('id', $id)->withoutField('id,status,create_time')->find();
|
||||
if (empty($data)) {
|
||||
return $this->error('插件不存在');
|
||||
}
|
||||
|
||||
$name = $data['name'];
|
||||
$pluginPath = plugin_path($name);
|
||||
$pluginClass = ucfirst($name);
|
||||
if ($data['import'] || is_dir($pluginPath)) {
|
||||
return $this->error('请勿重复生成插件');
|
||||
}
|
||||
|
||||
$pluginZip = __DIR__ . '/stubs/plugin_init.stub';
|
||||
$sourceFiles = plugin_path('plugin_init');
|
||||
$replaces = ['controller', 'model', 'validate', 'view'];
|
||||
$source = ['{name}', '{pluginClass}', '{title}', '{icon}'];
|
||||
$destVars = [$name, $pluginClass, $data['title'], $data['icon']];
|
||||
|
||||
try {
|
||||
|
||||
ZipArchives::unzip($pluginZip, plugin_path());
|
||||
foreach ($replaces as $item) {
|
||||
$namespace = $sourceFiles . 'app/admin' . DIRECTORY_SEPARATOR . $item;
|
||||
$tempPath = $namespace . DIRECTORY_SEPARATOR . 'demo';
|
||||
$tempPath = str_replace('\\', '/', $tempPath);
|
||||
if (is_dir($tempPath)) {
|
||||
$isFirst = false;
|
||||
$targetPath = $namespace . DIRECTORY_SEPARATOR . $name;
|
||||
rename($tempPath, $targetPath);
|
||||
$targetFile = $targetPath . DIRECTORY_SEPARATOR . 'Index.php';
|
||||
if (!is_file($targetFile)) {
|
||||
$isFirst = true;
|
||||
$targetFile = $targetPath . DIRECTORY_SEPARATOR . ($item === 'view' ? '/index/index.html' : 'Demo.php');
|
||||
}
|
||||
$content = str_replace($source, $destVars, read_file($targetFile));
|
||||
if (!empty($content)) {
|
||||
write_file($targetFile, $content);
|
||||
}
|
||||
if ($isFirst && $content && $item !== 'view') {
|
||||
rename($targetFile, $targetPath . DIRECTORY_SEPARATOR . $pluginClass . '.php');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$array = [$sourceFiles . 'app/index/controller/', $sourceFiles];
|
||||
foreach ($array as $item) {
|
||||
$file = $item . 'Demo.php';
|
||||
$content = str_replace($source, $destVars, read_file($file));
|
||||
write_file($file, $content);
|
||||
rename($file, $item . $pluginClass . '.php');
|
||||
}
|
||||
|
||||
foreach (['README.md', 'function.php', 'Upgrade.php', 'config.html'] as $item) {
|
||||
$file = $sourceFiles . $item;
|
||||
$content = str_replace($source, $destVars, read_file($file));
|
||||
write_file($file, $content);
|
||||
}
|
||||
|
||||
// 处理静态文件
|
||||
$staticFile = [
|
||||
$sourceFiles . 'app/index/view',
|
||||
$sourceFiles . 'public/static/plugin',
|
||||
$sourceFiles . 'public/static/system/plugin'
|
||||
];
|
||||
|
||||
foreach ($staticFile as $index => $item) {
|
||||
$file = $item . '/demo';
|
||||
if (!$index) {
|
||||
$elem = $file . DIRECTORY_SEPARATOR . 'index.html';
|
||||
write_file($elem, str_replace('{pluginClass}', $pluginClass, read_file($elem)));
|
||||
}
|
||||
rename($item . '/' . 'demo', $item . '/' . $name);
|
||||
}
|
||||
|
||||
$configPath = $sourceFiles . 'config.json';
|
||||
$data = $data->toArray();
|
||||
$data['rewrite'] = [];
|
||||
$data['extends'] = [
|
||||
'title' => $data['title'],
|
||||
];
|
||||
$data['area'] = ['600px', '650px',];
|
||||
write_file($configPath, json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
|
||||
rename($sourceFiles, $pluginPath);
|
||||
|
||||
if ($data['menu']) {
|
||||
AdminRules::createMenu($this->createPluginMenu($data), $name);
|
||||
}
|
||||
|
||||
// 启用插件
|
||||
foreach (File::getCopyDirs($name) as $copyDir) {
|
||||
copydirs($copyDir, root_path() . str_replace($pluginPath, '', $copyDir));
|
||||
}
|
||||
|
||||
AdminRules::enabled($name);
|
||||
set_plugin_config($name, ['status' => 1]);
|
||||
} catch (\Throwable $th) {
|
||||
@recursive_delete($pluginPath);
|
||||
@recursive_delete($sourceFiles);
|
||||
return $this->error($th->getMessage());
|
||||
}
|
||||
|
||||
return $this->success('插件初始化成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件打包
|
||||
* @return \support\Response
|
||||
* @throws Exception
|
||||
*/
|
||||
public function package(): \support\Response
|
||||
{
|
||||
$id = input('id');
|
||||
$data = $this->model->withoutField('id, import, create_time')->where('id', $id)->find();
|
||||
if (empty($data)) {
|
||||
return $this->error('插件不存在,打包失败!');
|
||||
}
|
||||
|
||||
$name = $data['name'];
|
||||
$pluginClass = ucfirst($name);
|
||||
$pluginPath = plugin_path($name);
|
||||
if (!is_dir($pluginPath)) {
|
||||
return $this->error('插件未生成!');
|
||||
}
|
||||
|
||||
try {
|
||||
$files = new \RecursiveIteratorIterator(
|
||||
new \RecursiveDirectoryIterator(root_path('app'), FilesystemIterator::SKIP_DOTS),
|
||||
\RecursiveIteratorIterator::CHILD_FIRST
|
||||
);
|
||||
|
||||
foreach ($files as $fileinfo) {
|
||||
if ($fileinfo->isFile()) {
|
||||
$filePath = $fileinfo->getPathName();
|
||||
$content = read_file($filePath);
|
||||
if (preg_match('/<!--' . $pluginClass . '-->/iU', $content, $match)) {
|
||||
$match = $match[0];
|
||||
$filePath = str_replace('\\', '/', $filePath);
|
||||
copy_file($filePath, str_replace(root_path(), $pluginPath, $filePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$statics = [
|
||||
root_path('public/static/plugin/' . $name),
|
||||
root_path('public/static/system/plugin/' . $name),
|
||||
];
|
||||
|
||||
foreach ($statics as $item) {
|
||||
if (is_dir($item)) {
|
||||
@copydirs($item, str_replace(root_path(), $pluginPath, $item));
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($data['menu'])) {
|
||||
arr2file($pluginPath . '/data/menu.php', AdminRules::export($name));
|
||||
}
|
||||
|
||||
// 加载配置文件
|
||||
$configPath = $pluginPath . 'config.json';
|
||||
$configInfo = json_decode(read_file($configPath), true);
|
||||
$configPack = array_merge($configInfo, $data->toArray());
|
||||
unset($configPack['path']);
|
||||
unset($configPack['filePath']);
|
||||
if (empty($configPack['rewrite'])) {
|
||||
$configPack['rewrite'] = [];
|
||||
}
|
||||
write_file($configPath, json_encode($configPack, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
|
||||
$pluginZip = root_path('public/upload') . $name . '-' . $data['version'] . '.zip';
|
||||
ZipArchives::compression($pluginZip, $pluginPath);
|
||||
$url = request()->domain() . str_replace(root_path() . 'public', '', $pluginZip);
|
||||
|
||||
} catch (\Throwable $th) {
|
||||
return $this->error($th->getMessage());
|
||||
}
|
||||
|
||||
return $this->success('插件打包成功', $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 基础菜单项
|
||||
* @param $plugin
|
||||
* @return array
|
||||
*/
|
||||
public function createPluginMenu($plugin): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'title' => $plugin['title'],
|
||||
'router' => '/' . $plugin['name'] . '/Index',
|
||||
'icon' => $plugin['icon'],
|
||||
'auth' => '1',
|
||||
'children' => [
|
||||
['router' => '/' . $plugin['name'] . '/Index/index', 'title' => '查看'],
|
||||
['router' => '/' . $plugin['name'] . '/Index/add', 'title' => '添加'],
|
||||
['router' => '/' . $plugin['name'] . '/Index/edit', 'title' => '编辑'],
|
||||
['router' => '/' . $plugin['name'] . '/Index/del', 'title' => '删除'],
|
||||
['router' => '/' . $plugin['name'] . '/Index/status', 'title' => '状态']
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<include file="/public/header" />
|
||||
<!-- // 重定位style -->
|
||||
<!--{pluginClass}-->
|
||||
<link href="__STATICADMIN__css/content.css" rel="stylesheet" type="text/css" />
|
||||
<div class="layui-fluid">
|
||||
<form class="layui-form layui-card" >
|
||||
|
||||
<div class="layui-card-body">
|
||||
<gt name="$data.id" value="0">
|
||||
<input type="text" name="id" value="{$data.id}" hidden="">
|
||||
<else/>
|
||||
<input type="text" name="id" value="" hidden="">
|
||||
</gt>
|
||||
{formItems}
|
||||
<div class="layui-footer layui-form-footer">
|
||||
<button class="layui-btn layui-btn-primary" type="button" sa-event="closeDialog">{:__('取消')}</button>
|
||||
<button class="layui-btn" type="button" lay-filter="submitIframe" lay-submit>{:__('提交')}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<include file="/public/static" />
|
||||
<include file="/public/footer" />
|
||||
@@ -0,0 +1,22 @@
|
||||
public function set{%field%}Attr($value)
|
||||
{
|
||||
if (!empty($value) && is_array($value)) {
|
||||
$arr = [];
|
||||
foreach ($value['key'] as $key => $elem) {
|
||||
$arr[$elem] = $value['value'][$key];
|
||||
}
|
||||
|
||||
$value = json_encode($arr,JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
return $value ?: json_encode([]);
|
||||
}
|
||||
|
||||
public function get{%field%}Attr($value)
|
||||
{
|
||||
if (!empty($value) && is_string($value)) {
|
||||
$value = json_decode($value, true);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
public function set{%field%}Attr($value)
|
||||
{
|
||||
if (!empty($value) && is_array($value)) {
|
||||
$value = implode(',',$value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function get{%field%}Attr($value)
|
||||
{
|
||||
if (!empty($value) && is_string($value)) {
|
||||
$value = explode(',',$value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
public function set{%field%}Attr($value)
|
||||
{
|
||||
if (!empty($value)) {
|
||||
$value = serialize($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function get{%field%}Attr($value)
|
||||
{
|
||||
if (!empty($value)) {
|
||||
$value = unserialize($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
namespace {%controllerNamespace%};
|
||||
|
||||
use app\AdminController;
|
||||
use Webman\Http\Request;
|
||||
use {%modelNamespace%}\{%modelName%} as {%modelName%}Model;
|
||||
|
||||
/**
|
||||
* {%table%}
|
||||
* {%title%}
|
||||
* <!--{%pluginClass%}-->
|
||||
* Class {%controllerName%}
|
||||
* @package {%controllerNamespace%}
|
||||
*/
|
||||
class {%controllerName%} extends AdminController
|
||||
{
|
||||
/**
|
||||
* {%modelName%}模型对象
|
||||
* @var \{%modelNamespace%}\{%modelName%}
|
||||
*/
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->model = new {%modelName%}Model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认生成的方法为index/add/edit/del/status 五个方法
|
||||
* 当创建CURD的时候,DIY的函数体和模板为空,请自行编写代码
|
||||
*/
|
||||
{%controllerDiy%}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<!-- 当前模板为合并模板 如有需求请自行开发 -->
|
||||
@@ -0,0 +1,9 @@
|
||||
<include file="/public/header" />
|
||||
<!-- // 重定位style -->
|
||||
<!--{pluginClass}-->
|
||||
<link href="__STATICADMIN__css/content.css" rel="stylesheet" type="text/css" />
|
||||
<div class="layui-fluid">
|
||||
示例模板,可自行开发
|
||||
</div>
|
||||
<include file="/public/static" />
|
||||
<include file="/public/footer" />
|
||||
@@ -0,0 +1,77 @@
|
||||
<include file="/public/header" />
|
||||
<!--{pluginClass}-->
|
||||
<div class="layui-fluid">
|
||||
<div class="layui-card">
|
||||
<!-- // 默认操作按钮 -->
|
||||
<div class="layui-card-header layadmin-card-header-auto ">
|
||||
<div class="layui-form">
|
||||
<!-- // 自定义搜索参数 -->
|
||||
<div id="laytable-search" class="layui-form-item" >
|
||||
{%everySearchHtml%}
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
{%adviceSearchHtml%}
|
||||
<div class="layui-inline" >
|
||||
<!-- // 默认搜索 -->
|
||||
<button class="layui-btn icon-btn" lay-filter="formSearch" lay-submit><i class="layui-icon layui-icon-search"></i>{:__('搜索')}</button>
|
||||
<!--formBegin-->
|
||||
<button class="layui-btn icon-btn" lay-open="" data-title="{:__('添加')}" data-area="{%FormArea%}" data-maxmin="true" data-url="{:url('{%controller%}add')}" >
|
||||
<i class="layui-icon layui-icon-add-1"></i>{:__('添加')}
|
||||
</button>
|
||||
<!--formEnd-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- // 创建数据实例 -->
|
||||
<table id="lay-tableList" lay-filter="lay-tableList"></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- // 列表状态栏 -->
|
||||
<script type="text/html" id="columnStatus">
|
||||
<input type="checkbox" lay-filter="switchStatus" data-url="{:url('{%controller%}status')}" value="{{d.id}}" lay-skin="switch" {{d.status==1?'checked':''}} />
|
||||
</script>
|
||||
|
||||
<!-- // 列表工具栏 -->
|
||||
<script type="text/html" id="tableBar">
|
||||
<!--formBegin-->
|
||||
<a class="layui-table-text" data-title="{:__('编辑')}" data-area="{%FormArea%}" data-maxmin="true"
|
||||
data-url="{:url('{%controller%}edit')}?id={{d.id}}" lay-event="edit" >{:__('编辑')}</a>
|
||||
<div class="layui-divider layui-divider-vertical"></div>
|
||||
<!--formEnd-->
|
||||
<a class="layui-table-text" data-url="{:url('{%controller%}del')}?id={{d.id}}" lay-event="del" >{:__('删除')}</a>
|
||||
</script>
|
||||
|
||||
{%editforms%}
|
||||
|
||||
<script type="text/html" id="tableButton"></script>
|
||||
|
||||
<include file="/public/footer" />
|
||||
<script>
|
||||
layui.use(['admin','table'], function () {
|
||||
|
||||
var admin = layui.admin;
|
||||
var table = layui.table;
|
||||
|
||||
/*
|
||||
* 初始化表格
|
||||
*/
|
||||
var isTable = table.render({
|
||||
elem: "#lay-tableList"
|
||||
,url: "{:url('{%controller%}index')}"
|
||||
,toolbar: '#tableButton'
|
||||
,defaultToolbar: ['filter', 'exports', 'print','search']
|
||||
,cellMinWidth: 160
|
||||
,page: true
|
||||
,limit: 18
|
||||
,cols: [[
|
||||
{type: 'checkbox', width: 50},
|
||||
{field: 'id', align: 'center',sort: true,width: 80, title: 'ID'},
|
||||
{%colsListArr%}
|
||||
{align: 'center', toolbar: '#tableBar', width:160, fixed: 'right', title: '{:__("操作")}'},
|
||||
]]
|
||||
})
|
||||
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,75 @@
|
||||
<include file="/public/header" />
|
||||
<!--{pluginClass}-->
|
||||
<div class="layui-fluid">
|
||||
<div class="layui-card">
|
||||
<!-- // 默认操作按钮 -->
|
||||
<div class="layui-card-header layadmin-card-header-auto ">
|
||||
<div class="layui-form">
|
||||
<!-- // 自定义搜索参数 -->
|
||||
<div id="laytable-search" class="layui-form-item" >
|
||||
{%everySearchHtml%}
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
{%adviceSearchHtml%}
|
||||
<div class="layui-inline" >
|
||||
<!-- // 默认搜索 -->
|
||||
<button class="layui-btn icon-btn" lay-filter="formSearch" lay-submit><i class="layui-icon layui-icon-search"></i>{:__('搜索')}</button>
|
||||
<!-- // 打开添加页面 -->
|
||||
<button class="layui-btn icon-btn" lay-open="" data-title="{:__('添加')}" data-area="{%FormArea%}" data-maxmin="true" data-url="#editforms" >
|
||||
<i class="layui-icon layui-icon-add-1"></i>{:__('添加')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- // 创建数据实例 -->
|
||||
<table id="lay-tableList" lay-filter="lay-tableList"></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- // 列表状态栏 -->
|
||||
<script type="text/html" id="columnStatus">
|
||||
<input type="checkbox" lay-filter="switchStatus" data-url="{:url('{%controller%}status')}" value="{{d.id}}" lay-skin="switch" {{d.status==1?'checked':''}} />
|
||||
</script>
|
||||
|
||||
<!-- // 列表工具栏 -->
|
||||
<script type="text/html" id="tableBar">
|
||||
<a class="layui-table-text" data-title="{:__('编辑')}" data-area="{%FormArea%}" data-maxmin="true" data-url="#editforms" lay-event="edit" >{:__('编辑')}</a>
|
||||
<div class="layui-divider layui-divider-vertical"></div>
|
||||
<a class="layui-table-text" data-url="{:url('{%controller%}del')}?id={{d.id}}" lay-event="del" >{:__('删除')}</a>
|
||||
</script>
|
||||
|
||||
{%editforms%}
|
||||
|
||||
<!-- // 工具栏按钮项 TODO -->
|
||||
<script type="text/html" id="tableButton">
|
||||
</script>
|
||||
|
||||
<include file="/public/footer" />
|
||||
<script>
|
||||
layui.use(['admin','table'], function () {
|
||||
|
||||
var admin = layui.admin;
|
||||
var table = layui.table;
|
||||
|
||||
/*
|
||||
* 初始化表格
|
||||
*/
|
||||
var isTable = table.render({
|
||||
elem: "#lay-tableList"
|
||||
,url: "{:url('{%controller%}index')}"
|
||||
,toolbar: '#tableButton'
|
||||
,defaultToolbar: ['filter', 'exports', 'print','search']
|
||||
,cellMinWidth: 160
|
||||
,page: true
|
||||
,limit: 18
|
||||
,cols: [[
|
||||
{type: 'checkbox', width:50},
|
||||
{field: 'id', align: 'center',sort: true,width: 80, title: 'ID'},
|
||||
{%colsListArr%}
|
||||
{align: 'center', toolbar: '#tableBar', width:160, fixed: 'right', title: '{:__("操作")}'},
|
||||
]]
|
||||
})
|
||||
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,13 @@
|
||||
<!-- // 内置表单项 -->
|
||||
<script type="text/html" id="editforms" >
|
||||
<div class="layui-fluid layui-bg-white" >
|
||||
<form class="layui-form layui-form-fixed" lay-filter="editforms" >
|
||||
<input type="text" name="id" hidden="">
|
||||
{formItems}
|
||||
<div class="layui-footer layui-form-item layui-center" >
|
||||
<button class="layui-btn layui-btn-primary" type="button" sa-event="closePageDialog" >{:__('取消')}</button>
|
||||
<button class="layui-btn" type="button" lay-filter="submitPage" lay-submit>{:__('提交')}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</script>
|
||||
@@ -0,0 +1,12 @@
|
||||
templet:function(d) {
|
||||
var colsTit = [];
|
||||
var colsArr = {colsArr};
|
||||
for (var key in colsArr) {
|
||||
let el = colsArr[key];
|
||||
if (d.{field}.indexOf(el.value) !== -1) {
|
||||
colsTit.push(el.title);
|
||||
}
|
||||
}
|
||||
|
||||
return colsTit.join(' ');
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
templet:function(d) {
|
||||
return '<a href="'+d.{field}+'" target="_blank" ><img class="filesuffix" src="'+d.{field}+'"></a>';
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
templet:function(d) {
|
||||
return '<a href="javascript:"><img class="filesuffix" lay-image-click src="'+d.{field}+'"></a>';
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
templet:function(d) {
|
||||
return JSON.stringify(d.{field});
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
templet:function(d) {
|
||||
var album = [];
|
||||
for (var i in d.{field}) {
|
||||
album[i] = '<a href="javascript:" class="fileslink" ><img class="filesuffix" lay-image-click src="'+d.{field}[i].src+'"></a>'
|
||||
}
|
||||
return album.join('');
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
templet:function(d) {
|
||||
var colsArr = {colsArr};
|
||||
return colsArr[d.{field}].title;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
templet:function(d) {
|
||||
var colsArr = {colsArr};
|
||||
return colsArr[d.{field}].title;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
templet:function(d) {
|
||||
return d.{field}.replace(',',' ');
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* method 函数
|
||||
*/
|
||||
public function method()
|
||||
{
|
||||
return $this->view();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace {%modelNamespace%};
|
||||
|
||||
use think\Model;
|
||||
{%softDeleteClassPath%}
|
||||
|
||||
/**
|
||||
* {%table%}
|
||||
* <!--{%pluginClass%}-->
|
||||
* {%title%}
|
||||
* Class {%modelName%}
|
||||
* @package {%modelNamespace%}
|
||||
*/
|
||||
class {%modelName%} extends Model
|
||||
{
|
||||
|
||||
{%softDelete%}
|
||||
|
||||
// 定义时间戳字段名
|
||||
protected $createTime = {%createTime%};
|
||||
protected $updateTime = {%updateTime%};
|
||||
protected $deleteTime = {%deleteTime%};
|
||||
|
||||
{%relationMethodList%}
|
||||
{%fieldAttrArr%}
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
<if (isset($data['id'])) && $data['id']>
|
||||
<eq name="$vo.checked" value="true">checked</eq>
|
||||
<else/>
|
||||
<eq name="$vo.value" value="$data.fieldName">checked</eq>
|
||||
</if>
|
||||
@@ -0,0 +1,6 @@
|
||||
<div class="layui-inline">
|
||||
<div class="layui-form-label">{:__('{%title%}')}</div>
|
||||
<div class="layui-input-inline ">
|
||||
<input name="{%field%}" lay-cascader="" class="layui-input" type="text" placeholder="{:__('{%title%}')}"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,6 @@
|
||||
<div class="layui-inline">
|
||||
<div class="layui-form-label">{:__('{%title%}')}</div>
|
||||
<div class="layui-input-inline ">
|
||||
<input name="{%field%}" lay-datetime data-range="true" data-type="date" data-dateformat="yyyy/MM/dd" class="layui-input" type="text" placeholder="{:__('{%title%}')}"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,6 @@
|
||||
<div class="layui-inline">
|
||||
<div class="layui-form-label">{:__('{%title%}')}</div>
|
||||
<div class="layui-input-inline ">
|
||||
<input name="{%field%}" class="layui-input" type="text" placeholder="{:__('{%title%}')}"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
<div class="layui-inline">
|
||||
<div class="layui-form-label">{:__('{%title%}')}</div>
|
||||
<div class="layui-input-inline" style="max-height:20px;">
|
||||
<input name="{%field%}" class="layui-input layui-hide {%field%}" type="text" placeholder="{:__('{%title%}')}"/>
|
||||
<div lay-rate="{%field%}" data-default="1" data-theme="{theme}" data-length="{length}" class="layui-inline"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
<div class="layui-inline">
|
||||
<div class="layui-form-label">{:__('{%title%}')}</div>
|
||||
<div class="layui-input-inline ">
|
||||
<php> ${%varlist%} = {%vardata%}; </php>
|
||||
<select name="{%field%}" lay-search >
|
||||
<option value="">{:__('请选择')}</option>
|
||||
<volist name="{%varlist%}" id="vo">
|
||||
<option value="{$vo.value}">{$vo.title}</option>
|
||||
</volist>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
<div class="layui-inline">
|
||||
<div class="layui-form-label">{:__('{%title%}')}</div>
|
||||
<div class="layui-input-inline ">
|
||||
<input name="{%field%}" class="layui-input layui-hide" type="text" />
|
||||
<div lay-slider="{%field%}" data_default="{default}" data-theme="{theme}" data-step="{step}" data-max="{max}" data-min="{min}" data-input="true"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
<div class="layui-inline">
|
||||
<select name="status">
|
||||
<option value="">{:__('按状态查询')}</option>
|
||||
<option value="2" >{:__('正常')}</option>
|
||||
<option value="1" >{:__('关闭')}</option>
|
||||
</select>
|
||||
</div>
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace {%validateNamespace%};
|
||||
|
||||
use think\Validate;
|
||||
/**
|
||||
* <!--{%pluginClass%}-->
|
||||
* {%validateName%} 验证器
|
||||
* Class {%validateName%}
|
||||
* @package {%validateNamespace%}
|
||||
*/
|
||||
class {%validateName%} extends Validate
|
||||
{
|
||||
/**
|
||||
* 验证规则
|
||||
*/
|
||||
protected $rule = [
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* 提示消息
|
||||
*/
|
||||
protected $message = [
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* 验证场景
|
||||
*/
|
||||
protected $scene = [
|
||||
'add' => [],
|
||||
'edit' => [],
|
||||
];
|
||||
|
||||
}
|
||||
17
plugin/developer/app/admin/model/developer/Generate.php
Normal file
17
plugin/developer/app/admin/model/developer/Generate.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\admin\model\developer;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* <!--Developer-->
|
||||
* @mixin \think\Model
|
||||
*/
|
||||
class Generate extends Model
|
||||
{
|
||||
// 定义时间戳字段名
|
||||
protected $createTime = 'create_time';
|
||||
protected $updateTime = 'update_time';
|
||||
}
|
||||
33
plugin/developer/app/admin/model/developer/Plugin.php
Normal file
33
plugin/developer/app/admin/model/developer/Plugin.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\developer;
|
||||
|
||||
use think\Model;
|
||||
|
||||
|
||||
/**
|
||||
* 插件开发
|
||||
* <!--Developer-->
|
||||
* Class Plugin
|
||||
* @package app\admin\model\developer
|
||||
*/
|
||||
class Plugin extends Model
|
||||
{
|
||||
|
||||
// 定义时间戳字段名
|
||||
protected $createTime = 'create_time';
|
||||
protected $updateTime = 'update_time';
|
||||
protected $deleteTime = false;
|
||||
|
||||
/**
|
||||
* 转换小写字母
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function setNameAttr($value): string
|
||||
{
|
||||
return strtolower($value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
59
plugin/developer/app/admin/validate/developer/Generate.php
Normal file
59
plugin/developer/app/admin/validate/developer/Generate.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\admin\validate\developer;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
/**
|
||||
* <!--Developer-->
|
||||
*/
|
||||
class Generate extends Validate
|
||||
{
|
||||
/**
|
||||
* 定义验证规则
|
||||
* 格式:'字段名' => ['规则1','规则2'...]
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $rule = [
|
||||
'menus' => 'rules',
|
||||
];
|
||||
|
||||
/**
|
||||
* 定义错误信息
|
||||
* 格式:'字段名.规则名' => '错误信息'
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $message = [
|
||||
'menus.rules' => '路由规则匹配错误',
|
||||
];
|
||||
|
||||
/**
|
||||
* 自定义验证规则
|
||||
*
|
||||
* @param [type] $value
|
||||
* @param [type] $rule
|
||||
* @param [type] $post
|
||||
* @return bool
|
||||
*/
|
||||
protected function rules($value, $rule, $post): bool
|
||||
{
|
||||
if (!empty($value)) {
|
||||
$controller = $post['controller'];
|
||||
$controller = substr($controller,1,strrpos($controller,'/')-1);
|
||||
$list = unserialize($value);
|
||||
foreach ($list as $value) {
|
||||
$router = $value['router'];
|
||||
$router = substr($router,1,strrpos($router,'/')-1);
|
||||
if ($router != $controller) {
|
||||
$this->message['menus.rules'] = $router.' regex error';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
74
plugin/developer/app/admin/validate/developer/Plugin.php
Normal file
74
plugin/developer/app/admin/validate/developer/Plugin.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\validate\developer;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
/**
|
||||
* <!--Developer-->
|
||||
*/
|
||||
class Plugin extends Validate
|
||||
{
|
||||
|
||||
/**
|
||||
* 定义验证规则
|
||||
* 格式:'字段名' => ['规则1','规则2'...]
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $rule = [
|
||||
'name|标识' => 'require|min:3|max:32|alphaNum|name_initial',
|
||||
'version|版本' => 'require|min:5|max:10|filters',
|
||||
];
|
||||
|
||||
/**
|
||||
* 定义错误信息
|
||||
* 格式:'字段名.规则名' => '错误信息'
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $message = [
|
||||
'name.require' => '标识不能为空',
|
||||
'name.min' => '标识不能少于3个字符',
|
||||
'name.max' => '标识不能超过32个字符',
|
||||
'name.alphaNum' => '标识只能是字母和数字',
|
||||
'name.name_initial' => '标识不能以数字开头',
|
||||
'version.min' => '版本不能少于5个字符',
|
||||
'version.filters' => '插件版本版本号应为1.0.0或1.0.1格式',
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* 验证场景
|
||||
*/
|
||||
protected $scene = [
|
||||
'add' => [],
|
||||
'edit' => [],
|
||||
];
|
||||
|
||||
/**
|
||||
* 验证版本是否符合格式
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function filters($value): bool
|
||||
{
|
||||
if (!preg_match('/^[1-9]\.[0-9]\.[0-9]$/i', $value)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证 插件标识规则
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function name_initial($value): bool
|
||||
{
|
||||
if (is_numeric($value[0])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
225
plugin/developer/app/admin/view/developer/example/auxiliar.html
Normal file
225
plugin/developer/app/admin/view/developer/example/auxiliar.html
Normal file
@@ -0,0 +1,225 @@
|
||||
<include file="/public/header"/>
|
||||
<!-- // 重定位style -->
|
||||
<div class="layui-fluid layui-form">
|
||||
<!--Developer-->
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">弹窗组件</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-btn-container" style="margin-top: 15px;">
|
||||
<button class="layui-btn" lay-open data-title="标题" data-url="#editor" data-area="600px,500px">内置弹窗</button>
|
||||
<button class="layui-btn" lay-open data-title="标题" data-url="https://api.swiftadmin.net/" data-area="600px,500px" >iframe弹窗</button>
|
||||
<button class="layui-btn" lay-open data-url="#editor" data-area="600px,500px" >无标题弹窗</button>
|
||||
<button class="layui-btn" lay-open data-title="标题" data-url="#editor" data-area="300px,300px" >300X300弹窗</button>
|
||||
<button class="layui-btn" lay-open data-title="标题" data-url="#editor" data-area="500px,500px" data-maxmin="true" >最大化窗口</button>
|
||||
<button class="layui-btn" lay-open data-title="标题" data-url="#editor" data-area="500px,500px" data-maxmin="true" data-offset="10px">窗口定位</button>
|
||||
<button class="layui-btn" lay-open data-title="标题" data-url="#editor" data-area="500px,500px" data-maxmin="true" data-shadeClose="true" >点击阴影关闭</button>
|
||||
|
||||
</div>
|
||||
<p style="margin: 5px 0 10px 0;">
|
||||
更多弹出层的使用示例请查看 <a href="https://layuion.com/layer/" target="_blank">layer弹窗组件</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">AJAX数据提交</div>
|
||||
<div class="layui-card-body">
|
||||
<button class="layui-btn" lay-ajax data-url="{:url('/ajax/index')}" >常规提交</button>
|
||||
<button class="layui-btn" lay-ajax data-url="{:url('/ajax/index')}" data-table="lay-tableList">刷新表格</button>
|
||||
<button class="layui-btn" lay-ajax data-url="{:url('/ajax/index')}" data-reload="parent">重载父页面</button>
|
||||
<button class="layui-btn" lay-ajax data-url="{:url('/ajax/index')}" data-reload="top">重载顶层页面</button>
|
||||
<button class="layui-btn" lay-ajax data-url="{:url('/ajax/index')}" data-confirm="确定要提交吗?">询问提交</button>
|
||||
<button class="layui-btn" lay-ajax data-url="{:url('/ajax/index')}" data-close="true">提交后关闭窗口/仅适用于窗口</button>
|
||||
<button class="layui-btn" lay-ajax data-url="{:url('/ajax/index')}" data-jump="false">关闭URL跳转</button>
|
||||
<button class="layui-btn layui-btn-primary" lay-ajax="" data-url="{:url('/ajax/index')}" data-object="type:ctype,host:chost,port:cport,user:cuser,pass:cpass">{:__('带参数提交')}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">消息通知</div>
|
||||
<div class="layui-card-body">
|
||||
<button class="layui-btn" onclick="layui.layer.msg('成功消息');" >成功通知</button>
|
||||
<button class="layui-btn layui-btn-danger" onclick="layui.layer.error('错误通知');" >错误通知</button>
|
||||
<button class="layui-btn layui-btn-warm" onclick="layui.layer.warning('警告通知');" >警告通知</button>
|
||||
<button class="layui-btn layui-btn-primary" onclick="layui.layer.info('信息通知');" >信息通知</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">元素切换</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">单选切换</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="cache_status" data-display="radioClass" lay-filter="radioStatus" value="1" title="开启" checked>
|
||||
<input type="radio" name="cache_status" data-display="radioClass" lay-filter="radioStatus" value="0" title="关闭" >
|
||||
</div>
|
||||
<div class="layui-input-inline radioClass">
|
||||
<div class="layui-input-inline">我是元素</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">下拉切换</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="cache_type" data-display="cache_type" data-disable="file" lay-filter="selectStatus" class="ctype">
|
||||
<option value="file" >file</option>
|
||||
<option value="redis" >redis</option>
|
||||
<option value="memcached">memcached</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="layui-input-inline cache_type">
|
||||
<div class="layui-input-inline">我是元素</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">下拉菜单</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-btn-container" style="margin-top: 15px;">
|
||||
<button class="layui-btn" id="demo1">
|
||||
下拉菜单
|
||||
<i class="layui-icon layui-icon-down layui-font-12"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">进度条</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-progress">
|
||||
<div class="layui-progress-bar layui-bg-red" lay-percent="20%"></div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="layui-progress">
|
||||
<div class="layui-progress-bar layui-bg-orange" lay-percent="30%"></div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="layui-progress">
|
||||
<div class="layui-progress-bar layui-bg-primary" lay-percent="40%"></div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="layui-progress">
|
||||
<div class="layui-progress-bar layui-bg-blue" lay-percent="50%"></div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="layui-progress">
|
||||
<div class="layui-progress-bar" lay-percent="60%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">其他组件</div>
|
||||
<div class="layui-card-body">
|
||||
<div>其他组件和元素请参考 <a href="https://layuion.com/docs/" target="_blank">Layui官网文档</a> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/html" id="editor">
|
||||
<form action="" class="layui-form">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-form-item">我是内置弹窗内容</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">禁止编辑</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" class="layui-input" value="我是数据" data-disabled="true" >
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</script>
|
||||
|
||||
<include file="/public/footer"/>
|
||||
<script>
|
||||
layui.use('dropdown', function(){
|
||||
var dropdown = layui.dropdown
|
||||
dropdown.render({
|
||||
elem: '#demo1' //可绑定在任意元素中,此处以上述按钮为例
|
||||
,data: [{
|
||||
title: 'menu item 1'
|
||||
,id: 100
|
||||
,href: '#'
|
||||
},{
|
||||
title: 'menu item 2'
|
||||
,id: 101
|
||||
,href: '{{d.root}}/' //开启超链接
|
||||
,target: '_blank' //新窗口方式打开
|
||||
},{type: '-'},{
|
||||
title: 'menu item 3'
|
||||
,id: 102
|
||||
,type: 'group' //菜单类型,支持:normal/group/parent/-
|
||||
,child: [{
|
||||
title: 'menu item 3-1'
|
||||
,id: 103
|
||||
},{
|
||||
title: 'menu item 3-2'
|
||||
,id: 104
|
||||
,child: [{
|
||||
title: 'menu item 3-2-1'
|
||||
,id: 105
|
||||
},{
|
||||
title: 'menu item 3-2-2'
|
||||
,id: 106
|
||||
}]
|
||||
},{
|
||||
title: 'menu item 3-3'
|
||||
,id: 107
|
||||
}]
|
||||
},{type: '-'},{
|
||||
title: 'menu item 4'
|
||||
,id: 108
|
||||
},{
|
||||
title: 'menu item 5'
|
||||
,id: 109
|
||||
,child: [{
|
||||
title: 'menu item 5-1'
|
||||
,id: 11111
|
||||
,child: [{
|
||||
title: 'menu item 5-1-1'
|
||||
,id: 2111
|
||||
},{
|
||||
title: 'menu item 5-1-2'
|
||||
,id: 3111
|
||||
}]
|
||||
},{
|
||||
title: 'menu item 5-2'
|
||||
,id: 52
|
||||
}]
|
||||
},{type:'-'},{
|
||||
title: 'menu item 6'
|
||||
,id: 6
|
||||
,type: 'group'
|
||||
,isSpreadItem: false
|
||||
,child: [{
|
||||
title: 'menu item 6-1'
|
||||
,id: 61
|
||||
},{
|
||||
title: 'menu item 6-2'
|
||||
,id: 62
|
||||
}]
|
||||
}]
|
||||
,id: 'demo1'
|
||||
//菜单被点击的事件
|
||||
,click: function(obj){
|
||||
console.log(obj);
|
||||
layer.msg('回调返回的参数已显示再控制台');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
94
plugin/developer/app/admin/view/developer/example/card.html
Normal file
94
plugin/developer/app/admin/view/developer/example/card.html
Normal file
@@ -0,0 +1,94 @@
|
||||
<include file="/public/header"/>
|
||||
<!-- // 重定位style -->
|
||||
<div class="layui-fluid ">
|
||||
<!--Developer-->
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-card layui-row ">
|
||||
<div class="layui-card-body layui-col-space10">
|
||||
<div class="layui-col-md3">
|
||||
<div class="layui-project"> <img class="layui-project-cover" src="https://gw.alipayobjects.com/zos/rmsportal/iZBVOIhGJiAnhplqjvZW.png">
|
||||
<div class="layui-project-body">
|
||||
<h2>Angular</h2>
|
||||
<div class="layui-project-text layui-text">希望是一个好东西,也许是最好的,好东西是不会消亡的</div>
|
||||
<div class="layui-project-desc"> <span class="time">2小时前</span>
|
||||
<div class="layui-project-head"> <img class="layui-project-head-item" lay-tips="曲丽丽" src="https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png"> <img class="layui-project-head-item" lay-tips="王昭君" src="https://gw.alipayobjects.com/zos/rmsportal/tBOxZPlITHqwlGjsJWaF.png"> <img class="layui-project-head-item" lay-tips="董娜娜" src="https://gw.alipayobjects.com/zos/rmsportal/sBxjgqiuHMGRkIjqlQCd.png"> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<div class="layui-project"> <img class="layui-project-cover" src="https://gw.alipayobjects.com/zos/rmsportal/iZBVOIhGJiAnhplqjvZW.png">
|
||||
<div class="layui-project-body">
|
||||
<h2>Angular</h2>
|
||||
<div class="layui-project-text layui-text">希望是一个好东西,也许是最好的,好东西是不会消亡的</div>
|
||||
<div class="layui-project-desc"> <span class="time">2小时前</span>
|
||||
<div class="layui-project-head"> <img class="layui-project-head-item" lay-tips="曲丽丽" src="https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png"> <img class="layui-project-head-item" lay-tips="王昭君" src="https://gw.alipayobjects.com/zos/rmsportal/tBOxZPlITHqwlGjsJWaF.png"> <img class="layui-project-head-item" lay-tips="董娜娜" src="https://gw.alipayobjects.com/zos/rmsportal/sBxjgqiuHMGRkIjqlQCd.png"> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<div class="layui-project"> <img class="layui-project-cover" src="https://gw.alipayobjects.com/zos/rmsportal/iZBVOIhGJiAnhplqjvZW.png">
|
||||
<div class="layui-project-body">
|
||||
<h2>Angular</h2>
|
||||
<div class="layui-project-text layui-text">希望是一个好东西,也许是最好的,好东西是不会消亡的</div>
|
||||
<div class="layui-project-desc"> <span class="time">2小时前</span>
|
||||
<div class="layui-project-head"> <img class="layui-project-head-item" lay-tips="曲丽丽" src="https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png"> <img class="layui-project-head-item" lay-tips="王昭君" src="https://gw.alipayobjects.com/zos/rmsportal/tBOxZPlITHqwlGjsJWaF.png"> <img class="layui-project-head-item" lay-tips="董娜娜" src="https://gw.alipayobjects.com/zos/rmsportal/sBxjgqiuHMGRkIjqlQCd.png"> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<div class="layui-project"> <img class="layui-project-cover" src="https://gw.alipayobjects.com/zos/rmsportal/iZBVOIhGJiAnhplqjvZW.png">
|
||||
<div class="layui-project-body">
|
||||
<h2>Angular</h2>
|
||||
<div class="layui-project-text layui-text">希望是一个好东西,也许是最好的,好东西是不会消亡的</div>
|
||||
<div class="layui-project-desc"> <span class="time">2小时前</span>
|
||||
<div class="layui-project-head"> <img class="layui-project-head-item" lay-tips="曲丽丽" src="https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png"> <img class="layui-project-head-item" lay-tips="王昭君" src="https://gw.alipayobjects.com/zos/rmsportal/tBOxZPlITHqwlGjsJWaF.png"> <img class="layui-project-head-item" lay-tips="董娜娜" src="https://gw.alipayobjects.com/zos/rmsportal/sBxjgqiuHMGRkIjqlQCd.png"> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="clear: both;"></div>
|
||||
<div class="layui-article" data-index="0" data-number="1">
|
||||
<h2>Alipay</h2>
|
||||
<span class="layui-badge-rim">1楼</span>
|
||||
<div class="layui-badge-list">
|
||||
<span class="layui-badge layui-badge-gray">SwiftAdmin Pro</span>
|
||||
<span class="layui-badge layui-badge-gray">管理系统</span> <span class="layui-badge layui-badge-gray">前端框架</span> </div>
|
||||
<div class="layui-article-text layui-text">SwiftAdmin 基于Layui的一套通用型极速开发管理后台系统。 </div>
|
||||
<div class="layui-article-desc layui-text">
|
||||
<img src="https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png" class="head">
|
||||
<a href="javascript:;" class="name">付小小</a>  发布在 
|
||||
<a href="javascript:;">http://swiftadmin.net</a>
|
||||
</div>
|
||||
<div class="layui-article-tool">
|
||||
<span class="layui-article-tool-item star-active" lay-event="star">
|
||||
<i class="layui-icon layui-icon-rate"></i>
|
||||
<span>185</span>
|
||||
</span>
|
||||
<span class="layui-article-tool-item star-active" lay-event="like">
|
||||
<i class="layui-icon layui-icon-praise"></i>
|
||||
<span>126</span>
|
||||
</span>
|
||||
<span class="layui-article-tool-item" lay-event="comment">
|
||||
<i class="layui-icon layui-icon-dialogue"></i>
|
||||
<span>18</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<include file="/public/footer"/>
|
||||
<script>
|
||||
layui.use(['layer'], function () {
|
||||
var $ = layui.jquery;
|
||||
var layer = layui.layer;
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
221
plugin/developer/app/admin/view/developer/example/component.html
Normal file
221
plugin/developer/app/admin/view/developer/example/component.html
Normal file
@@ -0,0 +1,221 @@
|
||||
<include file="/public/header"/>
|
||||
<!-- // 重定位style -->
|
||||
<link href="/static/system/css/content.css" rel="stylesheet" type="text/css"/>
|
||||
<div class="layui-fluid layui-form">
|
||||
<!--Developer-->
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">上传组件</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">文件上传</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="image" type="text" class="layui-input pic" placeholder="请上传或直接粘贴图片地址"/>
|
||||
</div>
|
||||
<button type="button" class="layui-btn layui-btn-normal" lay-upload="pic">{:__('上传图片')}</button>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">图片上传</label>
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input layui-input-upload avatar" name="avatar">
|
||||
<button type="button" class="layui-btn" lay-choose="avatar" data-type="images">
|
||||
<i class="layui-icon layui-icon-windows"></i> 选择
|
||||
</button>
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="layui-upload-drag layui-uplpad-image mt10" lay-upload="avatar" data-type="images"
|
||||
data-accept="file" data-size="102400">
|
||||
<i class="layui-icon layui-icon-upload"></i>
|
||||
<p>点击上传,或将文件拖拽到此处</p>
|
||||
<div class="layui-hide">
|
||||
<hr>
|
||||
<img src="" class="layui-upload-dragimg avatar" alt="上传成功后渲染">
|
||||
<span class="layui-badge layui-upload-clear">删除</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">多图上传</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-imagesbox">
|
||||
<div class="layui-input-inline layui-uplpad-image">
|
||||
<div class="layui-upload-drag" lay-upload="album" data-type="multiple" data-accept="file"
|
||||
data-size="102400">
|
||||
<i class="layui-icon layui-icon-upload"></i>
|
||||
<p>点击上传,或将文件拖拽到此处</p>
|
||||
<div class="layui-hide"></div>
|
||||
</div>
|
||||
<input class="layui-upload-file" type="file" accept="" name="file">
|
||||
<button type="button" class="layui-btn layui-btn-xs layui-btn-fluid" lay-choose="album"
|
||||
data-type="multiple">
|
||||
<i class="layui-icon layui-icon-windows"></i> 选择
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">时间组件</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">时间选择</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" class="layui-input" lay-datetime placeholder="yyyy-MM-dd">
|
||||
</div>
|
||||
|
||||
<label class="layui-form-label">左右面板</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" class="layui-input" placeholder="yyyy-MM-dd - yyyy-MM-dd" lay-datetime=""
|
||||
data-range="true" data-datetype="datetime" data-dateformat="yyyy-MM-dd HH:mm:ss"
|
||||
lay-key="22">
|
||||
</div>
|
||||
|
||||
<label class="layui-form-label">时间选择器</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" class="layui-input" placeholder="HH:mm:ss" lay-datetime="" data-datetype="time"
|
||||
data-dateformat="HH:mm:ss" lay-key="22">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">年选择器</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" class="layui-input" placeholder="yyyy" lay-datetime="" data-datetype="year"
|
||||
data-dateformat="yyyy" lay-key="22">
|
||||
</div>
|
||||
|
||||
<label class="layui-form-label">年月选择器</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" class="layui-input" placeholder="yyyy-MM" lay-datetime="" data-datetype="month"
|
||||
data-dateformat="yyyy-MM" lay-key="22">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">评分组件</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">评分组件</label>
|
||||
<div class="layui-input-inline">
|
||||
<input class="layui-input layui-hide rate_8" name="rate_8">
|
||||
<div lay-rate="rate_8" data-default="1" data-class="rate_8" data-theme="#1890ff" data-length="5"
|
||||
class="layui-inline"></div>
|
||||
</div>
|
||||
|
||||
<label class="layui-form-label">显示半星</label>
|
||||
<div class="layui-input-inline">
|
||||
<input class="layui-input layui-hide rate_81" name="rate_81">
|
||||
<div lay-rate="rate_8" data-default="1" data-class="rate_81" data-half="true" data-theme="#1890ff"
|
||||
data-length="5" class="layui-inline"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">开关单选</div>
|
||||
<div class="layui-card-body">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">开关</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="checkbox" checked="" name="open" lay-skin="switch" lay-filter="switchTest" title="开关">
|
||||
</div>
|
||||
|
||||
<label class="layui-form-label">单选框</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="sex" value="男" title="男" checked="">
|
||||
<input type="radio" name="sex" value="女" title="女">
|
||||
<input type="radio" name="sex" value="禁" title="禁用" disabled="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card" style="overflow: visible!important;">
|
||||
<div class="layui-card-header">下拉多选</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">下拉框</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="interest">
|
||||
<option value=""></option>
|
||||
<option value="0">写作</option>
|
||||
<option value="1">阅读</option>
|
||||
<option value="2">游戏</option>
|
||||
<option value="3">音乐</option>
|
||||
<option value="4">旅行</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label class="layui-form-label">多选框</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="checkbox" name="like1[write]" lay-skin="primary" title="写作" checked="">
|
||||
<input type="checkbox" name="like1[read]" lay-skin="primary" title="阅读">
|
||||
<input type="checkbox" name="like1[game]" lay-skin="primary" title="游戏" disabled="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">颜色选择器</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">选择器</label>
|
||||
<div class="layui-input-inline">
|
||||
<input class="layui-input layui-hide colorpicker_10" name="colorpicker_10">
|
||||
<div lay-colorpicker="colorpicker_10" data-value="undefined" class="layui-inline"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">标签选择器</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">常规使用</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" lay-tags>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">级联选择器</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-form-item" >
|
||||
<label class="layui-form-label">城市</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" id="city" class="layui-hide" lay-cascader="" name="city" data-value="label" data-parents="1" />
|
||||
</div>
|
||||
<div class="layui-input-inline">
|
||||
对于第三方组件,本框架未进行高度封装,如有特殊需求,可参考第三方文档自行渲染并进行数据处理!
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<include file="/public/footer"/>
|
||||
<script>
|
||||
layui.use(['layer'], function () {
|
||||
var $ = layui.jquery;
|
||||
var layer = layui.layer;
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
575
plugin/developer/app/admin/view/developer/example/echarts.html
Normal file
575
plugin/developer/app/admin/view/developer/example/echarts.html
Normal file
@@ -0,0 +1,575 @@
|
||||
<include file="/public/header"/>
|
||||
<!-- // 重定位style -->
|
||||
<!--Developer-->
|
||||
<style>
|
||||
.console-link-block {
|
||||
font-size: 16px;
|
||||
padding: 20px 20px;
|
||||
border-radius: 4px;
|
||||
background-color: #40D4B0;
|
||||
color: #FFFFFF !important;
|
||||
box-shadow: 0 2px 3px rgba(0, 0, 0, .05);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.console-link-block .console-link-block-num {
|
||||
font-size: 40px;
|
||||
margin-bottom: 5px;
|
||||
opacity: .9;
|
||||
}
|
||||
|
||||
.console-link-block .console-link-block-text {
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
.console-link-block .console-link-block-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 20px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
font-size: 50px;
|
||||
line-height: 50px;
|
||||
margin-top: -25px;
|
||||
color: #FFFFFF;
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
.console-link-block .console-link-block-band {
|
||||
color: #fff;
|
||||
width: 100px;
|
||||
font-size: 12px;
|
||||
padding: 2px 0 3px 0;
|
||||
background-color: #E32A16;
|
||||
line-height: inherit;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: -30px;
|
||||
transform-origin: center;
|
||||
transform: rotate(45deg) scale(.8);
|
||||
opacity: .95;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/** //统计快捷方式样式 */
|
||||
|
||||
/** 设置每个快捷块的颜色 */
|
||||
.layui-row > div:nth-child(2) .console-link-block {
|
||||
background-color: #55A5EA;
|
||||
}
|
||||
|
||||
.layui-row > div:nth-child(3) .console-link-block {
|
||||
background-color: #9DAFFF;
|
||||
}
|
||||
|
||||
.layui-row > div:nth-child(4) .console-link-block {
|
||||
background-color: #F591A2;
|
||||
}
|
||||
|
||||
.layui-row > div:nth-child(5) .console-link-block {
|
||||
background-color: #FEAA4F;
|
||||
}
|
||||
|
||||
.layui-row > div:last-child .console-link-block {
|
||||
background-color: #9BC539;
|
||||
}
|
||||
</style>
|
||||
<div class="layui-fluid">
|
||||
<!-- 快捷方式 -->
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div class="layui-col-md2 layui-col-sm4 layui-col-xs6">
|
||||
<div class="console-link-block">
|
||||
<div class="console-link-block-num">15</div>
|
||||
<div class="console-link-block-text">外出申请</div>
|
||||
<i class="console-link-block-icon layui-icon layui-icon-survey"></i>
|
||||
<div class="console-link-block-band">待审批</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md2 layui-col-sm4 layui-col-xs6">
|
||||
<div class="console-link-block">
|
||||
<div class="console-link-block-num">13</div>
|
||||
<div class="console-link-block-text">请假审批</div>
|
||||
<i class="console-link-block-icon layui-icon layui-icon-print"></i>
|
||||
<div class="console-link-block-band">待审批</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md2 layui-col-sm4 layui-col-xs6">
|
||||
<div class="console-link-block">
|
||||
<div class="console-link-block-num">22</div>
|
||||
<div class="console-link-block-text">研发周报</div>
|
||||
<i class="console-link-block-icon layui-icon layui-icon-list"
|
||||
style="font-size: 62px;padding-right: 5px;"></i>
|
||||
<div class="console-link-block-band">去查看</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md2 layui-col-sm4 layui-col-xs6">
|
||||
<div class="console-link-block">
|
||||
<div class="console-link-block-num">18</div>
|
||||
<div class="console-link-block-text">研发月报</div>
|
||||
<i class="console-link-block-icon layui-icon layui-icon-date"></i>
|
||||
<div class="console-link-block-band">去查看</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md2 layui-col-sm4 layui-col-xs6">
|
||||
<div class="console-link-block">
|
||||
<div class="console-link-block-num">11</div>
|
||||
<div class="console-link-block-text">拜访记录</div>
|
||||
<i class="console-link-block-icon layui-icon layui-icon-service"></i>
|
||||
<div class="console-link-block-band">去查看</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md2 layui-col-sm4 layui-col-xs6">
|
||||
<div class="console-link-block">
|
||||
<div class="console-link-block-num">26</div>
|
||||
<div class="console-link-block-text">项目申报</div>
|
||||
<i class="console-link-block-icon layui-icon layui-icon-email"></i>
|
||||
<div class="console-link-block-band">待审批</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 统计图表 -->
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div class="layui-col-md4 layui-col-sm6">
|
||||
<div class="layui-card" style="overflow: hidden;">
|
||||
<div class="layui-card-header">日统计</div>
|
||||
<div class="layui-card-body">
|
||||
<div id="consoleChartsDay" style="height: 300px;"></div>
|
||||
<div style="color: #10B4E8;font-size: 18px;position: absolute;bottom: 85px;left: 0;right:0;text-align: center;cursor: pointer;">
|
||||
签到明细<i class="layui-icon layui-icon-right" style="font-size: 16px;"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md4 layui-col-sm6">
|
||||
<div class="layui-card" style="overflow: hidden;">
|
||||
<div class="layui-card-header">周统计</div>
|
||||
<div class="layui-card-body">
|
||||
<div id="consoleChartsWeek" style="height: 300px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md4 layui-col-sm6">
|
||||
<div class="layui-card" style="overflow: hidden;">
|
||||
<div class="layui-card-header">月统计</div>
|
||||
<div class="layui-card-body">
|
||||
<div id="consoleChartsMonth" style="height: 300px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md4 layui-col-sm6">
|
||||
<div class="layui-card" style="overflow: hidden;">
|
||||
<div class="layui-card-header">雷达图</div>
|
||||
<div class="layui-card-body">
|
||||
<div id="consoleChartsWord" style="height: 300px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-col-md4 layui-col-sm6">
|
||||
<div class="layui-card" style="overflow: hidden;">
|
||||
<div class="layui-card-header">散点图</div>
|
||||
<div class="layui-card-body">
|
||||
<div id="consoleChartsScatter" style="height: 300px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-col-md4 layui-col-sm6">
|
||||
<div class="layui-card" style="overflow: hidden;">
|
||||
<div class="layui-card-header">旭日图</div>
|
||||
<div class="layui-card-body">
|
||||
<div id="consoleChartsSunburst" style="height: 300px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<include file="/public/footer"/>
|
||||
<script src="__STATICADMIN__module/echarts/echarts.js?console"></script>
|
||||
<script src="__STATICADMIN__module/echarts/china.js?console"></script>
|
||||
<script>
|
||||
layui.use(['layer'], function () {
|
||||
var $ = layui.jquery;
|
||||
var layer = layui.layer;
|
||||
|
||||
/** 渲染日统计图表 */
|
||||
var myCharts1 = echarts.init(document.getElementById('consoleChartsDay'));
|
||||
var options1 = {
|
||||
title: {
|
||||
text: '签到人数/应到人数', x: 'center', y: '32%',
|
||||
textStyle: {fontSize: 16, color: '#262626', fontWeight: 'normal'},
|
||||
subtextStyle: {fontSize: 39, color: '#10B4E8'}, itemGap: 20
|
||||
},
|
||||
color: ['#10B4E8', '#E0E0E0'],
|
||||
tooltip: {trigger: 'item'},
|
||||
legend: {
|
||||
orient: 'vertical', right: '0px', top: '0px',
|
||||
data: ['已签到', '未签到'], textStyle: {color: '#595959'}
|
||||
},
|
||||
series: [{name: '人数', type: 'pie', radius: ['75%', '80%'], label: {normal: {show: false}}}]
|
||||
};
|
||||
myCharts1.setOption(options1);
|
||||
// 赋值
|
||||
myCharts1.setOption({
|
||||
title: {subtext: '38/60'}, series: [{data: [{name: '已签到', value: 38}, {name: '未签到', value: 22}]}]
|
||||
});
|
||||
|
||||
/** 渲染周统计图表 */
|
||||
var myCharts2 = echarts.init(document.getElementById('consoleChartsWeek'));
|
||||
var options2 = {
|
||||
tooltip: {trigger: 'axis', axisPointer: {lineStyle: {color: '#E0E0E0'}}},
|
||||
color: ['#10B4E8', '#FFA800'],
|
||||
legend: {
|
||||
orient: 'vertical', right: '0px', top: '0px',
|
||||
data: ['已签到', '未签到'], textStyle: {color: '#595959'}
|
||||
},
|
||||
grid: {top: '75px', left: '35px', right: '55px', bottom: '40px'},
|
||||
xAxis: {
|
||||
name: '星期',
|
||||
nameTextStyle: {color: '#595959'},
|
||||
type: 'category',
|
||||
data: ['周一', '周二', '周三', '周四', '周五'],
|
||||
axisLine: {lineStyle: {color: '#E0E0E0'}, symbol: ['none', 'arrow'], symbolOffset: [0, 10]},
|
||||
axisLabel: {color: '#8c8c8c'},
|
||||
axisTick: {alignWithLabel: true}
|
||||
},
|
||||
yAxis: {
|
||||
name: '人数',
|
||||
nameTextStyle: {color: '#595959'},
|
||||
type: 'value',
|
||||
boundaryGap: ['0', '20%'],
|
||||
axisTick: {show: false},
|
||||
axisLine: {lineStyle: {color: '#E0E0E0'}, symbol: ['none', 'arrow'], symbolOffset: [0, 10]},
|
||||
axisLabel: {color: '#8c8c8c'},
|
||||
splitLine: {show: false},
|
||||
splitArea: {show: false},
|
||||
minInterval: 1
|
||||
},
|
||||
series: [{
|
||||
name: '已签到', type: 'bar', stack: 'one', barMaxWidth: '30px',
|
||||
label: {normal: {show: true, position: 'inside'}}
|
||||
}, {
|
||||
name: '未签到', type: 'bar', stack: 'one', barMaxWidth: '30px',
|
||||
label: {normal: {show: true, position: 'inside'}}
|
||||
}]
|
||||
};
|
||||
myCharts2.setOption(options2);
|
||||
// 赋值
|
||||
myCharts2.setOption({series: [{data: [5, 9, 6, 3, 10]}, {data: [10, 6, 9, 12, 5]}]});
|
||||
|
||||
/** 渲染月统计图表 */
|
||||
var myCharts3 = echarts.init(document.getElementById('consoleChartsMonth'));
|
||||
var options3 = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {lineStyle: {color: '#E0E0E0'}},
|
||||
formatter: '{b}号<br/><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#10B4E8;"></span>{a0}: {c0}<br/><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#FFA800;"></span>{a1}: {c1}'
|
||||
},
|
||||
color: ['#10B4E8', '#FFA800'],
|
||||
legend: {
|
||||
orient: 'vertical', right: '0px', top: '0px',
|
||||
data: ['已签到', '未签到'], textStyle: {color: '#595959'}
|
||||
},
|
||||
grid: {top: '75px', left: '35px', right: '55px', bottom: '40px'},
|
||||
xAxis: {
|
||||
name: '日期',
|
||||
nameTextStyle: {color: '#595959'},
|
||||
type: 'category',
|
||||
data: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31'],
|
||||
axisLine: {lineStyle: {color: '#E0E0E0'}, symbol: ['none', 'arrow'], symbolOffset: [0, 10]},
|
||||
axisLabel: {
|
||||
color: '#8c8c8c', interval: function (index, value) {
|
||||
return index === 0 || ((index + 1) % 5 === 0);
|
||||
}
|
||||
},
|
||||
axisTick: {alignWithLabel: true}
|
||||
},
|
||||
yAxis: {
|
||||
name: '人数',
|
||||
nameTextStyle: {color: '#595959'},
|
||||
type: 'value',
|
||||
boundaryGap: ['0', '20%'],
|
||||
axisTick: {show: false},
|
||||
axisLine: {lineStyle: {color: '#E0E0E0'}, symbol: ['none', 'arrow'], symbolOffset: [0, 10]},
|
||||
axisLabel: {color: '#8c8c8c'},
|
||||
splitLine: {show: false},
|
||||
splitArea: {show: false},
|
||||
minInterval: 1
|
||||
},
|
||||
series: [
|
||||
{name: '已签到', type: 'line', smooth: false},
|
||||
{name: '未签到', type: 'line', smooth: false}
|
||||
]
|
||||
};
|
||||
myCharts3.setOption(options3);
|
||||
// 赋值
|
||||
myCharts3.setOption({
|
||||
series: [
|
||||
{data: [15, 14, 13, 13, 13, 14, 15, 16, 17, 18, 19, 18, 18, 19, 20, 19, 18, 16, 14, 12, 10, 10, 12, 14, 16, 16, 14, 13, 12, 11, 10]},
|
||||
{data: [24, 22, 20, 18, 16, 14, 13, 12, 11, 11, 10, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 23, 24, 25, 26, 26, 24, 22, 20, 18, 16]}
|
||||
]
|
||||
});
|
||||
|
||||
/** 渲染散点图 */
|
||||
var myCharts4 = echarts.init(document.getElementById('consoleChartsScatter'));
|
||||
const axisData = ['Mon', 'Tue', 'Wed', 'Very Loooong Thu', 'Fri', 'Sat', 'Sun'];
|
||||
const data = axisData.map(function (item, i) {
|
||||
return Math.round(Math.random() * 1000 * (i + 1));
|
||||
});
|
||||
const links = data.map(function (item, i) {
|
||||
return {
|
||||
source: i,
|
||||
target: i + 1
|
||||
};
|
||||
});
|
||||
links.pop();
|
||||
var options4 = {
|
||||
title: {
|
||||
text: 'Graph on Cartesian'
|
||||
},
|
||||
tooltip: {},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: axisData
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'graph',
|
||||
layout: 'none',
|
||||
coordinateSystem: 'cartesian2d',
|
||||
symbolSize: 40,
|
||||
label: {
|
||||
show: true
|
||||
},
|
||||
edgeSymbol: ['circle', 'arrow'],
|
||||
edgeSymbolSize: [4, 10],
|
||||
data: data,
|
||||
links: links,
|
||||
lineStyle: {
|
||||
color: '#2f4554'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
myCharts4.setOption(options4);
|
||||
// 赋值
|
||||
myCharts4.setOption({
|
||||
series: [{
|
||||
data: [
|
||||
{name: "西藏", value: 60},
|
||||
{name: "青海", value: 167},
|
||||
{name: "宁夏", value: 210},
|
||||
{name: "海南", value: 252},
|
||||
{name: "甘肃", value: 502},
|
||||
{name: "贵州", value: 570},
|
||||
{name: "新疆", value: 661},
|
||||
{name: "云南", value: 8890},
|
||||
{name: "重庆", value: 10010},
|
||||
{name: "吉林", value: 5056},
|
||||
{name: "山西", value: 2123},
|
||||
{name: "天津", value: 9130},
|
||||
{name: "江西", value: 10170},
|
||||
{name: "广西", value: 6172},
|
||||
{name: "陕西", value: 9251},
|
||||
{name: "黑龙江", value: 5125},
|
||||
{name: "内蒙古", value: 1435},
|
||||
{name: "安徽", value: 9530},
|
||||
{name: "北京", value: 51919},
|
||||
{name: "福建", value: 3756},
|
||||
{name: "上海", value: 59190},
|
||||
{name: "湖北", value: 37109},
|
||||
{name: "湖南", value: 8966},
|
||||
{name: "四川", value: 31020},
|
||||
{name: "辽宁", value: 7222},
|
||||
{name: "河北", value: 3451},
|
||||
{name: "河南", value: 9693},
|
||||
{name: "浙江", value: 62310},
|
||||
{name: "山东", value: 39231},
|
||||
{name: "江苏", value: 35911},
|
||||
{name: "广东", value: 55891}
|
||||
]
|
||||
}]
|
||||
});
|
||||
|
||||
var myCharts5 = echarts.init(document.getElementById('consoleChartsWord'));
|
||||
var options5 = {
|
||||
legend: {
|
||||
data: ['项目一', '项目二']
|
||||
},
|
||||
radar: {
|
||||
// shape: 'circle',
|
||||
indicator: [
|
||||
{ name: '销售额', max: 6500 },
|
||||
{ name: '评分', max: 16000 },
|
||||
{ name: '信息技术', max: 30000 },
|
||||
{ name: '客户支持', max: 38000 },
|
||||
{ name: '开发率', max: 52000 },
|
||||
{ name: '市场占有率', max: 25000 }
|
||||
]
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'Budget vs spending',
|
||||
type: 'radar',
|
||||
data: [
|
||||
{
|
||||
value: [4200, 3000, 20000, 35000, 50000, 18000],
|
||||
name: 'Allocated Budget'
|
||||
},
|
||||
{
|
||||
value: [5000, 14000, 28000, 26000, 42000, 21000],
|
||||
name: 'Actual Spending'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
myCharts5.setOption(options5);
|
||||
|
||||
// 赋值
|
||||
var myCharts6 = echarts.init(document.getElementById('consoleChartsSunburst'));
|
||||
|
||||
|
||||
var options6 = {
|
||||
silent: true,
|
||||
series: [
|
||||
{
|
||||
radius: ['15%', '80%'],
|
||||
type: 'sunburst',
|
||||
sort: undefined,
|
||||
emphasis: {
|
||||
focus: 'ancestor'
|
||||
},
|
||||
data: [
|
||||
{
|
||||
value: 8,
|
||||
children: [
|
||||
{
|
||||
value: 4,
|
||||
children: [
|
||||
{
|
||||
value: 2
|
||||
},
|
||||
{
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
value: 0.5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 2
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 4,
|
||||
children: [
|
||||
{
|
||||
children: [
|
||||
{
|
||||
value: 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 4,
|
||||
children: [
|
||||
{
|
||||
children: [
|
||||
{
|
||||
value: 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
children: [
|
||||
{
|
||||
children: [
|
||||
{
|
||||
value: 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
label: {
|
||||
color: '#000',
|
||||
textBorderColor: '#fff',
|
||||
textBorderWidth: 2,
|
||||
formatter: function (param) {
|
||||
var depth = param.treePathInfo.length;
|
||||
if (depth === 2) {
|
||||
return 'radial';
|
||||
} else if (depth === 3) {
|
||||
return 'tangential';
|
||||
} else if (depth === 4) {
|
||||
return '0';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
},
|
||||
levels: [
|
||||
{},
|
||||
{
|
||||
itemStyle: {
|
||||
color: '#CD4949'
|
||||
},
|
||||
label: {
|
||||
rotate: 'radial'
|
||||
}
|
||||
},
|
||||
{
|
||||
itemStyle: {
|
||||
color: '#F47251'
|
||||
},
|
||||
label: {
|
||||
rotate: 'tangential'
|
||||
}
|
||||
},
|
||||
{
|
||||
itemStyle: {
|
||||
color: '#FFC75F'
|
||||
},
|
||||
label: {
|
||||
rotate: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
myCharts6.setOption(options6);
|
||||
|
||||
/** 窗口大小改变事件 */
|
||||
window.onresize = function () {
|
||||
myCharts1.resize();
|
||||
myCharts2.resize();
|
||||
myCharts3.resize();
|
||||
myCharts4.resize();
|
||||
myCharts5.resize();
|
||||
myCharts6.resize();
|
||||
};
|
||||
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,23 @@
|
||||
<include file="/public/header"/>
|
||||
<!-- // 重定位style -->
|
||||
<!--Developer-->
|
||||
<div class="layui-fluid ">
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header"> Tinymce 富文本编辑器</div>
|
||||
<div class="layui-card-body">
|
||||
<textarea name="" id="" lay-editor cols="30" rows="10"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header"> Cherry Markdown编辑器 腾讯出品</div>
|
||||
<div class="layui-card-body">
|
||||
<textarea name="" id="" lay-markdown cols="30" rows="10"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<include file="/public/static"/>
|
||||
<include file="/public/footer"/>
|
||||
|
||||
437
plugin/developer/app/admin/view/developer/example/index.html
Normal file
437
plugin/developer/app/admin/view/developer/example/index.html
Normal file
@@ -0,0 +1,437 @@
|
||||
<include file="/public/header"/>
|
||||
<!-- // 重定位style -->
|
||||
<!--Developer-->
|
||||
<div class="layui-fluid ">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
|
||||
<legend>综合演示</legend>
|
||||
</fieldset>
|
||||
<form class="layui-form" action="">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">单行输入框</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" lay-verify="title" autoComplete="off" placeholder="请输入标题"
|
||||
class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">验证必填项</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="username" lay-verify="required" lay-reqtext="用户名是必填项,岂能为空?"
|
||||
placeholder="请输入"
|
||||
autoComplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">验证手机</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="tel" name="phone" lay-verify="required|phone" autoComplete="off"
|
||||
class="layui-input demo-phone">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">验证码</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="vercode" lay-verify="required" autoComplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid" style="padding: 0!important;">
|
||||
<button type="button" class="layui-btn layui-btn-primary" lay-on="get-vercode">获取验证码</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">验证邮箱</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="email" lay-verify="email" autoComplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">验证日期</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="date" id="date" lay-verify="date" placeholder="yyyy-MM-dd"
|
||||
autoComplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">自定义验证</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="password" name="password" lay-verify="pass" placeholder="请输入" autoComplete="off"
|
||||
class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">6 到 12 位字符</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">范围</label>
|
||||
<div class="layui-input-inline" style="width: 100px;">
|
||||
<input type="text" name="price_min" placeholder="¥" autoComplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid">-</div>
|
||||
<div class="layui-input-inline" style="width: 100px;">
|
||||
<input type="text" name="price_max" placeholder="¥" autoComplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">单行选择框</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="interest" lay-filter="aihao">
|
||||
<option value=""></option>
|
||||
<option value="0">写作</option>
|
||||
<option value="1" selected="">阅读</option>
|
||||
<option value="2">游戏</option>
|
||||
<option value="3">音乐</option>
|
||||
<option value="4">旅行</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">分组选择框</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="quiz">
|
||||
<option value="">请选择问题</option>
|
||||
<optgroup label="城市记忆">
|
||||
<option value="你工作的第一个城市">你工作的第一个城市</option>
|
||||
</optgroup>
|
||||
<optgroup label="学生时代">
|
||||
<option value="你的工号">你的工号</option>
|
||||
<option value="你最喜欢的老师">你最喜欢的老师</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">搜索选择框</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="modules" lay-verify="required" lay-search="">
|
||||
<option value="">直接选择或搜索选择</option>
|
||||
<option value="1">layer</option>
|
||||
<option value="2">form</option>
|
||||
<option value="3">layim</option>
|
||||
<option value="4">element</option>
|
||||
<option value="5">laytpl</option>
|
||||
<option value="6">upload</option>
|
||||
<option value="7">laydate</option>
|
||||
<option value="8">laypage</option>
|
||||
<option value="9">flow</option>
|
||||
<option value="10">util</option>
|
||||
<option value="11">code</option>
|
||||
<option value="12">tree</option>
|
||||
<option value="13">layedit</option>
|
||||
<option value="14">nav</option>
|
||||
<option value="15">tab</option>
|
||||
<option value="16">table</option>
|
||||
<option value="17">select</option>
|
||||
<option value="18">checkbox</option>
|
||||
<option value="19">switch</option>
|
||||
<option value="20">radio</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">联动选择框</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="quiz1">
|
||||
<option value="">请选择省</option>
|
||||
<option value="浙江" selected="">浙江省</option>
|
||||
<option value="你的工号">江西省</option>
|
||||
<option value="你最喜欢的老师">福建省</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-input-inline">
|
||||
<select name="quiz2">
|
||||
<option value="">请选择市</option>
|
||||
<option value="杭州">杭州</option>
|
||||
<option value="宁波" disabled="">宁波</option>
|
||||
<option value="温州">温州</option>
|
||||
<option value="温州">台州</option>
|
||||
<option value="温州">绍兴</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-input-inline">
|
||||
<select name="quiz3">
|
||||
<option value="">请选择县/区</option>
|
||||
<option value="西湖区">西湖区</option>
|
||||
<option value="余杭区">余杭区</option>
|
||||
<option value="拱墅区">临安市</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">此处只是演示联动排版,并未做联动交互</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">复选框</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" name="like[write]" title="写作">
|
||||
<input type="checkbox" name="like[read]" title="阅读" checked="">
|
||||
<input type="checkbox" name="like[game]" title="游戏">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item" pane="">
|
||||
<label class="layui-form-label">原始复选框</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" name="like1[write]" lay-skin="primary" title="写作" checked="">
|
||||
<input type="checkbox" name="like1[read]" lay-skin="primary" title="阅读">
|
||||
<input type="checkbox" name="like1[game]" lay-skin="primary" title="游戏" disabled="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">开关-默认关</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" name="close" lay-skin="switch" lay-text="ON|OFF">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">开关-默认开</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" checked="" name="open" lay-skin="switch" lay-filter="switchTest"
|
||||
lay-text="ON|OFF">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">单选框</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="sex" value="男" title="男" checked="">
|
||||
<input type="radio" name="sex" value="女" title="女">
|
||||
<input type="radio" name="sex" value="禁" title="禁用" disabled="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">普通文本域</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea placeholder="请输入内容" class="layui-textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button type="submit" class="layui-btn" lay-submit="" lay-filter="demo1">立即提交</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- 示例-970 -->
|
||||
<!--
|
||||
<ins class="adsbygoogle"
|
||||
style="display:inline-block;width:970px;height:90px"
|
||||
data-ad-client="ca-pub-6111334333458862"
|
||||
data-ad-slot="3820120620"></ins>
|
||||
-->
|
||||
|
||||
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 50px;">
|
||||
<legend>赋值和取值</legend>
|
||||
</fieldset>
|
||||
|
||||
<form class="layui-form" action="" lay-filter="example">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">输入框</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="username" lay-verify="title" autoComplete="off" placeholder="请输入标题"
|
||||
class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">密码框</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="password" name="password" placeholder="请输入密码" autoComplete="off"
|
||||
class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">选择框</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="interest" lay-filter="aihao">
|
||||
<option value=""></option>
|
||||
<option value="0">写作</option>
|
||||
<option value="1">阅读</option>
|
||||
<option value="2">游戏</option>
|
||||
<option value="3">音乐</option>
|
||||
<option value="4">旅行</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">复选框</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" name="like[write]" title="写作">
|
||||
<input type="checkbox" name="like[read]" title="阅读">
|
||||
<input type="checkbox" name="like[daze]" title="发呆">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">开关</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" name="close" lay-skin="switch" lay-text="ON|OFF">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">单选框</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="sex" value="男" title="男" checked="">
|
||||
<input type="radio" name="sex" value="女" title="女">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">文本域</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea placeholder="请输入内容" class="layui-textarea" name="desc"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button type="button" class="layui-btn layui-btn-normal" id="LAY-component-form-setval">赋值
|
||||
</button>
|
||||
<button type="button" class="layui-btn layui-btn-normal" id="LAY-component-form-getval">取值
|
||||
</button>
|
||||
<button type="submit" class="layui-btn" lay-submit="" lay-filter="demo1">立即提交</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 50px;">
|
||||
<legend>方框风格的表单集合</legend>
|
||||
</fieldset>
|
||||
<form class="layui-form layui-form-pane" action="">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">长输入框</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" autoComplete="off" placeholder="请输入标题" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">短输入框</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="username" lay-verify="required" placeholder="请输入" autoComplete="off"
|
||||
class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">日期选择</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="date" id="date1" autoComplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">行内表单</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="number" autoComplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">密码</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="password" name="password" placeholder="请输入密码" autoComplete="off"
|
||||
class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">请务必填写用户名</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">范围</label>
|
||||
<div class="layui-input-inline" style="width: 100px;">
|
||||
<input type="text" name="price_min" placeholder="¥" autoComplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid">-</div>
|
||||
<div class="layui-input-inline" style="width: 100px;">
|
||||
<input type="text" name="price_max" placeholder="¥" autoComplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">单行选择框</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="interest" lay-filter="aihao">
|
||||
<option value=""></option>
|
||||
<option value="0">写作</option>
|
||||
<option value="1" selected="">阅读</option>
|
||||
<option value="2">游戏</option>
|
||||
<option value="3">音乐</option>
|
||||
<option value="4">旅行</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">行内选择框</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="quiz1">
|
||||
<option value="">请选择省</option>
|
||||
<option value="浙江" selected="">浙江省</option>
|
||||
<option value="你的工号">江西省</option>
|
||||
<option value="你最喜欢的老师">福建省</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-input-inline">
|
||||
<select name="quiz2">
|
||||
<option value="">请选择市</option>
|
||||
<option value="杭州">杭州</option>
|
||||
<option value="宁波" disabled="">宁波</option>
|
||||
<option value="温州">温州</option>
|
||||
<option value="温州">台州</option>
|
||||
<option value="温州">绍兴</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-input-inline">
|
||||
<select name="quiz3">
|
||||
<option value="">请选择县/区</option>
|
||||
<option value="西湖区">西湖区</option>
|
||||
<option value="余杭区">余杭区</option>
|
||||
<option value="拱墅区">临安市</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item" pane="">
|
||||
<label class="layui-form-label">开关-开</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" checked="" name="open" lay-skin="switch" lay-filter="switchTest"
|
||||
title="开关">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item" pane="">
|
||||
<label class="layui-form-label">单选框</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="sex" value="男" title="男" checked="">
|
||||
<input type="radio" name="sex" value="女" title="女">
|
||||
<input type="radio" name="sex" value="禁" title="禁用" disabled="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">文本域</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea placeholder="请输入内容" class="layui-textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<button class="layui-btn" lay-submit="" lay-filter="demo2">跳转式提交</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<include file="/public/footer"/>
|
||||
<script>
|
||||
layui.use(['layer'], function () {
|
||||
var $ = layui.jquery;
|
||||
var layer = layui.layer;
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
315
plugin/developer/app/admin/view/developer/example/table.html
Normal file
315
plugin/developer/app/admin/view/developer/example/table.html
Normal file
@@ -0,0 +1,315 @@
|
||||
<include file="/public/header"/>
|
||||
<!-- // 重定位style -->
|
||||
<!--Developer-->
|
||||
<div class="layui-fluid ">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<div id="demo"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-row layui-col-space10">
|
||||
|
||||
<div class="layui-col-md4">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">我的任务</div>
|
||||
<div class="layui-card-body task" style="height: 260px">
|
||||
<table class="layui-table" lay-skin="nob">
|
||||
<colgroup>
|
||||
<col>
|
||||
<col>
|
||||
<col width="250">
|
||||
<col>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>发起人</th>
|
||||
<th>发起时间</th>
|
||||
<th>当前进度</th>
|
||||
<th> 状态</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>权栈</td>
|
||||
<td>2021/01/28 10:23:46</td>
|
||||
<td>
|
||||
<div class="layui-progress">
|
||||
<div class="layui-progress-bar layui-bg-blue" lay-percent="92%"
|
||||
style="width: 92%;"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="layui-badge layui-bg-blue" lay-tips="这里可以增加额外的提示信息!">已完成</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>张爱玲</td>
|
||||
<td>2021/01/28 10:23:46</td>
|
||||
<td>
|
||||
<div class="layui-progress">
|
||||
<div class="layui-progress-bar layui-bg-orange" lay-percent="30%"
|
||||
style="width: 30%;"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="layui-badge layui-bg-orange" lay-tips="当前任务出现BUG急需修复!">待修复</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>岳飞</td>
|
||||
<td>2021/01/28 10:23:46</td>
|
||||
<td>
|
||||
<div class="layui-progress">
|
||||
<div class="layui-progress-bar layui-bg-green" lay-percent="83%"
|
||||
style="width: 83%;"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="layui-badge layui-bg-green">进行中</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>张三丰</td>
|
||||
<td>2021/01/28 10:23:46</td>
|
||||
<td>
|
||||
<div class="layui-progress">
|
||||
<div class="layui-progress-bar layui-bg-red" lay-percent="54%"
|
||||
style="width: 54%;"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="layui-badge">已延期</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>乔峰</td>
|
||||
<td>2021/01/28 10:23:46</td>
|
||||
<td>
|
||||
<div class="layui-progress">
|
||||
<div class="layui-progress-bar layui-bg-cyan" lay-percent="10%"
|
||||
style="width: 10%;"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="layui-badge layui-bg-cyan">未开始</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-col-md4">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">版本信息</div>
|
||||
<div class="layui-card-body">
|
||||
<table class="layui-table">
|
||||
<colgroup>
|
||||
<col width="90">
|
||||
<col>
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>当前版本</td>
|
||||
<td><a href="http://www.swiftadmin.net/" target="_blank">{:release()}</a>
|
||||
<a href="https://www.swiftadmin.net/download/" target="_blank"
|
||||
style="padding-left: 10px;">日志</a>
|
||||
<a href="javascript:;" sa-event="update" style="padding-left: 5px;">检查更新</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>前端框架</td>
|
||||
<td>layui-v2.6-Fix / 多语言 / 多布局 / 前端鉴权</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>后端框架</td>
|
||||
<td>ThinkPHP6lts</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PHP版本</td>
|
||||
<td>支持>=7.3 &8 QQ群:68221484</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>主要特色</td>
|
||||
<td><font color="red">ant design</font> / 零门槛 / 响应式 / 清爽</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>获取渠道</td>
|
||||
<td style="padding-bottom: 0;">
|
||||
<div class="layui-btn-container">
|
||||
<div class="layui-col-md4"><a href="https://www.swiftadmin.net/authorize.html"
|
||||
target="_blank" class="layui-btn layui-btn-danger">获取授权</a>
|
||||
</div>
|
||||
<div class="layui-col-md4">
|
||||
<a href="https://www.swiftadmin.net/download/" target="_blank" class="layui-btn">立即下载</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-col-md4">
|
||||
<div class="layui-card" id="console">
|
||||
<div class="layui-card-header">小组成员</div>
|
||||
<div class="layui-card-body" style="height: 260px">
|
||||
<div class="console-user-group">
|
||||
<img src="__ADMINIMAGES__/user.png" class="console-user-group-head" alt=""/>
|
||||
<div class="console-user-group-name">周星星</div>
|
||||
<div class="console-user-group-desc">产品负责人</div>
|
||||
<span class="layui-badge layui-badge-green">在线</span>
|
||||
</div>
|
||||
<div class="console-user-group">
|
||||
<img src="__ADMINIMAGES__/user.png" class="console-user-group-head" alt=""/>
|
||||
<div class="console-user-group-name">周星星</div>
|
||||
<div class="console-user-group-desc">项目负责人</div>
|
||||
<span class="layui-badge layui-badge-green">在线</span>
|
||||
</div>
|
||||
<div class="console-user-group">
|
||||
<img src="__ADMINIMAGES__/user.png" class="console-user-group-head" alt=""/>
|
||||
<div class="console-user-group-name">周星星</div>
|
||||
<div class="console-user-group-desc">产品负责人</div>
|
||||
<span class="layui-badge layui-badge-red">离线</span>
|
||||
</div>
|
||||
<div class="console-user-group">
|
||||
<img src="__ADMINIMAGES__/user.png" class="console-user-group-head" alt=""/>
|
||||
<div class="console-user-group-name">周星星</div>
|
||||
<div class="console-user-group-desc">测试负责人</div>
|
||||
<span class="layui-badge layui-badge-red">离线</span>
|
||||
</div>
|
||||
<div class="console-user-group">
|
||||
<img src="__ADMINIMAGES__/user.png" class="console-user-group-head" alt=""/>
|
||||
<div class="console-user-group-name">周星星</div>
|
||||
<div class="console-user-group-desc">测试负责人</div>
|
||||
<span class="layui-badge layui-badge-red">离线</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<include file="/public/footer"/>
|
||||
<script>
|
||||
layui.use(['layer','table'], function () {
|
||||
var $ = layui.jquery;
|
||||
var layer = layui.layer;
|
||||
var table = layui.table;
|
||||
|
||||
//展示已知数据
|
||||
table.render({
|
||||
elem: '#demo'
|
||||
,cols: [[ //标题栏
|
||||
{type: 'checkbox', width: 50},
|
||||
,{field: 'id', title: 'ID', width: 80, sort: true}
|
||||
,{field: 'username', title: '用户名', width: 120}
|
||||
,{field: 'email', title: '邮箱', minWidth: 150}
|
||||
,{field: 'sign', title: '签名', minWidth: 160}
|
||||
,{field: 'sex', title: '性别', width: 80}
|
||||
,{field: 'city', title: '城市', width: 100}
|
||||
,{field: 'experience', title: '积分', width: 80, sort: true}
|
||||
]]
|
||||
,data: [{
|
||||
"id": "10001"
|
||||
,"username": "杜甫"
|
||||
,"email": "test@email.com"
|
||||
,"sex": "男"
|
||||
,"city": "浙江杭州"
|
||||
,"sign": "人生恰似一场修行"
|
||||
,"experience": "116"
|
||||
,"ip": "192.168.0.8"
|
||||
,"logins": "108"
|
||||
,"joinTime": "2016-10-14"
|
||||
}, {
|
||||
"id": "10002"
|
||||
,"username": "李白"
|
||||
,"email": "test@email.com"
|
||||
,"sex": "男"
|
||||
,"city": "浙江杭州"
|
||||
,"sign": "人生恰似一场修行"
|
||||
,"experience": "12"
|
||||
,"ip": "192.168.0.8"
|
||||
,"logins": "106"
|
||||
,"joinTime": "2016-10-14"
|
||||
,"LAY_CHECKED": true
|
||||
}, {
|
||||
"id": "10003"
|
||||
,"username": "王勃"
|
||||
,"email": "test@email.com"
|
||||
,"sex": "男"
|
||||
,"city": "浙江杭州"
|
||||
,"sign": "人生恰似一场修行"
|
||||
,"experience": "65"
|
||||
,"ip": "192.168.0.8"
|
||||
,"logins": "106"
|
||||
,"joinTime": "2016-10-14"
|
||||
}, {
|
||||
"id": "10004"
|
||||
,"username": "贤心"
|
||||
,"email": "test@email.com"
|
||||
,"sex": "男"
|
||||
,"city": "浙江杭州"
|
||||
,"sign": "人生恰似一场修行"
|
||||
,"experience": "666"
|
||||
,"ip": "192.168.0.8"
|
||||
,"logins": "106"
|
||||
,"joinTime": "2016-10-14"
|
||||
}, {
|
||||
"id": "10005"
|
||||
,"username": "贤心"
|
||||
,"email": "test@email.com"
|
||||
,"sex": "男"
|
||||
,"city": "浙江杭州"
|
||||
,"sign": "人生恰似一场修行"
|
||||
,"experience": "86"
|
||||
,"ip": "192.168.0.8"
|
||||
,"logins": "106"
|
||||
,"joinTime": "2016-10-14"
|
||||
}, {
|
||||
"id": "10006"
|
||||
,"username": "贤心"
|
||||
,"email": "test@email.com"
|
||||
,"sex": "男"
|
||||
,"city": "浙江杭州"
|
||||
,"sign": "人生恰似一场修行"
|
||||
,"experience": "12"
|
||||
,"ip": "192.168.0.8"
|
||||
,"logins": "106"
|
||||
,"joinTime": "2016-10-14"
|
||||
}, {
|
||||
"id": "10007"
|
||||
,"username": "贤心"
|
||||
,"email": "test@email.com"
|
||||
,"sex": "男"
|
||||
,"city": "浙江杭州"
|
||||
,"sign": "人生恰似一场修行"
|
||||
,"experience": "16"
|
||||
,"ip": "192.168.0.8"
|
||||
,"logins": "106"
|
||||
,"joinTime": "2016-10-14"
|
||||
}, {
|
||||
"id": "10008"
|
||||
,"username": "贤心"
|
||||
,"email": "test@email.com"
|
||||
,"sex": "男"
|
||||
,"city": "浙江杭州"
|
||||
,"sign": "人生恰似一场修行"
|
||||
,"experience": "106"
|
||||
,"ip": "192.168.0.8"
|
||||
,"logins": "106"
|
||||
,"joinTime": "2016-10-14"
|
||||
}]
|
||||
//,skin: 'line' //表格风格
|
||||
,even: true
|
||||
,page: true //是否显示分页
|
||||
,limits: [5, 7, 10]
|
||||
//,limit: 5 //每页默认显示的数量
|
||||
});
|
||||
});
|
||||
</script>
|
||||
477
plugin/developer/app/admin/view/developer/generate/add.html
Normal file
477
plugin/developer/app/admin/view/developer/generate/add.html
Normal file
@@ -0,0 +1,477 @@
|
||||
<include file="/public/header" />
|
||||
<!--Developer-->
|
||||
<style>
|
||||
.layui-form-checkbox[lay-skin="primary"] span {
|
||||
padding-right: 13px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
.layui-form-item .layui-input-inline {
|
||||
width: 138px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div class="layui-fluid" style="display: none">
|
||||
<form class="layui-form layui-card">
|
||||
<div class="layui-card-header">基础配置</div>
|
||||
<div class="layui-card-body" style="padding-bottom:100px;">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('数据库表')}</label>
|
||||
<div class="layui-input-inline">
|
||||
<select id="table" name="table" lay-verify="required" <notempty name="$data['table']"> disabled </notempty>
|
||||
lay-search lay-filter="selectTable" data-type="table" >
|
||||
<option value="">{:__('请选择数据表')}</option>
|
||||
<volist name="$tables" id="vo">
|
||||
<option value="{$vo}" <if condition="$vo eq $data['table']"> selected </if> >{$vo}</option>
|
||||
</volist>
|
||||
</select>
|
||||
</div>
|
||||
<label class="layui-form-label">{:__('所属插件')}</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="plugin">
|
||||
<option value="">{:__('请选择开发的插件')}</option>
|
||||
<volist name="pluginList" id="vo">
|
||||
<option value="{$vo.name}" <if condition="$vo['name'] eq $data['plugin']"> selected </if>
|
||||
>{$vo.title}</option>
|
||||
</volist>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">
|
||||
<font color="red">* </font>{:__('菜单名称')}
|
||||
</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="title" type="text" class="layui-input" lay-verify="required"
|
||||
placeholder="{:__('请输入菜单名称')}">
|
||||
</div>
|
||||
<label class="layui-form-label">{:__('顶级菜单')}</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="pid">
|
||||
<option value="">{:__('请选择顶级菜单')}</option>
|
||||
<php>
|
||||
$where['pid'] = 0;
|
||||
$rules = \think\facade\Db::name('admin_rules')->where($where)->select();
|
||||
</php>
|
||||
<volist name="$rules" id="vo">
|
||||
<option value="{$vo.id}" <if condition="$vo['id'] eq $data['pid']"> selected </if>
|
||||
>{$vo.title}</option>
|
||||
</volist>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">
|
||||
<span style="color: red; ">* </span>{:__('控制器路径')}
|
||||
</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="controller" id="controller" lay-verify="required" type="text" class="layui-input"
|
||||
placeholder="{:__('请输入控制器路径')}">
|
||||
</div>
|
||||
<label class="layui-form-label">
|
||||
<span style="color: red; ">* </span>{:__('菜单图标')}
|
||||
</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="icon" type="text" id="iconPicker" class="layui-input"
|
||||
placeholder="{:__('layui-icon-app')}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">
|
||||
<span style="color: red; ">* </span>{:__('其他选项')}
|
||||
</label>
|
||||
<div class="layui-input-block" style="position:relative;">
|
||||
<input type="checkbox" lay-skin="primary" name="create" title="生成菜单" value="1">
|
||||
<input type="checkbox" lay-skin="primary" name="auth" title="菜单鉴权" value="1">
|
||||
<input type="checkbox" lay-skin="primary" name="force" title="强制覆盖" value="1">
|
||||
<input type="checkbox" lay-skin="primary" name="global" title="全局模型类" value="1">
|
||||
<i class="layui-icon layui-icon-tips" style="position:absolute; top:4px;"
|
||||
lay-tips="默认模型生成在app/admin/model目录下<br>* 选中后模型将会生成在app/common/model目录下" data-offset="1"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('列表字段')}</label>
|
||||
<div class="layui-input-inline" style="width: 52%;">
|
||||
<div class="listField" name="listField"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('关联模型')}</label>
|
||||
<div class="layui-input-block">
|
||||
<table class="layui-table" id="relationModel">
|
||||
<thead>
|
||||
<tr>
|
||||
<th lay-data="{field:'table', width:300}">数据模型/表</th>
|
||||
<th lay-data="{field:'style', width:150}">关联方式/HasOne</th>
|
||||
<th lay-data="{field:'foreignKey'}">关联外键/foreignKey</th>
|
||||
<th lay-data="{field:'localKey'}">关联主键/localKey</th>
|
||||
<th lay-data="{field:'Field'}">字段显示/Field</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="relationBody"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<label class="layui-form-label"></label>
|
||||
<div class="layui-input-inline">
|
||||
<button class="layui-btn layui-btn-sm layui-relation-add" type="button">添加</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('控制器/功能')}</label>
|
||||
<div class="layui-input-block">
|
||||
<table class="layui-table" lay-filter="parse-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th lay-data="{field:'name'}">名称</th>
|
||||
<th lay-data="{field:'controller'}">控制器</th>
|
||||
<th lay-data="{field:'route'}">路由</th>
|
||||
<th lay-data="{field:'view'}">视图模板</th>
|
||||
<th lay-data="{field:'type'}">类型</th>
|
||||
<th lay-data="{field:'auth'}">鉴权</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="parse-table">
|
||||
<tr>
|
||||
<td><input type="text" name="menus[title][]" class="layui-input" value="查看"></td>
|
||||
<td><input type="text" name="menus[router][]" data-type="index"
|
||||
class="layui-input change-router"></td>
|
||||
<td><input type="text" name="menus[route][]" disabled
|
||||
class="layui-input layui-disabled"></td>
|
||||
<td><input type="text" name="menus[template][]" class="layui-input"
|
||||
placeholder="{:__('默认')}"></td>
|
||||
<td>
|
||||
<input name="menus[type][]" type="text" hidden value="1">
|
||||
<span class="layui-badge layui-badge-blue ruletype">{:__("按钮")}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input name="menus[auth][]" type="text" hidden value="1">
|
||||
<span class="layui-badge layui-badge-blue ruleauth">{:__("是")}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="text" name="menus[title][]" class="layui-input" value="添加"></td>
|
||||
<td><input type="text" name="menus[router][]" data-type="add"
|
||||
class="layui-input change-router"></td>
|
||||
<td><input type="text" name="menus[route][]" disabled
|
||||
class="layui-input layui-disabled"></td>
|
||||
<td><input type="text" name="menus[template][]" class="layui-input"
|
||||
placeholder="{:__('默认')}"></td>
|
||||
<td>
|
||||
<input name="menus[type][]" type="text" hidden value="1">
|
||||
<span class="layui-badge layui-badge-blue ruletype">{:__("按钮")}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input name="menus[auth][]" type="text" hidden value="1">
|
||||
<span class="layui-badge layui-badge-blue ruleauth">{:__("是")}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="text" name="menus[title][]" class="layui-input" value="编辑"></td>
|
||||
<td><input type="text" name="menus[router][]" data-type="edit"
|
||||
class="layui-input change-router"></td>
|
||||
<td><input type="text" name="menus[route][]" disabled
|
||||
class="layui-input layui-disabled"></td>
|
||||
<td><input type="text" name="menus[template][]" class="layui-input"
|
||||
placeholder="{:__('默认')}"></td>
|
||||
<td>
|
||||
<input name="menus[type][]" type="text" hidden value="1">
|
||||
<span class="layui-badge layui-badge-blue ruletype">{:__("按钮")}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input name="menus[auth][]" type="text" hidden value="1">
|
||||
<span class="layui-badge layui-badge-blue ruleauth">{:__("是")}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="text" name="menus[title][]" class="layui-input" value="删除"></td>
|
||||
<td><input type="text" name="menus[router][]" data-type="del"
|
||||
class="layui-input change-router"></td>
|
||||
<td><input type="text" name="menus[route][]" disabled
|
||||
class="layui-input layui-disabled"></td>
|
||||
<td><input type="text" name="menus[template][]" class="layui-input"
|
||||
placeholder="{:__('默认')}"></td>
|
||||
<td>
|
||||
<input name="menus[type][]" type="text" hidden value="2">
|
||||
<span class="layui-badge layui-badge-green ruletype">{:__("接口")}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input name="menus[auth][]" type="text" hidden value="1">
|
||||
<span class="layui-badge layui-badge-blue ruleauth">{:__("是")}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="text" name="menus[title][]" class="layui-input" value="状态"></td>
|
||||
<td><input type="text" name="menus[router][]" data-type="status"
|
||||
class="layui-input change-router"></td>
|
||||
<td><input type="text" name="menus[route][]" disabled
|
||||
class="layui-input layui-disabled"></td>
|
||||
<td><input type="text" name="menus[template][]" class="layui-input"
|
||||
placeholder="{:__('默认')}"></td>
|
||||
<td>
|
||||
<input name="menus[type][]" type="text" hidden value="2">
|
||||
<span class="layui-badge layui-badge-green ruletype">{:__("接口")}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input name="menus[auth][]" type="text" hidden value="1">
|
||||
<span class="layui-badge layui-badge-blue ruleauth">{:__("是")}</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-footer layui-form-footer">
|
||||
<button class="layui-btn layui-btn-primary" type="button" sa-event="closeDialog">{:__('取消')}</button>
|
||||
<button class="layui-btn" lay-filter="submitIframe" type="button" lay-submit>{:__('提交')}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script type="text/html" id="relationHtml">
|
||||
<tr>
|
||||
<td>
|
||||
<div class="layui-input-inline" >
|
||||
<select name="relation_table[]" lay-filter="relationTable" lay-verify="required">
|
||||
<option value="">{:__('请选择数据表')}</option>
|
||||
<volist name="$tables" id="vo">
|
||||
<option value="{$vo}" >{$vo}</option>
|
||||
</volist>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="layui-input-inline" >
|
||||
<select name="relation_style[]" lay-verify="required" >
|
||||
<option value="">{:__('请选择关联方式')}</option>
|
||||
<option value="hasOne">hasOne</option>
|
||||
<option value="hasMany">hasMany</option>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="layui-input-inline" >
|
||||
<select name="foreignKey[]" class="foreignKey" lay-verify="required" >
|
||||
<option value="">{:__('请选择关联外键')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="layui-input-inline" >
|
||||
<select name="localKey[]" class="localKey" lay-verify="required" >
|
||||
<option value="">{:__('请选择关联主键')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="layui-input-inline" >
|
||||
<!-- // 隐藏关联字段表单 -->
|
||||
<div class="relationField"></div>
|
||||
</div>
|
||||
<span class="layui-relation-delete"><i class="layui-icon layui-icon-close"></i></span>
|
||||
</td>
|
||||
</tr>
|
||||
</script>
|
||||
|
||||
<include file="/public/static" />
|
||||
<include file="/public/footer" />
|
||||
|
||||
<script>
|
||||
layui.use(['form', 'jquery', 'admin', 'iconPicker'], function () {
|
||||
let form = layui.form;
|
||||
let $ = layui.jquery;
|
||||
let admin = layui.admin;
|
||||
let iconPicker = layui.iconPicker;
|
||||
let localFields = [];
|
||||
let fieldUrl = "{:url('/developer/Generate/queryFields')}";
|
||||
|
||||
form.on('select(selectTable)', function (data) {
|
||||
var route = data.value.split('_').slice(1).join('_');
|
||||
localFields = admin.event.ajax(fieldUrl, { table: route });
|
||||
route = route.substring(0,1).toUpperCase() + route.substring(1);
|
||||
route = route.replace(/\_(\w)/g, (_, letter) => letter.toUpperCase());
|
||||
var controller = '/' + route + '/';
|
||||
syncChengeController(controller);
|
||||
$('#controller').val(controller + 'index');
|
||||
// 重载字段
|
||||
$('.localKey').each(function (key, elem) {
|
||||
$(elem).empty();
|
||||
$(elem).append(new Option('请选择关联主键', ''));
|
||||
for (let index = 0; index < localFields.length; index++) {
|
||||
const element = localFields[index];
|
||||
$(elem).append(new Option(element.value, element.value));
|
||||
}
|
||||
});
|
||||
|
||||
form.render();
|
||||
xmRender('.listField', 'listField', localFields);
|
||||
})
|
||||
|
||||
// 改变控制器
|
||||
$('#controller').keyup(function (elem) {
|
||||
syncChengeController($(this).val().substring(0, $(this).val().lastIndexOf('/') + 1));
|
||||
})
|
||||
|
||||
var syncChengeController = function (route = null) {
|
||||
$('.change-router').each(function (index, elem) {
|
||||
var type = $(elem).data('type');
|
||||
var router = route + type;
|
||||
$(elem).val(router);
|
||||
$(elem).parent('td').next().find('input').val(router.substring(1).replaceAll('/', ':'));
|
||||
})
|
||||
}
|
||||
|
||||
$('.change-router').keyup(function(e) {
|
||||
var route = $(this).val().substring(1).replace('/', ':');
|
||||
$(this).parent('td').next().find('input').val(route);
|
||||
})
|
||||
|
||||
// 渲染字段显示
|
||||
var xmRender = function (elem, name = 'listField', field = [], init = []) {
|
||||
xmSelect.render({
|
||||
el: elem,
|
||||
name: name,
|
||||
theme: {
|
||||
color: '#1890ff',
|
||||
},
|
||||
data: field,
|
||||
initValue: init
|
||||
})
|
||||
}
|
||||
|
||||
// 增加关联选项
|
||||
$('.layui-relation-add').click(function (params) {
|
||||
var html = $('#relationHtml').html();
|
||||
$('#relationBody').append(html);
|
||||
form.render();
|
||||
})
|
||||
|
||||
// 关联表操作
|
||||
form.on('select(relationTable)', function (data) {
|
||||
var index = $(this).parents('tr').index();
|
||||
var xm_obj = $('.relationField:eq(' + index + ')');
|
||||
var foreignElem = $('.foreignKey:eq(' + index + ')');
|
||||
var localElem = $('.localKey:eq(' + index + ')');
|
||||
var route = data.value.split('_').slice(1).join('_');
|
||||
var foreignfiled = admin.event.ajax(fieldUrl, { table: route }, false);
|
||||
|
||||
console.log(foreignfiled);
|
||||
|
||||
// 重载关联外键
|
||||
foreignElem.empty();
|
||||
foreignElem.append(new Option('请选择关联外键', ''));
|
||||
for (let index = 0; index < foreignfiled.length; index++) {
|
||||
const element = foreignfiled[index];
|
||||
foreignElem.append(new Option(element.value, element.value));
|
||||
}
|
||||
|
||||
// 重载关联主键
|
||||
localElem.empty();
|
||||
localElem.append(new Option('请选择关联主键', ''));
|
||||
for (let index = 0; index < localFields.length; index++) {
|
||||
const element = localFields[index];
|
||||
localElem.append(new Option(element.value, element.value));
|
||||
}
|
||||
|
||||
form.render();
|
||||
multi_xml_func(index, foreignfiled, xm_obj);
|
||||
})
|
||||
|
||||
// 管理XM对象集合
|
||||
var xm_tree = [];
|
||||
var multi_xml_func = function (index, field, xm_obj, init = []) {
|
||||
if (xm_tree[index] !== undefined) {
|
||||
xm_tree[index].update({ data: field });
|
||||
} else {
|
||||
xm_tree[index] = xmSelect.render({
|
||||
el: xm_obj[0],
|
||||
name: 'relationField[' + index + ']',
|
||||
theme: {
|
||||
color: '#1890ff',
|
||||
},
|
||||
data: field,
|
||||
initValue: init,
|
||||
on: function (data) {
|
||||
let f = [];
|
||||
data.arr.forEach(v => {
|
||||
f.push(v.value);
|
||||
});
|
||||
xm_obj.prev().val(f.join());
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 删除关联元素
|
||||
$('body').on('click', '.layui-relation-delete i', function (elem) {
|
||||
if ($('#relationModel tbody tr').length) {
|
||||
$(this).parents('tr').remove();
|
||||
}
|
||||
})
|
||||
|
||||
// 修改鉴权操作
|
||||
$('.ruleauth').click(function (e) {
|
||||
var that = $(this), prev = that.prev();
|
||||
var val = prev.val();
|
||||
if (val >= 1) {
|
||||
that.addClass('layui-badge-red').text('否');
|
||||
} else {
|
||||
that.removeClass('layui-badge-red').text('是');
|
||||
}
|
||||
val >= 1 ? prev.val(0) : prev.val(1);
|
||||
})
|
||||
|
||||
// 切换类型
|
||||
$('.ruletype').click(function (e) {
|
||||
var that = $(this), prev = that.prev(),
|
||||
arr = {
|
||||
1: {
|
||||
value: '1',
|
||||
title: '按钮',
|
||||
class: 'layui-badge-blue'
|
||||
},
|
||||
2: {
|
||||
value: '2',
|
||||
title: '接口',
|
||||
class: 'layui-badge-green'
|
||||
},
|
||||
3: {
|
||||
value: '3',
|
||||
title: '系统',
|
||||
class: 'layui-badge-red'
|
||||
}
|
||||
};
|
||||
var val = Number(prev.val()) + 1;
|
||||
|
||||
if (val > 3) {
|
||||
val = 1;
|
||||
}
|
||||
$(that).prop('class', 'layui-badge');
|
||||
$(that).addClass(arr[val].class);
|
||||
$(that).text(arr[val].title);
|
||||
$(prev).val(arr[val].value);
|
||||
})
|
||||
|
||||
// 图标选择
|
||||
iconPicker.render({
|
||||
elem: '#iconPicker',
|
||||
type: 'fontClass',
|
||||
search: true,
|
||||
cellWidth: "14%",
|
||||
page: true,
|
||||
limit: 20,
|
||||
click: function (data) {
|
||||
$('#iconPicker').val(data.icon);
|
||||
},
|
||||
success: function (d) { }
|
||||
});
|
||||
|
||||
// 初始化元素
|
||||
xmRender('.listField');
|
||||
$('.layui-fluid').show();
|
||||
})
|
||||
</script>
|
||||
486
plugin/developer/app/admin/view/developer/generate/edit.html
Normal file
486
plugin/developer/app/admin/view/developer/generate/edit.html
Normal file
@@ -0,0 +1,486 @@
|
||||
<include file="/public/header" />
|
||||
<!--Developer-->
|
||||
<style>
|
||||
.layui-form-checkbox[lay-skin="primary"] span {
|
||||
padding-right: 13px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
.layui-form-item .layui-input-inline {
|
||||
width: 138px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
<div class="layui-fluid" style="display: none">
|
||||
<form class="layui-form layui-card">
|
||||
<div class="layui-card-header">基础配置</div>
|
||||
<div class="layui-card-body" style="padding-bottom:100px;">
|
||||
<input type="text" id="id" name="id" value="{$data.id}" hidden="">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('数据库表')}</label>
|
||||
<div class="layui-input-inline">
|
||||
<select id="table" name="table" lay-verify="required" <notempty name="$data['table']"> disabled</notempty> lay-search lay-filter="selectTable" data-type="table" >
|
||||
<option value="">{:__('请选择数据表')}</option>
|
||||
<volist name="tables" id="vo">
|
||||
<option value="{$vo}" <if condition="$vo eq $data['table']"> selected </if> >{$vo}</option>
|
||||
</volist>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label class="layui-form-label">{:__('所属插件')}</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="plugin">
|
||||
<option value="">{:__('请选择开发的插件')}</option>
|
||||
<volist name="pluginList" id="vo">
|
||||
<option value="{$vo.name}" <if condition="$vo['name'] eq $data['plugin']"> selected </if>
|
||||
>{$vo.title}</option>
|
||||
</volist>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">
|
||||
<font color="red">* </font>{:__('菜单名称')}
|
||||
</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="title" type="text" class="layui-input" lay-verify="required" value="{$data.title}"
|
||||
placeholder="{:__('请输入菜单名称')}">
|
||||
</div>
|
||||
<label class="layui-form-label">{:__('顶级菜单')}</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="pid">
|
||||
<option value="">{:__('请选择顶级菜单')}</option>
|
||||
<php>
|
||||
$rules = \think\facade\Db::name('admin_rules')->where('pid',0)->select();
|
||||
</php>
|
||||
<volist name="$rules" id="vo">
|
||||
<option value="{$vo.id}" <if condition="$vo['id'] eq $data['pid']"> selected </if>
|
||||
>{$vo.title}</option>
|
||||
</volist>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">
|
||||
<font color="red">* </font>{:__('控制器路径')}
|
||||
</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="controller" id="controller" lay-verify="required" type="text"
|
||||
value="{$data.controller}" class="layui-input" placeholder="{:__('请输出控制器路径')}">
|
||||
</div>
|
||||
<label class="layui-form-label">
|
||||
<font color="red">* </font>{:__('菜单图标')}
|
||||
</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="icon" type="text" id="iconPicker" class="iconPicker layui-input" value="{$data.icon}"
|
||||
placeholder="{:__('layui-icon-app')}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">
|
||||
<font color="red">* </font>{:__('其他选项')}
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" name="create" lay-skin="primary" title="生成菜单" <if
|
||||
condition="($data['create'] == '') OR ($data['create'] == 1)">checked=""</if> value="1">
|
||||
<input type="checkbox" name="auth" lay-skin="primary" title="菜单鉴权" <if
|
||||
condition="($data['auth'] == '') OR ($data['force'] == 1)">checked=""</if> value="1">
|
||||
<input type="checkbox" name="force" lay-skin="primary" title="强制覆盖" <if
|
||||
condition="($data['force'] == '') OR ($data['force'] == 1)">checked=""</if> value="1">
|
||||
<input type="checkbox" name="global" lay-skin="primary" title="全局模型类" <eq name="$data['global']"
|
||||
value="1">checked=""</eq> value="1" >
|
||||
<i class="layui-icon layui-icon-tips" style="position:absolute; top:3px;color: #1890ff;"
|
||||
lay-tips="默认模型生成在app/admin/model目录下<br>* 选中后模型将会生成在app/common/model目录下" data-offset="1"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('列表字段')}</label>
|
||||
<div class="layui-input-inline" style="width: 52%;">
|
||||
<div class="listField" name="listField"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('关联模型')}</label>
|
||||
<div class="layui-input-block">
|
||||
<table class="layui-table" id="relationModel">
|
||||
<thead>
|
||||
<tr>
|
||||
<th lay-data="{field:'table', width:300}">数据模型/表</th>
|
||||
<th lay-data="{field:'style', width:150}">关联方式/HasOne</th>
|
||||
<th lay-data="{field:'foreignKey'}">关联外键/foreignKey</th>
|
||||
<th lay-data="{field:'localKey'}">关联主键/localKey</th>
|
||||
<th lay-data="{field:'Field'}">字段显示/Field</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="relationBody">
|
||||
<volist name="$data['relation']" id="rel">
|
||||
<tr>
|
||||
<td>
|
||||
<div class="layui-input-inline">
|
||||
<select name="relation_table[]" multiple lay-filter="relationTable"
|
||||
data-type="relation">
|
||||
<option>{:__('请选择数据表')}</option>
|
||||
<volist name="$tables" id="vo">
|
||||
<option value="{$vo}" <if condition="$vo eq $rel['table']"> selected
|
||||
</if> >{$vo}</option>
|
||||
</volist>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="layui-input-inline">
|
||||
<select name="relation_style[]">
|
||||
<option>{:__('请选择关联方式')}</option>
|
||||
<option value="hasOne" <eq name="$rel['style']" value="hasOne">selected
|
||||
</eq> >hasOne</option>
|
||||
<option value="hasMany" <eq name="$rel['style']" value="hasMany">
|
||||
selected</eq> >hasMany</option>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="layui-input-inline">
|
||||
<php> $fields = \think\facade\Db::getFields($rel['table']);</php>
|
||||
<select name="foreignKey[]" class="foreignKey">
|
||||
<option>{:__('请选择关联外键')}</option>
|
||||
<volist name="$fields" id="field">
|
||||
<option value="{$field.name}" <if
|
||||
condition="$field['name'] eq $rel['foreignKey']"> selected </if>
|
||||
>{$field.name}</option>
|
||||
</volist>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="layui-input-inline">
|
||||
<php> $localFields = \think\facade\Db::getFields($data['table']);</php>
|
||||
<select name="localKey[]" class="localKey">
|
||||
<option>{:__('请选择关联主键')}</option>
|
||||
<volist name="$localFields" id="field">
|
||||
<option value="{$field.name}" <if
|
||||
condition="$field['name'] eq $rel['localKey']"> selected </if>
|
||||
>{$field.name}</option>
|
||||
</volist>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="layui-input-inline">
|
||||
<?php
|
||||
$html = [];
|
||||
foreach ($fields as $key => $value) {
|
||||
$html[] = [
|
||||
'name' => $value['name'],
|
||||
'value' => $value['name']
|
||||
];
|
||||
}
|
||||
?>
|
||||
<div class="relationField"></div>
|
||||
<div class="relationSource layui-hide"><?php echo json_encode($html)?></div>
|
||||
<div class="relationInit layui-hide"><?php echo trim($rel['relationField'])?></div>
|
||||
</div>
|
||||
<span class="layui-relation-delete"><i class="layui-icon layui-icon-close"></i></span>
|
||||
</td>
|
||||
</tr>
|
||||
</volist>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<label class="layui-form-label"></label>
|
||||
<div class="layui-input-inline">
|
||||
<button class="layui-btn layui-btn-sm layui-relation-add" type="button">添加</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('控制器/功能')}</label>
|
||||
<div class="layui-input-block">
|
||||
<table class="layui-table" lay-filter="parse-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th lay-data="{field:'name'}">名称</th>
|
||||
<th lay-data="{field:'controller'}">控制器</th>
|
||||
<th lay-data="{field:'route'}">路由</th>
|
||||
<th lay-data="{field:'view'}">视图模板</th>
|
||||
<th lay-data="{field:'type'}">类型</th>
|
||||
<th lay-data="{field:'auth'}">鉴权</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="parse-table">
|
||||
<volist name="$data['menus']" id="rekey">
|
||||
<tr>
|
||||
<td><input type="text" name="menus[title][]" class="layui-input"
|
||||
value="{$rekey.title}"></td>
|
||||
<td>
|
||||
<input type="text" name="menus[router][]" class="layui-input change-router" value="{$rekey.router}">
|
||||
</td>
|
||||
<td><input type="text" name="menus[route][]" disabled
|
||||
class="layui-input layui-disabled" value="{$rekey.route}"></td>
|
||||
<td>
|
||||
<input type="text" name="menus[template][]" class="layui-input"
|
||||
value="{$rekey.template|default='默认'}" placeholder="{:__('默认')}">
|
||||
</td>
|
||||
<td>
|
||||
<input name="menus[type][]" type="text" hidden value="{$rekey.type}">
|
||||
<if condition="$rekey['type'] == 1">
|
||||
<span class="layui-badge layui-badge-blue ruletype">{:__("按钮")}</span>
|
||||
<elseif condition="$rekey['type'] == 2">
|
||||
<span class="layui-badge layui-badge-green ruletype">{:__("接口")}</span>
|
||||
<else />
|
||||
<span class="layui-badge layui-badge-red ruletype">{:__("系统")}</span>
|
||||
</if>
|
||||
</td>
|
||||
<td>
|
||||
<input name="menus[auth][]" type="text" hidden value="{$rekey.auth}">
|
||||
<eq name="$rekey['auth']" value="1">
|
||||
<span class="layui-badge layui-badge-blue ruleauth">{:__("是")}</span>
|
||||
<else />
|
||||
<span class="layui-badge layui-badge-blue ruleauth layui-badge-red">否</span>
|
||||
</eq>
|
||||
</td>
|
||||
</tr>
|
||||
</volist>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-footer layui-form-footer">
|
||||
<button class="layui-btn layui-btn-primary" type="button" sa-event="closeDialog">{:__('取消')}</button>
|
||||
<button class="layui-btn" lay-filter="submitIframe" type="button" lay-submit>{:__('提交')}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/html" id="relationHtml">
|
||||
<tr>
|
||||
<td>
|
||||
<div class="layui-input-inline" >
|
||||
<select name="relation_table[]" lay-filter="relationTable" lay-verify="required">
|
||||
<option value="">{:__('请选择数据表')}</option>
|
||||
<volist name="$tables" id="vo">
|
||||
<option value="{$vo}" >{$vo}</option>
|
||||
</volist>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="layui-input-inline" >
|
||||
<select name="relation_style[]" lay-verify="required" >
|
||||
<option value="">{:__('请选择关联方式')}</option>
|
||||
<option value="hasOne">hasOne</option>
|
||||
<option value="hasMany">hasMany</option>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="layui-input-inline" >
|
||||
<select name="foreignKey[]" class="foreignKey" lay-verify="required" >
|
||||
<option value="">{:__('请选择关联外键')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="layui-input-inline" >
|
||||
<select name="localKey[]" class="localKey" lay-verify="required" >
|
||||
<option value="">{:__('请选择关联主键')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="layui-input-inline" >
|
||||
<!-- // 隐藏关联字段表单 -->
|
||||
<div class="relationField"></div>
|
||||
</div>
|
||||
<span class="layui-relation-delete"><i class="layui-icon layui-icon-close"></i></span>
|
||||
</td>
|
||||
</tr>
|
||||
</script>
|
||||
|
||||
<include file="/public/static" />
|
||||
<include file="/public/footer" />
|
||||
|
||||
<script>
|
||||
layui.use(['form', 'jquery', 'admin', 'iconPicker'], function () {
|
||||
var form = layui.form;
|
||||
var $ = layui.jquery;
|
||||
var admin = layui.admin;
|
||||
var iconPicker = layui.iconPicker;
|
||||
var localFields = {$data.localFields|raw};
|
||||
var fieldUrl = "{:url('/developer/Generate/queryFields')}";
|
||||
|
||||
// 渲染字段信息
|
||||
xmSelect.render({
|
||||
el: '.listField',
|
||||
name: 'listField',
|
||||
theme: {
|
||||
color: '#1890ff',
|
||||
},
|
||||
data: localFields,
|
||||
initValue: {$data.listField|raw},
|
||||
})
|
||||
|
||||
// 控制器
|
||||
$('#controller').keyup(function (elem) {
|
||||
syncChengeController($(this).val().substring(0, $(this).val().lastIndexOf('/') + 1));
|
||||
})
|
||||
|
||||
var syncChengeController = function (route = null) {
|
||||
$('.change-router').each(function (index, elem) {
|
||||
var type = $(elem).val().split('/');
|
||||
type = type[type.length-1];
|
||||
var router = route + type;
|
||||
$(elem).val(router);
|
||||
$(elem).parent('td').next().find('input').val(router.substring(1).replaceAll('/', ':'));
|
||||
})
|
||||
}
|
||||
|
||||
$('.change-router').keyup(function(e) {
|
||||
var route = $(this).val().substring(1).replace('/', ':');
|
||||
$(this).parent('td').next().find('input').val(route);
|
||||
})
|
||||
|
||||
// 增加关联选项
|
||||
$('.layui-relation-add').click(function (params) {
|
||||
var html = $('#relationHtml').html();
|
||||
$('#relationBody').append(html);
|
||||
form.render();
|
||||
})
|
||||
|
||||
// 关联表操作
|
||||
form.on('select(relationTable)', function (data) {
|
||||
var index = $(this).parents('tr').index();
|
||||
var xm_obj = $('.relationField:eq(' + index + ')');
|
||||
var foreignElem = $('.foreignKey:eq(' + index + ')');
|
||||
var localElem = $('.localKey:eq(' + index + ')');
|
||||
var route = data.value.split('_').slice(1).join('_');
|
||||
var foreignfiled = admin.event.ajax(fieldUrl, { table: route }, false);
|
||||
|
||||
// 重载关联外键
|
||||
foreignElem.empty();
|
||||
foreignElem.append(new Option('请选择关联外键', ''));
|
||||
for (let index = 0; index < foreignfiled.length; index++) {
|
||||
const element = foreignfiled[index];
|
||||
foreignElem.append(new Option(element.value, element.value));
|
||||
}
|
||||
|
||||
// 重载关联主键
|
||||
localElem.empty();
|
||||
localElem.append(new Option('请选择关联主键', ''));
|
||||
for (let index = 0; index < localFields.length; index++) {
|
||||
const element = localFields[index];
|
||||
localElem.append(new Option(element.value, element.value));
|
||||
}
|
||||
|
||||
form.render();
|
||||
multi_xml_func(index, foreignfiled, xm_obj);
|
||||
})
|
||||
|
||||
// 管理XM对象集合
|
||||
var xm_tree = [];
|
||||
var multi_xml_func = function (index, field, xm_obj, init = []) {
|
||||
if (xm_tree[index] != undefined) {
|
||||
xm_tree[index].update({ data: field, initValue: init });
|
||||
} else {
|
||||
xm_tree[index] = xmSelect.render({
|
||||
el: xm_obj[0],
|
||||
name: 'relationField[' + index + ']',
|
||||
theme: {
|
||||
color: '#1890ff',
|
||||
},
|
||||
data: field,
|
||||
initValue: init,
|
||||
on: function (data) {
|
||||
var f = [];
|
||||
data.arr.forEach(v => {
|
||||
f.push(v.value);
|
||||
});
|
||||
xm_obj.prev().val(f.join());
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 删除关联元素
|
||||
$('body').on('click', '.layui-relation-delete i', function (elem) {
|
||||
if ($('#relationModel tbody tr').length) {
|
||||
var elem = $(this).parents('tr'),
|
||||
index = elem.index();
|
||||
elem.remove();
|
||||
xm_tree.splice(index,1);
|
||||
}
|
||||
})
|
||||
|
||||
// 修改鉴权操作
|
||||
$('.ruleauth').click(function (e) {
|
||||
var that = $(this), prev = that.prev();
|
||||
var val = prev.val();
|
||||
if (val >= 1) {
|
||||
that.addClass('layui-badge-red').text('否');
|
||||
} else {
|
||||
that.removeClass('layui-badge-red').text('是');
|
||||
}
|
||||
val >= 1 ? prev.val(0) : prev.val(1);
|
||||
})
|
||||
|
||||
// 切换类型
|
||||
$('.ruletype').click(function (e) {
|
||||
var that = $(this), prev = that.prev(),
|
||||
arr = {
|
||||
1: {
|
||||
value: '1',
|
||||
title: '按钮',
|
||||
class: 'layui-badge-blue'
|
||||
},
|
||||
2: {
|
||||
value: '2',
|
||||
title: '接口',
|
||||
class: 'layui-badge-green'
|
||||
},
|
||||
3: {
|
||||
value: '3',
|
||||
title: '系统',
|
||||
class: 'layui-badge-red'
|
||||
}
|
||||
};
|
||||
var val = Number(prev.val()) + 1;
|
||||
|
||||
if (val > 3) {
|
||||
val = 1;
|
||||
}
|
||||
$(that).prop('class', 'layui-badge');
|
||||
$(that).addClass(arr[val].class);
|
||||
$(that).text(arr[val].title);
|
||||
$(prev).val(arr[val].value);
|
||||
})
|
||||
|
||||
// 图标选择
|
||||
iconPicker.render({
|
||||
elem: '#iconPicker',
|
||||
type: 'fontClass',
|
||||
search: true,
|
||||
cellWidth: "14%",
|
||||
page: true,
|
||||
limit: 20,
|
||||
click: function (data) {
|
||||
$('#iconPicker').val(data.icon);
|
||||
},
|
||||
success: function (d) { }
|
||||
});
|
||||
|
||||
// 初始化循环处理
|
||||
$('.relationField').each(function (i, k) {
|
||||
var allsfield = $(this).next().text();
|
||||
var initfield = $(this).next().next().text();
|
||||
initfield = initfield.replace(/(^\s*)|(\s*$)/g, "").split(',');
|
||||
multi_xml_func(i, JSON.parse(allsfield), $(this), initfield);
|
||||
})
|
||||
|
||||
$('.layui-fluid').show();
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,264 @@
|
||||
<include file="/public/header" />
|
||||
<!--Developer-->
|
||||
<link href="__STATICADMIN__/module/formDesign/formdesign.css?v={:release()}" rel="stylesheet" type="text/css" />
|
||||
<style>
|
||||
.layui-form-checkbox[lay-skin="primary"] span {
|
||||
padding-right: 13px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1900px) {
|
||||
#layui-form-attribute .layui-input-inline {
|
||||
width: 138px;
|
||||
}
|
||||
|
||||
#layui-form-attribute .layui-form-label {
|
||||
padding-left: 0;
|
||||
width: auto!important;
|
||||
}
|
||||
|
||||
.component .component-group ol {
|
||||
min-width: 50px!important;
|
||||
width: 30%!important;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
<div class="layui-fluid" >
|
||||
<form class="layui-form layui-card">
|
||||
<input type="text" name="id" value="{$data.id}" hidden="">
|
||||
<div class="layui-card-header">表单设计</div>
|
||||
<div class="layui-card-body" style="padding-bottom:100px;">
|
||||
<div class="layui-row layui-col-space30">
|
||||
<div class="layui-col-md2">
|
||||
<div class="layui-tab layui-tab-brief">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">{:__('表单组件')}</li>
|
||||
<li>{:__('表单模板')}</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content" id="layui-form-attribute">
|
||||
<div class="layui-tab-item layui-form layui-show">
|
||||
<div class="component">
|
||||
<div class="head">表单组件</div>
|
||||
<div class="component-group" id="sort_1">
|
||||
<ol data-tag="input">
|
||||
<div class="icon"><i class="layui-icon layui-icon-layer"></i></div>
|
||||
<div class="name">单行输入</div>
|
||||
</ol>
|
||||
<ol data-tag="textarea">
|
||||
<div class="icon"><i class="layui-icon layui-icon-align-left"></i></div>
|
||||
<div class="name">多行输入</div>
|
||||
</ol>
|
||||
<ol data-tag="radio">
|
||||
<div class="icon"><i class="layui-icon layui-icon-radio"></i></div>
|
||||
<div class="name">单选框</div>
|
||||
</ol>
|
||||
<ol data-tag="checkbox">
|
||||
<div class="icon"><i class="layui-icon layui-icon-table"></i></div>
|
||||
<div class="name">多选框</div>
|
||||
</ol>
|
||||
<ol data-tag="select">
|
||||
<div class="icon"><i class="layui-icon layui-icon-print"></i></div>
|
||||
<div class="name">下拉框</div>
|
||||
</ol>
|
||||
<ol data-tag="date">
|
||||
<div class="icon"><i class="layui-icon layui-icon-time"></i></div>
|
||||
<div class="name">日期组件</div>
|
||||
</ol>
|
||||
<ol data-tag="colorpicker">
|
||||
<div class="icon"><i class="layui-icon layui-icon-theme"></i></div>
|
||||
<div class="name">颜色选择器</div>
|
||||
</ol>
|
||||
<ol data-tag="slider">
|
||||
<div class="icon"><i class="layui-icon layui-icon-slider"></i></div>
|
||||
<div class="name">滑块</div>
|
||||
</ol>
|
||||
<ol data-tag="rate">
|
||||
<div class="icon"><i class="layui-icon layui-icon-rate-solid"></i></div>
|
||||
<div class="name">评分</div>
|
||||
</ol>
|
||||
<ol data-tag="switch">
|
||||
<div class="icon"><i class="layui-icon layui-icon-switch">
|
||||
<k></k>
|
||||
</i></div>
|
||||
<div class="name">开关</div>
|
||||
</ol>
|
||||
<ol data-tag="cascader">
|
||||
<div class="icon"><i class="layui-icon layui-icon-cols"></i></div>
|
||||
<div class="name">级联选择器</div>
|
||||
</ol>
|
||||
<ol data-tag="editor">
|
||||
<div class="icon"><i class="layui-icon layui-icon-form"></i></div>
|
||||
<div class="name">富文本</div>
|
||||
</ol>
|
||||
<ol data-tag="upload">
|
||||
<div class="icon"><i class="layui-icon layui-icon-upload"></i></div>
|
||||
<div class="name">文件上传</div>
|
||||
</ol>
|
||||
<ol data-tag="tags">
|
||||
<div class="icon"><i class="layui-icon fa-instagram"></i></div>
|
||||
<div class="name">标签选择器</div>
|
||||
</ol>
|
||||
<ol data-tag="json">
|
||||
<div class="icon"><i class="layui-icon fa-bars"></i></div>
|
||||
<div class="name">JSON组件</div>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="component">
|
||||
<div class="head">辅助组件</div>
|
||||
<div class="component-group" id="sort_2">
|
||||
<ol data-tag="tips">
|
||||
<div class="icon"><i class="layui-icon layui-icon-tips"></i></div>
|
||||
<div class="name">提示</div>
|
||||
</ol>
|
||||
<ol data-tag="button">
|
||||
<div class="icon"><i class="layui-icon layui-icon-layer"></i></div>
|
||||
<div class="name">按钮</div>
|
||||
</ol>
|
||||
<ol data-tag="note">
|
||||
<div class="icon"><i class="layui-icon layui-icon-note"></i></div>
|
||||
<div class="name">便签</div>
|
||||
</ol>
|
||||
<ol data-tag="subtraction">
|
||||
<div class="icon"><i class="layui-icon layui-icon-subtraction"></i></div>
|
||||
<div class="name">分割线</div>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div class="component">
|
||||
<div class="head">布局组件</div>
|
||||
<div class="component-group" id="sort_3">
|
||||
<ol data-tag="tab">
|
||||
<div class="icon"><i class="layui-icon layui-icon-tabs smallfont"></i></div>
|
||||
<div class="name">TAB选项卡</div>
|
||||
</ol>
|
||||
<ol data-tag="grid">
|
||||
<div class="icon"><i class="layui-icon layui-icon-layouts"></i></div>
|
||||
<div class="name">栅格</div>
|
||||
</ol>
|
||||
<ol data-tag="space">
|
||||
<div class="icon"><i class="layui-icon layui-icon-more"></i></div>
|
||||
<div class="name">间距</div>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- // 加载远程表单模板 -->
|
||||
<div id="layui-form-template" class="layui-tab-item">
|
||||
<div id="item-list" class="item-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md8">
|
||||
<div class="layui-card-header">
|
||||
<div class="fr">
|
||||
<button type="button" class="layui-btn layui-btn-sm layui-btn-export"><i
|
||||
class="layui-icon layui-icon-export"></i>导出</button>
|
||||
<button type="button" class="layui-btn layui-btn-sm layui-btn-import"><i
|
||||
class="layui-icon layui-icon-layer"></i>导入</button>
|
||||
<button type="button" class="layui-btn layui-btn-sm layui-btn-component"> <i
|
||||
class="layui-icon layui-icon-component"></i> 预览</button>
|
||||
<button type="button" class="layui-btn layui-btn-sm layui-btn-danger layui-form-clear"><i
|
||||
class="layui-icon layui-icon-delete"></i>清空</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- // 表单设计区域 -->
|
||||
<div id="formBuilder" style="width: 100%"></div>
|
||||
<!-- // 表单隐藏域 -->
|
||||
<textarea id="formDesign" name="formDesign" hidden>{$data.formDesign|default=''}</textarea>
|
||||
</div>
|
||||
<div class="layui-col-md2" style="padding-top: 0;" id="layui-form-attribute">
|
||||
<div class="layui-tab layui-tab-brief">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">{:__('组件属性')}</li>
|
||||
<li>{:__('表单属性')}</li>
|
||||
</ul>
|
||||
|
||||
<div class="layui-tab-content" >
|
||||
<div class="layui-tab-item layui-form layui-show" id="Propertie" lay-filter="Propertie">
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">
|
||||
<font color="red">*</font>{:__('表单ID')}
|
||||
</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" id="formName" name="formName" class="layui-input"
|
||||
value="{$data.formName|default='form'}" placeholder="请输入">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('表单类型')}</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="formType" title="弹窗" <eq name="$data['formType']"
|
||||
value="1">checked="" </eq> value="1">
|
||||
<input type="radio" name="formType" title="内置" <eq name="$data['formType']"
|
||||
value="0">checked="" </eq> value="0" >
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('表单宽高')}</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" id="formWidth" name="width"
|
||||
style="width: 70px;display: inline-block;" class="layui-input"
|
||||
value="{$data.width|default='1100px'}" placeholder="宽度">
|
||||
<em> - </em>
|
||||
<input type="text" id="formHeight" name="height"
|
||||
style="width:70px;display: inline-block;" class="layui-input"
|
||||
value="{$data.height|default='750px'}" placeholder="高度">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-footer layui-form-footer">
|
||||
<button class="layui-btn layui-btn-primary" type="button" sa-event="closeDialog">{:__('取消')}</button>
|
||||
<button class="layui-btn" lay-filter="submitIframe" type="button" lay-submit>{:__('提交')}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="layui-htmlview" style="display: none;">
|
||||
<textarea id="json-code"></textarea>
|
||||
<div class="layui-htmlbtn">
|
||||
<button id="copy-code" class="layui-btn layui-hide">复制代码</button>
|
||||
<button id="import-code" class="layui-btn layui-hide">导入数据</button>
|
||||
</div>
|
||||
</div>
|
||||
<script src="__STATICJS__Sortable/Sortable.js?v={:release()}"></script>
|
||||
<include file="/public/footer" />
|
||||
<include file="/public/static" />
|
||||
<script>
|
||||
layui.use(['jquery', 'flow', 'formDesign'], function () {
|
||||
let $ = layui.jquery;
|
||||
|
||||
let formDesign = layui.formDesign;
|
||||
formDesign.render({
|
||||
elem: '#formBuilder'
|
||||
, eval: '#formDesign'
|
||||
});
|
||||
|
||||
layui.flow.load({
|
||||
elem: '#item-list'
|
||||
, done: function (page, next) {
|
||||
var list = [];
|
||||
$.get('//api.swiftadmin.net/form/?page=' + page, function (res) {
|
||||
layui.each(res.data, function (index, item) {
|
||||
list.push(item);
|
||||
});
|
||||
next(list.join(''), page < res.total);
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
})
|
||||
// 获取字段信息
|
||||
window.tableInfo = {$table|raw};
|
||||
</script>
|
||||
125
plugin/developer/app/admin/view/developer/generate/index.html
Normal file
125
plugin/developer/app/admin/view/developer/generate/index.html
Normal file
@@ -0,0 +1,125 @@
|
||||
<include file="/public/header" />
|
||||
<!--Developer-->
|
||||
<div class="layui-fluid">
|
||||
<div class="layui-card">
|
||||
<!-- // 默认操作按钮 -->
|
||||
<div class="layui-card-header layadmin-card-header-auto ">
|
||||
<div class="layui-form">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
|
||||
<select name="status">
|
||||
<option value="">{:__('按状态查询')}</option>
|
||||
<option value="2" >{:__('正常')}</option>
|
||||
<option value="1" >{:__('关闭')}</option>
|
||||
</select>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="layui-inline">
|
||||
<div class="layui-form-label">{:__('名称检索')}</div>
|
||||
<div class="layui-input-inline "><input name="title" class="layui-input" type="text" placeholder="{:__('名称检索')}"/></div>
|
||||
</div>
|
||||
|
||||
<div class="layui-inline" >
|
||||
<!-- // 默认搜索 -->
|
||||
<button class="layui-btn icon-btn" lay-filter="formSearch" lay-submit>
|
||||
<i class="layui-icon layui-icon-search"></i>{:__('搜索')}
|
||||
</button>
|
||||
|
||||
<!-- // 打开添加页面 -->
|
||||
<button class="layui-btn icon-btn" lay-open="" data-area="100%,100%" data-offset="0px" data-maxmin="true" data-url="{:url('/developer/Generate/add')}" >
|
||||
<i class="layui-icon layui-icon-add-1"></i>{:__('添加')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- // 创建数据表实例 -->
|
||||
<table id="lay-tableList" lay-filter="lay-tableList"></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- // 列表工具栏 -->
|
||||
<script type="text/html" id="tableBar">
|
||||
<a class="layui-table-text" data-area="100%,100%" data-offset="0px" data-maxmin="true"
|
||||
data-url="{:url('/developer/Generate/edit')}?id={{d.id}}" lay-event="edit" >{:__('编辑')}</a>
|
||||
<div class="layui-divider layui-divider-vertical"></div>
|
||||
<a class="layui-table-text lay-form-design" data-url="{:url('/developer/Generate/formDesign')}?id={{d.id}}" >{:__('表单')}</a>
|
||||
<div class="layui-divider layui-divider-vertical"></div>
|
||||
<a class="layui-table-text" lay-ajax data-table="lay-tableList" data-url="{:url('/developer/Curd/build')}?id={{d.id}}" data-callback="reloadRouter" >{:__('部署')}</a>
|
||||
<div class="layui-divider layui-divider-vertical"></div>
|
||||
<a class="layui-table-text" lay-ajax data-table="lay-tableList" data-url="{:url('/developer/Curd/clear')}?id={{d.id}}" data-callback="reloadRouter" >{:__('清理')}</a>
|
||||
<div class="layui-divider layui-divider-vertical"></div>
|
||||
<a class="layui-table-text" data-url="{:url('/developer/Generate/del')}?id={{d.id}}" lay-event="del" >{:__('删除')}</a>
|
||||
</script>
|
||||
|
||||
<!-- // 列表按钮工具栏 -->
|
||||
<script type="text/html" id="tableBtn">
|
||||
|
||||
</script>
|
||||
|
||||
<include file="/public/footer" />
|
||||
<script>
|
||||
layui.use(['jquery','layer','admin','table'],function () {
|
||||
|
||||
var table = layui.table;
|
||||
var $ = layui.jquery;
|
||||
var layer = layui.layer;
|
||||
var admin = layui.admin;
|
||||
/*
|
||||
* 初始化表格
|
||||
*/
|
||||
var isTable = table.render({
|
||||
elem: "#lay-tableList"
|
||||
,url: "{:url('/developer/Generate/index')}"
|
||||
,toolbar: '#tableBtn'
|
||||
,loading: false
|
||||
,defaultToolbar: ['filter', 'exports', 'print','search']
|
||||
,page: true
|
||||
,limit: 18
|
||||
,cols: [[
|
||||
{type: 'checkbox', width:50},
|
||||
{field: 'id', align: 'center',sort: true,width: 80, title: 'ID'},
|
||||
{field: 'title', align: 'left', title: '{:__("名称")}'},
|
||||
{field: 'table', align: 'center',title: '{:__("数据库表")}'},
|
||||
{field: 'controller', align: 'center',title: '{:__("控制器")}'},
|
||||
{field: 'status', align: 'center',width:180, templet: function(d) {
|
||||
var status = ['<span class="layui-badge layui-bg-gray">未生成</span>','<span class="layui-badge layui-bg-red">已生成</span>'];
|
||||
return status[d.status];
|
||||
}, title: '{:__("状态")}'},
|
||||
{field: 'update_time', align: 'center',title: '{:__("更新时间")}'},
|
||||
{field: 'create_time', align: 'center',title: '{:__("创建时间")}'},
|
||||
{align: 'center', toolbar: '#tableBar', width:330, title: '{:__("操作")}'},
|
||||
]]
|
||||
})
|
||||
|
||||
/**
|
||||
* Ajax重载函数
|
||||
* @type {{success: layui.admin.callback.reloadRouter.success, error: layui.admin.callback.reloadRouter.error}}
|
||||
*/
|
||||
admin.callback.reloadRouter = {
|
||||
success: function (res) {
|
||||
layer.msg(res.msg);
|
||||
table.reload('lay-tableList');
|
||||
top.layui.admin.reloadLayout();
|
||||
}
|
||||
,error: function (res) {
|
||||
layer.error(res.msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设计FORM表单
|
||||
*/
|
||||
$('body').on('click','.lay-form-design',function(params) {
|
||||
top.layer.open({
|
||||
type:2,
|
||||
title: '',
|
||||
area: ['100%','100%'],
|
||||
content: [$(this).data('url')]
|
||||
})
|
||||
})
|
||||
})
|
||||
</script>
|
||||
31
plugin/developer/app/admin/view/developer/plugin/import.html
Normal file
31
plugin/developer/app/admin/view/developer/plugin/import.html
Normal file
@@ -0,0 +1,31 @@
|
||||
<include file="/public/header"/>
|
||||
<!--Developer-->
|
||||
<style>
|
||||
.item-dir {
|
||||
cursor: pointer;
|
||||
padding: 2px 8px;
|
||||
margin: 15px 0;
|
||||
color: #1890ff !important;
|
||||
background: #e6f7ff;
|
||||
}
|
||||
.item-dir:hover {
|
||||
background-color: #1890ff;
|
||||
color: #fff !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<form class="layui-form layui-card">
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-form-item">
|
||||
<volist name="dirs" id="vo">
|
||||
<div class="item-dir" lay-ajax data-url="{:url('/developer/Plugin/import',['dir'=>$vo.name])}" data-table="lay-tableList">
|
||||
<span class="">{$vo.name}</span>
|
||||
<span class="layui-fr">{$vo.title}</span>
|
||||
</div>
|
||||
</volist>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<include file="/public/footer"/>
|
||||
|
||||
216
plugin/developer/app/admin/view/developer/plugin/index.html
Normal file
216
plugin/developer/app/admin/view/developer/plugin/index.html
Normal file
@@ -0,0 +1,216 @@
|
||||
<include file="/public/header"/>
|
||||
<!--Developer-->
|
||||
<style>
|
||||
.layui-input-block textarea {
|
||||
height: 145px;
|
||||
}
|
||||
</style>
|
||||
<div class="layui-fluid">
|
||||
<div class="layui-card">
|
||||
<!-- // 默认操作按钮 -->
|
||||
<div class="layui-card-header layadmin-card-header-auto ">
|
||||
<div class="layui-form">
|
||||
<div class="layui-form-item">
|
||||
|
||||
<div class="layui-inline">
|
||||
<button id="install" class="layui-btn icon-btn layui-btn-danger"><i
|
||||
class="layui-icon fa-bug" style="font-size: 15px"></i> {:__('安装测试')}
|
||||
</button>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<button id="upgrade" class="layui-btn icon-btn layui-btn-checked"><i
|
||||
class="layui-icon fa-upload"></i> {:__('升级测试')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="layui-inline">
|
||||
<button class="layui-btn icon-btn" lay-open="" data-title="{:__('导入插件')}" data-area="300px,399px" data-shadeClose="true"
|
||||
data-url="{:url('/developer/Plugin/import')}" >
|
||||
<i class="layui-icon fa-codepen"></i> {:__('加载插件')}</button>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<!-- // 打开添加页面 -->
|
||||
<button class="layui-btn icon-btn" lay-open="" data-title="{:__('创建插件')}" data-area="698px"
|
||||
data-offset="10%" data-url="#editforms">
|
||||
<i class="layui-icon layui-icon-add-1"></i> {:__('新建插件')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="layui-inline">
|
||||
<button class="layui-btn icon-btn" sa-event="tabs" data-url="/admin/system/Plugin/index" data-title="插件管理">
|
||||
<i class="layui-icon fa-plug" style="font-size: 15px"></i>{:__('插件管理')}</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- // 创建数据实例 -->
|
||||
<table id="lay-tableList" lay-filter="lay-tableList"></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- // 添加编辑数据 -->
|
||||
<script type="text/html" id="editforms">
|
||||
<div class="layui-fluid layui-bg-white">
|
||||
<form class="layui-form layui-form-fixed" lay-filter="editforms">
|
||||
<input type="text" name="id" hidden="">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><font color="red">* </font>{:__('插件标识')}</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="name" class="layui-input" placeholder="请输入唯一插件标识" lay-verify="required"
|
||||
data-disabled autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><font color="red">* </font>{:__('插件名称')}</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" class="layui-input" placeholder="演示插件" lay-verify="required"
|
||||
data-disabled autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><font color="red">* </font>{:__('插件版本')}</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="version" class="layui-input" placeholder="示例:1.0.0" lay-verify="required" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('插件图标')}</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="icon" class="layui-input" placeholder="示例:fa-home">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span style="color: red; ">* </span>{:__('插件作者')}</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="author" class="layui-input" placeholder="请输入插件作者名称" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('前台地址')}</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="home" class="layui-input" placeholder="如有前台地址请填写 例如/demo/index">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span style="color: red; ">* </span>{:__('菜单配置')}</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="menu" value="1" title="开启" checked>
|
||||
<input type="radio" name="menu" value="0" title="关闭">
|
||||
</div>
|
||||
<label class="layui-form-label"><span style="color: red; ">* </span>{:__('插件配置')}</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="config" value="1" title="开启" checked>
|
||||
<input type="radio" name="config" value="0" title="关闭">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('插件简介')}</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="intro" class="layui-textarea" lay-verify="required"
|
||||
placeholder="如不需要菜单项(可选)关闭,适合简易型插件应用"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-footer layui-form-item layui-center">
|
||||
<button class="layui-btn layui-btn-primary" type="button" sa-event="closePageDialog">{:__('取消')}
|
||||
</button>
|
||||
<button class="layui-btn" lay-filter="submitPage" lay-submit>{:__('提交')}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<!-- // 列表工具栏 -->
|
||||
<script type="text/html" id="tableBar">
|
||||
<a class="layui-table-text" data-title="{:__('编辑插件')}" data-area="698px" data-url="#editforms" data-offset="10%"
|
||||
lay-event="edit">{:__('编辑')}</a>
|
||||
<div class="layui-divider layui-divider-vertical"></div>
|
||||
<a class="layui-table-text" lay-ajax data-url="{:url('/developer/Plugin/build')}?id={{d.id}}" data-callback="build">{:__('生成')}</a>
|
||||
<div class="layui-divider layui-divider-vertical"></div>
|
||||
<a class="layui-table-text" lay-ajax data-url="{:url('/developer/Plugin/package')}?id={{d.id}}" data-jump="true">{:__('打包')}</a>
|
||||
<div class="layui-divider layui-divider-vertical"></div>
|
||||
<a class="layui-table-text" data-url="{:url('/developer/Plugin/del')}?id={{d.id}}" lay-event="del">{:__('删除')}</a>
|
||||
</script>
|
||||
|
||||
<include file="/public/footer"/>
|
||||
<script>
|
||||
layui.use(['table', 'admin', 'layer', 'jquery'], function () {
|
||||
|
||||
var table = layui.table;
|
||||
var admin = layui.admin;
|
||||
var layer = layui.layer;
|
||||
var $ = layui.jquery;
|
||||
/*
|
||||
* 初始化表格
|
||||
*/
|
||||
var isTable = table.render({
|
||||
elem: "#lay-tableList"
|
||||
, url: "{:url('/developer/Plugin/index')}"
|
||||
, page: true
|
||||
, limit: 18
|
||||
, cols: [[
|
||||
{type: 'checkbox', width: 50},
|
||||
{field: 'id', align: 'center', sort: true, width: 80, title: 'ID'},
|
||||
{field: 'title', align: 'left', title: '{:__("插件名称")}'},
|
||||
{field: 'name', align: 'left', title: '{:__("插件标识")}'},
|
||||
{field: 'version', align: 'left', title: '{:__("插件版本")}'},
|
||||
{field: 'author', align: 'left', title: '{:__("插件作者")}'},
|
||||
{field: 'home', align: 'left', title: '{:__("前台地址")}'},
|
||||
{field: 'create_time', align: 'center', width: 160, title: '{:__("创建时间")}'},
|
||||
{align: 'center', toolbar: '#tableBar', width: 260, title: '{:__("操作")}'},
|
||||
]]
|
||||
})
|
||||
|
||||
/**
|
||||
* Ajax回调函数
|
||||
* @type {{success: layui.admin.callback.build.success, error: layui.admin.callback.build.error}}
|
||||
*/
|
||||
admin.callback.build = {
|
||||
'success': function (res) {
|
||||
layer.msg(res.msg);
|
||||
top.layui.admin.reloadLayout();
|
||||
},
|
||||
'error': function (res) {
|
||||
layer.error(res.msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 本地安装插件
|
||||
*/
|
||||
layui.upload.render({
|
||||
elem: '#install'
|
||||
, accept: 'file' //允许上传的文件类型
|
||||
, url: '{:url("/developer/Plugin/install")}'
|
||||
, done: function (res, index, upload) { //上传后的回调
|
||||
if (res.code === 200) {
|
||||
layer.msg(res.msg);
|
||||
top.layui.admin.reloadLayout();
|
||||
} else {
|
||||
layer.error(res.msg);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 本地升级测试
|
||||
*/
|
||||
layui.upload.render({
|
||||
elem: '#upgrade'
|
||||
, accept: 'file' //允许上传的文件类型
|
||||
, url: '{:url("/developer/Plugin/upgrade")}'
|
||||
, done: function (res, index, upload) { //上传后的回调
|
||||
if (res.code === 200) {
|
||||
layer.msg(res.msg);
|
||||
top.layui.admin.reloadLayout();
|
||||
} else {
|
||||
layer.error(res.msg);
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
20
plugin/developer/config.json
Normal file
20
plugin/developer/config.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "developer",
|
||||
"title": "开发助手",
|
||||
"intro": "插件开发助手,流程化建立插件!",
|
||||
"author": "官方",
|
||||
"home": "https:\/\/www.swiftadmin.net",
|
||||
"version": "1.0.3",
|
||||
"status": 1,
|
||||
"extends": [],
|
||||
"rewrite": [],
|
||||
"area": [
|
||||
"600px",
|
||||
"650px"
|
||||
],
|
||||
"auto": true,
|
||||
"config": 0,
|
||||
"icon": "fa-plug",
|
||||
"menu": 0,
|
||||
"path": "\/home\/bt_www\/www\/wwwroot\/pdm.sa.webadmain.com\/plugin\/developer\/"
|
||||
}
|
||||
84
plugin/developer/data/menu.php
Normal file
84
plugin/developer/data/menu.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
return [
|
||||
0 => [
|
||||
'title' => '开发助手',
|
||||
'router' => '/developer',
|
||||
'icon' => 'fa-plug',
|
||||
'auth' => 1,
|
||||
'type' => 0,
|
||||
'children' => [
|
||||
0 => [
|
||||
'title' => '插件开发',
|
||||
'router' => '/developer/Plugin/index',
|
||||
'icon' => '',
|
||||
'auth' => 1,
|
||||
'type' => 0,
|
||||
],
|
||||
1 => [
|
||||
'title' => '代码生成',
|
||||
'router' => '/developer/Generate/index',
|
||||
'icon' => '',
|
||||
'auth' => 1,
|
||||
'type' => 0,
|
||||
],
|
||||
],
|
||||
],
|
||||
1 => [
|
||||
'title' => '开发示例',
|
||||
'router' => '/developer/Example/',
|
||||
'icon' => 'fa-gitlab',
|
||||
'auth' => 1,
|
||||
'type' => 0,
|
||||
'children' => [
|
||||
0 => [
|
||||
'title' => '基础表单',
|
||||
'router' => '/developer/Example/index',
|
||||
'icon' => '',
|
||||
'auth' => 1,
|
||||
'type' => 0,
|
||||
],
|
||||
1 => [
|
||||
'title' => '数据表格',
|
||||
'router' => '/developer/Example/table',
|
||||
'icon' => '',
|
||||
'auth' => 1,
|
||||
'type' => 0,
|
||||
],
|
||||
2 => [
|
||||
'title' => '卡片列表',
|
||||
'router' => '/developer/Example/card',
|
||||
'icon' => '',
|
||||
'auth' => 1,
|
||||
'type' => 0,
|
||||
],
|
||||
3 => [
|
||||
'title' => '统计图表',
|
||||
'router' => '/developer/Example/echarts',
|
||||
'icon' => '',
|
||||
'auth' => 1,
|
||||
'type' => 0,
|
||||
],
|
||||
4 => [
|
||||
'title' => '组件示例',
|
||||
'router' => '/developer/Example/component',
|
||||
'icon' => '',
|
||||
'auth' => 1,
|
||||
'type' => 0,
|
||||
],
|
||||
5 => [
|
||||
'title' => '文本编辑器',
|
||||
'router' => '/developer/Example/editor',
|
||||
'icon' => '',
|
||||
'auth' => 1,
|
||||
'type' => 0,
|
||||
],
|
||||
6 => [
|
||||
'title' => '常规辅助元素',
|
||||
'router' => '/developer/Example/auxiliar',
|
||||
'icon' => '',
|
||||
'auth' => 1,
|
||||
'type' => 0,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
16
plugin/developer/function.php
Normal file
16
plugin/developer/function.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Developer插件公共函数库
|
||||
*/
|
||||
|
||||
if (!function_exists('format_time')) {
|
||||
/*
|
||||
* 格式化时间戳
|
||||
*/
|
||||
function format_time()
|
||||
{
|
||||
return date('Y-m-d H:i:s', time());
|
||||
}
|
||||
}
|
||||
|
||||
115
plugin/developer/install.sql
Normal file
115
plugin/developer/install.sql
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
Navicat Premium Data Transfer
|
||||
|
||||
Source Server : demo
|
||||
Source Server Type : MySQL
|
||||
Source Server Version : 50737
|
||||
Source Host : 127.0.0.1:3306
|
||||
Source Schema : sademo
|
||||
|
||||
Target Server Type : MySQL
|
||||
Target Server Version : 50737
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 19/07/2022 18:46:07
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for __PREFIX__ceshi
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `__PREFIX__ceshi`;
|
||||
CREATE TABLE `__PREFIX__ceshi` (
|
||||
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '姓名;权栈',
|
||||
`sex` int(1) NULL DEFAULT NULL COMMENT '性别',
|
||||
`avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '头像',
|
||||
`hobby` set('write','game','read') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '爱好',
|
||||
`text` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '内容页',
|
||||
`age` int(11) NULL DEFAULT NULL COMMENT '年龄',
|
||||
`tags` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '关键词',
|
||||
`album` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '相册;多文件上传必须为text类型',
|
||||
`stars` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '星级',
|
||||
`interest` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '签名',
|
||||
`week` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '星期',
|
||||
`birthday` int(11) NULL DEFAULT NULL COMMENT '生日;必须要int类型',
|
||||
`json` json NULL COMMENT '数组',
|
||||
`color` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '色彩',
|
||||
`lines` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '额度',
|
||||
`status` int(255) NULL DEFAULT NULL COMMENT '状态',
|
||||
`city` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '城市',
|
||||
`content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '内容;内容字段必须是longtext类型',
|
||||
`update_time` int(11) NULL DEFAULT NULL COMMENT '更新时间',
|
||||
`create_time` int(11) NULL DEFAULT NULL COMMENT '创建时间',
|
||||
`delete_time` int(11) NULL DEFAULT NULL COMMENT '软删除标识',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of __PREFIX__ceshi
|
||||
-- ----------------------------
|
||||
INSERT INTO `__PREFIX__ceshi` VALUES (1, '张三', 1, '/upload/avatars/f8e34ec67a2a0233_100x100.jpg', 'write,read', NULL, NULL, NULL, 'a:1:{i:0;a:2:{s:3:\"src\";s:44:\"/upload/avatars/f8e34ec67a2a0233_100x100.jpg\";s:5:\"title\";s:0:\"\";}}', '4', NULL, NULL, NULL, '{\"name\": \"hehe\"}', NULL, NULL, NULL, '北戴河区', '# Markdown编辑器\n', 1658058613, 1656980177, NULL);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for __PREFIX__generate
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `__PREFIX__generate`;
|
||||
CREATE TABLE `__PREFIX__generate` (
|
||||
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '菜单标题',
|
||||
`pid` int(1) UNSIGNED NULL DEFAULT 0 COMMENT '顶级菜单',
|
||||
`table` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '数据库表',
|
||||
`force` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '强制覆盖',
|
||||
`plugin` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '所属插件',
|
||||
`auth` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '1' COMMENT '菜单鉴权',
|
||||
`create` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '1' COMMENT '生成菜单',
|
||||
`global` int(1) UNSIGNED NULL DEFAULT 0 COMMENT '全局模型',
|
||||
`icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '菜单图标',
|
||||
`listField` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '列表字段',
|
||||
`controller` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '控制器',
|
||||
`menus` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '菜单内容',
|
||||
`formName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '表单名称',
|
||||
`formType` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '1' COMMENT '表单类型',
|
||||
`formDesign` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '表单内容',
|
||||
`width` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '表单宽度',
|
||||
`height` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '表单高度',
|
||||
`relation` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '关联数据',
|
||||
`status` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '生成状态',
|
||||
`update_time` int(11) NULL DEFAULT NULL COMMENT '更新时间',
|
||||
`create_time` int(11) NULL DEFAULT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '代码生成器' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of __PREFIX__generate
|
||||
-- ----------------------------
|
||||
INSERT INTO `__PREFIX__generate` VALUES (1, '测试代码', 0, '__PREFIX__ceshi', '1', '', '1', '1', 0, 'layui-icon-android', 'name,sex,avatar,hobby,age,tags,stars,city,album,json', '/ceshi/index', 'a:5:{i:0;a:6:{s:5:\"title\";s:6:\"查看\";s:5:\"route\";s:11:\"ceshi:index\";s:6:\"router\";s:12:\"/ceshi/index\";s:8:\"template\";s:6:\"默认\";s:4:\"auth\";s:1:\"1\";s:4:\"type\";s:1:\"1\";}i:1;a:6:{s:5:\"title\";s:6:\"添加\";s:5:\"route\";s:9:\"ceshi:add\";s:6:\"router\";s:10:\"/ceshi/add\";s:8:\"template\";s:6:\"默认\";s:4:\"auth\";s:1:\"1\";s:4:\"type\";s:1:\"1\";}i:2;a:6:{s:5:\"title\";s:6:\"编辑\";s:5:\"route\";s:9:\"ceshi:zdy\";s:6:\"router\";s:10:\"/ceshi/zdy\";s:8:\"template\";s:6:\"默认\";s:4:\"auth\";s:1:\"1\";s:4:\"type\";s:1:\"1\";}i:3;a:6:{s:5:\"title\";s:6:\"删除\";s:5:\"route\";s:14:\"ceshi:xiaoMing\";s:6:\"router\";s:15:\"/ceshi/xiaoMing\";s:8:\"template\";s:6:\"默认\";s:4:\"auth\";s:1:\"1\";s:4:\"type\";s:1:\"2\";}i:4;a:6:{s:5:\"title\";s:6:\"状态\";s:5:\"route\";s:12:\"ceshi:status\";s:6:\"router\";s:13:\"/ceshi/status\";s:8:\"template\";s:6:\"默认\";s:4:\"auth\";s:1:\"1\";s:4:\"type\";s:1:\"2\";}}', 'form', '1', '[{\"index\":0,\"tag\":\"input\",\"label\":\"姓名\",\"name\":\"name\",\"type\":\"text\",\"placeholder\":\"请输入\",\"default\":\"\",\"labelwidth\":\"110\",\"width\":100,\"maxlength\":\"\",\"min\":0,\"max\":0,\"required\":false,\"readonly\":false,\"disabled\":false,\"labelhide\":false,\"lay_verify\":\"\"},{\"index\":2,\"tag\":\"radio\",\"name\":\"sex\",\"label\":\"性别\",\"labelwidth\":110,\"width\":100,\"disabled\":false,\"labelhide\":false,\"options\":[{\"title\":\"男\",\"value\":\"1\",\"checked\":true},{\"title\":\"女\",\"value\":\"0\",\"checked\":false}]},{\"index\":3,\"tag\":\"upload\",\"name\":\"avatar\",\"label\":\"用户头像\",\"uploadtype\":\"images\",\"labelwidth\":110,\"width\":100,\"data_size\":102400,\"data_accept\":\"file\",\"disabled\":false,\"required\":false,\"labelhide\":false},{\"index\":7,\"tag\":\"upload\",\"name\":\"album\",\"label\":\"相册\",\"uploadtype\":\"multiple\",\"labelwidth\":110,\"width\":100,\"data_size\":102400,\"data_accept\":\"file\",\"disabled\":false,\"required\":false,\"labelhide\":false},{\"index\":8,\"tag\":\"rate\",\"name\":\"stars\",\"label\":\"星级\",\"labelwidth\":110,\"width\":100,\"data_default\":1,\"data_length\":5,\"data_half\":false,\"data_theme\":\"#1890ff\",\"readonly\":false,\"labelhide\":false},{\"index\":5,\"tag\":\"cascader\",\"name\":\"city\",\"label\":\"城市\",\"data_value\":\"label\",\"labelwidth\":110,\"width\":100,\"data_parents\":true,\"labelhide\":false},{\"index\":4,\"tag\":\"checkbox\",\"name\":\"hobby\",\"label\":\"爱好\",\"lay_skin\":\"primary\",\"labelwidth\":110,\"width\":100,\"disabled\":false,\"labelhide\":false,\"options\":[{\"title\":\"写作\",\"value\":\"write\",\"checked\":true},{\"title\":\"阅读\",\"value\":\"read\",\"checked\":true},{\"title\":\"游戏\",\"value\":\"game\",\"checked\":false}]},{\"index\":6,\"tag\":\"json\",\"name\":\"json\",\"label\":\"数组组件\",\"labelwidth\":110,\"width\":100,\"labelhide\":false},{\"index\":7,\"tag\":\"editor\",\"name\":\"content\",\"label\":\"编辑器\",\"editorType\":\"lay-editor\",\"labelwidth\":110,\"width\":100,\"labelhide\":false}]', '1200px', '900px', 'a:1:{i:0;a:5:{s:5:\"table\";s:7:\"__PREFIX__user\";s:5:\"style\";s:6:\"hasOne\";s:10:\"foreignKey\";s:8:\"group_id\";s:8:\"localKey\";s:2:\"id\";s:13:\"relationField\";s:12:\"group_id,pwd\";}}', '0', 1658227430, 1646395278);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for __PREFIX__plugin
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `__PREFIX__plugin`;
|
||||
CREATE TABLE `__PREFIX__plugin` (
|
||||
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '标识',
|
||||
`title` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '插件名称',
|
||||
`intro` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '插件简介',
|
||||
`icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '插件图标',
|
||||
`author` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '插件作者',
|
||||
`home` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '前台主页',
|
||||
`version` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '插件版本',
|
||||
`config` int(1) UNSIGNED NULL DEFAULT 0 COMMENT '是否配置',
|
||||
`menu` int(1) UNSIGNED NULL DEFAULT 1 COMMENT '后台菜单',
|
||||
`import` int(11) UNSIGNED NULL DEFAULT 0 COMMENT '导入时间戳',
|
||||
`status` int(1) UNSIGNED NULL DEFAULT 1 COMMENT '当前状态',
|
||||
`create_time` int(11) NULL DEFAULT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '插件开发助手' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of __PREFIX__plugin
|
||||
-- ----------------------------
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
1
plugin/developer/public/static/plugin/developer/index.js
Normal file
1
plugin/developer/public/static/plugin/developer/index.js
Normal file
@@ -0,0 +1 @@
|
||||
// 前端JS文件
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,418 @@
|
||||
/**
|
||||
// +----------------------------------------------------------------------
|
||||
// | layui表单设计器 [基于Sortable开发]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
|
||||
// +----------------------------------------------------------------------
|
||||
// | git://github.com/meystack/layui-form-design.git 616550110
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License Code
|
||||
// +----------------------------------------------------------------------
|
||||
*/
|
||||
input:disabled {
|
||||
color: -internal-light-dark(rgb(84, 84, 84), rgb(170, 170, 170));
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.layui-input:hover,.layui-textarea:hover {
|
||||
border-color: #1890ff;
|
||||
border-radius: 0px 3px 3px 0px;
|
||||
}
|
||||
.layui-relation-delete {
|
||||
top: 5px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
right: 3px;
|
||||
}
|
||||
|
||||
.layui-icon-close {
|
||||
line-height: 13px;
|
||||
border-radius: 50%;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.layui-form-mid {
|
||||
padding: 6px 0px !important;
|
||||
display: inline-block;
|
||||
float: none;
|
||||
position: relative;
|
||||
top: 3px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
#relationModel .layui-input-inline {
|
||||
width: 139px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 450px) {
|
||||
|
||||
table .layui-input-inline {
|
||||
margin-left: 0px!important;
|
||||
}
|
||||
.layui-input-block {
|
||||
overflow-x: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-badge {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.component .head {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.component-group ol {
|
||||
display: inline-block;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
min-width: 70px;
|
||||
width: 32%;
|
||||
height: 70px;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
transition: all .2s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.component-group ol:hover {
|
||||
background: #1890ff;
|
||||
border-radius: 5px;
|
||||
color: #fff;
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
|
||||
.component-group ol .icon {
|
||||
padding: 10px 5px 12px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.component-group ol .icon i {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.layui-icon-switch {
|
||||
border: 1px solid #666;
|
||||
border-radius: 20px;
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.layui-icon-switch k {
|
||||
position: absolute;
|
||||
left: 4px;
|
||||
top: 2px;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 20px;
|
||||
background-color: #666;
|
||||
-webkit-transition: .1s linear;
|
||||
transition: .1s linear;
|
||||
}
|
||||
|
||||
.component {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.component-group ol:hover .layui-icon-switch {
|
||||
color: #fff;
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
.component-group ol:hover k {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.component-group ol .name {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.layui-col-md2,.layui-col-md8 {
|
||||
border-right: 1px solid #f6f6ff;
|
||||
}
|
||||
|
||||
.fr {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.layui-col-md8 {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.layui-col-md8 #formBuilder {
|
||||
height: 800px;
|
||||
overflow: auto;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.layui-col-md8 #formBuilder div.layui-form-item {
|
||||
border: 1px dashed #d1d1d1;
|
||||
margin-bottom: 5px;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.layui-col-md8 #formBuilder .children div.layui-form-item {
|
||||
width: 98%;
|
||||
padding: 0;
|
||||
padding-top: 3px;
|
||||
padding-right: 6px;
|
||||
margin-top: 5px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.layui-col-md8 #formBuilder div.layui-form-item:hover,.layui-col-md8 #formBuilder div.layui-form-item.active {
|
||||
border: 1px solid #1890ff;
|
||||
background-color: #e9f4fd !important;
|
||||
}
|
||||
|
||||
.layui-col-md8 #formBuilder .layui-form-item .layui-input:hover,
|
||||
.layui-col-md8 #formBuilder .layui-select:hover,
|
||||
.layui-col-md8 #formBuilder .layui-form-select:hover,
|
||||
.layui-col-md8 #formBuilder .layui-textarea:hover,
|
||||
.layui-col-md8 #formBuilder .layui-form-checked i:hover,
|
||||
.layui-col-md8 #formBuilder .layui-input:hover {
|
||||
border-color: #d1d1d1!important;
|
||||
}
|
||||
|
||||
.layui-col-md8 #formBuilder div.sortableghost {
|
||||
border: 1px dashed #d1d1d1;
|
||||
}
|
||||
|
||||
.layui-col-md8 #formBuilder ol.sortableghost {
|
||||
border: 1px dashed #d1d1d1;
|
||||
text-indent: 3px;
|
||||
box-sizing: border-box;
|
||||
content: '';
|
||||
overflow : hidden;
|
||||
padding : 0;
|
||||
}
|
||||
|
||||
.layui-col-md8 #formBuilder .sortablechosen {
|
||||
border: 1px solid #1890ff;
|
||||
background-color: #e9f4fd !important;
|
||||
}
|
||||
|
||||
.layui-col-md8 #formBuilder ol.sortable-chosen {
|
||||
border: 1px solid #d1d1d1;
|
||||
background-color: #e9f4fd !important;
|
||||
}
|
||||
|
||||
.layui-col-md8 #formBuilder ol.sortable-chosen div {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.layui-col-md8 #formBuilder .children {
|
||||
min-height: 50px;
|
||||
border: 1px dashed #ccc;
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
/* form .layui-rate {
|
||||
padding: 0px!important;
|
||||
} */
|
||||
/*
|
||||
form .layui-rate li {
|
||||
display: inline-block!important;
|
||||
}
|
||||
|
||||
form .layui-rate .layui-inline{
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
form .layui-rate li i.layui-icon {
|
||||
font-size: 16px!important;
|
||||
margin-right: 0px!important;
|
||||
} */
|
||||
|
||||
#layui-form-attribute .layui-input-inline {
|
||||
width: 169px;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
#layui-form-attribute .layui-form-label {
|
||||
padding: 5px 6px 5px 5px;
|
||||
width: 70px!important;
|
||||
}
|
||||
|
||||
.layui-minmax {
|
||||
width: 76px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.layui-input-inline em {
|
||||
margin: 0px 5px;
|
||||
}
|
||||
|
||||
.layui-component-tools {
|
||||
position: absolute;
|
||||
background: #1890ff;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 1px 5px;
|
||||
cursor: pointer;
|
||||
z-index: 21;
|
||||
color: #fff;
|
||||
width: 32px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
display: none;
|
||||
}
|
||||
.layui-input-none {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.layui-col-md8 #formBuilder div.active .layui-component-tools {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.sortableghost .layui-component-tools {
|
||||
display: none;
|
||||
}
|
||||
.layui-component-tools i,.layui-component-move i {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#layui-elem-field legend {
|
||||
margin-left: 39%;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#form-options input {
|
||||
width: 90px;
|
||||
display: inline-block;
|
||||
margin: 0px 8px;
|
||||
}
|
||||
|
||||
#form-options .layui-input-inline,#tab-options .layui-input-inline {
|
||||
width: auto;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#form-options .layui-icon,#tab-options .layui-icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#form-options .layui-icon-subtraction,#tab-options .layui-icon-subtraction {
|
||||
border: 1px solid red;
|
||||
color: red;
|
||||
border-radius: 3px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#tab-options input {
|
||||
width: 139px;
|
||||
display: inline-block;
|
||||
margin: 0px 8px;
|
||||
}
|
||||
|
||||
#form-options .layui-add-option,#tab-options .layui-add-tab {
|
||||
position: relative;
|
||||
left: 26px;
|
||||
}
|
||||
#Propertie .layui-slider {
|
||||
margin-top: 13px;
|
||||
}
|
||||
|
||||
#tpl_main,#tpl_right_main {
|
||||
margin: 25% auto;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
color: #c9e0f3;
|
||||
}
|
||||
|
||||
#layui-form-template .item-list {
|
||||
padding: 8px 0px;
|
||||
}
|
||||
|
||||
.item-body {
|
||||
border: 1px solid #f6f6f6;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.item-body:hover {
|
||||
border: 1px solid #409eff;
|
||||
}
|
||||
|
||||
.item-body .item-img {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.item-body .item-img img {
|
||||
width: 100%;;
|
||||
}
|
||||
|
||||
.item-body .item-desc {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.item-body .item-desc span.item-title{
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.right-button {
|
||||
float: right;
|
||||
padding: 1px 3px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.button--text {
|
||||
color: #409eff;
|
||||
background: 0 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.layui-htmlview {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.layui-htmlview textarea {
|
||||
display: block;
|
||||
width: 760px;
|
||||
height: 566px;
|
||||
border: 10px solid #F8F8F8;
|
||||
border-top-width: 0;
|
||||
padding: 10px;
|
||||
line-height: 20px;
|
||||
overflow: auto;
|
||||
background-color: #3F3F3F;
|
||||
color: #eee;
|
||||
font-size: 12px;
|
||||
font-family: Courier New;
|
||||
}
|
||||
|
||||
.layui-htmlview .layui-htmlbtn{
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
bottom:20px;
|
||||
}
|
||||
|
||||
#parse-table .layui-input {
|
||||
height: 30px;
|
||||
width: 139px;
|
||||
font-size: 12px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#formBuilder div.lay-slider {
|
||||
padding-top: 13px;
|
||||
}
|
||||
|
||||
#formBuilder div.layui-slider-input {
|
||||
margin-top: 13px;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
// 后端JS文件
|
||||
3
plugin/developer/uninstall.sql
Normal file
3
plugin/developer/uninstall.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
DROP TABLE IF EXISTS `__PREFIX__ceshi`;
|
||||
DROP TABLE IF EXISTS `__PREFIX__plugin`;
|
||||
DROP TABLE IF EXISTS `__PREFIX__generate`;
|
||||
Reference in New Issue
Block a user