项目初始化

This commit is contained in:
1099438829 2021-02-18 14:45:15 +08:00
parent df28ee1759
commit 4a4730d122
696 changed files with 137999 additions and 233 deletions

3
.constant Normal file
View File

@ -0,0 +1,3 @@
<?php
define('INSTALL_DATE',1605972689);
define('SERIALNUMBER','u2lzT0');

1
.example.env Normal file
View File

@ -0,0 +1 @@
APP_DEBUG = true [APP] CDN = http://apeblog.io/ DEFAULT_TIMEZONE = Asia/Shanghai [DATABASE] TYPE = mysql HOSTNAME = 127.0.0.1 DATABASE = test USERNAME = username PASSWORD = password HOSTPORT = 3306 CHARSET = utf8 DEBUG = true [LANG] default_lang = zh-cn

28
.gitignore vendored
View File

@ -1,18 +1,10 @@
# Build and Release Folders
bin-debug/
bin-release/
[Oo]bj/
[Bb]in/
# Other files and folders
.settings/
# Executables
*.swf
*.air
*.ipa
*.apk
# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
# should NOT be excluded as they contain compiler settings and other important
# information for Eclipse / Flash Builder.
/.idea
/.vscode
/public/uploads
*.log
*/.DS_Store
.env
/runtime
/composer.lock
/vendor/.gitignore
/vendor

1
.htaccess Normal file
View File

@ -0,0 +1 @@

227
LICENSE
View File

@ -1,201 +1,32 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
ThinkPHP遵循Apache2开源协议发布并提供免费使用。
版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)
All rights reserved。
ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
1. Definitions.
Apache Licence是著名的非盈利开源组织Apache采用的协议。
该协议和BSD类似鼓励代码共享和尊重原作者的著作权
允许代码修改,再作为开源或商业软件发布。需要满足
的条件:
1 需要给代码的用户一份Apache Licence
2 如果你修改了代码,需要在被修改的文件中说明;
3 在延伸的代码中(修改和有源代码衍生的代码中)需要
带有原来代码中的协议,商标,专利声明和其他原来作者规
定需要包含的说明;
4 如果再发布的产品中包含一个Notice文件则在Notice文
件中需要带有本协议内容。你可以在Notice中增加自己的
许可但不可以表现为对Apache Licence构成更改。
具体的协议参考http://www.apache.org/licenses/LICENSE-2.0
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

120
README.md
View File

@ -3,35 +3,121 @@
#### 介绍
猿博博客系统
## 主要特性
### 开源无加密
源码开源无加密
### TP6框架
使用最新的 ThinkPHP 6.0框架开发
### 标准接口
标准接口、前后端分离,二次开发更方便
### 无缝事件机制
行为扩展更方便,方便二次开发
### 后台快速生成表单
后台应用form-builder 无需写页面快速增删改查
### 强大的后台权限管理
后台多种角色、多重身份权限管理,权限可以控制到每一步操作
#### 软件架构
软件架构说明
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
## 自动安装
1. 上传文件到网站根目录
2. 运行composer install 安装依赖
3. 修改目录权限linux系统777
/public
/runtime
4. 配置好域名,在浏览器里打开域名,根据安装向导进行安装
5. 后台登录 http://域名/admin
## 手动安装
1.创建数据库,倒入数据库文件
数据库文件目录/public/install/learn.sql
2.修改数据库连接文件
配置文件路径/.env
~~~
APP_DEBUG = true
[APP]
DEFAULT_TIMEZONE = Asia/Shanghai
[DATABASE]
TYPE = mysql
HOSTNAME = 127.0.0.1 #数据库连接地址
DATABASE = test #数据库名称
USERNAME = username #数据库登录账号
PASSWORD = password #数据库登录密码
HOSTPORT = 3306 #数据库端口
CHARSET = utf8
DEBUG = true
[LANG]
default_lang = zh-cn
~~~
3.执行composer安装
~~~
comoposer install
~~~
4.创建目录并修改目录权限linux系统777
~~~
mkdir public/upload
mkdir runtime
chmod -R 777 public/upload
chmod -R 777 runtime
~~~
5.后台登录:
http://域名/admin
默认账号admin 密码123456
#### 使用说明
1. xxxx
1. 运行环境要求PHP7.1+。
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
#### 特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
> 运行环境要求PHP7.1+。
## 特别感谢
[笔下光年 / Light Year Admin 一个基于Bootstrap v3.3.7的后台HTML模板。](https://gitee.com/yinqi/Light-Year-Admin-Template)
[xaboy / form-builder PHP表单生成器使用PHP快速生成现代化的form表单。](https://gitee.com/xaboy/form-builder)
## 文档
[TP6开发手册](https://www.kancloud.cn/manual/thinkphp6_0/content)
[FormBuilder](http://php.form-create.com/)
[Light Year Admin](http://www.itshubao.com/doc-lyear/lyear.html)
[Workerman](http://doc.workerman.net/)
## 联系我
邮箱1099438829@qq.com
## 版权信息
ape-blog 遵循Apache2开源协议发布并提供免费使用。
本项目包含的第三方源码和二进制文件之版权信息另行标注。
版权所有Copyright © 2019-2020 by 木子的忧伤 (https://www.apecloud.cn)
All rights reserved。

1
app/.htaccess Normal file
View File

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

27
app/AppService.php Normal file
View File

@ -0,0 +1,27 @@
<?php
declare (strict_types = 1);
namespace app;
use learn\utils\Json;
use think\Service;
/**
* 应用服务类
*/
class AppService extends Service
{
public $bind = [
'json' => Json::class
];
public function register()
{
// 服务注册
}
public function boot()
{
// 服务启动
}
}

209
app/BaseController.php Normal file
View File

@ -0,0 +1,209 @@
<?php
declare (strict_types = 1);
namespace app;
use think\App;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\facade\View;
use think\Validate;
/**
* 控制器基础类
*/
abstract class BaseController
{
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
/**
* 是否批量验证
* @var bool
*/
protected $batchValidate = false;
/**
* 控制器中间件
* @var array
*/
protected $middleware = [];
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 控制器初始化
$this->initialize();
}
// 初始化
protected function initialize()
{}
/**
* 验证数据
* @access protected
* @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息
* @param bool $batch 是否批量验证
* @return array|string|true
* @throws ValidateException
*/
protected function validate(array $data, $validate, array $message = [], bool $batch = false)
{
if (is_array($validate)) {
$v = new Validate();
$v->rule($validate);
} else {
if (strpos($validate, '.')) {
// 支持场景
[$validate, $scene] = explode('.', $validate);
}
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
$v = new $class();
if (!empty($scene)) {
$v->scene($scene);
}
}
$v->message($message);
// 是否批量验证
if ($batch || $this->batchValidate) {
$v->batch(true);
}
return $v->failException(true)->check($data);
}
public function __call($method, $args)
{
return json(['status'=>'01','msg'=>'方法不存在']);
}
/**
* 操作成功跳转的快捷方法
* @access protected
* @param mixed $msg 提示信息
* @param string $url 跳转的URL地址
* @param mixed $data 返回的数据
* @param integer $wait 跳转等待时间
* @param array $header 发送的Header信息
* @return void
*/
protected function success($msg = '', string $url = null, $data = '', int $wait = 3, array $header = [])
{
if (is_null($url) && isset($_SERVER["HTTP_REFERER"])) {
$url = $_SERVER["HTTP_REFERER"];
} elseif ($url) {
$url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : app('route')->buildUrl($url);
}
$result = [
'code' => 1,
'msg' => $msg,
'data' => $data,
'url' => $url,
'wait' => $wait,
];
$type = $this->getResponseType();
if ($type == 'html'){
$response = view(config('app.dispatch_success_tmpl'), $result);
} else if ($type == 'json') {
$response = json($result);
}
throw new HttpResponseException($response);
}
/**
* 操作错误跳转的快捷方法
* @access protected
* @param mixed $msg 提示信息
* @param string $url 跳转的URL地址
* @param mixed $data 返回的数据
* @param integer $wait 跳转等待时间
* @param array $header 发送的Header信息
* @return void
*/
protected function error($msg = '', string $url = null, $data = '', int $wait = 3, array $header = [])
{
if (is_null($url)) {
$url = $this->request->isAjax() ? '' : 'javascript:history.back(-1);';
} elseif ($url) {
$url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : $this->app->route->buildUrl($url);
}
$result = [
'code' => 0,
'msg' => $msg,
'data' => $data,
'url' => $url,
'wait' => $wait,
];
$type = $this->getResponseType();
if ($type == 'html'){
$response = view(config('app.dispatch_success_tmpl'), $result);
} else if ($type == 'json') {
$response = json($result);
}
throw new HttpResponseException($response);
}
/**
* 获取当前的response 输出类型
* @access protected
* @return string
*/
protected function getResponseType()
{
return $this->request->isJson() || $this->request->isAjax() ? 'json' : 'html';
}
/**
* 视图赋值
* @param mixed ...$vars
*/
protected function assign(...$vars)
{
View::assign(...$vars);
}
/**
* 返回视图
* @return string
* @throws \Exception
*/
protected function fetch(string $template = '')
{
return View::fetch($template);
}
/**
* 页面
* @param mixed ...$args
*/
protected function redirect(...$args){
throw new HttpResponseException(redirect(...$args));
}
}

58
app/ExceptionHandle.php Normal file
View File

@ -0,0 +1,58 @@
<?php
namespace app;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\Response;
use Throwable;
/**
* 应用异常处理类
*/
class ExceptionHandle extends Handle
{
/**
* 不需要记录信息(日志)的异常类列表
* @var array
*/
protected $ignoreReport = [
HttpException::class,
HttpResponseException::class,
ModelNotFoundException::class,
DataNotFoundException::class,
ValidateException::class,
];
/**
* 记录异常信息(包括日志或者其它方式记录)
*
* @access public
* @param Throwable $exception
* @return void
*/
public function report(Throwable $exception): void
{
// 使用内置的方式记录异常日志
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @access public
* @param \think\Request $request
* @param Throwable $e
* @return Response
*/
public function render($request, Throwable $e): Response
{
// 添加自定义异常处理机制
// 其他错误交给系统处理
return parent::render($request, $e);
}
}

15
app/Request.php Normal file
View File

@ -0,0 +1,15 @@
<?php
namespace app;
// 应用请求对象类
use Spatie\Macroable\Macroable;
/**
* Class Request
* @package app
*/
class Request extends \think\Request
{
// 宏指令
use Macroable;
}

133
app/admin/common.php Normal file
View File

@ -0,0 +1,133 @@
<?php
use think\facade\Cache;
if (!function_exists('un_camelize'))
{
/**
* 驼峰法转下划线
* @param $camelCaps
* @param string $separator
* @return string
*/
function un_camelize($camelCaps, $separator='_')
{
return strtolower(preg_replace('/([a-z])([A-Z])/', "$1" . $separator . "$2", $camelCaps));
}
}
if (!function_exists('auth_is_exit'))
{
/**
* 判断授权信息是否存在
* @return bool
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
function auth_is_exit(int $adminId): bool
{
return Cache::store('redis')->has('store_'.$adminId);
}
}
if (!function_exists('remove_cache'))
{
/**
* 判断授权信息是否存在
* @return bool
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
function remove_cache(string $path): bool
{
$res = true;
if(is_dir($path)){
if ($handle = opendir($path)) {
while (false !== ($item = readdir($handle))) {
if ($item != '.' && $item != '..') {
if (is_dir($path . '/' . $item)) remove_cache($path . '/' . $item);
else unlink($path . '/' . $item);
}
}
closedir($handle);
if (rmdir($path)) $res = true;
}
}
return $res;
}
}
if (!function_exists('to_int_array'))
{
/**
* 字符串数组转int数组
* @return array
*/
function to_int_array(array $str): array
{
foreach ($str as $k=>$v) $str[$k] = (int)$v;
return $str;
}
}
if (!function_exists('tag_options'))
{
/**
* 获取form标签
* @return array
*/
function tag_options(): array
{
$menus[] = ['value'=>"input",'label'=>"input"];
$menus[] = ['value'=>"textarea",'label'=>"textarea"];
$menus[] = ['value'=>"select",'label'=>"select"];
return $menus;
}
}
if (!function_exists('type_options'))
{
/**
* 获取form标签
* @return array
*/
function type_options(): array
{
$menus[] = ['value'=>"text",'label'=>"text"];
$menus[] = ['value'=>"radio",'label'=>"radio"];
$menus[] = ['value'=>"password",'label'=>"password"];
$menus[] = ['value'=>"checkbox",'label'=>"checkbox"];
$menus[] = ['value'=>"number",'label'=>"number"];
$menus[] = ['value'=>"hidden",'label'=>"hidden"];
$menus[] = ['value'=>"email",'label'=>"email"];
$menus[] = ['value'=>"tel",'label'=>"tel"];
$menus[] = ['value'=>"date",'label'=>"date"];
$menus[] = ['value'=>"file",'label'=>"file"];
return $menus;
}
}
if (!function_exists('get_dir'))
{
/**
* 获取文件目录列表,该方法返回数组
* @param $dir
* @return mixed
* @date 2021-02-17 21:27
*/
function get_dir($dir) {
$dirArray[]=NULL;
if (false != ($handle = opendir ( $dir ))) {
$i=0;
while ( false !== ($file = readdir ( $handle )) ) {
//去掉"“.”、“..”以及带“.xxx”后缀的文件
if ($file != "." && $file != ".."&&!strpos($file,".")) {
$dirArray[$i]=$file;
$i++;
}
}
//关闭句柄
closedir ( $handle );
}
return $dirArray;
}
}

View File

@ -0,0 +1,25 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | 应用设置
// +----------------------------------------------------------------------
return [
// 是否强制使用路由
'url_route_must' => false,
// 合并路由规则
'route_rule_merge' => true,
// 路由是否完全匹配
'route_complete_match' => false,
// 是否自动转换URL中的控制器和操作名
'url_convert' => true,
];

View File

@ -0,0 +1,11 @@
<?php
// +----------------------------------------------------------------------
// | 会话设置
// +----------------------------------------------------------------------
return [
// 过期时间
'expire' => 1440,
// 前缀
'prefix' => 'zz_admin',
];

14
app/admin/config/view.php Normal file
View File

@ -0,0 +1,14 @@
<?php
// +----------------------------------------------------------------------
// | 模板设置
// +----------------------------------------------------------------------
return [
// 模板后缀
'view_suffix' => 'html',
// 视图输出字符串内容替换
'tpl_replace_string' => [
'__PUBLIC_PATH__' => '/', //public 目录
'__ADMIN_PATH__' => '/static/admin/', //全局静态目录
]
];

View File

@ -0,0 +1,217 @@
<?php
namespace app\admin\controller;
use app\admin\model\Admin as aModel;
use app\admin\model\AdminRole as rModel;
use app\Request;
use learn\services\UtilService as Util;
use FormBuilder\Factory\Elm;
use learn\services\FormBuilderService as Form;
use think\facade\Route as Url;
/**
* 账号管理
* Class Admin
* @package app\admin\controller\admin
*/
class Admin extends AuthController
{
/**
* 账号列表
* @return string
* @throws \Exception
*/
public function index()
{
$this->assign("auths",rModel::getAuthLst());
return $this->fetch();
}
/**
* 账号列表
* @param Request $request
* @return
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function lst(Request $request)
{
$where = Util::postMore([
['name',''],
['tel',''],
['start_time',''],
['end_time',''],
['role_id',''],
['status',''],
['page',1],
['limit',20],
]);
return app("json")->layui(aModel::systemPage($where));
}
/**
* 添加账号
* @param Request $request
* @return string
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function add(Request $request)
{
$form = array();
$form[] = Elm::input('name','登录账号')->col(10);
$form[] = Elm::input('nickname','昵称')->col(10);
$form[] = Elm::frameImage('avatar','头像',Url::buildUrl('admin/widget.images/index',array('fodder'=>'avatar','limit'=>1)))->icon("ios-image")->width('96%')->height('440px')->col(10);
$form[] = Elm::password('pwd','密码')->col(10);
$form[] = Elm::input('realname','真实姓名')->col(10);
$form[] = Elm::select('role_id','角色')->options(function(){
$list = rModel::getAuthLst();
$menus=[];
foreach ($list as $menu){
$menus[] = ['value'=>$menu['id'],'label'=>$menu['name']];//,'disabled'=>$menu['pid']== 0];
}
return $menus;
})->col(10);
$form[] = Elm::input('tel','电话')->col(10);
$form[] = Elm::email('mail','邮箱')->col(10);
$form[] = Elm::radio('status','状态',1)->options([['label'=>'启用','value'=>1],['label'=>'冻结','value'=>0]])->col(10);
$form = Form::make_post_form($form, url('save')->build());
$this->assign(compact('form'));
return $this->fetch("public/form-builder");
}
/**
* 修改账号
* @return string
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function edit($id="")
{
if (!$id) return app("json")->fail("账号id不能为空");
$ainfo = aModel::get($id);
if (!$ainfo) return app("json")->fail("没有该账号");
$form = array();
$form[] = Elm::input('name','登录账号',$ainfo['name'])->col(10);
$form[] = Elm::input('nickname','昵称',$ainfo['nickname'])->col(10);
$form[] = Elm::frameImage('avatar','头像',Url::buildUrl('admin/widget.images/index',array('fodder'=>'avatar','limit'=>1)),$ainfo['avatar'])->icon("ios-image")->width('96%')->height('440px')->col(10);
$form[] = Elm::password('pwd','密码',$ainfo['pwd'])->col(10);
$form[] = Elm::input('realname','真实姓名',$ainfo['realname'])->col(10);
$form[] = Elm::select('role_id','角色',$ainfo['role_id'])->options(function(){
$list = rModel::getAuthLst();
$menus=[];
foreach ($list as $menu){
$menus[] = ['value'=>$menu['id'],'label'=>$menu['name']];//,'disabled'=>$menu['pid']== 0];
}
return $menus;
})->col(10);
$form[] = Elm::input('tel','电话',$ainfo['tel'])->col(10);
$form[] = Elm::email('mail','邮箱',$ainfo['mail'])->col(10);
$form[] = Elm::radio('status','状态',$ainfo['status'])->options([['label'=>'启用','value'=>1],['label'=>'冻结','value'=>0]])->col(10);
$form = Form::make_post_form($form, url('save',['id'=>$id])->build());
$this->assign(compact('form'));
return $this->fetch("public/form-builder");
}
/**
* 保存修改
* @param string $id
* @return mixed
*/
public function save($id="")
{
$data = Util::postMore([
['name',''],
['nickname',''],
['avatar',''],
['pwd',''],
['realname',''],
['role_id',''],
['tel',''],
['mail',''],
['status','']
]);
if ($data['name'] == "") return app("json")->fail("登录账号不能为空");
if ($data['pwd'] == "") return app("json")->fail("密码不能为空");
if ($data['tel'] == "") return app("json")->fail("手机号不能为空");
if ($data['mail'] == "") return app("json")->fail("邮箱不能为空");
if (is_array($data['avatar'])) $data['avatar'] = $data['avatar'][0];
if ($id=="")
{
//判断下用户是否存在
$info = aModel::where('name',$data['name'])->find();
if ($info){
return app("json")->fail("用户已存在");
}
$data['pwd'] = md5(md5($data['pwd']));
$data['ip'] = $this->request->ip();
$data['create_user'] = $this->adminId;
$data['create_time'] = time();
$res = aModel::insert($data);
}else
{
$ainfo = aModel::get($id);
if ($ainfo['pwd'] != $data['pwd']) $data['pwd'] = md5(md5($data['pwd']));
$data['update_user'] = $this->adminId;
$data['update_time'] = time();
$res = aModel::update($data,['id'=>$id]);
}
return $res ? app("json")->success("操作成功",'code') : app("json")->fail("操作失败");
}
/**
* 修改密码
* @param Request $request
* @return string
* @throws \Exception
*/
public function pwd(Request $request)
{
return $this->fetch();
}
/**
* 修改密码
* @param Request $request
* @return mixed
*/
public function changePwd(Request $request)
{
$data = Util::postMore([
['oldpwd',''],
['newpwd','']
]);
if ($data['oldpwd'] == '' || $data['newpwd'] == '') return app("json")->fail("参数有误,新旧密码为空!");
if ($this->adminInfo['pwd'] == md5(md5($data['oldpwd']))) return aModel::update(['pwd'=>md5(md5($data['newpwd']))],['id'=>$this->adminId]) ? app("json")->success("操作成功") : app("json")->fail("操作失败");
return app("json")->fail("密码不正确!");
}
/**
* 个人信息
* @return string
* @throws \Exception
*/
public function profile()
{
$this->assign("info",aModel::get($this->adminId));
return $this->fetch();
}
/**
* 修改密码
* @param Request $request
* @return mixed
*/
public function changProfile(Request $request)
{
$data = Util::postMore([
['nickname',''],
['avatar',''],
['tel',''],
['mail',''],
['remark','']
]);
if ($data['nickname'] == '' || $data['avatar'] == '' || $data['tel'] == '' || $data['mail'] == '') return app("json")->fail("必选项不能为空!");
return aModel::update(['nickname'=>$data['nickname'],'avatar'=>$data['avatar'],'tel'=>$data['tel'],'mail'=>$data['mail'],'remark'=>$data['remark']],['id'=>$this->adminId]) ? app("json")->success("操作成功") : app("json")->fail("操作失败");
}
}

View File

@ -0,0 +1,150 @@
<?php
namespace app\admin\controller;
use app\admin\model\AdminAuth as aModel;
use app\Request;
use FormBuilder\Exception\FormBuilderException;
use learn\services\UtilService as Util;
use FormBuilder\Factory\Elm;
use learn\services\FormBuilderService as Form;
use think\facade\Route as Url;
/**
* 权限管理
* Class AdminAuth
* @package app\admin\controller\admin
*/
class AdminAuth extends AuthController
{
public function index()
{
return $this->fetch();
}
/**
* 权限列表
* @param Request $request
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function lst(Request $request)
{
$where = Util::postMore([
['name',''],
['status','']
]);
return app("json")->layui(aModel::systemPage($where));
}
/**
* 添加
* @param int $pid
* @return string
* @throws FormBuilderException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function add($pid = 0)
{
$form = array();
$form[] = Elm::select('pid','上级权限',(int)$pid)->options(aModel::returnOptions())->col(10);
$form[] = Elm::input('name','权限名称')->col(10);
$form[] = Elm::frameInput('icon','图标',Url::buildUrl('admin/widget.icon/index',array('fodder'=>'icon')))->icon("ios-ionic")->width('96%')->height('390px')->col(10);
$form[] = Elm::input('module','模块名')->col(10);
$form[] = Elm::input('controller','控制器名')->col(10);
$form[] = Elm::input('action','方法名')->col(10);
$form[] = Elm::input('params','参数')->placeholder("php数组,不懂不要填写")->col(10);
$form[] = Elm::number('rank','排序')->col(10);
$form[] = Elm::radio('is_menu','是否菜单',1)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(10);
$form[] = Elm::radio('status','状态',1)->options([['label'=>'启用','value'=>1],['label'=>'冻结','value'=>0]])->col(10);
$form = Form::make_post_form($form, url('save')->build());
$this->assign(compact('form'));
return $this->fetch("public/form-builder");
}
/**
* 添加
* @param int $id
* @return string
* @throws FormBuilderException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function edit($id = 0)
{
if (!$id) return app("json")->fail("权限id不能为空");
$ainfo = aModel::get($id);
if (!$ainfo) return app("json")->fail("没有该权限");
$form = array();
$form[] = Elm::select('pid','上级权限',$ainfo['pid'])->options(aModel::returnOptions())->col(10);
$form[] = Elm::input('name','权限名称',$ainfo['name'])->col(10);
$form[] = Elm::frameInput('icon','图标',Url::buildUrl('admin/widget.icon/index',array('fodder'=>'icon')),$ainfo['icon'])->icon("ios-ionic")->width('96%')->height('390px')->col(10);
$form[] = Elm::input('module','模块名',$ainfo['module'])->col(10);
$form[] = Elm::input('controller','控制器名',$ainfo['controller'])->col(10);
$form[] = Elm::input('action','方法名',$ainfo['action'])->col(10);
$form[] = Elm::input('params','参数',$ainfo['params'])->placeholder("php数组,不懂不要填写")->col(10);
$form[] = Elm::number('rank','排序',$ainfo['rank'])->col(10);
$form[] = Elm::radio('is_menu','是否菜单',$ainfo['is_menu'])->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(10);
$form[] = Elm::radio('status','状态',$ainfo['status'])->options([['label'=>'启用','value'=>1],['label'=>'冻结','value'=>0]])->col(10);
$form = Form::make_post_form($form, url('save',['id'=>$id])->build());
$this->assign(compact('form'));
return $this->fetch("public/form-builder");
}
/**
* 保存
* @param $id
* @return
*/
public function save($id="")
{
$data = Util::postMore([
['name',''],
['pid',0],
['icon',''],
['module',''],
['controller',''],
['action',''],
['params',''],
['rank',0],
['is_menu',1],
['status',1]
]);
if ($data['name'] == "") return app("json")->fail("权限名称不能为空");
if ($data['pid'] == "") return app("json")->fail("上级归属不能为空");
if ($data['module'] == "") return app("json")->fail("模块名不能为空");
if ($data['controller'] == "") return app("json")->fail("控制器名不能为空");
if ($data['action'] == "") return app("json")->fail("方法名不能为空");
$data['path'] = '/'.$data['module'].'/'.$data['controller'].'/'.$data['action'];
if ($id=="")
{
$data['create_user'] = $this->adminId;
$data['create_time'] = time();
$res = aModel::insert($data);
}else
{
$data['update_user'] = $this->adminId;
$data['update_time'] = time();
$res = aModel::update($data,['id'=>$id]);
}
return $res ? app("json")->success("操作成功",'code') : app("json")->fail("操作失败");
}
/**
* 修改字段
* @param $id
* @return aModel
*/
public function field($id)
{
if (!$id) return app("json")->fail("参数有误Id为空");
$where = Util::postMore([['field',''],['value','']]);
if ($where['field'] == '' || $where['value'] =='') return app("json")->fail("参数有误!");
return aModel::update([$where['field']=>$where['value']],['id'=>$id]) ? app("json")->success("操作成功") : app("json")->fail("操作失败");
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace app\admin\controller;
/**
* 图标
* Class AdminIcon
* @package app\admin\controller\admin
*/
class AdminIcon extends AuthController
{
public function index()
{
return $this->fetch();
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace app\admin\controller;
use app\admin\model\AdminLog as lModel;
use app\Request;
use learn\services\UtilService as Util;
/**
* 日志
* Class AdminLog
* @package app\admin\controller\admin
*/
class AdminLog extends AuthController
{
protected $noNeedLogin = ['index'];
/**
* 主页
* @return string
* @throws \Exception
*/
public function index()
{
return $this->fetch();
}
/**
* 权限列表
* @param Request $request
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function lst(Request $request)
{
$where = Util::postMore([
['name',''],
['ip',''],
['start_time',''],
['end_time',''],
['page',1],
['limit',20],
]);
return app("json")->layui(lModel::systemPage($where));
}
/**
* 清空日志
* @param Request $request
* @throws \Exception
*/
public function empty(Request $request)
{
$res = lModel::where("1=1")->delete();
return $res ? app("json")->success("操作成功",'code') : app("json")->fail("操作失败");
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace app\admin\controller;
use learn\services\UtilService as Util;
use app\admin\model\AdminNotify as nModel;
/**
* 消息提醒
* Class AdminNotify
* @package app\admin\controller\admin
*/
class AdminNotify extends AuthController
{
/**
* 列表
* @return mixed
* @throws \Exception
*/
public function index()
{
$where = Util::postMore([
['title',''],
['start_time',''],
['end_time',''],
['is_read',''],
['aid',$this->adminId],
]);
$this->assign("where",$where);
$this->assign("list",nModel::systemPage($where));
return $this->fetch();
}
}

View File

@ -0,0 +1,113 @@
<?php
namespace app\admin\controller;
use app\admin\model\AdminRole as rModel;
use app\admin\model\AdminAuth as aModel;
use app\Request;
use FormBuilder\Exception\FormBuilderException;
use learn\services\UtilService as Util;
use FormBuilder\Factory\Elm;
use learn\services\FormBuilderService as Form;
class AdminRole extends AuthController
{
public function index()
{
return $this->fetch();
}
/**
* 角色列表
* @param Request $request
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function lst(Request $request)
{
return app("json")->layui(rModel::systemPage());
}
/**
* 添加
* @param int $pid
* @return string
* @throws FormBuilderException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function add($pid = 0)
{
$form = array();
$form[] = Elm::select('pid','所属上级',(int)$pid)->options(rModel::returnOptions())->filterable(true)->col(18);
$form[] = Elm::input('name','角色名称')->col(18);
$form[] = Elm::treeChecked('tree_data','选择权限')->data(aModel::selectAndBuildTree(0,$pid != 0 ? explode(",",rModel::get($pid)['auth']) : ($this->adminId == 1 ? aModel::getIds() : $this->auth)))->col(18);
$form[] = Elm::number('rank','排序')->col(18);
$form[] = Elm::radio('status','状态',1)->options([['label'=>'启用','value'=>1],['label'=>'冻结','value'=>0]])->col(18);
$form = Form::make_post_form($form, url('save')->build());
$this->assign(compact('form'));
return $this->fetch("public/form-builder");
}
/**
* 添加
* @param int $id
* @return string
* @throws FormBuilderException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function edit($id = 0)
{
if (!$id) return app("json")->fail("权限id不能为空");
$rinfo = rModel::get($id);
if (!$rinfo) return app("json")->fail("没有该权限");
$form = array();
$form[] = Elm::select('pid','所属上级',$rinfo['pid'])->options(rModel::returnOptions())->filterable(true)->col(18);
$form[] = Elm::input('name','角色名称',$rinfo['name'])->col(18);
$form[] = Elm::treeChecked('tree_data','选择权限',to_int_array(explode(",",$rinfo['tree_data'])))->data(aModel::selectAndBuildTree(0,$rinfo['pid'] == 0 ? aModel::getIds() : explode(",",rModel::get($rinfo['pid'])['auth'])))->col(18);
$form[] = Elm::number('rank','排序',$rinfo['rank'])->col(18);
$form[] = Elm::radio('status','状态',$rinfo['status'])->options([['label'=>'启用','value'=>1],['label'=>'冻结','value'=>0]])->col(18);
$form = Form::make_post_form($form, url('save',['id'=>$id])->build());
$this->assign(compact('form'));
return $this->fetch("public/form-builder");
}
/**
* 保存
* @param string $id
* @return mixed
*/
public function save($id="")
{
$data = Util::postMore([
['name',''],
['pid',0],
['tree_data',''],
['rank',0],
['status',1]
]);
if ($data['name'] == "") return app("json")->fail("角色名称不能为空");
if ($data['pid'] == "") return app("json")->fail("上级归属不能为空");
if ($data['tree_data'] == "") return app("json")->fail("权限不能为空");
$data['auth'] = aModel::getIds($data['tree_data']);
$data['auth'] = implode(",",array_diff(array_unique($data['auth']),[0]));
$data['tree_data'] = implode(",",$data['tree_data']);
if ($id=="")
{
$data['create_user'] = $this->adminId;
$data['create_time'] = time();
$res = rModel::insert($data);
}else
{
$data['update_user'] = $this->adminId;
$data['update_time'] = time();
$res = rModel::update($data,['id'=>$id]);
}
return $res ? app("json")->success("操作成功",'code') : app("json")->fail("操作失败");
}
}

View File

@ -0,0 +1,106 @@
<?php
namespace app\admin\controller;
use app\admin\model\Document;
use app\admin\model\DocumentArticle;
use app\admin\model\DocumentProduct;
use app\Request;
use learn\services\UtilService as Util;
/**
* Class Article
* @package app\admin\controller\system
* @author 李玉坤
* @date 2021-02-15 23:20
*/
class Article extends AuthController
{
/**
* 账号列表
* @return string
* @throws \Exception
*/
public function index()
{
return $this->fetch();
}
/**
* 文章列表
* @param Request $request
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 李玉坤
* @date 2021-02-15 23:26
*/
public function lst(Request $request)
{
$where = Util::postMore([
['name',''],
['start_time',''],
['end_time',''],
['status',''],
['page',1],
['limit',20],
]);
return app("json")->layui(Document::systemPage($where));
}
/**
* 更新
* @param Request $request
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 李玉坤
* @date 2021-02-16 21:15
*/
public function update(Request $request)
{
$data = Util::postMore([
['id',''],
['title',''],
['category_id',''],
['keywords',''],
['description',''],
['type','article'],
['isrecommend',0],
['istop',0],
['link_str',''],
['cover_path',''],
['display',1],
['sort',''],
['status',1],
]);
if ($data['id'] == '') return app("json")->fail("参数有误Id为空");
$id = $data['id'];
unset($data['id']);
$saveData = [];
foreach ($data as $key=>$value){
if ($value !== ''){
$saveData[$key] = $value;
}
}
return Document::update($saveData,['id'=>$id]) ? app("json")->success("操作成功") : app("json")->fail("操作失败");
}
/**
* 修改字段
* @param $id
* @return mixed
* @author 李玉坤
* @date 2021-02-16 23:12
*/
public function field($id)
{
if (!$id) return app("json")->fail("参数有误Id为空");
$where = Util::postMore([['field',''],['value','']]);
if ($where['field'] == '' || $where['value'] =='') return app("json")->fail("参数有误!");
return Document::update([$where['field']=>$where['value']],['id'=>$id]) ? app("json")->success("操作成功") : app("json")->fail("操作失败");
}
}

View File

@ -0,0 +1,169 @@
<?php
namespace app\admin\controller;
use app\admin\model\AdminAuth;
use app\admin\model\AdminRole;
use think\facade\App;
use think\facade\Lang;
use think\facade\Session;
/**
* 控制器基础类
*/
abstract class AuthController extends SystemBasic
{
/**
* model
* @var
*/
protected $model = null;
/**
* 当前登陆管理员信息
* @var
*/
protected $adminInfo;
/**
* 当前登陆管理员ID
* @var int
*/
protected $adminId;
/**
* 当前管理员权限
* @var array
*/
protected $auth = [];
/**
* 当前权限id
* @var int
*/
protected $nowAuthId = 0;
/**
* 无需登录的方法,同时也就不需要鉴权了
* @var array
*/
protected $noNeedLogin = [];
/**
* 无需鉴权的方法,但需要登录
* @var array
*/
protected $noNeedRight = [];
/**
* 无需记录日志
* @var array
*/
protected $noNeedLog = [];
/**
* 当前模块
* @var string
*/
private $module = "";
/**
* 当前控制器
* @var string
*/
private $controller = "";
/**
* 当前方法名
* @var string
*/
private $action = "";
/**
* Trait
*/
use TemplateTrait;
/**
* 初始化
*/
protected function initialize()
{
parent::initialize(); // TODO: Change the autogenerated stub
$this->adminInfo = Session::get("adminInfo");
$this->adminId = Session::get("adminId");
$this->module = App::getInstance()->http->getName();
$this->controller = un_camelize($this->request->controller());
$this->action = $this->request->action();
$this->auth = explode(",", AdminRole::getAuth($this->adminInfo['role_id'] ?? 0));
$this->nowAuthId = AdminAuth::getAuthId($this->module,$this->controller,$this->action);
$this->model = $this->buildModel($this->module,$this->request->controller());
// 鉴权
$this->checkAuth();
// 多语言
$this->loadLang();
// 日志
$this->createLog();
}
/**
* 检验权限
*/
protected function checkAuth()
{
// 不需要登录
if (in_array($this->action,$this->noNeedLogin) || $this->noNeedLogin == ['*'] || $this->noNeedLogin == "*") return true;
// 验证登录
if (!self::isActive()) exit($this->failedNotice(lang("未登录"),"/admin/login/login"));
// 权限验证
if ($this->nowAuthId == -1 || in_array($this->nowAuthId,$this->auth)) return true;
exit($this->failed(lang('没有权限!')));
}
/**
* 加载语言文件
*/
protected function loadLang()
{
Lang::load(App::getRootPath() . 'app/' . $this->module . '/lang/' . Lang::getLangSet() . '/' . $this->controller . '.php');
}
/**
* 验证登录
* @return bool
*/
protected static function isActive()
{
return Session::has('adminId') && Session::has('adminInfo');
}
/**
* 记录日志
* @return bool
*/
protected function createLog()
{
// 不需要登录不能记录日志
if (in_array($this->action,$this->noNeedLogin) || $this->noNeedLogin == ['*'] || $this->noNeedLogin == "*") return true;
// 无需记录日志
if (in_array($this->action,$this->noNeedLog) || $this->noNeedLog == ['*'] || $this->noNeedLog == "*") return true;
// 有操作权限,记录日志
if (in_array($this->nowAuthId,$this->auth)) event("AdminLog",[$this->adminInfo,$this->module,$this->controller,$this->action]);
return false;
}
/**
* 生成model路径
* @param string $module
* @param string $controller
* @return object|\think\App|null
*/
protected function buildModel(string $module, string $controller)
{
$path = explode(".", $this->request->controller());
$modelPath = "app\\{$this->module}\\model";
foreach ($path as $v) $modelPath .= "\\".$v;
if (class_exists($modelPath)) return app($modelPath);
return null;
}
}

View File

@ -0,0 +1,158 @@
<?php
namespace app\admin\controller;
use app\admin\model\DocumentCategory as aModel;
use app\Request;
use FormBuilder\Exception\FormBuilderException;
use FormBuilder\Factory\Elm;
use learn\services\FormBuilderService as Form;
use learn\services\UtilService as Util;
use think\facade\Route as Url;
/**
* Class Article
* @package app\admin\controller\system
* @author 李玉坤
* @date 2021-02-15 23:20
*/
class Category extends AuthController
{
/**
* 分类
* @return string
* @throws \Exception
* @author 李玉坤
* @date 2021-02-17 11:40
*/
public function index()
{
return $this->fetch();
}
/**
* 权限列表
* @param Request $request
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function lst(Request $request)
{
$where = Util::postMore([
['name',''],
['status','']
]);
return app("json")->layui(aModel::systemPage($where));
}
/**
* 添加
* @param int $pid
* @return string
* @throws FormBuilderException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function add($pid = 0)
{
$form = array();
$form[] = Elm::select('pid','上级权限',(int)$pid)->options(aModel::returnOptions())->col(10);
$form[] = Elm::input('name','权限名称')->col(10);
$form[] = Elm::frameInput('icon','图标',Url::buildUrl('admin/widget.icon/index',array('fodder'=>'icon')))->icon("ios-ionic")->width('96%')->height('390px')->col(10);
$form[] = Elm::input('module','模块名')->col(10);
$form[] = Elm::input('controller','控制器名')->col(10);
$form[] = Elm::input('action','方法名')->col(10);
$form[] = Elm::input('params','参数')->placeholder("php数组,不懂不要填写")->col(10);
$form[] = Elm::number('rank','排序')->col(10);
$form[] = Elm::radio('is_menu','是否菜单',1)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(10);
$form[] = Elm::radio('status','状态',1)->options([['label'=>'启用','value'=>1],['label'=>'冻结','value'=>0]])->col(10);
$form = Form::make_post_form($form, url('save')->build());
$this->assign(compact('form'));
return $this->fetch("public/form-builder");
}
/**
* 添加
* @param int $id
* @return string
* @throws FormBuilderException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function edit($id = 0)
{
if (!$id) return app("json")->fail("权限id不能为空");
$ainfo = aModel::get($id);
if (!$ainfo) return app("json")->fail("没有该权限");
$form = array();
$form[] = Elm::select('pid','上级权限',$ainfo['pid'])->options(aModel::returnOptions())->col(10);
$form[] = Elm::input('name','权限名称',$ainfo['name'])->col(10);
$form[] = Elm::frameInput('icon','图标',Url::buildUrl('admin/widget.icon/index',array('fodder'=>'icon')),$ainfo['icon'])->icon("ios-ionic")->width('96%')->height('390px')->col(10);
$form[] = Elm::input('module','模块名',$ainfo['module'])->col(10);
$form[] = Elm::input('controller','控制器名',$ainfo['controller'])->col(10);
$form[] = Elm::input('action','方法名',$ainfo['action'])->col(10);
$form[] = Elm::input('params','参数',$ainfo['params'])->placeholder("php数组,不懂不要填写")->col(10);
$form[] = Elm::number('rank','排序',$ainfo['rank'])->col(10);
$form[] = Elm::radio('is_menu','是否菜单',$ainfo['is_menu'])->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(10);
$form[] = Elm::radio('status','状态',$ainfo['status'])->options([['label'=>'启用','value'=>1],['label'=>'冻结','value'=>0]])->col(10);
$form = Form::make_post_form($form, url('save',['id'=>$id])->build());
$this->assign(compact('form'));
return $this->fetch("public/form-builder");
}
/**
* 保存
* @param $id
* @return
*/
public function save($id="")
{
$data = Util::postMore([
['name',''],
['pid',0],
['icon',''],
['module',''],
['controller',''],
['action',''],
['params',''],
['rank',0],
['is_menu',1],
['status',1]
]);
if ($data['name'] == "") return app("json")->fail("权限名称不能为空");
if ($data['pid'] == "") return app("json")->fail("上级归属不能为空");
if ($data['module'] == "") return app("json")->fail("模块名不能为空");
if ($data['controller'] == "") return app("json")->fail("控制器名不能为空");
if ($data['action'] == "") return app("json")->fail("方法名不能为空");
$data['path'] = '/'.$data['module'].'/'.$data['controller'].'/'.$data['action'];
if ($id=="")
{
$data['create_user'] = $this->adminId;
$data['create_time'] = time();
$res = aModel::insert($data);
}else
{
$data['update_user'] = $this->adminId;
$data['update_time'] = time();
$res = aModel::update($data,['id'=>$id]);
}
return $res ? app("json")->success("操作成功",'code') : app("json")->fail("操作失败");
}
/**
* 修改字段
* @param $id
* @return aModel
*/
public function field($id)
{
if (!$id) return app("json")->fail("参数有误Id为空");
$where = Util::postMore([['field',''],['value','']]);
if ($where['field'] == '' || $where['value'] =='') return app("json")->fail("参数有误!");
return aModel::update([$where['field']=>$where['value']],['id'=>$id]) ? app("json")->success("操作成功") : app("json")->fail("操作失败");
}
}

View File

@ -0,0 +1,213 @@
<?php
namespace app\admin\controller;
use app\admin\model\Attachment;
use learn\services\storage\QcloudCoService;
use learn\services\UtilService as Util;
use think\facade\Filesystem;
class Files extends AuthController
{
/**
* 单个图片上传
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function image()
{
$file = $this->request->file("file");
switch (system_config("storage_type"))
{
case 1:
$savename = Filesystem::putFile( 'image', $file);
$filePath = "/uploads/".$savename;
break;
case 2:
$savename = Filesystem::putFile( 'image', $file);
$ext = $file->getOriginalExtension();
$key = '/image/'.date('Ymd')."/".substr(md5($file->getRealPath()) , 0, 5). date('YmdHis') . rand(0, 9999) . '.' . $ext;
$filePath = QcloudCoService::put($key, $file->getRealPath());
break;
}
return Attachment::addAttachment($this->request->param("cid",0),$savename,$filePath,'image',$file->getMime(),$file->getSize(),system_config("storage_type")) ? app("json")->code()->success("上传成功",['filePath'=>$filePath,"name"=>$savename]) : app("json")->fail("上传失败");
}
/**
* base64转image
* @return mixed
*/
public function baseToImage()
{
$data = Util::postMore([
['image','']
]);
if ($data['image'] == '') return app("json")->fail("上传失败,没有文件");
$path = "uploads/image/".date("Ymd").'/';
if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $data['image'], $result)){
$type = $result[2];
if(!file_exists($path)) mkdir($path, 0755,true);
$savename = $path.md5(time()).".{$type}";
if (file_put_contents($savename, base64_decode(str_replace($result[1], '', $data['image'])))) return app("json")->success("上传成功",['src'=>"/".$savename]);
else return app("json")->fail("上传失败,写入文件失败!");
}else return app("json")->fail("上传失败,图片格式有误!");
}
/**
* tinymec
* @return mixed
*/
public function tinymce()
{
$savename = Filesystem::putFile( 'image', request()->file('file'));
return json_encode(['location'=>"/uploads/".$savename]);
}
/**
* 上传多图片
* @return mixed
*/
public function images()
{
return Filesystem::putFile( 'image', request()->file('file')) ? app("json")->code()->success("上传成功") : app("json")->fail("上传失败");
}
/**
* 证书上传
* @return mixed
*/
public function cert()
{
$file = $this->request->file("file");
$savename = Filesystem::putFile( 'file', $file);
$filePath = "/uploads/".$savename;
return $savename ? app("json")->code()->success("上传成功",['filePath'=>$filePath,"name"=>$savename]) : app("json")->fail("上传失败");
}
/**
* 上传文件到cid:0,
* 图片 视频 音频
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function file()
{
$file = $this->request->file("file");
try {
$savename = Filesystem::putFile( 'file', $file);
$filePath = "/uploads/".$savename;
return $savename ? app("json")->code()->success("上传成功",['filePath'=>$filePath,"name"=>$savename]) : app("json")->fail("上传失败");
} catch (\think\exception\ValidateException $e) {
return app("json")->fail($e->getMessage());
}
}
/**
* @文档上传
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function document()
{
// 获取表单上传文件 例如上传了001.jpg
$file = request()->file('file');//根据表单name替换imgFile
try {
// 使用验证器验证上传的文件
validate(['file' => [
// 限制文件大小(单位b)这里限制为5M
'fileSize' => 5 * 1024 * 1024,
// 限制文件后缀,多个后缀以英文逗号分割
'fileExt' => 'pdf,doc,docx'
// 更多规则请看“上传验证”的规则文档地址https://www.kancloud.cn/manual/thinkphp6_0/1037629#_444
]])->check(['file' => $file]);
$savename = Filesystem::putFile( 'file', $file);
$filePath = "/uploads/".$savename;
return $savename ? app("json")->code()->success("上传成功",['filePath'=>$filePath,"name"=>$savename]) : app("json")->fail("上传失败");
} catch (\think\exception\ValidateException $e) {
return app("json")->fail($e->getMessage());
}
}
/**
* @单文件上传
* @param string $type 类型 files images documents banners
* @return mixed
*/
public function upload()
{
if(Request::isPost()) {
// 获取表单上传文件 例如上传了001.jpg
$file = request()->file('file');//根据表单name替换imgFile
$type = $this->request->post("type");
$type = $type ?:'files';
switch ($type) {
case 'files':
$fileSize = 10 * 1024 * 1024;
$fileExt = 'pdf,doc,docx';
break;
case 'banner':
$fileSize = 5 * 1024 * 1024;
$fileExt = 'png,jpeg,jpg';
break;
case 'documents':
$fileSize = 5 * 1024 * 1024;
$fileExt = 'pdf,doc,docx';
break;
case 'image':
$fileSize = 5 * 1024 * 1024;
$fileExt = 'png,jpeg,jpg';
break;
case 'images':
$fileSize = 5 * 1024 * 1024;
$fileExt = 'png,jpeg,jpg';
break;
case 'template':
$fileSize = 5 * 1024 * 1024;
$fileExt = 'pdf,doc,docx';
break;
case 'talentpool':
$fileSize = 5 * 1024 * 1024;
$fileExt = 'pdf,doc,docx,png,jpeg,jpg';
break;
case 'offer':
$fileSize = 5 * 1024 * 1024;
$fileExt = 'pdf,doc,docx,png,jpeg,jpg';
break;
case 'contract':
$fileSize = 5 * 1024 * 1024;
$fileExt = 'pdf,doc,docx,png,jpeg,jpg';
break;
default:
$fileSize = 0 * 1024 * 1024;
$fileExt = 'pdf,doc,docx';
break;
}
// Log::record('yangzailu::');
// Log::record($fileExt);
try {
// 使用验证器验证上传的文件
validate(['file' => [
// 限制文件大小(单位b)这里限制为5M
'fileSize' => $fileSize,
// 限制文件后缀,多个后缀以英文逗号分割
'fileExt' => $fileExt
// 更多规则请看“上传验证”的规则文档地址https://www.kancloud.cn/manual/thinkphp6_0/1037629#_444
]])->check(['file' => $file]);
$savename = Filesystem::putFile( $type, $file);
$filePath = "/uploads/".$savename;
return $savename ? app("json")->code()->success("上传成功",['filePath'=>$filePath,"name"=>basename($savename)]) : app("json")->fail("上传失败");
} catch (ValidateException $e) {
return app("json")->fail($e->getMessage());
}
}else{
return app("json")->fail('上传失败');
}
}
}

View File

@ -0,0 +1,95 @@
<?php
namespace app\admin\controller;
use app\admin\model\FriendLink as aModel;
use app\Request;
use learn\services\UtilService as Util;
/**
* Class Message
* @package app\admin\controller\system
* @author 李玉坤
* @date 2021-02-15 23:20
*/
class FriendLink extends AuthController
{
/**
* 账号列表
* @return string
* @throws \Exception
*/
public function index()
{
return $this->fetch();
}
/**
* 文章列表
* @param Request $request
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 李玉坤
* @date 2021-02-15 23:26
*/
public function lst(Request $request)
{
$where = Util::postMore([
['name',''],
['status',''],
['page',1],
['limit',20],
]);
return app("json")->layui(aModel::systemPage($where));
}
/**
* 更新
* @param Request $request
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 李玉坤
* @date 2021-02-16 21:15
*/
public function update(Request $request)
{
$data = Util::postMore([
['id',''],
['title',''],
['url',''],
['image',''],
['description',''],
['sort',''],
['status',1],
]);
if ($data['id'] == '') return app("json")->fail("参数有误Id为空");
$id = $data['id'];
unset($data['id']);
$saveData = [];
foreach ($data as $key=>$value){
if ($value !== ''){
$saveData[$key] = $value;
}
}
return aModel::update($saveData,['id'=>$id]) ? app("json")->success("操作成功") : app("json")->fail("操作失败");
}
/**
* 修改字段
* @param $id
* @return mixed
* @author 李玉坤
* @date 2021-02-16 23:12
*/
public function field($id)
{
if (!$id) return app("json")->fail("参数有误Id为空");
$where = Util::postMore([['field',''],['value','']]);
if ($where['field'] == '' || $where['value'] =='') return app("json")->fail("参数有误!");
return aModel::update([$where['field']=>$where['value']],['id'=>$id]) ? app("json")->success("操作成功") : app("json")->fail("操作失败");
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace app\admin\controller;
/**
* Class Icon
* @package app\admin\controller\widget
*/
class Icon extends AuthController
{
public function index()
{
return $this->fetch();
}
}

View File

@ -0,0 +1,200 @@
<?php
namespace app\admin\controller;
use app\admin\model\Attachment;
use app\admin\model\AttachmentCategory;
use FormBuilder\Factory\Elm;
use learn\services\FormBuilderService as Form;
use learn\services\storage\QcloudCoService;
use learn\services\UtilService as Util;
use learn\utils\Json;
/**
* Class Images
* @package app\admin\controller\widget
*/
class Images extends AuthController
{
/**
* 附件类型
* @var string
*/
private $type = "images";
public function index()
{
return $this->fetch();
}
/**
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function category()
{
return app("json")->success(AttachmentCategory::buildNodes("image",0,$this->request->param("title","")));
}
/**
* 添加目录
* @param int $id
* @param int $pid
* @return string
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function addCategory($id=0, $pid=0)
{
$form = array();
$form[] = Elm::select('pid','上级分类',(int)$pid?: (int)$id)->options(function (){
$menu = [];
$menu[] = ['label'=>"顶级分类","value"=>0];
$list = AttachmentCategory::getCategoryLst();
foreach ($list as $value) $menu[] = ['label'=>$value['name'],"value"=>$value['id']];
return $menu;
})->col(18);
$form[] = Elm::input('name','分类名称')->col(18);
$form[] = Elm::hidden('type','images')->col(18);
$form = Form::make_post_form($form, url('saveCategory')->build());
$this->assign(compact('form'));
return $this->fetch("public/form-builder");
}
/**
* 目录的修改
* @param $id
* @return string
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function editCategory($id=0,$pid=0)
{
if ($id==0) return app("json")->fail("没有选中分类");
$form = array();
$form[] = Elm::select('pid','上级分类',(int)$pid)->options(function (){
$menu = [];
$menu[] = ['label'=>"顶级分类","value"=>0];
$list = AttachmentCategory::getCategoryLst();
foreach ($list as $value) $menu[] = ['label'=>$value['name'],"value"=>$value['id']];
return $menu;
})->col(18);
$form[] = Elm::input('name','分类名称',AttachmentCategory::getNameById($id))->col(18);
$form[] = Elm::hidden('type','images')->col(18);
$form = Form::make_post_form($form, Url('saveCategory',['id'=>$id])->build());
$this->assign(compact('form'));
return $this->fetch("public/form-builder");
}
/**
* 保存目录
* @param string $id
* @return json
*/
public function saveCategory($id="")
{
$data = Util::postMore([
['pid',0],
['type','images'],
['name','']
]);
if ($data['name'] == '') return app("json")->fail("分类名称不能为空");
if ($id == "")
{
$data['create_user'] = $this->adminId;
$data['create_time'] = time();
$res = AttachmentCategory::insert($data);
}
else
{
$data['update_user'] = $this->adminId;
$data['update_time'] = time();
$res = AttachmentCategory::update($data,['id'=>$id]);
}
return $res ? app("json")->success("操作成功",'code') : app("json")->fail("操作失败");
}
/**
* 删除目录
* @param $id
* @return
*/
public function delCategory($id)
{
if ($id == 0) return app("json")->fail("未选择分类");
if (Attachment::be($id,"cid")) return app("json")->fail("该分类下有图片不能删除");
if (AttachmentCategory::be($id,"pid")) return app("json")->fail("该分类下有子分类不能删除");
return AttachmentCategory::del($id) ? app("json")->success("删除成功") : app("json")->fail("删除失败");
}
/**
* @return mixed
*/
public function getImageList()
{
$where = Util::postMore([
['cid',''],
['type',$this->type],
['page',1],
['limit',12]
]);
return app("json")->layui(Attachment::pagination($where));
}
/**
* @param $id
* @return string
* @throws \FormBuilder\Exception\FormBuilderException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function editImage($id)
{
if ($id==0) return app("json")->fail("没有选中图片");
$image = Attachment::get($id);
$form = array();
$form[] = Elm::select('cid','选中分类',(int)$image['cid'])->options(AttachmentCategory::returnOptions())->col(18);
$form[] = Elm::hidden('type','images')->col(18);
$form = Form::make_post_form($form, Url('saveImage',['id'=>$id])->build());
$this->assign(compact('form'));
return $this->fetch("public/form-builder");
}
/**
* 修改图片分类
* @param $id
* @return mixed
*/
public function saveImage($id)
{
return Attachment::update(['cid'=>$this->request->param('cid')],['id'=>$id]) ? app("json")->success("修改成功",'code') : app("json")->fail("修改失败");
}
/**
* 删除图片
* @param $id
* @return mixed
*/
public function delImage($id)
{
if ($id == 0) return app("json")->fail("未选择图片");
$image = Attachment::get($id);
try {
switch ($image['storage'])
{
case 1:
unlink(app()->getRootPath() . 'public'.$image['path']);
break;
case 2:
QcloudCoService::del(str_replace(system_config("storage_domain"),"",$image['path']));
break;
}
return Attachment::del($id) ? app("json")->success("删除成功") : app("json")->fail("删除失败");
}catch (\Exception $e)
{
return app("json")->fail("删除失败".$e);
}
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace app\admin\controller;
use app\admin\model\AdminAuth;
use app\admin\model\AdminNotify;
use app\Request;
use learn\services\UtilService as Util;
class Index extends AuthController
{
// 无需登录的
protected $noNeedLogin = ['test','accessauth','pddlogin'];
// 无需权限的
protected $noNeedRight = [''];
/**
* 后台首页
* @return string
* @throws \Exception
*/
public function index()
{
$this->assign("adminInfo",$this->adminInfo);
$this->assign("menu",AdminAuth::getMenu(0,$this->auth));
$this->assign("message",AdminNotify::pageList(5));
return $this->fetch();
}
/**
* 控制台
* @return string
* @throws \Exception
*/
public function main()
{
return $this->fetch();
}
/**
* 菜单
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function menu()
{
return app("json")->success(AdminAuth::getMenu(0,$this->auth));
}
}

View File

@ -0,0 +1,48 @@
<?php
namespace app\admin\controller;
use app\admin\model\InvitationCode as aModel;
use app\Request;
use learn\services\UtilService as Util;
/**
* Class Invitation
* @package app\admin\controller\system
* @author 李玉坤
* @date 2021-02-15 23:20
*/
class Invitation extends AuthController
{
/**
* 活动列表
* @return string
* @throws \Exception
* @author 李玉坤
* @date 2021-02-16 13:15
*/
public function index()
{
return $this->fetch();
}
/**
* 文章列表
* @param Request $request
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 李玉坤
* @date 2021-02-15 23:26
*/
public function lst(Request $request)
{
$where = Util::postMore([
['code',''],
['page',1],
['limit',20],
]);
return app("json")->layui(aModel::systemPage($where));
}
}

View File

@ -0,0 +1,90 @@
<?php
namespace app\admin\controller;
use app\admin\model\Admin;
use app\admin\model\Admin as adminModel;
use learn\services\UtilService as Util;
class Login extends AuthController
{
/**
* 无需登录
* @var array
*/
protected $noNeedLogin = ['login','register','forget','captcha','verify'];
/**
* 登录
* @return string
* @throws \Exception
*/
public function login()
{
return $this->fetch();
}
/**
* 验证登录
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function verify()
{
list($account,$pwd,$verify) = Util::postMore(['account','pwd','verify'],null,true);
if (empty($account) || empty($pwd)) return app("json")->fail("账号、密码和验证码不能为空!");
// 验证码验证
if (!captcha_check($verify)) return app("json")->fail("验证码不正确!");
// 验证登录
if (!adminModel::login($account,$pwd)) return app("json")->fail("登录失败!");
return app("json")->success("登录成功!");
}
public function wechatLogin()
{
}
/**
* 注册
* @return string
* @throws \Exception
*/
public function register()
{
return $this->fetch();
}
/**
* 忘记密码
* @return string
* @throws \Exception
*/
public function forget()
{
return $this->fetch();
}
/**
* 退出登陆
* @return mixed
* @throws \Exception
*/
public function logout()
{
return Admin::clearLoginInfo() ? $this->successfulNotice("操作成功","/admin/login/login") : $this->failedNotice("操作失败","/admin/index/index");
}
/**
* 验证码
* @return \think\Response
*/
public function captcha()
{
ob_clean();
return captcha();
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace app\admin\controller;
use app\admin\model\MessageForm as aModel;
use app\Request;
use learn\services\UtilService as Util;
/**
* Class Message
* @package app\admin\controller\system
* @author 李玉坤
* @date 2021-02-15 23:20
*/
class Message extends AuthController
{
/**
* 账号列表
* @return string
* @throws \Exception
*/
public function index()
{
return $this->fetch();
}
/**
* 文章列表
* @param Request $request
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 李玉坤
* @date 2021-02-15 23:26
*/
public function lst(Request $request)
{
$where = Util::postMore([
['name',''],
['tel',''],
['email',''],
['start_time',''],
['end_time',''],
['page',1],
['limit',20],
]);
return app("json")->layui(aModel::systemPage($where));
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace app\admin\controller;
use app\admin\model\Slides as aModel;
use app\Request;
use learn\services\UtilService as Util;
/**
* Class Slides
* @package app\admin\controller\system
* @author 李玉坤
* @date 2021-02-15 23:20
*/
class Slides extends AuthController
{
/**
* 幻灯片管理
* @return string
* @throws \Exception
* @author 李玉坤
* @date 2021-02-16 13:15
*/
public function index()
{
return $this->fetch();
}
/**
* 文章列表
* @param Request $request
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 李玉坤
* @date 2021-02-15 23:26
*/
public function lst(Request $request)
{
$where = Util::postMore([
['title',''],
['start_time',''],
['end_time',''],
['status',''],
['page',1],
['limit',20],
]);
return app("json")->layui(aModel::systemPage($where));
}
}

View File

@ -0,0 +1,123 @@
<?php
/**
*
* @author: xaboy<365615158@qq.com>
* @day: 2017/10/09
*/
namespace app\admin\controller;
use learn\basic\admin\BaseController;
class SystemBasic extends BaseController
{
/**
* 操作失败提示框
* @param string $msg 提示信息
* @param string $backUrl 跳转地址
* @param string $title 标题
* @param int $duration 持续时间
* @return mixed
* @throws \Exception
*/
protected function failedNotice($msg = '操作失败', $backUrl = 0, $info = '', $duration = 3)
{
$type = 'error';
$this->assign(compact('msg','backUrl','info','duration','type'));
return $this->fetch('public/notice');
}
/**
* 失败提示一直持续
* @param $msg
* @param int $backUrl
* @param string $title
* @return mixed
* @throws \Exception
*/
protected function failedNoticeLast($msg = '操作失败', $backUrl = 0, $info = '')
{
return $this->failedNotice($msg,$backUrl,$info,0);
}
/**
* 操作成功提示框
* @param string $msg 提示信息
* @param string $backUrl 跳转地址
* @param string $title 标题
* @param int $duration 持续时间
* @return mixed
* @throws \Exception
*/
protected function successfulNotice($msg = '操作成功',$backUrl = 0,$info = '',$duration = 3)
{
$type = 'success';
$this->assign(compact('msg','backUrl','info','duration','type'));
return $this->fetch('public/notice');
}
/**
* 成功提示一直持续
* @param $msg
* @param int $backUrl
* @param string $title
* @return mixed
* @throws \Exception
*/
protected function successfulNoticeLast($msg = '操作成功',$backUrl = 0,$info = '')
{
return $this->successfulNotice($msg,$backUrl,$info,0);
}
/**
* 错误提醒页面
* @param string $msg
* @param int $url
* @throws \Exception
*/
protected function failed($msg = '哎呀…亲…您访问的页面出现错误', $url = 0)
{
if($this->request->isAjax()){
exit(app("json")->fail($msg,$url)->getContent());
}else{
$this->assign(compact('msg','url'));
exit($this->fetch('public/error'));
}
}
/**
* 成功提醒页面
* @param string $msg
* @param int $url
* @throws \Exception
*/
protected function successful($msg, $url = 0)
{
if($this->request->isAjax()){
exit(app("json")->success($msg,$url)->getContent());
}else{
$this->assign(compact('msg','url'));
exit($this->fetch('public/success'));
}
}
/**异常抛出
* @param $name
* @throws \Exception
*/
protected function exception($msg = '无法打开页面')
{
$this->assign(compact('msg'));
exit($this->fetch('public/exception'));
}
/**找不到页面
* @param $name
* @throws \Exception
*/
public function _empty($name)
{
exit($this->fetch('public/404'));
}
}

View File

@ -0,0 +1,246 @@
<?php
namespace app\admin\controller;
use app\admin\model\SystemConfig as cModel;
use app\admin\model\SystemConfigTab as tModel;
use app\Request;
use FormBuilder\Factory\Elm;
use learn\services\FormBuilderService as Form;
use learn\services\UtilService as Util;
/**
* 系统配置
* Class SystemConfig
* @package app\admin\controller\system
*/
class SystemConfig extends AuthController
{
/**
* 基础配置
* @param int $tab_id
* @return string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function base($tab_id = 1)
{
if ($tab_id < 5)
{
$system = cModel::getLstByTabId($tab_id);
//特殊处理主题信息
if ($tab_id == 1){
foreach ($system as &$form){
if ($form['form_name'] == 'web_template'){
$templateDir = public_path('template');
$templateList = get_dir($templateDir);
if ($templateList){
$form['param'] = '';
foreach ($templateList as $value){
$form['param'] .= ($form['param']?"\n":'').$value .'=>'.$value;
}
}
}
}
}
$this->assign("tab_id",$tab_id);
$this->assign("system",$system);
return $this->fetch();
}else if ($tab_id == 38 || $tab_id == 39)
{
$this->assign("tab_id",$tab_id);
$this->assign("system",cModel::getLstByTabId($tab_id));
return $this->fetch("pay");
}
}
/**
* @param Request $request
* @return
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function clearCache(Request $request)
{
if($request->isPost()){
$adminPath = config("cache.runtime")."/admin/";
$commonPath = config("cache.runtime")."/cache/";
$indexPath = config("cache.runtime")."/index/";
$apiPath = config("cache.runtime")."/api/";
if (remove_cache($adminPath) && remove_cache($indexPath) && remove_cache($apiPath) && remove_cache($commonPath)) return app("json")->success("操作成功");
return app("json")->error("操作失败");
}
return $this->fetch();
}
/**
* 上传配置
* @return string
* @throws \Exception
*/
public function upload()
{
return $this->fetch();
}
/**
* 短信配置
* @return string
* @throws \Exception
*/
public function sms()
{
return $this->fetch();
}
/**
*邮件配置
* @return string
* @throws \Exception
*/
public function email()
{
return $this->fetch();
}
/**
* 列表
* @param int $tab_id
* @return string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function lst(Request $request)
{
$where = Util::postMore([
['page',1],
['limit',20],
['tab_id',0]
]);
return app("json")->layui(cModel::lst($where));
}
/**
* 列表
* @param int $tab_id
* @return string
* @throws \Exception
*/
public function index($tab_id = 0)
{
$this->assign("tab",tModel::get($tab_id));
return $this->fetch("list");
}
/**
* 添加
* @param Request $request
* @return string
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function add(Request $request)
{
$form = array();
$form[] = Elm::hidden('tab_id',$request->param("tab_id"))->col(10);
$form[] = Elm::select('tag_type','标签类型')->options(tag_options())->col(10);
$form[] = Elm::select('form_type','表单类型')->options(type_options())->col(10);
$form[] = Elm::input('name','标题名称')->col(10);
$form[] = Elm::input('form_name','表单名称')->col(10);
$form[] = Elm::input('value','内容')->col(10);
$form[] = Elm::number('rank','排序',0)->col(10);
$form[] = Elm::textarea('param','参数')->col(20);
$form[] = Elm::textarea('remark','字段备注')->col(20);
$form[] = Elm::radio('is_show','是否显示',1)->options([['label'=>'隐藏','value'=>0],['label'=>'显示','value'=>1]])->col(10);
$form[] = Elm::radio('upload_type','上传配置',0)->options([['label'=>'单选','value'=>0],['label'=>'多选','value'=>1]])->col(10);
$form[] = Elm::radio('status','状态',1)->options([['label'=>'禁用','value'=>0],['label'=>'启用','value'=>1]])->col(10);
$form = Form::make_post_form($form, url('save')->build());
$this->assign(compact('form'));
return $this->fetch("public/form-builder");
}
/**
* 修改
* @param Request $request
* @return string
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function edit($id='')
{
if (!$id) return app("json")->fail("项目id不能为空");
$info = cModel::get($id);
if (!$info) return app("json")->fail("没有该项目");
$form = array();
$form[] = Elm::hidden('tab_id',$info['tab_id'])->col(10);
$form[] = Elm::select('tag_type','标签类型',$info['tag_type'])->options(tag_options())->col(10);
$form[] = Elm::select('form_type','表单类型',$info['form_type'])->options(type_options())->col(10);
$form[] = Elm::input('name','标题名称',$info['name'])->col(10);
$form[] = Elm::input('form_name','表单名称',$info['form_name'])->col(10);
$form[] = Elm::input('value','内容',$info['value'])->col(10);
$form[] = Elm::number('rank','排序',$info['rank'])->col(10);
$form[] = Elm::textarea('param','参数',$info['param'])->col(20);
$form[] = Elm::textarea('remark','字段备注',$info['remark'])->col(20);
$form[] = Elm::radio('is_show','是否显示',$info['is_show'])->options([['label'=>'隐藏','value'=>0],['label'=>'显示','value'=>1]])->col(10);
$form[] = Elm::radio('upload_type','上传配置',$info['upload_type'])->options([['label'=>'单选','value'=>0],['label'=>'多选','value'=>1]])->col(10);
$form[] = Elm::radio('status','状态',$info['status'])->options([['label'=>'禁用','value'=>0],['label'=>'启用','value'=>1]])->col(10);
$form = Form::make_post_form($form, url('save',["id"=>$id])->build());
$this->assign(compact('form'));
return $this->fetch("public/form-builder");
}
/**
* 保存修改
* @param string $id
* @return mixed
*/
public function save($id="")
{
$data = Util::postMore([
['name',''],
['tab_id',0],
['tag_type',''],
['form_type',''],
['form_name',''],
['value',''],
['rank',1],
['remark',''],
['param',''],
['is_show',1],
['upload_type',0],
['status',1]
]);
if ($data['name'] == "") return app("json")->fail("标题名称不能为空");
if ($data['tag_type'] == "") return app("json")->fail("标签类型不能为空");
if ($data['form_type'] == "") return app("json")->fail("表单类型不能为空");
if ($data['form_name'] == "") return app("json")->fail("表单名称不能为空");
if ($id=="")
{
$data['create_user'] = $this->adminId;
$data['create_time'] = time();
$res = cModel::insert($data);
}else
{
$data['update_user'] = $this->adminId;
$data['update_time'] = time();
$res = cModel::update($data,['id'=>$id]);
}
return $res ? app("json")->success("操作成功",'code') : app("json")->fail("操作失败");
}
/**
* 提交修改
* @param Request $request
* @return
*/
public function ajaxSave(Request $request)
{
try {
foreach ($request->param() as $k => $v) cModel::editValueByFormName($k,$v);
cache('systemConfig',null);//清除缓存
return app("json")->success("操作成功");
}catch (\Exception $e)
{
return app("json")->fail("操作失败");
}
}
}

View File

@ -0,0 +1,121 @@
<?php
namespace app\admin\controller;
use app\Request;
use FormBuilder\Factory\Elm;
use learn\services\FormBuilderService as Form;
use learn\services\UtilService as Util;
use app\admin\model\SystemConfigTab as tModel;
use app\admin\model\SystemConfig as cModel;
/**
* 管理员配置
* Class SystemConfigTab
* @package app\admin\controller\system
*/
class SystemConfigTab extends AuthController
{
public function index()
{
return $this->fetch();
}
/**
* 列表
* @param Request $request
* @return
*/
public function lst(Request $request)
{
$where = Util::postMore([
['page',1],
['limit',20],
['name',''],
['status',''],
]);
return app("json")->layui(tModel::lst($where));
}
/**
* 添加
* @param Request $request
* @return string
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function add(Request $request)
{
$form = array();
$form[] = Elm::input('name','分类名称')->col(10);
$form[] = Elm::number('rank','排序',0)->col(24);
$form[] = Elm::radio('status','状态',1)->options([['label'=>'禁用','value'=>0],['label'=>'启用','value'=>1]])->col(24);
$form = Form::make_post_form($form, url('save')->build());
$this->assign(compact('form'));
return $this->fetch("public/form-builder");
}
/**
* 修改
* @param Request $request
* @return string
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function edit($id='')
{
if (!$id) return app("json")->fail("项目id不能为空");
$info = tModel::get($id);
if (!$info) return app("json")->fail("没有该项目");
$form = array();
$form[] = Elm::input('name','分类名称',$info['name'])->col(10);
$form[] = Elm::number('rank','排序',$info['rank'])->col(24);
$form[] = Elm::radio('status','状态',$info['status'])->options([['label'=>'禁用','value'=>0],['label'=>'启用','value'=>1]])->col(24);
$form = Form::make_post_form($form, url('save',["id"=>$id])->build());
$this->assign(compact('form'));
return $this->fetch("public/form-builder");
}
/**
* 保存修改
* @param string $id
* @return mixed
*/
public function save($id="")
{
$data = Util::postMore([
['name',''],
['rank',0],
['status',1]
]);
if ($data['name'] == "") return app("json")->fail("分类名称不能为空");
if ($id=="")
{
$data['create_user'] = $this->adminId;
$data['create_time'] = time();
$res = tModel::insert($data);
}else
{
$data['update_user'] = $this->adminId;
$data['update_time'] = time();
$res = tModel::update($data,['id'=>$id]);
}
return $res ? app("json")->success("操作成功",'code') : app("json")->fail("操作失败");
}
/**
* 重写删除
* @param Request $request
* @return mixed|void
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function del(Request $request)
{
$ids = $request->param("id",0);
if ($ids == 0) return app("json")->fail("参数有误Id为空");
if (!is_array($ids)) $ids = array_filter(explode(",",$ids));
if (cModel::where("tab_id","in",$ids)->count()>0) return app("json")->fail("该配置项下有配置数据,不能删除!");
return parent::del($request);
}
}

View File

@ -0,0 +1,73 @@
<?php
namespace app\admin\controller;
use app\Request;
use learn\services\UtilService as Util;
/**
* Trait TemplateTrait
* @package app\admin\controller
*/
trait TemplateTrait
{
public function index()
{
return $this->fetch();
}
/**
* 删除操作
* @param Request $request
* @return mixed
*/
public function del(Request $request)
{
$ids = $request->param("id",0);
if (empty($ids) || !$ids) return app("json")->fail("参数有误Id为空");
if (!is_array($ids)) $ids = explode(",",$ids);
if (in_array(1,$ids)) return app("json")->fail("参数有误初始ID不允许操作");
return $this->model->where($this->model->getPk(),"in",$ids)->delete() ? app("json")->success("操作成功") : app("json")->fail("操作失败");
}
/**
* 启用
* @param Request $request
* @return mixed
*/
public function enabled(Request $request)
{
$ids = $request->param("id",0);
if (empty($ids) || !$ids) return app("json")->fail("参数有误Id为空");
if (!is_array($ids)) $ids = explode(",",$ids);
if (in_array(1,$ids)) return app("json")->fail("参数有误初始ID不允许操作");
return $this->model->where($this->model->getPk(),"in",$ids)->update(['status'=>1]) ? app("json")->success("操作成功") : app("json")->fail("操作失败");
}
/**
* 禁用
* @param Request $request
* @return mixed
*/
public function disabled(Request $request)
{
$ids = $request->param("id",0);
if (empty($ids) || !$ids) return app("json")->fail("参数有误Id为空");
if (!is_array($ids)) $ids = explode(",",$ids);
if (in_array(1,$ids)) return app("json")->fail("参数有误初始ID不允许操作");
return $this->model->where($this->model->getPk(),"in",$ids)->update(['status'=>0]) ? app("json")->success("操作成功") : app("json")->fail("操作失败");
}
/**
* 修改字段
* @param $id
* @return mixed
*/
public function field($id)
{
if (empty($id) || !$id) return app("json")->fail("参数有误Id为空");
$where = Util::postMore([['field',''],['value','']]);
if ($where['field'] == '' || $where['value'] =='') return app("json")->fail("参数有误!");
return $this->model::update([$where['field']=>$where['value']],[$this->model->getPk()=>$id]) ? app("json")->success("操作成功") : app("json")->fail("操作失败");
}
}

View File

@ -0,0 +1,65 @@
<?php
namespace app\admin\controller;
use app\admin\model\Document as aModel;
use app\Request;
use learn\services\UtilService as Util;
/**
* Class User
* @package app\admin\controller\system
* @author 李玉坤
* @date 2021-02-15 23:20
*/
class User extends AuthController
{
/**
* 活动列表
* @return string
* @throws \Exception
* @author 李玉坤
* @date 2021-02-16 13:15
*/
public function index()
{
return $this->fetch();
}
/**
* 文章列表
* @param Request $request
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 李玉坤
* @date 2021-02-15 23:26
*/
public function lst(Request $request)
{
$where = Util::postMore([
['status',''],
['tel',''],
['start_time',''],
['end_time',''],
['role_id',''],
['status',''],
['page',1],
['limit',20],
]);
return app("json")->layui(aModel::systemPage($where));
}
/**
* 用户回收站
* @return string
* @throws \Exception
* @author 李玉坤
* @date 2021-02-16 13:26
*/
public function recovery()
{
return $this->fetch();
}
}

View File

@ -0,0 +1,5 @@
<?php
return [
'lang' => 'English'
];

View File

@ -0,0 +1,5 @@
<?php
return [
'lang' => 'わご'
];

View File

@ -0,0 +1,5 @@
<?php
return [
'lang' => 'Việt nam'
];

4
app/admin/lang/zh-cn.php Normal file
View File

@ -0,0 +1,4 @@
<?php
return [
'lang' => '简体中文22'
];

View File

@ -0,0 +1,5 @@
<?php
return [
'lang' => '简体中文'
];

View File

@ -0,0 +1,5 @@
<?php
return [
'No Account' => '登录账号不存在'
];

153
app/admin/model/Admin.php Normal file
View File

@ -0,0 +1,153 @@
<?php
namespace app\admin\model;
use app\admin\model\BaseModel;
use app\admin\model\wechat\WechatUser;
use think\facade\Cache;
use think\facade\Session;
/**
* 管理员管理
* Class Admin
* @package app\admin\model
*/
class Admin extends BaseModel
{
/**
* 登录
* @param $name
* @param $pwd
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function login(string $name,string $pwd): bool
{
$info = self::where("name|tel","=", $name)->find();
if (!$info) return self::setErrorInfo("登录账号不存在");
if ($info['pwd'] != md5(md5($pwd))) return self::setErrorInfo("密码不正确!");
if ($info['status'] == 2) return self::setErrorInfo("账号已被冻结!");
self::setLoginInfo($info);
return true;
}
/**
* 微信扫码登录后台
* @param array $message
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public static function wechatLogin(array $message)
{
$param = param_to_array(str_replace("qrscene_","",$message['EventKey']));
// 查找用户uid
$uid = WechatUser::getUidByOpenId($message['FromUserName']);
if (!$uid) return ['status'=>101];
$adminInfo = self::where("uid",$uid)->find();
if (!$adminInfo) return ['status'=>102];
Cache::store('redis')->set("info_".$param['token'],$adminInfo,60);
return ['status'=>100];
}
/**
* 设置登录信息
* @param $info
* @return bool
*/
public static function setLoginInfo($info)
{
Session::set("adminId",$info['id']);
Session::set("adminInfo",$info->toArray());
event("AdminLog",[$info->toArray(),"admin","login","login"]);
return true;
}
/**
* 退出登录
*/
public static function clearLoginInfo()
{
Session::delete("adminId");
Session::delete("adminInfo");
Session::clear();
return true;
}
/**
* 是否登录
* @return bool
*/
public static function isActive(): bool
{
return Session::has('adminId') && Session::has('adminInfo');
}
/**
* 列表
* @param array $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function systemPage(array $where): array
{
$model = new self;
if ($where['name'] != '') $model = $model->where("name|id|nickname","like","%$where[name]%");
if ($where['start_time'] != '') $model = $model->where("create_time",">",strtotime($where['start_time']." 00:00:00"));
if ($where['end_time'] != '') $model = $model->where("create_time","<", strtotime($where['end_time']." 23:59:59"));
if ($where['tel'] != '') $model = $model->where("tel|mail", "like","%$where[tel]%");
if ($where['status'] != '') $model = $model->where("status",$where['status']);
if ($where['role_id'] != '') $model = $model->where("role_id",$where['role_id']);
$count = self::counts($model);
if ($where['page'] && $where['limit']) $model = $model->page((int)$where['page'],(int)$where['limit']);
$data = $model->select()->each(function ($item){
// 用户信息
$info = self::getAdminInfoById($item['create_user']);
$item['create_user'] = $info ? $info['nickname'] : $item['create_user'];
$item['role_id'] = AdminRole::getAuthNameById($item['role_id']);
});
$data = $data ? $data->toArray() : [];
return compact("data","count");
}
/**
* 获取账号信息
* @param int $id
* @param string $field
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getAdminInfoById(int $id, string $field = '*'): array
{
$model = new self;
$model = $model->where("id",$id);
$model = $model->field($field);
$info = $model->find();
return $info ? $info->toArray() : [];
}
/**
* 人员列表
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function lst()
{
$model = new self;
$model = $model->where("status",1);
$model = $model->field("id,realname");
$data = $model->select();
return $data ? $data->toArray() : [];
}
}

View File

@ -0,0 +1,194 @@
<?php
namespace app\admin\model;
use app\admin\model\BaseModel;
/**
* 操作权限
* Class AdminAuth
* @package app\admin\model\admin
*/
class AdminAuth extends BaseModel
{
/**
* 获取权限id 找不到是返回 -1
* @param string $module
* @param string $controller
* @param string $action
* @return int
*/
public static function getAuthId(string $module, string $controller,string $action): int
{
return self::where("module",$module)->where("controller",$controller)->where("action",$action)->value('id') ?: -1;
}
/**
* 获取菜单
* @param int $pid
* @param array $auth
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getMenu(int $pid = 0, array $auth = []): array
{
$model = new self;
$model = $model->where("is_menu",1);
$model = $model->where("status",1);
$model = $model->where("pid",$pid);
if ($auth != []) $model = $model->where("id",'in',$auth);
$model = $model->field(['name as title','path as href','icon','id','font_family as fontFamily','is_check as isCheck','spreed','params']);
$model = $model->order(["rank desc","id"]);
$data = $model->select()->each(function ($item) use ($auth)
{
$item['children'] = self::getMenu($item['id'],$auth);
$item['isCheck'] = $item['isCheck'] ? true : false;
$item['spreed'] = $item['spreed'] ? true : false;
});
return $data->toArray() ?: [];
}
/**
* 权限列表
* @param $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function systemPage($where): array
{
$model = new self;
if (isset($where['status']) && $where['status'] != '') $model = $model->where("status",$where['status']);
if (isset($where['name']) && $where['name'] != '') $model = $model->where("name|id","like","%$where[name]%");
$model = $model->field(['id','name','icon','pid','module','controller','action','params','is_menu','path','rank','status']);
$model = $model->order(["rank desc","id"]);
$data = $model->select();
return $data->toArray() ?: [];
}
/**
* 获取选择数据
* @param int $pid
* @param array $auth
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function lst(int $pid = 0, array $auth = []): array
{
$model = new self;
$model = $model->where("pid",$pid);
if ($auth != []) $model = $model->where("id",'in',$auth);
$model = $model->field(['name','id']);
$model = $model->order(["rank desc","id"]);
$data = $model->select()->each(function ($item) use ($auth)
{
$item['children'] = self::lst($item['id'],$auth);
});
return $data->toArray() ?: [];
}
/**
* 遍历选择项
* @param array $data
* @param $list
* @param int $num
* @param bool $clear
*/
public static function myOptions(array $data, &$list, $num = 0, $clear=true)
{
foreach ($data as $k=>$v)
{
$list[] = ['value'=>$v['id'],'label'=>self::cross($num).$v['name']];
if (is_array($v['children']) && !empty($v['children'])) {
self::myOptions($v['children'],$list,$num+1,false);
}
}
}
/**
* 返回选择项
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function returnOptions(): array
{
$list = [];
$list[] = ['value'=>0,'label'=>'总后台'];
self::myOptions(self::lst(),$list, 1, true);
return $list;
}
/**
* 横线
* @param int $num
* @return string
*/
public static function cross(int $num=0): string
{
$str = "";
if ($num == 1) $str .= "|--";
elseif ($num > 1) for($i=0;$i<$num;$i++)
if ($i==0) $str .= "|--";
else $str .= "--";
return $str." ";
}
/**
* 生成treeData
* @param int $pid
* @param array $auth
* @param array $list
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function selectAndBuildTree(int $pid = 0, array $auth = [], array $list = [])
{
$model = new self;
$model = $model->where("pid",$pid);
if ($auth != []) $model = $model->where("id",'in',$auth);
$model = $model->where("status",1);
$model = $model->field(['name','id']);
$model = $model->order(["rank desc","id"]);
$data = $model->select();
foreach ($data as $k => $v)
{
$list[] = AdminRole::buildTreeData($v['id'],$v['name'],self::selectAndBuildTree($v['id'],$auth));
}
return $list;
}
/**
* 获取所有权限id
* @param array $ids
* @return array
*/
public static function getIds(array $ids = []):array
{
if (empty($ids)) return self::where("status",1)->column("id");
$pids = self::where("id","in",$ids)->column("pid");
return array_merge($ids,$pids) ?: [];
}
/**
* 获取操作名
* @param string $module
* @param string $controller
* @param string $action
* @return string
*/
public static function getNameByAction(string $module, string $controller, string $action)
{
return self::where("module",$module)->where("controller",$controller)->where("action",$action)->value("name") ?: '未知操作';
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace app\admin\model;
use app\admin\model\BaseModel;
/**
* 操作日志
* Class AdminLog
* @package app\admin\model\admin
*/
class AdminLog extends BaseModel
{
/**
* 保存日志
* @param array $adminInfo
* @param string $module
* @param string $controller
* @param string $action
* @return bool
*/
public static function saveLog(array $adminInfo, string $module, string $controller, string $action): bool
{
return self::create([
'admin_id' => $adminInfo['id'],
'admin_name' => $adminInfo['name'],
'module' => $module,
'controller' => $controller,
'action' => $action,
'ip' => request()->ip(),
'create_time' => time(),
'user_agent' => substr(request()->server('HTTP_USER_AGENT'), 0, 255),
]) ? true : false;
}
/**
* 日志列表
* @param $where
* @return array
* @throws \think\db\exception\DbException
*/
public static function systemPage($where)
{
$model = new self;
$model = $model->order("id desc");
if ($where['name'] != '') $model = $model->where('admin_name|id',"like","%$where[name]%");
if ($where['ip'] != '') $model = $model->where('ip',"like","%$where[ip]%");
if ($where['start_time'] != '') $model = $model->where('create_time','>',strtotime($where['start_time']." 00:00:00"));
if ($where['end_time'] != '') $model = $model->where('create_time','<', strtotime($where['end_time']." 23:59:59"));
$count = self::counts($model);
if (!empty($where['page']) && !empty($where['limit'])) $model = $model->page((int)$where['page'], (int)$where['limit']);
$data = $model->select()->each(function ($item){
$item['name'] = AdminAuth::getNameByAction($item['module'],$item['controller'],$item['action']);
});
$data = $data ? $data->toArray() : [];
return compact("data","count");
}
}

View File

@ -0,0 +1,66 @@
<?php
namespace app\admin\model;
use app\admin\model\BaseModel;
/**
* 消息通知
* Class AdminNotify
* @package app\admin\model\admin
*/
class AdminNotify extends BaseModel
{
/**
* 系统分页
* @param array $where
* @return \think\Paginator
* @throws \think\db\exception\DbException
*/
public static function systemPage(array $where)
{
$model = new self;
if ($where['start_time'] != "" && $where['end_time'] != "")
{
$model = $model->where("add_time","between",[strtotime($where['start_time']." 00:00:00"),strtotime($where['end_time']." 23:59:59")]);
}
if ($where['title'] != '') $model = $model->where("title|content","like","%$where[title]%");
if ($where['is_read'] != '') $model = $model->where("is_read",$where['is_read']);
if ($where['aid'] != '') $model = $model->where("aid",$where['aid']);
$model = $model->order("is_read");
$model = $model->order("add_time desc");
return $model->paginate(10)->appends($where);
}
/**
* 添加记录
* @param array $data
* @return int|string
*/
public static function addLog(array $data)
{
return self::insert($data);
}
/**
* 后台首页获取通知信息
* @param int $num
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function pageList(int $num)
{
$model = new self;
$model = $model->where("is_read",0);
$count = self::counts($model);
$model = $model->order("add_time desc");
$model = $model->page(1,$num);
$data = $model->select();
if ($data) $data = $data->toArray();
return compact("data","count");
}
}

View File

@ -0,0 +1,151 @@
<?php
namespace app\admin\model;
use app\admin\model\BaseModel;
use FormBuilder\Factory\Elm;
/**
* 操作角色
* Class AdminRole
* @package app\admin\model\admin
*/
class AdminRole extends BaseModel
{
/**
* 获取权限
* @param int $id
* @return string
*/
public static function getAuth(int $id): string
{
return self::where("id",$id)->value("auth") ?: '';
}
/**
* 获取所有角色ids
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getAuthLst(): array
{
$data = self::where("status",1)->field("id,name")->select();
return $data ? $data->toArray() : [];
}
/**
* 获取角色名称
* @param int $id
* @return string
*/
public static function getAuthNameById(int $id): string
{
return self::where("id",$id)->value("name") ?: (string)$id;
}
/**
* 角色列表
* @param int $pid
* @param array $auth
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function systemPage(int $pid = -1): array
{
$model = new self;
if ($pid != -1) $model = $model->where("pid",$pid);
$model = $model->field(['id','name','pid','auth','rank','status']);
$model = $model->order(["rank desc","id"]);
$data = $model->select();
return $data->toArray() ?: [];
}
/**
* 获取选择数据
* @param int $pid
* @param array $auth
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function lst(int $pid = 0, array $auth = []): array
{
$model = new self;
$model = $model->where("pid",$pid);
$model = $model->field(['name','id']);
$model = $model->order(["rank desc","id"]);
$data = $model->select()->each(function ($item) use ($auth)
{
$item['children'] = self::lst($item['id'],$auth);
});
return $data->toArray() ?: [];
}
/**
* 遍历选择项
* @param array $data
* @param $list
* @param int $num
* @param bool $clear
*/
public static function myOptions(array $data, &$list, $num = 0, $clear=true)
{
foreach ($data as $k=>$v)
{
$list[] = ['value'=>$v['id'],'label'=>self::cross($num).$v['name']];
if (is_array($v['children']) && !empty($v['children'])) {
self::myOptions($v['children'],$list,$num+1,false);
}
}
}
/**
* 返回选择项
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function returnOptions(): array
{
$list = [];
$list[] = ['label'=>'总后台','value'=>0];
self::myOptions(self::lst(),$list, 1, true);
return $list;
}
/**
* 横线
* @param int $num
* @return string
*/
public static function cross(int $num=0): string
{
$str = "";
if ($num == 1) $str .= "|--";
elseif ($num > 1) for($i=0;$i<$num;$i++)
if ($i==0) $str .= "|--";
else $str .= "--";
return $str." ";
}
/**
* 生成单个节点
* @param $id
* @param $title
* @return array
*/
public static function buildTreeData($id, $title, $children=[]): array
{
$tree = Elm::TreeData($id,$title);
if (!empty($children)) $tree = $tree->children($children);
return $tree->getOption();
}
}

View File

@ -0,0 +1,57 @@
<?php
namespace app\admin\model;
use app\admin\model\BaseModel;
use app\admin\model\system\SystemConfig;
/**
* Class attachment
* @package app\admin\model\widget
*/
class Attachment extends BaseModel
{
/**
* @param int $cid
* @param string $name
* @param string $path
* @param string $type
* @param string $mime
* @param float $size
* @param int $storage
* @return int|string
*/
public static function addAttachment(int $cid, string $name, string $path, string $type, string $mime, float $size, int $storage)
{
$data = [
'cid' => $cid,
'name' => $name,
'path' => $path,
'type' => $type,
'mime' => $mime,
'size' => $size,
'storage' => $storage,
'upload_time' => time()
];
return self::insert($data);
}
/**
* 分页显示
* @param array $where
* @return array
*/
public static function pagination(array $where)
{
$model = self::where("type",$where['type']);
if ($where['cid'] != "") $model = $model->where("cid", $where['cid']);
$count = self::counts($model);
$model = $model->order("id desc");
$model = $model->field("path");
$data = $model->page((int)$where['page'],(int)$where['limit'])->select();
if ($data) $data = $data->toArray();
return compact("data","count");
}
}

View File

@ -0,0 +1,105 @@
<?php
namespace app\admin\model;
use app\admin\model\BaseModel;
/**
* Class AttachmentCategory
* @package app\admin\model\widget
*/
class AttachmentCategory extends BaseModel
{
/**
* 获取目录
* @param string $type
* @param int $pid
* @param bool $lower
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getCategoryLst(string $type = "image", int $pid = 0, bool $lower = false)
{
$model = new self;
$model = $model->where("type",$type);
$model = $model->where("pid",$pid);
$model = $model->field(['id','pid','name']);
$data = $model->select();
if ($lower)
{
$data = $data->each(function ($item) use ($type){
$item['children'] = self::getCategoryLst($type, $item['id']);
});
}
return $data ? $data->toArray() : [];
}
/**
* 获取目录名称
* @param int $id
* @return string
*/
public static function getNameById(int $id)
{
return self::where("id",$id)->value("name") ?: "";
}
/**
* @param string $type
* @param int $pid
* @param string $title
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function buildNodes(string $type = "image", int $pid = 0, string $title = "")
{
$model = new self;
$model = $model->where("type",$type);
$model = $model->where("pid",$pid);
if ($title != "") $model = $model->where("name","like","%$title%");
$model = $model->field(['id','pid','name as text']);
$data = $model->select()->each(function ($item) use ($type){
$item['nodes'] = self::buildNodes($type, $item['id']);
if (empty($item['nodes'])) unset($item['nodes']);
});
return $data ? $data->toArray() : [];
}
/**
* 遍历选择项
* @param array $data
* @param $list
* @param int $num
* @param bool $clear
*/
public static function myOptions(array $data, &$list, $num = 0, $clear=true)
{
foreach ($data as $k=>$v)
{
$list[] = ['value'=>$v['id'],'label'=>self::cross($num).$v['name']];
if (isset($v['children']) && is_array($v['children']) && !empty($v['children'])) {
self::myOptions($v['children'],$list,$num+1,false);
}
}
}
/**
* 返回选择项
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function returnOptions(): array
{
$list = [];
self::myOptions(self::getCategoryLst('image','0',true),$list, 0, true);
return $list;
}
}

View File

@ -0,0 +1,81 @@
<?php
namespace app\admin\model;
use think\facade\Db;
use think\Model;
class BaseModel extends Model
{
use ModelTrait;
private static $errorMsg;
private static $transaction = 0;
private static $DbInstance = [];
const DEFAULT_ERROR_MSG = '操作失败,请稍候再试!';
/**
* 设置错误信息
* @param string $errorMsg
* @return bool
*/
protected static function setErrorInfo($errorMsg = self::DEFAULT_ERROR_MSG,$rollback = false)
{
if($rollback) self::rollbackTrans();
self::$errorMsg = $errorMsg;
return false;
}
/**
* 获取错误信息
* @param string $defaultMsg
* @return string
*/
public static function getErrorInfo($defaultMsg = self::DEFAULT_ERROR_MSG)
{
return !empty(self::$errorMsg) ? self::$errorMsg : $defaultMsg;
}
/**
* 开启事务
*/
public static function beginTrans()
{
Db::startTrans();
}
/**
* 提交事务
*/
public static function commitTrans()
{
Db::commit();
}
/**
* 关闭事务
*/
public static function rollbackTrans()
{
Db::rollback();
}
/**
* 根据结果提交滚回事务
* @param $res
*/
public static function checkTrans($res)
{
if($res){
self::commitTrans();
}else{
self::rollbackTrans();
}
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace app\admin\model;
/**
* Class Document
* @package app\admin\model\system
* @author 李玉坤
* @date 2021-02-15 23:22
*/
class Document extends BaseModel
{
/**
* 列表
* @param $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 李玉坤
* @date 2021-02-15 23:24
*/
public static function systemPage($where): array
{
$model = new self;
$count = self::counts($model);
if ($where['page'] && $where['limit']) $model = $model->page((int)$where['page'],(int)$where['limit']);
$data = $model->select();
if ($data) $data = $data->toArray();
return compact('data','count');
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace app\admin\model;
use app\admin\model\BaseModel;
/**
* Class DocumentArticle
* @package app\admin\model\system
* @author 李玉坤
* @date 2021-02-15 23:22
*/
class DocumentArticle extends BaseModel
{
/**
* 列表
* @param $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 李玉坤
* @date 2021-02-15 23:24
*/
public static function systemPage($where): array
{
$model = new self;
$count = self::counts($model);
if ($where['page'] && $where['limit']) $model = $model->page((int)$where['page'],(int)$where['limit']);
$data = $model->select();
if ($data) $data = $data->toArray();
return compact('data','count');
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace app\admin\model;
use app\admin\model\BaseModel;
/**
* Class DocumentCategory
* @package app\admin\model\system
* @author 李玉坤
* @date 2021-02-15 23:22
*/
class DocumentCategory extends BaseModel
{
/**
* 列表
* @param $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 李玉坤
* @date 2021-02-15 23:24
*/
public static function systemPage($where): array
{
$model = new self;
$model = $model->where('status','>',-1)
->field('id,pid,title,sort,display')
->order('sort asc,id asc');
if (isset($where['status']) && $where['status'] != '') $model = $model->where("status",$where['status']);
if (isset($where['name']) && $where['name'] != '') $model = $model->where("name|id","like","%$where[name]%");
$data = $model->select();
return $data->toArray() ?: [];
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace app\admin\model;
use app\admin\model\BaseModel;
/**
* Class DocumentCategoryContent
* @package app\admin\model\system
* @author 李玉坤
* @date 2021-02-15 23:22
*/
class DocumentCategoryContent extends BaseModel
{
/**
* 列表
* @param $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 李玉坤
* @date 2021-02-15 23:24
*/
public static function systemPage($where): array
{
$model = new self;
$count = self::counts($model);
if ($where['page'] && $where['limit']) $model = $model->page((int)$where['page'],(int)$where['limit']);
$data = $model->select();
if ($data) $data = $data->toArray();
return compact('data','count');
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace app\admin\model;
use app\admin\model\BaseModel;
/**
* Class DocumentProduct
* @package app\admin\model\system
* @author 李玉坤
* @date 2021-02-15 23:22
*/
class DocumentProduct extends BaseModel
{
/**
* 列表
* @param $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 李玉坤
* @date 2021-02-15 23:24
*/
public static function systemPage($where): array
{
$model = new self;
$count = self::counts($model);
if ($where['page'] && $where['limit']) $model = $model->page((int)$where['page'],(int)$where['limit']);
$data = $model->select();
if ($data) $data = $data->toArray();
return compact('data','count');
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace app\admin\model;
use app\admin\model\BaseModel;
/**
* Class FriendLink
* @package app\admin\model\system
* @author 李玉坤
* @date 2021-02-15 23:22
*/
class FriendLink extends BaseModel
{
/**
* 列表
* @param $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 李玉坤
* @date 2021-02-15 23:24
*/
public static function systemPage($where): array
{
$model = new self;
$count = self::counts($model);
if ($where['page'] && $where['limit']) $model = $model->page((int)$where['page'],(int)$where['limit']);
$data = $model->select();
if ($data) $data = $data->toArray();
return compact('data','count');
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace app\admin\model;
use app\admin\model\BaseModel;
/**
* Class InvitationCode
* @package app\admin\model\system
* @author 李玉坤
* @date 2021-02-15 23:22
*/
class InvitationCode extends BaseModel
{
/**
* 邀请码列表
* @param $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 李玉坤
* @date 2021-02-15 23:24
*/
public static function systemPage($where): array
{
$model = new self;
$model = $model->order('id','desc');
if (isset($where['code']) && $where['code'] !== '') $model->where('code', "like", "%$where[code]%");
$count = self::counts($model);
if ($where['page'] && $where['limit']) $model = $model->page((int)$where['page'],(int)$where['limit']);
$data = $model->select();
if ($data) $data = $data->toArray();
return compact('data','count');
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace app\admin\model;
use app\admin\model\BaseModel;
/**
* Class Document
* @package app\admin\model\system
* @author 李玉坤
* @date 2021-02-15 23:22
*/
class MessageForm extends BaseModel
{
/**
* 列表
* @param $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 李玉坤
* @date 2021-02-15 23:24
*/
public static function systemPage($where): array
{
$model = new self;
$model = $model->order('create_time','desc');
if (isset($where['name']) && $where['name'] !== '') $model->where('name', "like", "%$where[name]%");
if (isset($where['email']) && $where['email'] !== '') $model->where('email', "like", "%$where[email]%");
if (isset($where['tel']) && $where['tel'] !== '') $model->where('tel', "like", "%$where[tel]%");
if (isset($where['start_time']) && $where['start_time'] != '') $model = $model->where("m.created_at", ">", strtotime($where['start_time'] . " 00:00:00"));
if (isset($where['end_time']) && $where['end_time'] != '') $model = $model->where("m.created_at", "<", strtotime($where['end_time'] . " 23:59:59"));
$count = self::counts($model);
if ($where['page'] && $where['limit']) $model = $model->page((int)$where['page'],(int)$where['limit']);
$data = $model->select();
if ($data) $data = $data->toArray();
return compact('data','count');
}
}

View File

@ -0,0 +1,353 @@
<?php
namespace app\admin\model;
use think\Model;
trait ModelTrait
{
public static function get($where)
{
if(!is_array($where)){
return self::find($where);
}else{
return self::where($where)->find();
}
}
public static function all($function){
$query = self::newQuery();
$function($query);
return $query->select();
}
/**
* 添加多条数据
* @param $group
* @param bool $replace
* @return mixed
*/
public static function setAll($group, $replace = false)
{
return self::insertAll($group,$replace);
}
/**
* 修改一条数据
* @param $data
* @param $id
* @param $field
* @return bool $type 返回成功失败
*/
public static function edit($data,$id,$field = null)
{
$model = new self;
if(!$field) $field = $model->getPk();
// return false !== $model->update($data,[$field=>$id]);
// return 0 < $model->update($data,[$field=>$id])->result;
$res=$model->update($data,[$field=>$id]);
if(isset($res->result))
return 0 < $res->result;
else if(isset($res['data']['result']))
return 0 < $res['data']['result'];
else
return false !== $res;
}
/**
* 查询一条数据是否存在
* @param $map
* @param string $field
* @return bool 是否存在
*/
public static function be($map, $field = '')
{
$model = (new self);
if(!is_array($map) && empty($field)) $field = $model->getPk();
$map = !is_array($map) ? [$field=>$map] : $map;
return 0 < $model->where($map)->count();
}
/**
* 删除一条数据
* @param $id
* @return bool $type 返回成功失败
*/
public static function del($id)
{
return false !== self::destroy($id);
}
/**
* 分页
* @param null $model 模型
* @param null $eachFn 处理结果函数
* @param array $params 分页参数
* @param int $limit 分页数
* @return array
*/
public static function page($model = null, $eachFn = null, $params = [], $limit = 20)
{
if(is_numeric($eachFn) && is_numeric($model)){
return parent::page($model,$eachFn);
}
if(is_numeric($eachFn)){
$limit = $eachFn;
$eachFn = null;
}else if(is_array($eachFn)){
$params = $eachFn;
$eachFn = null;
}
if(is_callable($model)){
$eachFn = $model;
$model = null;
}elseif(is_numeric($model)){
$limit = $model;
$model = null;
}elseif(is_array($model)){
$params = $model;
$model = null;
}
if(is_numeric($params)){
$limit = $params;
$params = [];
}
$paginate = $model === null ? self::paginate($limit,false,['query'=>$params]) : $model->paginate($limit,false,['query'=>$params]);
$list = is_callable($eachFn) ? $paginate->each($eachFn) : $paginate;
$page = $list->render();
$total = $list->total();
return compact('list','page','total');
}
/**
* 获取分页 生成where 条件和 whereOr 支持多表查询生成条件
* @param object $model 模型对象
* @param array $where 需要检索的数组
* @param array $field where字段名
* @param array $fieldOr whereOr字段名
* @param array $fun 闭包函数
* @param string $like 模糊查找 关键字
* @return array
*/
public static function setWherePage($model=null,$where=[],$field=[],$fieldOr=[],$fun=null,$like='LIKE'){
if(!is_array($where) || !is_array($field)) return false;
if($model===null) $model=new self();
//处理等于行查询
foreach ($field as $key=>$item){
if(($count=strpos($item,'.'))===false){
if(isset($where[$item]) && $where[$item]!='') {
$model=$model->where($item,$where[$item]);
}
}else{
$item_l=substr($item,$count+1);
if(isset($where[$item_l]) && $where[$item_l]!=''){
$model=$model->where($item,$where[$item_l]);
}
}
}
//回收变量
unset($count,$key,$item,$item_l);
//处理模糊查询
if(!empty($fieldOr) && is_array($fieldOr) && isset($fieldOr[0])){
if(($count=strpos($fieldOr[0],'.'))===false){
if(isset($where[$fieldOr[0]]) && $where[$fieldOr[0]]!='') {
$model=$model->where(self::get_field($fieldOr),$like,"%".$where[$fieldOr[0]]."%");
}
}else{
$item_l = substr($fieldOr[0],$count+1);
if(isset($where[$item_l]) && $where[$item_l]!='') {
$model=$model->where(self::get_field($fieldOr),$like,"%".$where[$item_l]."%");
}
}
}
unset($count,$key,$item,$item_l);
return $model;
}
/**
* 字符串拼接
* @param int|array $id
* @param string $str
* @return string
*/
private static function get_field($id,$str='|'){
if(is_array($id)){
$sql="";
$i=0;
foreach($id as $val){
$i++;
if($i<count($id)){
$sql.=$val.$str;
}else{
$sql.=$val;
}
}
return $sql;
}else{
return $id;
}
}
/**
* 条件切割
* @param string $order
* @param string $file
* @return string
*/
public static function setOrder($order,$file='-'){
if(empty($order)) return '';
return str_replace($file,' ',$order);
}
/**
* 获取时间段之间的model
* @param int|string $time
* @param string $ceil
* @return array
*/
public static function getModelTime($where,$model=null,$prefix='add_time',$data='data',$field=' - '){
if ($model == null) $model = new self;
if(!isset($where[$data])) return $model;
switch ($where[$data]){
case 'today':case 'week':case 'month':case 'year':case 'yesterday':
$model=$model->whereTime($prefix,$where[$data]);
break;
case 'quarter':
list($startTime,$endTime)=self::getMonth();
$model = $model->where($prefix, '>', strtotime($startTime));
$model = $model->where($prefix, '<', strtotime($endTime));
break;
case 'lately7':
$model = $model->where($prefix,'between',[strtotime("-7 day"),time()]);
break;
case 'lately30':
$model = $model->where($prefix,'between',[strtotime("-30 day"),time()]);
break;
default:
if(strstr($where[$data],$field)!==false){
list($startTime, $endTime) = explode($field, $where[$data]);
$model = $model->where($prefix, '>', strtotime($startTime));
$model = $model->where($prefix, '<', strtotime($endTime));
}
break;
}
return $model;
}
/**
* 获取去除html去除空格去除软回车,软换行,转换过后的字符串
* @param string $str
* @return string
*/
public static function HtmlToMbStr($str){
return trim(strip_tags(str_replace(["\n","\t","\r"," ","&nbsp;"],'',htmlspecialchars_decode($str))));
}
/**
* 截取中文指定字节
* @param string $str
* @param int $utf8len
* @param string $chaet
* @param string $file
* @return string
*/
public static function getSubstrUTf8($str,$utf8len=100,$chaet='UTF-8',$file='....'){
if(mb_strlen($str,$chaet)>$utf8len){
$str=mb_substr($str,0,$utf8len,$chaet).$file;
}
return $str;
}
/**
* 获取本季度 time
* @param int|string $time
* @param string $ceil
* @return array
*/
public static function getMonth($time='',$ceil=0){
if($ceil!=0)
$season = ceil(date('n') /3)-$ceil;
else
$season = ceil(date('n') /3);
$firstday=date('Y-m-01',mktime(0,0,0,($season - 1) *3 +1,1,date('Y')));
$lastday=date('Y-m-t',mktime(0,0,0,$season * 3,1,date('Y')));
return array($firstday,$lastday);
}
/**
* 高精度 加法
* @param int|string $uid id
* @param string $decField 相加的字段
* @param float|int $dec 加的值
* @param string $keyField id的字段
* @param int $acc 精度
* @return bool
*/
public static function bcInc($key, $incField, $inc, $keyField = null, $acc=2)
{
if(!is_numeric($inc)) return false;
$model = new self();
if($keyField === null) $keyField = $model->getPk();
$result = self::where($keyField,$key)->find();
if(!$result) return false;
$new = bcadd($result[$incField],$inc,$acc);
return false !== $model->where($keyField,$key)->update([$incField=>$new]);
}
/**
* 高精度 减法
* @param int|string $uid id
* @param string $decField 相减的字段
* @param float|int $dec 减的值
* @param string $keyField id的字段
* @param bool $minus 是否可以为负数
* @param int $acc 精度
* @return bool
*/
public static function bcDec($key, $decField, $dec, $keyField = null, $minus = false, $acc=2)
{
if(!is_numeric($dec)) return false;
$model = new self();
if($keyField === null) $keyField = $model->getPk();
$result = self::where($keyField,$key)->find();
if(!$result) return false;
if(!$minus && $result[$decField] < $dec) return false;
$new = bcsub($result[$decField],$dec,$acc);
return false !== $model->where($keyField,$key)->update([$decField=>$new]);
}
/**
* @param null $model
* @return Model
*/
protected static function getSelfModel($model = null)
{
return $model == null ? (new self()) : $model;
}
/**
* 数据个数
* @param string|\think\db\Raw $model
* @return int
*/
public static function counts($model): int
{
return $model->count();
}
/**
* 横线
* @param int $num
* @return string
*/
public static function cross(int $num=0): string
{
$str = "";
if ($num == 1) $str .= "|--";
elseif ($num > 1) for($i=0;$i<$num;$i++)
if ($i==0) $str .= "|--";
else $str .= "--";
return $str." ";
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace app\admin\model;
use app\admin\model\BaseModel;
/**
* Class Slides
* @package app\admin\model\system
* @author 李玉坤
* @date 2021-02-15 23:22
*/
class Slides extends BaseModel
{
/**
* 列表
* @param $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 李玉坤
* @date 2021-02-15 23:24
*/
public static function systemPage($where): array
{
$model = new self;
$count = self::counts($model);
if ($where['page'] && $where['limit']) $model = $model->page((int)$where['page'],(int)$where['limit']);
$data = $model->select()->each(function ($item){
if (!empty($item->pic)){
$item->pic = file_cdn($item->pic);
}
});
if ($data) $data = $data->toArray();
return compact('data','count');
}
}

View File

@ -0,0 +1,110 @@
<?php
namespace app\admin\model;
use app\admin\model\BaseModel;
/**
* 系统配置
* Class SystemConfig
* @package app\admin\model\system
*/
class SystemConfig extends BaseModel
{
/**
* 列表
* @param int $tab_id
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function lst($where): array
{
$model = new self;
if ($where['tab_id']) $model = $model->where('tab_id',$where['tab_id']);
$count = self::counts($model);
if ($where['page'] && $where['limit']) $model = $model->page((int)$where['page'],(int)$where['limit']);
$data = $model->select();
if ($data) $data = $data->toArray();
return compact('data','count');
}
/**
* 获取字段值
* @param string $formName
* @return string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getValueByFormName(string $formName): string
{
$model = new self;
$model = $model->where("form_name",$formName);
$model = $model->where("status",1);
$info = $model->find();
return $info ? $info['value'] : '';
}
/**
* @获取系统配置
* @return array
*/
public static function getSystemConfigValues(): array
{
$model = new self;
return $model->where("status",1)->column('value', 'form_name');
}
/**
* 获取字段值
* @param string $formNames
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getValuesByFormNames(array $formNames): array
{
$model = new self;
$model = $model->where("form_name",'in', $formNames);
$model = $model->where("status",1);
$info = $model->select();
return $info ? $info->toArray() : [];
}
/**
* 获取参数
* @param int $tab_id
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getLstByTabId(int $tab_id = 0): array
{
$model = new self;
$model = $model->where("tab_id",$tab_id);
$model = $model->where("status",1);
$model = $model->where("is_show",1);
$model = $model->order("rank desc");
$info = $model->select();
return $info ? $info->toArray() : [];
}
/**
* 修改value
* @param string $form_name
* @param string $value
* @return SystemConfig
*/
public static function editValueByFormName(string $form_name, string $value)
{
$model = new self;
$model = $model->where("form_name", $form_name);
return $model->update(['value'=>$value]);
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace app\admin\model;
use app\admin\model\BaseModel;
class SystemConfigTab extends BaseModel
{
/**
* 列表
* @param $where
* @return array
*/
public static function lst($where)
{
$model = new self;
if ($where['status'] != "") $model=$model->where("status",$where['status']);
if ($where['name'] != "") $model=$model->where("name","like","%$where[name]%");
$count = self::counts($model);
$model = $model->page((int)$where['page'],(int)$where['limit']);
$data = $model->select();
if ($data) $data = $data->toArray();
return compact("data","count");
}
}

View File

@ -0,0 +1,298 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<title>用户管理 - {:system_config("title")}后台管理系统</title>
{include file="public/header" /}
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>搜索</h4></div>
<div class="card-body">
<form class="form-inline searchForm" onsubmit="return false;">
<div class="form-group">
<label for="name">账号昵称</label>
<div class="input-group">
<div class="input-group">
<input type="text" class="form-control" id="name" value="" name="name" placeholder="请输入账号或者昵称搜索">
</div>
</div>
</div>
<div class="form-group">
<label for="tel">电话邮箱</label>
<div class="input-group">
<div class="input-group">
<input type="text" class="form-control" id="tel" value="" name="tel" placeholder="请输入电话或者邮箱">
</div>
</div>
</div>
<div class="form-group">
<label for="start_time">创建时间</label>
<div class="input-group">
<input class="form-control js-datetimepicker" type="text" id="start_time" name="start_time" value="" autocomplete="off" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="开始时间">
<span class="input-group-addon">~</span>
<input class="form-control js-datetimepicker" type="text" name="end_time" value="" autocomplete="off" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="结束时间">
</div>
</div>
<div class="form-group">
<label for="role_id">角色类型</label>
<select name="role_id" id="role_id" class="form-control">
<option value="">所有</option>
{volist name="auths" id="vo"}
<option value="{$vo.id}">{$vo.name}</option>
{/volist}
</select>
</div>
<div class="form-group">
<label for="status">状态</label>
<select name="status" id="status" class="form-control">
<option value="">所有</option>
<option value="1">启用</option>
<option value="0">禁用</option>
</select>
</div>
<button type="submit" class="btn btn-success" style="margin: -10px 0 0 10px;" id="search">搜索</button>
</form>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>用户管理</h4></div>
<div class="card-body">
<div id="toolbar" class="toolbar-btn-action">
<button id="btn_add" type="button" class="btn btn-primary m-r-5" onclick="iframe.createIframe('添加用户','/admin/admin/add')">
<span class="mdi mdi-plus" aria-hidden="true"></span>新增
</button>
<button id="btn_edit" type="button" class="btn btn-success m-r-5" onclick="isEnable('enable')">
<span class="mdi mdi-check" aria-hidden="true"></span>启用
</button>
<button id="btn_disable" type="button" class="btn btn-warning m-r-5" onclick="isEnable('disable')">
<span class="mdi mdi-block-helper" aria-hidden="true"></span>禁用
</button>
<button id="btn_delete" type="button" class="btn btn-danger" onclick="del()">
<span class="mdi mdi-window-close" aria-hidden="true"></span>删除
</button>
</div>
<table id="tb_departments"></table>
</div>
</div>
</div>
</div>
</div>
{include file="public/footer"/}
<script type="text/javascript">
$('#tb_departments').bootstrapTable({
classes: 'table table-bordered table-hover table-striped',
url: '/admin/admin/lst',
method: 'post',
dataType : 'json', // 因为本示例中是跨域的调用,所以涉及到ajax都采用jsonp,
uniqueId: 'id',
idField: 'id', // 每行的唯一标识字段
toolbar: '#toolbar', // 工具按钮容器
showColumns: true, // 是否显示所有的列
showRefresh: true, // 是否显示刷新按钮
responseHandler: function (res) {
return {
"total": res.count,
"rows": res.data,
};
},
pagination: true,
queryParams: function(params) {
var temp = toArrayList($(".searchForm").serializeArray());
temp['limit'] = params.limit;
temp['page'] = (params.offset / params.limit) + 1;
return temp;
},
sidePagination: "server",
pageNumber: 1,
pageSize: 20,
pageList: [20, 50, 100],
columns: [{
checkbox: true // 是否显示复选框
}, {
field: 'id',
title: 'ID',
sortable: true // 是否排序
}, {
field: 'name',
title: '账号'
}, {
field: 'nickname',
title: '昵称',
}, {
field: 'avatar',
title: '头像',
formatter:function (value,row,index) {
return '<img src="'+value+'" style="width: 64px;"/>';
},
}, {
field: 'role_id',
title: '角色类型'
}, {
field: 'tel',
title: '电话'
}, {
field: 'mail',
title: '邮箱'
}, {
field: 'create_time',
title: '创建时间'
}
, {
field: 'status',
title: '状态',
formatter:function (value,row,index) {
return value === 1 ? '启用' : '冻结';
},
}, {
field: 'operate',
title: '操作',
formatter: btnGroup, // 自定义方法
events: {
'click .edit-btn': function (event, value, row, index) {
iframe.createIframe('修改用户','/admin/admin/edit?id='+row.id)
},
'click .del-btn': function (event, value, row, index) {
$.alert({
title: '系统提示',
content: '删除提醒',
buttons: {
confirm: {
text: '确认',
btnClass: 'btn-primary',
action: function(){
$.post(url="/admin/admin/del",data={"id":row.id},function (res) {
if (res.status == 200) {parent.lightyear.notify('删除成功', 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');$("#tb_departments").bootstrapTable('refresh');}
else parent.lightyear.notify('删除失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
});
}
},
cancel: {
text: '取消'
}
}
});
}
}
}],
onEditableSave: function (field, row, oldValue, $el) {
$.ajax({
type: "get",
url: "/admin/admin/lst",
data: row,
dataType: 'jsonp',
success: function (data, status) {
if (data.code == '200') {
// 这里的状态显示有自定义样式区分,做单行的更新
$('.example-table').bootstrapTable('updateRow', {index: row.id, row: row});
} else {
alert(data.msg);
}
},
error: function () {
alert('修改失败,请稍后再试');
}
});
},
onLoadSuccess: function(data){
$("[data-toggle='tooltip']").tooltip();
}
});
$("#search").click(function () {
$("#tb_departments").bootstrapTable('refresh',{query:{page:1},pageNumber:1});
});
// 操作按钮
function btnGroup ()
{
let html =
'<a href="#!" class="btn btn-xs btn-default m-r-5 edit-btn" title="编辑" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>' +
'<a href="#!" class="btn btn-xs btn-default del-btn" title="删除" data-toggle="tooltip"><i class="mdi mdi-window-close"></i></a>';
return html;
}
// 删除
function del() {
var checkID = "";
var selectedItem = $('#tb_departments').bootstrapTable('getAllSelections');
if (selectedItem=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
for (var i = 0 ; i< selectedItem.length; i++)
{
checkID += selectedItem[i]['id']+",";
}
if (checkID=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.confirm({
title: '重要提醒!',
content: '选中项将全部被删除,请谨慎操作!' ,
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin/del",data={id:checkID},function (res) {
if (res.status == 200){ lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');location.reload();}
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
// 批量启用或者禁用
function isEnable(type) {
var checkID = "";
var selectedItem = $('#tb_departments').bootstrapTable('getAllSelections');
if (selectedItem=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
for (var i = 0 ; i< selectedItem.length; i++)
{
checkID += selectedItem[i]['id']+",";
}
if (checkID=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.confirm({
title: '重要提醒!',
content: type == 'enable' ? '选中项将全部启用,请谨慎操作!' : '选中项将全部禁用,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
if (type == 'enable')
{
$.post("/admin/admin/enabled",data={id:checkID},function (res) {
if (res.status == 200) {lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');location.reload();}
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
})
}else
{
$.post("/admin/admin/disabled",data={id:checkID},function (res) {
if (res.status == 200) {lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');location.reload();}
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
})
}
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
</script>
</body>
</html>

View File

@ -0,0 +1,406 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>个人信息 - {:system_config("title")}后台管理系统</title>
<link rel="icon" href="{:system_config("favicon")}" type="image/ico">
<meta name="keywords" content="{:system_config("keywords")}">
<meta name="description" content="{:system_config("description")}">
<meta name="author" content="{:system_config("author")}">
<link href="__ADMIN_PATH__css/bootstrap.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/materialdesignicons.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/style.min.css" rel="stylesheet">
<link rel="stylesheet" href="__ADMIN_PATH__js/jconfirm/jquery-confirm.min.css">
<link href="__ADMIN_PATH__css/cropper.min.css" rel="stylesheet">
<style type="text/css">
/* 裁剪样式 */
.image-wrapper {
height: 364px;
width: 100%;
box-shadow: inset 0 0 3px rgba(0, 0, 0, .075);
background-color: #fcfdfe;
overflow: hidden;
}
.image-preview {
float: left;
margin-bottom: 0.5rem;
margin-right: 0.5rem;
border: 1px solid #f1f2f3;
border-radius: 2px;
background-color: #fff;
overflow: hidden;
}
.image-preview img {
vertical-align: top;
}
.preview-lg {
height: 9rem;
width: 16rem;
}
.preview-md {
height: 4.5rem;
width: 8rem;
}
.preview-sm {
height: 2.25rem;
width: 4rem;
}
.preview-xs {
height: 1.125rem;
margin-right: 0;
width: 2rem;
}
@media (max-width: 991px) {
#image-modal .image-btns {
margin-bottom: 15px;
}
}
/* loading样式 - 可整体替换之前的loading */
@-webkit-keyframes spinner-border {
to {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes spinner-borderspinner-border {
to {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
.spinner-border {
display: inline-block;
vertical-align: text-bottom;
border: 0.125em solid currentColor;
border-right-color: transparent;
border-radius: 50%;
-webkit-animation: spinner-border .75s linear infinite;
animation: spinner-border .75s linear infinite;
}
</style>
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-body">
<div class="edit-avatar">
<img src="{$info.avatar}" alt="{$info.name}" class="img-avatar">
<div class="avatar-divider"></div>
<div class="edit-avatar-content">
<button class="btn btn-default trigger-btn">修改头像</button>
<p class="m-0">选择一张你喜欢的图片裁剪后会自动生成264x264大小上传图片大小不能超过2M。</p>
</div>
</div>
<hr>
<form class="site-form">
<input type="hidden" class="form-control" name="avatar" id="avatar" value="{$info.avatar}"/>
<div class="form-group">
<label for="name">用户名</label>
<input type="text" class="form-control" name="name" id="name" value="{$info.name}" disabled="disabled" />
</div>
<div class="form-group">
<label for="realname">真实姓名</label>
<input type="text" class="form-control" name="realname" id="realname" value="{$info.realname}" disabled="disabled" />
</div>
<div class="form-group">
<label for="nickname">昵称</label>
<input type="text" class="form-control" name="nickname" id="nickname" value="{$info.nickname}" />
</div>
<div class="form-group">
<label for="tel">电话</label>
<input type="tel" class="form-control" name="tel" id="tel" placeholder="输入您的昵称" value="{$info.tel}">
</div>
<div class="form-group">
<label for="mail">邮箱</label>
<input type="email" class="form-control" name="mail" id="mail" aria-describedby="emailHelp" placeholder="请输入正确的邮箱地址" value="{$info.mail}">
<small id="emailHelp" class="form-text text-muted">请保证您填写的邮箱地址是正确的。</small>
</div>
<div class="form-group">
<label for="remark">简介</label>
<textarea class="form-control" name="remark" id="remark" rows="3">{$info.remark|default="这家伙很懒,什么也没留下"}</textarea>
</div>
<button type="submit" class="btn btn-primary">保存</button>
</form>
</div>
</div>
</div>
</div>
</div>
<!--图片裁剪START-->
<div class="modal fade" id="image-modal" aria-hidden="true" aria-labelledby="image-modal-label" role="dialog" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button class="close" data-dismiss="modal" type="button">&times;</button>
<h4 class="modal-title" id="image-modal-label">上传图片</h4>
</div>
<div class="modal-body">
<div class="image-body">
<div class="image-upload m-b-15">
<button class="btn btn-primary" type="button" onclick="$('input[id=imageInput]').click();">请选择图片</button>
<span class="image-name"></span>
<input type="file" class="image-input hide" id="imageInput" name="file" accept=".jpg,.jpeg,.png,.gif,.bmp,.tiff">
</div>
<div class="row">
<div class="col-md-9 m-b-15">
<div class="image-wrapper"></div>
</div>
<div class="col-md-3">
<div class="image-previews clearfix">
<div class="image-preview preview-lg"></div>
<div class="image-preview preview-md"></div>
<div class="image-preview preview-sm"></div>
<div class="image-preview preview-xs"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 image-btns">
<button class="btn btn-primary mdi mdi-rotate-left" data-method="rotate" data-option="-45" type="button" title="向左旋转-45度"></button>
<button class="btn btn-primary mdi mdi-rotate-right" data-method="rotate" data-option="45" type="button" title="向右旋转45度"></button>
<button type="button" class="btn btn-primary mdi mdi-magnify-plus-outline" data-method="zoom" data-option="0.1" title="放大图片"></button>
<button type="button" class="btn btn-primary mdi mdi-magnify-minus-outline" data-method="zoom" data-option="-0.1" title="缩小图片"></button>
<button type="button" class="btn btn-primary mdi mdi-cached" data-method="reset" title="重置图片"></button>
</div>
<div class="col-md-5 image-btns toggles-btns">
<div class="btn-group btn-group-toggle" data-toggle="buttons">
<label class="btn btn-primary">
<input type="radio" name="aspectRatio" id="aspectRatio1" value="1.7777777777777777">
<span>16:9</span>
</label>
<label class="btn btn-primary">
<input type="radio" name="aspectRatio" id="aspectRatio2" value="1.3333333333333333">
<span>4:3</span>
</label>
<label class="btn btn-primary active">
<input type="radio" name="aspectRatio" id="aspectRatio3" value="1" checked>
<span>1:1</span>
</label>
<label class="btn btn-primary">
<input type="radio" name="aspectRatio" id="aspectRatio4" value="0.6666666666666666">
<span>2:3</span>
</label>
<label class="btn btn-primary">
<input type="radio" name="aspectRatio" id="aspectRatio5" value="NaN">
<span>自适应</span>
</label>
</div>
</div>
<div class="col-md-3">
<button class="btn btn-primary btn-block upload-btn mdi mdi-content-save" type="submit">保存修改</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!--图片裁剪END-->
<script type="text/javascript" src="__ADMIN_PATH__js/jquery.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/main.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/cropper.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-notify.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/lightyear.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/jquery.lyear.loading.js"></script>
<script src="__ADMIN_PATH__js/jconfirm/jquery-confirm.min.js"></script>
<script>
$(".site-form").submit(function () {
if ($("input[name='nickname']").val() == '') lightyear.notify('昵称不能为空', 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
else if ($("input[name='avatar']").val() == '') lightyear.notify('头像不能为空', 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
else if ($("input[name='tel']").val() == '') lightyear.notify('电话不能为空', 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
else if ($("input[name='mail']").val() == '') lightyear.notify('邮箱不能为空', 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
else
$.post(url="/admin/admin/changProfile",{
"nickname":$("input[name='nickname']").val(),
"avatar":$("input[name='avatar']").val(),
"tel":$("input[name='tel']").val(),
"mail":$("input[name='mail']").val(),
"remark":$("textarea[name='remark']").val()
},function (res) {
if (res.status === 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
});
return false;
})
</script>
<script>
function cropImage()
{
this.$triggerBtn = $('.trigger-btn'); // 上传按钮
//this.$imageText = this.$triggerBtn.parent().prev('.image-src'); // 图片地址输入框
this.$imageModal = $('#image-modal'); // 弹出框
this.$imageName = this.$imageModal.find('.image-name') // 图片名称
this.$imageInput = this.$imageModal.find('.image-input'); // file上传文件
this.$imageUpload = this.$imageModal.find('.image-upload'); // file所在元素
this.$imageBtns = this.$imageModal.find('.image-btns'); // 图片调整按钮(旋转、放大等)
this.$imageWrapper = this.$imageModal.find('.image-wrapper'); // 图片处理区域
this.$imagePreview = this.$imageModal.find('.image-preview'); // 图片裁剪预览区域
this.$uploadBtn = this.$imageModal.find('.upload-btn'); // 上传按钮
this.$togglesBtns = this.$imageModal.find('.toggles-btns'); // 比例切换按钮
this.URL = window.URL || window.webkitURL;
this.$options = {
aspectRatio: 1 / 1,
preview: '.image-preview'
}; // 配置
this.init();
}
cropImage.prototype = {
constructor: cropImage,
init: function() {
this.initModal();
this.addListener();
},
initModal: function() {
this.$imageModal.modal({
show: false
});
if(!URL) {
this.$imageInput.prop('disabled', true);
}
},
addListener: function() {
// 绑定事件
this.$triggerBtn.on('click', $.proxy(this.click, this));
this.$imageInput.on('change', $.proxy(this.change, this));
this.$togglesBtns.on('change', $.proxy(this.choose, this));
this.$uploadBtn.on('click', $.proxy(this.ajaxUpload, this));
this.$imageBtns.on('click', $.proxy(this.rotate, this));
},
click: function(e) {
// 点击上传按钮
this.$imageText = $(e.target).parent().prev('.image-src');
this.$imageModal.modal('show');
this.initPreview();
},
initPreview: function() {
this.active = false;
this.$imageInput.val('');
this.$imageName.text('');
this.$imageWrapper.empty();
// 如果已有图片地址,初始化图片预览区域
this.$imagePreview.empty();
// var url = this.$imageText.val();
// url != "" && this.$imagePreview.html('<img src="' + url + '">');
},
change: function() {
// 选择图片
var files, file;
files = this.$imageInput.prop('files');
if (files && files.length > 0) {
file = files[0];
if (this.isImageFile(file)) {
this.$imageType = file.type;
this.$imageName.text(file.name);
if (this.imageUrl) {
this.URL.revokeObjectURL(this.imageUrl);
}
this.imageUrl = this.URL.createObjectURL(file);
this.startCropper();
}
}
},
startCropper: function() {
// 选择图片后初始化
if (this.active) {
this.$image.cropper('replace', this.url);
} else {
this.$image = $('<img src="' + this.imageUrl + '">');
this.$imageWrapper.empty().html(this.$image);
this.$image.cropper('destroy').cropper(this.$options);
this.active = true;
}
},
isImageFile: function(file) {
// 判断是否图片格式
if (file.type) {
return /^image\/\w+$/.test(file.type);
} else {
return /\.(jpg|jpeg|png|gif|bmp|tiff)$/.test(file);
}
},
choose: function(e) {
var $this = $(e.target);
var name = $this.attr('name');
if (!this.active) {
return;
}
this.$options[name] = $this.val();
this.$image.cropper('destroy').cropper(this.$options);
},
rotate: function(e) {
// 调整图片操作
var data;
if (this.active) {
data = $(e.target).data();
if (data.method) {
this.$image.cropper(data.method, data.option);
}
}
},
stopCropper: function() {
// 裁剪上传完成后重置
if (this.active) {
this.$image.cropper('destroy');
this.$image.remove();
this.$imageModal.modal('hide');
this.$imageInput.val('');
this.$imageName.text('');
this.$togglesBtns.find('#aspectRatio3').attr('checked', true);
this.active = false;
}
},
ajaxUpload: function() {
var cas = this.$image.cropper('getCroppedCanvas'),
base64Data = cas.toDataURL(this.$imageType),
_this = this,
$loading;
// ajax上传
$.ajax("/admin/files/baseToImage", {
type: 'post',
data: {"image" : base64Data},
dataType: 'json',
beforeSend: function() {
_this.$uploadBtn.prop('disabled', true);
$loading = $('.upload-btn').lyearloading({
opacity: 0.2,
spinnerSize: 'nm'
});
},
success: function(data) {
if ($.isPlainObject(data) && (data.state === 200 || data.status === 200 || data.code === 200)) {
$("#avatar").val(data.data.src);
$(".img-avatar").attr("src",data.data.src);
_this.$imageText.val(data.data.src);
_this.stopCropper();
} else {
lightyear.notify(data.message, 'danger', 3000);
}
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log(textStatus);
},
complete: function() {
_this.$uploadBtn.prop('disabled', false);
$loading.destroy();
}
});
}
};
$(document).ready(function(){
new cropImage();
});
</script>
</body>
</html>

View File

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>修改密码 - {:system_config("title")}后台管理系统</title>
<link rel="icon" href="{:system_config("favicon")}" type="image/ico">
<meta name="keywords" content="{:system_config("keywords")}">
<meta name="description" content="{:system_config("description")}">
<meta name="author" content="{:system_config("author")}">
<link href="__ADMIN_PATH__css/bootstrap.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/materialdesignicons.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/style.min.css" rel="stylesheet">
<link rel="stylesheet" href="__ADMIN_PATH__js/jconfirm/jquery-confirm.min.css">
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-body">
<form class="site-form" id="changePwd">
<div class="form-group">
<label for="old-password">旧密码</label>
<input type="password" class="form-control" name="oldpwd" id="old-password" placeholder="输入账号的原登录密码">
</div>
<div class="form-group">
<label for="new-password">新密码</label>
<input type="password" class="form-control" name="newpwd" id="new-password" placeholder="输入新的密码">
</div>
<div class="form-group">
<label for="confirm-password">确认新密码</label>
<input type="password" class="form-control" name="confirmpwd" id="confirm-password" placeholder="确认新密码">
</div>
<button type="submit" class="btn btn-primary">修改密码</button>
</form>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="__ADMIN_PATH__js/jquery.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-notify.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/main.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/lightyear.js"></script>
<script src="__ADMIN_PATH__js/jconfirm/jquery-confirm.min.js"></script>
<script>
$("#changePwd").submit(function () {
if ($("input[name='oldpwd']").val() == '') lightyear.notify('旧密码为空', 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
else if ($("input[name='newpwd']").val() == '') lightyear.notify('新密码为空', 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
else if ($("input[name='confirmpwd']").val() == '') lightyear.notify('重复输入密码为空', 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
else if ($("input[name='newpwd']").val() != $("input[name='confirmpwd']").val()) lightyear.notify('两次密码输入不正确', 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
else
$.post(url="/admin/admin/changePwd",{"oldpwd":$("input[name='oldpwd']").val(),"newpwd":$("input[name='newpwd']").val()},function (res) {
if (res.status === 200) {
lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
setTimeout(function(){ top.location.href = "/admin/login/login"; }, 1000);
} else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
});
return false;
})
</script>
</body>
</html>

View File

@ -0,0 +1,349 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<title>登录页面 - {:system_config("title")}后台管理系统</title>
{include file="public/header" /}
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>搜索</h4></div>
<div class="card-body">
<form class="form-inline searchForm" onsubmit="return false;">
<div class="form-group">
<label for="name">权限名称</label>
<div class="input-group">
<div class="input-group">
<input type="text" class="form-control" id="name" value="" name="name" placeholder="请输入权限名称或者ID">
</div>
</div>
</div>
<div class="form-group">
<label for="status">状态</label>
<select name="status" id="status" class="form-control">
<option value="">所有</option>
<option value="1">启用</option>
<option value="0">禁用</option>
</select>
</div>
<button type="submit" class="btn btn-success" style="margin: -10px 0 0 10px;" id="search">搜索</button>
</form>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<h4>权限管理</h4>
</div>
<div class="card-body">
<div id="toolbar2" class="toolbar-btn-action">
<button type="button" class="btn btn-primary m-r-5" onclick="iframe.createIframe('添加权限','/admin/admin_auth/add')"><span class="mdi mdi-plus" aria-hidden="true"></span>新增</button>
<button id="btn_edit" type="button" class="btn btn-success m-r-5" onclick="isEnable('enable')">
<span class="mdi mdi-check" aria-hidden="true"></span>启用
</button>
<button id="btn_disable" type="button" class="btn btn-warning m-r-5" onclick="isEnable('disable')">
<span class="mdi mdi-block-helper" aria-hidden="true"></span>禁用
</button>
<button id="btn_delete" type="button" class="btn btn-danger" onclick="del()">
<span class="mdi mdi-window-close" aria-hidden="true"></span>删除
</button>
</div>
<table class="tree-table"></table>
</div>
</div>
</div>
</div>
</div>
{include file="public/footer"/}
<!--以下是tree-grid的使用示例-->
<link href="__ADMIN_PATH__js/jquery-treegrid/jquery.treegrid.min.css" rel="stylesheet">
<script type="text/javascript" src="__ADMIN_PATH__js/jquery-treegrid/jquery.treegrid.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-table/extensions/treegrid/bootstrap-table-treegrid.min.js"></script>
<script type="text/javascript">
// tree-grid使用
var $treeTable = $('.tree-table');
$treeTable.bootstrapTable({
url: '/admin/adminAuth/lst',
method: 'post',
responseHandler: function (res) {
return {
"rows": res.data,
};
},
queryParams: function(params) {
var temp = toArrayList($(".searchForm").serializeArray());
return temp;
},
idField: 'id',
uniqueId: 'id',
dataType: 'json',
toolbar: '#toolbar2',
showColumns: true, // 是否显示所有的列
showRefresh: true, // 是否显示刷新按钮
columns: [
{
field: 'check',
checkbox: true
},
{
field: 'name',
title: '名称'
},
{
field: 'id',
title: '权限ID'
},
{
field: 'icon',
title: '图标',
formatter: function (value, row, index) {
return '<i class="'+value+'"></i>';
},
},
{
field: 'module',
title: '模板名'
},
{
field: 'controller',
title: '控制器'
},
{
field: 'action',
title: '方法名'
},
{
field: 'is_menu',
title: '是否菜单',
formatter: function (value, row, index) {
if (value == 0) {
is_checked = '';
} else if (value == 1){
is_checked = 'checked="checked"';
}
var field = "is_menu";
result = '<label class="lyear-switch switch-primary switch-solid lyear-status"><input type="checkbox" '+ is_checked +'><span onClick="updateStatus('+ row.id +', '+ value +', \''+ field +'\')"></span></label>';
return result;
},
},
{
field: 'rank',
title: '排序',
sortable: true,
},
{
field: 'status',
title: '状态',
formatter: function (value, row, index) {
if (value == 0) {
is_checked = '';
} else if (value == 1){
is_checked = 'checked="checked"';
}
var field = "status";
result = '<label class="lyear-switch switch-primary switch-solid lyear-status"><input type="checkbox" '+ is_checked +'><span onClick="updateStatus('+ row.id +', '+ value +', \''+ field +'\')"></span></label>';
return result;
},
},
{
field: 'operate',
title: '操作',
align: 'center',
events : {
'click .role-add': function (e, value, row, index) {
iframe.createIframe('添加权限','/admin/admin_auth/add?pid='+row.id);
},
'click .role-delete': function (e, value, row, index) {
$.alert({
title: '系统提示',
content: '删除提醒',
buttons: {
confirm: {
text: '确认',
btnClass: 'btn-primary',
action: function(){
$.post(url="/admin/admin_auth/del",data={"id":row.id},function (res) {
if (res.status == 200) {parent.lightyear.notify('删除成功', 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');$(".tree-table").bootstrapTable('refresh');}
else parent.lightyear.notify('删除失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
});
}
},
cancel: {
text: '取消'
}
}
});
},
'click .role-edit': function (e, value, row, index) {
iframe.createIframe('修改权限','/admin/admin_auth/edit?id='+row.id)
}
},
formatter: operateFormatter
}
],
treeShowField: 'name',
parentIdField: 'pid',
onResetView: function(data) {
$treeTable.treegrid({
initialState: 'collapsed', // 所有节点都折叠
treeColumn: 1,
onChange: function() {
$treeTable.bootstrapTable('resetWidth');
}
});
// 只展开树形的第一集节点
$treeTable.treegrid('getRootNodes').treegrid('expand');
},
onCheck: function(row) {
var datas = $treeTable.bootstrapTable('getData');
selectChilds(datas, row, 'id', 'pid', true);
selectParentChecked(datas, row, 'id', 'pid');
$treeTable.bootstrapTable('load', datas);
},
onUncheck: function(row) {
var datas = $treeTable.bootstrapTable('getData');
selectChilds(datas, row, 'id', 'pid', false);
$treeTable.bootstrapTable('load', datas);
},
});
// 操作按钮
function operateFormatter(value, row, index) {
return [
'<a type="button" class="role-add btn btn-xs btn-default m-r-5" title="编辑" data-toggle="tooltip"><i class="mdi mdi-plus"></i></a>',
'<a type="button" class="role-edit btn btn-xs btn-default m-r-5" title="修改" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>',
'<a type="button" class="role-delete btn btn-xs btn-default" title="删除" data-toggle="tooltip"><i class="mdi mdi-delete"></i></a>'
].join('');
}
/**
* 选中父项时,同时选中子项
* @param datas 所有的数据
* @param row 当前数据
* @param id id 字段名
* @param pid 父id字段名
*/
function selectChilds(datas,row,id,pid,checked) {
for(var i in datas){
if(datas[i][pid] == row[id]){
datas[i].check=checked;
selectChilds(datas,datas[i],id,pid,checked);
};
}
}
function selectParentChecked(datas,row,id,pid){
for(var i in datas){
if(datas[i][id] == row[pid]){
datas[i].check=true;
selectParentChecked(datas,datas[i],id,pid);
};
}
}
function updateStatus(id, value,field) {
var newstate = (value == 1) ? 0 : 1; // 发送参数值跟当前参数值相反
$.ajax({
type: "post",
url: "/admin/admin_auth/field?id="+id,
data: {field: field, value: newstate},
dataType: 'json',
success: function (res) {
if (res.status == 200) {parent.lightyear.notify('修改成功', 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');$(".tree-table").bootstrapTable('refresh');}
else parent.lightyear.notify('修改失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
},
error: function () {
parent.lightyear.notify('修改失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
}
});
}
// 删除
function del() {
var checkID = "";
var selectedItem = $treeTable.bootstrapTable('getSelections');
if (selectedItem=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
for (var i = 0 ; i< selectedItem.length; i++)
{
checkID += selectedItem[i]['id']+",";
}
if (checkID=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.confirm({
title: '重要提醒!',
content: '选中项将全部被删除,请谨慎操作!' ,
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_auth/del",data={id:checkID},function (res) {
if (res.status == 200){ lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');location.reload();}
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
// 批量启用或者禁用
function isEnable(type) {
var checkID = "";
var selectedItem = $treeTable.bootstrapTable('getSelections');
if (selectedItem=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
for (var i = 0 ; i< selectedItem.length; i++)
{
checkID += selectedItem[i]['id']+",";
}
if (checkID=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.confirm({
title: '重要提醒!',
content: type == 'enable' ? '选中项将全部启用,请谨慎操作!' : '选中项将全部禁用,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
if (type == 'enable')
{
$.post("/admin/admin_auth/enabled",data={id:checkID},function (res) {
if (res.status == 200) {lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');location.reload();}
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
})
}else
{
$.post("/admin/admin_auth/disabled",data={id:checkID},function (res) {
if (res.status == 200) {lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');location.reload();}
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
})
}
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
$("#search").click(function () {
$treeTable.bootstrapTable('refresh', {});
});
</script>
</body>
</html>

View File

@ -0,0 +1,214 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<title>操作日志 - {:system_config("title")}后台管理系统</title>
{include file="public/header" /}
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>搜索</h4></div>
<div class="card-body">
<form class="form-inline searchForm" onsubmit="return false;">
<div class="form-group">
<label for="name">操作人</label>
<div class="input-group">
<div class="input-group">
<input type="text" class="form-control" id="name" name="name" placeholder="请输入操作人名称ID">
</div>
</div>
</div>
<div class="form-group">
<label for="ip">来访IP</label>
<div class="input-group">
<div class="input-group">
<input type="text" class="form-control" id="ip" name="ip" placeholder="IP地址">
</div>
</div>
</div>
<div class="form-group">
<label for="start_time">操作时间</label>
<div class="input-group">
<input class="form-control js-datetimepicker" type="text" id="start_time" name="start_time" autocomplete="off" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="开始时间">
<span class="input-group-addon">~</span>
<input class="form-control js-datetimepicker" type="text" id="end_time" name="end_time" autocomplete="off" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="结束时间">
</div>
</div>
<button type="submit" class="btn btn-success" style="margin: -10px 0 0 10px;" id="search">搜索</button>
</form>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="card">
<div class="card-toolbar clearfix">
<div class="toolbar-btn-action">
<a class="btn btn-warning" href="#!" onclick="delSelect()"><i class="mdi mdi-window-close"></i> 删除</a>
<a class="btn btn-danger" href="#!" onclick="delAll()"><i class="mdi mdi-window-close"></i> 全部删除</a>
</div>
</div>
<div class="card-body">
<table id="tb_departments"></table>
</div>
</div>
</div>
</div>
</div>
{include file="public/footer"/}
<script type="text/javascript">
$('#tb_departments').bootstrapTable({
classes: 'table table-bordered table-hover table-striped',
url: '/admin/admin_log/Lst',
method: 'post',
dataType : 'json', // 因为本示例中是跨域的调用,所以涉及到ajax都采用jsonp,
uniqueId: 'id',
idField: 'id', // 每行的唯一标识字段
toolbar: '#toolbar', // 工具按钮容器
showColumns: false, // 是否显示所有的列
showRefresh: false, // 是否显示刷新按钮
responseHandler: function (res) {
return {
"total": res.count,
"rows": res.data,
};
},
pagination: true,
queryParams: function(params) {
let temp = toArrayList($(".searchForm").serializeArray());
temp['limit'] = params.limit;
temp['page'] = (params.offset / params.limit) + 1;
return temp;
},
sidePagination: "server",
pageNumber: 1,
pageSize: 10,
pageList: [10, 20, 50, 100],
columns: [{
checkbox: true, // 是否显示复选框
},{
field: 'id',
title: '序号'
},{
field: 'admin_name',
title: '操作人'
}, {
field: 'name',
title: '操作名称',
}, {
field: 'ip',
title: 'IP',
},{
field: 'user_agent',
title: 'User Agent',
}, {
field: 'create_time',
title: '操作时间',
}, {
field: 'operate',
title: '操作',
formatter:function (value,row,index) {
let html ='<a class="btn btn-xs btn-default btn-del" href="#!" title="删除" data-toggle="tooltip" onclick="delOne('+row.id+')"><i class="mdi mdi-window-close"></i></a>';
return html;
}
}],
onLoadSuccess: function(data){
$("[data-toggle='tooltip']").tooltip();
}
});
//搜索
$("#search").click(function () {
let start_time = $('#start_time').val();
let end_time = $('#end_time').val();
if(start_time && end_time && start_time > end_time ){
alert('开始时间不能大于结束时间');
return false;
}
$("#tb_departments").bootstrapTable('refresh',{query:{page:1},pageNumber:1});
});
function delOne(id) {
$.confirm({
title: '重要提醒!',
content: '删除后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/del",data={id:id},function (res) {
if (res.status == 200 || res.code == 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
location.reload();
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
function delAll() {
$.confirm({
title: '重要提醒!',
content: '清空后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/empty",data={},function (res) {
if (res.status == 200 || res.code == 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
location.reload();
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
function delSelect() {
var checkID = "";
var selectedItem = $('#tb_departments').bootstrapTable('getSelections');
if (selectedItem=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
for (var i = 0 ; i< selectedItem.length; i++)
{
checkID += selectedItem[i]['id']+",";
}
if (checkID=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.confirm({
title: '重要提醒!',
content: '选中项删除后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/del",data={id:checkID},function (res) {
if (res.status == 200 || res.code == 200) { lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');location.reload();}
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
</script>
</body>
</html>

View File

@ -0,0 +1,103 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的信息 - {:system_config("title")}后台管理系统</title>
{include file="public/header" /}
<style>
.mytb{
float: right;
font-size: 14px;
}
.mytb::after {
font-family: 'Material Design Icons';
color: rgb(170, 170, 170);
display: block;
float: right;
content: "\f35d";
padding-left: 5px;
}
.collapsed > .mytb:after {
content: '\f142';
}
.panel-title{
color: #666;
}
.panel-title .active{
color: #000;
}
</style>
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>搜索</h4></div>
<div class="card-body">
<form class="form-inline searchForm">
<div class="form-group">
<label for="title">关键词</label>
<div class="input-group">
<div class="input-group">
<input type="text" class="form-control" id="title" value="{$where.title}" autocomplete="off" name="title" placeholder="请输入标题或者内容">
</div>
</div>
</div>
<div class="form-group">
<label for="start_time">时间</label>
<div class="input-group">
<input class="form-control js-datetimepicker" type="text" id="start_time" autocomplete="off" name="start_time" value="{$where.start_time}" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="开始时间">
<span class="input-group-addon">~</span>
<input class="form-control js-datetimepicker" type="text" name="end_time" autocomplete="off" value="{$where.end_time}" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="结束时间">
</div>
</div>
<div class="form-group">
<label for="is_read">是否已读</label>
<select name="is_read" id="is_read" class="form-control">
<option value="" {if $where.is_read === ''} selected {/if}>所有</option>
<option value="1" {if $where.is_read === '1'} selected {/if}>已读</option>
<option value="0" {if $where.is_read === '0'} selected {/if}>未读</option>
</select>
</div>
<button type="submit" class="btn btn-success" style="margin: -10px 0 0 10px;" id="search">搜索</button>
</form>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>我的信息</h4></div>
<div class="card-body">
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="false">
{volist name="list" id="vo"}
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="heading{$vo.id}">
<h4 class="panel-title">
<a role="button" class="collapsed {if $vo.is_read == 0}active{/if}" data-toggle="collapse" data-parent="#accordion" href="#collapse{$vo.id}" aria-expanded="false" aria-controls="collapse{$vo.id}" onclick="isRead('{$vo.id}')">
{$vo.title} <span class="mytb">{$vo.add_time|date="Y-m-d H:i:s"}</span>
</a>
</h4>
</div>
<div id="collapse{$vo.id}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading{$vo.id}">
<div class="panel-body">
{$vo.content}
</div>
</div>
</div>
{/volist}
</div>
{$list|raw}
</div>
</div>
</div>
</div>
</div>
</body>
{include file="public/footer"/}
<script>
function isRead(id) {
$.post(url="/admin/admin_notify/field?id="+id,{field:'is_read',value:1}); // 点击已读
}
</script>
</html>

View File

@ -0,0 +1,225 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<title>角色管理 - {:system_config("title")}后台管理系统</title>
{include file="public/header" /}
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<h4>角色管理</h4>
</div>
<div class="card-body">
<div id="toolbar2" class="toolbar-btn-action">
<button type="button" class="btn btn-primary m-r-5" onclick="iframe.createIframe('添加角色','/admin/admin_role/add')"><span class="mdi mdi-plus" aria-hidden="true"></span>新增</button>
</div>
<table class="tree-table"></table>
</div>
</div>
</div>
</div>
</div>
{include file="public/footer"/}
<!--以下是tree-grid的使用示例-->
<link href="__ADMIN_PATH__js/jquery-treegrid/jquery.treegrid.min.css" rel="stylesheet">
<script type="text/javascript" src="__ADMIN_PATH__js/jquery-treegrid/jquery.treegrid.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-table/extensions/treegrid/bootstrap-table-treegrid.min.js"></script>
<script type="text/javascript">
// tree-grid使用
var $treeTable = $('.tree-table');
$treeTable.bootstrapTable({
url: '/admin/admin_role/lst',
responseHandler: function (res) {
return {
"rows": res.data,
};
},
idField: 'id',
uniqueId: 'id',
dataType: 'json',
toolbar: '#toolbar2',
showColumns: true, // 是否显示所有的列
showRefresh: true, // 是否显示刷新按钮
columns: [
{
field: 'check',
checkbox: true
},
{
field: 'name',
title: '名称'
},
{
field: 'id',
title: '角色ID'
},
// {
// field: 'auth',
// title: '权限ID'
// },
{
field: 'rank',
title: '排序',
sortable: true,
},
{
field: 'status',
title: '状态',
formatter: function (value, row, index) {
if (value == 0) {
is_checked = '';
} else if (value == 1){
is_checked = 'checked="checked"';
}
var field = "status";
result = '<label class="lyear-switch switch-primary switch-solid lyear-status"><input type="checkbox" '+ is_checked +'><span onClick="updateStatus('+ row.id +', '+ value +', \''+ field +'\')"></span></label>';
return result;
},
},
{
field: 'operate',
title: '操作',
align: 'center',
events : {
'click .role-add': function (e, value, row, index) {
iframe.createIframe('添加权限','/admin/admin_role/add?pid='+row.id);
},
'click .role-delete': function (e, value, row, index) {
$.alert({
title: '系统提示',
content: '删除提醒',
buttons: {
confirm: {
text: '确认',
btnClass: 'btn-primary',
action: function(){
$.post(url="/admin/admin_role/del",data={"id":row.id},function (res) {
if (res.status == 200) {parent.lightyear.notify('删除成功', 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');$(".tree-table").bootstrapTable('refresh');}
else parent.lightyear.notify('删除失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
});
}
},
cancel: {
text: '取消'
}
}
});
},
'click .role-edit': function (e, value, row, index) {
iframe.createIframe('修改权限','/admin/admin_role/edit?id='+row.id)
}
},
formatter: operateFormatter
}
],
treeShowField: 'name',
parentIdField: 'pid',
onResetView: function(data) {
$treeTable.treegrid({
initialState: 'collapsed', // 所有节点都折叠
treeColumn: 1,
//expanderExpandedClass: 'mdi mdi-folder-open', // 可自定义图标样式
//expanderCollapsedClass: 'mdi mdi-folder',
onChange: function() {
$treeTable.bootstrapTable('resetWidth');
}
});
// 只展开树形的第一集节点
$treeTable.treegrid('getRootNodes').treegrid('expand');
},
onCheck: function(row) {
var datas = $treeTable.bootstrapTable('getData');
selectChilds(datas, row, 'id', 'pid', true); // 选择子类
selectParentChecked(datas, row, 'id', 'pid'); // 选择父类
$treeTable.bootstrapTable('load', datas);
},
onUncheck: function(row) {
var datas = $treeTable.bootstrapTable('getData');
selectChilds(datas, row, 'id', 'pid', false);
$treeTable.bootstrapTable('load', datas);
},
});
// 操作按钮
function operateFormatter(value, row, index) {
return [
'<a type="button" class="role-add btn btn-xs btn-default m-r-5" title="编辑" data-toggle="tooltip"><i class="mdi mdi-plus"></i></a>',
'<a type="button" class="role-edit btn btn-xs btn-default m-r-5" title="修改" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>',
'<a type="button" class="role-delete btn btn-xs btn-default" title="删除" data-toggle="tooltip"><i class="mdi mdi-delete"></i></a>'
].join('');
}
/**
* 选中父项时,同时选中子项
* @param datas 所有的数据
* @param row 当前数据
* @param id id 字段名
* @param pid 父id字段名
*/
function selectChilds(datas,row,id,pid,checked) {
for(var i in datas){
if(datas[i][pid] == row[id]){
datas[i].check=checked;
selectChilds(datas,datas[i],id,pid,checked);
};
}
}
function selectParentChecked(datas,row,id,pid){
for(var i in datas){
if(datas[i][id] == row[pid]){
datas[i].check=true;
selectParentChecked(datas,datas[i],id,pid);
};
}
}
function updateStatus(id, value, field) {
var newstate = (value == 1) ? 0 : 1; // 发送参数值跟当前参数值相反
$.ajax({
type: "post",
url: "/admin/admin_role/field?id="+id,
data: {field: field, value: newstate},
dataType: 'json',
success: function (res) {
if (res.status == 200) {parent.lightyear.notify('修改成功', 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');$(".tree-table").bootstrapTable('refresh');}
else parent.lightyear.notify('修改失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
},
error: function () {
parent.lightyear.notify('修改失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
}
});
}
function test() {
var selRows = $treeTable.bootstrapTable("getSelections");
if(selRows.length == 0){
alert("请至少选择一行");
return;
}
console.log(selRows);
var postData = "";
$.each(selRows,function(i) {
postData += this.id;
if (i < selRows.length - 1) {
postData += " ";
}
});
alert("你选中行的 id 为:"+postData);
}
</script>
</body>
</html>

View File

@ -0,0 +1,333 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<title>文章管理 - {:system_config("title")}后台管理系统</title>
{include file="public/header" /}
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>搜索</h4></div>
<div class="card-body">
<form class="form-inline searchForm" onsubmit="return false;">
<div class="form-group">
<label for="name">文章标题</label>
<div class="input-group">
<div class="input-group">
<input type="text" class="form-control" id="name" name="name" placeholder="请输入文章标题">
</div>
</div>
</div>
<div class="form-group">
<label for="ip">来访IP</label>
<div class="input-group">
<div class="input-group">
<input type="text" class="form-control" id="ip" name="ip" placeholder="IP地址">
</div>
</div>
</div>
<div class="form-group">
<label for="start_time">操作时间</label>
<div class="input-group">
<input class="form-control js-datetimepicker" type="text" id="start_time" name="start_time" autocomplete="off" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="开始时间">
<span class="input-group-addon">~</span>
<input class="form-control js-datetimepicker" type="text" id="end_time" name="end_time" autocomplete="off" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="结束时间">
</div>
</div>
<button type="submit" class="btn btn-success" style="margin: -10px 0 0 10px;" id="search">搜索</button>
</form>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="card">
<div class="card-toolbar clearfix">
<div class="toolbar-btn-action">
<a class="btn btn-warning" href="#!" onclick="delSelect()"><i class="mdi mdi-window-close"></i> 删除</a>
<a class="btn btn-danger" href="#!" onclick="delAll()"><i class="mdi mdi-window-close"></i> 全部删除</a>
</div>
</div>
<div class="card-body">
<table id="tb_departments"></table>
</div>
</div>
</div>
</div>
</div>
{include file="public/footer"/}
<script type="text/javascript">
$('#tb_departments').bootstrapTable({
classes: 'table table-bordered table-hover table-striped',
url: '/admin/article/Lst',
method: 'post',
dataType : 'json', // 因为本示例中是跨域的调用,所以涉及到ajax都采用jsonp,
uniqueId: 'id',
idField: 'id', // 每行的唯一标识字段
toolbar: '#toolbar', // 工具按钮容器
showColumns: false, // 是否显示所有的列
showRefresh: false, // 是否显示刷新按钮
responseHandler: function (res) {
return {
"total": res.count,
"rows": res.data,
};
},
pagination: true,
queryParams: function(params) {
let temp = toArrayList($(".searchForm").serializeArray());
temp['limit'] = params.limit;
temp['page'] = (params.offset / params.limit) + 1;
return temp;
},
sidePagination: "server",
pageNumber: 1,
pageSize: 10,
pageList: [10, 20, 50, 100],
columns: [{
checkbox: true, // 是否显示复选框
},{
field: 'id',
title: '序号'
},{
field: 'title',
title: '标题'
}, {
field: 'category_title',
title: '分类',
}, {
field: 'display',
title: '可见性',
formatter: function (value, row, index) {
if (value == 0) {
is_checked = '';
} else if (value == 1){
is_checked = 'checked="checked"';
}
var field = "display";
result = '<label class="lyear-switch switch-primary switch-solid lyear-status"><input type="checkbox" '+ is_checked +'><span onClick="updateStatus('+ row.id +', '+ value +', \''+ field +'\')"></span></label>';
return result;
},
},{
field: 'view',
title: '浏览量',
}, {
field: 'sort',
title: '排序',
editable: {
type: 'text',
emptytext:'',
highlight: false,
mode:'inline'
}
}, {
field: 'create_time',
title: '创建时间',
}, {
field: 'create_time',
title: '更新时间',
}, {
field: 'operate',
title: '操作',
formatter:function (value,row,index) {
let html ='<a class="btn btn-xs btn-default btn-del" href="#!" title="删除" data-toggle="tooltip" onclick="delOne('+row.id+')"><i class="mdi mdi-window-close"></i></a>\n' +
'<a type="button" class="btn-edit btn btn-xs btn-default m-r-5" title="编辑" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>';
return html;
},
events : {
'click .btn-edit': function (e, value, row, index) {
var rule_name = row.rule_name.replace('{$}','xx');
var content = '<form action="" class="form-inline searchForm">' +
' <div class="form-group">';
if (row.rule_name.indexOf('{$}')>-1){
//开始替换值
//切割字符串为数组
var arr = row.rule_name.split("{$}");
for (i = 0; i < arr.length; i++) {
content+=' <span>'+arr[i]+'</span>\n';
if (i < arr.length-1){
content+= ' <input class="form-control value" type="text" name="value[]" style="width: 15%;">\n';
}
}
content += '</div>'
'</form>';
}else{
$.alert('此规则不支持修改');
return false;
}
$.confirm({
title: '修改规则',
content: content,
buttons: {
formSubmit: {
text: '确定',
btnClass: 'btn-primary',
action: function () {
var vals = this.$content.find('form').serializeArray();
var vals = $('form').serializeArray();
var data = [];
$.each(vals, function () {
if (!this.value){
$.alert('值不能为空');
return false;
}
data.push(this.value);
});
$.post(url="/admin/pushRule/update",data={"rule_value":data.toString(),"id":row.id},function (res) {
if (res.code == 200 || res.status == 200) {
parent.lightyear.notify('操作成功', 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
$("#tb_departments").bootstrapTable('refresh',{query:{page:1},pageNumber:1});
} else{
parent.lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
}
});
}
},
cancel: {
text: '取消'
},
},
onContentReady: function () {
var jc = this;
this.$content.find('form').on('submit', function (e) {
e.preventDefault();
jc.$$formSubmit.trigger('click');
});
}
});
}
}
}],
onEditableSave: function (field, row) {
$.ajax({
type: "post",
url: "/admin/article/update",
data: row,
success: function (res) {
if (res.code == 200 || res.status == 200) {
parent.lightyear.notify('操作成功', 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
} else{
parent.lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
}
},
complete: function () {
}
});
},
onLoadSuccess: function(data){
$("[data-toggle='tooltip']").tooltip();
}
});
//搜索
$("#search").click(function () {
let start_time = $('#start_time').val();
let end_time = $('#end_time').val();
if(start_time && end_time && start_time > end_time ){
alert('开始时间不能大于结束时间');
return false;
}
$("#tb_departments").bootstrapTable('refresh',{query:{page:1},pageNumber:1});
});
function updateStatus(id, value,field) {
var newstate = (value == 1) ? 0 : 1; // 发送参数值跟当前参数值相反
$.ajax({
type: "post",
url: "/admin/article/field?id="+id,
data: {field: field, value: newstate},
dataType: 'json',
success: function (res) {
if (res.status == 200) {parent.lightyear.notify('修改成功', 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');$(".tree-table").bootstrapTable('refresh');}
else parent.lightyear.notify('修改失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
},
error: function () {
parent.lightyear.notify('修改失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
}
});
}
function delOne(id) {
$.confirm({
title: '重要提醒!',
content: '删除后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/del",data={id:id},function (res) {
if (res.status == 200 || res.code == 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
location.reload();
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
function delAll() {
$.confirm({
title: '重要提醒!',
content: '清空后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/empty",data={},function (res) {
if (res.status == 200 || res.code == 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
location.reload();
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
function delSelect() {
var checkID = "";
var selectedItem = $('#tb_departments').bootstrapTable('getSelections');
if (selectedItem=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
for (var i = 0 ; i< selectedItem.length; i++)
{
checkID += selectedItem[i]['id']+",";
}
if (checkID=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.confirm({
title: '重要提醒!',
content: '选中项删除后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/del",data={id:checkID},function (res) {
if (res.status == 200 || res.code == 200) { lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');location.reload();}
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
</script>
</body>
</html>

View File

@ -0,0 +1,316 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<title>登录页面 - {:system_config("title")}后台管理系统</title>
{include file="public/header" /}
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>搜索</h4></div>
<div class="card-body">
<form class="form-inline searchForm" onsubmit="return false;">
<div class="form-group">
<label for="title">权限名称</label>
<div class="input-group">
<div class="input-group">
<input type="text" class="form-control" id="title" value="" name="title" placeholder="请输入权限名称或者ID">
</div>
</div>
</div>
<div class="form-group">
<label for="status">状态</label>
<select name="status" id="status" class="form-control">
<option value="">所有</option>
<option value="1">启用</option>
<option value="0">禁用</option>
</select>
</div>
<button type="submit" class="btn btn-success" style="margin: -10px 0 0 10px;" id="search">搜索</button>
</form>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<h4>权限管理</h4>
</div>
<div class="card-body">
<div id="toolbar2" class="toolbar-btn-action">
<button type="button" class="btn btn-primary m-r-5" onclick="iframe.createIframe('添加权限','/admin/admin_auth/add')"><span class="mdi mdi-plus" aria-hidden="true"></span>新增</button>
<button id="btn_edit" type="button" class="btn btn-success m-r-5" onclick="isEnable('enable')">
<span class="mdi mdi-check" aria-hidden="true"></span>启用
</button>
<button id="btn_disable" type="button" class="btn btn-warning m-r-5" onclick="isEnable('disable')">
<span class="mdi mdi-block-helper" aria-hidden="true"></span>禁用
</button>
<button id="btn_delete" type="button" class="btn btn-danger" onclick="del()">
<span class="mdi mdi-window-close" aria-hidden="true"></span>删除
</button>
</div>
<table class="tree-table"></table>
</div>
</div>
</div>
</div>
</div>
{include file="public/footer"/}
<!--以下是tree-grid的使用示例-->
<link href="__ADMIN_PATH__js/jquery-treegrid/jquery.treegrid.min.css" rel="stylesheet">
<script type="text/javascript" src="__ADMIN_PATH__js/jquery-treegrid/jquery.treegrid.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-table/extensions/treegrid/bootstrap-table-treegrid.min.js"></script>
<script type="text/javascript">
// tree-grid使用
var $treeTable = $('.tree-table');
$treeTable.bootstrapTable({
url: '/admin/category/lst',
method: 'post',
responseHandler: function (res) {
return {
"rows": res.data,
};
},
queryParams: function(params) {
var temp = toArrayList($(".searchForm").serializeArray());
return temp;
},
idField: 'id',
uniqueId: 'id',
dataType: 'json',
toolbar: '#toolbar2',
showColumns: true, // 是否显示所有的列
showRefresh: true, // 是否显示刷新按钮
columns: [
{
field: 'check',
checkbox: true
},
{
field: 'title',
title: '名称'
},
{
field: 'id',
title: '权限ID'
},
{
field: 'display',
title: '可见性',
formatter: function (value, row, index) {
if (value == 0) {
is_checked = '';
} else if (value == 1){
is_checked = 'checked="checked"';
}
var field = "display";
result = '<label class="lyear-switch switch-primary switch-solid lyear-status"><input type="checkbox" '+ is_checked +'><span onClick="updateStatus('+ row.id +', '+ value +', \''+ field +'\')"></span></label>';
return result;
},
},
{
field: 'sort',
title: '排序',
sortable: true,
},
{
field: 'operate',
title: '操作',
align: 'center',
events : {
'click .role-add': function (e, value, row, index) {
iframe.createIframe('添加权限','/admin/admin_auth/add?pid='+row.id);
},
'click .role-delete': function (e, value, row, index) {
$.alert({
title: '系统提示',
content: '删除提醒',
buttons: {
confirm: {
text: '确认',
btnClass: 'btn-primary',
action: function(){
$.post(url="/admin/admin_auth/del",data={"id":row.id},function (res) {
if (res.status == 200) {parent.lightyear.notify('删除成功', 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');$(".tree-table").bootstrapTable('refresh');}
else parent.lightyear.notify('删除失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
});
}
},
cancel: {
text: '取消'
}
}
});
},
'click .role-edit': function (e, value, row, index) {
iframe.createIframe('修改权限','/admin/admin_auth/edit?id='+row.id)
}
},
formatter: operateFormatter
}
],
treeShowField: 'title',
parentIdField: 'pid',
onResetView: function(data) {
$treeTable.treegrid({
initialState: 'collapsed', // 所有节点都折叠
treeColumn: 1,
onChange: function() {
$treeTable.bootstrapTable('resetWidth');
}
});
// 只展开树形的第一集节点
$treeTable.treegrid('getRootNodes').treegrid('expand');
},
onCheck: function(row) {
var datas = $treeTable.bootstrapTable('getData');
selectChilds(datas, row, 'id', 'pid', true);
selectParentChecked(datas, row, 'id', 'pid');
$treeTable.bootstrapTable('load', datas);
},
onUncheck: function(row) {
var datas = $treeTable.bootstrapTable('getData');
selectChilds(datas, row, 'id', 'pid', false);
$treeTable.bootstrapTable('load', datas);
},
});
// 操作按钮
function operateFormatter(value, row, index) {
return [
'<a type="button" class="role-add btn btn-xs btn-default m-r-5" title="编辑" data-toggle="tooltip"><i class="mdi mdi-plus"></i></a>',
'<a type="button" class="role-edit btn btn-xs btn-default m-r-5" title="修改" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>',
'<a type="button" class="role-delete btn btn-xs btn-default" title="删除" data-toggle="tooltip"><i class="mdi mdi-delete"></i></a>'
].join('');
}
/**
* 选中父项时,同时选中子项
* @param datas 所有的数据
* @param row 当前数据
* @param id id 字段名
* @param pid 父id字段名
*/
function selectChilds(datas,row,id,pid,checked) {
for(var i in datas){
if(datas[i][pid] == row[id]){
datas[i].check=checked;
selectChilds(datas,datas[i],id,pid,checked);
};
}
}
function selectParentChecked(datas,row,id,pid){
for(var i in datas){
if(datas[i][id] == row[pid]){
datas[i].check=true;
selectParentChecked(datas,datas[i],id,pid);
};
}
}
function updateStatus(id, value,field) {
var newstate = (value == 1) ? 0 : 1; // 发送参数值跟当前参数值相反
$.ajax({
type: "post",
url: "/admin/admin_auth/field?id="+id,
data: {field: field, value: newstate},
dataType: 'json',
success: function (res) {
if (res.status == 200) {parent.lightyear.notify('修改成功', 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');$(".tree-table").bootstrapTable('refresh');}
else parent.lightyear.notify('修改失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
},
error: function () {
parent.lightyear.notify('修改失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
}
});
}
// 删除
function del() {
var checkID = "";
var selectedItem = $treeTable.bootstrapTable('getSelections');
if (selectedItem=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
for (var i = 0 ; i< selectedItem.length; i++)
{
checkID += selectedItem[i]['id']+",";
}
if (checkID=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.confirm({
title: '重要提醒!',
content: '选中项将全部被删除,请谨慎操作!' ,
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_auth/del",data={id:checkID},function (res) {
if (res.status == 200){ lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');location.reload();}
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
// 批量启用或者禁用
function isEnable(type) {
var checkID = "";
var selectedItem = $treeTable.bootstrapTable('getSelections');
if (selectedItem=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
for (var i = 0 ; i< selectedItem.length; i++)
{
checkID += selectedItem[i]['id']+",";
}
if (checkID=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.confirm({
title: '重要提醒!',
content: type == 'enable' ? '选中项将全部启用,请谨慎操作!' : '选中项将全部禁用,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
if (type == 'enable')
{
$.post("/admin/admin_auth/enabled",data={id:checkID},function (res) {
if (res.status == 200) {lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');location.reload();}
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
})
}else
{
$.post("/admin/admin_auth/disabled",data={id:checkID},function (res) {
if (res.status == 200) {lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');location.reload();}
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
})
}
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
$("#search").click(function () {
$treeTable.bootstrapTable('refresh', {});
});
</script>
</body>
</html>

View File

@ -0,0 +1,268 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<title>友情链接管理 - {:system_config("title")}后台管理系统</title>
{include file="public/header" /}
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>搜索</h4></div>
<div class="card-body">
<form class="form-inline searchForm" onsubmit="return false;">
<div class="form-group">
<label for="name">操作人</label>
<div class="input-group">
<div class="input-group">
<input type="text" class="form-control" id="name" name="name" placeholder="请输入操作人名称ID">
</div>
</div>
</div>
<div class="form-group">
<label for="ip">来访IP</label>
<div class="input-group">
<div class="input-group">
<input type="text" class="form-control" id="ip" name="ip" placeholder="IP地址">
</div>
</div>
</div>
<div class="form-group">
<label for="start_time">操作时间</label>
<div class="input-group">
<input class="form-control js-datetimepicker" type="text" id="start_time" name="start_time" autocomplete="off" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="开始时间">
<span class="input-group-addon">~</span>
<input class="form-control js-datetimepicker" type="text" id="end_time" name="end_time" autocomplete="off" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="结束时间">
</div>
</div>
<button type="submit" class="btn btn-success" style="margin: -10px 0 0 10px;" id="search">搜索</button>
</form>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="card">
<div class="card-toolbar clearfix">
<div class="toolbar-btn-action">
<a class="btn btn-warning" href="#!" onclick="delSelect()"><i class="mdi mdi-window-close"></i> 删除</a>
<a class="btn btn-danger" href="#!" onclick="delAll()"><i class="mdi mdi-window-close"></i> 全部删除</a>
</div>
</div>
<div class="card-body">
<table id="tb_departments"></table>
</div>
</div>
</div>
</div>
</div>
{include file="public/footer"/}
<script type="text/javascript">
$('#tb_departments').bootstrapTable({
classes: 'table table-bordered table-hover table-striped',
url: '/admin/friendlink/Lst',
method: 'post',
dataType : 'json', // 因为本示例中是跨域的调用,所以涉及到ajax都采用jsonp,
uniqueId: 'id',
idField: 'id', // 每行的唯一标识字段
toolbar: '#toolbar', // 工具按钮容器
showColumns: false, // 是否显示所有的列
showRefresh: false, // 是否显示刷新按钮
responseHandler: function (res) {
return {
"total": res.count,
"rows": res.data,
};
},
pagination: true,
queryParams: function(params) {
let temp = toArrayList($(".searchForm").serializeArray());
temp['limit'] = params.limit;
temp['page'] = (params.offset / params.limit) + 1;
return temp;
},
sidePagination: "server",
pageNumber: 1,
pageSize: 10,
pageList: [10, 20, 50, 100],
columns: [{
checkbox: true, // 是否显示复选框
},{
field: 'id',
title: '序号'
},{
field: 'title',
title: '链接名称'
}, {
field: 'url',
title: '链接地址',
}, {
field: 'sort',
title: '排序',
editable: {
type: 'text',
emptytext:'',
highlight: false,
mode:'inline'
}
}, {
field: 'create_time',
title: '创建时间',
}, {
field: 'create_time',
title: '更新时间',
},{
field: 'status',
title: '状态',
formatter: function (value, row, index) {
if (value == 0) {
is_checked = '';
} else if (value == 1){
is_checked = 'checked="checked"';
}
var field = "status";
result = '<label class="lyear-switch switch-primary switch-solid lyear-status"><input type="checkbox" '+ is_checked +'><span onClick="updateStatus('+ row.id +', '+ value +', \''+ field +'\')"></span></label>';
return result;
},
}, {
field: 'operate',
title: '操作',
formatter:function (value,row,index) {
let html = '<a type="button" class="btn-edit btn btn-xs btn-default m-r-5" title="编辑" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a> \n' +
'<a class="btn btn-xs btn-default btn-del" href="#!" title="删除" data-toggle="tooltip" onclick="delOne('+row.id+')"><i class="mdi mdi-window-close"></i></a>';
return html;
}
}],
onEditableSave: function (field, row) {
$.ajax({
type: "post",
url: "/admin/friendlink/update",
data: row,
success: function (res) {
if (res.code == 200 || res.status == 200) {
parent.lightyear.notify('操作成功', 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
} else{
parent.lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
}
},
complete: function () {
}
});
},
onLoadSuccess: function(data){
$("[data-toggle='tooltip']").tooltip();
}
});
//搜索
$("#search").click(function () {
let start_time = $('#start_time').val();
let end_time = $('#end_time').val();
if(start_time && end_time && start_time > end_time ){
alert('开始时间不能大于结束时间');
return false;
}
$("#tb_departments").bootstrapTable('refresh',{query:{page:1},pageNumber:1});
});
function updateStatus(id, value,field) {
var newstate = (value == 1) ? 0 : 1; // 发送参数值跟当前参数值相反
$.ajax({
type: "post",
url: "/admin/friendlink/field?id="+id,
data: {field: field, value: newstate},
dataType: 'json',
success: function (res) {
if (res.status == 200) {parent.lightyear.notify('修改成功', 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');$(".tree-table").bootstrapTable('refresh');}
else parent.lightyear.notify('修改失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
},
error: function () {
parent.lightyear.notify('修改失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
}
});
}
function delOne(id) {
$.confirm({
title: '重要提醒!',
content: '删除后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/del",data={id:id},function (res) {
if (res.status == 200 || res.code == 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
location.reload();
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
function delAll() {
$.confirm({
title: '重要提醒!',
content: '清空后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/empty",data={},function (res) {
if (res.status == 200 || res.code == 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
location.reload();
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
function delSelect() {
var checkID = "";
var selectedItem = $('#tb_departments').bootstrapTable('getSelections');
if (selectedItem=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
for (var i = 0 ; i< selectedItem.length; i++)
{
checkID += selectedItem[i]['id']+",";
}
if (checkID=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.confirm({
title: '重要提醒!',
content: '选中项删除后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/del",data={id:checkID},function (res) {
if (res.status == 200 || res.code == 200) { lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');location.reload();}
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
</script>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,363 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>选择图片 - {:system_config("title")}后台管理系统</title>
<link rel="icon" href="{:system_config("favicon")}" type="image/ico">
<meta name="keywords" content="{:system_config("keywords")}">
<meta name="description" content="{:system_config("description")}">
<meta name="author" content="{:system_config("author")}">
<link rel="stylesheet" href="__ADMIN_PATH__js/bootstrap-treeview/bootstrap.min.css">
<link rel="stylesheet" href="__ADMIN_PATH__js/jconfirm/jquery-confirm.min.css">
<link rel="stylesheet" href="__ADMIN_PATH__js/bootstrap-treeview/bootstrap-treeview.min.css">
<script type="text/javascript" src="__ADMIN_PATH__js/iframe.js"></script>
<style>
.list-group-item{
border: 0px !important;
padding: 5px 10px;
}
#tree{
height: 390px;
overflow-y: scroll;
border-right: 1px solid #ccc;
margin-top: 10px;
}
#tree::-webkit-scrollbar{
width: 4px;
}
#tree::-webkit-scrollbar-thumb{
border-radius: 10px;
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
background: rgba(0,0,0,0.2);
}
#tree::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
border-radius: 0;
background: rgba(0,0,0,0.1);
}
.form-control2{
display: block;
width: 100%;
height: 28px;
padding: 2px 6px;
font-size: 12px;
line-height: 1.42857143;
color: #555;
background-color: #fff;
background-image: none;
border: 1px solid #ccc;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
}
.btn{
padding: 3px 8px;
}
.cart-item{
height: 110px;
padding: 5px;
text-align: center;
line-height: 80px;
}
.cart-item-image{
max-width: 100%;
max-height:100%;
margin: 0 auto;
}
.btn-round {
-webkit-border-radius: 1rem;
}
.btn-success {
background-color: #15c377;
border-color: #15c377;
color: #fff!important;
}
.btn-info {
background-color: #48b0f7;
border-color: #48b0f7;
color: #fff!important;
}
.btn-danger {
background-color: #f96868;
border-color: #f96868;
color: #fff!important;
}
.checkedItem{
border: 2px solid #f96868;
padding: 5px;
}
.pageination_align > li > a{
margin: 0 3px;
}
.pageination_align > .active > a, .pagination > .active > a:focus, .pagination > .active > a:hover, .pagination > .active > span, .pagination > .active > span:focus, .pagination > .active > span:hover {
background-color: #33cabb;
border-color: #33cabb;
}
.pageination_align{
margin: 19px 0 0 0;
float: right;
}
.pageination_align {
text-align: center
}
.pageination {
color: #48576a;
font-size: 12px;
display: inline-block;
user-select: none;
}
.pagination_page {
padding: 0 4px;
border: 1px solid #d1dbe5;
border-right: 0;
background: #fff;
font-size: 13px;
min-width: 28px;
height: 28px;
line-height: 28px;
cursor: pointer;
box-sizing: border-box;
text-align: center;
float: left;
}
.pagination_page_right {
border-right: 1px solid #d1dbe5;
}
.pagination_page:hover {
color: #20a0ff;
}
.disabled {
color: #e4e4e4 !important;
background-color: #fff;
cursor: not-allowed;
}
.pagination_page_active {
border-color: #20a0ff;
background-color: #20a0ff;
color: #fff !important;;
cursor: default;
}
</style>
</head>
<body>
<div class="container-fluid p-t-15" id="app">
<div class="row">
<div class="col-xs-3">
<div id="box-left">
<input type="text" class="form-control2" id="search" placeholder="一级分类名称" @change="tree()">
<div id="tree"></div>
</div>
</div>
<div class="col-xs-9">
<div class="card">
<div class="card-header">
<a class="btn btn-round btn-success" @click="events('addCategory')">添加分类</a>
<a class="btn btn-round btn-info" @click="events('editCategory')">修改分类</a>
<a class="btn btn-round btn-danger" @click="events('delCategory')">删除分类</a>
<a class="btn btn-round btn-success" @click="events('uploadImage')">上传图片</a>
<a class="btn btn-round btn-info" @click="events('moveImage')">移动图片</a>
<a class="btn btn-round btn-danger" @click="events('delImage')">删除图片</a>
<a class="btn btn-round btn-info" @click="events('choice')">确定选择</a>
</div>
<div class="card-body" style="margin-top: 20px;height: 340px;">
<div class="row">
<div v-for="(image,index) in imageList" class="col-xs-3 cart-item" :class="image.isSelect ? 'checkedItem': '' ">
<img :src="image.path" class="cart-item-image" @click="changImage(image,index)">
</div>
</div>
</div>
<div class="card-footer">
<pageination :total="model.total" :size="model.size" :page="model.page" :changge="pageFn" ></pageination>
</div>
</div>
</div>
</div>
<input id="fileUpload" type="file" name="file" style="display: none;" @change="upload" accept="image/*">
</div>
<script type="text/javascript" src="__ADMIN_PATH__js/jquery.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-notify.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/jconfirm/jquery-confirm.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/lightyear.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-treeview/bootstrap-treeview.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/vue/vue.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/vue-page/pageination.js"></script>
<script>
let id='',pid=0;
let parentinputname = '{$Request.param.fodder}';
let choices = [];
let limit = '{$Request.param.limit}';
var vm = new Vue({
el: "#app",
data() {
return {
imageList:[],
checkedImage:[],
checkedImageId:[],
model:{
total:12,
size:12,
page:1,
}
}
},
watch:{
page:function () {
this.getImageList();
},
},
mounted: function() {
this.tree();
this.getImageList();
},
methods:{
pageFn(val){
this.model.page=val;
this.getImageList(val);
},
tree: function ()
{
const that = this;
$.post(url = "/admin/images/category", data = {'title':$('#search').val()}, function (res) {
if (res.status === 200) {
$('#tree').treeview({
expandIcon: 'glyphicon glyphicon-chevron-right',
collapseIcon: 'glyphicon glyphicon-chevron-down',
selectedColor: '#ff0000',
selectedBackColor: null,
onhoverColor: null,
data: res.data,
levels:0
});
// 选中节点
$('#tree').on('nodeSelected', function (event, data) {
console.log(data);
id = data.id;
pid = data.pid;
that.getImageList();
that.checkedImageId.length = 0;
that.checkedImage.length = 0;
that.model.page = 1;
});
// 取消选中
$('#tree').on('nodeUnselected', function (event, data) {
id = '';
pid = 0;
that.getImageList();
});
}
});
},
events: function (type)
{
const that = this;
switch (type)
{
case 'addCategory':
iframe.createIframe('添加分类','/admin/images/addCategory?id='+id+'&pid='+pid,{height:'215px;'});
break;
case 'editCategory':
if (id == '') return lightyear.notify('未选择分类', 'danger', 1000, 'mdi mdi-emoticon-neutral', 'top', 'center');
iframe.createIframe('修改分类','/admin/images/editCategory?id='+id+'&pid='+pid,{height:'215px;'});
break;
case 'delCategory':
if (id == '') return lightyear.notify('未选择分类', 'danger', 1000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.get(url = "/admin/images/delCategory", data = {id:id}, function (res) {
if (res.status === 200 || res.code === 200) {
lightyear.notify(res.msg, 'success', 1000, 'mdi mdi-emoticon-happy', 'top', 'center');
return tree();
}
else return lightyear.notify(res.msg, 'danger', 1000, 'mdi mdi-emoticon-neutral', 'top', 'center');
});
break;
case 'uploadImage':
if (id == '') return lightyear.notify('请选择上传的目录', 'danger', 1000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$("#fileUpload").click();
break;
case 'moveImage':
if (this.checkedImageId.length <= 0) return lightyear.notify('未选择图片', 'danger', 1000, 'mdi mdi-emoticon-neutral', 'top', 'center');
iframe.createIframe('修改图片分类','/admin/images/editImage?id='+this.checkedImageId[this.checkedImageId.length-1],{height:'215px;'});
break;
case 'delImage':
if (this.checkedImageId.length <= 0) return lightyear.notify('未选择图片', 'danger', 1000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.get(url = "/admin/images/delImage", data = {id:this.checkedImageId[this.checkedImageId.length-1]}, function (res) {
if (res.status === 200 || res.code === 200) {
lightyear.notify(res.msg, 'success', 1000, 'mdi mdi-emoticon-happy', 'top', 'center');
that.checkedImageId.length--;
that.checkedImage.length--;
that.getImageList();
}
else return lightyear.notify(res.msg, 'danger', 1000, 'mdi mdi-emoticon-neutral', 'top', 'center');
});
break;
case 'choice':
parent.$f.changeField(parentinputname,this.checkedImage);
parent.$f.closeModal(parentinputname);
break;
}
},
upload:function ()
{
const that = this;
if (!$("#fileUpload").val()) return;
var formData = new FormData();
formData.append("file", $("#fileUpload")[0].files[0]);
formData.append("cid",id);
$.ajax({
type: "POST",
url: "/admin/files/image",
enctype: 'multipart/form-data',
data: formData,
processData: false,
contentType: false,
success: function (res) {
if (res.code == 200) that.getImageList();
}
});
},
getImageList:function (page = 1)
{
const th = this;
$.post(url="/admin/images/getImageList",data={cid:id,page:page,limit:th.model.size},function (res) {
if (res.code == 0) {
th.imageList = res.data;
th.model.total = res.count;
}
});
},
changImage: function(item,index)
{
if ($.inArray(item.path,this.checkedImage)>=0)
{
this.checkedImageId.remove(item.id)
this.checkedImage.remove(item.path);
}else
{
if (this.checkedImage.length >= limit) return lightyear.notify('不能再选了,最多只能选'+limit+'个', 'danger', 1000, 'mdi mdi-emoticon-neutral', 'top', 'center');;
this.checkedImageId.push(item.id);
this.checkedImage.push(item.path);
}
this.$set(this.imageList[index],'isSelect',item.isSelect == undefined ? true : !item.isSelect);
}
}
});
Array.prototype.remove = function(val) {
var index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
}
</script>
</body>
</html>

View File

@ -0,0 +1,260 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>首页 - {:system_config("title")}后台管理系统</title>
<link rel="icon" href="{:system_config("favicon")}" type="image/ico">
<meta name="keywords" content="{:system_config("keywords")}">
<meta name="description" content="{:system_config("description")}">
<meta name="author" content="{:system_config("author")}">
<link href="__ADMIN_PATH__css/bootstrap.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/materialdesignicons.min.css" rel="stylesheet">
<link rel="stylesheet" href="__ADMIN_PATH__js/bootstrap-multitabs/multitabs.min.css">
<link href="__ADMIN_PATH__css/animate.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/style.min.css" rel="stylesheet">
<link rel="stylesheet" href="__ADMIN_PATH__js/jconfirm/jquery-confirm.min.css">
<style>
body{
opacity: 0;
animation: page-fade-in 1s forwards;
}
@keyframes page-fade-in {
0% {
opacity: 0
}
100% {
opacity: 1
}
}
</style>
</head>
<body>
<div class="lyear-layout-web">
<div class="lyear-layout-container">
<!--左侧导航-->
<aside class="lyear-layout-sidebar">
<!-- logo -->
<div id="logo" class="sidebar-header">
<a href="/admin/index/index.html"><img src="__ADMIN_PATH__images/logo-sidebar.png" title="{:system_config("title")}后台管理系统" alt="{:system_config("title")}后台管理系统" /></a>
</div>
<div class="lyear-layout-sidebar-scroll">
<nav class="sidebar-main">
<ul class="nav nav-drawer">
{volist name="menu" id="vo"}
{if !empty($vo['children'])}
<li class="nav-item nav-item-has-subnav">
<a href="javascript:void(0)"><i class="{$vo.icon}"></i> <span>{$vo.title}</span></a>
<ul class="nav nav-subnav">
{foreach $vo['children'] as $key=>$val}
{if !empty($val['children'])}
<li class="nav-item nav-item-has-subnav">
<a href="javascript:void(0)"><i class="{$val.icon}"></i> <span>{$val.title}</span></a>
<ul class="nav nav-subnav">
{foreach $val['children'] as $key2=>$val2}
<li><a class="multitabs" href="{$val2.href}">{$val2.title}</a> </li>
{/foreach}
</ul>
</li>
{else /}
<li><a class="multitabs" href="{$val.href}{if $val.params}{$val.params}{/if}">{$val.title}</a> </li>
{/if}
{/foreach}
</ul>
</li>
{else /}
<li class="nav-item"> <a class="multitabs" href="{$vo.href}"><i class="{$vo.icon}"></i> <span>{$vo.title}</span></a> </li>
{/if}
{/volist}
</ul>
</nav>
<div class="sidebar-footer" style="text-align: center;">
<p class="copyright">{:system_config("copyright")}</p>
</div>
</div>
</aside>
<!--End 左侧导航-->
<!--头部信息-->
<header class="lyear-layout-header">
<nav class="navbar navbar-default">
<div class="topbar">
<div class="topbar-left">
<div class="lyear-aside-toggler">
<span class="lyear-toggler-bar"></span>
<span class="lyear-toggler-bar"></span>
<span class="lyear-toggler-bar"></span>
</div>
</div>
<ul class="topbar-right">
<li class="dropdown dropdown-profile">
<a href="javascript:void(0)" data-toggle="dropdown">
<img class="img-avatar img-avatar-48 m-r-10" src="{$adminInfo.avatar}" alt="{$adminInfo.nickname}" style="width: 32px;height: 32px;"/>
<span>{$adminInfo.nickname} <span class="caret"></span></span>
</a>
<ul class="dropdown-menu dropdown-menu-right">
<li> <a class="multitabs" data-url="/admin/admin/profile" href="javascript:void(0)"><i class="mdi mdi-account"></i> 个人信息</a> </li>
<li> <a class="multitabs" data-url="/admin/admin/pwd" href="javascript:void(0)"><i class="mdi mdi-lock-outline"></i> 修改密码</a> </li>
<li class="divider"></li>
<li> <a href="/admin/login/logout.html"><i class="mdi mdi-logout-variant"></i> 退出登录</a> </li>
</ul>
</li>
<!--切换主题配色-->
<li class="dropdown dropdown-skin">
<span data-toggle="dropdown" class="icon-palette"><i class="mdi mdi-palette"></i></span>
<ul class="dropdown-menu dropdown-menu-right" data-stopPropagation="true">
<li class="drop-title"><p>LOGO</p></li>
<li class="drop-skin-li clearfix">
<span class="inverse">
<input type="radio" name="logo_bg" value="default" id="logo_bg_1" checked>
<label for="logo_bg_1"></label>
</span>
<span>
<input type="radio" name="logo_bg" value="color_2" id="logo_bg_2">
<label for="logo_bg_2"></label>
</span>
<span>
<input type="radio" name="logo_bg" value="color_3" id="logo_bg_3">
<label for="logo_bg_3"></label>
</span>
<span>
<input type="radio" name="logo_bg" value="color_4" id="logo_bg_4">
<label for="logo_bg_4"></label>
</span>
<span>
<input type="radio" name="logo_bg" value="color_5" id="logo_bg_5">
<label for="logo_bg_5"></label>
</span>
<span>
<input type="radio" name="logo_bg" value="color_6" id="logo_bg_6">
<label for="logo_bg_6"></label>
</span>
<span>
<input type="radio" name="logo_bg" value="color_7" id="logo_bg_7">
<label for="logo_bg_7"></label>
</span>
<span>
<input type="radio" name="logo_bg" value="color_8" id="logo_bg_8">
<label for="logo_bg_8"></label>
</span>
</li>
<li class="drop-title"><p>头部</p></li>
<li class="drop-skin-li clearfix">
<span class="inverse">
<input type="radio" name="header_bg" value="default" id="header_bg_1" checked>
<label for="header_bg_1"></label>
</span>
<span>
<input type="radio" name="header_bg" value="color_2" id="header_bg_2">
<label for="header_bg_2"></label>
</span>
<span>
<input type="radio" name="header_bg" value="color_3" id="header_bg_3">
<label for="header_bg_3"></label>
</span>
<span>
<input type="radio" name="header_bg" value="color_4" id="header_bg_4">
<label for="header_bg_4"></label>
</span>
<span>
<input type="radio" name="header_bg" value="color_5" id="header_bg_5">
<label for="header_bg_5"></label>
</span>
<span>
<input type="radio" name="header_bg" value="color_6" id="header_bg_6">
<label for="header_bg_6"></label>
</span>
<span>
<input type="radio" name="header_bg" value="color_7" id="header_bg_7">
<label for="header_bg_7"></label>
</span>
<span>
<input type="radio" name="header_bg" value="color_8" id="header_bg_8">
<label for="header_bg_8"></label>
</span>
</li>
<li class="drop-title"><p>侧边栏</p></li>
<li class="drop-skin-li clearfix">
<span class="inverse">
<input type="radio" name="sidebar_bg" value="default" id="sidebar_bg_1" checked>
<label for="sidebar_bg_1"></label>
</span>
<span>
<input type="radio" name="sidebar_bg" value="color_2" id="sidebar_bg_2">
<label for="sidebar_bg_2"></label>
</span>
<span>
<input type="radio" name="sidebar_bg" value="color_3" id="sidebar_bg_3">
<label for="sidebar_bg_3"></label>
</span>
<span>
<input type="radio" name="sidebar_bg" value="color_4" id="sidebar_bg_4">
<label for="sidebar_bg_4"></label>
</span>
<span>
<input type="radio" name="sidebar_bg" value="color_5" id="sidebar_bg_5">
<label for="sidebar_bg_5"></label>
</span>
<span>
<input type="radio" name="sidebar_bg" value="color_6" id="sidebar_bg_6">
<label for="sidebar_bg_6"></label>
</span>
<span>
<input type="radio" name="sidebar_bg" value="color_7" id="sidebar_bg_7">
<label for="sidebar_bg_7"></label>
</span>
<span>
<input type="radio" name="sidebar_bg" value="color_8" id="sidebar_bg_8">
<label for="sidebar_bg_8"></label>
</span>
</li>
</ul>
</li>
<!--切换主题配色-->
<!--消息-->
<li class="dropdown notifications-menu">
<span class="dropdown-toggle icon-notifications" data-toggle="dropdown">
<i class="mdi mdi-bell"></i>
<span class="label label-warning">{$message.count}</span>
</span>
<ul class="dropdown-menu dropdown-menu-right">
<li class="header">您有{$message.count}个未读消息</li>
<li>
<!-- inner menu: contains the actual data -->
<ul class="menu">
{volist name="message.data" id="vo"}
<li>
<a data-url="/admin/admin_notify/index" data-title="我的消息" class="multitabs">
{if $vo.type=='timer'}<i class="mdi mdi-timer-sand-empty text-primary"></i>{elseif $vo.type=='system'/}<i class="mdi mdi-access-point text-primary"></i>{else/}<i class="mdi mdi-timer-sand text-primary"></i>{/if} {$vo.title}
</a>
</li>
{/volist}
</ul>
</li>
<li class="text-center"><a data-url="/admin/adminNotify/index" class="multitabs" style="cursor: pointer;">我的消息</a></li>
</ul>
</li>
<!--end 消息-->
</ul>
</div>
</nav>
</header>
<!--End 头部信息-->
<!--页面主要内容-->
<main class="lyear-layout-content">
<div id="iframe-content"></div>
</main>
<!--End 页面主要内容-->
</div>
</div>
<script type="text/javascript" src="__ADMIN_PATH__js/jquery.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/perfect-scrollbar.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-multitabs/multitabs.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-notify.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/jquery.cookie.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/index.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/lightyear.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/jconfirm/jquery-confirm.min.js"></script>
</body>
</html>

View File

@ -0,0 +1,251 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>首页 - {:system_config("title")}后台管理系统</title>
<link rel="icon" href="{:system_config("favicon")}" type="image/ico">
<meta name="keywords" content="{:system_config("keywords")}">
<meta name="description" content="{:system_config("description")}">
<meta name="author" content="{:system_config("author")}">
<link href="__ADMIN_PATH__css/bootstrap.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/materialdesignicons.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/style.min.css" rel="stylesheet">
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-sm-6 col-md-3">
<div class="card bg-primary">
<div class="card-body clearfix">
<div class="pull-right">
<p class="h6 text-white m-t-0">今日收入</p>
<p class="h3 text-white m-b-0">102,125.00</p>
</div>
<div class="pull-left"> <span class="img-avatar img-avatar-48 bg-translucent"><i class="mdi mdi-currency-cny fa-1-5x"></i></span> </div>
</div>
</div>
</div>
<div class="col-sm-6 col-md-3">
<div class="card bg-danger">
<div class="card-body clearfix">
<div class="pull-right">
<p class="h6 text-white m-t-0">用户总数</p>
<p class="h3 text-white m-b-0">920,000</p>
</div>
<div class="pull-left"> <span class="img-avatar img-avatar-48 bg-translucent"><i class="mdi mdi-account fa-1-5x"></i></span> </div>
</div>
</div>
</div>
<div class="col-sm-6 col-md-3">
<div class="card bg-success">
<div class="card-body clearfix">
<div class="pull-right">
<p class="h6 text-white m-t-0">下载总量</p>
<p class="h3 text-white m-b-0">34,005,000</p>
</div>
<div class="pull-left"> <span class="img-avatar img-avatar-48 bg-translucent"><i class="mdi mdi-arrow-down-bold fa-1-5x"></i></span> </div>
</div>
</div>
</div>
<div class="col-sm-6 col-md-3">
<div class="card bg-purple">
<div class="card-body clearfix">
<div class="pull-right">
<p class="h6 text-white m-t-0">新增留言</p>
<p class="h3 text-white m-b-0">153 条</p>
</div>
<div class="pull-left"> <span class="img-avatar img-avatar-48 bg-translucent"><i class="mdi mdi-comment-outline fa-1-5x"></i></span> </div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4>每周用户</h4>
</div>
<div class="card-body">
<canvas class="js-chartjs-bars"></canvas>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4>交易历史记录</h4>
</div>
<div class="card-body">
<canvas class="js-chartjs-lines"></canvas>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<h4>项目信息</h4>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>#</th>
<th>项目名称</th>
<th>开始日期</th>
<th>截止日期</th>
<th>状态</th>
<th>进度</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>111</td>
<td>2021-02-23 22:12:11</td>
<td>2021-02-23 22:12:11</td>
<td><span class="label label-danger">未开始</span></td>
<td>
<div class="progress progress-striped progress-sm">
<div class="progress-bar progress-bar-success" style="width: 100%;"></div>
</div>
</td>
</tr>
<tr>
<td>1</td>
<td>111</td>
<td>2021-02-23 22:12:11</td>
<td>2021-02-23 22:12:11</td>
<td><span class="label label-warning">进行中</span></td>
<td>
<div class="progress progress-striped progress-sm">
<div class="progress-bar progress-bar-success" style="width: 100%;"></div>
</div>
</td>
</tr>
<tr>
<td>1</td>
<td>111</td>
<td>2021-02-23 22:12:11</td>
<td>2021-02-23 22:12:11</td>
<td><span class="label label-success">已完成</span></td>
<td>
<div class="progress progress-striped progress-sm">
<div class="progress-bar progress-bar-success" style="width: 100%;"></div>
</div>
</td>
</tr>
<tr>
<td>1</td>
<td>111</td>
<td>2021-02-23 22:12:11</td>
<td>2021-02-23 22:12:11</td>
<td><span class="label label-pink">维护中</span></td>
<td>
<div class="progress progress-striped progress-sm">
<div class="progress-bar progress-bar-success" style="width: 100%;"></div>
</div>
</td>
</tr>
<tr>
<td>1</td>
<td>111</td>
<td>2021-02-23 22:12:11</td>
<td>2021-02-23 22:12:11</td>
<td><span class="label label-purple">已终止</span></td>
<td>
<div class="progress progress-striped progress-sm">
<div class="progress-bar progress-bar-success" style="width: 100%;"></div>
</div>
</td>
</tr>
<tr>
<td>1</td>
<td>111</td>
<td>2021-02-23 22:12:11</td>
<td>2021-02-23 22:12:11</td>
<td><span class="label label-danger">未开始</span></td>
<td>
<div class="progress progress-striped progress-sm">
<div class="progress-bar progress-bar-success" style="width: 100%;"></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="__ADMIN_PATH__js/jquery.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/main.min.js"></script>
<!--图表插件-->
<script type="text/javascript" src="__ADMIN_PATH__js/Chart.js"></script>
<script type="text/javascript">
$(document).ready(function(e) {
var $dashChartBarsCnt = jQuery( '.js-chartjs-bars' )[0].getContext( '2d' ),
$dashChartLinesCnt = jQuery( '.js-chartjs-lines' )[0].getContext( '2d' );
var $dashChartBarsData = {
labels: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
datasets: [
{
label: '注册用户',
borderWidth: 1,
borderColor: 'rgba(0,0,0,0)',
backgroundColor: 'rgba(51,202,185,0.5)',
hoverBackgroundColor: "rgba(51,202,185,0.7)",
hoverBorderColor: "rgba(0,0,0,0)",
data: [2500, 1500, 1200, 3200, 4800, 3500, 1500]
}
]
};
var $dashChartLinesData = {
labels: ['2003', '2004', '2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014'],
datasets: [
{
label: '交易资金',
data: [20, 25, 40, 30, 45, 40, 55, 40, 48, 40, 42, 50],
borderColor: '#358ed7',
backgroundColor: 'rgba(53, 142, 215, 0.175)',
borderWidth: 1,
fill: false,
lineTension: 0.5
}
]
};
new Chart($dashChartBarsCnt, {
type: 'bar',
data: $dashChartBarsData
});
var myLineChart = new Chart($dashChartLinesCnt, {
type: 'line',
data: $dashChartLinesData,
});
});
</script>
</body>
</html>

View File

@ -0,0 +1,207 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<title>邀请码管理 - {:system_config("title")}后台管理系统</title>
{include file="public/header" /}
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>搜索</h4></div>
<div class="card-body">
<form class="form-inline searchForm" onsubmit="return false;">
<div class="form-group">
<label for="code">邀请码</label>
<div class="input-group">
<div class="input-group">
<input type="text" class="form-control" id="code" name="code" placeholder="请输入操作人名称ID">
</div>
</div>
</div>
<div class="form-group">
<label for="start_time">操作时间</label>
<div class="input-group">
<input class="form-control js-datetimepicker" type="text" id="start_time" name="start_time" autocomplete="off" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="开始时间">
<span class="input-group-addon">~</span>
<input class="form-control js-datetimepicker" type="text" id="end_time" name="end_time" autocomplete="off" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="结束时间">
</div>
</div>
<button type="submit" class="btn btn-success" style="margin: -10px 0 0 10px;" id="search">搜索</button>
</form>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="card">
<div class="card-toolbar clearfix">
<div class="toolbar-btn-action">
<a class="btn btn-warning" href="#!" onclick="delSelect()"><i class="mdi mdi-window-close"></i> 删除</a>
<a class="btn btn-danger" href="#!" onclick="delAll()"><i class="mdi mdi-window-close"></i> 全部删除</a>
</div>
</div>
<div class="card-body">
<table id="tb_departments"></table>
</div>
</div>
</div>
</div>
</div>
{include file="public/footer"/}
<script type="text/javascript">
$('#tb_departments').bootstrapTable({
classes: 'table table-bordered table-hover table-striped',
url: '/admin/invitation/Lst',
method: 'post',
dataType : 'json', // 因为本示例中是跨域的调用,所以涉及到ajax都采用jsonp,
uniqueId: 'id',
idField: 'id', // 每行的唯一标识字段
toolbar: '#toolbar', // 工具按钮容器
showColumns: false, // 是否显示所有的列
showRefresh: false, // 是否显示刷新按钮
responseHandler: function (res) {
return {
"total": res.count,
"rows": res.data,
};
},
pagination: true,
queryParams: function(params) {
let temp = toArrayList($(".searchForm").serializeArray());
temp['limit'] = params.limit;
temp['page'] = (params.offset / params.limit) + 1;
return temp;
},
sidePagination: "server",
pageNumber: 1,
pageSize: 10,
pageList: [10, 20, 50, 100],
columns: [{
checkbox: true, // 是否显示复选框
},{
field: 'id',
title: '序号'
},{
field: 'code',
title: '邀请码'
},{
field: 'status',
title: '状态',
formatter:function (value,row,index) {
if (value){
return '已使用';
}else{
return "未使用";
}
}
},{
field: 'user',
title: '使用人',
},{
field: 'operate',
title: '操作',
formatter:function (value,row,index) {
let html ='<a class="btn btn-xs btn-default btn-del" href="#!" title="删除" data-toggle="tooltip" onclick="delOne('+row.id+')"><i class="mdi mdi-window-close"></i></a>';
return html;
}
}],
onLoadSuccess: function(data){
$("[data-toggle='tooltip']").tooltip();
}
});
//搜索
$("#search").click(function () {
let start_time = $('#start_time').val();
let end_time = $('#end_time').val();
if(start_time && end_time && start_time > end_time ){
alert('开始时间不能大于结束时间');
return false;
}
$("#tb_departments").bootstrapTable('refresh',{query:{page:1},pageNumber:1});
});
function delOne(id) {
$.confirm({
title: '重要提醒!',
content: '删除后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/del",data={id:id},function (res) {
if (res.status == 200 || res.code == 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
location.reload();
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
function delAll() {
$.confirm({
title: '重要提醒!',
content: '清空后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/empty",data={},function (res) {
if (res.status == 200 || res.code == 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
location.reload();
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
function delSelect() {
var checkID = "";
var selectedItem = $('#tb_departments').bootstrapTable('getSelections');
if (selectedItem=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
for (var i = 0 ; i< selectedItem.length; i++)
{
checkID += selectedItem[i]['id']+",";
}
if (checkID=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.confirm({
title: '重要提醒!',
content: '选中项删除后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/del",data={id:checkID},function (res) {
if (res.status == 200 || res.code == 200) { lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');location.reload();}
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
</script>
</body>
</html>

View File

@ -0,0 +1,210 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>登录页面 - {:system_config("title")}后台管理系统</title>
<link rel="icon" href="{:system_config("favicon")}" type="image/ico">
<meta name="keywords" content="{:system_config("keywords")}">
<meta name="description" content="{:system_config("description")}">
<meta name="author" content="{:system_config("author")}">
<link href="__ADMIN_PATH__css/bootstrap.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/materialdesignicons.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/style.min.css" rel="stylesheet">
<style>
.lyear-wrapper {
position: relative;
}
.lyear-login {
display: flex !important;
min-height: 100vh;
align-items: center !important;
justify-content: center !important;
}
.login-center {
background: #fff;
min-width: 29.25rem;
padding: 2.14286em 3.57143em;
border-radius: 5px;
margin: 2.85714em;
}
.login-header {
margin-bottom: 1.5rem !important;
}
.login-center .has-feedback.feedback-left .form-control {
padding-left: 38px;
padding-right: 12px;
}
.login-center .has-feedback.feedback-left .form-control-feedback {
left: 0;
right: auto;
width: 38px;
height: 38px;
line-height: 38px;
z-index: 4;
color: #dcdcdc;
}
.login-center .has-feedback.feedback-left.row .form-control-feedback {
left: 15px;
}
</style>
</head>
<body style="background: url('__ADMIN_PATH__images/back.jpg')">
<div class="row lyear-wrapper">
<div class="lyear-login">
<div class="login-center">
<div class="login-header">
<div class="row" style="line-height: 36px;">
<div class="col-xs-8 text-left">
<a href="/index" style="font-size: 20px;color: #1c1e2f;">{:system_config("title")}后台管理系统</a>
</div>
<div class="col-xs-4 text-right">
<a onclick="changeLoginType()" style="cursor: pointer;" id="loginLabel">扫码登录</a>
</div>
</div>
</div>
<div style="height: 212px;width: 100%;display: none;" id="scan">
<div style="padding: 10px;text-align: center;position: relative;">
<img src="__ADMIN_PATH__images/wechat.png" id="qrcode" width="160" height="160" alt="请打开微信扫一扫登录" title="请打开微信扫一扫登录">
<div style="position: absolute;top: 0;left: 0;width: 100%;padding: 10px;display: none;" class="lab_qrcode_text">
<p style="height: 160px;width: 160px;margin: auto;line-height: 160px;background: rgba(0, 0, 0, 0.6);color: #fff;font-size: 16px;cursor: pointer;" title="点击重新加载" onclick="openws();">二维码已过期</p>
</div>
</div>
<p style="text-align: center;margin-top: 10px;font-size: 20px;">请打开微信扫一扫登录</p>
</div>
<form action="#" method="post" style="height: 212px;width: 100%;" id="loginFrm">
<div class="form-group has-feedback feedback-left has-username" style="margin-bottom: 20px;">
<input type="text" placeholder="请输入您的用户名" class="form-control" name="username" id="username" />
<span class="mdi mdi-account form-control-feedback" aria-hidden="true"></span>
</div>
<div class="form-group has-feedback feedback-left has-password" style="margin-bottom: 20px;">
<input type="password" placeholder="请输入密码" class="form-control" id="password" name="password" />
<span class="mdi mdi-lock form-control-feedback" aria-hidden="true"></span>
</div>
<div class="form-group has-feedback feedback-left row" style="margin-bottom: 20px;">
<div class="col-xs-7 has-captchas">
<input type="text" name="captcha" id="captchas" class="form-control" placeholder="验证码">
<span class="mdi mdi-check-all form-control-feedback" aria-hidden="true"></span>
</div>
<div class="col-xs-5">
<img src="/admin/login/captcha" class="pull-right" id="captcha" style="cursor: pointer;width: 120px;height: 38px;" onclick="this.src='/admin/login/captcha?d='+Math.random();" title="点击刷新" alt="captcha">
</div>
</div>
<div class="form-group" style="margin-bottom: 20px;">
<button class="btn btn-block btn-primary" type="button" onclick="btnLogin()">立即登录</button>
</div>
</form>
<hr>
<footer class="col-sm-12 text-center">
<p class="m-b-0">{:system_config("copyright")}</p>
</footer>
</div>
</div>
</div>
<script type="text/javascript" src="__ADMIN_PATH__js/jquery.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/login.js"></script>
<script>
let scand = false;
let type = false;
let protocol = location.protocol === 'https:' ? "wss://"+window.location.host+"/wss" : "ws://"+window.location.host+":1996";
// 切换登录
function changeLoginType() {
$("#loginFrm").toggle();
$("#scan").toggle();
type = !type;
if (type) $("#loginLabel").text("账号登录");
else $("#loginLabel").text("扫码登录");
if (!scand && type){
scand = true;
openws();
}
}
/**
* 获取cookie,单个或者多个
* @param name
* @returns {any[]|any}
*/
function getCookies(name)
{
var _cookies = document.cookie.split(";");
const value = new Array();
if (!Array.isArray(name)) _name = new Array(name);
for(var i = 0; i < _cookies.length;i++)
{
var _cookie = _cookies[i].trim().split("=");
if (_name.includes(_cookie[0].trim())) value[_cookie[0].trim()] = _cookie[1].trim();
}
if (Array.isArray(name)) return value;
else return value[name];
}
let ws = new WebSocket(protocol);
// 打开 ws
function openws() {
let time = null,tryNum = 10;
if (ws.readyState == 3) ws = new WebSocket(protocol);
// 关闭遮罩
$(".lab_qrcode_text").hide();
try {
ws.send('{"type":"qrcode","token":"'+getCookies("PHPSESSID")+'"}');
} catch(err) {
// 重试10次每次之间间隔3秒
time = setTimeout(function () {
if (tryNum > 0) {
tryNum--;
if (ws.readyState == 1)
{
clearTimeout(time);
ws.send('{"type":"qrcode","token":"'+getCookies("PHPSESSID")+'"}');
}
} else {
clearTimeout(time);
scand = false;
console.error("连接超时.");
}
}, 100);
}
ws.onmessage = function(e)
{
data = JSON.parse(e.data);
event(data['type'],data['data'])
}
}
let t1;
// 事件处理
function event(type,data)
{
switch (type)
{
case 'qrcode':
t1 = setInterval(function () {
ws.send('{"type":"valid","token":"'+getCookies("PHPSESSID")+'"}');
}, 2000);
$("#qrcode").attr("src",data['src']);
break;
case 'valid':
switch (data['status'])
{
case 200:
clearInterval(t1);
window.location = "/admin/index/index";
break;
case 300:
break;
case 400:
clearInterval(t1);
scand = false;
$(".lab_qrcode_text").show();
break;
}
break;
case 'timeout':
clearInterval(t1);
scand = false;
}
}
</script>
</body>
</html>

View File

@ -0,0 +1,254 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<title>留言管理 - {:system_config("title")}后台管理系统</title>
{include file="public/header" /}
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>搜索</h4></div>
<div class="card-body">
<form class="form-inline searchForm" onsubmit="return false;">
<div class="form-group">
<label for="name">姓名</label>
<div class="input-group">
<div class="input-group">
<input type="text" class="form-control" id="name" name="name" placeholder="请输入姓名">
</div>
</div>
</div>
<div class="form-group">
<label for="email">邮箱</label>
<div class="input-group">
<div class="input-group">
<input type="text" class="form-control" id="email" name="email" placeholder="邮箱">
</div>
</div>
</div>
<div class="form-group">
<label for="tel">电话</label>
<div class="input-group">
<div class="input-group">
<input type="text" class="form-control" id="tel" name="tel" placeholder="电话号码">
</div>
</div>
</div>
<div class="form-group">
<label for="start_time">操作时间</label>
<div class="input-group">
<input class="form-control js-datetimepicker" type="text" id="start_time" name="start_time" autocomplete="off" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="开始时间">
<span class="input-group-addon">~</span>
<input class="form-control js-datetimepicker" type="text" id="end_time" name="end_time" autocomplete="off" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="结束时间">
</div>
</div>
<button type="submit" class="btn btn-success" style="margin: -10px 0 0 10px;" id="search">搜索</button>
</form>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="card">
<div class="card-toolbar clearfix">
<div class="toolbar-btn-action">
<a class="btn btn-warning" href="#!" onclick="delSelect()"><i class="mdi mdi-window-close"></i> 删除</a>
<a class="btn btn-danger" href="#!" onclick="delAll()"><i class="mdi mdi-window-close"></i> 全部删除</a>
</div>
</div>
<div class="card-body">
<table id="tb_departments"></table>
</div>
</div>
</div>
</div>
</div>
{include file="public/footer"/}
<script type="text/javascript">
$('#tb_departments').bootstrapTable({
classes: 'table table-bordered table-hover table-striped',
url: '/admin/message/Lst',
method: 'post',
dataType : 'json', // 因为本示例中是跨域的调用,所以涉及到ajax都采用jsonp,
uniqueId: 'id',
idField: 'id', // 每行的唯一标识字段
toolbar: '#toolbar', // 工具按钮容器
showColumns: false, // 是否显示所有的列
showRefresh: false, // 是否显示刷新按钮
responseHandler: function (res) {
return {
"total": res.count,
"rows": res.data,
};
},
pagination: true,
queryParams: function(params) {
let temp = toArrayList($(".searchForm").serializeArray());
temp['limit'] = params.limit;
temp['page'] = (params.offset / params.limit) + 1;
return temp;
},
sidePagination: "server",
pageNumber: 1,
pageSize: 10,
pageList: [10, 20, 50, 100],
columns: [{
checkbox: true, // 是否显示复选框
},{
field: 'id',
title: 'ID'
},{
field: 'name',
title: '姓名'
}, {
field: 'tel',
title: '电话',
}, {
field: 'email',
title: '邮箱',
},{
field: 'create_time',
title: '留言时间',
}, {
field: 'operate',
title: '操作',
formatter:function (value,row,index) {
let html = '<a href="#!" class="btn btn-xs btn-default m-r-5 btn-detail" title="详情" data-toggle="tooltip" data-trigger="hover"><i class="mdi mdi-eye-outline"></i></a> \n' +
'<a class="btn btn-xs btn-default btn-del" href="#!" title="删除" data-toggle="tooltip" onclick="delOne('+row.id+')"><i class="mdi mdi-window-close"></i></a>';
return html;
},
events: {
'click .btn-detail': function (event, value, row, index) {
//职位描述+任职要求
let content = ' <div class="p-lr-15">\n' +
' <div class="row show-grid">\n' +
' <div class="col-xs-12 col-md-4">姓名:</div>\n' +
' <div class="col-xs-12 col-md-8">'+row.name+'</div>\n' +
' </div>\n' +
' <div class="row show-grid">\n' +
' <div class="col-xs-12 col-md-4">联系方式:</div>\n' +
' <div class="col-xs-12 col-md-8">'+row.tel+'</div>\n' +
' </div>\n' +
' <div class="row show-grid">\n' +
' <div class="col-xs-12 col-md-4">邮箱:</div>\n' +
' <div class="col-xs-12 col-md-8">'+row.email+'</div>\n' +
' </div>\n' +
' <div class="row show-grid">\n' +
' <div class="col-xs-12 col-md-4">留言内容:</div>\n' +
' <div class="col-xs-12 col-md-8" style="white-space: pre-wrap;">'+row.content+'</div>\n' +
' </div>\n' +
' </div>';
$.alert({
title: '详情',
content: content,
boxWidth: '50%', //定义弹窗宽度
useBootstrap: false, //定义宽度必须设置
buttons: {
cancel: {
text: '关闭',
}
}
});
}
}
}],
onLoadSuccess: function(data){
$("[data-toggle='tooltip']").tooltip();
}
});
//搜索
$("#search").click(function () {
let start_time = $('#start_time').val();
let end_time = $('#end_time').val();
if(start_time && end_time && start_time > end_time ){
alert('开始时间不能大于结束时间');
return false;
}
$("#tb_departments").bootstrapTable('refresh',{query:{page:1},pageNumber:1});
});
function delOne(id) {
$.confirm({
title: '重要提醒!',
content: '删除后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/del",data={id:id},function (res) {
if (res.status == 200 || res.code == 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
location.reload();
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
function delAll() {
$.confirm({
title: '重要提醒!',
content: '清空后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/empty",data={},function (res) {
if (res.status == 200 || res.code == 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
location.reload();
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
function delSelect() {
var checkID = "";
var selectedItem = $('#tb_departments').bootstrapTable('getSelections');
if (selectedItem=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
for (var i = 0 ; i< selectedItem.length; i++)
{
checkID += selectedItem[i]['id']+",";
}
if (checkID=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.confirm({
title: '重要提醒!',
content: '选中项删除后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/del",data={id:checkID},function (res) {
if (res.status == 200 || res.code == 200) { lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');location.reload();}
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
</script>
</body>
</html>

View File

@ -0,0 +1,52 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>404 - {:system_config("title")}后台管理系统</title>
<link rel="icon" href="{:system_config("favicon")}" type="image/ico">
<meta name="keywords" content="{:system_config("keywords")}">
<meta name="description" content="{:system_config("description")}">
<meta name="author" content="{:system_config("author")}">
<link href="__ADMIN_PATH__css/bootstrap.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/materialdesignicons.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/style.min.css" rel="stylesheet">
<style>
body{
background-color: #fff;
}
.error-page {
height: 100%;
position: fixed;
width: 100%;
}
.error-body {
padding-top: 5%;
}
.error-body h1 {
font-size: 210px;
font-weight: 700;
text-shadow: 4px 4px 0 #f5f6fa, 6px 6px 0 #33cabb;
line-height: 210px;
color: #33cabb;
}
.error-body h4 {
margin: 30px 0px;
}
</style>
</head>
<body>
<section class="error-page">
<div class="error-box">
<div class="error-body text-center">
<h1>404</h1>
<h4>很抱歉,但是那个页面看起来已经不存在了。</h4>
<a href="/admin/index/index" class="btn btn-primary ">返回首页</a>
</div>
</div>
</section>
<script type="text/javascript" src="__ADMIN_PATH__js/jquery.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap.min.js"></script>
<script type="text/javascript">;</script>
</body>
</html>

View File

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>页面提醒 - {:system_config("title")}后台管理系统</title>
<link rel="icon" href="{:system_config("favicon")}" type="image/ico">
<meta name="keywords" content="{:system_config("keywords")}">
<meta name="description" content="{:system_config("description")}">
<meta name="author" content="{:system_config("author")}">
<link href="__ADMIN_PATH__css/bootstrap.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/materialdesignicons.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/style.min.css" rel="stylesheet">
<style>
body{
background-color: #fff;
}
.error-page {
height: 100%;
position: fixed;
width: 100%;
}
.error-body {
padding-top: 5%;
}
.error-body h1 {
font-weight: 700;
text-shadow: 1px 1px 0 #f5f6fa, 2px 2px 0 #33cabb;
line-height: 210px;
color: #33cabb;
}
.error-body h4 {
margin: 30px 0px;
}
</style>
</head>
<body>
<section class="error-page">
<div class="error-box">
<div class="error-body text-center">
<h4>{$msg}</h4>
</div>
</div>
</section>
<script type="text/javascript" src="__ADMIN_PATH__js/jquery.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap.min.js"></script>
<script type="text/javascript">;</script>
</body>
</html>

View File

@ -0,0 +1,36 @@
<script type="text/javascript" src="__ADMIN_PATH__js/jquery.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/iframe.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/perfect-scrollbar.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-table/bootstrap-table.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-table/bootstrap-table-zh-CN.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/x-editable/1.5.1/bootstrap3-editable/js/bootstrap-editable.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-table/extensions/editable/bootstrap-table-editable.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/jconfirm/jquery-confirm.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/main.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-datetimepicker/moment.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-datetimepicker/locale/zh-cn.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-notify.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/lightyear.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/layer/layer.js"></script>
<script type="text/javascript">
Array.prototype.remove = function(val) {
var index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
};
/**
* @param fields
* @returns {{}}
*/
function toArrayList(fields) {
var f = {};//声明一个对象
$.each(fields,function(index,field){
f[field.name] = field.value;
});
return f;
}
</script>

View File

@ -0,0 +1,141 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><?=$form->getTitle()?></title>
<script type="text/javascript" src="__ADMIN_PATH__js/formbuilder/jquery.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/formbuilder/vue.min.js"></script>
<link href="__ADMIN_PATH__js/formbuilder/iview.css" rel="stylesheet">
<script type="text/javascript" src="__ADMIN_PATH__js/formbuilder/iview.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/formbuilder/form-create.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/formbuilder/province_city.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/formbuilder/province_city_area.js"></script>
<style>
.ivu-modal-footer{
display: none;
}
</style>
</head>
<body>
<script>
window.$f = null;
// 回调
formCreate.formSuccess = function(res){
setTimeout(function (){
parent.location.reload();
}, 2000);
};
// 构建表单
(function () {
var create = (function() {
var e = function(l, k) {
return Object.prototype.toString.call(l) === ("[object " + k + "]")
};
var g = function(k) {
k.forEach(function(n) {
var m = n.type ? ("" + n.type).toLocaleLowerCase() : ""
, l = e(k.children, "Array") ? k.children : [];
if ((m === "cascader" || m === "tree") && n.props) {
if (n.props.data && e(n.props.data, "String") && n.props.data.indexOf("js.") === 0) {
n.props.data = window[n.props.data.substr(3)]
} else {
if (n.props.options && e(n.props.options, "String") && n.props.options.indexOf("js.") === 0) {
n.props.options = window[n.props.options.substr(3)]
}
}
}
if (l.length) {
g(l)
}
});
return k
};
var i = function(k, l, m, n) {
$.ajax({
url: k,
type: ("" + l).toLocaleUpperCase(),
dataType: "json",
headers: c,
contentType: j,
data: m,
success: function(o) {
n(1, o)
},
error: function() {
n(0, {})
}
})
};
var h = g(<?=$form->parseFormRule()?>)
, c = {}
, d = {}
, j = "<?=$form->getFormContentType()?>"
, f = "<?=$form->getAction()?>"
, a = "<?=$form->getMethod()?>"
, b = new Vue();
if (!b.$Message && b.$message) {
Vue.prototype.$Message = b.$message
}
return function(l) {
if (!l) {
l = {}
}
if (l.el) {
d.el = l.el
}
d.onSubmit = function(m) {
k.submitBtnProps({
loading: true,
disabled: true
});
i(f, a, m, function(n, o) {
if (l.callback) {
return l.callback(n, o, k)
}
k.submitBtnProps({
loading: false,
disabled: false
});
if (n && o.code === 200) {
b.$Message.success(o.msg || "表单提交成功")
formCreate.formSuccess && formCreate.formSuccess(o);
} else {
b.$Message.error(o.msg || "表单提交失败")
}
})
}
;
d.global = {
upload: {
props: {
onExceededSize: function(m) {
b.$Message.error(m.name + "超出指定大小限制")
},
onFormatError: function() {
b.$Message.error(file.name + "格式验证失败")
},
onError: function(m) {
b.$Message.error(file.name + "上传失败,(" + m + ")")
},
onSuccess: function(n, m) {
if (n.code === 200) {
m.url = n.data.filePath
} else {
b.$Message.error(n.msg)
}
}
}
}
};
var k = formCreate.create(h, d);
return k
}
}
)();
window.$f = create();
})()
</script>
</body>
</html>

View File

@ -0,0 +1,22 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<link rel="icon" href="{:system_config("favicon")}" type="image/ico">
<meta name="keywords" content="{:system_config("keywords")}">
<meta name="description" content="{:system_config("description")}">
<meta name="author" content="{:system_config("author")}">
<link href="__ADMIN_PATH__css/bootstrap.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/materialdesignicons.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/animate.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/style.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__js/bootstrap-table/bootstrap-table.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__js/x-editable/1.5.1/bootstrap3-editable/css/bootstrap-editable.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__js/jconfirm/jquery-confirm.min.css" rel="stylesheet" >
<link href="__ADMIN_PATH__js/bootstrap-datetimepicker/bootstrap-datetimepicker.min.css" rel="stylesheet">
<style>
.form-inline .form-group label{
padding: 0 10px;
}
.form-inline .form-group{
margin-bottom: 10px !important;
}
</style>

View File

@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>页面提醒 - {:system_config("title")}后台管理系统</title>
<link rel="icon" href="{:system_config("favicon")}" type="image/ico">
<meta name="keywords" content="{:system_config("keywords")}">
<meta name="description" content="{:system_config("description")}">
<meta name="author" content="{:system_config("author")}">
<link href="__ADMIN_PATH__css/bootstrap.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/materialdesignicons.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/style.min.css" rel="stylesheet">
<style>
body{
background-color: #fff;
}
.error-page {
height: 100%;
position: fixed;
width: 100%;
}
.error-body {
padding-top: 5%;
}
.error-body h1 {
font-weight: 700;
line-height: 210px;
color: #15c377;
}
.error-body h4 {
margin: 30px 0px;
}
.mdi:before, .mdi-set{
font-size: 210px;
}
</style>
</head>
<body>
<section class="error-page">
<div class="error-box">
<div class="error-body text-center">
<h1>{eq name="type" value="success"}<span class="mdi mdi-emoticon"></span>{else/}<span class="mdi mdi-emoticon-sad" style="color: #f96868"></span>{/eq}</h1>
{if $backUrl}
<h3>{$msg}</h3>
<h4>This page will be re-directed in <span id="wait" style="font-size: large;color: #f96868">3</span> seconds</h4>
{/if}
<a href="{$backUrl}" class="btn {eq name="type" value="success"}btn-success{else/}btn btn-danger{/eq}">返回页面</a>
</div>
</div>
</section>
{if $backUrl}
<script type="text/javascript">
(function () {
var wait = document.getElementById('wait');
var interval = setInterval(function () {
var time = --wait.innerHTML;
if (time <= 0) {
if(top !== self){
top.location.href = history.length < 1 ? "/" : "{$backUrl}";
}else{
location.href = history.length < 1 ? "/" : "{$backUrl}";
}
clearInterval(interval);
}
}, 1000);
})();
</script>
{/if}
<script type="text/javascript" src="__ADMIN_PATH__js/jquery.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap.min.js"></script>
<script type="text/javascript">;</script>
</body>
</html>

View File

@ -0,0 +1,209 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<title>幻灯片管理 - {:system_config("title")}后台管理系统</title>
{include file="public/header" /}
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>搜索</h4></div>
<div class="card-body">
<form class="form-inline searchForm" onsubmit="return false;">
<div class="form-group">
<label for="title">幻灯片名称</label>
<div class="input-group">
<div class="input-group">
<input type="text" class="form-control" id="title" name="title" placeholder="请输入幻灯片名称">
</div>
</div>
</div>
<div class="form-group">
<label for="start_time">操作时间</label>
<div class="input-group">
<input class="form-control js-datetimepicker" type="text" id="start_time" name="start_time" autocomplete="off" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="开始时间">
<span class="input-group-addon">~</span>
<input class="form-control js-datetimepicker" type="text" id="end_time" name="end_time" autocomplete="off" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="结束时间">
</div>
</div>
<button type="submit" class="btn btn-success" style="margin: -10px 0 0 10px;" id="search">搜索</button>
</form>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="card">
<div class="card-toolbar clearfix">
<div class="toolbar-btn-action">
<a class="btn btn-warning" href="#!" onclick="delSelect()"><i class="mdi mdi-window-close"></i> 删除</a>
<a class="btn btn-danger" href="#!" onclick="delAll()"><i class="mdi mdi-window-close"></i> 全部删除</a>
</div>
</div>
<div class="card-body">
<table id="tb_departments"></table>
</div>
</div>
</div>
</div>
</div>
{include file="public/footer"/}
<script type="text/javascript">
$('#tb_departments').bootstrapTable({
classes: 'table table-bordered table-hover table-striped',
url: '/admin/slides/Lst',
method: 'post',
dataType : 'json', // 因为本示例中是跨域的调用,所以涉及到ajax都采用jsonp,
uniqueId: 'id',
idField: 'id', // 每行的唯一标识字段
toolbar: '#toolbar', // 工具按钮容器
showColumns: false, // 是否显示所有的列
showRefresh: false, // 是否显示刷新按钮
responseHandler: function (res) {
return {
"total": res.count,
"rows": res.data,
};
},
pagination: true,
queryParams: function(params) {
let temp = toArrayList($(".searchForm").serializeArray());
temp['limit'] = params.limit;
temp['page'] = (params.offset / params.limit) + 1;
return temp;
},
sidePagination: "server",
pageNumber: 1,
pageSize: 10,
pageList: [10, 20, 50, 100],
columns: [{
checkbox: true, // 是否显示复选框
},{
field: 'id',
title: 'ID'
},{
field: 'title',
title: '幻灯片名称'
},
{
field: 'pic',
title: '幻灯片图片',
formatter:function (value,row,index) {
let html ='<img src="'+value+'" alt="" width="50px;">';
return html;
}
},
{
field: 'url',
title: '幻灯片链接地址',
}, {
field: 'create_time',
title: '添加时间',
}, {
field: 'operate',
title: '操作',
formatter:function (value,row,index) {
let html ='<a class="btn btn-xs btn-default btn-del" href="#!" title="删除" data-toggle="tooltip" onclick="delOne('+row.id+')"><i class="mdi mdi-window-close"></i></a>';
return html;
}
}],
onLoadSuccess: function(data){
$("[data-toggle='tooltip']").tooltip();
}
});
//搜索
$("#search").click(function () {
let start_time = $('#start_time').val();
let end_time = $('#end_time').val();
if(start_time && end_time && start_time > end_time ){
alert('开始时间不能大于结束时间');
return false;
}
$("#tb_departments").bootstrapTable('refresh',{query:{page:1},pageNumber:1});
});
function delOne(id) {
$.confirm({
title: '重要提醒!',
content: '删除后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/del",data={id:id},function (res) {
if (res.status == 200 || res.code == 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
location.reload();
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
function delAll() {
$.confirm({
title: '重要提醒!',
content: '清空后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/empty",data={},function (res) {
if (res.status == 200 || res.code == 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
location.reload();
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
function delSelect() {
var checkID = "";
var selectedItem = $('#tb_departments').bootstrapTable('getSelections');
if (selectedItem=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
for (var i = 0 ; i< selectedItem.length; i++)
{
checkID += selectedItem[i]['id']+",";
}
if (checkID=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.confirm({
title: '重要提醒!',
content: '选中项删除后将不可恢复,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/admin_log/del",data={id:checkID},function (res) {
if (res.status == 200 || res.code == 200) { lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');location.reload();}
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
</script>
</body>
</html>

View File

@ -0,0 +1,148 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>网站配置 - {:system_config("title")}后台管理系统</title>
<link rel="icon" href="{:system_config("favicon")}" type="image/ico">
<meta name="keywords" content="{:system_config("keywords")}">
<meta name="description" content="{:system_config("description")}">
<meta name="author" content="{:system_config("author")}">
<link href="__ADMIN_PATH__css/bootstrap.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/materialdesignicons.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/style.min.css" rel="stylesheet">
<link rel="stylesheet" href="__ADMIN_PATH__js/jconfirm/jquery-confirm.min.css">
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<ul class="nav nav-tabs page-tabs">
<li {eq name="tab_id" value="1"}class="active"{/eq}><a href="/admin/system_config/base?tab_id=1">基本</a></li>
<li {eq name="tab_id" value="2"}class="active"{/eq}><a href="/admin/system_config/base?tab_id=2">上传</a></li>
<li {eq name="tab_id" value="3"}class="active"{/eq}><a href="/admin/system_config/base?tab_id=3">短信</a></li>
<li {eq name="tab_id" value="4"}class="active"{/eq}><a href="/admin/system_config/base?tab_id=4">邮件</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active">
<form name="edit-form" id="edit-form" class="edit-form" onsubmit="return toSubmit()">
{volist name="system" id="vo"}
{switch $vo.tag_type}
{case textarea}
<div class="form-group">
<label for="{$vo.form_name}">{$vo.name}</label>
<textarea class="form-control" id="{$vo.form_name}" rows="5" name="{$vo.form_name}" placeholder="请输入{$vo.name}" >{$vo.value}</textarea>
<small class="help-block">{$vo.remark}</small>
</div>
{/case}
{case select}
{/case}
{default/}
<div class="form-group">
<label for="web_site_title">{$vo.name}</label>
{switch $vo.form_type}
{case file}
<div class="input-group">
<input type="text" class="form-control" name="{$vo.form_name}" id="{$vo.form_name}" value="{$vo.value}" />
<input type="file" id="file{$vo.form_name}" style="display: none;" onchange="upload('{$vo.form_name}')"/>
<div class="input-group-btn"><button class="btn btn-success" type="button" for-input="{$vo.form_name}" onclick="btnClick('{$vo.form_name}')">上传</button></div>
</div>
{/case}
{case radio}
<div class="controls-box">
{php}
foreach(explode("\n",$vo['param']) as $k=>$v)
{
$tmp = explode("=>",$v);
$checked = $tmp[0] == $vo["value"] ? 'checked' : '';
echo '<label class="lyear-radio radio-inline radio-primary">
<input type="radio" name="'.$vo["form_name"].'" value="'.$tmp[0].'" '.$checked.'><span>'.$tmp[1].'</span>
</label>';
}
{/php}
</div>
{/case}
{case select}
<select class="form-control" id="{$vo.form_name}" name="{$vo.form_name}" size="1">
<option value="0">请选择</option>
{php}
foreach(explode("\n",$vo['param']) as $k=>$v)
{
$tmp = explode("=>",$v);
$selected = $tmp[0] == $vo["value"] ? 'selected' : '';
echo '<option value="'.$tmp[0].'" '.$selected.'>'.$tmp[1].'</option>';
}
{/php}
</select>
{/case}
{default/}
<input class="form-control" type="{$vo.form_type}" id="web_site_title" name="{$vo.form_name}" value="{$vo.value}" placeholder="请输入{$vo.name}" >
{/switch}
<small class="help-block" style="color: #da6565;">{$vo.remark}</small>
</div>
{/switch}
{/volist}
<div class="form-group">
<button type="submit" class="btn btn-primary m-r-5">确 定</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="__ADMIN_PATH__js/jquery.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/main.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-notify.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/lightyear.js"></script>
<script src="__ADMIN_PATH__js/jconfirm/jquery-confirm.min.js"></script>
<script>
/**
* 选择文件
* @param inputName
*/
function btnClick(inputName) {
$("#file"+inputName).click()
}
/**
* 异步上传
* @param inputName
*/
function upload(inputName) {
var formData = new FormData();
formData.append("file",$("#file"+inputName)[0].files[0]);
formData.append("cid",0);
formData.append("storage",1);
$.ajax({
type:'POST',
url:'/admin/files/file',
data: formData,
cache: false,
processData: false,
contentType: false,
success: function (res) {
$("#"+inputName).val(res.data.filePath);
}
});
}
/**
* 提交表单
*/
function toSubmit(){
$.post(
url = '/admin/system_config/ajaxSave',
data = $("#edit-form").serializeArray(),
function (res) {
//if (!Array.isArray(res)) res = jQuery.parseJSON(res);
if (res.status === 200 || res.code === 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
}
);
return false;
}
</script>
</body>
</html>

View File

@ -0,0 +1,78 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>缓存清理 - {:system_config("title")}后台管理系统</title>
<link rel="icon" href="{:system_config("favicon")}" type="image/ico">
<meta name="keywords" content="{:system_config("keywords")}">
<meta name="description" content="{:system_config("description")}">
<meta name="author" content="{:system_config("author")}">
<link href="__ADMIN_PATH__css/bootstrap.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/materialdesignicons.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/style.min.css" rel="stylesheet">
<link rel="stylesheet" href="__ADMIN_PATH__js/jconfirm/jquery-confirm.min.css">
<style>
body{
background-color: #fff;
}
.error-page {
height: 100%;
position: fixed;
width: 100%;
}
.error-body {
padding-top: 5%;
}
.error-body h1 {
font-weight: 700;
text-shadow: 1px 1px 0 #f5f6fa, 2px 2px 0 #33cabb;
line-height: 210px;
color: #33cabb;
}
.error-body h4 {
margin: 30px 0px;
}
</style>
</head>
<body>
<section class="error-page">
<div class="error-box">
<div class="error-body text-center">
<h1>缓存清理</h1>
<a class="btn btn-primary" href="javascript:void(0)" onclick="clearCache()"><i class="mdi mdi-delete"></i> 清空缓存</a></li>
</div>
</div>
</section>
<script type="text/javascript" src="__ADMIN_PATH__js/jquery.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap.min.js"></script>
<!--消息提示-->
<script src="__ADMIN_PATH__js/bootstrap-notify.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/lightyear.js"></script>
<script src="__ADMIN_PATH__js/jconfirm/jquery-confirm.min.js"></script>
<script>
function clearCache() {
$.alert({
title: '系统提示',
content: '即将进行清理缓存操作',
buttons: {
confirm: {
text: '确认',
btnClass: 'btn-primary',
action: function(){
$.post(url="/admin/system_config/clearCache",[],function (res) {
//if (!Array.isArray(res)) res = jQuery.parseJSON(res);
if (res.status === 200 || res.code === 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
});
}
},
cancel: {
text: '取消'
}
}
});
}
</script>
</body>
</html>

View File

@ -0,0 +1,236 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<title>表单配置 - {:system_config("title")}后台管理系统</title>
{include file="public/header" /}
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>{$tab.name}</h4></div>
<div class="card-body">
<div id="toolbar" class="toolbar-btn-action">
<button id="btn_add" type="button" class="btn btn-primary m-r-5" onclick="iframe.createIframe('{$tab.name}-添加字段','/admin/system_config/add?tab_id={$tab.id}')">
<span class="mdi mdi-plus" aria-hidden="true"></span>新增
</button>
<button id="btn_edit" type="button" class="btn btn-success m-r-5" onclick="isEnable('enable')">
<span class="mdi mdi-check" aria-hidden="true"></span>启用
</button>
<button id="btn_disable" type="button" class="btn btn-warning m-r-5" onclick="isEnable('disable')">
<span class="mdi mdi-block-helper" aria-hidden="true"></span>禁用
</button>
<button id="btn_delete" type="button" class="btn btn-danger" onclick="del()">
<span class="mdi mdi-window-close" aria-hidden="true"></span>删除
</button>
</div>
<table id="tb_departments"></table>
</div>
</div>
</div>
</div>
</div>
{include file="public/footer"/}
<script type="text/javascript">
$('#tb_departments').bootstrapTable({
classes: 'table table-bordered table-hover table-striped',
url: '/admin/system_config/lst?tab_id={$tab.id}',
method: 'post',
dataType : 'json', // 因为本示例中是跨域的调用,所以涉及到ajax都采用jsonp,
uniqueId: 'id',
idField: 'id', // 每行的唯一标识字段
toolbar: '#toolbar', // 工具按钮容器
//clickToSelect: true, // 是否启用点击选中行
showColumns: true, // 是否显示所有的列
showRefresh: true, // 是否显示刷新按钮
responseHandler: function (res) {
return {
"total": res.count,
"rows": res.data,
};
},
//showToggle: true, // 是否显示详细视图和列表视图的切换按钮(clickToSelect同时设置为true时点击会报错)
pagination: true, // 是否显示分页
sortOrder: "asc", // 排序方式
queryParams: function(params) {
var temp = {
limit: params.limit, // 每页数据量
offset: params.offset, // sql语句起始索引
page: (params.offset / params.limit) + 1,
sort: params.sort, // 排序的列名
sortOrder: params.order // 排序方式'asc' 'desc'
};
return temp;
}, // 传递参数
sidePagination: "server", // 分页方式client客户端分页server服务端分页
pageNumber: 1, // 初始化加载第一页,默认第一页
pageSize: 20, // 每页的记录行数
pageList: [20, 50, 100], // 可供选择的每页的行数
columns: [{
checkbox: true // 是否显示复选框
}, {
field: 'id',
title: 'ID',
sortable: true // 是否排序
}, {
field: 'name',
title: '标题名称'
}, {
field: 'tag_type',
title: '标签类型'
},{
field: 'form_type',
title: '表单类型'
},{
field: 'form_name',
title: '表单名称'
}, {
field: 'param',
title: '参数'
}, {
field: 'value',
title: '内容'
}, {
field: 'remark',
title: '备注'
}, {
field: 'upload_type',
title: '上传配置'
},{
field: 'rank',
title: '排序'
},{
field: 'status',
title: '状态',
formatter:function (value,row,index) {
switch (value) {
case 0:
return '禁用';
case 1:
return '启用';
}
},
}, {
field: 'operate',
title: '操作',
formatter: btnGroup, // 自定义方法
events: {
'click .edit-btn': function (event, value, row, index) {
iframe.createIframe('{$tab.name}-修改字段','/admin/system_config/edit?id='+row.id)
},
'click .del-btn': function (event, value, row, index) {
$.alert({
title: '系统提示',
content: '删除提醒',
buttons: {
confirm: {
text: '确认',
btnClass: 'btn-primary',
action: function(){
$.post(url="/admin/system_config/del",data={"id":row.id},function (res) {
if (res.status == 200) {parent.lightyear.notify('删除成功', 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');$("#tb_departments").bootstrapTable('refresh');}
else parent.lightyear.notify('删除失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
});
}
},
cancel: {
text: '取消'
}
}
});
}
}
}],
});
// 操作按钮
function btnGroup ()
{
let html =
'<a href="#!" class="btn btn-xs btn-default m-r-5 edit-btn" title="编辑" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>' +
'<a href="#!" class="btn btn-xs btn-default m-r-5 del-btn" title="删除" data-toggle="tooltip"><i class="mdi mdi-window-close"></i></a>';
return html;
}
// 删除
function del() {
var checkID = "";
var selectedItem = $('#tb_departments').bootstrapTable('getAllSelections');
if (selectedItem=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
for (var i = 0 ; i< selectedItem.length; i++)
{
checkID += selectedItem[i]['id']+",";
}
if (checkID=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.confirm({
title: '重要提醒!',
content: '选中项将全部被删除,请谨慎操作!' ,
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/system_config/del",data={id:checkID},function (res) {
if (res.status == 200){ lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');location.reload();}
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
// 批量启用或者禁用
function isEnable(type) {
var checkID = "";
var selectedItem = $('#tb_departments').bootstrapTable('getAllSelections');
if (selectedItem=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
for (var i = 0 ; i< selectedItem.length; i++)
{
checkID += selectedItem[i]['id']+",";
}
if (checkID=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.confirm({
title: '重要提醒!',
content: type == 'enable' ? '选中项将全部启用,请谨慎操作!' : '选中项将全部禁用,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
if (type == 'enable')
{
$.post("/admin/system_config/enabled",data={id:checkID},function (res) {
if (res.status == 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
location.reload();
})
}else
{
$.post("/admin/system_config/disabled",data={id:checkID},function (res) {
if (res.status == 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
location.reload();
})
}
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
</script>
</body>
</html>

View File

@ -0,0 +1,132 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>网站配置 - {:system_config("title")}后台管理系统</title>
<link rel="icon" href="{:system_config("favicon")}" type="image/ico">
<meta name="keywords" content="{:system_config("keywords")}">
<meta name="description" content="{:system_config("description")}">
<meta name="author" content="{:system_config("author")}">
<link href="__ADMIN_PATH__css/bootstrap.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/materialdesignicons.min.css" rel="stylesheet">
<link href="__ADMIN_PATH__css/style.min.css" rel="stylesheet">
<link rel="stylesheet" href="__ADMIN_PATH__js/jconfirm/jquery-confirm.min.css">
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<ul class="nav nav-tabs page-tabs">
<li {eq name="tab_id" value="38"}class="active"{/eq}><a href="/admin/system_config/base?tab_id=38">公众号</a></li>
<li {eq name="tab_id" value="39"}class="active"{/eq}><a href="/admin/system_config/base?tab_id=39">支付宝</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active">
<form name="edit-form" id="edit-form" class="edit-form" onsubmit="return toSubmit()">
{volist name="system" id="vo"}
{switch $vo.tag_type}
{case textarea}
<div class="form-group">
<label for="{$vo.form_name}">{$vo.name}</label>
<textarea class="form-control" id="{$vo.form_name}" rows="5" name="{$vo.form_name}" placeholder="请输入{$vo.name}" >{$vo.value}</textarea>
<small class="help-block">{$vo.remark}</small>
</div>
{/case}
{case select}
{/case}
{default/}
<div class="form-group">
<label for="web_site_title">{$vo.name}</label>
{switch $vo.form_type}
{case file}
<div class="input-group">
<input type="text" class="form-control" name="{$vo.form_name}" id="{$vo.form_name}" value="{$vo.value}" />
<input type="file" id="file{$vo.form_name}" style="display: none;" onchange="upload('{$vo.form_name}')"/>
<div class="input-group-btn"><button class="btn btn-success" type="button" for-input="{$vo.form_name}" onclick="btnClick('{$vo.form_name}')">上传</button></div>
</div>
{/case}
{case radio}
<div class="controls-box">
{php}
foreach(explode("\n",$vo['param']) as $k=>$v)
{
$tmp = explode("=>",$v);
$checked = $tmp[0] == $vo["value"] ? 'checked' : '';
echo '<label class="lyear-radio radio-inline radio-primary">
<input type="radio" name="'.$vo["form_name"].'" value="'.$tmp[0].'" '.$checked.'><span>'.$tmp[1].'</span>
</label>';
}
{/php}
</div>
{/case}
{default/}
<input class="form-control" type="{$vo.form_type}" id="web_site_title" name="{$vo.form_name}" value="{$vo.value}" placeholder="请输入{$vo.name}" >
{/switch}
<small class="help-block" style="color: #da6565;">{$vo.remark}</small>
</div>
{/switch}
{/volist}
<div class="form-group">
<button type="submit" class="btn btn-primary m-r-5">确 定</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="__ADMIN_PATH__js/jquery.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/main.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/bootstrap-notify.min.js"></script>
<script type="text/javascript" src="__ADMIN_PATH__js/lightyear.js"></script>
<script src="__ADMIN_PATH__js/jconfirm/jquery-confirm.min.js"></script>
<script>
/**
* 选择文件
* @param inputName
*/
function btnClick(inputName) {
$("#file"+inputName).click()
}
/**
* 异步上传
* @param inputName
*/
function upload(inputName) {
var formData = new FormData();
formData.append("file",$("#file"+inputName)[0].files[0]);
formData.append("cid",0);
$.ajax({
type:'POST',
url:'/admin/files/cert',
data: formData,
cache: false,
processData: false,
contentType: false,
success: function (res) {
$("#"+inputName).val(res.data.filePath);
}
});
}
/**
* 提交表单
*/
function toSubmit(){
$.post(
url = '/admin/system_config/ajaxSave',
data = $("#edit-form").serializeArray(),
function (res) {
//if (!Array.isArray(res)) res = jQuery.parseJSON(res);
if (res.status === 200 || res.code === 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
}
);
return false;
}
</script>
</body>
</html>

View File

@ -0,0 +1,239 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<title>开发者配置 - {:system_config("title")}后台管理系统</title>
{include file="public/header" /}
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>搜索</h4></div>
<div class="card-body">
<form class="form-inline searchForm" onsubmit="return false;">
<div class="form-group">
<label for="name">配置项名称</label>
<div class="input-group">
<div class="input-group">
<input type="text" class="form-control" id="name" value="" name="name" placeholder="请输入名称或者ID">
</div>
</div>
</div>
<div class="form-group">
<label for="status">是否启用</label>
<select name="status" id="status" class="form-control">
<option value="">所有</option>
<option value="1">启用</option>
<option value="0">禁用</option>
</select>
</div>
<button type="submit" class="btn btn-success" style="margin: -10px 0 0 10px;" id="search">搜索</button>
</form>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>开发者配置</h4></div>
<div class="card-body">
<div id="toolbar" class="toolbar-btn-action">
<button id="btn_add" type="button" class="btn btn-primary m-r-5" onclick="iframe.createIframe('添加配置','/admin/system_config_tab/add')">
<span class="mdi mdi-plus" aria-hidden="true"></span>新增
</button>
<button id="btn_edit" type="button" class="btn btn-success m-r-5" onclick="isEnable('enable')">
<span class="mdi mdi-check" aria-hidden="true"></span>启用
</button>
<button id="btn_disable" type="button" class="btn btn-warning m-r-5" onclick="isEnable('disable')">
<span class="mdi mdi-block-helper" aria-hidden="true"></span>禁用
</button>
<button id="btn_delete" type="button" class="btn btn-danger" onclick="del()">
<span class="mdi mdi-window-close" aria-hidden="true"></span>删除
</button>
</div>
<table id="tb_departments"></table>
</div>
</div>
</div>
</div>
</div>
{include file="public/footer"/}
<script type="text/javascript">
$('#tb_departments').bootstrapTable({
classes: 'table table-bordered table-hover table-striped',
url: '/admin/system_config_tab/lst',
method: 'post',
dataType : 'json', // 因为本示例中是跨域的调用,所以涉及到ajax都采用jsonp,
uniqueId: 'id',
idField: 'id', // 每行的唯一标识字段
toolbar: '#toolbar', // 工具按钮容器
showColumns: true, // 是否显示所有的列
showRefresh: true, // 是否显示刷新按钮
responseHandler: function (res) {
return {
"total": res.count,
"rows": res.data,
};
},
pagination: true, // 是否显示分页
queryParams: function(params) {
var temp = toArrayList($(".searchForm").serializeArray());
temp['limit'] = params.limit;
temp['page'] = (params.offset / params.limit) + 1;
return temp;
}, // 传递参数
sidePagination: "server", // 分页方式client客户端分页server服务端分页
pageNumber: 1, // 初始化加载第一页,默认第一页
pageSize: 20, // 每页的记录行数
pageList: [20, 50, 100], // 可供选择的每页的行数
columns: [{
checkbox: true // 是否显示复选框
}, {
field: 'id',
title: '配置ID',
sortable: true // 是否排序
}, {
field: 'name',
title: '配置名称'
},{
field: 'rank',
title: '排序'
}, {
field: 'status',
title: '状态',
formatter:function (value,row,index) {
switch (value) {
case 0:
return '禁用';
case 1:
return '启用';
}
},
}, {
field: 'operate',
title: '操作',
formatter: btnGroup, // 自定义方法
events: {
'click .edit-btn': function (event, value, row, index) {
iframe.createIframe('修改配置','/admin/system_config_tab/edit?id='+row.id)
},
'click .add-btn': function (event, value, row, index) {
window.location.href = "/admin/system_config/index?tab_id="+row.id;
},
'click .del-btn': function (event, value, row, index) {
$.alert({
title: '系统提示',
content: '删除提醒',
buttons: {
confirm: {
text: '确认',
btnClass: 'btn-primary',
action: function(){
$.post(url="/admin/system_config_tab/del",data={"id":row.id},function (res) {
if (res.status == 200) {parent.lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');$("#tb_departments").bootstrapTable('refresh');}
else parent.lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
});
}
},
cancel: {
text: '取消'
}
}
});
}
}
}],
});
$("#search").click(function () {
$("#tb_departments").bootstrapTable('refresh',{query:{page:1},pageNumber:1});
});
// 操作按钮
function btnGroup ()
{
let html =
'<a href="#!" class="btn btn-xs btn-default m-r-5 edit-btn" title="编辑" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>' +
'<a href="#!" class="btn btn-xs btn-default m-r-5 del-btn" title="删除" data-toggle="tooltip"><i class="mdi mdi-window-close"></i></a>' +
'<a href="#!" class="btn btn-xs btn-default add-btn" title="添加" data-toggle="tooltip"><i class="mdi mdi-plus"></i></a>';
return html;
}
// 删除
function del() {
var checkID = "";
var selectedItem = $('#tb_departments').bootstrapTable('getAllSelections');
if (selectedItem=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
for (var i = 0 ; i< selectedItem.length; i++)
{
checkID += selectedItem[i]['id']+",";
}
if (checkID=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.confirm({
title: '重要提醒!',
content: '选中项将全部被删除,请谨慎操作!' ,
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
$.post("/admin/system_config_tab/del",data={id:checkID},function (res) {
if (res.status == 200){ lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');location.reload();}
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
})
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
// 批量启用或者禁用
function isEnable(type) {
var checkID = "";
var selectedItem = $('#tb_departments').bootstrapTable('getAllSelections');
if (selectedItem=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
for (var i = 0 ; i< selectedItem.length; i++)
{
checkID += selectedItem[i]['id']+",";
}
if (checkID=="") return lightyear.notify("没有选中项", 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
$.confirm({
title: '重要提醒!',
content: type == 'enable' ? '选中项将全部启用,请谨慎操作!' : '选中项将全部禁用,请谨慎操作!',
backgroundDismiss: true,
buttons: {
ok: {
text: '确认',
btnClass: 'btn-danger',
action: function () {
if (type == 'enable')
{
$.post("/admin/system_config_tab/enabled",data={id:checkID},function (res) {
if (res.status == 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
location.reload();
})
}else
{
$.post("/admin/system_config_tab/disabled",data={id:checkID},function (res) {
if (res.status == 200) lightyear.notify(res.msg, 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
else lightyear.notify(res.msg, 'danger', 3000, 'mdi mdi-emoticon-neutral', 'top', 'center');
location.reload();
})
}
}
},
cancel: {
text: '取消',
btnClass: 'btn-primary'
}
}
});
}
</script>
</body>
</html>

View File

@ -0,0 +1,203 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<title>登录页面 - {:system_config("title")}后台管理系统</title>
{include file="public/header" /}
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>搜索</h4></div>
<div class="card-body">
<form class="form-inline searchForm" onsubmit="return false;">
<div class="form-group">
<label for="add_time">留言时间</label>
<div class="input-group">
<input class="form-control js-datetimepicker" type="text" id="add_time" name="add_time" value="" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="开始时间">
<span class="input-group-addon">~</span>
<input class="form-control js-datetimepicker" type="text" name="add_time" value="" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="结束时间">
</div>
</div>
<div class="form-group">
<label for="type">来源</label>
<select name="type" id="type" class="form-control">
<option value="">所有</option>
<option value="1">CMS留言</option>
</select>
</div>
<div class="form-group">
<label for="is_read">是否已读</label>
<select name="is_read" class="form-control" id="is_read">
<option value="">全部</option>
<option value="0">未读</option>
<option value="1">已读</option>
</select>
</div>
<button type="submit" class="btn btn-success" style="margin: -10px 0 0 10px;" id="search">搜索</button>
</form>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>用户留言</h4></div>
<div class="card-body">
<div id="toolbar" class="toolbar-btn-action">
<button id="btn_delete" type="button" class="btn btn-danger">
<span class="mdi mdi-window-close" aria-hidden="true"></span>删除
</button>
</div>
<table id="tb_departments"></table>
</div>
</div>
</div>
</div>
</div>
{include file="public/footer" /}
<script type="text/javascript">
$('#tb_departments').bootstrapTable({
classes: 'table table-bordered table-hover table-striped',
url: '/admin/user/lst',
method: 'post',
dataType : 'json', // 因为本示例中是跨域的调用,所以涉及到ajax都采用jsonp,
uniqueId: 'id',
idField: 'id', // 每行的唯一标识字段
toolbar: '#toolbar', // 工具按钮容器
showColumns: true, // 是否显示所有的列
showRefresh: true, // 是否显示刷新按钮
responseHandler: function (res) {
return {
"total": res.count,
"rows": res.data,
};
},
pagination: true, // 是否显示分页
sortOrder: "asc", // 排序方式
queryParams: function(params) {
var add_time = new Array();
$("input[name='add_time']").each(function(){
add_time.push($(this).val());
});
var temp = {
is_read: $('#is_read option:selected').val(),
type: $('#type option:selected').val(),
add_time: add_time,
limit: params.limit, // 每页数据量
page: (params.offset / params.limit) + 1,
};
return temp;
}, // 传递参数
sidePagination: "server", // 分页方式client客户端分页server服务端分页
pageNumber: 1, // 初始化加载第一页,默认第一页
pageSize: 10, // 每页的记录行数
pageList: [20, 50, 100], // 可供选择的每页的行数
columns: [{
checkbox: true // 是否显示复选框
}, {
field: 'id',
title: '留言ID',
}, {
field: 'name',
title: '用户昵称'
}, {
field: 'tel',
title: '电话'
}, {
field: 'email',
title: '邮箱'
}, {
field: 'type',
title: '留言来源'
}, {
field: 'content',
title: '内容',
}, {
field: 'ip',
title: 'ip',
}, {
field: 'user_agent',
title: 'UserAgent',
}, {
field: 'add_time',
title: '创建时间',
}, {
field: 'is_read',
title: '是否已读',
formatter: function (value, row, index) {
if (value == 0) {
is_checked = '';
} else if (value == 1){
is_checked = 'checked="checked"';
}
var field = "is_read";
result = '<label class="lyear-switch switch-primary switch-solid lyear-status"><input type="checkbox" '+ is_checked +'><span onClick="updateStatus('+ row.id +', '+ value +', \''+ field +'\')"></span></label>';
return result;
},
}, {
field: 'operate',
title: '操作',
formatter: btnGroup, // 自定义方法
events: {
'click .edit-btn': function (event, value, row, index) {
iframe.createIframe('修改','/admin/user/edit?id='+row.id)
},
'click .del-btn': function (event, value, row, index) {
$.alert({
title: '系统提示',
content: '删除提醒',
buttons: {
confirm: {
text: '确认',
btnClass: 'btn-primary',
action: function(){
$.post(url="/admin/user/del",data={"id":row.id},function (res) {
if (res.status == 200) {parent.lightyear.notify('删除成功', 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');$("#tb_departments").bootstrapTable('refresh');}
else parent.lightyear.notify('删除失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
});
}
},
cancel: {
text: '取消'
}
}
});
}
}
}],
onLoadSuccess: function(data){
$("[data-toggle='tooltip']").tooltip();
}
});
// 操作按钮
function btnGroup ()
{
let html =
'<a href="#!" class="btn btn-xs btn-default del-btn" title="删除" data-toggle="tooltip"><i class="mdi mdi-window-close"></i></a>';
return html;
}
$("#search").click(function () {
$("#tb_departments").bootstrapTable('refresh',{query:{page:1},pageNumber:1});
});
function updateStatus(id, value, field) {
var newstate = (value == 1) ? 0 : 1; // 发送参数值跟当前参数值相反
$.ajax({
type: "post",
url: "/admin/user/field?id="+id,
data: {field: field, value: newstate},
dataType: 'json',
success: function (res) {
if (res.status == 200) {parent.lightyear.notify('修改成功', 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');$(".tree-table").bootstrapTable('refresh');}
else parent.lightyear.notify('修改失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
},
error: function () {
parent.lightyear.notify('修改失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
}
});
}
</script>
</body>
</html>

View File

@ -0,0 +1,203 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<title>登录页面 - {:system_config("title")}后台管理系统</title>
{include file="public/header" /}
</head>
<body>
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>搜索</h4></div>
<div class="card-body">
<form class="form-inline searchForm" onsubmit="return false;">
<div class="form-group">
<label for="add_time">留言时间</label>
<div class="input-group">
<input class="form-control js-datetimepicker" type="text" id="add_time" name="add_time" value="" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="开始时间">
<span class="input-group-addon">~</span>
<input class="form-control js-datetimepicker" type="text" name="add_time" value="" data-side-by-side="true" data-locale="zh-cn" data-format="YYYY-MM-DD" placeholder="结束时间">
</div>
</div>
<div class="form-group">
<label for="type">来源</label>
<select name="type" id="type" class="form-control">
<option value="">所有</option>
<option value="1">CMS留言</option>
</select>
</div>
<div class="form-group">
<label for="is_read">是否已读</label>
<select name="is_read" class="form-control" id="is_read">
<option value="">全部</option>
<option value="0">未读</option>
<option value="1">已读</option>
</select>
</div>
<button type="submit" class="btn btn-success" style="margin: -10px 0 0 10px;" id="search">搜索</button>
</form>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>用户留言</h4></div>
<div class="card-body">
<div id="toolbar" class="toolbar-btn-action">
<button id="btn_delete" type="button" class="btn btn-danger">
<span class="mdi mdi-window-close" aria-hidden="true"></span>删除
</button>
</div>
<table id="tb_departments"></table>
</div>
</div>
</div>
</div>
</div>
{include file="public/footer" /}
<script type="text/javascript">
$('#tb_departments').bootstrapTable({
classes: 'table table-bordered table-hover table-striped',
url: '/admin/user_message/lst',
method: 'post',
dataType : 'json', // 因为本示例中是跨域的调用,所以涉及到ajax都采用jsonp,
uniqueId: 'id',
idField: 'id', // 每行的唯一标识字段
toolbar: '#toolbar', // 工具按钮容器
showColumns: true, // 是否显示所有的列
showRefresh: true, // 是否显示刷新按钮
responseHandler: function (res) {
return {
"total": res.count,
"rows": res.data,
};
},
pagination: true, // 是否显示分页
sortOrder: "asc", // 排序方式
queryParams: function(params) {
var add_time = new Array();
$("input[name='add_time']").each(function(){
add_time.push($(this).val());
});
var temp = {
is_read: $('#is_read option:selected').val(),
type: $('#type option:selected').val(),
add_time: add_time,
limit: params.limit, // 每页数据量
page: (params.offset / params.limit) + 1,
};
return temp;
}, // 传递参数
sidePagination: "server", // 分页方式client客户端分页server服务端分页
pageNumber: 1, // 初始化加载第一页,默认第一页
pageSize: 10, // 每页的记录行数
pageList: [20, 50, 100], // 可供选择的每页的行数
columns: [{
checkbox: true // 是否显示复选框
}, {
field: 'id',
title: '留言ID',
}, {
field: 'name',
title: '用户昵称'
}, {
field: 'tel',
title: '电话'
}, {
field: 'email',
title: '邮箱'
}, {
field: 'type',
title: '留言来源'
}, {
field: 'content',
title: '内容',
}, {
field: 'ip',
title: 'ip',
}, {
field: 'user_agent',
title: 'UserAgent',
}, {
field: 'add_time',
title: '创建时间',
}, {
field: 'is_read',
title: '是否已读',
formatter: function (value, row, index) {
if (value == 0) {
is_checked = '';
} else if (value == 1){
is_checked = 'checked="checked"';
}
var field = "is_read";
result = '<label class="lyear-switch switch-primary switch-solid lyear-status"><input type="checkbox" '+ is_checked +'><span onClick="updateStatus('+ row.id +', '+ value +', \''+ field +'\')"></span></label>';
return result;
},
}, {
field: 'operate',
title: '操作',
formatter: btnGroup, // 自定义方法
events: {
'click .edit-btn': function (event, value, row, index) {
iframe.createIframe('修改','/admin/user_message/edit?id='+row.id)
},
'click .del-btn': function (event, value, row, index) {
$.alert({
title: '系统提示',
content: '删除提醒',
buttons: {
confirm: {
text: '确认',
btnClass: 'btn-primary',
action: function(){
$.post(url="/admin/cms.cms_tag/del",data={"id":row.id},function (res) {
if (res.status == 200) {parent.lightyear.notify('删除成功', 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');$("#tb_departments").bootstrapTable('refresh');}
else parent.lightyear.notify('删除失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
});
}
},
cancel: {
text: '取消'
}
}
});
}
}
}],
onLoadSuccess: function(data){
$("[data-toggle='tooltip']").tooltip();
}
});
// 操作按钮
function btnGroup ()
{
let html =
'<a href="#!" class="btn btn-xs btn-default del-btn" title="删除" data-toggle="tooltip"><i class="mdi mdi-window-close"></i></a>';
return html;
}
$("#search").click(function () {
$("#tb_departments").bootstrapTable('refresh',{query:{page:1},pageNumber:1});
});
function updateStatus(id, value, field) {
var newstate = (value == 1) ? 0 : 1; // 发送参数值跟当前参数值相反
$.ajax({
type: "post",
url: "/admin/user_message/field?id="+id,
data: {field: field, value: newstate},
dataType: 'json',
success: function (res) {
if (res.status == 200) {parent.lightyear.notify('修改成功', 'success', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');$(".tree-table").bootstrapTable('refresh');}
else parent.lightyear.notify('修改失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
},
error: function () {
parent.lightyear.notify('修改失败', 'danger', 3000, 'mdi mdi-emoticon-happy', 'top', 'center');
}
});
}
</script>
</body>
</html>

164
app/common.php Normal file
View File

@ -0,0 +1,164 @@
<?php
// 应用公共文件
if (!function_exists('system_config_more'))
{
/**
* 获取系统配置值
* @param array $formNames
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
function system_config_more(array $formNames): array
{
$systemConfig = cache('systemConfig');
if (empty($systemConfig)){
$systemConfig = \app\admin\model\system\SystemConfig::getSystemConfigValues();
cache('systemConfig',$systemConfig);
}
$data = [];
foreach ($formNames as $v){
$data[$v] = $systemConfig[$v]??'';
}
return $data;
}
}
if (!function_exists('param_to_array'))
{
/**
* 参数分割成数组
* @param string $param
* @param string $delimiter
* @return array
*/
function param_to_array(string $param, string $delimiter = "&"): array
{
$arr = [];
foreach (explode($delimiter,$param) as $value)
{
$tmp = explode("=",$value);
$arr[$tmp[0]] = $tmp[1];
}
return $arr;
}
}
if (!function_exists('get_File_type'))
{
/**
* 获取文件类型
* @param string $mime
* @return string
*/
function get_File_type(string $mime): string
{
if (stristr($mime,'image')) return 'image';
elseif (stristr($mime,'video')) return 'video';
elseif (stristr($mime,'audio')) return 'audio';
}
}
if (!function_exists('system_config'))
{
/**
* 获取系统配置值
* @param string $formName
* @return string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
function system_config(string $formName): string
{
$systemConfig = cache('systemConfig');
if (empty($systemConfig)){
$systemConfig = \app\admin\model\system\SystemConfig::getSystemConfigValues();
cache('systemConfig',$systemConfig);
}
return $systemConfig[$formName]??'';
}
}
if (!function_exists('create_order_id'))
{
/**
* 创建订单id
* @return string
*/
function create_order_id(): string
{
return "O".date("YmdHis").rand(1000,9999);
}
}
if (!function_exists('unicode_encode'))
{
/**
* 中文转unicode
* @param $str
* @return string
*/
function unicode_encode($str)
{
$strArr = preg_split('/(?<!^)(?!$)/u', $str);
$resUnicode = '';
foreach ($strArr as $str)
{
$bin_str = '';
$arr = is_array($str) ? $str : str_split($str);
foreach ($arr as $value) $bin_str .= decbin(ord($value));
$bin_str = preg_replace('/^.{4}(.{4}).{2}(.{6}).{2}(.{6})$/', '$1$2$3', $bin_str);
$unicode = dechex(bindec($bin_str));
$_sup = '';
for ($i = 0; $i < 4 - strlen($unicode); $i++) $_sup .= '0';
$str = '\\u' . $_sup . $unicode;
$resUnicode .= $str;
}
return $resUnicode;
}
}
if (!function_exists('unicode_decode'))
{
/**
* unicode转中文
* @param $unicode_str
* @return string
*/
function unicode_decode($unicode_str)
{
$json = '{"str":"'.$unicode_str.'"}';
$arr = json_decode($json,true);
if(empty($arr)) return '';
return $arr['str'];
}
}
if (!function_exists('file_cdn'))
{
/**
* 文件cdn
* @param $path
* @return string
* @author 李玉坤
* @date 2021-02-17 23:32
*/
function file_cdn($path)
{
if (empty($path)){
return $path;
}
if (strpos($path, 'http') !== false) {
//是网址开头的不处理
return $path;
}
if (!(substr($path, 0,1) == '/')){
//统一路径
$path = '/'.$path;
}
return config("app.cdn_url").$path;
}
}

View File

@ -0,0 +1,195 @@
<?php
namespace app\common\paginator;
use think\Paginator;
class Layer extends Paginator
{
/**
* 上一页按钮
* @param string $text
* @return string
*/
protected function getPreviousButton($text = "上一页")
{
if ($this->currentPage() <= 1) {
return $this->getDisabledTextWrapper($text);
}
$url = $this->url(
$this->currentPage() - 1
);
return $this->getPageLinkWrapper($url, $text);
}
/**
* 下一页按钮
* @param string $text
* @return string
*/
protected function getNextButton($text = '下一页')
{
if (!$this->hasMore) {
return $this->getDisabledTextWrapper($text);
}
$url = $this->url($this->currentPage() + 1);
$temp=$this->getPageLinkWrapper($url, $text);
return $temp;
}
/**
* 页码按钮
* @return string
*/
protected function getLinks()
{
if ($this->simple)
return '';
$block = [
'first' => null,
'slider' => null,
'last' => null
];
$side = 3;
$window = $side * 2;
if ($this->lastPage < $window + 6) {
$block['first'] = $this->getUrlRange(1, $this->lastPage);
} elseif ($this->currentPage <= $window) {
$block['first'] = $this->getUrlRange(1, $window + 2);
$block['last'] = $this->getUrlRange($this->lastPage - 1, $this->lastPage);
} elseif ($this->currentPage > ($this->lastPage - $window)) {
$block['first'] = $this->getUrlRange(1, 2);
$block['last'] = $this->getUrlRange($this->lastPage - ($window + 2), $this->lastPage);
} else {
$block['first'] = $this->getUrlRange(1, 2);
$block['slider'] = $this->getUrlRange($this->currentPage - $side, $this->currentPage + $side);
$block['last'] = $this->getUrlRange($this->lastPage - 1, $this->lastPage);
}
$html = '';
if (is_array($block['first'])) {
$html .= $this->getUrlLinks($block['first']);
}
if (is_array($block['slider'])) {
$html .= $this->getDots();
$html .= $this->getUrlLinks($block['slider']);
}
if (is_array($block['last'])) {
$html .= $this->getDots();
$html .= $this->getUrlLinks($block['last']);
}
return $html;
}
/**
* 渲染分页html
* @return mixed
*/
public function render()
{
if ($this->hasPages()) {
if ($this->simple) {
return sprintf(
'<div class="layui-box layui-laypage layui-laypage-default">%s %s</div>',
$this->getPreviousButton(),
$this->getNextButton()
);
} else {
return sprintf(
'<div class="layui-box layui-laypage layui-laypage-default">%s %s %s</div>',
$this->getPreviousButton(),
$this->getLinks(),
$this->getNextButton()
);
}
}
}
/**
* 生成一个可点击的按钮
*
* @param string $url
* @param int $page
* @return string
*/
protected function getAvailablePageWrapper($url, $page)
{
return '<a href="' . htmlentities($url) . '">' . $page . '</a>';
}
/**
* 生成一个禁用的按钮
*
* @param string $text
* @return string
*/
protected function getDisabledTextWrapper($text)
{
return '<a class="layui-laypage-prev layui-disabled">' . $text . '</a>';
}
/**
* 生成一个激活的按钮
*
* @param string $text
* @return string
*/
protected function getActivePageWrapper($text)
{
return '<span class="layui-laypage-curr"><em class="layui-laypage-em"></em><em>' . $text . '</em></span>';
}
/**
* 生成省略号按钮
*
* @return string
*/
protected function getDots()
{
return $this->getDisabledTextWrapper('...');
}
/**
* 批量生成页码按钮.
*
* @param array $urls
* @return string
*/
protected function getUrlLinks(array $urls)
{
$html = '';
foreach ($urls as $page => $url) {
$html .= $this->getPageLinkWrapper($url, $page);
}
return $html;
}
/**
* 生成普通页码按钮
*
* @param string $url
* @param int $page
* @return string
*/
protected function getPageLinkWrapper($url, $page)
{
if ($page == $this->currentPage()) {
return $this->getActivePageWrapper($page);
}
return $this->getAvailablePageWrapper($url, $page);
}
}

247
app/common/taglib/Zz.php Normal file
View File

@ -0,0 +1,247 @@
<?php
// +----------------------------------------------------------------------
// | HulaCWMS 呼啦企业网站管理系统
// +----------------------------------------------------------------------
// | Copyright (c) 2019 http://www.zhuopro.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: 灼灼文化
// +----------------------------------------------------------------------
namespace app\common\taglib;
use think\template\TagLib;
class Zz extends TagLib{
/**
* 定义标签列表
*/
protected $tags = [
// 标签定义: attr 属性列表 close 是否闭合0 或者1 默认1 alias 标签别名 level 嵌套层次
'channel'=> ['attr' => 'type,typeid,row,void,where,orderby,display', 'close' => 1],
'arclist'=> ['attr' => 'typeid,orderby,row,void,model,type,where,display,ids,limit', 'close' => 1],
'type'=> ['attr' => 'typeid', 'close' => 1],
'list'=> ['attr' => 'orderby,pagesize,type,typeid,void,model,where,display', 'close' => 1],
'prenext'=> ['attr' => 'get,cid,void', 'close' => 1],
'flink'=> ['attr' => 'type,row,void', 'close' => 1],
'sql'=> ['attr' => 'sql', 'close' => 1],
'article'=> ['attr' => 'id,void,model', 'close' => 1],
'tags'=> ['attr' => 'tags,void', 'close' => 1],
];
/**
* 栏目列表
* type,栏目分类数据读取分类
* typeid,栏目分类,数字,字符串,或者变量
*/
public function tagChannel($tag,$content)
{
$type=isset($tag['type'])?$tag['type']:'son';
$typeid=isset($tag['typeid'])?$tag['typeid']:'$cid';
$row=isset($tag['row'])?$tag['row']:100;
$void=isset($tag['void'])?$tag['void']:'field';
$where=isset($tag['where'])?$tag['where']:'';
$orderby=isset($tag['orderby'])?$tag['orderby']:'sort asc';
$display=isset($tag['display'])?$tag['display']:1;
$display=$display==1?1:0;
//3中传参类型
//1、栏目id数字类型
//2、多个栏目id逗号隔开
//3、变量
//只有当多个栏目id时才需要单引号加持。保证生成的为字符串
if(strpos($typeid,',')){
$typeid="'$typeid'";
}
$parse = '<?php ';
$parse .= '$__LIST__ = '."tpl_get_channel(\"$type\",$typeid,$row,\"$where\",\"$orderby\",$display);";
$parse .= ' ?>';
$parse .= '{volist name="__LIST__" id="'.$void.'"}';
$parse .= $content;
$parse .= '{/volist}';
return $parse;
}
/**
* 文章列表
*/
public function tagArclist($tag,$content)
{
$typeid = isset($tag['typeid'])?$tag['typeid']:'$cid';
$orderby=isset($tag['orderby'])?$tag['orderby']:'sort asc,create_time desc';
$row=isset($tag['row'])?$tag['row']:'100';
$void=isset($tag['void'])?$tag['void']:'field';
$model=isset($tag['model'])?$tag['model']:'article';
$type=isset($tag['type'])?$tag['type']:'find';
$where=isset($tag['where'])?$tag['where']:'';
$ids=isset($tag['ids'])?$tag['ids']:'';
$limit=isset($tag['limit'])?$tag['limit']:'100';
//limit参数优先于row
if(isset($tag['limit'])){
$row=$tag['limit'];
}
$display=isset($tag['display'])?$tag['display']:1;
$display=$display==1?1:0;
//3中传参类型
//1、栏目id数字类型
//2、多个栏目id逗号隔开
//3、变量
//只有当多个栏目id时才需要单引号加持。保证生成的为字符串
if(strpos($typeid,',')){
$typeid="'$typeid'";
}
$parse = '<?php ';
$parse .= '$__LIST__ = '."tpl_get_article_list($typeid,\"$row\",\"$orderby\",\"$model\",\"$type\",\"$where\",$display,\"$ids\");";;
$parse .= ' ?>';
$parse .= '{volist name="__LIST__" id="'.$void.'"}';
$parse .= $content;
$parse .= '{/volist}';
return $parse;
}
/**
* 栏目分类-单个
*/
public function tagType($tag,$content)
{
if(!isset($tag['typeid'])){
return '';
}
$typeid = $tag['typeid'];
$parse = '<?php ';
$parse .= '$__LIST__ =[];array_push($__LIST__,get_document_category('.$typeid.'));';
$parse .= ' ?>';
$parse .= '{volist name="__LIST__" id="field"}';
$parse .= $content;
$parse .= '{/volist}';
return $parse;
}
/**
* 列表分页
*/
public function tagList($tag,$content)
{
$orderby=isset($tag['orderby'])?$tag['orderby']:'sort asc,create_time desc';
$pagesize=isset($tag['pagesize'])?$tag['pagesize']:15;
$type=isset($tag['type'])?$tag['type']:'find';
$typeid=isset($tag['typeid'])?$tag['typeid']:'$cid';
$void=isset($tag['void'])?$tag['void']:'field';
$model=isset($tag['model'])?$tag['model']:'article';
$where=isset($tag['where'])?$tag['where']:'';
$display=isset($tag['display'])?$tag['display']:1;
$display=$display==1?1:0;
$parse = '<?php ';
$parse .= '$__FUN__ ='."tpl_get_list(\"$orderby\",$pagesize,$typeid,\"$type\",\"$model\",\"$where\",$display);";
$parse .= '$__LIST__ =$__FUN__["lists"];$pager = $__FUN__["model"]->render();';
$parse .= ' ?>';
$parse .= '{volist name="__LIST__" id="'.$void.'"}';
$parse .= $content;
$parse .= '{/volist}';
return $parse;
}
/**
* 详情页 上一篇 下一篇
* get=pre|next获取上一篇还是下一篇
* cid=栏目分类id获取当前分类下的上一篇下一篇
*/
public function tagPrenext($tag,$content)
{
$get=isset($tag['get'])?$tag['get']:'pre';
$cid=isset($tag['cid'])?$tag['cid']:'$cid';
$void=isset($tag['void'])?$tag['void']:'field';
$parse = '<?php ';
$parse .= '$__LIST__ =[];array_push($__LIST__,'."tpl_get_prenext(\"$get\",$cid));";
$parse .= ' ?>';
$parse .= '{volist name="__LIST__" id="'.$void.'"}';
$parse .= $content;
$parse .= '{/volist}';
return $parse;
}
/**
* 友情链接
*/
public function tagFlink($tag,$content)
{
$type=isset($tag['type'])?$tag['type']:'text';
$type=$type=='text'?0:1;
$row=isset($tag['row'])?$tag['row']:100;
$void=isset($tag['void'])?$tag['void']:'field';
$parse = '<?php ';
$parse .= '$__LIST__ ='."tpl_get_friend_link($type,$row);";
$parse .= ' ?>';
$parse .= '{volist name="__LIST__" id="'.$void.'"}';
$parse .= $content;
$parse .= '{/volist}';
return $parse;
}
/**
* 执行SQL
*/
public function tagSql($tag,$content)
{
if(!isset($tag['sql'])){
return '';
}
$sql=$tag['sql'];
$parse = '<?php ';
$parse .= '$__LIST__ ='."db()->query(\"$sql\");";
$parse .= ' ?>';
$parse .= '{volist name="__LIST__" id="field"}';
$parse .= $content;
$parse .= '{/volist}';
return $parse;
}
/**
* 获取单篇文章
*/
public function tagArticle($tag,$content)
{
if(!isset($tag['id'])){
return '';
}
$void=isset($tag['void'])?$tag['void']:'field';
$model=isset($tag['model'])?$tag['model']:'article';
$id=$tag['id'];
$parse = '<?php ';
$parse .= '$__LIST__ =[];array_push($__LIST__,'."tpl_get_article($id,'$model'));";
$parse .= ' ?>';
$parse .= '{volist name="__LIST__" id="'.$void.'"}';
$parse .= $content;
$parse .= '{/volist}';
return $parse;
}
/**
* 文章标签
*/
public function tagTags($tag,$content)
{
if(!isset($tag['tags'])){
return false;
}
$tags=$tag['tags'];
$void=isset($tag['void'])?$tag['void']:'field';
$parse = '<?php ';
$parse .= '$__TAG_LIST__ ='."tpl_get_tags_list($tags);";
$parse .= ' ?>';
$parse .= '{volist name="$__TAG_LIST__" id="'.$void.'"}';
$parse .= $content;
$parse .= '{/volist}';
return $parse;
}
}

View File

@ -0,0 +1,44 @@
<?php
// +----------------------------------------------------------------------
// | HulaCWMS 呼啦企业网站管理系统
// +----------------------------------------------------------------------
// | Copyright (c) 2019 http://www.zhuopro.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: 灼灼文化
// +----------------------------------------------------------------------
namespace app\common\validate;
use think\Validate;
/**
* 后台菜单验证器
*/
class AdminMenu extends Validate {
protected $rule = [
'title' => 'require|max:50',
'url' => 'max:255',
'pid' => 'require|number',
'sort' => 'require|number',
'is_dev' => 'require|number',
];
protected $message = [
'title.require' => '请输入菜单名称',
'title.max' => '菜单名称最多不能超过50个字符',
'url.max' => '链接地址最多不能超过50个字符',
'pid.require' => '请选择上级菜单',
'pid.number' => '请选择有效的上级菜单',
'sort' => '请输入排序序号',
'sort.number' => '排序序号只能是数字',
'is_dev' => '请选择可见模式',
'is_dev.number' => '可见模式只能是数字',
];
//更新排序
protected $scene = [
'sort' => ['sort']
];
}

View File

@ -0,0 +1,37 @@
<?php
// +----------------------------------------------------------------------
// | HulaCWMS 呼啦企业网站管理系统
// +----------------------------------------------------------------------
// | Copyright (c) 2019 http://www.zhuopro.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: 灼灼文化
// +----------------------------------------------------------------------
namespace app\common\validate;
use think\Validate;
/**
* 后台菜单验证器
*/
class Adminaction extends Validate {
protected $rule = [
'name' => 'require|max:30',
'title' => 'require|max:80',
'remark' => 'max:140',
'type' => 'number',
'status' => 'number',
];
protected $message = [
'name.require' => '请输入行为标识!',
'title.require' => '请输入行为名称!',
'title.max' => '行为名称最多输入80个字符',
'name.max' => '行为标识最多输入30个字符',
'remark.max' => '行为描述最多输入140个字符',
'type.number' => '行为类型只能为数字',
'status.number' => '行为状态只能为数字',
];
}

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