企业办公项目代码初始化版本

This commit is contained in:
hdm 2021-11-15 23:51:08 +08:00
parent 370a100859
commit eaa68ffb6f
523 changed files with 183824 additions and 63 deletions

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
/.idea
/.vscode
/.gitee
*.log
*.env
*.lock
*.ini
/runtime/*
/public/storage/*
/public/backup/*

37
LICENSE.txt Normal file
View File

@ -0,0 +1,37 @@
ThinkPHP遵循Apache2开源协议发布并提供免费使用。
版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)
All rights reserved。
ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
Apache Licence是著名的非盈利开源组织Apache采用的协议。
该协议和BSD类似鼓励代码共享和尊重原作者的著作权
允许代码修改,再作为开源或商业软件发布。需要满足
的条件:
1 需要给代码的用户一份Apache Licence
2 如果你修改了代码,需要在被修改的文件中说明;
3 在延伸的代码中(修改和有源代码衍生的代码中)需要
带有原来代码中的协议,商标,专利声明和其他原来作者规
定需要包含的说明;
4 如果再发布的产品中包含一个Notice文件则在Notice文
件中需要带有本协议内容。你可以在Notice中增加自己的
许可但不可以表现为对Apache Licence构成更改。
具体的协议参考http://www.apache.org/licenses/LICENSE-2.0
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.
勾股CMS遵循Apache2开源协议发布并提供免费使用。
版权所有Copyright © 2021 by gouguCMS (https://www.gougucms.com)
All rights reserved。

View File

@ -1,36 +0,0 @@
# 勾股办公
#### Description
勾股办公是一款基于ThinkPHP6 + Layui + MySql打造的简单实用的开源免费的企业办公系统框架。系统集成了系统设置、人事管理模块、消息管理模块、日常办公、财务管理等基础模块。系统简约易于功能扩展方便二次开发让开发者更专注于业务深度需求的开发帮助开发者简单高效降低二次开发成本通过二次开发之后也可以作为可以用来做CRMERP业务管理等系统。
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

255
README.md
View File

@ -1,37 +1,238 @@
# 勾股办公
# 勾股CMS
#### 介绍
勾股办公是一款基于ThinkPHP6 + Layui + MySql打造的简单实用的开源免费的企业办公系统框架。系统集成了系统设置、人事管理模块、消息管理模块、日常办公、财务管理等基础模块。系统简约易于功能扩展方便二次开发让开发者更专注于业务深度需求的开发帮助开发者简单高效降低二次开发成本通过二次开发之后也可以作为可以用来做CRMERP业务管理等系统。
[![勾股CMS](https://img.shields.io/badge/license-Apache%202-blue.svg)](https://gitee.com/gougucms/gougucms/)
[![勾股CMS](https://img.shields.io/badge/GouguCMS-1.0.0-brightgreen.svg)](https://gitee.com/gougucms/gougucms/)
[![star](https://gitee.com/gougucms/gougucms/badge/star.svg?theme=dark)](https://gitee.com/gougucms/gougucms/stargazers)
[![fork](https://gitee.com/gougucms/gougucms/badge/fork.svg?theme=dark)](https://gitee.com/gougucms/gougucms/members)
#### 软件架构
软件架构说明
### 链接
- 勾股CMShttps://www.gougucms.com
- giteehttps://gitee.com/gougucms/gougucms.git
### 开源项目
- [开源项目系列之勾股CMS](https://www.gougucms.com)
- [开源项目系列之勾股博客](https://blog.gougucms.com)
### 介绍
- 勾股CMS是一套基于ThinkPHP6 + Layui + MySql打造的轻量级、高性能极速后台开发框架。
- 系统后台各管理模块,一目了然,操作简单;通用型的后台权限管理框架,前后台用户的操作记录覆盖跟踪,紧随潮流、极低门槛、开箱即用。
- 系统易于功能扩展,代码维护,方便二次开发,帮助开发者简单高效降低二次开发的成本,满足专注业务深度开发的需求。
- 可以快速基于此系统进行ThinkPHP6的快速开发免去每次都写一次后台基础的痛苦。
- 可去前台版权,真正意义的永久免费,可商用的后台系统。
### 目录结构
初始的目录结构如下:
~~~
www 系统部署目录(或者子目录)
├─app 应用目录
│ ├─admin 后台模块目录
│ │ ├─controller 控制器目录
│ │ ├─middleware 中间层目录
│ │ ├─model 模型目录
│ │ ├─validate 校验器目录
│ │ ├─view 视图模板目录
│ │ ├─BaseController.php 基础控制器
│ │ ├─common.php 模块函数文件
│ │
│ ├─home 前台模块目录
│ │ ├─controller 控制器目录
│ │ ├─middleware 中间层目录
│ │ ├─model 模型目录
│ │ ├─validate 校验器目录
│ │ ├─view 视图模板目录
│ │ ├─BaseController.php 基础控制器
│ │ ├─common.php 模块函数文件
│ │
│ ├─install 安装模块目录(系统安装完后,建议删除)
│ │ ├─controller 控制器目录
│ │ ├─data 初始化数据库文件
│ │ ├─validate 校验器目录
│ │ ├─view 视图模板目录
│ │
├─config 配置文件目录
│ ├─app.php 系统主要配置文件
│ ├─database.php 数据库配置文件
├─extend 扩展类库目录
│ ├─avatars 自动生成头像文件目录
│ ├─backup 数据库备份文件目录
├─public WEB目录对外访问目录域名绑定的目录
│ ├─backup 数据库备份目录
│ ├─static css、js等静态资源目录
│ │ ├─admin 系统后台css、js文件
│ │ ├─home 系统前台css、js文件
│ │ ├─layui layui目录
│ │ ├─ueditor 百度编辑器目录
│ ├─storage 上传的图片等资源目录
│ ├─tpl TP中转界面模板目录
│ ├─index.php 入口文件
│ ├─router.php 快速测试文件
│ └─.htaccess 用于apache的重写
├─route 路由目录
├─vendor 第三方类库目录(Composer依赖库目录)
├─runtime 应用的运行时目录(可写,可定制)
├─composer.json composer 定义文件
├─LICENSE.txt 授权说明文件
├─README.md README 文件
├─think 命令行入口文件
~~~
#### 安装教程
### 功能矩阵
1. xxxx
2. xxxx
3. xxxx
系统后台集成了主流的通用功能登录验证、系统配置、操作日志管理、用户管理、用户权限、功能管理后台菜单管理、导航设置、网站地图、轮播广告、TAG关键字管理、文件上传、数据备份/还原、文章功能、用户管理、用户操作日志、用户注册/登录、 API接口等。更多的个性化功能可以基于当前系统便捷做二次开发。
#### 使用说明
具体功能如下:
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
~~~
系统
├─系统管理
│ ├─系统配置
│ ├─功能菜单
│ ├─功能节点
│ ├─权限角色
│ ├─管 理 员
│ ├─操作日志
│ ├─数据备份
│ ├─系统配置
│ ├─数据还原
├─基础数据
│ ├─导航设置
│ ├─网站地图
│ ├─轮播广告
│ ├─SEO关键字
│ ├─搜索关键词
├─平台用户
│ ├─用户列表
│ ├─操作记录
│ ├─操作日志
├─资讯中心
│ ├─文章分类
│ ├─文章列表
├─...
~~~
#### 特技
### 安装教程
一、勾股CMS推荐你使用阿里云和腾讯云服务器。
阿里云服务器官方长期折扣优惠地址:
点击访问,(https://www.aliyun.com/activity/daily/bestoffer?userCode=dmrcx154)
腾讯云服务器官方长期折扣优惠地址:
点击访问,(https://curl.qcloud.com/PPEgI0oV)
二、服务器运行环境要求。
~~~
PHP >= 7.1
Mysql >= 5.5.0 (需支持innodb引擎)
Apache 或 Nginx
PDO PHP Extension
MBstring PHP Extension
CURL PHP Extension
Composer (用于管理第三方扩展包)
~~~
三、系统安装
**方式一:完整包安装**
第一步:前往官网下载页面 (https://www.gougucms.com) 下载完整包解压到你的项目目录
第二步添加虚拟主机并绑定到项目的public目录
第三步:访问 http://www.yoursite.com/install/index 进行安装
**方式二:命令行安装(推荐)**
推荐使用命令行安装因为采用命令行安装的方式可以和勾股CMS随时保持更新同步。使用命令行安装请提前准备好Git、Composer。
Linux下勾股CMS的安装请使用以下命令进行安装。
第一步克隆勾股CMS到你本地
git clone https://gitee.com/gougucms/gougucms.git
第二步:进入目录
cd gougucms
第三步下载PHP依赖包
composer install
注意composer的版本最好是2.0.8版本否则可能下载PHP依赖包失败composer降级composer self-update 2.0.8
第四步添加虚拟主机并绑定到项目的public目录
第五步:访问 http://www.yoursite.com/install/index 进行安装
**PS如需要重新安装请删除目录里面 config/install.lock 的文件,即可重新安装。**
四、伪静态配置
**Nginx**
修改nginx.conf 配置文件 加入下面的语句。
~~~
location / {
if (!-e $request_filename){
rewrite ^(.*)$ /index.php?s=$1 last; break;
}
}
~~~
**Apache**
把下面的内容保存为.htaccess文件放到应用入 public 文件的同级目录下。
~~~
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
</IfModule>
~~~
### 常见问题
1. 安装失败可能存在php配置文件禁止了putenv 和 proc_open函数。解决方法查找php.ini文件位置打开php.ini搜索 disable_functions 项看是否禁用了putenv 和 proc_open函数。如果在禁用列表里移除putenv proc_open然后退出重启php即可。
2. 如果安装后打开页面提示404错误请检查服务器伪静态配置如果是宝塔面板网站伪静态请配置使用thinkphp规则。
3. 如果提示当前权限不足无法写入配置文件config/database.php请检查database.php是否可读还有可能是当前安装程序无法访问父目录请检查PHP的open_basedir配置。
4. 如果composer install失败请尝试在命令行进行切换配置到国内源命令如下composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/。
5. 如果composer install失败请尝试composer降级composer self-update 2.0.8。
6. 访问 http://www.yoursite.com/install/index 请注意查看伪静态请配置是否设置了thinkphp规则。
7. 遇到问题请到QQ群24641076 反馈。
### 截图预览
![输入图片说明](https://images.gitee.com/uploads/images/2021/0225/002705_51fd21e2_8633021.png "p1.png")
![输入图片说明](https://images.gitee.com/uploads/images/2021/0225/002716_e8037c3c_8633021.png "p2.png")
![输入图片说明](https://images.gitee.com/uploads/images/2021/0904/222609_7cb6d1a9_72602.png "p3.png")
### 开源协议
勾股CMS遵循Apache2开源协议发布并提供免费使用。
### 开源助力
毫无保留的真开源,不要吝啬您的赞许和鼓励,请给我们⭐ STAR ⭐吧!
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/)

124
app/api/BaseController.php Normal file
View File

@ -0,0 +1,124 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\api;
use think\App;
use think\exception\HttpResponseException;
use think\facade\Request;
use think\Response;
/**
* 控制器基础类
*/
abstract class BaseController
{
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
/**
* 是否批量验证
* @var bool
*/
protected $batchValidate = false;
/**
* 控制器中间件
* @var array
*/
protected $middleware = [];
/**
* 分页数量
* @var string
*/
protected $pageSize = '';
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 控制器初始化
$this->initialize();
}
// 初始化
protected function initialize()
{
//每页显示数据量
$this->pageSize = Request::param('page_size', \think\facade\Config::get('app.page_size'));
}
/**
* Api处理成功结果返回方法
* @param $message
* @param null $redirect
* @param null $extra
* @return mixed
* @throws ReturnException
*/
protected function apiSuccess($msg = 'success',$data=[])
{
return $this->apiReturn($data, 0, $msg);
}
/**
* Api处理结果失败返回方法
* @param $error_code
* @param $message
* @param null $redirect
* @param null $extra
* @return mixed
* @throws ReturnException
*/
protected function apiError($msg = 'fail',$data=[], $code = 1)
{
return $this->apiReturn($data, $code, $msg);
}
/**
* 返回封装后的API数据到客户端
* @param mixed $data 要返回的数据
* @param integer $code 返回的code
* @param mixed $msg 提示信息
* @param string $type 返回数据格式
* @param array $header 发送的Header信息
* @return Response
*/
protected function apiReturn($data, int $code = 0, $msg = '', string $type = '', array $header = []): Response
{
$result = [
'code' => $code,
'msg' => $msg,
'time' => time(),
'data' => $data,
];
$type = $type ?: 'json';
$response = Response::create($result, $type)->header($header);
throw new HttpResponseException($response);
}
}

12
app/api/common.php Normal file
View File

@ -0,0 +1,12 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
//读取文章分类列表
function get_article_cate()
{
$cate = \think\facade\Db::name('ArticleCate')->order('create_time asc')->select()->toArray();
return $cate;
}

View File

@ -0,0 +1,150 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\api\controller;
use app\api\BaseController;
use app\api\middleware\Auth;
use app\api\service\JwtAuth;
use think\facade\Db;
use think\facade\Request;
class Index extends BaseController
{
/**
* 控制器中间件 [登录、注册 不需要鉴权]
* @var array
*/
protected $middleware = [
Auth::class => ['except' => ['index','login','reg'] ]
];
/**
* @api {post} /index/index API页面
* @apiDescription 返回首页信息
*/
public function index()
{
$list = Db::name('Article')->select();
$seo = get_system_config('web');
add_user_log('api', '首页');
$this->apiSuccess('请求成功',['list' => $list,'seo' => $seo]);
}
/**
* @api {post} /index/login 会员登录
* @apiDescription 系统登录接口,返回 token 用于操作需验证身份的接口
* @apiParam (请求参数:) {string} username 登录用户名
* @apiParam (请求参数:) {string} password 登录密码
* @apiParam (响应字段:) {string} token Token
* @apiSuccessExample {json} 成功示例
* {"code":0,"msg":"登录成功","time":1627374739,"data":{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhcGkuZ291Z3VjbXMuY29tIiwiYXVkIjoiZ291Z3VjbXMiLCJpYXQiOjE2MjczNzQ3MzksImV4cCI6MTYyNzM3ODMzOSwidWlkIjoxfQ.gjYMtCIwKKY7AalFTlwB2ZVWULxiQpsGvrz5I5t2qTs"}}
* @apiErrorExample {json} 失败示例
* {"code":1,"msg":"帐号或密码错误","time":1627374820,"data":[]}
*/
public function login()
{
$param = get_params();
if(empty($param['username']) || empty($param['password'])){
$this->apiError('参数错误');
}
// 校验用户名密码
$user = Db::name('User')->where(['username' => $param['username']])->find();
if (empty($user)) {
$this->apiError('帐号或密码错误');
}
$param['pwd'] = set_password($param['password'], $user['salt']);
if ($param['pwd'] !== $user['password']) {
$this->apiError('帐号或密码错误');
}
if ($user['status'] == -1) {
$this->apiError('该用户禁止登录,请于平台联系');
}
$data = [
'last_login_time' => time(),
'last_login_ip' => request()->ip(),
'login_num' => $user['login_num'] + 1,
];
$res = Db::name('user')->where(['id' => $user['id']])->update($data);
if($res){
//获取jwt的句柄
$jwtAuth = JwtAuth::getInstance();
$token = $jwtAuth->setUid($user['id'])->encode()->getToken();
add_user_log('api', '登录');
$this->apiSuccess('登录成功',['token' => $token]);
}
}
/**
* @api {post} /index/reg 会员注册
* @apiDescription 系统注册接口,返回是否成功的提示,需再次登录
* @apiParam (请求参数:) {string} username 用户名
* @apiParam (请求参数:) {string} password 密码
* @apiSuccessExample {json} 成功示例
* {"code":0,"msg":"注册成功","time":1627375117,"data":[]}
* @apiErrorExample {json} 失败示例
* {"code":1,"msg":"该账户已经存在","time":1627374899,"data":[]}
*/
public function reg()
{
$param = get_params();
if(empty($param['username']) || empty($param['pwd'])){
$this->apiError('参数错误');
}
$user = Db::name('user')->where(['username' => $param['username']])->find();
if (!empty($user)) {
$this->apiError('该账户已经存在');
}
$param['salt'] = set_salt(20);
$param['password'] = set_password($param['pwd'], $param['salt']);
$param['register_time'] = time();
$param['headimgurl'] = '/static/home/images/icon.png';
$param['register_ip'] = request()->ip();
$char = mb_substr($param['username'], 0, 1, 'utf-8');
$uid = Db::name('User')->strict(false)->field(true)->insertGetId($param);
if($uid){
add_user_log('api', '注册');
$this->apiSuccess('注册成功');
}else{
$this->apiError('注册失败');
}
}
/**
* @api {post} /index/demo 测试页面
* @apiDescription 返回文章列表信息
* @apiParam (请求参数:) {string} token Token
* @apiSuccessExample {json} 响应数据样例
* {"code":1,"msg":"","time":1563517637,"data":{"id":13,"email":"test110@qq.com","password":"e10adc3949ba59abbe56e057f20f883e","sex":1,"last_login_time":1563517503,"last_login_ip":"127.0.0.1","qq":"123455","mobile":"","mobile_validated":0,"email_validated":0,"type_id":1,"status":1,"create_ip":"127.0.0.1","update_time":1563507130,"create_time":1563503991,"type_name":"注册会员"}}
*/
public function demo()
{
$list = Db::name('Article')->select();
$jwtAuth = JwtAuth::getInstance();
$uid = $jwtAuth->getUid();
$userInfo = Db::name('User')->where(['id' => $uid])->find();
add_user_log('api', '测试页面');
$this->apiSuccess('请求成功',['list' => $list,'user' => $userInfo]);
}
/**
* 获取用户id
* @return mixed
*/
protected function getUid()
{
$jwtAuth = JwtAuth::getInstance();
return $jwtAuth->getUid();
}
}

5
app/api/event.php Normal file
View File

@ -0,0 +1,5 @@
<?php
// 这是系统自动生成的event定义文件
return [
];

8
app/api/middleware.php Normal file
View File

@ -0,0 +1,8 @@
<?php
// 这是系统自动生成的middleware定义文件
return [
//开启session中间件
//'think\middleware\SessionInit',
//验证勾股cms是否完成安装
\app\home\middleware\Install::class,
];

View File

@ -0,0 +1,62 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\api\middleware;
use app\api\service\JwtAuth;
use think\exception\HttpResponseException;
use think\facade\Request;
use think\Response;
class Auth
{
public function handle($request, \Closure $next)
{
$token = Request::header('Token');
if ($token) {
if (count(explode('.', $token)) != 3) {
$this->result([], 110, 'token格式错误');
}
$jwtAuth = JwtAuth::getInstance();
$jwtAuth->setToken($token);
if ($jwtAuth->validate() && $jwtAuth->verify()) {
return $next($request);
} else {
$this->result([], 111, 'token已过期');
}
} else {
$this->result([], 112, 'token不能为空');
}
return $next($request);
}
/**
* 返回封装后的API数据到客户端
* @param mixed $data 要返回的数据
* @param integer $code 返回的code
* @param mixed $msg 提示信息
* @param string $type 返回数据格式
* @param array $header 发送的Header信息
* @return Response
*/
protected function result($data, int $code = 0, $msg = '', string $type = '', array $header = []): Response
{
$result = [
'code' => $code,
'msg' => $msg,
'time' => time(),
'data' => $data,
];
$type = $type ?: 'json';
$response = Response::create($result, $type)->header($header);
throw new HttpResponseException($response);
}
}

143
app/api/service/JwtAuth.php Normal file
View File

@ -0,0 +1,143 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\api\service;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\ValidationData;
/**
* 单例 一次请求中所有出现jwt的地方都是一个用户
* Class JwtAuth
* @package app\api\service
*/
class JwtAuth
{
// jwt token
private $token;
// jwt 过期时间
private $expTime = 3600;
// claim iss 签发组织
private $iss = 'wwww.gougucms.com';
// claim aud签发作者
private $aud = 'gougucms';
// secrect
private $secrect = 'GOUGUCMS';
// claim uid
private $uid;
// decode token
private $decodeToken;
// 单例模式JwtAuth句柄
private static $instance;
// 获取JwtAuth的句柄
public static function getInstance()
{
if (is_null(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
// 私有化构造函数
public function __construct()
{
// jwt 过期时间
$this->expTime = get_system_config('token','exptime');
// claim iss 签发组织
$this->iss = get_system_config('token','iss');
// claim aud签发作者
$this->aud = get_system_config('token','aud');
// secrect
$this->secrect = get_system_config('token','secrect');
}
// 私有化clone函数
private function __clone()
{
// TODO: Implement __clone() method.
}
// 获取token
public function getToken()
{
return (string) $this->token;
}
// 设置token
public function setToken($token)
{
$this->token = $token;
return $this;
}
// 设置uid
public function setUid($uid)
{
$this->uid = $uid;
return $this;
}
// 获取uid
public function getUid()
{
return $this->uid;
}
// 编码jwt token
public function encode()
{
$time = time(); //签发时间
$this->token = (new Builder())->setHeader('alg', 'HS256')
->setIssuer($this->iss)
->setAudience($this->aud)
->setIssuedAt($time)
->setExpiration($time + $this->expTime)
->set('uid', $this->uid)
->sign(new Sha256(), $this->secrect)
->getToken();
return $this;
}
public function decode()
{
if (!$this->decodeToken) {
$this->decodeToken = (new Parser())->parse((string) $this->token); // Parses from a string
$this->uid = $this->decodeToken->getClaim('uid');
}
return $this->decodeToken;
}
// validate
public function validate()
{
$data = new ValidationData(); // It will use the current time to validate (iat, nbf and exp)
$data->setIssuer($this->iss);
$data->setAudience($this->aud);
$data->setId($this->uid);
return $this->decode()->validate($data);
}
// verify token
public function verify()
{
$signer = new Sha256();
return $this->decode()->verify($signer, $this->secrect);
}
}

460
app/common.php Normal file
View File

@ -0,0 +1,460 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
// 应用公共文件,内置主要的数据处理方法
use think\facade\Config;
use think\facade\Request;
//读取文件配置
function get_config($key)
{
return Config::get($key);
}
//判断cms是否完成安装
function is_installed()
{
static $isInstalled;
if (empty($isInstalled)) {
$isInstalled = file_exists(CMS_ROOT . 'config/install.lock');
}
return $isInstalled;
}
//获取服务器信息
function get_system_info($key)
{
$system = [
'os' => PHP_OS,
'php' => PHP_VERSION,
'upload_max_filesize' => get_cfg_var("upload_max_filesize") ? get_cfg_var("upload_max_filesize") : "不允许上传附件",
'max_execution_time' => get_cfg_var("max_execution_time") . "",
];
if (empty($key)) {
return $system;
} else {
return $system[$key];
}
}
//获取url参数
function get_params($key = "")
{
return Request::instance()->param($key);
}
//生成一个不会重复的字符串
function make_token()
{
$str = md5(uniqid(md5(microtime(true)), true));
$str = sha1($str); //加密
return $str;
}
//随机字符串默认长度10
function set_salt($num = 10)
{
$str = 'qwertyuiopasdfghjklzxcvbnm1234567890';
$salt = substr(str_shuffle($str), 10, $num);
return $salt;
}
//密码加密
function set_password($pwd, $salt)
{
return md5(md5($pwd . $salt) . $salt);
}
/**
* 截取文章摘要
* @return bool
*/
function get_desc_content($content, $count)
{
$content = preg_replace("@<script(.*?)</script>@is", "", $content);
$content = preg_replace("@<iframe(.*?)</iframe>@is", "", $content);
$content = preg_replace("@<style(.*?)</style>@is", "", $content);
$content = preg_replace("@<(.*?)>@is", "", $content);
$content = str_replace(PHP_EOL, '', $content);
$space = array(" ", " ", " ", " ", " ");
$go_away = array("", "", "", "", "");
$content = str_replace($space, $go_away, $content);
$res = mb_substr($content, 0, $count, 'UTF-8');
if (mb_strlen($content, 'UTF-8') > $count) {
$res = $res . "...";
}
return $res;
}
/**
* PHP格式化字节大小
* @param number $size 字节数
* @param string $delimiter 数字和单位分隔符
* @return string 格式化后的带单位的大小
*/
function format_bytes($size, $delimiter = '')
{
$units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
for ($i = 0; $size >= 1024 && $i < 5; $i++) {
$size /= 1024;
}
return round($size, 2) . $delimiter . $units[$i];
}
/**
*数据处理成树形格式1
* @return array
*/
function list_to_tree($list, $pk = 'id', $pid = 'pid', $child = 'list', $root = 0)
{
// 创建Tree
$tree = array();
if (is_array($list)) {
// 创建基于主键的数组引用
$refer = array();
foreach ($list as $key => $data) {
$refer[$data[$pk]] = &$list[$key];
}
foreach ($list as $key => $data) {
// 判断是否存在parent
$parentId = $data[$pid];
if ($root == $parentId) {
$tree[$data[$pk]] = &$list[$key];
} else {
if (isset($refer[$parentId])) {
$parent = &$refer[$parentId];
$parent[$child][$data[$pk]] = &$list[$key];
}
}
}
}
return $tree;
}
/**
*数据处理成树形格式2
* @return array
*/
function create_tree_list($pid, $arr, $group, &$tree = [])
{
foreach ($arr as $key => $vo) {
if ($key == 0) {
$vo['spread'] = true;
}
if (!empty($group) and in_array($vo['id'], $group)) {
$vo['checked'] = true;
} else {
$vo['checked'] = false;
}
if ($vo['pid'] == $pid) {
$child = create_tree_list($vo['id'], $arr, $group);
if ($child) {
$vo['children'] = $child;
}
$tree[] = $vo;
}
}
return $tree;
}
//递归排序,用于分类选择
function set_recursion($result, $pid = 0, $level=-1)
{
/*记录排序后的类别数组*/
static $list = array();
static $space = ['','├─','§§├─','§§§§├─','§§§§§§├─'];
$level++;
foreach ($result as $k => $v) {
if ($v['pid'] == $pid) {
if ($pid != 0) {
$v['title'] = $space[$level] . $v['title'];
}
/*将该类别的数据放入list中*/
$list[] = $v;
set_recursion($result, $v['id'],$level);
}
}
return $list;
}
//递归返回树形菜单数据
function get_tree($data, $pId ,$open=0,$deep=0)
{
$tree = [];
foreach($data as $k => $v)
{
$v['checkArr']=array('type'=>0, 'isChecked'=>0);
$v['spread']=true;
$v['parentId']=$v['pid'];
if($deep>=$open){
$v['spread']=false;
}
$v['name']=$v['title'];
if($v['pid'] == $pId){
//父亲找到儿子
$deep++;
$v['children'] = get_tree($data, $v['id'],$open,$deep);
$tree[] = $v;
//unset($data[$k]);
}
}
return array_values($tree);
}
/**
* 根据id递归返回子数据
* @param $data 数据
* @param $pid 父节点id
*/
function get_data_node($data=[],$pid=0){
$dep = [];
foreach($data as $k => $v){
if($v['pid'] == $pid){
$node=get_data_node($data, $v['id']);
array_push($dep,$v);
if(!empty($node)){
$dep=array_merge($dep,$node);
}
}
}
return array_values($dep);
}
//访问按小时归档统计
function hour_document($arrData)
{
$documents = array();
$hour = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23];
foreach ($hour as $val) {
$documents[$val] = 0;
}
foreach ($arrData as $index => $value) {
$archivesTime = intval(date("H", $value['create_time']));
$documents[$archivesTime] += 1;
}
return $documents;
}
//访问按日期归档统计
function date_document($arrData)
{
$documents = array();
foreach ($arrData as $index => $value) {
$archivesTime = date("Y-m-d", $value['create_time']);
if (empty($documents[$archivesTime])) {
$documents[$archivesTime] = 1;
} else {
$documents[$archivesTime] += 1;
}
}
return $documents;
}
/**
* 返回json数据用于接口
* @param integer $code
* @param string $msg
* @param array $data
* @param string $url
* @param integer $httpCode
* @param array $header
* @param array $options
* @return json
*/
function to_assign($code = 0, $msg = "操作成功", $data = [], $url = '', $httpCode = 200, $header = [], $options = [])
{
$res = ['code' => $code];
$res['msg'] = $msg;
$res['url'] = $url;
if (is_object($data)) {
$data = $data->toArray();
}
$res['data'] = $data;
$response = \think\Response::create($res, "json", $httpCode, $header, $options);
throw new \think\exception\HttpResponseException($response);
}
/**
* 适配layui table数据列表的返回数据方法用于接口
* @param integer $code
* @param string $msg
* @param array $data
* @param integer $httpCode
* @param array $header
* @param array $options
* @return json
*/
function table_assign($code = 0, $msg = '请求成功', $data = [], $httpCode = 200, $header = [], $options = [])
{
$res['code'] = $code;
$res['msg'] = $msg;
if (is_object($data)) {
$data = $data->toArray();
}
if (!empty($data['total'])) {
$res['count'] = $data['total'];
} else {
$res['count'] = 0;
}
$res['data'] = $data['data'];
$response = \think\Response::create($res, "json", $httpCode, $header, $options);
throw new \think\exception\HttpResponseException($response);
}
/**
* 时间戳格式化
* @param int $time
* @param string $format 默认'Y-m-d H:i'x代表毫秒
* @return string 完整的时间显示
*/
function time_format($time = NULL, $format = 'Y-m-d H:i:s')
{
$usec = $time = $time === null ? '' : $time;
if (strpos($time, '.')!==false) {
list($usec, $sec) = explode(".", $time);
} else {
$sec = 0;
}
return $time != '' ? str_replace('x', $sec, date($format, intval($usec))) : '';
}
function parseDateTime($string, $timeZone=null) {
$date = new DateTime(
$string,
$timeZone ? $timeZone : new DateTimeZone('UTC')
);
if ($timeZone) {
$date->setTimezone($timeZone);
}
return $date;
}
function stripTime($datetime) {
return new DateTime($datetime->format('Y-m-d'));
}
/**
* 间隔时间段格式化
* @param int $time 时间戳
* @param string $format 格式 【d显示到天 i显示到分钟 s显示到秒】
* @return string
*/
function time_trans($time, $format = 'd')
{
$now = time();
$diff = $now - $time;
if ($diff < 60) {
return '1分钟前';
} else if ($diff < 3600) {
return floor($diff / 60) . '分钟前';
} else if ($diff < 86400) {
return floor($diff / 3600) . '小时前';
}
$yes_start_time = strtotime(date('Y-m-d 00:00:00', strtotime('-1 days'))); //昨天开始时间
$yes_end_time = strtotime(date('Y-m-d 23:59:59', strtotime('-1 days'))); //昨天结束时间
$two_end_time = strtotime(date('Y-m-d 23:59:59', strtotime('-2 days'))); //2天前结束时间
$three_end_time = strtotime(date('Y-m-d 23:59:59', strtotime('-3 days'))); //3天前结束时间
$four_end_time = strtotime(date('Y-m-d 23:59:59', strtotime('-4 days'))); //4天前结束时间
$five_end_time = strtotime(date('Y-m-d 23:59:59', strtotime('-5 days'))); //5天前结束时间
$six_end_time = strtotime(date('Y-m-d 23:59:59', strtotime('-6 days'))); //6天前结束时间
$seven_end_time = strtotime(date('Y-m-d 23:59:59', strtotime('-7 days'))); //7天前结束时间
if ($time > $yes_start_time && $time < $yes_end_time) {
return '昨天';
}
if ($time > $yes_start_time && $time < $two_end_time) {
return '1天前';
}
if ($time > $yes_start_time && $time < $three_end_time) {
return '2天前';
}
if ($time > $yes_start_time && $time < $four_end_time) {
return '3天前';
}
if ($time > $yes_start_time && $time < $five_end_time) {
return '4天前';
}
if ($time > $yes_start_time && $time < $six_end_time) {
return '5天前';
}
if ($time > $yes_start_time && $time < $seven_end_time) {
return '6天前';
}
switch ($format) {
case 'd':
$show_time = date('Y-m-d', $time);
break;
case 'i':
$show_time = date('Y-m-d H:i', $time);
break;
case 's':
$show_time = date('Y-m-d H:i:s', $time);
break;
}
return $show_time;
}
/**
* 判断是否是手机浏览器
* @return bool
*/
function is_mobile()
{
if (isset($_SERVER['HTTP_VIA']) && stristr($_SERVER['HTTP_VIA'], "wap")) {
return true;
} elseif (isset($_SERVER['HTTP_ACCEPT']) && strpos(strtoupper($_SERVER['HTTP_ACCEPT']), "VND.WAP.WML")) {
return true;
} elseif (isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE'])) {
return true;
} elseif (isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/(blackberry|configuration\/cldc|hp |hp-|htc |htc_|htc-|iemobile|kindle|midp|mmp|motorola|mobile|nokia|opera mini|opera |Googlebot-Mobile|YahooSeeker\/M1A1-R2D2|android|iphone|ipod|mobi|palm|palmos|pocket|portalmmm|ppc;|smartphone|sonyericsson|sqh|spv|symbian|treo|up.browser|up.link|vodafone|windows ce|xda |xda_)/i', $_SERVER['HTTP_USER_AGENT'])) {
return true;
} else {
return false;
}
}
/**
* 验证输入的邮件地址是否合法
* @param $user_email 邮箱
* @return bool
*/
function is_email($user_email)
{
$chars = "/^([a-z0-9+_]|\\-|\\.)+@(([a-z0-9_]|\\-)+\\.)+[a-z]{2,6}\$/i";
if (strpos($user_email, '@') !== false && strpos($user_email, '.') !== false) {
if (preg_match($chars, $user_email)) {
return true;
} else {
return false;
}
} else {
return false;
}
}
/**
* 验证输入的手机号码是否合法
* @param $mobile_phone 手机号
* @return bool
*/
function is_mobile_phone($mobile_phone)
{
$chars = "/^13[0-9]{1}[0-9]{8}$|15[0-9]{1}[0-9]{8}$|18[0-9]{1}[0-9]{8}$|17[0-9]{1}[0-9]{8}$/";
if (preg_match($chars, $mobile_phone)) {
return true;
}
return false;
}

248
app/home/BaseController.php Normal file
View File

@ -0,0 +1,248 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home;
use think\App;
use think\exception\HttpResponseException;
use think\facade\Request;
use think\facade\Cache;
use think\facade\Session;
use think\facade\Db;
use think\facade\View;
/**
* 控制器基础类
*/
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->module = strtolower(app('http')->getName());
$this->app = $app;
$this->request = $this->app->request;
$this->controller = strtolower($this->request->controller());
$this->action = strtolower($this->request->action());
$this->uid=0;
// 控制器初始化
$this->initialize();
}
// 初始化
protected function initialize()
{
// 检测权限
$this->checkLogin();
$this->param = $this->request->param();
}
/**
*验证用户登录
*/
protected function checkLogin()
{
if ($this->controller !== 'login' && $this->controller !=='captcha' ) {
$session_admin = get_config('app.session_admin');
if (!Session::has($session_admin)) {
if ($this->request->isAjax()) {
return to_assign(404, '请先登录');
} else {
redirect('/home/login/index.html')->send();
exit;
}
}
else{
$this->uid = Session::get($session_admin)['id'];
View::assign('login_user',$this->uid);
// 验证用户访问权限
if ($this->controller !== 'index' && $this->controller !== 'api') {
if (!$this->checkAuth()) {
if ($this->request->isAjax()) {
return to_assign(202, '你没有权限,请联系管理员或者人事部');
} else {
echo '<div style="text-align:center;color:red;margin-top:20%;">你没有权限,请联系管理员或者人事部</div>';exit;
}
}
}
}
}
}
/**
* 验证用户访问权限
* @DateTime 2020-12-21
* @param string $controller 当前访问控制器
* @param string $action 当前访问方法
* @return [type]
*/
protected function checkAuth()
{
//Cache::delete('RulesSrc' . $uid);
$uid = $this->uid;
if (!Cache::get('RulesSrc' . $uid) || !Cache::get('RulesSrc0')) {
//用户所在权限组及所拥有的权限
// 执行查询
$groups = [];
$position_id=Db::name('Admin')->where('id',$uid)->value('position_id');
$groups = Db::name('PositionGroup')
->alias('a')
->join("AdminGroup g", "a.group_id=g.id", 'LEFT')
->where([['a.pid','=',$position_id],['g.status','=',1]])
->select()
->toArray();
//保存用户所属用户组设置的所有权限规则id
$ids = [];
foreach ($groups as $g) {
$ids = array_merge($ids, explode(',', trim($g['rules'], ',')));
}
$ids = array_unique($ids);
//读取所有权限规则
$rules_all = Db::name('AdminRule')->field('src')->select();
//读取用户组所有权限规则
$rules = Db::name('AdminRule')->where('id', 'in', $ids)->field('src')->select();
//循环规则,判断结果。
$auth_list_all = [];
$auth_list = [];
foreach ($rules_all as $rule_all) {
$auth_list_all[] = strtolower($rule_all['src']);
}
foreach ($rules as $rule) {
$auth_list[] = strtolower($rule['src']);
}
//规则列表结果保存到Cache
Cache::tag('adminRules')->set('RulesSrc0', $auth_list_all, 36000);
Cache::tag('adminRules')->set('RulesSrc' . $uid, $auth_list, 36000);
} else {
$auth_list_all = Cache::get('RulesSrc0');
$auth_list = Cache::get('RulesSrc' . $uid);
}
$pathUrl = $this->module. '/' .$this->controller . '/' . $this->action;
if (!in_array($pathUrl, $auth_list)) {
return false;
} else {
return true;
}
}
//
// 以下为新增,为了使用旧版的 success error redirect 跳转 start
//
/**
* 操作成功跳转的快捷方法
* @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' => 0,
'msg' => $msg,
'data' => $data,
'url' => $url,
'wait' => $wait,
];
$type = $this->getResponseType();
if ($type == 'html') {
$response = view($this->app->config->get('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' => 1,
'msg' => $msg,
'data' => $data,
'url' => $url,
'wait' => $wait,
];
$type = $this->getResponseType();
if ($type == 'html') {
$response = view($this->app->config->get('app.dispatch_error_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';
}
//
// 以上为新增,为了使用旧版的 success error redirect 跳转 end
//
}

338
app/home/common.php Normal file
View File

@ -0,0 +1,338 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
/**
======================
*模块数据获取公共文件
======================
*/
use think\facade\Cache;
use think\facade\Db;
//设置缓存
function set_cache($key, $value, $date = 86400)
{
Cache::set($key, $value, $date);
}
//读取缓存
function get_cache($key)
{
return Cache::get($key);
}
//清空缓存
function clear_cache($key)
{
Cache::clear($key);
}
//读取系统配置
function get_system_config($name,$key='')
{
$config=[];
if (get_cache('system_config' . $name)) {
$config = get_cache('system_config' . $name);
} else {
$conf = Db::name('config')->where('name',$name)->find();
if($conf['content']){
$config = unserialize($conf['content']);
}
set_cache('system_config' . $name, $config);
}
if($key==''){
return $config;
}
else{
if($config[$key]){
return $config[$key];
}
}
}
//获取指定管理员的信息
function get_admin($id)
{
$admin = Db::name('Admin')->where(['id' => $id])->find();
$admin['department'] = Db::name('Department')->where(['id' => $admin['did']])->value('title');
$admin['position'] = Db::name('Position')->where(['id' => $admin['position_id']])->value('title');
$admin['last_login_time'] = empty($admin['last_login_time']) ? '-' : date('Y-m-d H:i', $admin['last_login_time']);
return $admin;
}
//获取当前登录用户的信息
function get_login_admin($key='')
{
$session_admin = get_config('app.session_admin');
if (\think\facade\Session::has($session_admin)) {
$gougu_admin = \think\facade\Session::get($session_admin);
$admin = get_admin($gougu_admin['id']);
if (!empty($key)) {
if (isset($admin[$key])) {
return $admin[$key];
} else {
return '';
}
} else {
return $admin;
}
} else {
return '';
}
}
//读取后台菜单列表
function get_admin_menu()
{
$menu = Db::name('AdminMenu')->order('sort asc')->select()->toArray();
return $menu;
}
//读取权限节点列表
function get_admin_rule()
{
$rule = Db::name('AdminRule')->order('create_time asc')->select()->toArray();
return $rule;
}
//读取权限分组列表
function get_admin_group()
{
$group = Db::name('AdminGroup')->order('create_time asc')->select()->toArray();
return $group;
}
//读取指定权限分组详情
function get_admin_group_info($id)
{
$group = Db::name('AdminGroup')->where(['id' => $id])->find();
$group['rules'] = explode(',', $group['rules']);
$group['menus'] = explode(',', $group['menus']);
return $group;
}
//菜单父子关系排序,用于后台菜单
function get_admin_menus()
{
$admin = get_login_admin();
if (get_cache('menu' . $admin['id'])) {
$list = get_cache('menu' . $admin['id']);
} else {
$adminGroup = Db::name('PositionGroup')->where(['pid' => $admin['position_id']])->column('group_id');
$adminMenu = Db::name('AdminGroup')->where('id', 'in', $adminGroup)->column('menus');
$adminMenus = [];
foreach ($adminMenu as $k => $v) {
$v = explode(',', $v);
$adminMenus = array_merge($adminMenus, $v);
}
$menu = Db::name('AdminMenu')->where('id', 'in', $adminMenus)->order('sort asc')->select()->toArray();
$list = list_to_tree($menu);
Cache::tag('adminMenu')->set('menu' . $admin['id'], $list);
}
return $list;
}
//读取部门列表
function d_department()
{
$department = Db::name('Department')->select()->toArray();
return $department;
}
//获取某部门的子部门id
function d_department_son($did = 0,$is_self=1)
{
$department=d_department();
$department_list = get_data_node($department,$did);
$department_array = array_column($department_list,'id');
if($is_self == 1){
//包括自己在内
$department_array[]=$did;
}
return $department_array;
}
//读取关键字列表
function get_keywords()
{
$keywords = Db::name('Keywords')->where(['status' => 1])->order('create_time asc')->select();
return $keywords;
}
//读取公告分类列表
function get_note_cate()
{
$cate = Db::name('NoteCate')->order('create_time asc')->select()->toArray();
return $cate;
}
//读取知识分类列表
function get_article_cate()
{
$cate = Db::name('ArticleCate')->order('create_time asc')->select()->toArray();
return $cate;
}
/**
* 根据附件表的id返回url地址
* @param [type] $id [description]
*/
function get_file($id)
{
if ($id) {
$geturl = Db::name("file")->where(['id' => $id])->find();
if ($geturl['status'] == 1) {
//审核通过
//获取签名的URL
$url = $geturl['filepath'];
return $url;
} elseif ($geturl['status'] == 0) {
//待审核
return '/static/home/images/none_pic.jpg';
} else {
//不通过
return '/static/home/images/none_pic.jpg';
}
}
return false;
}
/**
* 节点权限判断
* @return bool
*/
function check_auth($rule,$uid){
$auth_list = Cache::get('RulesSrc' . $uid);
if (!in_array($rule, $auth_list)) {
return false;
} else {
return true;
}
}
/**
* 员工操作日志
* @param string $type 操作类型 login add edit view delete
* @param int $param_id 操作类型
* @param array $param 提交的参数
*/
function add_log($type, $param_id = '', $param = [])
{
$request = get_params();
switch ($type) {
case 'login':
$title = '登录';
break;
case 'upload':
$title = '上传';
break;
case 'add':
$title = '新增';
break;
case 'edit':
$title = '编辑';
break;
case 'view':
$title = '查看';
break;
case 'delete':
$title = '删除';
break;
case 'check':
$title = '审核';
break;
default:
$title = '未知';
break;
}
if ($type == 'login') {
$login_admin = Db::name('Admin')->where(array('id' => $param_id))->find();
} else {
$session_admin = get_config('app.session_admin');
$login_admin = \think\facade\Session::get($session_admin);
}
$data = [];
$data['uid'] = $login_admin['id'];
$data['name'] = $login_admin['name'];
$data['type'] = $type;
$data['param_id'] = $param_id;
$data['param'] = json_encode($param);
$data['module'] = \think\facade\App::initialize()->http->getName();
$data['controller'] = strtolower(app('request')->controller());
$data['function'] = app('request')->action();
$parameter = $data['module'] . '/' . $data['controller'] . '/' . $data['function'];
$data['rule_menu'] = $parameter;
$data['title'] = Db::name('AdminRule')->where(array('src' => $parameter))->value('title') ?? $title;
$content = $login_admin['name'] . '在' . date('Y-m-d H:i:s') . '执行了' . $data['title'] . '操作';
$data['content'] = $content;
$data['ip'] = app('request')->ip();
$data['create_time'] = time();
Db::name('AdminLog')->strict(false)->field(true)->insert($data);
}
/**
* 邮件发送
* @param $to 接收人
* @param string $subject 邮件标题
* @param string $content 邮件内容(html模板渲染后的内容)
* @throws Exception
* @throws phpmailerException
*/
function send_email($to, $subject = '', $content = '')
{
$mail = new PHPMailer\PHPMailer\PHPMailer();
$email_config = Db::name('config')
->where('name', 'email')
->find();
$config = unserialize($email_config['content']);
$mail->CharSet = 'UTF-8'; //设定邮件编码默认ISO-8859-1如果发中文此项必须设置否则乱码
$mail->isSMTP();
$mail->SMTPDebug = 0;
//调试输出格式
//$mail->Debugoutput = 'html';
//smtp服务器
$mail->Host = $config['smtp'];
//端口 - likely to be 25, 465 or 587
$mail->Port = $config['smtp_port'];
if($mail->Port == '465'){
$mail->SMTPSecure = 'ssl';// 使用安全协议
}
//Whether to use SMTP authentication
$mail->SMTPAuth = true;
//发送邮箱
$mail->Username = $config['smtp_user'];
//密码
$mail->Password = $config['smtp_pwd'];
//Set who the message is to be sent from
$mail->setFrom($config['email'], $config['from']);
//回复地址
//$mail->addReplyTo('replyto@example.com', 'First Last');
//接收邮件方
if (is_array($to)) {
foreach ($to as $v) {
$mail->addAddress($v);
}
} else {
$mail->addAddress($to);
}
$mail->isHTML(true);// send as HTML
//标题
$mail->Subject = $subject;
//HTML内容转换
$mail->msgHTML($content);
$status = $mail->send();
if ($status) {
return true;
} else {
// echo "Mailer Error: ".$mail->ErrorInfo;// 输出错误信息
// die;
return false;
}
}

View File

@ -0,0 +1,304 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\BaseController;
use app\home\model\Admin as AdminList;
use app\home\validate\AdminCheck;
use avatars\MDAvatars;
use Overtrue\Pinyin\Pinyin;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\View;
class Admin extends BaseController
{
public function index()
{
if (request()->isAjax()) {
$param = get_params();
$where = array();
if (!empty($param['keywords'])) {
$where[] = ['id|username|nickname|desc|mobile', 'like', '%' . $param['keywords'] . '%'];
}
$where[] = ['status', '>=', 0];
if (isset($param['status'])) {
$where[] = ['status', '=', $param['status']];
}
if (!empty($param['type'])) {
$where[] = ['type', '=', $param['type']];
}
if (!empty($param['did'])) {
$department_array = d_department_son($param['did']);
$where[] = ['did', 'in', $department_array];
}
$rows = empty($param['limit']) ? get_config(app . page_size) : $param['limit'];
$admin = AdminList::where($where)
->order('create_time asc')
->paginate($rows, false, ['query' => $param])
->each(function ($item, $key) {
$item->department = Db::name('Department')->where(['id' => $item->did])->value('title');
$item->position = Db::name('Position')->where(['id' => $item->position_id])->value('title');
$item->entry_time = empty($item->entry_time) ? '-' : date('Y-m-d', $item->entry_time);
$item->last_login_time = empty($item->last_login_time) ? '-' : date('Y-m-d H:i', $item->last_login_time);
$item->last_login_ip = empty($item->last_login_ip) ? '-' : $item->last_login_ip;
});
return table_assign(0, '', $admin);
} else {
return view();
}
}
//添加
public function add()
{
$id = empty(get_params('id')) ? 0 : get_params('id');
$department = set_recursion(d_department());
$position = Db::name('Position')->where('status', '>=', 0)->order('create_time asc')->select();
if ($id > 0) {
$detail = get_admin($id);
View::assign('detail', $detail);
} else {
//初始化密码
$reg_pwd = set_salt(6);
View::assign('reg_pwd', $reg_pwd);
}
View::assign('department', $department);
View::assign('position', $position);
View::assign('id', $id);
return view();
}
//生成头像
public function to_avatars($char)
{
$defaultData = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'S', 'Y', 'Z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖', '拾',
'一', '二', '三', '四', '五', '六', '七', '八', '九', '十');
if (isset($char)) {
$Char = $char;
} else {
$Char = $defaultData[mt_rand(0, count($defaultData) - 1)];
}
$OutputSize = min(512, empty($_GET['size']) ? 36 : intval($_GET['size']));
$Avatar = new MDAvatars($Char, 256, 1);
$avatar_name = '/avatars/avatar_256_' . set_salt(10) . time() . '.png';
$path = get_config('filesystem.disks.public.url') . $avatar_name;
$res = $Avatar->Save('.' . $path, 256);
$Avatar->Free();
return $path;
}
//提交添加
public function post_submit()
{
if (request()->isAjax()) {
$param = get_params();
$param['entry_time'] = strtotime($param['entry_time']);
$param['nickname'] = $param['name'];
$pinyin = new Pinyin();
$username = $pinyin->name($param['name'], PINYIN_UMLAUT_V);
$param['username'] = implode('', $username);
if (!empty($param['id']) && $param['id'] > 0) {
try {
validate(AdminCheck::class)->scene('edit')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
// 启动事务
Db::startTrans();
try {
$count = Db::name('Admin')->where([['username','=',$param['username']],['id','<>',$param['id']]])->count();
if ($count > 0) {
$param['username'] = implode('', $username) . $count;
}
Db::name('Admin')->where(['id' => $param['id']])->strict(false)->field(true)->update($param);
if (!isset($param['thumb']) || $param['thumb'] == '') {
$char = mb_substr($param['name'], 0, 1, 'utf-8');
Db::name('Admin')->where('id', $param['id'])->update(['thumb' => $this->to_avatars($char)]);
}
add_log('edit', $param['id'], $param);
//清除菜单\权限缓存
clear_cache('adminMenu');
clear_cache('adminRules');
// 提交事务
Db::commit();
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
return to_assign(1, '提交失败:' . $e->getMessage());
}
} else {
try {
validate(AdminCheck::class)->scene('add')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$count = Db::name('Admin')->where('username', $param['username'])->count();
if ($count > 0) {
$param['username'] = implode('', $username) . $count;
}
$param['salt'] = set_salt(20);
$param['pwd'] = set_password($param['reg_pwd'], $param['salt']);
// 启动事务
Db::startTrans();
try {
$uid = Db::name('Admin')->strict(false)->field(true)->insertGetId($param);
if (!isset($param['thumb']) || $param['thumb'] == '') {
$char = mb_substr($param['name'], 0, 1, 'utf-8');
Db::name('Admin')->where('id', $uid)->update(['thumb' => $this->to_avatars($char)]);
}
add_log('add', $uid, $param);
// 提交事务
Db::commit();
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
return to_assign(1, '提交失败:' . $e->getMessage());
}
}
return to_assign();
}
}
//查看
public function view()
{
$id = get_params('id');
$detail = get_admin($id);
//查询所有菜单和权限节点
$menu = get_admin_menu();
$rule = get_admin_rule();
//查询用户拥有的查单和节点
$user_groups = Db::name('PositionGroup')
->alias('a')
->join("AdminGroup g", "a.group_id=g.id", 'LEFT')
->where([['a.pid', '=', $detail["position_id"]], ['g.status', '=', 1]])
->select()
->toArray();
$groups = $user_groups ?: [];
$menus = [];
$rules = [];
foreach ($groups as $g) {
$menus = array_merge($menus, explode(',', trim($g['menus'], ',')));
$rules = array_merge($rules, explode(',', trim($g['rules'], ',')));
}
$menus = array_unique($menus);
$rules = array_unique($rules);
//数据嵌套
$role_menu = create_tree_list(0, $menu, $menus);
$role_rule = create_tree_list(0, $rule, $rules);
View::assign('role_menu', $role_menu);
View::assign('role_rule', $role_rule);
View::assign('detail', $detail);
add_log('view', get_params('id'));
return view();
}
//禁用,离职,恢复
public function set()
{
$type = get_params("type");
$ids = get_params("ids");
$idArray = explode(',', $ids);
$list = [];
foreach ($idArray as $key => $val) {
if ($val == 1) {
continue;
}
$list[] = [
'status' => $type,
'id' => $val,
'update_time' => time(),
];
}
foreach ($list as $key => $v) {
if (Db::name('Admin')->update($v) !== false) {
if ($type = 0) {
add_log('disable', $v['id']);
} else if ($type = 1) {
add_log('leave', $v['id']);
} else if ($type = 2) {
add_log('recovery', $v['id']);
}
}
}
return to_assign(0, '操作成功');
}
//重置密码
public function reset_psw()
{
$id = get_params("id");
$new_pwd = set_salt(6);
$salt = set_salt(20);
$list = [
'reg_pwd' => $new_pwd,
'salt' => $salt,
'pwd' => set_password($new_pwd, $salt),
'id' => $id,
'update_time' => time(),
];
if (Db::name('Admin')->update($list) !== false) {
add_log('reset_psw', $id);
return to_assign(0, '操作成功');
} else {
return to_assign(1, '操作失败');
}
}
//管理员操作日志
public function log()
{
if (request()->isAjax()) {
$param = get_params();
$where = array();
if (!empty($param['keywords'])) {
$where[] = ['nickname|rule_menu|param_id', 'like', '%' . $param['keywords'] . '%'];
}
if (!empty($param['title_cate'])) {
$where['title'] = $param['title_cate'];
}
if (!empty($param['rule_menu'])) {
$where['rule_menu'] = $param['rule_menu'];
}
$rows = empty($param['limit']) ? get_config(app . page_size) : $param['limit'];
$content = DB::name('AdminLog')
->field("id,uid,nickname,title,content,rule_menu,ip,param_id,param,FROM_UNIXTIME(create_time,'%Y-%m-%d %H:%i:%s') create_time")
->order('create_time desc')
->where($where)
->paginate($rows, false, ['query' => $param]);
$content->toArray();
foreach ($content as $k => $v) {
$data = $v;
$param_array = json_decode($v['param'], true);
$param_value = '';
foreach ($param_array as $key => $value) {
if (is_array($value)) {
$value = implode(',', $value);
}
$param_value .= $key . ':' . $value . '&nbsp;&nbsp;|&nbsp;&nbsp;';
}
$data['param'] = $param_value;
$content->offsetSet($k, $data);
}
return table_assign(0, '', $content);
} else {
return view();
}
}
}

339
app/home/controller/Api.php Normal file
View File

@ -0,0 +1,339 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\BaseController;
use app\home\model\AdminLog;
use app\home\validate\AdminCheck;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\Session;
class Api extends BaseController
{
//上传文件
public function upload()
{
$param = get_params();
if (request()->file('file')) {
$file = request()->file('file');
} else {
return to_assign(1, '没有选择上传文件');
}
// dump($file);die;
// 获取上传文件的hash散列值
$sha1 = $file->hash('sha1');
$md5 = $file->hash('md5');
$rule = [
'image' => 'jpg,png,jpeg,gif',
'doc' => 'doc,docx,ppt,pptx,xls,xlsx,pdf',
'file' => 'zip,gz,7z,rar,tar',
];
$fileExt = $rule['image'] . ',' . $rule['doc'] . ',' . $rule['file'];
//1M=1024*1024=1048576字节
$fileSize = 2 * 1024 * 1024;
if (isset($param['type']) && $param['type']) {
$fileExt = $rule[$param['type']];
}
if (isset($param['size']) && $param['size']) {
$fileSize = $param['size'];
}
$validate = \think\facade\Validate::rule([
'image' => 'require|fileSize:' . $fileSize . '|fileExt:' . $fileExt,
]);
$file_check['image'] = $file;
if (!$validate->check($file_check)) {
return to_assign(1, $validate->getError());
}
// 日期前綴
$dataPath = date('Ym');
$use = 'thumb';
$filename = \think\facade\Filesystem::disk('public')->putFile($dataPath, $file, function () use ($md5) {
return $md5;
});
if ($filename) {
//写入到附件表
$data = [];
$path = get_config('filesystem.disks.public.url');
$data['filepath'] = $path . '/' . $filename;
$data['name'] = $file->getOriginalName();
$data['mimetype'] = $file->getOriginalMime();
$data['fileext'] = $file->extension();
$data['filesize'] = $file->getSize();
$data['filename'] = $filename;
$data['sha1'] = $sha1;
$data['md5'] = $md5;
$data['module'] = \think\facade\App::initialize()->http->getName();
$data['action'] = app('request')->action();
$data['uploadip'] = app('request')->ip();
$data['create_time'] = time();
$data['user_id'] = $this->uid;
if ($data['module'] = 'admin') {
//通过后台上传的文件直接审核通过
$data['status'] = 1;
$data['admin_id'] = $data['user_id'];
$data['audit_time'] = time();
}
$data['use'] = request()->has('use') ? request()->param('use') : $use; //附件用处
$res['id'] = Db::name('file')->insertGetId($data);
$res['filepath'] = $data['filepath'];
$res['name'] = $data['name'];
$res['filename'] = $data['filename'];
add_log('upload', $data['user_id'], $data);
return to_assign(0, '上传成功', $res);
} else {
return to_assign(1, '上传失败,请重试');
}
}
//清空缓存
public function cache_clear()
{
\think\facade\Cache::clear();
return to_assign(0, '系统缓存已清空');
}
//获取权限树所需的节点列表
public function get_rule()
{
$rule = get_admin_rule();
$group = [];
if (!empty(get_params('id'))) {
$group = get_admin_group_info(get_params('id'))['rules'];
}
$list = create_tree_list(0, $rule, $group);
return to_assign(0, '', $list);
}
//获取菜单树列表
public function get_menu()
{
$rule = get_admin_menu();
$group = [];
if (!empty(get_params('id'))) {
$group = get_admin_group_info(get_params('id'))['menus'];
}
$list = create_tree_list(0, $rule, $group);
return to_assign(0, '', $list);
}
//获取关键字
public function get_keyword_cate()
{
$keyword = get_keywords();
return to_assign(0, '', $keyword);
}
// 测试邮件发送
public function email_test()
{
$sender = get_params('email');
//检查是否邮箱格式
if (!is_email($sender)) {
return to_assign(1, '测试邮箱码格式有误');
}
$email_config = \think\facade\Db::name('config')->where('name', 'email')->find();
$config = unserialize($email_config['content']);
$content = $config['template'];
//所有项目必须填写
if (empty($config['smtp']) || empty($config['smtp_port']) || empty($config['smtp_user']) || empty($config['smtp_pwd'])) {
return to_assign(1, '请完善邮件配置信息!');
}
$send = send_email($sender, '测试邮件', $content);
if ($send) {
return to_assign(0, '邮件发送成功!');
} else {
return to_assign(1, '邮件发送失败!');
}
}
//获取部门节点列表
public function get_department_tree()
{
$department = d_department();
$list = get_tree($department, 0,2);
$data['trees'] = $list;
return json($data);
}
//获取子部门所有员工
public function get_employee($did=0)
{
$did=get_params('did');
$department=d_department_son($did);
$employee = Db::name('admin')
->field('a.id,a.did,a.position_id,a.mobile,a.name,a.nickname,a.sex,a.status,a.thumb,a.username,d.title as department')
->alias('a')
->join('Department d', 'a.did = d.id')
->where(['a.status'=>1])
->where('a.did',"in",$department)
->select();
return to_assign(0,'',$employee);
}
//获取角色列表
public function get_position()
{
$position = Db::name('Position')->field('id,title as name')->where([['status','=',1],['id','>',1]])->select();
return to_assign(0,'',$position);
}
//首页公告
public function get_note_list()
{
$list = Db::name('Note')
->field('a.*,c.title as cate_title')
->alias('a')
->join('note_cate c', 'a.cate_id = c.id')
->where(['a.status' => 1])
->order('a.id desc')
->limit(10)
->select()->toArray();
foreach ($list as $key => $val) {
$list[$key]['create_time'] = date('Y-m-d :H:i', $val['create_time']);
}
$res['data'] = $list;
return table_assign(0, '', $res);
}
//首页文章
public function get_article_list()
{
$list = Db::name('Article')
->field('a.*,c.title as cate_title')
->alias('a')
->join('article_cate c', 'a.article_cate_id = c.id')
->where(['a.status' => 1])
->order('a.id desc')
->limit(10)
->select()->toArray();
foreach ($list as $key => $val) {
$list[$key]['create_time'] = date('Y-m-d :H:i', $val['create_time']);
}
$res['data'] = $list;
return table_assign(0, '', $res);
}
//修改个人信息
public function edit_personal()
{
return view('admin/edit_personal', [
'admin' => get_admin($this->uid),
]);
}
//保存个人信息修改
public function personal_submit()
{
if (request()->isAjax()) {
$param = get_params();
try {
validate(AdminCheck::class)->scene('editPersonal')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
unset($param['username']);
$uid = $this->uid;
Db::name('Admin')->where(['id' => $uid])->strict(false)->field(true)->update($param);
$session_admin = get_config('app.session_admin');
Session::set($session_admin, Db::name('admin')->find($uid));
return to_assign();
}
}
//修改密码
public function edit_password()
{
return view('admin/edit_password', [
'admin' => get_admin($this->uid),
]);
}
//保存密码修改
public function password_submit()
{
if (request()->isAjax()) {
$param = get_params();
try {
validate(AdminCheck::class)->scene('editpwd')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$admin = get_admin($this->uid);
if (set_password($param['old_pwd'], $admin['salt']) !== $admin['pwd']) {
return to_assign(1, '旧密码不正确!');
}
unset($param['username']);
$param['salt'] = set_salt(20);
$param['pwd'] = set_password($param['pwd'], $param['salt']);
Db::name('Admin')->where(['id' => $admin['id'],
])->strict(false)->field(true)->update($param);
$session_admin = get_config('app.session_admin');
Session::set($session_admin, Db::name('admin')->find($admin['id']));
return to_assign();
}
}
//删除
public function del_expense_interfix()
{
$id = get_params("id");
$admin_id = Db::name('ExpenseInterfix')->where('id',$id)->value('admin_id');
if($admin_id == $this->uid){
if (Db::name('ExpenseInterfix')->where('id',$id)->delete() !== false) {
return to_assign(0, "删除成功");
} else {
return to_assign(1, "删除失败");
}
}else{
return to_assign(1, "您没权限删除该报销数据");
}
}
//系统操作日志
public function log_list()
{
return view('admin/log_list');
}
//获取系统操作日志
public function get_log_list()
{
$param = get_params();
$log = new AdminLog();
$content = $log->get_log_list($param);
return table_assign(0, '', $content);
}
//获取访问记录
public function get_view_data()
{
$param = get_params();
$first_time = time();
$second_time = $first_time - 86400;
$three_time = $first_time - 86400*365;
$begin_first = strtotime(date('Y-m-d', $first_time) . " 00:00:00");
$end_first = strtotime(date('Y-m-d', $first_time) . " 23:59:59");
$begin_second = strtotime(date('Y-m-d', $second_time) . " 00:00:00");
$end_second = strtotime(date('Y-m-d', $second_time) . " 23:59:59");
$begin_three = strtotime(date('Y-m-d', $three_time) . " 00:00:00");
$data_first = Db::name('AdminLog')->field('create_time')->whereBetween('create_time', "$begin_first,$end_first")->select();
$data_second = Db::name('AdminLog')->field('create_time')->whereBetween('create_time', "$begin_second,$end_second")->select();
$data_three = Db::name('AdminLog')->field('create_time')->whereBetween('create_time', "$begin_three,$end_first")->select();
return to_assign(0, '', ['data_first' => hour_document($data_first), 'data_second' => hour_document($data_second), 'data_three'=>date_document($data_three)]);
}
}

View File

@ -0,0 +1,238 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\BaseController;
use app\home\model\Article as ArticleList;
use app\home\model\ArticleCate;
use app\home\model\Keywords;
use app\home\validate\ArticleCateCheck;
use app\home\validate\ArticleCheck;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\View;
class Article extends BaseController
{
public function cate()
{
if (request()->isAjax()) {
$cate = Db::name('ArticleCate')->order('create_time asc')->select();
return to_assign(0, '', $cate);
}
else{
return view();
}
}
//文章分类添加
public function cate_add()
{
return view('', ['pid' => get_params('pid')]);
}
//提交保存文章分类
public function cate_post_submit()
{
if (request()->isAjax()) {
$param = get_params();
if (!empty($param['id']) && $param['id'] > 0) {
$data[$param['field']] = $param['value'];
$data['id'] = $param['id'];
$data['update_time'] = time();
if(!empty($data['title'])){
try {
validate(ArticleCateCheck::class)->scene('edit')->check($data);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
}
$res = ArticleCate::strict(false)->field(true)->update($data);
if ($res) {
add_log('edit', $data['id'], $data);
}
return to_assign();
} else {
try {
validate(ArticleCateCheck::class)->scene('add')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$param['create_time'] = time();
$insertId = ArticleCate::strict(false)->field(true)->insertGetId($param);
if ($insertId) {
add_log('add', $insertId, $param);
}
return to_assign();
}
}
}
//删除文章分配
public function cate_delete()
{
$id = get_params("id");
$cate_count = Db::name('ArticleCate')->where(["pid" => $id])->count();
if ($cate_count > 0) {
return to_assign(1, "该分类下还有子分类,无法删除");
}
$content_count = Db::name('Article')->where(["article_cate_id" => $id])->count();
if ($content_count > 0) {
return to_assign(1, "该分类下还有文章,无法删除");
}
if (Db::name('ArticleCate')->delete($id) !== false) {
add_log('delete', $id);
return to_assign(0, "删除分类成功");
} else {
return to_assign(1, "删除失败");
}
}
public function index()
{
if (request()->isAjax()) {
$param = get_params();
$where = array();
if (!empty($param['keywords'])) {
$where[] = ['a.id|a.title|a.keywords|a.desc|a.content|w.title', 'like', '%' . $param['keywords'] . '%'];
}
if (!empty($param['article_cate_id'])) {
$where[] = ['a.article_cate_id', '=', $param['article_cate_id']];
}
$where[] = ['a.status', '>=', 0];
$rows = empty($param['limit']) ? get_config(app . page_size) : $param['limit'];
$content = ArticleList::where($where)
->field('a.*,w.id as cate_id,a.id as id,w.title as cate_title,a.title as title')
->alias('a')
->join('article_cate w', 'a.article_cate_id = w.id')
->order('a.create_time desc')
->paginate($rows, false, ['query' => $param]);
return table_assign(0, '', $content);
}
else{
return view();
}
}
//文章添加&&编辑
public function add()
{
$id = empty(get_params('id')) ? 0 : get_params('id');
View::assign('id', $id);
if ($id > 0) {
$article = (new ArticleList())->detail($id);
View::assign('article', $article);
return view('edit');
}
return view();
}
//文章内容提交保存
public function post_submit()
{
if (request()->isAjax()) {
$param = get_params();
$DbRes=false;
if (!empty($param['id']) && $param['id'] > 0) {
try {
validate(ArticleCheck::class)->scene('edit')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$param['update_time'] = time();
Db::startTrans();
try {
$res = ArticleList::strict(false)->field(true)->update($param);
$aid = $param['id'];
if ($res) {
//关联关键字
if (isset($param['keyword_names']) && $param['keyword_names']) {
Db::name('ArticleKeywords')->where(['aid'=>$aid])->delete();
$keywordArray = explode(',', $param['keyword_names']);
$res_keyword = (new ArticleList())->insertKeyword($keywordArray,$aid);
}
else{
$res_keyword == true;
}
if($res_keyword!== false){
add_log('edit', $param['id'], $param);
Db::commit();
$DbRes=true;
}
} else {
Db::rollback();
}
}
catch (\Exception $e) { ##这里参数不能删除($e错误信息)
Db::rollback();
}
} else {
try {
validate(ArticleCheck::class)->scene('add')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$param['create_time'] = time();
Db::startTrans();
try {
if(empty($param['desc'])){
$param['desc'] = get_desc_content($param['content'], 100);
}
$aid = ArticleList::strict(false)->field(true)->insertGetId($param);
if ($aid) {
//关联关键字
if (isset($param['keyword_names']) && $param['keyword_names']) {
$keywordArray = explode(',', $param['keyword_names']);
$res_keyword = (new ArticleList())->insertKeyword($keywordArray,$aid);
}
else{
$res_keyword == true;
}
if($res_keyword!== false){
add_log('add', $aid, $param);
Db::commit();
$DbRes=true;
}
} else {
Db::rollback();
}
}
catch (\Exception $e) { ##这里参数不能删除($e错误信息)
Db::rollback();
}
}
if($DbRes){
return to_assign();
}
else{
return to_assign(1,'操作失败');
}
}
}
//删除文章
public function delete()
{
$id = get_params("id");
$data['status'] = '-1';
$data['id'] = $id;
$data['update_time'] = time();
if (Db::name('Article')->update($data) !== false) {
add_log('delete', $id);
return to_assign(0, "删除成功");
} else {
return to_assign(1, "删除失败");
}
}
}

View File

@ -0,0 +1,121 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\BaseController;
use app\home\validate\ConfCheck;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\View;
class Conf extends BaseController
{
public function index()
{
if (request()->isAjax()) {
$param = get_params();
$where = array();
$where[] = ['status', '>=', 0];
$rows = empty($param['limit']) ? get_config(app . page_size) : $param['limit'];
$content = Db::name('Config')
->where($where)
->paginate($rows, false, ['query' => $param]);
return table_assign(0, '', $content);
} else {
return view();
}
}
//添加
public function add()
{
$id = empty(get_params('id')) ? 0 : get_params('id');
if ($id > 0) {
$config = Db::name('Config')->where(['id' => $id])->find();
View::assign('config', $config);
}
View::assign('id', $id);
return view();
}
//提交添加
public function post_submit()
{
if (request()->isAjax()) {
$param = get_params();
try {
validate(ConfCheck::class)->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
if (!empty($param['id']) && $param['id'] > 0) {
$param['update_time'] = time();
$res = Db::name('config')->strict(false)->field(true)->update($param);
if ($res) {
add_log('edit', $param['id'], $param);
}
return to_assign();
} else {
$param['create_time'] = time();
$insertId = Db::name('Config')->strict(false)->field(true)->insertGetId($param);
if ($insertId) {
add_log('add', $insertId, $param);
}
return to_assign();
}
}
}
//删除
public function delete()
{
$id = get_params("id");
$data['status'] = '-1';
$data['id'] = $id;
$data['update_time'] = time();
if (Db::name('Config')->update($data) !== false) {
add_log('delete', $id, $data);
return to_assign(0, "删除成功");
} else {
return to_assign(1, "删除失败");
}
}
//编辑配置
public function edit()
{
$id = empty(get_params('id')) ? 0 : get_params('id');
$conf = Db::name('Config')->where('id', $id)->find();
$config = [];
if ($conf['content']) {
$config = unserialize($conf['content']);
}
return view($conf['name'], ['id' => $id, 'config' => $config]);
}
//提交添加
public function conf_submit()
{
if (request()->isAjax()) {
$param = get_params();
$data['content'] = serialize($param);
$data['update_time'] = time();
$data['id'] = $param['id'];
$res = Db::name('Config')->strict(false)->field(true)->update($data);
$conf = Db::name('Config')->where('id', $param['id'])->find();
clear_cache('system_config' . $conf['name']);
if ($res) {
add_log('edit', $param['id'], $param);
}
return to_assign();
}
}
}

View File

@ -0,0 +1,181 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\BaseController;
use backup\Backup;
use think\facade\Db;
use think\facade\View;
class Database extends BaseController
{
protected $db = '', $datadir;
public function initialize()
{
parent::initialize();
$this->config = array(
'path' => './backup/', // 数据库备份路径
'part' => 20971520, // 数据库备份卷大小
'compress' => 0, // 数据库备份文件是否启用压缩 0不压缩 1 压缩
'level' => 9, // 数据库备份文件压缩级别 1普通 4 一般 9最高
);
$this->db = new Backup($this->config);
}
// 数据列表
public function database()
{
if (request()->isAjax()) {
// 数据信息
$list = $this->db->dataList();
// 计算总大小
$total = 0;
foreach ($list as $k => $v) {
$total += $v['data_length'];
$list[$k]['data_size'] = $v['data_length'];
$list[$k]['data_length'] = format_bytes($v['data_length']);
}
// 提示信息
$dataTips = '数据库中共有<strong> ' . count($list) . '</strong> 张表,共计 <strong>' . format_bytes($total) . '</strong>大小。';
$data['data'] = $list;
return table_assign(0, $dataTips, $data);
}
return view();
}
// 备份
public function backup()
{
$tables = get_params('id');
if (!empty($tables)) {
$tables = explode(',', $tables);
foreach ($tables as $table) {
$this->db->setFile()->backup($table, 0);
}
add_log('add');
return to_assign(0, '备份成功!');
} else {
return to_assign(1, '请选择要备份的表!');
}
}
// 优化
public function optimize()
{
$tables = get_params('id');
if (empty($tables)) {
return to_assign(0, '请选择要优化的表!');
}
$tables = explode(',', $tables);
if ($this->db->optimize($tables)) {
add_log('edit');
return to_assign(0, '数据表优化成功!');
} else {
return to_assign(1, '数据表优化出错请重试!');
}
}
// 修复
public function repair()
{
$tables = get_params('id');
if (empty($tables)) {
return to_assign(1, '请选择要修复的表!');
}
$tables = explode(',', $tables);
if ($this->db->repair($tables)) {
add_log('edit');
return to_assign(0, '数据表修复成功!');
} else {
return to_assign(1, '数据表修复出错请重试!');
}
}
// 还原列表
public function backuplist()
{
// 数据信息
$list = $this->db->fileList();
$listNew = [];
$indx = 0;
foreach ($list as $k => $v) {
$listNew[$indx]['time'] = $k;
$listNew[$indx]['data'][] = $v;
$indx++;
// $listNew[$k]['list'] = $list[$k];
}
$list = $listNew;
array_multisort(array_column($list, 'time'), SORT_DESC, $list);
return view('', ['list' => $list]);
}
// 执行还原数据库操作
public function import(int $id)
{
$list = $this->db->getFile('timeverif', $id);
$this->db->setFile($list)->import(1);
add_log('save');
return to_assign(0, '还原成功!');
}
// 下载
public function downfile(string $name)
{
$file_name = $name; //得到文件名
header("Content-type:text/html;charset=utf-8");
$file_name = iconv("utf-8", "gb2312", $file_name); // 转换编码
$file_sub_path = $this->config['path']; //确保文件在这个路径下面,换成你文件所在的路径
$file_path = $file_sub_path . $file_name;
# 将反斜杠 替换成正斜杠
$file_path = str_replace('\\', '/', $file_path);
if (!file_exists($file_path)) {
$this->error($file_path);exit; //如果提示这个错误,很可能你的路径不对,可以打印$file_sub_path查看
}
$fp = fopen($file_path, "r"); // 以可读的方式打开这个文件
# 如果出现图片无法打开,可以在这个位置添加函数
ob_clean(); # 清空擦掉,输出缓冲区。
$file_size = filesize($file_path);
//下载文件需要用到的头
Header("Content-type: application/octet-stream");
Header("Accept-Ranges: bytes");
Header("Accept-Length:" . $file_size);
Header("Content-Disposition: attachment; filename = " . $file_name);
$buffer = 1024000;
$file_count = 0;
while (!feof($fp) && $file_count < $file_size) {
$file_con = fread($fp, $buffer);
$file_count += $buffer;
echo $file_con;
}
fclose($fp); //关闭这个打开的文件
}
// 删除sql文件
public function del(string $id)
{
if (request()->isAjax()) {
if (strpos($id, ',') !== false) {
$idArr = explode(',', $id);
foreach ($idArr as $k => $v) {
$this->db->delFile($v);
}
add_log('delete');
return to_assign(0, "删除成功!");
}
if ($this->db->delFile($id)) {
add_log('delete');
return to_assign(0, "删除成功!");
} else {
return to_assign(1, "备份文件删除失败,请检查文件权限!");
}
}
}
}

View File

@ -0,0 +1,130 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\BaseController;
use app\home\validate\DepartmentCheck;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\View;
class Department extends BaseController
{
public function index()
{
if (request()->isAjax()) {
$list = Db::name('Department')->order('create_time asc')->select();
return to_assign(0, '', $list);
} else {
return view();
}
}
//添加部门
public function add()
{
$id = empty(get_params('id')) ? 0 : get_params('id');
$pid = empty(get_params('pid')) ? 0 : get_params('pid');
$department = set_recursion(d_department());
if($id > 0) {
$detail = Db::name('Department')->where(['id' => $id])->find();
View::assign('detail', $detail);
}
View::assign('department', $department);
View::assign('pid', $pid);
View::assign('id', $id);
return view();
}
public function post_submit()
{
if (request()->isAjax()) {
$param = get_params();
if ($param['id'] > 0) {
try {
validate(DepartmentCheck::class)->scene('edit')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$param['update_time'] = time();
Db::name('Department')->strict(false)->field(true)->update($param);
add_log('edit', $param['id'], $param);
} else {
try {
validate(DepartmentCheck::class)->scene('add')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$did = Db::name('Department')->strict(false)->field(true)->insertGetId($param);
add_log('add', $did, $param);
}
return to_assign();
}
}
//提交添加
public function save()
{
if($this->request->isPost()){
$param = vae_get_param();
if($param['id']>0){
$result = $this->validate($param, 'app\home\validate\Department.edit');
if ($result !== true) {
return vae_assign(0,$result);
} else {
$param['update_time'] = time();
$department_array=[];
$department_cate = vae_get_department();
$department_ids=get_data_node($department_cate,$param['id']);
$department_array = array_column($department_ids, 'id');
$department_array[]=$param['id'];
if (in_array($param['pid'], $department_array)){
return vae_assign(0,'上级部门不能是该部门本身或其下属部门');
}
else{
$res = \think\loader::model('Department')->strict(false)->field(true)->update($param);
if($res) add_log('edit',$param['id'],$param);
}
}
}else{
$result = $this->validate($param, 'app\home\validate\Department.add');
if ($result !== true) {
return vae_assign(0,$result);
} else {
$param['create_time'] = time();
$mid = \think\loader::model('Department')->strict(false)->field(true)->insertGetId($param);
}
}
return vae_assign();
}
}
//删除
public function delete()
{
$id = get_params("id");
$count = Db::name('Department')->where(["pid" => $id,'status'=>['egt',0]])->count();
$users = Db::name('Admin')->where(["did" => $id,'status'=>['egt',0]])->count();
if ($count > 0) {
return to_assign(1,"该部门下还有子部门,无法删除");
}
if ($users > 0) {
return to_assign(1,"该部门下还有员工,无法删除");
}
if (Db::name('Department')->delete($id) !== false) {
add_log('delete',$id);
return to_assign(0,"删除部门成功");
} else {
return to_assign(1,"删除失败");
}
}
}

View File

@ -0,0 +1,46 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\BaseController;
use think\facade\Db;
use think\facade\View;
class Index extends BaseController
{
public function index()
{
$menu = get_admin_menus();
View::assign('menu', $menu);
return View();
}
public function main()
{
$install = false;
if (file_exists(CMS_ROOT . 'app/install')) {
$install = true;
}
$adminCount = Db::name('Admin')->where('status', '1')->count();
$articleCount = Db::name('Article')->where('status', '1')->count();
$scheduleCount = Db::name('Schedule')->where('status', '1')->count();
View::assign('install', $install);
View::assign('adminCount', $adminCount);
View::assign('articleCount', $articleCount);
View::assign('scheduleCount', $scheduleCount);
return View();
}
public function errorShow()
{
echo '错误';
}
}

View File

@ -0,0 +1,102 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\BaseController;
use app\home\validate\KeywordsCheck;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\View;
class Keywords extends BaseController
{
public function index()
{
if (request()->isAjax()) {
$param = get_params();
$where = array();
if (!empty($param['keywords'])) {
$where[] = ['title', 'like', '%' . $param['keywords'] . '%'];
}
$where[] = ['status', '>=', 0];
$rows = empty($param['limit']) ? get_config(app . page_size) : $param['limit'];
$content = Db::name('Keywords')
->order('create_time desc')
->where($where)
->paginate($rows, false, ['query' => $param]);
return table_assign(0, '', $content);
} else {
return view();
}
}
//添加
public function add()
{
$id = empty(get_params('id')) ? 0 : get_params('id');
if ($id > 0) {
$keywords = Db::name('Keywords')->where(['id' => $id])->find();
View::assign('keywords', $keywords);
}
View::assign('id', $id);
return view();
}
//提交添加
public function post_submit()
{
if (request()->isAjax()) {
$param = get_params();
if (!empty($param['id']) && $param['id'] > 0) {
try {
validate(KeywordsCheck::class)->scene('edit')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$param['update_time'] = time();
$res = Db::name('Keywords')->strict(false)->field(true)->update($param);
if ($res) {
add_log('edit', $param['id'], $param);
}
return to_assign();
} else {
try {
validate(KeywordsCheck::class)->scene('add')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$param['create_time'] = time();
$insertId = Db::name('Keywords')->strict(false)->field(true)->insertGetId($param);
if ($insertId) {
add_log('add', $insertId, $param);
}
return to_assign();
}
}
}
//删除
public function delete()
{
$id = get_params("id");
$data['status'] = '-1';
$data['id'] = $id;
$data['update_time'] = time();
if (Db::name('Keywords')->update($data) !== false) {
add_log('delete', $id, $data);
return to_assign(0, "删除成功");
} else {
return to_assign(1, "删除失败");
}
}
}

View File

@ -0,0 +1,74 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\validate\UserCheck;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\Session;
class Login
{
//登录
public function index()
{
return View();
}
//错误页面
public function errorshow()
{
return View();
}
//提交登录
public function login_submit()
{
$param = get_params();
try {
validate(UserCheck::class)->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$admin = Db::name('Admin')->where(['username' => $param['username']])->find();
if (empty($admin)) {
return to_assign(1, '用户名或密码错误');
}
$param['pwd'] = set_password($param['password'], $admin['salt']);
if ($admin['pwd'] !== $param['pwd']) {
return to_assign(1, '用户名或密码错误');
}
if ($admin['status'] == 0) {
return to_assign(1, '该用户禁止登录,请于系统所有者联系');
}
$data = [
'last_login_time' => time(),
'last_login_ip' => request()->ip(),
'login_num' => $admin['login_num'] + 1,
];
Db::name('admin')->where(['id' => $admin['id']])->update($data);
$session_admin = get_config('app.session_admin');
Session::set($session_admin, $admin);
$token = make_token();
set_cache($token, $admin, 7200);
$admin['token'] = $token;
add_log('login', $admin['id'], $data);
return to_assign(0, '登录成功', ['uid' => $admin['id']]);
}
//退出登录
public function login_out()
{
$session_admin = get_config('app.session_admin');
Session::delete($session_admin);
//redirect('/')->send();
return to_assign(0, "退出成功");
}
}

View File

@ -0,0 +1,541 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\BaseController;
use app\home\model\Mail as MailList;
use think\facade\Db;
use think\facade\View;
class Mail extends BaseController
{
//收件箱
public function inbox()
{
if (request()->isAjax()) {
$param = get_params();
$param['status'] = 1;
$map = [];
if (!empty($param['keywords'])) {
$map[] = ['name', 'like', '%' . $param['keywords'] . '%'];
}
if (!empty($param['is_read'])) {
$map[] = ['is_read', '=', $param['is_read']];
}
if (!empty($param['mail_type'])) {
$map[] = ['mail_type', '=', $param['mail_type']];
}
$map[] = ['to_uid', '=', $this->uid];
$map[] = ['status', '=', $param['status']];
//按时间检索
$start_time = isset($param['start_time']) ? strtotime(urldecode($param['start_time'])) : 0;
$end_time = isset($param['end_time']) ? strtotime(urldecode($param['end_time'])) : 0;
if ($start_time > 0 && $end_time > 0) {
$map[] = ['send_time', 'between', "$start_time,$end_time"];
}
$list = $this->getList($map, $param);
return table_assign(0, '', $list);
} else {
return view();
}
}
//发件箱
public function sendbox()
{
if (request()->isAjax()) {
$param = get_params();
$param['status'] = 1;
$map = [];
if (!empty($param['keywords'])) {
$map[] = ['name', 'like', '%' . $param['keywords'] . '%'];
}
$map[] = ['from_uid', '=', $this->uid];
$map[] = ['to_uid', '=', 0];
$map[] = ['status', '=', $param['status']];
$map[] = ['is_draft', '=', 1];
//按时间检索
$start_time = isset($param['start_time']) ? strtotime(urldecode($param['start_time'])) : 0;
$end_time = isset($param['end_time']) ? strtotime(urldecode($param['end_time'])) : 0;
if ($start_time > 0 && $end_time > 0) {
$map[] = ['send_time', 'between', "$start_time,$end_time"];
}
$list = $this->getList($map, $param);
return table_assign(0, '', $list);
} else {
return view();
}
}
//草稿箱
public function draft()
{
if (request()->isAjax()) {
$param = get_params();
$param['status'] = 2;
$map = [];
if (!empty($param['keywords'])) {
$map[] = ['name', 'like', '%' . $param['keywords'] . '%'];
}
$map[] = ['from_uid', '=', $this->uid];
$map[] = ['status', '=', 1];
$map[] = ['is_draft', '=', $param['status']];
//按时间检索
$start_time = isset($param['start_time']) ? strtotime(urldecode($param['start_time'])) : 0;
$end_time = isset($param['end_time']) ? strtotime(urldecode($param['end_time'])) : 0;
if ($start_time > 0 && $end_time > 0) {
$map[] = ['send_time', 'between', "$start_time,$end_time"];
}
$list = $this->getList($map, $param);
return table_assign(0, '', $list);
} else {
return view();
}
}
//垃圾箱
public function rubbish()
{
if (request()->isAjax()) {
$param = get_params();
$param['status'] = 0;
$map = [];
if (!empty($param['keywords'])) {
$map[] = ['name', 'like', '%' . $param['keywords'] . '%'];
}
$map[] = ['status', '=', $param['status']];
//按时间检索
$start_time = isset($param['start_time']) ? strtotime(urldecode($param['start_time'])) : 0;
$end_time = isset($param['end_time']) ? strtotime(urldecode($param['end_time'])) : 0;
if ($start_time > 0 && $end_time > 0) {
$map[] = ['send_time', 'between', "$start_time,$end_time"];
}
$list = $this->getList($map, $param);
return table_assign(0, '', $list);
} else {
return view();
}
}
//获取消息列表
public function getList($map = [], $param = [])
{
$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
//垃圾箱列表特殊处理
if ($param['status'] == 0) {
$where = [['from_uid', '=', $this->uid], ['to_uid', '=', $this->uid]];
$mail = MailList::where($map)
->where(function ($query) use ($where) {$query->whereOr($where);})
->order('create_time desc')
->paginate($rows, false, ['query' => $param])
->each(function ($item, $key) {
$item->send_time = empty($item->send_time) ? '-' : date('Y-m-d H:i:s', $item->send_time);
$item->from_name = Db::name('Admin')->where(['id' => $item->from_uid])->value('nickname');
$item->to_name = Db::name('Admin')->where(['id' => $item->to_uid])->value('nickname');
$item->type_title = MailList::$Type[$item->type];
$item->is_read_title = MailList::$Read[$item->is_read];
$item->mail_type_title = MailList::$MailType[$item->mail_type];
$item->delete_source_title = MailList::$Source[$item->delete_source];
$item->files = Db::name('MailFileInterfix')->where(['mid' => $item->id, 'status' => 1])->count();
});
return $mail;
} else {
$mail = MailList::where($map)
->order('create_time desc')
->paginate($rows, false, ['query' => $param])
->each(function ($item, $key) {
$item->send_time = empty($item->send_time) ? '-' : date('Y-m-d H:i:s', $item->send_time);
$item->from_name = Db::name('Admin')->where(['id' => $item->from_uid])->value('nickname');
$item->to_name = Db::name('Admin')->where(['id' => $item->to_uid])->value('nickname');
$item->type_title = MailList::$Type[$item->type];
$item->is_read_title = MailList::$Read[$item->is_read];
$item->mail_type_title = MailList::$MailType[$item->mail_type];
$item->files = Db::name('MailFileInterfix')->where(['mid' => $item->id, 'status' => 1])->count();
});
return $mail;
}
}
//新增信息
public function add()
{
$id = empty(get_params('id')) ? 0 : get_params('id');
$fid = 0;
if ($id > 0) {
$detail = Db::name('Mail')->where(['id' => $id, 'from_uid' => $this->uid])->find();
if (empty($detail)) {
$this->error('该信息不存在');
}
$fid = $detail['fid'];
$person_name = [];
if ($detail['type'] == 0) { //人员
$users = Db::name('Admin')->where('status', 1)->where('id', 'in', $detail['type_user'])->select()->toArray();
$person_name = array_column($users, 'name');
} elseif ($detail['type'] == 1) { //部门
$departments = Db::name('Department')->where('id', 'in', $detail['type_user'])->select()->toArray();
$person_name = array_column($departments, 'title');
} elseif ($detail['type'] == 2) { //角色
$group_uid = Db::name('PositionGroup')->where('group_id', 'in', $detail['type_user'])->select()->toArray();
$pids = array_column($group_uid, 'pid');
$positions = Db::name('Position')->where('id', 'in', $pids)->select()->toArray();
$person_name = array_column($positions, 'title');
}
$detail['person_name'] = implode(",", $person_name);
$file_array = Db::name('MailFileInterfix')
->field('mf.id,mf.mid,mf.file_id,f.name,f.filesize,f.filepath')
->alias('mf')
->join('file f', 'mf.file_id = f.id', 'LEFT')
->order('mf.create_time desc')
->where(array('mf.mid' => $id, 'mf.status' => 1))
->select()->toArray();
$interfix_ids = array_column($file_array, 'file_id');
$detail['file_ids'] = implode(",", $interfix_ids);
//引用消息的附件
if($detail['fid']>0){
$detail['from_content'] = Db::name('Mail')->where(['id' => $detail['fid']])->value('content');
$from_file_array = Db::name('MailFileInterfix')
->field('mf.id,mf.mid,mf.file_id,f.name,f.filesize,f.filepath')
->alias('mf')
->join('file f', 'mf.file_id = f.id', 'LEFT')
->order('mf.create_time desc')
->where(array('mf.mid' => $detail['fid'], 'mf.status' => 1))
->select()->toArray();
$detail['from_file_array'] = $from_file_array;
}
View::assign('file_array', $file_array);
View::assign('detail', $detail);
}
View::assign('id', $id);
View::assign('fid', $fid);
return view();
}
//回复和转发消息
public function reply()
{
$id = empty(get_params('id')) ? 0 : get_params('id');
$type = empty(get_params('type')) ? 0 : get_params('type');
$detail = Db::name('Mail')->where(['id' => $id, 'mail_type' => 2])->find();
if (empty($detail)) {
$this->error('该信息不存在');
}
if ($detail['to_uid'] != $this->uid && $detail['from_uid'] != $this->uid) {
$this->error('该信息不存在');
}
$sender = get_admin($detail['from_uid']);
$detail['person_name'] = $sender['name'];
$file_array = Db::name('MailFileInterfix')
->field('mf.id,mf.mid,mf.file_id,f.name,f.filesize,f.filepath')
->alias('mf')
->join('file f', 'mf.file_id = f.id', 'LEFT')
->order('mf.create_time desc')
->where(array('mf.mid' => $id, 'mf.status' => 1))
->select()->toArray();
$interfix_ids = array_column($file_array, 'file_id');
$detail['file_ids'] = implode(",", $interfix_ids);
View::assign('file_array', $file_array);
View::assign('detail', $detail);
View::assign('fid', $id);
View::assign('type', $type);
return view();
}
//查看消息
public function read()
{
$param = get_params();
$id = $param['id'];
$detail = Db::name('Mail')->where(['id' => $id])->find();
if (empty($detail)) {
$this->error('该信息不存在');
}
if ($detail['to_uid'] != $this->uid && $detail['from_uid'] != $this->uid) {
$this->error('该信息不存在');
}
Db::name('Mail')->where(['id' => $id])->update(['is_read' => 2]);
if($detail['from_uid']==0){
$detail['person_name'] = '系统管理员';
}
else{
$sender = get_admin($detail['from_uid']);
$detail['person_name'] = $sender['name'];
}
//引用消息的附件
if($detail['fid']>0){
$detail['from_content'] = Db::name('Mail')->where(['id' => $detail['fid']])->value('content');
$from_file_array = Db::name('MailFileInterfix')
->field('mf.id,mf.mid,mf.file_id,f.name,f.filesize,f.filepath')
->alias('mf')
->join('file f', 'mf.file_id = f.id', 'LEFT')
->order('mf.create_time desc')
->where(array('mf.mid' => $detail['fid'], 'mf.status' => 1))
->select()->toArray();
$detail['from_file_array'] = $from_file_array;
}
//当前消息的附件
$file_array = Db::name('MailFileInterfix')
->field('mf.id,mf.mid,mf.file_id,f.name,f.filesize,f.filepath')
->alias('mf')
->join('file f', 'mf.file_id = f.id', 'LEFT')
->order('mf.create_time desc')
->where(array('mf.mid' => $detail['id'], 'mf.status' => 1))
->select()->toArray();
$detail['file_array'] = $file_array;
$detail['send_time'] = date('Y-m-d h:i:s',$detail['send_time']);
//发送人查询
$user_names=[];
//已读回执
$read_user_names = [];
if($detail['from_uid'] == $this->uid){
$mails= Db::name('Mail')->where(['pid' => $id])->select()->toArray();
$read_mails= Db::name('Mail')->where(['pid' => $id,'is_read' => 2])->select()->toArray();
$read_user_ids = array_column($read_mails, 'to_uid');
$read_users = Db::name('Admin')->where('status', 1)->where('id', 'in', $read_user_ids)->select()->toArray();
$read_user_names = array_column($read_users, 'name');
}
else{
$mails= Db::name('Mail')->where(['pid' => $detail['pid']])->select()->toArray();
}
$user_ids = array_column($mails, 'to_uid');
$users = Db::name('Admin')->where('status', 1)->where('id', 'in', $user_ids)->select()->toArray();
$user_names = array_column($users, 'name');
$detail['users'] = implode(",", $user_names);
$detail['read_users'] = implode(",", $read_user_names);
View::assign('detail', $detail);
return view();
}
//保存到草稿
public function save()
{
$param = get_params();
$id = empty($param['id']) ? 0 : $param['id'];
$fid = empty($param['fid']) ? 0 : $param['fid'];
//接受人类型判断
if ($param['type'] == 0) {
if (!$param['uids']) {
return to_assign(1, '人员不能为空');
} else {
$type_user = $param['uids'];
}
} elseif ($param['type'] == 1) {
if (!$param['dids']) {
return to_assign(1, '部门不能为空');
} else {
$type_user = $param['dids'];
}
} elseif ($param['type'] == 2) {
if (!$param['pids']) {
return to_assign(1, '岗位不能为空');
} else {
$type_user = $param['pids'];
}
} else {
$type_user = '';
}
//基础信息数据
$admin_id = $this->uid;
$did = get_admin($admin_id)['did'];
$basedata = [];
$basedata['from_uid'] = $admin_id;
$basedata['admin_id'] = $admin_id;
$basedata['did'] = $did;
$basedata['fid'] = $fid;
$basedata['mail_type'] = 2;//同事信息类型
$basedata['is_draft'] = 2;//默认是草稿信息
$basedata['name'] = $param['name'];
$basedata['type'] = $param['type'];
$basedata['type_user'] = $type_user;
$basedata['content'] = $param['content'];
if ($id > 0) {
//编辑信息的情况
$basedata['update_time'] = time();
$basedata['id'] = $id;
$res = Db::name('Mail')->strict(false)->field(true)->update($basedata);
} else {
//新增信息的情况
$basedata['create_time'] = time();
$res = Db::name('Mail')->strict(false)->field(true)->insertGetId($basedata);
}
if ($res !== false) {
//信息附件处理
if ($id > 0) {
$mid = $id;
Db::name('MailFileInterfix')->where('mid', $mid)->delete();
} else {
$mid = $res;
}
//附件插入附件
if (!empty($param['file_ids'])) {
$file_array = explode(',', $param['file_ids']);
$file_data = array();
foreach ($file_array as $key => $value) {
if (!$value) {
continue;
}
$file_data[] = array(
'mid' => $mid,
'file_id' => $value,
'create_time' => time(),
'admin_id' => $admin_id,
);
}
if ($file_data) {
Db::name('MailFileInterfix')->strict(false)->field(true)->insertAll($file_data);
}
}
add_log('save',$mid);
return to_assign(0, '保存成功', $mid);
} else {
return to_assign(1, '操作失败');
}
}
//发送消息
public function send()
{
$param = get_params();
//查询要发的消息
$msg = Db::name('Mail')->where(['id' => $param['id']])->find();
$users = [];
if ($msg) {
$admin_id = $msg['admin_id'];
//查询全部收件人
if ($msg['type'] == 0) { //人员
$users = Db::name('Admin')->where('status', 1)->where('id', 'in', $msg['type_user'])->select()->toArray();
} elseif ($msg['type'] == 1) { //部门
$users = Db::name('Admin')->where('status', 1)->where('did', 'in', $msg['type_user'])->select()->toArray();
} elseif ($msg['type'] == 2) { //角色
$group_uid = Db::name('PositionGroup')->where('group_id', 'in', $msg['type_user'])->select()->toArray();
$pids = array_column($group_uid, 'pid');
$users = Db::name('Admin')->where('status', 1)->where('position_id', 'in', $pids)->select()->toArray();
} elseif ($msg['type'] == 3) { //全部
$users = Db::name('Admin')->where('status', 1)->select()->toArray();
}
//组合要发的消息
$send_data = [];
foreach ($users as $key => $value) {
if (!$value || ($value['id'] == $admin_id)) {
continue;
}
$send_data[] = array(
'pid' => $msg['id'],//来源发件关联id
'fid' => $msg['fid'],//转发或回复消息关联id
'name' => $msg['name'],
'type' => $msg['type'],
'type_user' => $msg['type_user'],
'from_uid' => $admin_id,//发送人
'did' => $value['did'],
'to_uid' => $value['id'],
'mail_type' => 2,//同事信息类型
'content' => $msg['content'],
'send_time' => time(),
'admin_id' => $admin_id,
'create_time' => time()
);
}
$res = Db::name('Mail')->strict(false)->field(true)->insertAll($send_data);
if ($res!==false) {
//查询原来的附件,并插入
$file_array = Db::name('MailFileInterfix')->where('mid', $msg['id'])->select()->toArray();
if ($file_array) {
$mids = Db::name('Mail')->where('pid', $msg['id'])->select()->toArray();
foreach ($mids as $k => $v) {
$file_data = array();
foreach ($file_array as $key => $value) {
if (!$value) {
continue;
}
$file_data[] = array(
'mid' => $v['id'],
'file_id' => $value['file_id'],
'create_time' => time(),
'admin_id' => $admin_id,
);
}
if ($file_data) {
Db::name('MailFileInterfix')->strict(false)->field(true)->insertAll($file_data);
}
}
}
//草稿消息变成已发消息
Db::name('Mail')->where(['id' => $msg['id']])->update(['is_draft' => '1', 'send_time' => time(), 'update_time' => time()]);
add_log('send',$msg['id']);
return to_assign(0, '发送成功');
} else {
return to_assign(1, '发送失败');
}
} else {
return to_assign(1, '发送失败,找不到要发送的内容');
}
}
//状态修改
public function check()
{
$param = get_params();
$type = empty($param['type']) ? 0 : $param['type'];
$source = empty($param['source']) ? 0 : $param['source'];
$ids = empty($param['ids']) ? 0 : $param['ids'];
$idArray = explode(',', $ids);
$list = [];
foreach ($idArray as $key => $val) {
if ($type==1) { //设置信息为已读
$list[] = [
'is_read' => 2,
'id' => $val,
'update_time' => time(),
];
}
else if ($type==2) { //设置信息进入垃圾箱
$list[] = [
'status' => 0,
'id' => $val,
'delete_source' => $source,
'update_time' => time(),
];
}
else if ($type==3) { //设置信息从垃圾箱恢复
$list[] = [
'status' => 1,
'id' => $val,
'update_time' => time(),
];
}
else if ($type==4) { //设置信息彻底删除
$list[] = [
'status' => -1,
'id' => $val,
'update_time' => time(),
];
}
}
foreach ($list as $key => $v) {
if (Db::name('Mail')->update($v) !== false) {
if ($type = 1) {
add_log('view', $v['id']);
} else if ($type = 2) {
add_log('delete', $v['id']);
} else if ($type = 3) {
add_log('recovery', $v['id']);
}
else if ($type = 4) {
add_log('clear', $v['id']);
}
}
}
return to_assign(0, '操作成功');
}
}

View File

@ -0,0 +1,97 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\BaseController;
use app\home\validate\MenuCheck;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\View;
class Menu extends BaseController
{
public function index()
{
if (request()->isAjax()) {
$menu = Db::name('AdminMenu')->order('sort asc')->select();
return to_assign(0, '', $menu);
} else {
return view();
}
}
//添加菜单页面
public function add()
{
return view('', ['pid' => get_params('pid')]);
}
//提交添加
public function post_submit()
{
if (request()->isAjax()) {
$param = get_params();
if ($param['id'] > 0) {
$data[$param['field']] = $param['value'];
$data['id'] = $param['id'];
if(!empty($data['title'])){
try {
validate(MenuCheck::class)->scene('edit')->check($data);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
}
Db::name('AdminMenu')->strict(false)->field(true)->update($data);
add_log('edit', $param['id'], $data);
} else {
try {
validate(MenuCheck::class)->scene('add')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$mid = Db::name('AdminMenu')->strict(false)->field(true)->insertGetId($param);
//自动为系统所有者管理组分配新增的菜单
$group = Db::name('AdminGroup')->find(1);
if (!empty($group)) {
$newGroup['id'] = 1;
$newGroup['menus'] = $group['menus'] . ',' . $mid;
Db::name('AdminGroup')->strict(false)->field(true)->update($newGroup);
add_log('add', $mid, $param);
}
}
// 删除后台菜单缓存
clear_cache('adminMenu');
return to_assign();
}
}
//删除
public function delete()
{
$id = get_params('id');
$count = Db::name('AdminMenu')->where(['pid' => $id])->count();
if ($count > 0) {
return to_assign(1, '该菜单下还有子菜单,无法删除');
}
if (Db::name('AdminMenu')->delete($id) !== false) {
// 删除后台菜单缓存
clear_cache('adminMenu');
add_log('delete', $id, []);
return to_assign(0, '删除菜单成功');
} else {
return to_assign(1, '删除失败');
}
}
}

View File

@ -0,0 +1,198 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\BaseController;
use app\home\model\Note as NoteList;
use app\home\model\NoteCate;
use app\home\validate\NoteCateCheck;
use app\home\validate\NoteCheck;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\View;
class Note extends BaseController
{
public function cate()
{
if (request()->isAjax()) {
$cate = Db::name('NoteCate')->order('create_time asc')->select();
return to_assign(0, '', $cate);
} else {
return view();
}
}
//分类添加
public function cate_add()
{
return view('', ['pid' => get_params('pid')]);
}
//提交保存分类
public function cate_post_submit()
{
if (request()->isAjax()) {
$param = get_params();
if (!empty($param['id']) && $param['id'] > 0) {
$data[$param['field']] = $param['value'];
$data['id'] = $param['id'];
$data['update_time'] = time();
if (!empty($data['title'])) {
try {
validate(NoteCateCheck::class)->scene('edit')->check($data);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
}
$res = NoteCate::strict(false)->field(true)->update($data);
if ($res) {
add_log('edit', $data['id'], $data);
}
return to_assign();
} else {
try {
validate(NoteCateCheck::class)->scene('add')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$param['create_time'] = time();
$insertId = NoteCate::strict(false)->field(true)->insertGetId($param);
if ($insertId) {
add_log('add', $insertId, $param);
}
return to_assign();
}
}
}
//删除分类
public function cate_delete()
{
$id = get_params("id");
$cate_count = Db::name('NoteCate')->where(["pid" => $id])->count();
if ($cate_count > 0) {
return to_assign(1, "该分类下还有子分类,无法删除");
}
$content_count = Db::name('Article')->where(["article_cate_id" => $id])->count();
if ($content_count > 0) {
return to_assign(1, "该分类下还有文章,无法删除");
}
if (Db::name('NoteCate')->delete($id) !== false) {
add_log('delete', $id);
return to_assign(0, "删除分类成功");
} else {
return to_assign(1, "删除失败");
}
}
public function index()
{
if (request()->isAjax()) {
$param = get_params();
$where = array();
if (!empty($param['keywords'])) {
$where[] = ['a.title|a.content', 'like', '%' . $param['keywords'] . '%'];
}
$where[] = ['a.status', '>=', 0];
$rows = empty($param['limit']) ? get_config('app . page_size') : $param['limit'];
$note = NoteList::where($where)
->field('a.*,c.title as cate_title')
->alias('a')
->join('NoteCate c', 'a.cate_id = c.id', 'LEFT')
->order('a.create_time asc')
->paginate($rows, false, ['query' => $param])
->each(function ($item, $key) {
$item->start_time = empty($item->start_time) ? '-' : date('Y-m-d', $item->start_time);
$item->end_time = empty($item->end_time) ? '-' : date('Y-m-d', $item->end_time);
});
return table_assign(0, '', $note);
} else {
return view();
}
}
//添加
public function add()
{
$id = empty(get_params('id')) ? 0 : get_params('id');
if ($id > 0) {
$note = Db::name('Note')->where(['id' => $id])->find();
View::assign('note', $note);
}
View::assign('id', $id);
return view();
}
//提交添加
public function post_submit()
{
if (request()->isAjax()) {
$param = get_params();
$param['start_time'] = isset($param['start_time']) ? strtotime(urldecode($param['start_time'])) : 0;
$param['end_time'] = isset($param['end_time']) ? strtotime(urldecode($param['end_time'])) : 0;
if (!empty($param['id']) && $param['id'] > 0) {
try {
validate(NoteCheck::class)->scene('edit')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$param['update_time'] = time();
$res = NoteList::where('id', $param['id'])->strict(false)->field(true)->update($param);
if ($res) {
add_log('edit', $param['id'], $param);
}
return to_assign();
} else {
try {
validate(NoteCheck::class)->scene('add')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$param['create_time'] = time();
$sid = NoteList::strict(false)->field(true)->insertGetId($param);
if ($sid) {
add_log('add', $sid, $param);
}
return to_assign();
}
}
}
//查看
public function view()
{
$id = empty(get_params('id')) ? 0 : get_params('id');
$note = Db::name('Note')->where(['id' => $id])->find();
View::assign('note', $note);
return view();
}
//删除
public function delete()
{
$id = get_params("id");
$data['status'] = '-1';
$data['id'] = $id;
$data['update_time'] = time();
if (Db::name('Note')->update($data) !== false) {
add_log('delete', $id);
return to_assign(1, "删除成功");
} else {
return to_assign(0, "删除失败");
}
}
}

View File

@ -0,0 +1,188 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\BaseController;
use app\home\validate\PositionCheck;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\View;
class Position extends BaseController
{
public function index()
{
if (request()->isAjax()) {
$list = Db::name('Position')->where('status','>=',0)->order('create_time asc')->select()->toArray();
foreach ($list as &$val) {
$groupId = Db::name('PositionGroup')->where(['pid' => $val['id']])->column('group_id');
$groupName = Db::name('AdminGroup')->where('id', 'in', $groupId)->column('title');
$val['groupName'] = implode(',', $groupName);
}
$res['data'] = $list;
return table_assign(0, '', $res);
} else {
return view();
}
}
//添加
public function add()
{
$id = empty(get_params('id')) ? 0 : get_params('id');
$group = Db::name('AdminGroup')->order('create_time asc')->select()->toArray();
if($id > 0) {
$detail = Db::name('Position')->where(['id' => $id])->find();
$detail['group_id'] = Db::name('PositionGroup')->where(['pid' => $id])->column('group_id');
foreach ($group as &$val) {
if(in_array($val['id'],$detail['group_id'])){
$val['checked'] = 1;
}
else{
$val['checked'] = 0;
}
}
View::assign('detail', $detail);
}
View::assign('group', $group);
View::assign('id', $id);
return view();
}
//提交添加
public function post_submit()
{
if (request()->isAjax()) {
$param = get_params();
if (!empty($param['id']) && $param['id'] > 0) {
try {
validate(PositionCheck::class)->scene('edit')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
// 启动事务
Db::startTrans();
try {
Db::name('Position')->where(['id' => $param['id']])->strict(false)->field(true)->update($param);
Db::name('PositionGroup')->where(['pid' => $param['id']])->delete();
foreach ($param['group_id'] as $k => $v) {
$data[$k] = [
'pid' => $param['id'],
'group_id' => $v,
'create_time' => time()
];
}
Db::name('PositionGroup')->strict(false)->field(true)->insertAll($data);
add_log('edit', $param['id'], $param);
//清除菜单\权限缓存
clear_cache('adminMenu');
clear_cache('adminRules');
// 提交事务
Db::commit();
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
return to_assign(1, '提交失败:' . $e->getMessage());
}
} else {
try {
validate(PositionCheck::class)->scene('add')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
// 启动事务
Db::startTrans();
try {
$uid = Db::name('Position')->strict(false)->field(true)->insertGetId($param);
foreach ($param['group_id'] as $k => $v) {
$data[$k] = [
'pid' => $uid,
'group_id' => $v,
'create_time' => time()
];
}
Db::name('PositionGroup')->strict(false)->field(true)->insertAll($data);
add_log('add', $uid, $param);
// 提交事务
Db::commit();
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
return to_assign(1, '提交失败:' . $e->getMessage());
}
}
return to_assign();
}
}
//查看
public function view()
{
$id = get_params('id');
$group = Db::name('AdminGroup')->order('create_time asc')->select()->toArray();
$detail = Db::name('Position')->where(['id' => $id])->find();
$detail['group_id'] = Db::name('PositionGroup')->where(['pid' => $id])->column('group_id');
foreach ($group as &$val) {
if(in_array($val['id'],$detail['group_id'])){
$val['checked'] = 1;
}
else{
$val['checked'] = 0;
}
}
$menu = get_admin_menu();
$rule = get_admin_rule();
$user_groups = Db::name('PositionGroup')
->alias('a')
->join("AdminGroup g", "a.group_id=g.id", 'LEFT')
->where("a.pid='{$id}' and g.status='1'")
->select()
->toArray();
$groups = $user_groups ?: [];
$menus = [];
$rules = [];
foreach ($groups as $g) {
$menus = array_merge($menus, explode(',', trim($g['menus'], ',')));
$rules = array_merge($rules, explode(',', trim($g['rules'], ',')));
}
$menus = array_unique($menus);
$rules = array_unique($rules);
$role_menu = create_tree_list(0, $menu, $menus);
$role_rule = create_tree_list(0, $rule, $rules);
View::assign('role_menu', $role_menu);
View::assign('role_rule', $role_rule);
View::assign('detail', $detail);
View::assign('group', $group);
add_log('view', $id);
return view();
}
//删除
public function delete()
{
$id = get_params("id");
if($id == 1){
return to_assign(0, "超级岗位,不能删除");
}
$data['status'] = '-1';
$data['id'] = $id;
$data['update_time'] = time();
if (Db::name('Position')->update($data) !== false) {
add_log('delete', $id);
return to_assign(0, "删除岗位成功");
} else {
return to_assign(1, "删除失败");
}
}
}

View File

@ -0,0 +1,117 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\BaseController;
use app\home\model\AdminGroup;
use app\home\validate\GroupCheck;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\View;
class Role extends BaseController
{
public function index()
{
if (request()->isAjax()) {
$param = get_params();
$where = array();
if (!empty($param['keywords'])) {
$where[] = ['id|title|desc', 'like', '%' . $param['keywords'] . '%'];
}
$rows = empty($param['limit']) ? get_config(app . page_size) : $param['limit'];
$group = AdminGroup::where($where)
->order('create_time asc')
->paginate($rows, false, ['query' => $param]);
return table_assign(0, '', $group);
} else {
return view();
}
}
//添加&编辑
public function add()
{
$id = empty(get_params('id')) ? 0 : get_params('id');
$menu = get_admin_menu();
$rule = get_admin_rule();
if($id > 0) {
$group = get_admin_group_info($id);
$role_menu = create_tree_list(0, $menu, $group['menus']);
$role_rule = create_tree_list(0, $rule, $group['rules']);
$role = Db::name('AdminGroup')->where(['id' => $id])->find();
View::assign('role', $role);
}
else{
$role_menu = create_tree_list(0, $menu, []);
$role_rule = create_tree_list(0, $rule, []);
}
View::assign('role_menu', $role_menu);
View::assign('role_rule', $role_rule);
View::assign('id', $id);
return view();
}
//提交保存
public function post_submit()
{
if (request()->isAjax()) {
$param = get_params();
$menuData = isset($param['menu']) ? $param['menu'] : 0;
$ruleData = isset($param['rule']) ? $param['rule'] : 0;
//sort($menuData);
//sort($ruleData);
$param['menus'] = implode(',',$menuData);
$param['rules'] = implode(',',$ruleData);
if (!empty($param['id']) && $param['id'] > 0) {
try {
validate(GroupCheck::class)->scene('edit')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
//为了系统安全id为1的系统所有者管理组不允许修改
if ($param['id'] == 1) {
return to_assign(1, '为了系统安全,该管理组不允许修改');
}
Db::name('AdminGroup')->where(['id' => $param['id']])->strict(false)->field(true)->update($param);
add_log('edit', $param['id'], $param);
} else {
try {
validate(GroupCheck::class)->scene('add')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$gid = Db::name('AdminGroup')->strict(false)->field(true)->insertGetId($param);
add_log('add', $gid, $param);
}
//清除菜单\权限缓存
clear_cache('adminMenu');
clear_cache('adminRules');
return to_assign();
}
}
//删除
public function delete()
{
$id = get_params("id");
if ($id == 1) {
return to_assign(1, "该组是系统所有者,无法删除");
}
if (Db::name('AdminGroup')->delete($id) !== false) {
add_log('delete', $id, []);
return to_assign(0, "删除角色成功");
} else {
return to_assign(1, "删除失败");
}
}
}

View File

@ -0,0 +1,101 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\BaseController;
use app\home\validate\RuleCheck;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\View;
class Rule extends BaseController
{
public function index()
{
if (request()->isAjax()) {
$rule = Db::name('adminRule')->order('create_time asc')->select();
return to_assign(0, '', $rule);
} else {
return view();
}
}
//添加
public function add()
{
return view('', ['pid' => get_params('pid')]);
}
//提交添加
public function post_submit()
{
if (request()->isAjax()) {
$param = get_params();
if ($param['id'] > 0) {
$data[$param['field']] = $param['value'];
$data['id'] = $param['id'];
if(!empty($data['title'])){
try {
validate(RuleCheck::class)->scene('edit_title')->check($data);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
}
if(!empty($data['src'])){
try {
validate(RuleCheck::class)->scene('edit_src')->check($data);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
}
Db::name('AdminRule')->strict(false)->field(true)->update($data);
add_log('edit', $param['id'], $data);
} else {
try {
validate(RuleCheck::class)->scene('add')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$rid = Db::name('AdminRule')->strict(false)->field(true)->insertGetId($param);
//自动为系统所有者管理组分配新增的节点
$group = Db::name('AdminGroup')->find(1);
if (!empty($group)) {
$newGroup['id'] = 1;
$newGroup['rules'] = $group['rules'] . ',' . $rid;
Db::name('AdminGroup')->strict(false)->field(true)->update($newGroup);
add_log('add', $rid, $param);
}
}
// 删除后台节点缓存
clear_cache('adminRules');
return to_assign();
}
}
//删除
public function delete()
{
$id = get_params("id");
$count = Db::name('AdminRule')->where(["pid" => $id])->count();
if ($count > 0) {
return to_assign(1, "该节点下还有子节点,无法删除");
}
if (Db::name('AdminRule')->delete($id) !== false) {
clear_cache('adminRules');
add_log('delete', $id, []);
return to_assign(0, "删除节点成功");
} else {
return to_assign(1, "删除失败");
}
}
}

View File

@ -0,0 +1,304 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\BaseController;
use app\home\model\Schedule as ScheduleList;
use app\home\validate\ScheduleCheck;
use think\exception\ValidateException;
use schedule\Schedule as ScheduleIndex;
use think\facade\Db;
use think\facade\View;
class Schedule extends BaseController
{
public function index()
{
if (request()->isAjax()) {
$param=get_params();
$uid=$this->uid;
if (!empty($param['uid'])) {
$uid = $param['uid'];
}
$where=[];
$where[]=['start_time','>=',strtotime($param['start'])];
$where[]=['end_time','<=',strtotime($param['end'])];
$where[] =['admin_id','=',$uid];
$where[] = ['status','=', 1];
$schedule = Db::name('Schedule')->where($where)->field('id,name,labor_time,start_time,end_time')->select()->toArray();
$events = [];
$countEvents=[];
foreach ($schedule as $k => $v) {
$v['backgroundColor']='#009688';
$v['borderColor']='#009688';
$v['title']='['.$v['labor_time'].'工时] '.$v['name'];
$v['start']=date('Y-m-d H:i', $v['start_time']);
$v['end']=date('Y-m-d H:i', $v['end_time']);
$temData=date('Y-m-d', $v['start_time']);
if(array_key_exists($temData, $countEvents)){
$countEvents[$temData]['times']+=$v['labor_time'];
}
else{
$countEvents[$temData]['times']=$v['labor_time'];
$countEvents[$temData]['start']=date('Y-m-d', $v['start_time']);
}
unset($v['name']);
unset($v['start_time']);
unset($v['end_time']);
$events[] = $v;
}
foreach ($countEvents as $kk => $vv) {
$vv['backgroundColor']='#FF5722';
$vv['borderColor']='#FF5722';
$vv['title']='【当天总工时:'.$vv['times'].'】';
$vv['end']=$vv['start'];
$vv['id']=0;
unset($vv['times']);
$events[] = $vv;
}
$input_arrays = $events;
$range_start = parseDateTime($param['start']);
$range_end = parseDateTime($param['end']);
$timeZone = null;
if (isset($_GET['timeZone'])) {
$timeZone = new DateTimeZone($_GET['timeZone']);
}
// Accumulate an output array of event data arrays.
$output_arrays = array();
foreach ($input_arrays as $array) {
// Convert the input array into a useful Event object
$event = new ScheduleIndex($array, $timeZone);
// If the event is in-bounds, add it to the output
if ($event->isWithinDayRange($range_start, $range_end)) {
$output_arrays[] = $event->toArray();
}
}
return json($output_arrays);
} else {
return view();
}
}
public function list()
{
if (request()->isAjax()) {
$param = get_params();
//按时间检索
$start_time = isset($param['start_time']) ? strtotime($param['start_time']) : 0;
$end_time = isset($param['end_time']) ? strtotime($param['end_time']) : 0;
$where=[];
if ($start_time > 0 && $end_time > 0) {
$where[]=['a.start_time','between', [$start_time,$end_time]];
}
if (!empty($param['keywords'])) {
$where[] = ['a.name','like', '%' . trim($param['keywords']) . '%'];
}
if (!empty($param['uid'])) {
$where[] =['a.admin_id','=',$param['uid']];
}
else{
$where[] =['a.admin_id','=',$this->uid];
}
$where[] = ['a.status','=', 1];
$rows = empty($param['limit']) ? get_config('app . page_size') : $param['limit'];
$schedule = ScheduleList::where($where)
->field('a.*,u.name as create_admin')
->alias('a')
->join('admin u', 'u.id = a.admin_id', 'LEFT')
->order('a.id desc')
->paginate($rows, false)
->each(function ($item, $key) {
$item->start_time = empty($item->start_time) ? '': date('Y-m-d H:i', $item->start_time);
//$item->end_time = empty($item->end_time) ? '': date('Y-m-d H:i', $item->end_time);
$item->end_time = empty($item->end_time) ? '': date('H:i', $item->end_time);
});
return table_assign(0, '', $schedule);
} else {
return view();
}
}
//保存日志数据
public function save()
{
$param = get_params();
$admin_id=$this->uid;
if($param['id']==0){
if(isset($param['start_time'])){
$param['start_time'] = strtotime($param['start_time'].''.$param['start_time_1']);
}
if(isset($param['end_time'])){
$param['end_time'] = strtotime($param['end_time'].''.$param['end_time_1']);
}
if( $param['end_time'] <= $param['start_time']){
return to_assign(1, "结束时间需要大于开始时间");
}
$where1[]=['status','=',1];
$where1[]=['admin_id','=',$admin_id];
$where1[]=['start_time','between', [$param['start_time'],$param['end_time']-1]];
$where2[]=['status','=',1];
$where2[]=['admin_id','=',$admin_id];
$where2[]=['start_time','<=',$param['start_time']];
$where2[]=['start_time','>=',$param['end_time']];
$where3[]=['status','=',1];
$where3[]=['admin_id','=',$admin_id];
$where3[]=['end_time','between', [$param['start_time']+1,$param['end_time']]];
$record = Db::name('Schedule')
->where(function ($query) use ($where1) {
$query->where($where1);
})
->whereOr(function ($query) use ($where2) {
$query->where($where2);
})
->whereOr(function ($query) use ($where3) {
$query->where($where3);
})
->count();
if($record>0){
return to_assign(1, "您所选的时间区间已有工作记录,请重新选时间");
}
$param['labor_time'] = ($param['end_time'] - $param['start_time']) / 3600;
$param['admin_id'] = $admin_id;
$param['did'] = get_admin($admin_id)['did'];
$param['create_time']=time();
$addid = Db::name('Schedule')->strict(false)->field(true)->insertGetId($param);
if($addid>0){
add_log('add', $addid, $param);
return to_assign(0,'操作成功');
}else{
return to_assign(0,'操作失败');
}
}else{
$param['update_time'] = time();
$res = Db::name('Schedule')->strict(false)->field(true)->update($param);
if ($res!==false) {
add_log('edit', $addid, $param);
return to_assign(0,'操作成功');
}else{
return to_assign(0,'操作失败');
}
}
}
//更改工时
public function update_labor_time()
{
$param = get_params();
if(isset($param['start_time'])){
$param['start_time'] = strtotime($param['start_time'].''.$param['start_time_1']);
}
if(isset($param['end_time'])){
$param['end_time'] = strtotime($param['end_time'].''.$param['end_time_1']);
}
if( $param['end_time'] <= $param['start_time']){
return to_assign(1, "结束时间需要大于开始时间");
}
$where1[]=['status','=',1];
$where1[]=['id','<>',$param['id']];
$where1[]=['admin_id','=',$param['admin_id']];
$where1[]=['start_time','between', [$param['start_time'],$param['end_time']-1]];
$where2[]=['status','=',1];
$where2[]=['id','<>',$param['id']];
$where2[]=['admin_id','=',$param['admin_id']];
$where2[]=['start_time','<=',$param['start_time']];
$where2[]=['start_time','>=',$param['end_time']];
$where3[]=['status','=',1];
$where3[]=['id','<>',$param['id']];
$where3[]=['admin_id','=',$param['admin_id']];
$where3[]=['end_time','between', [$param['start_time']+1,$param['end_time']]];
$record = Db::name('Schedule')
->where(function ($query) use ($where1) {
$query->where($where1);
})
->whereOr(function ($query) use ($where2) {
$query->where($where2);
})
->whereOr(function ($query) use ($where3) {
$query->where($where3);
})
->count();
if($record>0){
return to_assign(1, "您所选的时间区间已有工作记录,请重新选时间");
}
$param['labor_time'] = ($param['end_time'] - $param['start_time']) / 3600;
$res = Db::name('Schedule')->strict(false)->field(true)->update($param);
if ($res!==false) {
return to_assign(0, "操作成功");
add_log('edit', $param['id'], $param);
} else {
return to_assign(1, "操作失败");
}
}
//删除工作记录
public function delete()
{
$id = get_params("id");
$data['status'] = '-1';
$data['id'] = $id;
$data['update_time'] = time();
if (Db::name('schedule')->update($data) !== false) {
add_log('delete', $data['id'], $data);
return to_assign(0, "删除成功");
} else {
return to_assign(1, "删除失败");
}
}
public function detail($id)
{
$id=get_params('id');
$schedule = Db::name('Schedule')->where(['id'=>$id])->find();
if (!empty($schedule)) {
$schedule['start_time_1'] = date('H:i', $schedule['start_time']);
$schedule['end_time_1'] = date('H:i', $schedule['end_time']);
$schedule['start_time'] = date('Y-m-d', $schedule['start_time']);
$schedule['end_time'] = date('Y-m-d', $schedule['end_time']);
$schedule['create_time'] = date('Y-m-d H:i:s', $schedule['create_time']);
$schedule['user'] = Db::name('Admin')->where(['id'=>$schedule['admin_id']])->value('name');
}
if (request()->isAjax()) {
return to_assign(0, "", $schedule);
}
else{
return $schedule;
}
}
//读取日程弹层详情
public function view()
{
$id=get_params('id');
$schedule=$this->detail($id);
if($schedule){
View::assign('schedule', $schedule);
return view();
}
else{
echo '该工作记录不存在';
}
}
//个人年度工作情况
public function user()
{
$this_year = date("Y");
$admin_did = \think\Session::get('vae_admin');
return view('', ['this_year' => $this_year, 'this_uid' => $admin_did['id'],'username'=>$admin_did['nickname']]);
}
}

View File

@ -0,0 +1,48 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\BaseController;
use think\facade\Db;
use think\facade\View;
class Search extends BaseController
{
public function index()
{
if (request()->isAjax()) {
$param = get_params();
$where = array();
if (!empty($param['keywords'])) {
$where[] = ['title', 'like', '%' . $param['keywords'] . '%'];
}
$rows = empty($param['limit']) ? get_config(app . page_size) : $param['limit'];
$content = Db::name('SearchKeywords')
->order('id desc')
->where($where)
->paginate($rows, false, ['query' => $param]);
return table_assign(0, '', $content);
} else {
return view();
}
}
//删除
public function delete()
{
$id = get_params("id");
if (Db::name('SearchKeywords')->delete($id) !== false) {
add_log('delete', $id);
return to_assign(0, "删除成功!");
} else {
return to_assign(1, "删除失败!");
}
}
}

View File

@ -0,0 +1,343 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\controller;
use app\home\BaseController;
use app\home\model\Expense as ExpenseList;
use app\home\model\ExpenseCate;
use app\home\validate\ExpenseCateCheck;
use app\home\validate\ExpenseCheck;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\View;
class Expense extends BaseController
{
public function cate()
{
if (request()->isAjax()) {
$cate = Db::name('ExpenseCate')->order('create_time asc')->select();
return to_assign(0, '', $cate);
} else {
return view();
}
}
//提交保存分类
public function cate_post_submit()
{
if (request()->isAjax()) {
$param = get_params();
if (!empty($param['id']) && $param['id'] > 0) {
try {
validate(ExpenseCateCheck::class)->scene('edit')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$data['update_time'] = time();
$res = ExpenseCate::strict(false)->field(true)->update($param);
if ($res) {
add_log('edit', $param['id'], $param);
}
return to_assign();
} else {
try {
validate(ExpenseCateCheck::class)->scene('add')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$param['create_time'] = time();
$insertId = ExpenseCate::strict(false)->field(true)->insertGetId($param);
if ($insertId) {
add_log('add', $insertId, $param);
}
return to_assign();
}
}
}
public function get_list($param=[],$where=[])
{
$rows = empty($param['limit']) ? get_config('app . page_size') : $param['limit'];
$expense = ExpenseList::where($where)
->order('create_time asc')
->paginate($rows, false, ['query' => $param])
->each(function ($item, $key) {
$item->income_month = empty($item->income_month) ? '-' : date('Y-m', $item->income_month);
$item->expense_time = empty($item->expense_time) ? '-' : date('Y-m-d', $item->expense_time);
$item->user_name = Db::name('Admin')->where(['id' => $item->uid])->value('name');
$item->admin_name = Db::name('Admin')->where(['id' => $item->admin_id])->value('name');
$item->department = Db::name('Department')->where(['id' => $item->did])->value('title');
$item->check_name = Db::name('Admin')->where(['id' => $item->check_admin_id])->value('name');
$item->check_time = empty($item->check_time) ? '-' : date('Y-m-d H:i', $item->check_time);
$item->pay_name = Db::name('Admin')->where(['id' => $item->pay_admin_id])->value('name');
$item->pay_time = empty($item->pay_time) ? '-' : date('Y-m-d H:i', $item->pay_time);
$item->amount = Db::name('ExpenseInterfix')->where(['exid'=>$item->id])->sum('amount');
});
return $expense;
}
public function detail($id=0)
{
$expense = Db::name('Expense')->where(['id' => $id])->find();
if($expense){
$expense['income_month'] = empty($expense['income_month']) ? '-' : date('Y-m', $expense['income_month']);
$expense['expense_time'] = empty($expense['expense_time']) ? '-' : date('Y-m-d', $expense['expense_time']);
$expense['user_name'] = Db::name('Admin')->where(['id' => $expense['uid']])->value('name');
$expense['department'] = Db::name('Department')->where(['id' => $expense['did']])->value('title');
$expense['amount'] = Db::name('ExpenseInterfix')->where(['exid'=>$expense['id']])->sum('amount');
if($expense['check_admin_id']>0){
$expense['check_admin'] = Db::name('Admin')->where(['id' => $expense['check_admin_id']])->value('name');
$expense['check_time'] = date('Y-m-d H:i:s', $expense['check_time']);
}
if($expense['pay_admin_id']>0){
$expense['pay_admin'] = Db::name('Admin')->where(['id' => $expense['pay_admin_id']])->value('name');
$expense['pay_time'] = date('Y-m-d H:i:s', $expense['pay_time']);
}
$expense['list'] = Db::name('ExpenseInterfix')
->field('a.*,c.title as cate_title')
->alias('a')
->join('ExpenseCate c', 'a.cate_id = c.id')
->where(['a.exid'=>$expense['id']])
->select();
}
return $expense;
}
public function index()
{
if (request()->isAjax()) {
$param = get_params();
$where=[];
$where[] = ['status', '=', 1];
//按时间检索
$start_time = isset($param['start_time']) ? strtotime(urldecode($param['start_time'])) : 0;
$end_time = isset($param['end_time']) ? strtotime(urldecode($param['end_time'])) : 0;
if ($start_time > 0 && $end_time > 0) {
$where[] = ['expense_time', 'between', [$start_time,$end_time]];
}
$expense = $this->get_list($param,$where);
return table_assign(0, '', $expense);
} else {
return view();
}
}
public function list()
{
if (request()->isAjax()) {
$param = get_params();
$where=[];
$where[] = ['admin_id', '=', $this->uid];
$where[] = ['status', '=', 1];
//按时间检索
$start_time = isset($param['start_time']) ? strtotime(urldecode($param['start_time'])) : 0;
$end_time = isset($param['end_time']) ? strtotime(urldecode($param['end_time'])) : 0;
if ($start_time > 0 && $end_time > 0) {
$where[] = ['expense_time', 'between', [$start_time,$end_time]];
}
$expense = $this->get_list($param,$where);
return table_assign(0, '', $expense);
} else {
return view();
}
}
//添加
public function add()
{
$id = empty(get_params('id')) ? 0 : get_params('id');
if ($id > 0) {
$expense = $this->detail($id );
View::assign('expense', $expense);
}
$expense_cate=Db::name('ExpenseCate')->where(['status' => 1])->select()->toArray();
View::assign('user', get_admin($this->uid));
View::assign('expense_cate', $expense_cate);
View::assign('id', $id);
return view();
}
//提交添加
public function post_submit()
{
$admin_id=$this->uid;
$dbRes = false;
$param = get_params();
$param['admin_id'] = $admin_id;
$param['income_month'] = isset($param['income_month']) ? strtotime(urldecode($param['income_month'])) : 0;
$param['expense_time'] = isset($param['expense_time']) ? strtotime(urldecode($param['expense_time'])) : 0;
$param['check_status'] = 1;
if (!empty($param['id']) && $param['id'] > 0) {
try {
validate(ExpenseCheck::class)->scene('edit')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$param['update_time'] = time();
Db::startTrans();
try {
$res = ExpenseList::where('id', $param['id'])->strict(false)->field(true)->update($param);
if ($res!==false) {
$exid = $param['id'];
//相关内容多个数组;
$amountData=isset($param['amount'])? $param['amount'] : '';
$remarksData=isset($param['remarks'])? $param['remarks'] : '';
$cateData=isset($param['cate_id'])? $param['cate_id'] : '';
$idData=isset($param['expense_id'])? $param['expense_id'] : 0;
if($amountData){
foreach ($amountData as $key => $value) {
if (!$value ) continue;
$data = [];
$data['id'] = $idData[$key];
$data['exid'] = $exid;
$data['admin_id'] = $admin_id;
$data['amount'] = $amountData[$key];
$data['cate_id'] = $cateData[$key];
$data['remarks'] = $remarksData[$key];
if($data['amount'] == 0){
Db::rollback();
return to_assign(1,'第'.($key+1).'条报销金额不能为零');
}
if($data['id']>0){
$data['update_time'] =time();
$resa = Db::name('ExpenseInterfix')->strict(false)->field(true)->update($data);
}
else{
$data['create_time'] =time();
$eid = Db::name('ExpenseInterfix')->strict(false)->field(true)->insertGetId($data);
}
}
}
add_log('edit',$exid,$param);
Db::commit();
$dbRes=true;
} else {
Db::rollback();
}
}
catch (\Exception $e) { ##这里参数不能删除($e错误信息)
Db::rollback();
return to_assign(1,$e->getMessage());
}
} else {
try {
validate(ExpenseCheck::class)->scene('add')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$param['create_time'] = time();
Db::startTrans();
try {
$exid = ExpenseList::strict(false)->field(true)->insertGetId($param);
if ($exid) {
//相关内容多个数组;
$amountData=isset($param['amount'])? $param['amount'] : '';
$remarksData=isset($param['remarks'])? $param['remarks'] : '';
$cateData=isset($param['cate_id'])? $param['cate_id'] : '';
if($amountData){
foreach ($amountData as $key => $value) {
if (!$value ) continue;
$data = [];
$data['exid'] = $exid;
$data['admin_id'] = $admin_id;
$data['amount'] = $amountData[$key];
$data['cate_id'] = $cateData[$key];
$data['remarks'] = $remarksData[$key];
$data['create_time'] =time();
if($data['amount'] == 0){
Db::rollback();
return to_assign(1,'第'.($key+1).'条报销金额不能为零');
}
$eid = Db::name('ExpenseInterfix')->strict(false)->field(true)->insertGetId($data);
}
}
add_log('add',$exid,$param);
Db::commit();
$dbRes=true;
} else {
Db::rollback();
}
}
catch (\Exception $e) { ##这里参数不能删除($e错误信息)
Db::rollback();
return to_assign(1,$e->getMessage());
}
}
if($dbRes==true){
return to_assign();
}
else{
return to_assign(1,'保存失败');
}
}
//查看
public function view()
{
$id = empty(get_params('id')) ? 0 : get_params('id');
$expense = $this->detail($id );
View::assign('uid', $this->uid);
View::assign('expense', $expense);
return view();
}
//删除
public function delete()
{
$id = get_params("id");
$expense = $this->detail($id );
if($expense['check_status'] == 2){
return to_assign(1, "已审核的报销记录不能删除");
}
if($expense['check_status'] == 3){
return to_assign(1, "已打款的报销记录不能删除");
}
$data['status'] = '-1';
$data['id'] = $id;
$data['update_time'] = time();
if (Db::name('expense')->update($data) !== false) {
add_log('delete', $id);
return to_assign(0, "删除成功");
} else {
return to_assign(1, "删除失败");
}
}
//设置
public function check()
{
$param = get_params();
if (request()->isAjax()) {
if($param['check_status'] == 2 || $param['check_status'] == 0){
$param['check_admin_id'] = $this->uid;
$param['check_time'] = time();
}
if($param['check_status'] == 3){
$param['pay_admin_id'] = $this->uid;
$param['pay_time'] = time();
}
$res = ExpenseList::where('id', $param['id'])->strict(false)->field(true)->update($param);
if($res !==false){
return to_assign();
} else {
return to_assign(1, "操作失败");
}
} else {
$expense = $this->detail($param['id']);
View::assign('expense', $expense);
View::assign('uid', $this->uid);
return view();
}
}
}

5
app/home/event.php Normal file
View File

@ -0,0 +1,5 @@
<?php
// 这是系统自动生成的event定义文件
return [
];

15
app/home/model/Admin.php Normal file
View File

@ -0,0 +1,15 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\model;
use think\Model;
class Admin extends Model
{
}

View File

@ -0,0 +1,15 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\model;
use think\Model;
class AdminGroup extends Model
{
}

View File

@ -0,0 +1,52 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
declare (strict_types = 1);
namespace app\home\model;
use think\Model;
class AdminLog extends Model
{
public function get_log_list($param = [])
{
$where = array();
if (!empty($param['no_delete'])) {
$where['type'] = ['neq', 'delete']; //过滤删除操作
}
if (!empty($param['no_admin'])) {
$where['uid'] = ['neq', 1]; //超级管理员删除操作
}
if (!empty($param['uid'])) {
$where['uid'] = $param['uid']; //查询指定用户的操作
}
$where['status'] = 1;
$rows = empty($param['limit']) ? get_config('app.pages') : $param['limit'];
$content = \think\facade\Db::name('AdminLog')
->field("id,uid,nickname,type,title,module,controller,function,param,content,create_time")
->order('create_time desc')
->where($where)
->paginate($rows, false, ['query' => $param]);
$content->toArray();
foreach ($content as $k => $v) {
$data = $v;
$param_array = json_decode($v['param'], true);
$name = '';
if (!empty($param_array['name'])) {
$name = '' . $param_array['name'];
}
if (!empty($param_array['title'])) {
$name = '' . $param_array['title'];
}
$data['content'] = $v['content'] . $name;
$data['times'] = time_trans($v['create_time']);
$content->offsetSet($k, $data);
}
return $content;
}
}

View File

@ -0,0 +1,53 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\model;
use app\home\model\Keywords;
use think\Model;
class Article extends Model
{
// 获取文章详情
public function detail($id)
{
$article = \think\facade\Db::name('Article')->where(['id' => $id])->find();
if (empty($article)) {
return $this->error('文章不存在');
}
$keywrod_array = \think\facade\Db::name('ArticleKeywords')
->field('i.aid,i.keywords_id,k.title')
->alias('i')
->join('keywords k', 'k.id = i.keywords_id', 'LEFT')
->order('i.create_time asc')
->where(array('i.aid' => $id, 'k.status' => 1))
->select()->toArray();
$article['keyword_ids'] = implode(",", array_column($keywrod_array, 'keywords_id'));
$article['keyword_names'] = implode(',', array_column($keywrod_array, 'title'));
return $article;
}
//插入关键字
public function insertKeyword($keywordArray = [], $aid)
{
$insert = [];
$time = time();
foreach ($keywordArray as $key => $value) {
if (!$value) {
continue;
}
$keywords_id = (new Keywords())->increase($value);
$insert[] = ['aid' => $aid,
'keywords_id' => $keywords_id,
'create_time' => $time,
];
}
$res = \think\facade\Db::name('ArticleKeywords')->strict(false)->field(true)->insertAll($insert);
return $res;
}
}

View File

@ -0,0 +1,15 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\model;
use think\Model;
class ArticleCate extends Model
{
}

View File

@ -0,0 +1,7 @@
<?php
namespace app\home\model;
use think\Model;
class Expense extends Model
{
}

View File

@ -0,0 +1,15 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\model;
use think\Model;
class ExpenseCate extends Model
{
}

View File

@ -0,0 +1,26 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\model;
use think\Model;
// 关键字模型
class Keywords extends Model
{
// 关联关键字
public function increase($keywords)
{
$is_exist = $this->where('title', $keywords)->find();
if ($is_exist) {
$res = $is_exist['id'];
} else {
$res = $this->strict(false)->field(true)->insertGetId(['title' => $keywords, 'create_time' => time()]);
}
return $res;
}
}

60
app/home/model/Mail.php Normal file
View File

@ -0,0 +1,60 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\model;
use think\Model;
class Mail extends Model
{
// 垃圾消息来源[delete_source]
const SOURCE_ZERO = 0;
const SOURCE_ONE = 1;
const SOURCE_TWO = 2;
const SOURCE_THREE = 3;
// 阅览人类型[type]
const TYPE_ZERO = 0;
const TYPE_ONE = 1;
const TYPE_TWO = 2;
const TYPE_THREE = 3;
// 是否已读[is_read]
const READ_ONE = 1;
const READ_TWO = 2;
// 消息来源[mail_type]
const MAILTYPE_ZERO = 0;
const MAILTYPE_ONE = 1;
const MAILTYPE_TWO = 2;
const MAILTYPE_THREE = 3;
public static $Source = [
self::SOURCE_ZERO => '无',
self::SOURCE_ONE => '已发消息',
self::SOURCE_TWO => '草稿消息',
self::SOURCE_THREE => '已收消息',
];
public static $Type = [
self::TYPE_ZERO => '同事',
self::TYPE_ONE => '部门',
self::TYPE_TWO => '岗位',
self::TYPE_THREE => '全部',
];
public static $MailType = [
self::MAILTYPE_ONE => '系统消息',
self::SOURCE_TWO => '同事消息',
];
public static $Read = [
self::READ_ONE => '未读',
self::READ_TWO => '已读',
];
}

7
app/home/model/Note.php Normal file
View File

@ -0,0 +1,7 @@
<?php
namespace app\home\model;
use think\Model;
class Note extends Model
{
}

View File

@ -0,0 +1,15 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\model;
use think\Model;
class NoteCate extends Model
{
}

View File

@ -0,0 +1,8 @@
<?php
namespace app\home\model;
use think\Db;
use think\Model;
class Schedule extends Model
{
}

15
app/home/model/User.php Normal file
View File

@ -0,0 +1,15 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\model;
use think\Model;
class User extends Model
{
}

View File

@ -0,0 +1,62 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\validate;
use think\Validate;
class AdminCheck extends Validate
{
protected $regex = [ 'checkUser' => '/^[A-Za-z]{1}[A-Za-z0-9_-]{4,19}$/'];
protected $rule = [
'name' => 'require|chs',
'username' => 'require|regex:checkUser|unique:admin',
'mobile' => 'require|mobile|unique:admin',
'reg_pwd' => 'require|min:6',
'did' => 'require',
'position_id' => 'require',
'type' => 'require',
'entry_time' => 'require',
'id' => 'require',
'status' => 'require|checkStatus:-1,1',
'old_pwd' => 'require|different:pwd',
'edit_pwd' => 'min:6|confirm',
];
protected $message = [
'name.require' => '员工姓名不能为空',
'name.chs' => '员工姓名只能是汉字',
'username.require' => '登录账号不能为空',
'username.regex' => '登录账号必须是以字母开头只能包含字母数字下划线和减号5到20位',
'username.unique' => '同样的登录账号已经存在建议增加数字xxx123',
'mobile.require' => '手机不能为空',
'mobile.mobile' => '手机格式错误',
'mobile.unique' => '同样的手机号码已经存在,请检查一下是否被离职或者禁用员工占用',
'reg_pwd.require' => '密码不能为空',
'reg_pwd.min' => '密码至少要6个字符',
'did.require' => '请选择所在部门',
'position_id.require' => '请选择职位',
'type.require' => '请选择员工类型',
'entry_time.require' => '请选择入职时间',
'id.require' => '缺少更新条件',
'pwd.require' => '密码不能为空',
'pwd.min' => '密码至少要6个字符',
'edit_pwd.min' => '密码至少要6个字符',
'edit_pwd.confirm' => '两次密码不一致',
'old_pwd.require' => '请提供旧密码',
'old_pwd.different' => '新密码不能和旧密码一样',
];
protected $scene = [
'add' => ['name', 'username', 'mobile','reg_pwd', 'did', 'position_id', 'type', 'entry_time'],
'edit' => ['name', 'username', 'mobile', 'did', 'position_id', 'entry_time', 'id'],
'editPersonal' => ['mobile', 'name', 'id'],
'editpwd' => ['old_pwd', 'pwd', 'id'],
];
}

View File

@ -0,0 +1,29 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\validate;
use think\Validate;
class ArticleCateCheck extends Validate
{
protected $rule = [
'title' => 'require|unique:article_cate',
'id' => 'require',
];
protected $message = [
'title.require' => '名称不能为空',
'title.unique' => '同样的名称已经存在',
'id.require' => '缺少更新条件',
];
protected $scene = [
'add' => ['title'],
'edit' => ['id', 'title'],
];
}

View File

@ -0,0 +1,34 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\validate;
use think\Validate;
class ArticleCheck extends Validate
{
protected $rule = [
'title' => 'require|unique:article',
'content' => 'require',
'id' => 'require',
'article_cate_id' => 'require',
'status' => 'require',
];
protected $message = [
'title.require' => '标题不能为空',
'title.unique' => '同样的文章标题已经存在',
'article_cate_id.require' => '所属分类为必选',
'id.require' => '缺少更新条件',
'status.require' => '状态为必选',
];
protected $scene = [
'add' => ['title', 'article_cate_id', 'content', 'status'],
'edit' => ['title', 'article_cate_id', 'content', 'id', 'status'],
];
}

View File

@ -0,0 +1,25 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\validate;
use think\Validate;
class ConfCheck extends Validate
{
protected $rule = [
'title' => 'require|unique:config',
'name' => 'require|unique:config',
];
protected $message = [
'title.require' => '配置名称不能为空',
'title.unique' => '同样的配置名称已经存在',
'name.require' => '配置标识不能为空',
'name.unique' => '同样的配置标识已经存在',
];
}

View File

@ -0,0 +1,29 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\validate;
use think\Validate;
class DepartmentCheck extends Validate
{
protected $rule = [
'title' => 'require|unique:department',
'id' => 'require',
];
protected $message = [
'title.require' => '部门名称不能为空',
'title.unique' => '同样的部门名称已经存在',
'id.require' => '缺少更新条件',
];
protected $scene = [
'add' => ['title'],
'edit' => ['id', 'title'],
];
}

View File

@ -0,0 +1,29 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\validate;
use think\Validate;
class ExpenseCateCheck extends Validate
{
protected $rule = [
'title' => 'require|unique:expense_cate',
'id' => 'require',
];
protected $message = [
'title.require' => '名称不能为空',
'title.unique' => '同样的名称已经存在',
'id.require' => '缺少更新条件',
];
protected $scene = [
'add' => ['title'],
'edit' => ['id', 'title'],
];
}

View File

@ -0,0 +1,23 @@
<?php
namespace app\home\validate;
use think\Validate;
class ExpenseCheck extends Validate
{
protected $rule = [
'code' => 'require',
'id' => 'require',
'status' => 'require'
];
protected $message = [
'code.require' => '报销凭证编号不能为空',
'id.require' => '缺少更新条件',
'status.require' => '状态为必选',
];
protected $scene = [
'add' => ['code'],
'edit' => ['id', 'code']
];
}

View File

@ -0,0 +1,41 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\validate;
use think\Validate;
class GroupCheck extends Validate
{
protected $rule = [
'title' => 'require|unique:admin_group',
'id' => 'require',
'status' => 'require|checkStatus:-1,1',
];
protected $message = [
'title.require' => '名称不能为空',
'title.unique' => '同样的记录已经存在',
'id.require' => '缺少更新条件',
'status.require' => '状态为必选',
'status.checkStatus' => '系统所有者组不能被禁用',
];
protected $scene = [
'add' => ['title', 'status'],
'edit' => ['id', 'title', 'status'],
];
// 自定义验证规则
protected function checkStatus($value, $rule, $data)
{
if ($value == -1 and $data['id'] == 1) {
return $rule == false;
}
return $rule == true;
}
}

View File

@ -0,0 +1,31 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\validate;
use think\facade\Db;
use think\Validate;
class KeywordsCheck extends Validate
{
protected $rule = [
'title' => 'require|unique:keywords',
'id' => 'require',
];
protected $message = [
'title.require' => '关键字名称不能为空',
'title.unique' => '同样的关键字名称已经存在',
'id.require' => '缺少更新条件',
];
protected $scene = [
'add' => ['title'],
'edit' => ['id', 'title'],
];
}

View File

@ -0,0 +1,29 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\validate;
use think\Validate;
class MenuCheck extends Validate
{
protected $rule = [
'title' => 'require|unique:admin_menu',
'id' => 'require',
];
protected $message = [
'title.require' => '菜单名称不能为空',
'title.unique' => '同样的菜单名称已经存在',
'id.require' => '缺少更新条件',
];
protected $scene = [
'add' => ['title'],
'edit' => ['id','title'],
];
}

View File

@ -0,0 +1,29 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\validate;
use think\Validate;
class NoteCateCheck extends Validate
{
protected $rule = [
'title' => 'require|unique:note_cate',
'id' => 'require',
];
protected $message = [
'title.require' => '名称不能为空',
'title.unique' => '同样的名称已经存在',
'id.require' => '缺少更新条件',
];
protected $scene = [
'add' => ['title'],
'edit' => ['id', 'title'],
];
}

View File

@ -0,0 +1,24 @@
<?php
namespace app\home\validate;
use think\Validate;
class NoteCheck extends Validate
{
protected $rule = [
'title' => 'require|unique:note',
'id' => 'require',
'status' => 'require'
];
protected $message = [
'title.require' => '标题不能为空',
'title.unique' => '同样的记录已经存在!',
'id.require' => '缺少更新条件',
'status.require' => '状态为必选',
];
protected $scene = [
'add' => ['title'],
'edit' => ['id', 'title']
];
}

View File

@ -0,0 +1,34 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\validate;
use think\Validate;
class PositionCheck extends Validate
{
protected $rule = [
'title' => 'require|unique:position',
'work_price' => 'require|number',
'group_id' => 'require',
'id' => 'require'
];
protected $message = [
'title.require' => '岗位名称不能为空',
'title.unique' => '同样的岗位名称已经存在',
'work_price.require' => '岗位工时单价不能为空',
'work_price.number' => '岗位工时单价只能是整数',
'group_id.require' => '至少要选择一个角色权限',
'id.require' => '缺少更新条件',
];
protected $scene = [
'add' => ['title', 'work_price', 'group_id'],
'edit' => ['title', 'work_price', 'group_id', 'id'],
];
}

View File

@ -0,0 +1,33 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\validate;
use think\Validate;
class RuleCheck extends Validate
{
protected $rule = [
'title' => 'require|unique:admin_rule',
'src' => 'unique:admin_rule',
'id' => 'require',
];
protected $message = [
'title.require' => '节点名称不能为空',
'title.unique' => '同样的节点名称已经存在',
'src.unique' => '同样的节点规则已经存在',
'id.require' => '缺少更新条件',
'filed.require' => '缺少要更新的字段名',
];
protected $scene = [
'add' => ['title','src'],
'edit_title' => ['id', 'title'],
'edit_src' => ['id', 'src'],
];
}

View File

@ -0,0 +1,26 @@
<?php
/**
* @copyright Copyright (c) 2021 勾股工作室
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.gougucms.com
*/
namespace app\home\validate;
use think\Validate;
class UserCheck extends Validate
{
protected $rule = [
'username' => 'require',
'password' => 'require',
'captcha' => 'require|captcha',
];
protected $message = [
'username.require' => '用户名不能为空',
'password.require' => '密码不能为空',
'captcha.require' => '验证码不能为空',
'captcha.captcha' => '验证码不正确',
];
}

View File

@ -0,0 +1,240 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<form class="layui-form body-content">
{if condition="$id eq 0"}
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray">员工姓名<font>*</font></td>
<td>
<input type="text" name="name" lay-verify="required" placeholder="请输入员工姓名" lay-reqText="请输入员工姓名" autocomplete="off" class="layui-input">
</td>
<td class="layui-td-gray">手机号码<font>*</font></td>
<td>
<input type="text" name="mobile" lay-verify="required" placeholder="可使用手机号码登录" lay-reqText="请输入手机" autocomplete="off" class="layui-input">
</td>
<td class="layui-td-gray">初始密码</td>
<td>
{$reg_pwd}
<input type="hidden" name="reg_pwd" value="{$reg_pwd}" lay-verify="required">
</td>
</tr>
<tr>
<td class="layui-td-gray">入职日期<font>*</font></td>
<td>
<input type="text" id="entry_time" name="entry_time" readonly lay-verify="required" placeholder="请选择入职日期" lay-reqText="请选择入职日期" autocomplete="off" class="layui-input">
</td>
<td class="layui-td-gray">员工性别<font>*</font></td>
<td>
<input type="radio" name="sex" value="1" title="男">
<input type="radio" name="sex" value="2" title="女">
</td>
<td rowspan="3" class="layui-td-gray2">头像<br /><span style="font-size: 12px;">(如若不上传<br />系统将自动生成)</span></td>
<td rowspan="3" valign="top" style="width: 100px;">
<div class="layui-upload" style="width: 100px;">
<div class="layui-upload-list" id="demo1" style="width: 100%; height:100px; overflow: hidden;">
<img src="/static/home/images/nonepic600x600.jpg" height="100" style="max-width: 100%; width: 100%;" />
<input type="hidden" name="thumb" value="">
</div>
<button type="button" class="layui-btn layui-btn-normal" style="width: 100%;" id="test1">上传头像</button>
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray">所在部门<font>*</font></td>
<td>
<select name="did" lay-verify="required" lay-reqText="请选择所属部门">
<option value="">请选择所属部门</option>
{volist name="department" id="v"}
<option value="{$v.id}">{$v.title}</option>
{/volist}
</select>
</td>
<td class="layui-td-gray">岗位职称<font>*</font></td>
<td>
<select name="position_id" lay-verify="required" lay-reqText="请选择岗位职称">
<option value="">请选择岗位职称</option>
{volist name="position" id="v"}
<option value="{$v.id}">{$v.title}</option>
{/volist}
</select>
</td>
</tr>
<tr>
<td class="layui-td-gray">员工类型<font>*</font></td>
<td colspan="3">
<input type="radio" name="type" value="3" title="实习">
<input type="radio" name="type" value="2" title="试用">
<input type="radio" name="type" value="1" title="正式">
</td>
</tr>
<tr>
<td class="layui-td-gray">账号状态</td>
<td colspan="5">
<input type="radio" name="status" value="0" title="禁止登录">
<input type="radio" name="status" value="1" title="正常" checked>
<input type="radio" name="status" value="2" title="离职">
</td>
</tr>
<tr>
<td class="layui-td-gray">员工简介</td>
<td colspan="7">
<textarea name="desc" placeholder="请输入员工简介" class="layui-textarea"></textarea>
</td>
</tr>
</table>
{else/}
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray2">员工姓名<font>*</font></td>
<td>
<input type="text" name="name" value="{$detail.name}" lay-verify="required" placeholder="请输入员工姓名" lay-reqText="请输入员工姓名" autocomplete="off" class="layui-input">
</td>
<td class="layui-td-gray2">登录账号</td>
<td>
{$detail.username}
</td>
<td class="layui-td-gray2">初始密码</td>
<td>
{empty name="$detail.reg_pwd"}
密码已重置
{else/}
{$detail.reg_pwd}
{/empty}
</td>
</tr>
<tr>
<td class="layui-td-gray2">手机号码<font>*</font></td>
<td>
<input type="text" name="mobile" value="{$detail.mobile}" lay-verify="required" placeholder="可使用手机号码登录" lay-reqText="请输入手机" autocomplete="off" class="layui-input">
</td>
<td class="layui-td-gray2">员工性别<font>*</font></td>
<td>
<input type="radio" name="sex" value="1" title="男" {eq name="$detail.sex" value="1"}checked{/eq}>
<input type="radio" name="sex" value="2" title="女" {eq name="$detail.sex" value="2"}checked{/eq}>
</td>
<td rowspan="3" class="layui-td-gray2">头像<br /><span style="font-size: 12px;">(如若不上传<br />系统将自动生成)</span></td>
<td rowspan="3" valign="top" style="width: 100px;">
<div class="layui-upload" style="width: 100px;">
<div class="layui-upload-list" id="demo1" style="width: 100%; height:100px; overflow: hidden;">
<img src="{$detail.thumb}" height="100" style="max-width: 100%; width: 100%;" />
<input type="hidden" name="thumb" value="{$detail.thumb}">
</div>
<button type="button" class="layui-btn layui-btn-normal" style="width: 100%;" id="test1">上传头像</button>
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray2">所在部门<font>*</font></td>
<td>
<select name="did" lay-verify="required" lay-reqText="请选择所属部门">
<option value="">请选择所属部门</option>
{volist name="department" id="v"}
<option value="{$v.id}" {eq name="$v.id" value="$detail.did"}selected{/eq}>{$v.title}</option>
{/volist}
</select>
</td>
<td class="layui-td-gray2">岗位职称<font>*</font></td>
<td>
<select name="position_id" lay-verify="required" lay-reqText="请选择岗位职称">
<option value="">请选择岗位职称</option>
{volist name="position" id="v"}
<option value="{$v.id}" {eq name="$v.id" value="$detail.position_id"}selected{/eq}>{$v.title}</option>
{/volist}
</select>
</td>
</tr>
<tr>
<td class="layui-td-gray2">入职日期<font>*</font></td>
<td>
<input type="text" id="entry_time" value="{$detail.entry_time|time_format=###,'Y-m-d'}" name="entry_time" readonly lay-verify="required" placeholder="请选择入职日期" lay-reqText="请选择入职日期" autocomplete="off" class="layui-input">
</td>
<td class="layui-td-gray2">员工类型<font>*</font></td>
<td>
<input type="radio" name="type" value="3" title="实习" {eq name="$detail.type" value="3"}checked{/eq}>
<input type="radio" name="type" value="2" title="试用" {eq name="$detail.type" value="2"}checked{/eq}>
<input type="radio" name="type" value="1" title="正式" {eq name="$detail.type" value="1"}checked{/eq}>
</td>
</tr>
<tr>
<td class="layui-td-gray2">账号状态</td>
<td colspan="5">
{eq name="$detail.status" value="0"}<span style="color:#FF5722">禁止登录</span>{/eq}
{eq name="$detail.status" value="1"}<span style="color:#009688">正常</span>{/eq}
{eq name="$detail.status" value="2"}<span style="color:#FFB800">已离职</span>{/eq}
</td>
</tr>
<tr>
<td class="layui-td-gray2">员工简介</td>
<td colspan="7">
<textarea name="desc" placeholder="请输入员工简介" class="layui-textarea">{$detail.desc}</textarea>
</td>
</tr>
</table>
{/if}
<div style="padding: 10px 0">
<input type="hidden" value="{$id}" name="id">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var TAB = parent.layui.tab,
form = layui.form,
layer = layui.layer,
laydate = layui.laydate,
upload = layui.upload;
//日期选择
laydate.render({
elem: '#entry_time',
max:7,
showBottom: false
});
//头像上传
var uploadInst = upload.render({
elem: "#test1",
url: "{:url('home/api/upload')}",
done: function (e) {
//如果上传失败
if (e.code == 1) {
return layer.msg('上传失败');
}
//上传成功
$('#demo1 input').attr('value', e.data.filepath);
$('#demo1 img').attr('src', e.data.filepath);
}
});
//监听提交
form.on('submit(webform)', function (data) {
$.ajax({
url: "{:url('home/admin/post_submit')}",
type: 'post',
data: data.field,
success: function (e) {
if (e.code == 0) {
layer.confirm('保存成功,返回列表页吗?', { icon: 3, title: '提示' }, function (index) {
parent.location.reload();
});
} else {
layer.msg(e.msg);
}
}
})
return false;
});
}
</script>
{include file="common/layui" base='base' extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,67 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<form class="layui-form body-content">
<h3 style="height:36px">重置密码</h3>
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray2">用户名 <span style="color: red">*</span></td>
<td><input type="text" lay-verify="required" autocomplete="off" placeholder="" class="layui-input"
value="{$admin.username}" disabled></td>
<td class="layui-td-gray2">旧密码<span style="color: red">*</span></td>
<td>
<input type="password" lay-verify="required" name="old_pwd" placeholder="请输入旧密码" lay-reqText="请输入旧密码" autocomplete="off" class="layui-input">
</td>
</tr>
<tr>
<td class="layui-td-gray2">新密码 <span style="color: red">*</span></td>
<td>
<input type="password" lay-verify="required" name="pwd" placeholder="请输入新密码" lay-reqText="请输入新密码" autocomplete="off" class="layui-input">
</td>
<td class="layui-td-gray2">确认新密码 <span style="color: red">*</span></td>
<td>
<input type="password" lay-verify="required" name="pwd_confirm" placeholder="请再次输入新密码" lay-reqText="请再次输入新密码" autocomplete="off" class="layui-input">
</td>
</tr>
</table>
<div style="padding: 10px 0">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var TAB = parent.layui.tab,
form = layui.form,
layer = layui.layer;
//监听提交
form.on('submit(webform)', function (data) {
$.ajax({
url: "{:url('home/api/personal_submit')}",
type: 'post',
data: data.field,
success: function (e) {
if (e.code == 0) {
layer.msg('修改密码成功');
setTimeout(function () {
TAB.sonDelete();
layer.close(index);
}, 1000)
} else {
layer.msg(e.msg);
}
}
})
return false;
});
}
</script>
{include file="common/layui" base='base' extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,93 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<form class="layui-form body-content">
<h3 style="height:36px">修改个人信息</h3>
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray2">用户名 <span style="color: red">*</span></td>
<td><input type="text" lay-verify="required" autocomplete="off" placeholder="请输入节点名称" class="layui-input"
value="{$admin.username}" disabled></td>
<td class="layui-td-gray2" rowspan="3">头像</td>
<td rowspan="3">
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-normal" id="test1">上传头像</button>
<div class="layui-upload-list" id="demo1">
<img src="{$admin.thumb}" width="100" />
<input type="hidden" name="thumb" value="{$admin.thumb}">
</div>
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray2">昵称<span style="color: red">*</span></td>
<td>
<input type="text" name="nickname" lay-verify="required" placeholder="请输入昵称" lay-reqText="请输入昵称"
autocomplete="off" class="layui-input" value="{$admin.nickname}">
</td>
</tr>
<tr>
<td class="layui-td-gray2">手机</td>
<td><input type="text" name="mobile" lay-verify="required" placeholder="请输入手机" autocomplete="off"
class="layui-input" value="{$admin.mobile}"></td>
</tr>
</table>
<div style="padding: 10px 0">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var TAB = parent.layui.tab,
form = layui.form,
layer = layui.layer,
upload = layui.upload;
//头像上传
var uploadInst = upload.render({
elem: '#test1'
, url: "{:url('home/api/upload')}",
, done: function (e) {
//如果上传失败
if (e.code == 1) {
return layer.msg('上传失败');
}
else{
//上传成功
$('#demo1 input').attr('value', e.data.filepath);
$('#demo1 img').attr('src', e.data.filepath);
}
}
});
//监听提交
form.on('submit(webform)', function (data) {
$.ajax({
url: "{:url('home/api/personal_submit')}",
type: 'post',
data: data.field,
success: function (e) {
if (e.code == 0) {
layer.confirm('保存成功,关闭本页面吗?', { icon: 3, title: '提示' }, function (index) {
TAB.sonDelete();
layer.close(index);
});
} else {
layer.msg(e.msg);
}
}
})
return false;
});
}
</script>
{include file="common/layui" base='base' extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,371 @@
{extend name="common/base"/}
{block name="style"}
<style>
html,body{height: calc(100% - 18px);}
.layui-tree-entry{font-size:15px; line-height:24px}
.layui-tree-set{padding:2px 0}
.layui-tree-iconClick .layui-icon{color:#1E9FFF}
.layui-tree-icon {height: 14px;line-height: 14px; width: 14px;text-align: center;border: 1px solid #1E9FFF; color:#1E9FFF}
.layui-tree-line .layui-tree-set .layui-tree-set:after{top:18px;}
.tree-left{width:200px; float:left; height:calc(100% - 30px); overflow: scroll; border:1px solid #e6e6e6; background-color:#f8f8f8; padding:12px 12px 12px 5px;}
.tree-left h3{font-size:16px; height:30px; padding-left:10px; font-weight:800}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<div class="body-content" style="height: 100%">
<div class="tree-left">
<h3>企业组织架构</h3>
<div id="depament"></div>
</div>
<div style="margin-left:228px;">
<form class="layui-form">
<div class="layui-input-inline" style="width:136px">
<select name="status">
<option value="">选择员工状态</option>
<option value="1">正常状态</option>
<option value="2">离职状态</option>
<option value="0">禁止登录</option>
</select>
</div>
<div class="layui-input-inline" style="width:136px">
<select name="type">
<option value="">选择员工类型</option>
<option value="1">正式员工</option>
<option value="2">试用员工</option>
<option value="3">实习员工</option>
</select>
</div>
<div class="layui-input-inline" style="width:240px">
<input type="text" name="keywords" placeholder="输入关键字ID/姓名/手机号码" class="layui-input" autocomplete="off" />
</div>
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">提交搜索</button>
</form>
<table class="layui-hide" id="test" lay-filter="test"></table>
</div>
</div>
<script type="text/html" id="thumb">
<img src="{{d.thumb}}" width="30" height="30" />
</script>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-normal layui-btn-sm" lay-event="add"><i class="layui-icon">&#xe61f;</i>添加员工</button>
<button class="layui-btn layui-btn-warm layui-btn-sm" lay-event="leave"><i class="layui-icon">&#xe616;</i>设为离职</button>
<button class="layui-btn layui-btn-danger layui-btn-sm" lay-event="disable"><i class="layui-icon">&#x1006;</i>禁止登录</button>
<button class="layui-btn layui-btn-sm" lay-event="recovery"><i class="layui-icon">&#xe605;</i>恢复正常</button>
</div>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var TAB = parent.layui.tab,
tree = layui.tree,
table = layui.table,
rightpage = layui.rightpage,
form = layui.form;
$.ajax({
url:"{:url('home/api/get_department_tree')}",
type:'post',
success:function(res){
//仅节点左侧图标控制收缩
tree.render({
elem: '#depament',
data: res.trees,
onlyIconControl: true, //是否仅允许节点左侧图标控制展开收缩
click: function(obj){
//layer.msg(JSON.stringify(obj.data));
tableIns.reload({
where: {did: obj.data.id}
,page:{curr:1}
});
$('[name="keywords"]').val('');
$('[name="status"]').val('');
$('[name="type"]').val('');
layui.form.render('select');
}
});
}
})
var tableIns = table.render({
elem: '#test',
title: '员工列表',
toolbar: '#toolbarDemo',
url: "{:url('home/admin/index')}", //数据接口
page: true, //开启分页
limit: 20,
cols: [
[
{type:'checkbox',fixed:'left'},
{
field: 'id',
title: 'ID号',
align: 'center',
width: 80
}, {
field: 'status',
title: '状态',
align: 'center',
width: 80,
templet: function (d) {
var html = '<span class="layui-badge layui-bg-green">正常</span>';
if(d.status == 2){
html = '<span class="layui-badge layui-bg-orange">已离职</span>'
}
else if(d.status == 0){
html = '<span class="layui-badge">被禁用</span>'
}
return html;
}
},{
field: 'type',
title: '员工类型',
align: 'center',
width: 90,
templet: function (d) {
var html = '<span style="color:#393D49">正式员工</span>';
if(d.type == 2){
html = '<span style="color:#01AAED">试用员工</span>'
}
else if(d.type == 3){
html = '<span style="color:#5FB878">实 习 生</span>'
}
return html;
}
}, {
field: 'username',
title: '登录账号',
width: 136
}, {
field: 'thumb',
title: '头像',
toolbar: '#thumb',
align: 'center',
width: 60
}, {
field: 'name',
title: '用户姓名',
align: 'center',
width: 90
},{
field: 'mobile',
title: '手机号码',
align: 'center',
width: 120
},{
field: 'sex',
title: '性别',
align: 'center',
width: 60,
templet: function (d) {
var html = '未知';
if(d.sex == 1){
html = '男'
}
else if(d.sex == 2){
html = '女'
}
return html;
}
},{
field: 'department',
title: '所在部门',
align: 'center',
width: 110
}, {
field: 'position',
title: '岗位职称',
align: 'center',
width: 110
}, {
field: 'entry_time',
title: '入职日期',
align: 'center',
width: 100
}, {
field: 'login_num',
title: '累计登录',
align: 'center',
width: 80
}, {
field: 'last_login_time',
title: '最后登录时间',
align: 'center',
width: 136
},{
field: 'right',
fixed:'right',
title: '操作',
width: 160,
align: 'center',
templet: function (d) {
var html = '';
var btn1 = '<span class="layui-btn layui-btn-xs layui-btn-normal" lay-event="view">详情</span>';
var btn2 = '<span class="layui-btn layui-btn-xs" lay-event="edit">编辑</span>';
var btn3 = '<span class="layui-btn layui-btn-xs layui-btn-warm" lay-event="copy">复制密码</span>';
var btn4 = '<span class="layui-btn layui-btn-xs layui-btn-warm" lay-event="psw">重置密码</span>';
if(d.reg_pwd == ''){
html = '<div class="layui-btn-group">'+btn1+btn2+btn4+'</div>';
}
else{
html = '<div class="layui-btn-group">'+btn1+btn2+btn3+'</div>';
}
return html;
}
}
]
]
});
//表头工具栏事件
table.on('toolbar(test)', function(obj){
var checkStatus = table.checkStatus(obj.config.id); //获取选中行状态
var data = checkStatus.data;
if (obj.event === 'add') {
rightpage.open("{:url('home/admin/add')}");
return;
}
if(data.length==0){
layer.msg('请选择要操作的员工');
return false;
}
var uidArray=[],msg='是否执行该操作?',type=0;
for(var i=0;i<data.length;i++){
uidArray.push(data[i].id);
}
switch(obj.event){
case 'disable':
msg = '您确定要把选中的员工设为禁止登录?';
type = 0;
break;
case 'recovery':
msg = '您确定要把选中的员工恢复正常?';
type = 1;
break;
case 'leave':
msg = '您确定要把选中的员工设为离职?';
type = 2;
break;
};
layer.confirm(msg, {
icon: 3,
title: '提示'
}, function (index) {
$.ajax({
url: "{:url('home/admin/set')}",
data: {
ids: uidArray.join(','),
type:type
},
success: function (e) {
layer.msg(e.msg);
if(e.code==0){
tableIns.reload();
}
}
})
layer.close(index);
});
});
//监听行工具事件
table.on('tool(test)', function (obj) {
var data = obj.data;
if (obj.event === 'view') {
//TAB.sonAdd('/home/admin/view?id='+data.id,'员工详情');
rightpage.open('/home/admin/view?id='+data.id);
return;
}
if(obj.event === 'edit'){
rightpage.open('/home/admin/add?id='+data.id);
}
else if (obj.event === 'copy') {
copyToClip(data.reg_pwd);
return;
}
else if (obj.event === 'psw') {
resetPsw(data.id);
return;
}
});
//监听搜索提交
form.on('submit(webform)', function (data) {
tableIns.reload({
where: {
keywords: data.field.keywords,
status: data.field.status,
type: data.field.type
},
page: {
curr: 1
}
});
return false;
});
}
//重设密码
function resetPsw(id){
layer.confirm('确定要重设该用户的密码?', {
icon: 3,
title: '提示'
}, function (index) {
$.ajax({
url: "{:url('home/admin/reset_psw')}",
data: {
id: id
},
success: function (e) {
layer.msg(e.msg);
if(e.code==0){
setTimeout(function(){
location.reload();
},2000);
}
}
})
layer.close(index);
});
}
//拷贝密码
function copyToClip(content) {
if (navigator.clipboard) {
// clipboard api 澶嶅埗
navigator.clipboard.writeText(content);
} else {
var copy_textarea = document.createElement('textarea');
// 闅愯棌姝よ緭鍏ユ
copy_textarea.style.position = 'fixed';
copy_textarea.style.clip = 'rect(0 0 0 0)';
copy_textarea.style.top = '10px';
copy_textarea.value = content;
document.body.appendChild(copy_textarea);
// 閫変腑
copy_textarea.select();
// 澶嶅埗
document.execCommand('copy', true);
// 绉婚櫎杈撳叆妗<E58F86>
document.body.removeChild(copy_textarea);
}
if (content != '') {
layer.msg('复制成功');
}
}
</script>
{include file="common/layui" base='base' extend="['rightpage']" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,102 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<div class="body-content">
<form class="layui-form">
<div class="layui-input-inline" style="width:300px;">
<input type="text" name="keywords" placeholder="昵称/操作节点名称/操作数据ID" class="layui-input" autocomplete="off" />
</div>
<div class="layui-input-inline">
<select name="title_cate">
<option value="">请选择类型</option>
<option value="登录">登录操作</option>
<option value="上传">上传操作</option>
<option value="新增">新增操作</option>
<option value="编辑">编辑操作</option>
<option value="查看">查看操作</option>
<option value="删除">删除操作</option>
</select>
</div>
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">提交搜索</button>
</form>
<table class="layui-hide" id="test" lay-filter="test"></table>
</div>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var table = layui.table,
form = layui.form;
var tableIns = table.render({
elem: '#test',
title: '操作日志列表',
toolbar: '#toolbarDemo',
url: "{:url('home/admin/log')}", //数据接口
page: true, //开启分页
limit: 20,
cols: [
[ //表头
{
field: 'id',
title: 'ID号',
align: 'center',
width: 90
}, {
field: 'title',
title: '操作',
width: 150
}, {
field: 'content',
title: '操作描述',
width: 348
}, {
field: 'param_id',
title: '操作数据ID',
align: 'center',
width: 100
}, {
field: 'param',
title: '操作数据'
}, {
field: 'nickname',
title: '操作用户',
align: 'center',
width: 100
}, {
field: 'ip',
title: 'IP地址',
align: 'center',
width: 150
}, {
field: 'create_time',
title: '操作时间',
fixed: 'right',
align: 'center',
width: 160
}
]
]
});
//监听搜索提交
form.on('submit(webform)', function (data) {
tableIns.reload({
where: {
keywords: data.field.keywords,
title_cate: data.field.title_cate
},
page: {
curr: 1
}
});
return false;
});
}
</script>
{include file="common/layui" base='base' extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,62 @@
{extend name="common/base"/}
{block name="style"}
<style type="text/css">
.table-title{font-size: 20px; padding-bottom: 12px;}
.latest-news{padding-top: 12px; padding-bottom:30px; padding-left: 20px; position: relative;}
.latest-news .layui-timeline-title{padding-bottom:0; font-size: 14px;}
.latest-news .layui-timeline-item{padding-bottom:5px;}
.layui-timeline-title span{color:#999}
.panel-more{width: 100%; height:48px; line-height: 48px; text-align: center; position: absolute; bottom: 0; left:0; background: linear-gradient(rgba(225,225,225,0),rgba(225,225,225,.8));}
.panel-more a{color:#0088FF}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<div class="body-content" style="padding: 20px;">
<div class="table-title">最新动态</div>
<div class="latest-news">
<ul class="layui-timeline" id="logs">
</ul>
<div class="panel-more"><a href="javascript:getLogs();">查看更多动态</a></div>
</div>
</div>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
var page=1,limit=20;
function getLogs() {
$.ajax({
url: "{:url('home/api/get_log_list')}",
type: 'post',
data: {
page:page,
limit: limit
},
success: function(e) {
if (e.code == 0) {
var html = '';
if(e.data.length>0){
page++;
$.each(e.data, function(key, value) {
html += '<li class="layui-timeline-item">\
<i class="layui-icon layui-timeline-axis"></i>\
<div class="layui-timeline-content layui-text">\
<div class="layui-timeline-title"><span title="'+value.id+'">'+value.times+'</span>'+value.content+'</div>\
</div>\
</li>';
});
$('#logs').append(html);
}else{
$('.panel-more').remove();
}
}
}
})
}
getLogs();
</script>
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,229 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<form class="layui-form body-content">
<h3 style="font-weight:600; padding:10px 0">基本信息</h3>
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray">登录账号</td>
<td>
{$detail.username}
</td>
<td class="layui-td-gray">登录密码</td>
<td>
{empty name="$detail.reg_pwd"}
密码已重置
<span class="layui-btn layui-btn-normal layui-btn-xs" onclick="resetPsw({$detail.id});">重设新密码</span>
{else/}
{$detail.reg_pwd}
<span class="layui-btn layui-btn-normal layui-btn-xs" onclick="copyToClip('{$detail.reg_pwd}');">复制初始密码</span>
{/empty}
</td>
<td class="layui-td-gray">员工状态</td>
<td>
{eq name="$detail.status" value="0"}<span style="color:#FF5722">禁止登录</span>{/eq}
{eq name="$detail.status" value="1"}<span style="color:#009688">正常</span>{/eq}
{eq name="$detail.status" value="2"}<span style="color:#FFB800">已离职</span>{/eq}
</td>
<td rowspan="3" class="layui-td-gray">头像</td>
<td rowspan="3" valign="top" style="width: 100px;">
<div class="layui-upload">
<img src="{$detail.thumb}" style="width:100px; height:100px; max-width:100%" />
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray">员工姓名</td>
<td>
{$detail.name}
</td>
<td class="layui-td-gray">手机号码</td>
<td>
{$detail.mobile}
</td>
<td class="layui-td-gray">性别</td>
<td>
{eq name="$detail.sex" value="0"}未知{/eq}
{eq name="$detail.sex" value="1"}男{/eq}
{eq name="$detail.sex" value="2"}女{/eq}
</td>
</tr>
<tr>
<td class="layui-td-gray">所在部门</td>
<td>{$detail.department}</td>
<td class="layui-td-gray">岗位职称</td>
<td>{$detail.position}</td>
<td class="layui-td-gray">入职日期</td>
<td>
{$detail.entry_time | date='Y-m-d'}
</td>
</tr>
<tr>
<td class="layui-td-gray">员工类型</td>
<td>
{eq name="$detail.type" value="0"}<span style="color:#5FB878">实 习 生</span>{/eq}
{eq name="$detail.type" value="1"}<span style="color:#01AAED">试用员工</span>{/eq}
{eq name="$detail.type" value="2"}<span style="color:#393D49">正式员工</span>{/eq}
</td>
<td class="layui-td-gray2">最后登录时间</td>
<td>
{$detail.last_login_time}
</td>
<td class="layui-td-gray">最后登录IP</td>
<td>
{$detail.last_login_ip}
</td>
<td class="layui-td-gray2">累计登录次数</td>
<td>
{$detail.login_num}
</td>
</tr>
<tr>
<td class="layui-td-gray">员工简介</td>
<td colspan="7">
{$detail.desc}
</td>
</tr>
</table>
<h3 style="font-weight:600; padding:10px 0">用户权限</h3>
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray2" style="vertical-align:top">权限配置<br>操作菜单可见</td>
<td colspan="3">
<table style="width:100%">
{volist name="role_menu" id="vo"}
<tr>
<td style="font-weight:800">
<input type="checkbox" disabled value="{$vo.id}" title="{$vo.title}" {eq name="$vo.checked" value="true" }checked{/eq}>
</td>
{notempty name="vo.children"}
<td>
<div style="padding:10px 0;">
{volist name="vo.children" key="k" id="voo"}
<div class="layui-input-inline" style="margin-right:10px; font-weight:800">
<input type="checkbox" disabled value="{$voo.id}" lay-skin="primary" title="{$voo.title}" {eq name="$voo.checked" value="true" }checked{/eq}>
</div>
{notempty name="voo.children"}
<div style="padding:10px 0 0 28px; {if condition='$k != count($vo.children)'}margin-bottom:12px; padding-bottom:16px; border-bottom:1px solid #eee;{/if}">
{volist name="voo.children" id="vooo"}
<div class="layui-input-inline" style="margin-right:10px;">
<input type="checkbox" disabled value="{$voo.id}" lay-skin="primary" title="{$vooo.title}" {eq name="$vooo.checked" value="true" }checked{/eq}>
</div>
{/volist}
</div>
{/notempty}
{/volist}
</div>
</td>
{/notempty}
</tr>
{/volist}
</table>
</td>
</tr>
<tr>
<td class="layui-td-gray2" style="vertical-align:top">权限配置<br>操作节点可用</td>
<td colspan="3">
<table style="width:100%" id="rule">
{volist name="role_rule" id="vo"}
<tr>
<td style="font-weight:800">
<input type="checkbox" disabled value="{$vo.id}" title="{$vo.title}" {eq name="$vo.checked" value="true" }checked{/eq}>
</td>
{notempty name="vo.children"}
<td>
<div style="padding:10px 0;">
{volist name="vo.children" key="k" id="voo"}
<div class="layui-input-inline" style="margin-right:10px; font-weight:800">
<input type="checkbox" disabled value="{$voo.id}" lay-skin="primary" title="{$voo.title}" {eq name="$voo.checked" value="true" }checked{/eq}>
</div>
{notempty name="voo.children"}
<div style="padding:10px 0 0 28px; {if condition='$k != count($vo.children)'}margin-bottom:12px; padding-bottom:16px; border-bottom:1px solid #eee;{/if}">
{volist name="voo.children" id="vooo"}
<div class="layui-input-inline" style="margin-right:10px;">
<input type="checkbox" disabled value="{$voo.id}" lay-skin="primary" title="{$vooo.title}" {eq name="$vooo.checked" value="true" }checked{/eq}>
</div>
{/volist}
</div>
{/notempty}
{/volist}
</div>
</td>
{/notempty}
</tr>
{/volist}
</table>
</td>
</tr>
</table>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var TAB = parent.layui.tab,
form = layui.form;
//监听返回
$('.body-content').on('click', '[lay-event="back"]', function () {
//TAB.sonDelete();
var index = parent.layer.getFrameIndex(window.name); //获取窗口索引
parent.layer.close(index);//关闭弹出的子页面窗口
return false;
});
}
//重设密码
function resetPsw(id){
layer.confirm('确定要重设该用户的密码?', {
icon: 3,
title: '提示'
}, function (index) {
$.ajax({
url: "{:url('home/admin/reset_psw')}",
data: {
id: id
},
success: function (e) {
layer.msg(e.msg);
if(e.code==0){
setTimeout(function(){
location.reload();
},2000);
}
}
})
layer.close(index);
});
}
//拷贝密码
function copyToClip(content) {
if (navigator.clipboard) {
// clipboard api 澶嶅埗
navigator.clipboard.writeText(content);
} else {
var copy_textarea = document.createElement('textarea');
// 闅愯棌姝よ緭鍏ユ
copy_textarea.style.position = 'fixed';
copy_textarea.style.clip = 'rect(0 0 0 0)';
copy_textarea.style.top = '10px';
copy_textarea.value = content;
document.body.appendChild(copy_textarea);
// 閫変腑
copy_textarea.select();
// 澶嶅埗
document.execCommand('copy', true);
// 绉婚櫎杈撳叆妗<E58F86>
document.body.removeChild(copy_textarea);
}
if (content != '') {
layer.msg('复制成功');
}
}
</script>
{include file="common/layui" base='base' extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,165 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<form class="layui-form body-content">
<table class="layui-table">
<tr>
<td class="layui-td-gray2">文章标题 <span style="color: red">*</span></td>
<td colspan="7"><input type="text" name="title" lay-verify="required" lay-reqText="请输入文章标题" autocomplete="off" placeholder="请输入文章标题"
class="layui-input"></td>
</tr>
<tr>
<td class="layui-td-gray2">文章分类<span style="color: red">*</span></td>
<td>
<select name="article_cate_id" lay-verify="required" lay-reqText="请选择分类">
<option value="">请选择分类</option>
{volist name=":set_recursion(get_article_cate())" id="v"}
<option value="{$v.id}">{$v.title}</option>
{/volist}
</select>
</td>
<td class="layui-td-gray2">关键字<span style="color: red">*</span></td>
<td>
<input type="text" id="keyword_name" name="keyword_names" autocomplete="off" lay-verify="required" lay-reqText="请选择关键字" placeholder="请选择关键字"
class="layui-input" readonly>
<input type="hidden" id="keyword_id" name="keyword_ids" autocomplete="off">
</td>
<td class="layui-td-gray2">状态<span style="color: red">*</span></td>
<td>
<input type="radio" name="status" value="1" title="正常" checked>
<input type="radio" name="status" value="0" title="下架">
</td>
</tr>
<tr>
<td class="layui-td-gray2">排序</td>
<td>
<input type="text" name="sort" value="0" placeholder="请输入排序,数字" autocomplete="off" class="layui-input">
</td>
<td class="layui-td-gray2">首页显示</td>
<td>
<input type="radio" name="is_home" value="1" title="是" checked>
<input type="radio" name="is_home" value="0" title="否">
</td>
<td class="layui-td-gray2">属性</td>
<td>
<select name="type">
<option value="">请选择属性</option>
<option value="1">精华</option>
<option value="2">热门</option>
<option value="3">推荐</option>
</select>
</td>
</tr>
<tr>
<td class="layui-td-gray2">是否原创</td>
<td>
<input type="radio" name="original" value="1" title="是">
<input type="radio" name="original" value="0" title="否" checked>
</td>
<td class="layui-td-gray2">作者/来源</td>
<td>
<input type="text" name="origin" class="layui-input" autocomplete="off" placeholder="请输入文章作者或来源">
</td>
<td class="layui-td-gray2">来源链接</td>
<td>
<input type="text" name="origin_url" class="layui-input" autocomplete="off" placeholder="请输入来源链接">
</td>
</tr>
<tr>
<td class="layui-td-gray2" style="vertical-align:top;">文章摘要</td>
<td colspan="3">
<textarea name="desc" placeholder="请输入摘要不能超过200个字" class="layui-textarea"></textarea>
</td>
<td class="layui-td-gray2" style="vertical-align:top;">缩略图</td>
<td>
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-normal layui-btn-sm" id="test1">上传缩略图尺寸240x136</button>
<div class="layui-upload-list" id="demo1" style="width: 120px; height:66px; overflow: hidden;">
<img src="" style="max-width: 100%; height:66px;" />
<input type="hidden" name="thumb" value="">
</div>
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray2" style="vertical-align:top;">文章内容<span style="color: red">*</span></td>
<td colspan="5">
<textarea name="content" placeholder="请输入内容" class="layui-textarea" id="container" lay-verify="required" lay-reqText="请完善文章内容"
style="border:0;padding:0"></textarea>
</td>
</tr>
</table>
<div class="layui-form-item">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<button lay-event="back" class="layui-btn layui-btn-primary">返回</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var form = layui.form
, layer = layui.layer
, tagspicker = layui.tagpicker
, upload = layui.upload;
var tags = new tagspicker({
'url': "{:url('home/api/get_keyword_cate')}",
'target': 'keyword_name',
'tag_ids': 'keyword_id',
'tag_tags': 'keyword_name',
'height': 500,
'isDiy': 1
});
//封面上传
var uploadInst = upload.render({
elem: '#test1'
, url: "{:url('home/api/upload')}",
, done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
$('#demo1 input').attr('value', res.data.id);
$('#demo1 img').attr('src', res.data.filepath);
}
});
//监听提交
form.on('submit(webform)', function (data) {
$.ajax({
url: "{:url('home/article/post_submit')}",
type: 'post',
data: data.field,
success: function (e) {
if (e.code == 0) {
layer.confirm('保存成功,返回列表页吗?', { icon: 3, title: '提示' }, function (index) {
history.back(-1);
layer.close(index);
});
} else {
layer.msg(e.msg);
}
}
})
return false;
});
//监听返回
$('.body-content').on('click', '[lay-event="back"]', function () {
history.back(-1);
return false;
});
}
</script>
{include file="common/layui" base='base' extend="['tagpicker']" callback="init" /}
{include file="common/ueditor" id="container" name="content" width="776" height="500" toolbar="[]" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,104 @@
{extend name="common/base"/}
<!-- 样式 -->
{block name="style"}
<style>
html,body{
height: calc(100% - 20px);
}
</style>
<!-- /样式 -->
<!-- 主体 -->
{block name="body"}
<div class="body-content" style="height: 100%">
<div style="height:39px;">
<a class="layui-btn layui-btn-normal layui-btn-sm" href="{:url('home/article/cate_add')}">+ 添加分类</a><span style="color:#999;margin-left:20px">点击表格内容可编辑</span>
</div>
<div style="height: calc(100% - 30px)">
<table class="layui-hide" id="treeTable" lay-filter="treeTable"></table>
</div>
</div>
<script type="text/html" id="switchStatus">
<input type="checkbox" name="status" value="{{d.id}}" lay-skin="switch" lay-text="是|否" lay-filter="status" {{ d.status == 1 ? 'checked' : '' }}>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
var editObj=null,ptable=null,treeGrid=null,tableId='treeTable',layer=null;
function init(layui){
var table=layui.table,form = layui.form;
treeGrid = layui.treeGrid;//很重要
layer=layui.layer;
ptable=treeGrid.render({
id:tableId
,elem: '#'+tableId
,idField:'id'
,url:"{:url('home/article/cate')}"
,cellMinWidth: 100
,treeId:'id'//树形id字段名称
,treeUpId:'pid'//树形父id字段名称
,treeShowName:'title'//以树形式显示的字段
,cols: [[
{field:'id',width:80, title: 'ID号', align:'center'}
,{field: 'sort', title: '排序', edit: "text", align:'center', style:'cursor: pointer;', width:80}
,{field:'title', edit:'text',width:240, title: '分类名称'}
,{field:'pid', title: '父级ID', edit:"text",width:80, align:'center'}
,{field:'keywords', title: '关键词', edit:"text",width:200,}
,{field:'desc', title: '描述', edit:"text"}
,{width:100,title: '操作', align:'center'
,templet: function(d){
var html='';
var addBtn='<a class="layui-btn layui-btn-normal layui-btn-xs" title="添加分类" href="/home/article/cate_add?pid='+d.id+'">添加</a>';
var delBtn='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>';
return addBtn+delBtn;
}
}
]]
,page:false
//,skin:'line'
});
//单元格编辑
treeGrid.on('edit('+tableId+')', function(obj){
layer.confirm('确定要提交修改吗?', {icon: 3, title:'提示'}, function(index){
$.ajax({
url:"{:url('home/article/cate_post_submit')}",
type:'post',
data:{id:obj.data.id,field:obj.field,value:obj.value},
success:function(res){
layer.msg(res.msg);
if(res.code == 1){
setTimeout(function(){
location.reload()
},2000)
}
}
})
layer.close(index);
});
});
//删除
treeGrid.on('tool('+tableId+')',function (obj) {
if(obj.event === 'del'){
layer.confirm('确定要删除吗?', {icon: 3, title:'提示'}, function(index){
$.ajax({
url:"{:url('home/article/cate_delete')}",
type:'post',
data:{id:obj.data.id},
success:function(res){
layer.msg(res.msg);
if(res.code == 0){
obj.del();
}
}
})
layer.close(index);
});
}
});
}
</script>
{include file="common/layui" base='base' extend="['treeGrid']" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,81 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<form class="layui-form body-content">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray2">父级分类<font>*</font></td>
<td>
<select name="pid" lay-verify="required" lay-reqText="请选择父级分类">
<option value="0">作为顶级分类</option>
{volist name=":set_recursion(get_article_cate())" id="v"}
<option value="{$v.id}" {eq name="pid" value="$v.id"}selected=""{/eq}>{$v.title}</option>
{/volist}
</select>
</td>
<td class="layui-td-gray2">分类名称<font>*</font></td>
<td>
<input type="text" name="title" lay-verify="required" autocomplete="off" placeholder="请输入分类名称" lay-reqText="请输入分类名称" class="layui-input">
</td>
</tr>
<tr>
<td class="layui-td-gray2">排序</td>
<td>
<input type="text" name="sort" placeholder="请输入排序,数字" value="0" autocomplete="off" class="layui-input">
</td>
<td class="layui-td-gray2">关键词</td>
<td>
<input type="text" name="keywords" placeholder="请输入关键词,用“,”隔开,可空" autocomplete="off" class="layui-input">
</td>
</tr>
<tr>
<td class="layui-td-gray2">描述</td>
<td colspan="3"><textarea name="desc" placeholder="请输入描述,可空" class="layui-textarea"></textarea></td>
</tr>
</table>
<div style="padding: 10px 0">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<button lay-event="back" class="layui-btn layui-btn-primary">返回</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui){
var form = layui.form
,layer = layui.layer;
//监听提交
form.on('submit(webform)', function(data){
$.ajax({
url:"{:url('home/article/cate_post_submit')}",
type:'post',
data:data.field,
success:function(e){
if(e.code==0){
layer.confirm('保存成功,返回列表页吗?', {icon: 3, title:'提示'}, function(index){
history.back(-1);
layer.close(index);
});
}else{
layer.msg(e.msg);
}
}
})
return false;
});
//监听返回
$('.body-content').on('click','[lay-event="back"]',function () {
history.back(-1);
return false;
});
}
</script>
{include file="common/layui" base='base' extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,171 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<form class="layui-form body-content">
<div>
<table class="layui-table">
<tr>
<td class="layui-td-gray2">文章标题 <span style="color: red">*</span></td>
<td colspan="7"> <input type="text" name="title" lay-verify="required" lay-reqText="请输入文章标题" autocomplete="off" placeholder="请输入文章标题"
class="layui-input" value="{$article.title}"></td>
</tr>
<tr>
<td class="layui-td-gray2">文章分类<span style="color: red">*</span></td>
<td>
<select name="article_cate_id" lay-verify="required" lay-reqText="请选择分类">
<option value="">请选择分类</option>
{volist name=":set_recursion(get_article_cate())" id="v"}
<option value="{$v.id}" {eq name="$article.article_cate_id" value="$v.id" }selected{/eq}>{$v.title}</option>
{/volist}
</select>
</td>
<td class="layui-td-gray2">关键字<span style="color: red">*</span></td>
<td>
<input type="text" id="keyword_name" name="keyword_names" autocomplete="off" lay-verify="required" lay-reqText="请选择关键字" placeholder="请选择关键字"
class="layui-input" value="{$article.keyword_names}" readonly>
<input type="hidden" id="keyword_id" name="keywords_id" autocomplete="off" value="{$article.keyword_ids}">
</td>
<td class="layui-td-gray2">状态<span style="color: red">*</span></td>
<td>
<input type="radio" name="status" value="1" title="正常" {eq name="$article.status" value="1" }checked{/eq}>
<input type="radio" name="status" value="0" title="下架" {eq name="$article.status" value="0" }checked{/eq}>
</td>
</tr>
<tr>
<td class="layui-td-gray2">排序</td>
<td>
<input type="text" name="sort" placeholder="请输入排序,数字" autocomplete="off" class="layui-input"
value="{$article.sort}">
</td>
<td class="layui-td-gray2">首页显示</td>
<td>
<input type="radio" name="is_home" value="1" title="是" {eq name="$article.is_home" value="1" }checked{/eq}>
<input type="radio" name="is_home" value="0" title="否" {eq name="$article.is_home" value="0" }checked{/eq}>
</td>
<td class="layui-td-gray2">属性</td>
<td>
<select name="type">
<option value="">请选择属性</option>
<option value="1" {eq name="$article.type" value="1" }selected{/eq}>精华</option>
<option value="2" {eq name="$article.type" value="2" }selected{/eq}>热门</option>
<option value="3" {eq name="$article.type" value="3" }selected{/eq}>推荐</option>
</select>
</td>
</tr>
<tr>
<td class="layui-td-gray2">是否原创</td>
<td>
<input type="radio" name="original" value="1" title="是" {eq name="$article.original" value="1" }checked{/eq}>
<input type="radio" name="original" value="0" title="否" {eq name="$article.original" value="0" }checked{/eq}>
</td>
<td class="layui-td-gray2">作者/来源</td>
<td>
<input type="text" name="origin" class="layui-input" autocomplete="off" placeholder="请输入文章来源"
value="{$article.origin}">
</td>
<td class="layui-td-gray2">来源链接</td>
<td>
<input type="text" name="origin_url" class="layui-input" autocomplete="off" placeholder="请输入来源链接"
value="{$article.origin_url}">
</td>
</tr>
<tr>
<td class="layui-td-gray2" style="vertical-align:top;">摘要</td>
<td colspan="3">
<textarea name="desc" placeholder="请输入摘要不能超过200个字" class="layui-textarea">{$article.desc}</textarea>
</td>
<td class="layui-td-gray2" style="vertical-align:top;">缩略图</td>
<td>
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-normal layui-btn-sm" id="test1">上传缩略图尺寸240x136</button>
<div class="layui-upload-list" id="demo1" style="width: 120px; height:66px; overflow: hidden;">
<img src="{:get_file($article.thumb)}" style="max-width: 100%; height:66px;" />
<input type="hidden" name="thumb" value="{$article.thumb}">
</div>
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray2" style="vertical-align:top;">文章内容<span style="color: red">*</span></td>
<td colspan="5">
<textarea name="content" placeholder="请输入内容" class="layui-textarea" id="container" lay-verify="required" lay-reqText="请完善文章内容"
style="border:0;padding:0">{$article.content}</textarea>
</td>
</tr>
</table>
<div class="layui-form-item">
<input type="hidden" name="id" value="{$article.id}">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<button lay-event="back" class="layui-btn layui-btn-primary">返回</button>
</div>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var form = layui.form
, layer = layui.layer
, tagspicker = layui.tagpicker
, upload = layui.upload;
var tags = new tagspicker({
'url': "{:url('home/api/get_keyword_cate')}",
'target': 'keyword_name',
'tag_ids': 'keyword_id',
'tag_tags': 'keyword_name',
'height': 500,
'isDiy': 1
});
//封面上传
var uploadInst = upload.render({
elem: '#test1'
, url: "{:url('home/api/upload')}",
, done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
$('#demo1 input').attr('value', res.data.id);
$('#demo1 img').attr('src', res.data.filepath);
}
});
//监听提交
form.on('submit(webform)', function (data) {
$.ajax({
url: "{:url('home/api/post_submit')}",
type: 'post',
data: data.field,
success: function (e) {
if (e.code == 0) {
layer.confirm('保存成功,返回列表页吗?', { icon: 3, title: '提示' }, function (index) {
history.back(-1);
layer.close(index);
});
} else {
layer.msg(e.msg);
}
}
})
return false;
});
//监听返回
$('.body-content').on('click', '[lay-event="back"]', function () {
history.back(-1);
return false;
});
}
</script>
{include file="common/layui" base='base' extend="['tagpicker']" callback="init" /}
{include file="common/ueditor" id="container" name="content" width="776" height="500" toolbar="[]" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,139 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<div class="body-content">
<form class="layui-form">
<div class="layui-input-inline">
<select name="article_cate_id">
<option value="">请选择文章分类</option>
{volist name=":set_recursion(get_article_cate())" id="v"}
<option value="{$v.id}">{$v.title}</option>
{/volist}
</select>
</div>
<div class="layui-input-inline" style="width:300px;">
<input type="text" name="keywords" placeholder="ID/标题/分类/描述/内容" class="layui-input" autocomplete="off" />
</div>
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">提交搜索</button>
</form>
<table class="layui-hide" id="test" lay-filter="test"></table>
</div>
<script type="text/html" id="status">
<i class="layui-icon {{# if(d.status == 1){ }}layui-icon-ok{{# } else { }}layui-icon-close{{# } }}"></i>
</script>
<script type="text/html" id="is_home">
<i class="layui-icon {{# if(d.is_home == 1){ }}layui-icon-ok{{# } else { }}layui-icon-close{{# } }}"></i>
</script>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<a class="layui-btn layui-btn-normal layui-btn-sm" title="添加文章" href="{:url('home/article/add')}">+ 添加文章</a>
</div>
</script>
<script type="text/html" id="barDemo">
<div class="layui-btn-group"><a class="layui-btn layui-btn-xs" href="/home/article/add?id={{d.id}}">编辑</a><a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a></div>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var TAB = parent.layui.tab,
table = layui.table,
form = layui.form;
var tableIns = table.render({
elem: '#test',
title: '文章列表',
toolbar: '#toolbarDemo',
url: "{:url('home/article/index')}", //数据接口
page: true, //开启分页
limit: 20,
cols: [
[ //表头
{
field: 'id',
title: '编号',
align: 'center',
width: 80
}, {
field: 'sort',
title: '排序',
align: 'center',
width: 80
}, {
field: 'cate_title',
title: '分类',
width: 200
}, {
field: 'title',
title: '文章标题',
templet: '<div><a href="/home/index/index/id/{{d.id}}.html" class="layui-table-link" target="_blank">{{d.title}}</a></div>'
}, {
field: 'status',
title: '状态',
toolbar: '#status',
align: 'center',
width: 66
}, {
field: 'is_home',
title: '首页显示',
toolbar: '#is_home',
align: 'center',
width: 90
}, {
field: 'right',
title: '操作',
toolbar: '#barDemo',
width: 100,
align: 'center'
}
]
]
});
//监听行工具事件
table.on('tool(test)', function(obj) {
var data = obj.data;
if (obj.event === 'del') {
layer.confirm('确定要删除吗?', {
icon: 3,
title: '提示'
}, function(index) {
$.ajax({
url: "{:url('home/article/delete')}",
data: {
id: data.id
},
success: function(e) {
layer.msg(e.msg);
if (e.code == 0) {
obj.del();
}
}
})
layer.close(index);
});
}
});
//监听搜索提交
form.on('submit(webform)', function(data) {
tableIns.reload({
where: {
keywords: data.field.keywords,
article_cate_id: data.field.article_cate_id
},
page: {
curr: 1
}
});
return false;
});
}
</script>
{include file="common/layui" base="base" extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="renderer" content="webkit"/>
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
{block name="meta"}
<link rel="mobile-prefetch" href=""/>
{/block}
{block name="title"}
<title>{:get_system_config('web','admin_title')}</title>
{/block}
{block name="keywords"}
<meta name="keywords" content="{:get_system_config('web','keywords')}"/>
<meta name="description" content="{:get_system_config('web','desc')}"/>
{/block}
{block name="css"}
<link rel="stylesheet" href="{__LAYUI__}/css/layui.css?v={:get_system_config('web','version')}" media="all">
<link rel="stylesheet" href="{__CSS__}/common.css?v={:get_system_config('web','version')}" media="all">
{/block}
{block name="style"}{/block}
{block name="js"}
<script src="{__STATIC__}/jquery.min.js"></script>
<script>
const login_user={$login_user};
</script>
{/block}
</head>
<body class="main-body">
<!-- 主体 -->
{block name="body"}{/block}
<!-- /主体 -->
<!-- 底部 -->
{block name="footer"}{/block}
<!-- /底部 -->
<!-- 脚本 -->
{block name="script"}{/block}
<!-- /脚本 -->
<!-- 统计代码 -->
{block name="code"}{/block}
<!-- /统计代码 -->
</body>
</html>

View File

@ -0,0 +1,23 @@
<script src="{__LAYUI__}/layui.js?v={:get_system_config('web','version')}"></script>
<script>
var base='{__JS__}/module/';
{if condition=" '[base]'!=='base' "}
base=[base];
{/if}
var extendArray=[extend];
var callback=[callback];
var extend={};
if(extendArray){
if(extendArray.length>0){
for(var i=0;i<extendArray.length;i++){
extend[extendArray[i]]=extendArray[i];
}
}
}
layui.config({
base: base,
version:'{:get_system_config('web','version')}'
}).extend(extend).use(extendArray, function(){
callback(layui);
});
</script>

View File

@ -0,0 +1,33 @@
<script id="[id]" name="[name]" type="text/plain"></script>
{if condition=" '[ueditor]'!=='more' "}
<script type="text/javascript" src="{__STATIC__}/ueditor/ueditor.config.min.js"></script>
<script type="text/javascript" src="{__STATIC__}/ueditor/ueditor.all.min.js"></script>
{/if}
<script type="text/javascript">
var id='[id]';
var width='[width]';
var height='[height]';
var readonly='[readonly]';
var toolbarArray=[toolbar];
var read=false;
if(readonly=='true'){
read=true;
}
var toolbar=['fullscreen', 'source', 'undo', 'redo','|','fontsize','bold', 'italic', 'underline','forecolor', 'strikethrough', 'superscript', 'subscript','|', 'removeformat', 'formatmatch', 'insertcode', 'pasteplain','link','unlink','|','justifyleft','justifycenter','justifyright','justifyjustify','|', 'insertorderedlist', 'insertunorderedlist','simpleupload', 'insertimage', 'inserttable', 'selectall', 'cleardoc'];
if(toolbarArray && toolbarArray.length>0){
toolbar=toolbarArray;
}
if(toolbarArray && toolbarArray.length>0){
toolbar=toolbarArray;
}
var ue = UE.getEditor(id,{
//初始化高度
toolbars: [
toolbar
],
pasteplain:true,
readonly:read,
initialFrameWidth:width,
initialFrameHeight:height
});
</script>

View File

@ -0,0 +1,81 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<form class="layui-form body-content">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray2">配置名称<font>*</font>
</td>
<td>
<input type="hidden" name="id" value="{$id}" />
<input type="text" name="title" lay-verify="required" autocomplete="off" placeholder="请输入配置名称"
class="layui-input" {notempty name="$config.title"}
value="{$config.title}" {/notempty}>
</td>
<td class="layui-td-gray2">状态<font>*</font></td>
<td>{if condition="$id eq 0"}
<input type="radio" name="status" value="1" title="正常" checked>
<input type="radio" name="status" value="0" title="禁用">
{else/}
<input type="radio" name="status" value="1" title="正常" {eq name="$config.status" value="1"
}checked{/eq}>
<input type="radio" name="status" value="0" title="禁用" {eq name="$config.status" value="0"
}checked{/eq}>
{/if}
</td>
</tr>
<tr>
<td class="layui-td-gray2" style="vertical-align: top;">
配置标识<font>*</font>
</td>
<td colspan="3">
<input style="width: 300px;" type="text" name="name" placeholder="请输入配置标识" lay-verify="required" autocomplete="off" class="layui-input" {notempty name="$config.name"} value="{$config.name}" {/notempty}>
<span style ="color: red; font-size: 12px; margin-top: 5px;">(注意:新增配置项以后,需要对应新增模板文件,模板文件名称需与标识名称一致,建议复制现有的配置模板文件,然后根据需求修改对应的表单即可)</span>
</td>
</tr>
</table>
<div style="padding: 10px 0">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<button lay-event="back" class="layui-btn layui-btn-primary">返回</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var form = layui.form
, layer = layui.layer;
//监听提交
form.on('submit(webform)', function (data) {
$.ajax({
url: "{:url('home/conf/conf_submit')}",
type: 'post',
data: data.field,
success: function (e) {
if (e.code == 0) {
layer.confirm('保存成功,返回列表页吗?', { icon: 3, title: '提示' }, function (index) {
history.back(-1);
layer.close(index);
});
} else {
layer.msg(e.msg);
}
}
})
return false;
});
//监听返回
$('.body-content').on('click', '[lay-event="back"]', function () {
history.back(-1);
return false;
});
}
</script>
{include file="common/layui" base="base" extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,147 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<form class="layui-form body-content">
<h3 style="height:36px">邮箱配置</h3>
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray2">SMTP地址<font>*</font>
</td>
<td>
<input type="hidden" name="id" value="{$id}">
<input type="text" name="smtp" lay-verify="required" autocomplete="off" placeholder="请输入SMTP服务器地址"
class="layui-input" {notempty name="$config.smtp"} value="{$config.smtp}" {/notempty} style="width:240px;display: inline-block;">
<span style="color:#999; font-size:12px;">QQ邮箱的SMTP服务器地址是smtp.qq.com163邮箱的SMTP服务器地址是smtp.163.com</span>
</td>
</tr>
<tr>
<td class="layui-td-gray2">协议端口号<font>*</font>
</td>
<td>
<input type="text" name="smtp_port" lay-verify="required" autocomplete="off" placeholder="请输入端口"
class="layui-input" {notempty name="$config.smtp_port"} value="{$config.smtp_port}" {/notempty} style="width:240px;display: inline-block;">
<span style="color:#999; font-size:12px;">QQ邮箱的ssl协议方式端口号是465/587163邮箱的ssl协议方式端口号是465/994</span>
</td>
</tr>
<tr>
<td class="layui-td-gray2">邮箱账户<font>*</font>
</td>
<td>
<input type="text" name="smtp_user" lay-verify="required" autocomplete="off" placeholder="请输入邮箱用户名"
class="layui-input" {notempty name="$config.smtp_user"} value="{$config.smtp_user}" {/notempty} style="width:240px;display: inline-block;">
<span style="color:#999; font-size:12px;">gougucms@qq.com</span>
</td>
</tr>
<tr>
<td class="layui-td-gray2">邮箱密码<font>*</font>
</td>
<td>
<input type="password" name="smtp_pwd" lay-verify="required" autocomplete="off" placeholder="请输入邮箱密码"
class="layui-input" {notempty name="$config.smtp_pwd"} value="{$config.smtp_pwd}" {/notempty} style="width:240px;display: inline-block;">
<span style="color:#999; font-size:12px;">
不一定是登录密码如QQ邮箱的是第三方授权登录码要自己去开启在邮箱的设置->账户->POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务</span>
</td>
</tr>
<tr>
<td class="layui-td-gray2">发送人<font>*</font>
</td>
<td>
<input type="text" name="from" lay-verify="required" autocomplete="off" placeholder="请输入要显示的发送者"
class="layui-input" {notempty name="$config.from"} value="{$config.from}" {/notempty} style="width:240px; display: inline-block;">
<span style="color:#999; font-size:12px;">用于展示给发送方勾股CMS系统管理员</span>
</td>
</tr>
<tr>
<td class="layui-td-gray2">显示的邮箱<font>*</font>
</td>
<td>
<input type="text" name="email" lay-verify="required" autocomplete="off" placeholder="请输入要显示的发送者邮箱"
class="layui-input" {notempty name="$config.email"} value="{$config.email}" {/notempty} style="width:240px;display: inline-block;">
<span style="color:#999;font-size:12px;">可以不同于上面的账户用于展示给发送方的邮箱admin@gougucms.com</span>
</td>
</tr>
<tr>
<td class="layui-td-gray2">邮件模板</td>
<td><textarea name="template" placeholder="" class="layui-textarea" id="container" style="border:0;padding:0">{notempty name="$config.template"}{$config.template}{/notempty}</textarea></td>
</tr>
</table>
<div style="padding: 10px 0">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button lay-event="email" class="layui-btn">发送测试</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<button lay-event="back" class="layui-btn layui-btn-primary">返回</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var form = layui.form
, layer = layui.layer;
//监听提交
form.on('submit(webform)', function (data) {
$.ajax({
url: "{:url('home/conf/conf_submit')}",
type: 'post',
data: data.field,
success: function (e) {
if (e.code == 0) {
layer.confirm('保存成功,关闭本页面吗?', { icon: 3, title: '提示' }, function (index) {
history.back(-1);
layer.close(index);
});
} else {
layer.msg(e.msg);
}
}
})
return false;
});
$('.body-content').on('click', '[lay-event="email"]', function () {
layer.prompt({
formType: 0,
value: '',
title: '输入接收测试邮件的邮箱',
id: 'email_to'
}, function (value, index, elem) {
var isEmail = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
if (value.length < 6 || !(isEmail.test(value))) {
layer.tips('请正确输入邮箱', elem);
return false;
}
$.ajax({
url: "{:url('home/api/email_test')}",
data: { email: value },
type: "post",
beforeSend: function () {
// 禁用按钮防止重复提交
$("#email_to input").val('');
},
success: function (e) {
layer.msg(e.msg);
if (e.code == 0) {
layer.close(index);
}
}
})
});
return false;
})
//监听返回
$('.body-content').on('click', '[lay-event="back"]', function () {
history.back(-1);
return false;
});
}
</script>
{include file="common/layui" base="base" extend="[]" callback="init" /}
{include file="common/ueditor" id="container" name="content" width="100%" height="100%" toolbar="[]" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,108 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<div class="body-content">
<table class="layui-hide" id="test" lay-filter="test"></table>
</div>
<script type="text/html" id="status">
<i class="layui-icon {{# if(d.status == 1){ }}layui-icon-ok{{# } else { }}layui-icon-close{{# } }}"></i>
</script>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<a class="layui-btn layui-btn-normal layui-btn-sm" href="/conf/add">+ 添加配置项</a>
</div>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var table = layui.table,
form = layui.form;
var tableIns = table.render({
elem: '#test',
title: '配置列表',
toolbar: '#toolbarDemo',
url: "{:url('home/conf/index')}",
page: true, //开启分页
limit: 20,
cols: [
[{
field: 'id',
width: 80,
title: 'ID编号',
align: 'center'
},{
field: 'title',
title: '配置名称'
}, {
field: 'name',
title: '配置标识(新增的模板文件名称需与标识名称一致)'
},{
field: 'status',
width: 80,
title: '状态',
templet: '#status',
align: 'center'
}, {
width: 160,
title: '操作',
align: 'center',
templet: function (d) {
var html = '<div class="layui-btn-group"><a class="layui-btn layui-btn-xs" href="/home/conf/add?id=' + d.id + '">修改</a><a class="layui-btn layui-btn-normal layui-btn-xs" href="/home/conf/edit?id=' + d.id + '">编辑配置</a><a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a></div>';
return html;
}
}]
]
});
//监听搜索提交
form.on('submit(webform)', function (data) {
if (data.field.keywords) {
tableIns.reload({
where: {
keywords: data.field.keywords
},
page: {
curr: 1
}
});
} else {
location.reload();
}
return false;
});
//删除
table.on('tool(test)', function (obj) {
if (obj.event === 'del') {
layer.confirm('确定要删除吗?', {
icon: 3,
title: '提示'
}, function (index) {
$.ajax({
url: "{:url('home/conf/delete')}",
type: 'post',
data: {
id: obj.data.id
},
success: function (res) {
layer.msg(res.msg);
if (res.code == 0) {
obj.del();
}
}
})
layer.close(index);
});
}
});
}
</script>
{include file="common/layui" base="base" extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,70 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<form class="layui-form body-content">
<h3 style="height:36px">其他配置</h3>
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray2">开发者</td>
<td>
<input type="hidden" value="{$id}" name="id">
<input type="text" name="author" autocomplete="off" placeholder="请输入开发者"
lay-reqText="请输入开发者" class="layui-input"{notempty name="$config.author"} value="{$config.author}" {/notempty}>
</td>
<td class="layui-td-gray2">开发版本号
</td>
<td>
<input type="text" name="version" autocomplete="off" placeholder="请输入版本号"
lay-reqText="请输入版本号" class="layui-input" {notempty name="$config.version"} value="{$config.version}" {/notempty}>
</td>
</tr>
</table>
<div style="padding: 10px 0">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<button lay-event="back" class="layui-btn layui-btn-primary">返回</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var form = layui.form,
layer = layui.layer;
//监听提交
form.on('submit(webform)', function (data) {
$.ajax({
url: "{:url('home/conf/conf_submit')}",
type: 'post',
data: data.field,
success: function (e) {
if (e.code == 0) {
layer.confirm('保存成功,关闭本页面吗?', {
icon: 3,
title: '提示'
}, function (index) {
history.back(-1);
layer.close(index);
});
} else {
layer.msg(e.msg);
}
}
})
return false;
});
//监听返回
$('.body-content').on('click', '[lay-event="back"]', function () {
history.back(-1);
return false;
});
}
</script>
{include file="common/layui" base="base" extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,202 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<form class="layui-form body-content">
<h3 style="height:36px">Token配置</h3>
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray2">Token签发组织</td>
<td>
<input type="hidden" value="{$id}" name="id">
<input type="text" name="iss" autocomplete="off" placeholder="请输入签发组织"
lay-reqText="请输入签发组织" class="layui-input"{notempty name="$config.iss"} value="{$config.iss}" {/notempty}>
</td>
<td class="layui-td-gray2">Token签发作者
</td>
<td>
<input type="text" name="aud" autocomplete="off" placeholder="请输入签发作者"
lay-reqText="请输入签发作者" class="layui-input" {notempty name="$config.aud"} value="{$config.aud}" {/notempty}>
</td>
</tr>
<tr>
<td class="layui-td-gray2">Token Secrect</td>
<td>
<input type="text" name="secrect" autocomplete="off" placeholder="请输入secrect"
lay-reqText="请输入secrect" class="layui-input"{notempty name="$config.secrect"} value="{$config.secrect}" {/notempty}>
</td>
<td class="layui-td-gray2">Token过期时间
</td>
<td>
<input type="text" name="exptime" autocomplete="off" placeholder="请输入过期时间"
lay-reqText="请输入过期时间" class="layui-input" {notempty name="$config.exptime"} value="{$config.exptime}" {/notempty}>
</td>
</tr>
</table>
<div style="padding:20px 0;">
<span class="layui-btn layui-btn-sm" onclick="testReg();">Api测试注册</span>
<span class="layui-btn layui-btn-sm" onclick="testLogin();">Api测试登录</span>
<span class="layui-btn layui-btn-sm" onclick="testToken();">Token测试</span>
</div>
<div style="padding:20px; background-color:#f2f2f2;word-wrap:break-word">
测试结果:
<div id="res"></div>
</div>
<div style="padding: 20px 0">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<button lay-event="back" class="layui-btn layui-btn-primary">返回</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var form = layui.form,
layer = layui.layer;
//监听提交
form.on('submit(webform)', function (data) {
$.ajax({
url: "{:url('home/conf/conf_submit')}",
type: 'post',
data: data.field,
success: function (e) {
if (e.code == 0) {
layer.confirm('保存成功,关闭本页面吗?', {
icon: 3,
title: '提示'
}, function (index) {
history.back(-1);
layer.close(index);
});
} else {
layer.msg(e.msg);
}
}
})
return false;
});
//监听返回
$('.body-content').on('click', '[lay-event="back"]', function () {
history.back(-1);
return false;
});
}
var token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhcGkuZ291Z3VjbXMuY29tIiwiYXVkIjoiZ291Z3VjbXMiLCJpYXQiOjE2MjczMTY1MTgsImV4cCI6MTYyNzMyMDExOCwidWlkIjoxfQ.3soLDbwrEqn4EZtpD4h05FmvmMtJEh1LtE1vZ_ANcnI';
function testToken(){
$.ajax({
headers: {
Token: token
},
url: "{:url('home/api/index/demo')}",
type: "get",
success: function (res) {
$('#res').html(JSON.stringify(res));
if(res.code == 111){
layer.msg(res.msg);
}
}
});
}
function testReg(){
var content='<form class="layui-form" style="width:400px"><div style="padding:10px 15px">\
<p style="padding:10px 0">用户名:</p>\
<p><input name="username" type="text" class="layui-input" value=""/></p>\
<p style="padding:10px 0">密 码:</p>\
<p><input name="password" type="password" class="layui-input" value=""/></p>\
<p style="padding:10px 0">重复密码:</p>\
<p><input name="newpassword" type="password" class="layui-input" value=""/></p>\
</div>\
</form>';
layer.open({
type:1,
title:'API测试用户注册',
area:['432px','360px'],
content:content,
btnAlign: 'c',
btn: ['注册'],
yes: function(idx){
var username = $('[name="username"]').val();
var password = $('[name="password"]').val();
var newpassword = $('[name="newpassword"]').val();
if(username==''){
layer.msg('请填写用户名');
return;
}
if(password==''){
layer.msg('请填写密码');
return;
}
if(password != newpassword){
layer.msg('两次密码填写不一致');
return;
}
$.ajax({
url:"{:url('home/api/index/reg')}",
type:'post',
data:{username:username,pwd:password},
success:function(res){
$('#res').html(JSON.stringify(res));
layer.msg(res.msg);
if(res.code==1){
token = res.data.token;
layer.close(idx);
}
}
})
}
})
}
function testLogin(){
var content='<form class="layui-form" style="width:400px"><div style="padding:10px 15px">\
<p style="padding:10px 0">用户名:</p>\
<p><input name="username" type="text" class="layui-input" value="hdm58"/></p>\
<p style="padding:10px 0">密 码:</p>\
<p><input name="password" type="password" class="layui-input" value="123456"/></p>\
</div>\
</form>';
layer.open({
type:1,
title:'API测试用户登录',
area:['432px','300px'],
content:content,
btnAlign: 'c',
btn: ['登录'],
yes: function(idx){
var username = $('[name="username"]').val();
var password = $('[name="password"]').val();
if(username==''){
layer.msg('请填写用户名');
return;
}
if(password==''){
layer.msg('请填写密码');
return;
}
$.ajax({
url:"{:url('home/api/index/login')}",
type:'post',
data:{username:username,password:password},
success:function(res){
$('#res').html(JSON.stringify(res));
layer.msg(res.msg);
if(res.code==1){
token = res.data.token;
layer.close(idx);
}
}
})
}
})
}
</script>
{include file="common/layui" base="base" extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

153
app/home/view/conf/web.html Normal file
View File

@ -0,0 +1,153 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<form class="layui-form body-content">
<h3 style="height:36px">系统配置</h3>
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray2">系统名称<font>*</font>
</td>
<td>
<input type="hidden" name="id" value="{$id}">
<input type="text" name="admin_title" lay-verify="required" autocomplete="off" placeholder="请输入系统名称"
lay-reqText="请输入系统名称" class="layui-input" {notempty name="$config.admin_title"} value="{$config.admin_title}" {/notempty}>
</td>
<td class="layui-td-gray2">网站名称<font>*</font>
</td>
<td>
<input type="text" name="title" lay-verify="required" autocomplete="off" placeholder="请输入网站平台名称"
lay-reqText="请输入网站名称" class="layui-input" {notempty name="$config.title"} value="{$config.title}" {/notempty}>
</td>
<td rowspan="3" class="layui-td-gray2">系统LOGO</td>
<td rowspan="3" style="width: 240px;">
<div class="layui-upload" style="width: 240px;">
<div class="layui-upload-list" id="demo1" style="width: 100%; height:100px; overflow: hidden;">
<img src='{notempty name="$config.logo"}{$config.logo}{/notempty}' style="max-width: 100%; width: 100%;" />
<input type="hidden" name="logo" {notempty name="$config.logo"} value="{$config.logo}" {/notempty}>
</div>
<button type="button" class="layui-btn layui-btn-normal" style="width: 100%;"
id="test1">上传LOGO</button>
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray2">网站域名<font>*</font>
</td>
<td>
<input type="text" name="domain" lay-verify="required" autocomplete="off" placeholder="请输入网站域名"
lay-reqText="请输入网站域名" class="layui-input" {notempty name="$config.domain"} value="{$config.domain}" {/notempty}>
</td>
<td class="layui-td-gray2">ICP备案号</td>
<td>
<input type="text" name="icp" autocomplete="off" placeholder="请输入ICP备案号" class="layui-input"
{notempty name="$config.icp"} value="{$config.icp}" {/notempty}>
</td>
</tr>
<tr>
<td class="layui-td-gray2">SEO关键词<font>*</font>
</td>
<td>
<input type="text" name="keywords" lay-verify="required" autocomplete="off" placeholder="多个关键词用“,”隔开"
lay-reqText="请输入SEO关键字" class="layui-input" {notempty name="$config.keywords"} value="{$config.keywords}" {/notempty}>
</td>
<td class="layui-td-gray2">公安备案号</td>
<td>
<input type="text" name="beian" autocomplete="off" placeholder="请输入公安备案号" class="layui-input"
{notempty name="$config.beian"} value="{$config.beian}" {/notempty}>
</td>
</tr>
<tr>
<td class="layui-td-gray2">SEO描述<font>*</font>
</td>
<td colspan="5">
<textarea name="desc" lay-verify="required" placeholder="请输入网站描述" lay-reqText="请输入网站描述"
class="layui-textarea">{notempty name="$config.desc"}{$config.desc} {/notempty}</textarea>
</td>
</tr>
<tr>
<td class="layui-td-gray2">统计代码</td>
<td colspan="5">
<textarea name="code" placeholder="请输入完整的统计代码" class="layui-textarea">{notempty name="$config.code"} value={$config.code}{/notempty}</textarea>
</td>
</tr>
<tr>
<td class="layui-td-gray2">版权信息</td>
<td colspan="3">
<input type="text" name="copyright" autocomplete="off" placeholder="请输入版权信息"
lay-reqText="请输入版权信息" class="layui-input"{notempty name="$config.copyright"} value="{$config.copyright}" {/notempty}>
</td>
<td class="layui-td-gray2">代码版本号<font>*</font>
</td>
<td>
<input type="text" lay-verify="required" name="version" autocomplete="off" placeholder="请输入版本号"
lay-reqText="请输入版本号" class="layui-input" {notempty name="$config.version"} value="{$config.version}" {/notempty}>
</td>
</tr>
</table>
<div style="padding: 10px 0">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<button lay-event="back" class="layui-btn layui-btn-primary">返回</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var form = layui.form,
layer = layui.layer,
upload = layui.upload;
//logo上传
var uploadInst = upload.render({
elem: '#test1',
url: "{:url('home/api/upload')}",
done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
layer.msg('上传成功');
$('#demo1 input').attr('value', res.data.filepath);
$('#demo1 img').attr('src', res.data.filepath);
}
});
//监听提交
form.on('submit(webform)', function (data) {
$.ajax({
url: "{:url('home/conf/conf_submit')}",
type: 'post',
data: data.field,
success: function (e) {
if (e.code == 0) {
layer.confirm('保存成功,关闭本页面吗?', {
icon: 3,
title: '提示'
}, function (index) {
history.back(-1);
layer.close(index);
});
} else {
layer.msg(e.msg);
}
}
})
return false;
});
//监听返回
$('.body-content').on('click', '[lay-event="back"]', function () {
history.back(-1);
return false;
});
}
</script>
{include file="common/layui" base="base" extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,108 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<form class="layui-form body-content">
<h3 style="height:36px">微信配置</h3>
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray3">token<font>*</font></td>
<td>
<input type="hidden" value="{$id}" name="id">
<input type="text" name="token" lay-verify="required" autocomplete="off" placeholder="请输入Token" class="layui-input" {notempty name="$config.token"} value="{$config.token}" {/notempty}>
</td>
<td class="layui-td-gray3">登录回调地址<font>*</font></td>
<td>
<input type="text" name="login_back_url" lay-verify="required" autocomplete="off" placeholder="请输入微信登录回调地址" class="layui-input" {notempty name="$config.login_back_url"} value="{$config.login_back_url}" {/notempty}>
</td>
</tr>
<tr>
<td class="layui-td-gray3">公众号appid<font>*</font></td>
<td>
<input type="text" name="appid" lay-verify="required" autocomplete="off" placeholder="请输入appID" class="layui-input" {notempty name="$config.appid"} value="{$config.appid}" {/notempty}>
</td>
<td class="layui-td-gray3">公众号appsecret<font>*</font></td>
<td>
<input type="text" name="appsecret" lay-verify="required" autocomplete="off" placeholder="请输入secretey" class="layui-input" {notempty name="$config.appsecret"} value="{$config.appsecret}" {/notempty}>
</td>
</tr>
<tr>
<td class="layui-td-gray3">支付商户号</td>
<td>
<input type="text" name="mchid" autocomplete="off" placeholder="请输入微信支付商户号" class="layui-input" {notempty name="$config.mchid"} value="{$config.mchid}" {/notempty}>
</td>
<td class="layui-td-gray3">支付API密钥</td>
<td>
<input type="text" name="secrect_key" autocomplete="off" placeholder="请输入微信支付API密钥" class="layui-input"
{notempty name="$config.secrect_key"} value="{$config.secrect_key}" {/notempty}>
</td>
</tr>
<tr>
<td class="layui-td-gray3">支付证书路径</td>
<td>
<input type="text" name="cert_url" autocomplete="off" placeholder="请输入微信支付证书路径" class="layui-input"
{notempty name="$config.cert_url"} value="{$config.cert_url}" {/notempty}>
</td>
<td class="layui-td-gray3">支付回调地址</td>
<td>
<input type="text" name="pay_back_url" autocomplete="off" placeholder="请输入微信支付回调地址" class="layui-input" {notempty name="$config.pay_back_url"} value="{$config.pay_back_url}" {/notempty}>
</td>
</tr>
<tr>
<td class="layui-td-gray3">小程序appid<font>*</font></td>
<td>
<input type="text" name="xcx_appid" lay-verify="required" autocomplete="off" placeholder="请输入小程序appid" class="layui-input" {notempty name="$config.xcx_appid"} value="{$config.xcx_appid}" {/notempty}>
</td>
<td class="layui-td-gray3">小程序appsecret<font>*</font></td>
<td>
<input type="text" name="xcx_appsecret" lay-verify="required" autocomplete="off" placeholder="请输入小程序appsecret" class="layui-input" {notempty name="$config.xcx_appsecret"} value="{$config.xcx_appsecret}" {/notempty}>
</td>
</tr>
</table>
<div style="padding: 10px 0">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<button lay-event="back" class="layui-btn layui-btn-primary">返回</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var form = layui.form,
layer = layui.layer;
//监听提交
form.on('submit(webform)', function(data) {
$.ajax({
url: "{:url('home/conf/conf_submit')}",
type: 'post',
data: data.field,
success: function(e) {
if (e.code == 0) {
layer.confirm('保存成功,关闭本页面吗?', {
icon: 3,
title: '提示'
}, function(index) {
history.back(-1);
layer.close(index);
});
} else {
layer.msg(e.msg);
}
}
})
return false;
});
//监听返回
$('.body-content').on('click', '[lay-event="back"]', function () {
history.back(-1);
return false;
});
}
</script>
{include file="common/layui" base="base" extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,91 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<div class="body-content">
<table cellspacing="0" cellpadding="0" border="0" class="layui-table">
<tr style="background-color: #f5f5f5; text-align: center;">
<th style=" text-align: center; font-weight: 800;"><span>文件名称</span></th>
<th style=" text-align: center; font-weight: 800;"><span>分卷</span></th>
<th style=" text-align: center; font-weight: 800;"><span>文件大小</span></th>
<th style=" text-align: center; font-weight: 800;"><span>文件格式</span></th>
<th style=" text-align: center; font-weight: 800;"><span>分隔符</span></th>
<th style=" text-align: center; font-weight: 800;"><span>操作</span></th>
</tr>
{empty name="list"}
<tr>
<td colspan="6" align="center">暂无备份数据</td>
</tr>
{/empty}
{volist name="list" id="vo" key="k"}
<tr style="background-color: #f5f5f5;">
<td colspan="6">备份时间:{$vo.time}</td>
</tr>
{volist name="vo.data" id="voo"}
<tr>
<td>
{:date("Ymd",$voo.time)}{$voo.compress}{:date("His",$voo.time)}{$voo.compress}{$voo.part}.sql
</td>
<td align="center"><span>{$voo.part}</span></td>
<td align="center"><span>{:format_bytes($voo.size)}</span></td>
<td align="center"><span>.sql</span></td>
<td align="center"><span>{$voo.compress}</span></td>
<td align="center" data-id='{$voo.time}'>
<a class="layui-btn layui-btn-xs layui-btn-normal" lay-event="import">数据还原</a>
<a class="layui-btn layui-btn-xs" href='/database/downfile?name={:date("Ymd",$voo.time)}{$voo.compress}{:date("His",$voo.time)}{$voo.compress}{$voo.part}.sql'>备份下载</a><a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">备份删除</a>
</td>
</tr>
{/volist}
{/volist}
</table>
</div>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var table = layui.table,
form = layui.form;
//监听行工具事件
$('[lay-event="import"]').on('click',function(){
var id=$(this).parent().data('id');
layer.confirm('确认要还原该备份吗?', {
icon: 3,
title: '提示'
}, function (index) {
$.ajax({
url: "/home/database/import?id="+id,
success: function (res) {
layer.msg(res.msg);
}
})
layer.close(index);
});
})
$('[lay-event="del"]').on('click',function(){
var id=$(this).parent().data('id');
layer.confirm('确认要删除该备份吗?', {
icon: 3,
title: '提示'
}, function (index) {
$.ajax({
url: "{:url('home/database/del')}",
data: {'id':id},
success: function (res) {
layer.msg(res.msg);
if (res.code == 0) {
location.reload();
}
}
})
layer.close(index);
});
})
}
</script>
{include file="common/layui" base="base" extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,152 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<div class="body-content">
<table class="layui-hide" id="test" lay-filter="test"></table>
</div>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-group">
<span class="layui-btn layui-btn-sm layui-btn-normal" lay-event="backup">数据备份</span><span class="layui-btn layui-btn-sm" lay-event="optimize">数据优化</span><span class="layui-btn layui-btn-danger layui-btn-sm" lay-event="repair">数据修复</span>
</div>
<span id="dataTips" style="font-size:12px; margin-left:10px"></span>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var table = layui.table,
form = layui.form;
var tableIns = table.render({
elem: '#test',
title: '数据备份',
toolbar: '#toolbarDemo',
url: "{:url('home/database/database')}", //数据接口
page: false,
cols: [
[ //表头
{type: 'checkbox'},
{
field: 'name',
title: '数据表',
width: 220
}, {
field: 'engine',
title: '存储引擎',
align: 'center',
width: 90
}, {
field: 'row_format',
title: '行格式',
align: 'center',
width: 90
}, {
field: 'rows',
title: '行数',
align: 'center',
width: 100,
}, {
field: 'data_size',
title: '字节数',
align: 'center',
width: 120
}, {
field: 'data_length',
title: '数据大小',
align: 'center',
width: 120
}, {
field: 'comment',
title: '数据表注释'
}, {
field: 'create_time',
title: '创建时间',
width: 160,
align: 'center'
}
]
],
done:function(res, curr, count){
$('#dataTips').html(res.msg);
}
});
//监听行工具事件
table.on('toolbar(test)', function (obj) {
var checkData = table.checkStatus(obj.config.id).data;
var len = checkData.length;
var ids='';
if(len==0){
layer.msg('请先选择表');
return false;
}
for(var i=0;i<len;i++){
if(i==0){
ids+=checkData[i].name;
}
else{
ids+=','+checkData[i].name;
}
}
if (obj.event === 'backup') {
layer.confirm('确认要备份选中的'+len+'个数据表吗?', {
icon: 3,
title: '提示'
}, function (index) {
$.ajax({
url: "{:url('home/database/backup')}",
data: {'id':ids},
success: function (res) {
layer.msg(res.msg);
if (res.code == 0) {
location.reload();
}
}
})
layer.close(index);
});
}else if (obj.event === 'optimize') {
layer.confirm('确认要优化选中的'+len+'个数据表吗?', {
icon: 3,
title: '提示'
}, function (index) {
$.ajax({
url: "{:url('home/database/optimize')}",
data: {'id':ids},
success: function (res) {
layer.msg(res.msg);
if (res.code == 0) {
location.reload();
}
}
})
layer.close(index);
});
}else if (obj.event === 'repair') {
layer.confirm('确认要修复选中的'+len+'个数据表吗?', {
icon: 3,
title: '提示'
}, function (index) {
$.ajax({
url: "{:url('home/database/repair')}",
data: {'id':ids},
success: function (res) {
layer.msg(res.msg);
if (res.code == 0) {
location.reload();
}
}
})
layer.close(index);
});
}
});
}
</script>
{include file="common/layui" base="base" extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,110 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<form class="layui-form body-content">
{eq name="$id" value="0"}
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray2">上级部门<font>*</font></td>
<td>
<select name="pid" lay-verify="required" lay-reqText="请选择上级部门">
<option value="0">作为顶级部门</option>
{volist name="department" id="v"}
<option value="{$v.id}" {eq name="pid" value="$v.id" }selected {/eq}>{$v.title}</option>
{/volist}
</select>
</td>
<td class="layui-td-gray2">部门名称<font>*</font></td>
<td>
<input type="text" name="title" lay-verify="required" autocomplete="off" placeholder="请输入部门名称" lay-reqText="请输入部门名称" class="layui-input">
</td>
</tr>
<tr>
<td class="layui-td-gray2">部门负责人</td>
<td>
<input type="text" name="uid" placeholder="请选择部门负责人,可空" autocomplete="off" class="layui-input">
</td>
<td class="layui-td-gray2">部门联系电话</td>
<td>
<input type="text" name="phone" placeholder="请输入部门联系电话,可空" autocomplete="off" class="layui-input">
</td>
</tr>
</table>
{else/}
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray2">上级部门<font>*</font></td>
<td>
<select name="pid" lay-verify="required" lay-reqText="请选择上级部门">
<option value="0">作为顶级部门</option>
{volist name="department" id="v"}
<option value="{$v.id}" {eq name="detail.pid" value="$v.id"} selected{/eq}>{$v.title}</option>
{/volist}
</select>
</td>
<td class="layui-td-gray2">部门名称<font>*</font></td>
<td>
<input type="text" name="title" value="{$detail.title}" lay-verify="required" autocomplete="off" placeholder="请输入部门名称" lay-reqText="请输入部门名称" class="layui-input">
</td>
</tr>
<tr>
<td class="layui-td-gray2">部门负责人</td>
<td>
<input type="text" name="uid" value="{$detail.uid}" placeholder="请选择部门负责人,可空" autocomplete="off" class="layui-input">
</td>
<td class="layui-td-gray2">部门联系电话</td>
<td>
<input type="text" name="phone" value="{$detail.phone}" placeholder="请输入部门联系电话,可空" autocomplete="off" class="layui-input">
</td>
</tr>
</table>
{/eq}
<div style="padding: 10px 0">
<input type="hidden" name="id" value="{$id}">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<button lay-event="back" class="layui-btn layui-btn-primary">返回</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var form = layui.form,
layer = layui.layer;
//监听提交
form.on('submit(webform)', function(data) {
$.ajax({
url: "{:url('home/department/post_submit')}",
type: 'post',
data: data.field,
success: function(e) {
if (e.code == 0) {
layer.confirm('保存成功,返回列表页吗?', {
icon: 3,
title: '提示'
}, function(index) {
history.back(-1);
layer.close(index);
});
} else {
layer.msg(e.msg);
}
}
})
return false;
});
//监听返回
$('.body-content').on('click', '[lay-event="back"]', function() {
history.back(-1);
return false;
});
}
</script>
{include file="common/layui" base="base" extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,80 @@
{extend name="common/base"/}
{block name="style"}
<style>
html,
body {
height: calc(100% - 20px);
}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<div class="body-content" style="height: 100%">
<div style="height:39px;">
<a class="layui-btn layui-btn-normal layui-btn-sm" href="{:url('home/department/add')}">+ 添加部门</a>
</div>
<div style="height: calc(100% - 30px)">
<table class="layui-hide" id="treeTable" lay-filter="treeTable"></table>
</div>
</div>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var treeGrid = layui.treeGrid,
layer = layui.layer,
ptable = treeGrid.render({
id: 'treeTable'
, elem: '#treeTable'
, idField: 'id'
, url: "{:url('home/department/index')}"
, cellMinWidth: 100
, treeId: 'id'//树形id字段名称
, treeUpId: 'pid'//树形父id字段名称
, treeShowName: 'title'//以树形式显示的字段
, height: 'full-0'
,isOpenDefault:true
, cols: [[
{ field: 'id', width: 100, title: 'ID号', align: 'center' }
, { field: 'pid', title: '上级部门ID',width: 120, align: 'center'}
, { field: 'title', title: '部门名称'}
, { field: 'uername', title: '部门负责人',width: 120, align: 'center'}
, { field: 'phone', title: '部门电话',width: 180, align: 'center'}
, { width: 200, title: '操作', align: 'center', templet: function (d) {
var html = '<a class="layui-btn layui-btn-normal layui-btn-xs" href="/home/department/add?pid=' + d.id + '">添加下级部门</a><a class="layui-btn layui-btn-xs" href="/home/department/add?id=' + d.id + '">编辑</a><a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>';
return html;
}
}
]]
, page: false
});
//删除
treeGrid.on('tool(treeTable)', function (obj) {
if (obj.event === 'del') {
layer.confirm('确定要删除吗?', { icon: 3, title: '提示' }, function (index) {
$.ajax({
url: "{:url('home/department/delete')}",
type: 'post',
data: { id: obj.data.id },
success: function (e) {
layer.msg(e.msg);
if (e.code == 0) {
obj.del();
}
}
})
layer.close(index);
});
}
});
}
</script>
{include file="common/layui" base="base" extend="['treeGrid']" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,279 @@
{extend name="common/base"/}
{block name="style"}
<style>
.layui-table-min th{font-size:13px; text-align:center; background-color:#f8f8f8;}
.layui-table-min td{font-size:13px; padding:6px;text-align:center;}
</style>
<link rel="stylesheet" href="{__JS__}/module/dtree/dtree.css">
<link rel="stylesheet" href="{__JS__}/module/dtree/font/dtreefont.css">
{/block}
<!-- 主体 -->
{block name="body"}
<form class="layui-form body-content">
<h3>报销信息</h3>
{if condition="($id == 0)"}
<table class="layui-table">
<tr>
<td class="layui-td-gray2">报销凭证编号<span style="color: red">*</span></td>
<td>
<input type="text" name="code" autocomplete="off" lay-verify="required" placeholder="报销凭证编号" lay-reqText="请填写报销凭证编号" class="layui-input" value="">
</td>
<td class="layui-td-gray">入账月份<span style="color: red">*</span></td>
<td>
<input type="text" class="layui-input" id="income_month" name="income_month" lay-verify="required" placeholder="请选择入账月份" lay-reqText="请选择入账月份" readonly value="">
</td>
<td class="layui-td-gray2">原始单据日期<span style="color: red">*</span></td>
<td>
<input type="text" class="layui-input" id="expense_time" name="expense_time" lay-verify="required" placeholder="请选择原始单据日期" lay-reqText="请选择原始单据日期" readonly value="">
</td>
</tr>
<tr>
<td class="layui-td-gray2">报销人<span style="color: red">*</span></td>
<td>
<input type="text" name="name" placeholder="请选择报销人" readonly class="layui-input" lay-verify="required" lay-reqText="请选择报销人" value="{$user.name}" readonly>
<input type="hidden" name="uid" autocomplete="off" class="layui-input" value="{$user.id}">
</td>
<td class="layui-td-gray">报销部门</td>
<td>
<input type="text" name="department" readonly class="layui-input" value="{$user.department}" readonly>
<input type="hidden" name="did" autocomplete="off" class="layui-input" value="{$user.did}">
</td>
</tr>
<tr>
<td class="layui-td-gray2">费用金额<span style="color: red">*</span><button class="layui-btn layui-btn-normal layui-btn-sm" type="button" id="addInterfix">+报销选项</button></td>
<td colspan="5">
<div>
<table id="interfix" class="layui-table layui-table-min">
<tr>
<th width="200">报销金额</th>
<th width="300">报销项目</th>
<th>备注信息</th>
<th width="100">操作</th>
</tr>
<tr class="more_interfix">
<td><input type="text" name="amount[]" value="" class="layui-input" lay-verify="required|number" lay-reqText="请完善报销金额"></td>
<td style="text-align:left">
<select name="cate_id[]" lay-verify="required" lay-reqText="请选择报销项目">
<option value="">请选择</option>
{volist name="$expense_cate" id="vo"}
<option value="{$vo.id}">{$vo.title}</option>
{/volist}
</select>
</td>
<td><input type="text" name="remarks[]" class="layui-input" value=""><input type="hidden" name="expense_id[]" class="layui-input" value="0"></td>
<td><a class="layui-btn layui-btn-danger layui-btn-xs" data-id="0" lay-event="del">删除</a></td>
</tr>
</table>
</div>
</td>
</tr>
</table>
{else/}
<table class="layui-table">
<tr>
<td class="layui-td-gray2">报销凭证编号<span style="color: red">*</span></td>
<td>
<input type="text" name="code" autocomplete="off" lay-verify="required" placeholder="报销凭证编号" lay-reqText="请填写报销凭证编号" class="layui-input" value="{$expense.code}">
</td>
<td class="layui-td-gray">入账月份<span style="color: red">*</span></td>
<td>
<input type="text" class="layui-input" id="income_month" name="income_month" lay-verify="required" placeholder="请选择入账月份" lay-reqText="请选择入账月份" readonly value="{$expense.income_month}">
</td>
<td class="layui-td-gray2">原始单据日期<span style="color: red">*</span></td>
<td>
<input type="text" class="layui-input" id="expense_time" name="expense_time" lay-verify="required" placeholder="请选择原始单据日期" lay-reqText="请选择原始单据日期" readonly value="{$expense.expense_time}">
</td>
</tr>
<tr>
<td class="layui-td-gray2">报销人<span style="color: red">*</span></td>
<td>
<input type="text" name="name" placeholder="请选择报销人" readonly class="layui-input" lay-verify="required" lay-reqText="请选择报销人" value="{$expense.user_name}" readonly>
<input type="hidden" name="uid" autocomplete="off" class="layui-input" value="{$expense.uid}">
</td>
<td class="layui-td-gray">报销部门</td>
<td>
<input type="text" name="department" readonly class="layui-input" value="{$expense.department}" readonly>
<input type="hidden" name="did" autocomplete="off" class="layui-input" value="{$expense.did}">
</td>
</tr>
<tr>
<td class="layui-td-gray2">费用金额<span style="color: red">*</span><button class="layui-btn layui-btn-normal layui-btn-sm" type="button" id="addInterfix">+报销选项</button></td>
<td colspan="5">
<div>
<table id="interfix" class="layui-table layui-table-min">
<tr>
<th width="200">报销金额</th>
<th width="300">报销类别</th>
<th>备注信息</th>
<th width="100">操作</th>
</tr>
{volist name="$expense.list" id="val"}
<tr class="more_interfix">
<td><input type="text" name="amount[]" value="{$val.amount}" class="layui-input" lay-verify="required|number" lay-reqText="请完善报销金额"></td>
<td style="text-align:left">
<select name="cate_id[]" lay-verify="required" lay-reqText="请选择报销项目">
<option value="">请选择</option>
{volist name="$expense_cate" id="vo"}
<option value="{$vo.id}" {eq name="$vo.id" value="$val.cate_id"} selected{/eq}>{$vo.title}</option>
{/volist}
</select>
</td>
<td><input type="text" name="remarks[]" class="layui-input" value="{$val.remarks}"><input type="hidden" name="expense_id[]" class="layui-input" value="{$val.id}"></td>
<td><a class="layui-btn layui-btn-danger layui-btn-xs" data-id="{$val.id}" lay-event="del">删除</a></td>
</tr>
{/volist}
</table>
</div>
</td>
</tr>
</table>
{/if}
<div class="layui-form-item" style="padding-top:10px;">
<input name="id" id="id" type="hidden" value="{$id}">
<button class="layui-btn" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
<div id="selectTem" style="display:none;">
<select name="cate_id[]" lay-verify="required" lay-reqText="请选择报销项目">
<option value="">请选择</option>
{volist name="$expense_cate" id="vo"}
<option value="{$vo.id}">{$vo.title}</option>
{/volist}
</select>
</div>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui){
var form = layui.form
,layer = layui.layer
,table = layui.table
,employeepicker = layui.employeepicker//很重要
,laydate = layui.laydate;
laydate.render({
elem: '#income_month',
type:'month',
showBottom: false
});
laydate.render({
elem: '#expense_time',
max:0,
showBottom: false
});
// 选择员工
$('.body-content').on('click','[name="name"]',function(){
var that = $(this);
var names = that.val(), ids = $('[name="uid"]').val();
employeepicker.init({
ids: ids,
names: names,
type: 0,
department_url:"{:url('/home/api/get_department_tree')}",
employee_url:"{:url('/home/api/get_employee')}",
callback: function (ids, names, dids, departments) {
$('[name="uid"]').val(ids);
$('[name="did"]').val(dids);
$('[name="department"]').val(departments);
that.val(names);
}
})
});
//监听提交
form.on('submit(webform)', function(data){
var interfix = $('.more_interfix');
if(interfix.length <1 ){
layer.msg('至少要保留一个报销选项');
return false;
}
$.ajax({
url:"{:url('/home/expense/post_submit')}",
type:'post',
data:data.field,
success:function(e){
layer.msg(e.msg);
if(e.code==0){
parent.location.reload();
}
}
})
return false;
});
//添加报销信息表格
$('#addInterfix').on('click',function(){
var html = '';
var selectTem=$('#selectTem').html();
html += '<tr class="more_interfix">\
<td><input type="text" name="amount[]" class="layui-input" lay-verify="required|number" lay-reqText="请完善报销金额"></td>\
<td style="text-align:left">'+selectTem+'</td>\
<td><input type="text" name="remarks[]" class="layui-input"><input type="hidden" name="expense_id[]" class="layui-input" value="0"></td>\
<td><a class="layui-btn layui-btn-danger layui-btn-xs" data-id="0" lay-event="del">删除</a></td>\
</tr>';
$("#interfix").append(html).find('.tr-none').remove();
form.render();
});
$('#interfix').on('click', '[lay-event="del"]', function() {
if($('.more_interfix').length<2){
layer.msg('至少保留一个报销选项');
return false;
}
var that=$(this);
var _id = that.data('id');
if(_id>0){
layer.confirm('确定删除该报销数据项?', {
icon: 3,
title: '提示'
}, function(index) {
$.ajax({
url: "{:url('home/api/del_expense_interfix')}",
data: {
id: _id
},
success: function(res) {
layer.msg(res.msg);
if (res.code == 0) {
that.parents(".more_interfix").remove();
}
}
})
layer.close(index);
});
}
else{
that.parents(".more_interfix").remove();
}
});
//报销成员修改
$('[name="nickname"]').on('click',function() {
var that=$(this);
var ids=that.next().val(),names=that.val();
employeepicker.init({
ids:ids,
names:names,
type:0,
callback:function(ids,names,dids,departments){
that.val(names);
that.next().val(ids);
$('[name="department"]').val(departments);
$('[name="did"]').val(dids);
}
});
});
}
</script>
{include file="common/layui" base='base' extend="['employeepicker']" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,146 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<div class="body-content">
<table class="layui-hide" id="test" lay-filter="test"></table>
</div>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-normal layui-btn-sm addNew" type="button">+ 添加报销类别</button>
</div>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui){
var table=layui.table,
form = layui.form,
layer=layui.layer;
var tableIns = table.render({
elem: '#test'
,toolbar: '#toolbarDemo'
,title:'报销类别列表'
,url:"{:url('home/expense/cate')}"
,page: true //开启分页
,limit: 20
,cellMinWidth: 80
,cols: [[
{field:'id',width:80, title: 'ID号', align:'center'}
,{field:'title',title: '类别名称'}
,{field:'status', title: '状态',width:80,align:'center',templet: function(d){
var html1='<span>正常</span>';
var html2='<span style="color:#FF5722">禁用</span>';
if(d.status==1){
return html1;
}
else{
return html2;
}
}}
,{width:100,title: '操作', align:'center',templet: function(d){
var html='';
var btn='<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>';
var btn1='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="disable">禁用</a>';
var btn2='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="open">启用</a>';
if(d.status==1){
html = '<div class="layui-btn-group">'+btn+btn1+'</div>';
}
else{
html = '<div class="layui-btn-group">'+btn+btn2+'</div>';
}
return html;
}}
]]
});
table.on('tool(test)',function (obj) {
if(obj.event === 'edit'){
addExpense(obj.data.id,obj.data.title);
}
if(obj.event === 'disable'){
layer.confirm('确定要禁用该类别吗?', {icon: 3, title:'提示'}, function(index){
$.ajax({
url: "{:url('home/expense/cate_post_submit')}",
type: 'post',
data: {
id: obj.data.id,
status: 0,
title: obj.data.title,
},
success: function(e) {
layer.msg(e.msg);
if (e.code == 0) {
setTimeout('location.reload()', 1000);
}
}
})
layer.close(index);
});
}
if(obj.event === 'open'){
layer.confirm('确定要启用该类别吗?', {icon: 3, title:'提示'}, function(index){
$.ajax({
url: "{:url('home/expense/cate_post_submit')}",
type: 'post',
data: {
id: obj.data.id,
status: 1,
title: obj.data.title,
},
success: function(e) {
layer.msg(e.msg);
if (e.code == 0) {
setTimeout('location.reload()', 1000);
}
}
})
layer.close(index);
});
}
});
$('.body-content').on('click','.addNew',function(){
addExpense(0,'');
});
function addExpense(id,val){
var title = '新增类别';
if(id>0){
title = '编辑类别';
}
layer.prompt({
title: title,
value: val,
yes: function(index, layero) {
// 获取文本框输入的值
var value = layero.find(".layui-layer-input").val();
if (value) {
$.ajax({
url: "{:url('home/expense/cate_post_submit')}",
type: 'post',
data: {
id: id,
title: value,
},
success: function(e) {
layer.msg(e.msg);
if (e.code == 0) {
setTimeout('location.reload()', 1000);
}
}
})
} else {
layer.msg('请填写类别标题');
}
}
})
}
}
</script>
{include file="common/layui" base='base' extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,175 @@
{extend name="common/base"/}
{block name="style"}
<style>
.layui-table-min th{font-size:13px; text-align:center; background-color:#f8f8f8;}
.layui-table-min td{font-size:13px; padding:6px;text-align:center;}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<div class="body-content">
<h3>报销详情</h3>
<table class="layui-table">
<tr>
<td class="layui-td-gray2">报销凭证编号</td>
<td>{$expense.code}</td>
<td class="layui-td-gray2">入账月份</td>
<td>{$expense.income_month}</td>
<td class="layui-td-gray2">原始单据日期</td>
<td>{$expense.expense_time}</td>
</tr>
<tr>
<td class="layui-td-gray2">报销人</td>
<td>{$expense.user_name}</td>
<td class="layui-td-gray2">报销部门</td>
<td>{$expense.department}</td>
<td class="layui-td-gray">报销总费用(元)</td>
<td><span style="color:#1E9FFF">{$expense.amount}</span></td>
</tr>
<tr>
<td class="layui-td-gray2">报销状态</td>
<td colspan="5">
{if condition="$expense.check_status == 0"}
<span style="color:#FF5722">审核不通过 【原因:{$expense.check_remark}】</span>
{elseif condition="$expense.check_status == 1"}
<span style="color:#393D49">报销审核中</span>
{elseif condition="$expense.check_status == 2"}
<span style="color:#5FB878">审核通过</span>
{elseif condition="$expense.check_status == 3"}
<span style="color:#009688">已打款</span>
{/if}
</td>
</tr>
{if condition="$expense.check_admin_id > 0"}
<tr>
<td class="layui-td-gray2">审核人</td>
<td>{$expense.check_admin}</td>
<td class="layui-td-gray2">审核时间</td>
<td colspan="3">{$expense.check_time}</td>
</tr>
{/if}
{if condition="$expense.pay_admin_id > 0"}
<tr>
<td class="layui-td-gray2">打款确认人</td>
<td>{$expense.pay_admin}</td>
<td class="layui-td-gray2">打款确认时间</td>
<td colspan="3">{$expense.pay_time}</td>
</tr>
{/if}
<tr>
<td class="layui-td-gray2">费用金额</td>
<td colspan="5">
<div>
<table class="layui-table layui-table-min">
<tr>
<th width="200">报销金额(元)</th>
<th width="300">报销类别</th>
<th>备注信息</th>
</tr>
{volist name="$expense.list" id="vo"}
<tr>
<td>{$vo.amount}</td>
<td>{$vo.cate_title}</td>
<td style="text-align:left">{$vo.remarks}</td>
</tr>
{/volist}
</table>
</div>
</td>
</tr>
</table>
<div class="layui-form-item" style="padding-top:10px;">
<input name="id" id="id" type="hidden" value="{$expense.id}">
{if condition="($expense.check_status == 0) AND ($uid == $expense.admin_id)"}
<a class="layui-btn" href="/home/expense/add?id={$expense.id}">编辑</a>
{/if}
{eq name="$expense.check_status" value="1"}
<button class="layui-btn layui-btn-danger" lay-event="checkno">审核不通过</button>
<button class="layui-btn" lay-event="checkok">审核通过</button>
{/eq}
{eq name="$expense.check_status" value="2"}
<button class="layui-btn" lay-event="payed">已打款确认</button>
{/eq}
</div>
</div>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
//监听返回
$('.body-content').on('click', '[lay-event="back"]', function () {
window.location.href="{:url('home/expense/index')}";
return false;
});
$('.body-content').on('click', '[lay-event="checkok"]', function () {
var id=$('#id').val();
layer.confirm('确定审核通过该报销申请?', {icon: 3, title:'提示'}, function(index){
$.ajax({
url:"{:url('home/expense/check')}",
data:{id:id,check_status:2},
success:function(res){
layer.msg(res.msg);
if(res.code==0){
window.setTimeout(function(){
window.location.reload();
},1200)
}
}
})
})
return false;
});
$('.body-content').on('click', '[lay-event="checkno"]', function () {
var id=$('#id').val();
layer.confirm('确定拒绝该提现申请?', {icon: 3, title:'提示'}, function(index){
layer.prompt({title: '拒绝的理由', formType: 3,value :''}, function(text, index){
if(text ==''){
layer.msg('请输入拒绝的理由');
return false;
}
$.ajax({
url:"{:url('home/expense/check')}",
data:{id:id,check_status:0,check_remark:text},
success:function(res){
layer.msg(res.msg);
if(res.code==0){
window.setTimeout(function(){
parent.location.reload();
},1200)
}
}
})
layer.closeAll();
})
})
})
$('.body-content').on('click', '[lay-event="payed"]', function () {
var id=$('#id').val();
layer.confirm('确定已经打款?', {icon: 3, title:'提示'}, function(index){
$.ajax({
url:"{:url('home/expense/check')}",
data:{id:id,check_status:3},
success:function(res){
layer.msg(res.msg);
if(res.code==0){
window.setTimeout(function(){
parent.location.reload();
},1200)
}
}
})
})
})
}
</script>
{include file="common/layui" base='base' extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,156 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<div class="body-content">
<table class="layui-hide" id="test" lay-filter="test"></table>
</div>
<script type="text/html" id="barDemo">
<div class="layui-btn-group"><span class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详情</span><span class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</span></div>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var table = layui.table,
rightpage = layui.rightpage,
form = layui.form;
var tableIns = table.render({
elem: '#test',
title: '报销管理列表',
toolbar: '#toolbarDemo',
url: "{:url('home/expense/index')}", //数据接口
page: true, //开启分页
limit: 20,
cols: [
[
{
field: 'id',
title: 'ID号',
align: 'center',
width: 80
}, {
field: 'amount',
title: '报销总金额(元)',
align: 'right',
width: 120,
},{
field: 'user_name',
title: '报销人',
align: 'center',
width: 90
},{
field: 'department',
title: '报销部门',
align: 'center',
width: 120
},{
field: 'code',
title: '报销凭证编号',
width: 150,
},{
field: 'expense_time',
title: '原始单据日期',
align: 'center',
width: 110
},{
field: 'income_month',
title: '入账月份',
align: 'center',
width: 100
},{
field: 'admin_name',
title: '登记人',
align: 'center',
width: 100
},{
field: 'create_time',
title: '录入时间',
align: 'center',
width: 150
},{
field: 'status',
title: '状态',
align: 'center',
width: 120,
templet:function(d){
var html='<span style="color:#FF5722">审核不通过</span>';
if(d.check_status==1){
html='<span style="color:#393D49">报销审核中</span>';
}
else if(d.check_status==2){
html='<span style="color:#5FB878">审核通过</span>';
}
else if(d.check_status==3){
html='<span style="color:#009688">已打款</span>';
}
return html;
}
},{
field: 'check_name',
title: '审核人',
align: 'center',
width: 90
},{
field: 'check_time',
title: '审核时间',
align: 'center',
width: 136
},{
field: 'pay_name',
title: '打款确认人',
align: 'center',
width: 90
},{
field: 'pay_time',
title: '打款确认时间',
align: 'center',
width: 136
}, {
field: 'right',
fixed: 'right',
title: '操作',
toolbar: '#barDemo',
width: 100,
align: 'center'
}
]
]
});
//监听行工具事件
table.on('tool(test)', function(obj) {
var data = obj.data;
if (obj.event === 'view') {
rightpage.open("/home/expense/check?id="+data.id);
return;
}
if (obj.event === 'del') {
layer.confirm('确定删除该报销记录吗?', {
icon: 3,
title: '提示'
}, function(index) {
$.ajax({
url: "{:url('home/expense/delete')}",
data: {
id: data.id
},
success: function(res) {
layer.msg(res.msg);
if (res.code == 0) {
obj.del();
}
}
})
layer.close(index);
});
}
});
}
</script>
{include file="common/layui" base='base' extend="['rightpage']" use="['table','form']" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,161 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<div class="body-content">
<table class="layui-hide" id="test" lay-filter="test"></table>
</div>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<a class="layui-btn layui-btn-normal layui-btn-sm" href="{:url('home/expense/add')}">添加报销登记</a>
</div>
</script>
<script type="text/html" id="barDemo">
<div class="layui-btn-group"><span class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详情</span><span class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</span></div>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var table = layui.table,
rightpage = layui.rightpage,
form = layui.form;
var tableIns = table.render({
elem: '#test',
title: '报销管理列表',
toolbar: '#toolbarDemo',
url: "{:url('home/expense/index')}", //数据接口
page: true, //开启分页
limit: 20,
cols: [
[
{
field: 'id',
title: 'ID号',
align: 'center',
width: 80
}, {
field: 'amount',
title: '报销总金额(元)',
align: 'right',
width: 120,
},{
field: 'user_name',
title: '报销人',
align: 'center',
width: 90
},{
field: 'department',
title: '报销部门',
align: 'center',
width: 120
},{
field: 'code',
title: '报销凭证编号',
width: 150,
},{
field: 'expense_time',
title: '原始单据日期',
align: 'center',
width: 110
},{
field: 'income_month',
title: '入账月份',
align: 'center',
width: 100
},{
field: 'admin_name',
title: '登记人',
align: 'center',
width: 100
},{
field: 'create_time',
title: '录入时间',
align: 'center',
width: 150
},{
field: 'status',
title: '状态',
align: 'center',
width: 120,
templet:function(d){
var html='<span style="color:#FF5722">审核不通过</span>';
if(d.check_status==1){
html='<span style="color:#393D49">报销审核中</span>';
}
else if(d.check_status==2){
html='<span style="color:#5FB878">审核通过</span>';
}
else if(d.check_status==3){
html='<span style="color:#009688">已打款</span>';
}
return html;
}
},{
field: 'check_name',
title: '审核人',
align: 'center',
width: 90
},{
field: 'check_time',
title: '审核时间',
align: 'center',
width: 136
},{
field: 'pay_name',
title: '打款确认人',
align: 'center',
width: 90
},{
field: 'pay_time',
title: '打款确认时间',
align: 'center',
width: 136
}, {
field: 'right',
fixed: 'right',
title: '操作',
toolbar: '#barDemo',
width: 100,
align: 'center'
}
]
]
});
//监听行工具事件
table.on('tool(test)', function(obj) {
var data = obj.data;
if (obj.event === 'view') {
rightpage.open("/home/expense/check?id="+data.id);
return;
}
if (obj.event === 'del') {
layer.confirm('确定删除该报销记录吗?', {
icon: 3,
title: '提示'
}, function(index) {
$.ajax({
url: "{:url('home/expense/delete')}",
data: {
id: data.id
},
success: function(res) {
layer.msg(res.msg);
if (res.code == 0) {
obj.del();
}
}
})
layer.close(index);
});
}
});
}
</script>
{include file="common/layui" base='base' extend="['rightpage']" use="['table','form']" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,100 @@
{extend name="common/base"/}
{block name="style"}
<style>
.layui-table-min th{font-size:13px; text-align:center; background-color:#f8f8f8;}
.layui-table-min td{font-size:13px; padding:6px;text-align:center;}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<div class="body-content">
<h3>报销详情</h3>
<table class="layui-table">
<tr>
<td class="layui-td-gray2">报销凭证编号</td>
<td>{$expense.code}</td>
<td class="layui-td-gray2">入账月份</td>
<td>{$expense.income_month}</td>
<td class="layui-td-gray2">原始单据日期</td>
<td>{$expense.expense_time}</td>
</tr>
<tr>
<td class="layui-td-gray2">报销人</td>
<td>{$expense.user_name}</td>
<td class="layui-td-gray2">报销部门</td>
<td>{$expense.department}</td>
<td class="layui-td-gray">报销总费用(元)</td>
<td><span style="color:#1E9FFF">{$expense.amount}</span></td>
</tr>
<tr>
<td class="layui-td-gray2">报销状态</td>
<td colspan="5">
{if condition="$expense.check_status == 0"}
<span style="color:#FF5722">审核不通过 【原因:{$expense.check_remark}】</span>
{elseif condition="$expense.check_status == 1"}
<span style="color:#393D49">报销审核中</span>
{elseif condition="$expense.check_status == 2"}
<span style="color:#5FB878">审核通过</span>
{elseif condition="$expense.check_status == 3"}
<span style="color:#009688">已打款</span>
{/if}
</td>
</tr>
{if condition="$expense.check_admin_id > 0"}
<tr>
<td class="layui-td-gray2">审核人</td>
<td>{$expense.check_admin}</td>
<td class="layui-td-gray2">审核时间</td>
<td colspan="3">{$expense.check_time}</td>
</tr>
{/if}
{if condition="$expense.pay_admin_id > 0"}
<tr>
<td class="layui-td-gray2">打款确认人</td>
<td>{$expense.pay_admin}</td>
<td class="layui-td-gray2">打款确认时间</td>
<td colspan="3">{$expense.pay_time}</td>
</tr>
{/if}
<tr>
<td class="layui-td-gray2">费用金额</td>
<td colspan="5">
<div>
<table class="layui-table layui-table-min">
<tr>
<th width="200">报销金额(元)</th>
<th width="300">报销类别</th>
<th>备注信息</th>
</tr>
{volist name="$expense.list" id="vo"}
<tr>
<td>{$vo.amount}</td>
<td>{$vo.cate_title}</td>
<td style="text-align:left">{$vo.remarks}</td>
</tr>
{/volist}
</table>
</div>
</td>
</tr>
</table>
{if condition="($expense.check_status == 0) AND ($uid == $expense.admin_id)"}
<div class="layui-form-item" style="padding-top:10px;">
<a class="layui-btn" href="/home/expense/add?id={$expense.id}">编辑</a>
</div>
{/if}
</div>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
}
</script>
{include file="common/layui" base='base' extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,126 @@
{extend name="common/base"/}
{block name="style"}
<link rel="stylesheet" href="{__LAYUI__}/font/extend/iconfont.css?v={:get_system_config('web','version')}">
<link rel="stylesheet" href="{__CSS__}/gougucms.css?v={:get_system_config('web','version')}">
{/block}
<!-- 主体 -->
{block name="body"}
<div class="layui-layout-body">
<div class="layui-layout layui-layout-admin">
<div class="layui-header">
<div class="layui-logo" ittab-home><img src="{__IMG__}/syslogo.png" width="166"
alt="{:get_system_config('web','admin_title')}" /></div>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item" lay-unselect>
<a href="javascript:;" ittab-refresh class="refreshThis" id="ittab-refresh" title="刷新当前页"
style="margin-top:3px;">
<i class="layui-icon layui-icon-refresh-3"></i>
</a>
</li>
<li class="layui-nav-item" lay-unselect>
<a href="javascript:;" ittab-del-cache id="ittab-del-cache" style="margin-top:2px;" title="清空缓存"><i
class="layui-icon layui-icon-fonts-clear"></i></a>
</li>
<li class="layui-nav-item" lay-unselect>
<a href="javascript:;" ittab-logout title="{:get_login_admin('nickname')}-点击退出登录">
<img src="{:get_login_admin('thumb')}" class="layui-nav-img"
onerror="javascript:this.src='{__IMG__}/nonepic360x360.jpg';this.onerror=null;">
</a>
</li>
</ul>
</div>
<div class="layui-side ittab-bg-gray">
<div class="ittab-menulist">
<div class="ittab-menulist-top">
<a href="/" title="返回首页" style="background-color: #E94335"><i class="layui-icon layui-icon-home"></i></a><a href="javascript:;" title="修改个人信息" style="background-color:#fbbc05" data-id="10000" data-title="修改个人信息" data-src="{:url('home/api/edit_personal')}" class="site-menu-active"><i class="layui-icon layui-icon-username"></i></a><a href="javascript:;" title="修改密码" style="background-color:#4285f4" data-id="10001" data-title="修改密码" data-src="{:url('home/api/edit_password')}" class="site-menu-active"><i class="layui-icon layui-icon-password"></i></a>
</div>
<div class="ittab-menulist-1">
{foreach name="menu" item="a"}
<div class="ittab-menulist-2"><i class="iconfont {$a.icon}"></i> {$a.title}</div>
{notempty name="$a.list"}
<div class="ittab-menulist-3">
<ul>
{foreach name="$a.list" item="b"}
{empty name="$b.list"}
<li data-id="{$b.id}" data-title="{$b.title}" data-src="{:url($b.src)}"
class="site-menu-active"><span>{$b.title}</span></li>
{else /}
<li class="ittab-menulist-2">{$b.title}<i class="layui-icon layui-icon-triangle-r"></i></li>
<div class="ittab-menulist-3 ittab-menulist-4">
<ul>
{foreach name="$b.list" item="c"}
{empty name="$c.list"}
<li data-id="{$c.id}" data-title="{$c.title}" data-src="{:url($c.src)}"
class="site-menu-active"><span>{$c.title}</span></li>
{else /}
<li class="ittab-menulist-2">{$c.title}<i
class="layui-icon layui-icon-triangle-r"></i></li>
<div class="ittab-menulist-3 ittab-menulist-5">
<ul>
{foreach name="$c.list" item="d"}
<li data-id="{$d.id}" data-title="{$d.title}" data-src="{:url($d.src)}"
class="site-menu-active"><span>{$d.title}</span></li>
{/foreach}
</ul>
</div>
{/empty}
{/foreach}
</ul>
</div>
{/empty}
{/foreach}
</ul>
</div>
{/notempty}
{/foreach}
</div>
</div>
</div>
<div class="layui-body">
<div class="layui-tab layui-tab-brief gougu-admin-tab" lay-filter="gougu-admin-tab" lay-unauto="" lay-allowClose="true" style="height: 100%;">
<ul class="layui-tab-title">
<li class="layui-this ittab-tab-home" lay-id="0">首页</li>
</ul>
<div class="layui-icon layui-icon-prev" id="left_button" title="向左滚动菜单"></div>
<div class="layui-icon layui-icon-next" id="right_button" title="向右滚动菜单"></div>
<div class="layui-tab-content" style="height: 100%;">
<div class="layui-tab-item layui-show">
<iframe id="0" data-frameid="0" name="myiframe" src="{:url('home/index/main')}" frameborder="0" align="left" width="100%" height="100%" scrolling="yes"></iframe>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- /主体 -->
{/block}
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var layer = layui.layer;
$("[ittab-logout]").on("click", function () {
layer.confirm('确认注销登录吗?', { icon: 7, title: '警告' }, function (index) {
//注销
$.ajax({
url: "{:url('home/login/login_out')}",
success: function (e) {
layer.msg(e.msg);
if (e.code == 0) {
setTimeout(function () {
location.href = "{:url('home/login/index')}"
}, 1000)
}
}
})
layer.close(index);
});
});
};
</script>
{include file="common/layui" base='base' extend="['gougucms']" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,480 @@
{extend name="common/base"/}
{block name="style"}
<style type="text/css">
.table-title {
font-size: 18px;
font-weight: 800;
padding: 15px 0 5px 15px;
}
.panel-num table {
width: 100%;
}
.panel-num td {
text-align: center;
padding: 20px 0;
width: 20%;
border-bottom: 1px solid #eee;
border-left: 1px solid #eee
}
.panel-num .num-title {
padding-bottom: 10px;
color: #999;
}
.panel-num .num-num {
font-size: 28px;
font-weight: 300;
color: #009688;
}
.layui-timeline-title {
padding-bottom: 0;
}
.layui-timeline-item {
padding-bottom: 1px;
}
.layui-timeline-title span {
color: #999
}
.layui-timeline{
padding-bottom: 30px;
}
.panel-more {
width: 100%;
height: 48px;
line-height: 48px;
text-align: center;
position: absolute;
bottom: 0;
left: 0;
background: linear-gradient(rgba(225, 225, 225, 0), rgba(225, 225, 225, .9));
}
.panel-more a {
color: #0088FF
}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<div class="layui-row layui-col-space10">
<div class="layui-col-md8">
<div class="layui-row layui-col-space10">
<div class="layui-col-md12">
<div class="layui-card panel-num">
<table>
<tr>
<td>
<div class="num-title">员工</div>
<div class="num-num">{$adminCount}</div>
</td>
<td>
<div class="num-title">知识</div>
<div class="num-num">{$articleCount}</div>
</td>
<td>
<div class="num-title">工作记录</div>
<div class="num-num">{$scheduleCount}</div>
</td>
<td>
<div class="num-title">客户</div>
<div class="num-num">0</div>
</td>
<td>
<div class="num-title">项目</div>
<div class="num-num">0</div>
</td>
</tr>
</table>
</div>
<div class="layui-card">
<div class="table-title">企业公告</div>
<div style="padding: 0 15px 5px;">
<table id="Note" lay-filter="Note" class="layui-hide" style="margin-top:0"></table>
</div>
</div>
<div class="layui-card">
<div class="table-title">知识列表</div>
<div style="padding: 0 15px 5px;">
<table id="Article" lay-filter="Article" class="layui-hide" style="margin-top:0"></table>
</div>
</div>
<div class="layui-card">
<div id="chartView" style="width: 100%;height:300px;"></div>
</div>
<div class="layui-card">
<div id="chartYear" style="width: 100%;height:240px;"></div>
</div>
</div>
</div>
</div>
<div class="layui-col-md4">
<div class="layui-card">
<div class="table-title">系统信息</div>
<div class="layui-card-body">
<table class="layui-table" lay-skin="" lay-size="sm">
{if condition="($install == true)"}
<tr>
<td colspan="4" style="color: #E94335; background-color:#f5f5f5">提醒发现app目录下的install文件夹没删除为了系统的安全,请手动去删除。</td>
</tr>
{/if}
<tr>
<td class="layui-td-gray">服务器系统</td>
<td>{:get_system_info('os')}</td>
<td class="layui-td-gray">PHP版本</td>
<td>{:get_system_info('php')}</td>
</tr>
<tr>
<td class="layui-td-gray">上传限制</td>
<td>{:get_system_info('upload_max_filesize')}</td>
<td class="layui-td-gray">执行限制</td>
<td>{:get_system_info('max_execution_time')}</td>
</tr>
<tr>
<td class="layui-td-gray">ThinkPHP</td>
<td colspan="3">{:TP_VERSION}<a class="layui-badge layui-bg-blue" style="margin-left:10px"
href="https://www.kancloud.cn/manual/thinkphp6_0" target="_blank">TP6文档</a></td>
</tr>
<tr>
<td class="layui-td-gray">Layui</td>
<td colspan="3">{:LAYUI_VERSION}<a class="layui-badge layui-bg-blue" style="margin-left:10px"
href="https://www.layui.site/doc/" target="_blank">Layui文档</a></td>
</tr>
<tr>
<td class="layui-td-gray">勾股OA</td>
<td colspan="3">{:CMS_VERSION}<a class="layui-badge layui-bg-blue" style="margin-left:10px"
href="https://oa.gougucms.com/" target="_blank">勾股OA</a></td>
</tr>
<tr>
<td class="layui-td-gray">BUG反馈</td>
<td><a href="mailto:hdm58@qq.com" target="_blank">hdm58@qq.com</a></td>
<td class="layui-td-gray">QQ交流群</td>
<td><a href="https://qm.qq.com/cgi-bin/qm/qr?k=verenlO-kEIhi6yi4mvD_Goye2KF50sa&authKey=NsYa9Dcx6R5EYzKYScW1XT8RfQskT/wtsVxtDNOyuMBRRkTpBpO5bmCVNbozQYFi&noverify=0" target="_blank">24641076</a></td>
</tr>
</table>
</div>
</div>
<div class="layui-card">
<div class="table-title">员工动态</div>
<div class="layui-card-body">
<ul class="layui-timeline" id="logs"></ul>
<div class="panel-more"><a href="{:url('home/api/log_list')}">查看更多动态</a></div>
</div>
</div>
</div>
</div>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.1.2/echarts.min.js"></script>
<script>
function init(layui) {
var layer = layui.layer, table = layui.table;
get_logs();
//公告
table.render({
elem: '#Note'
, url: "{:url('home/api/get_note_list')}" //数据接口
, page: false //开启分页
, cols: [[ //表头
{ field: 'cate_title', title: '公告分类', align: 'center','width': 120 },
{ field: 'title', title: '公告标题'},
{ field: 'create_time', title: '发布时间', align: 'center','width': 150}
]]
});
//文章
table.render({
elem: '#Article'
, url: "{:url('home/api/get_article_list')}" //数据接口
, page: false //开启分页
, cols: [[ //表头
{ field: 'cate_title', title: '知识分类', align: 'center','width': 120 },
{ field: 'title', title: '知识标题'},
{ field: 'read', title: '访问量', align: 'center','width': 80 },
{ field: 'create_time', title: '发布时间', align: 'center','width': 150}
]]
});
get_view_data();
}
function get_logs() {
$.ajax({
url: "{:url('home/api/get_log_list')}",
type: 'post',
data: {
page: 1,
limit: 20
},
success: function (e) {
if (e.code == 0) {
var html = '';
$.each(e.data, function (key, value) {
html += '<li class="layui-timeline-item">\
<i class="layui-icon layui-timeline-axis"></i>\
<div class="layui-timeline-content layui-text">\
<div class="layui-timeline-title"><span title="'+ value.id + '">' + value.times + '</span>' + value.content + '</div>\
</div>\
</li>';
});
$('#logs').html(html);
}
}
})
}
function setHour(num) {
var str = num + ':00';
if (num < 10) {
str = '0' + num + ':00';
}
return str;
}
var chartView = echarts.init(document.getElementById('chartView'));
function get_view_data() {
$.ajax({
url: "{:url('home/api/get_view_data')}",
type: 'post',
data: {},
success: function (e) {
if (e.code == 0) {
var data_first = e.data.data_first;
var data_second = e.data.data_second;
archiveCalendar = e.data.data_three;
var myDate = new Date();
var nowHour = myDate.getHours(); //获取当前小时数(0-23)
var xData = [];
var yData1 = [];
var yData2 = [];
$.each(data_first, function (key, value) {
if (key <= nowHour) {
yData1.push(value);
}
});
$.each(data_second, function (key, value) {
xData.push(setHour(key));
yData2.push(value);
});
var ops = {
title: {
top: '15px',
text: '今日与昨日访问统计',
left: '12px',
textStyle: {
fontSize: '18',
color: '#333',
}
},
color: ["#1AAD19", "#1890FF"],
grid: {
left: '20px',
right: '30px',
bottom: '15px',
top: '60px',
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
}
},
toolbox: {
show: true,
},
legend: {
data: ["今日", "昨日"],
top: '18px',
},
xAxis: [{
type: "category",
boundaryGap: !1,
data: xData,
axisLine: {
lineStyle: {
color: '#999999',
width: 1,
}
},
}],
yAxis: [{
type: "value",
axisLine: {
show: true,
lineStyle: {
color: '#999999',
width: 1,
}
},
}],
series: [{
name: "今日",
type: "line",
smooth: !0,
itemStyle: {
normal: {
areaStyle: {
type: "default",
opacity: 0.2
}
}
},
data: yData1
}, {
name: "昨日",
type: "line",
smooth: !0,
itemStyle: {
normal: {
areaStyle: {
type: "default",
opacity: 0.2
}
}
},
data: yData2
}]
}
chartView.setOption(ops);
let myChart = echarts.init(document.getElementById('chartYear'));
let option = {
title: {
top: '15px',
text: '近一年访问统计',
left: '12px',
textStyle: {
fontSize: '18',
color: '#333',
}
},
tooltip: {
padding: 6,
formatter: function (obj) {
var value = obj.value;
return '<div style="font-size: 12px;">' + value[0] + '' + value[1] + ' 个访客</div>';
}
},
visualMap: {
min: 0,
max: 300,
show: false,
inRange: {
color: ['#fafafa', '#1AAD19']
}
},
calendar: {
top: 75,
left: 52,
right: 20,
range: getRange(),
cellSize: ['auto', 21],
splitLine: {
lineStyle: {
color: '#aaa',
type: 'dashed'
}
},
itemStyle: {
borderWidth: 0.5
},
yearLabel: { show: false },
monthLabel: {
nameMap: 'cn',
fontSize: 12
},
dayLabel: {
show: true,
formatter: '{start} 1st',
fontWeight: 'lighter',
nameMap: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
fontSize: 12
}
},
series: [{
type: 'heatmap',
coordinateSystem: 'calendar',
calendarIndex: 0,
data: getDay()
}]
};
myChart.setOption(option);
setTimeout(function () {
window.onresize = function () {
chartView.resize();
myChart.resize();
}
})
console.log(e.data);
}
}
})
var archiveCalendar = {};
function getRange() {
let today = new Date();
let tYear = today.getFullYear();
let tMonth = today.getMonth() + 1;
let tDate = today.getDate();
let dateFirst = tYear + "-" + tMonth + "-" + tDate;
let datelast = (tYear - 1) + "-" + tMonth + "-" + tDate;
let dataRange = [];
dataRange.push(dateFirst);
dataRange.push(datelast);
return dataRange;
}
function getDay() {
var today = new Date();
var dayArray = [];
for (var i = 0; i < 366; i++) {
var targetday_milliseconds = today.getTime() - 1000 * 60 * 60 * 24 * i;
var date = new Date(targetday_milliseconds);
dayArray.push(retunDay(date));
}
return dayArray;
}
function retunDay(day) {
var tYear = day.getFullYear();
var tMonth = day.getMonth();
var tDate = day.getDate();
tMonth = tMonth + 1;
if (tMonth.toString().length == 1) {
tMonth = "0" + tMonth;
}
if (tDate.toString().length == 1) {
tDate = "0" + tDate;
}
var dateStr = tYear + "-" + tMonth + "-" + tDate;
var dateArray = [];
dateArray.push(dateStr);
if (archiveCalendar[dateStr]) {
dateArray.push(archiveCalendar[dateStr]);
}
else {
dateArray.push(0);
}
return dateArray;
}
}
</script>
{include file="common/layui" base='base' extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,81 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<form class="layui-form body-content">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray2">关键字名称<font>*</font>
</td>
<td>
<input type="hidden" name="id" value="{$id}" />
<input type="text" name="title" lay-verify="required" lay-reqText="请输入关键字名称" autocomplete="off" placeholder="请输入关键字名称"
class="layui-input" style="max-width: 360px;" {notempty name="$keywords.title"}
value="{$keywords.title}" {/notempty}>
</td>
<td class="layui-td-gray2">排序</td>
<td><input type="text" name="sort" placeholder="请输入排序,数字" autocomplete="off" class="layui-input"
style="max-width: 360px;" {notempty name="$keywords.sort" }value="{$keywords.sort}" {/notempty}>
</td>
</tr>
<tr>
<td class="layui-td-gray2">状态<font>*</font>
</td>
<td colspan="3">
{if condition="$id eq 0"}
<input type="radio" name="status" value="1" title="正常" checked>
<input type="radio" name="status" value="0" title="禁用">
{else/}
<input type="radio" name="status" value="1" title="正常" {eq name="$keywords.status" value="1"
}checked{/eq}>
<input type="radio" name="status" value="0" title="禁用" {eq name="$keywords.status" value="0"
}checked{/eq}>
{/if}
</td>
</tr>
</table>
<div style="padding: 10px 0">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<button lay-event="back" class="layui-btn layui-btn-primary">返回</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var form = layui.form
, layer = layui.layer;
//监听提交
form.on('submit(webform)', function (data) {
$.ajax({
url: "{:url('home/keywords/post_submit')}",
type: 'post',
data: data.field,
success: function (e) {
if (e.code == 0) {
layer.confirm('保存成功,返回列表页吗?', { icon: 3, title: '提示' }, function (index) {
history.back(-1);
layer.close(index);
});
} else {
layer.msg(e.msg);
}
}
})
return false;
});
//监听返回
$('.body-content').on('click', '[lay-event="back"]', function () {
history.back(-1);
return false;
});
}
</script>
{include file="common/layui" base="base" extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,118 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<div class="body-content">
<form class="layui-form">
<div class="layui-input-inline" style="width:300px;">
<input type="text" name="keywords" placeholder="关键字名称" class="layui-input" autocomplete="off" />
</div>
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">提交搜索</button>
</form>
<table class="layui-hide" id="test" lay-filter="test"></table>
</div>
<script type="text/html" id="status">
<i class="layui-icon {{# if(d.status == 1){ }}layui-icon-ok{{# } else { }}layui-icon-close{{# } }}"></i>
</script>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<a class="layui-btn layui-btn-normal layui-btn-sm" href="{:url('home/keywords/add')}">+ 添加关键字</a>
</div>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui) {
var table = layui.table,
form = layui.form;
var tableIns = table.render({
elem: '#test',
title: '关键字列表',
toolbar: '#toolbarDemo',
url: "{:url('home/keywords/index')}",
page: true, //开启分页
limit: 20,
cols: [
[{
field: 'id',
width: 80,
title: 'ID编号',
align: 'center'
}, {
field: 'sort',
width: 80,
title: '排序',
align: 'center',
edit: "text"
}, {
field: 'title',
title: '关键字名称',
edit: "text"
}, {
field: 'status',
width: 80,
title: '状态',
templet: '#status',
align: 'center'
}, {
width: 100,
title: '操作',
align: 'center',
templet: function (d) {
var html = '<div class="layui-btn-group"><a class="layui-btn layui-btn-xs" href="/home/keywords/add?id=' + d.id + '">编辑</a><a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a></div>';
return html;
}
}]
]
});
//监听搜索提交
form.on('submit(webform)', function (data) {
if (data.field.keywords) {
tableIns.reload({
where: {
keywords: data.field.keywords
},
page: {
curr: 1
}
});
} else {
location.reload();
}
return false;
});
//删除
table.on('tool(test)', function (obj) {
if (obj.event === 'del') {
layer.confirm('确定要删除吗?', {
icon: 3,
title: '提示'
}, function (index) {
$.ajax({
url: "{:url('home/keywords/delete')}",
type: 'post',
data: {
id: obj.data.id
},
success: function (e) {
layer.msg(e.msg);
if (e.code == 0) {
obj.del();
}
}
})
layer.close(index);
});
}
});
}
</script>
{include file="common/layui" base="base" extend="[]" callback="init" /}
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>404错误</title>
<style>
.box-404{padding: 50px 0; text-align: center;}
.error-404{width:480px; margin: 0 auto; line-height: 2;}
.title-404{font-size: 24px; color: #EA4335;}
.text-404{font-size: 16px; color:#333;}
.btn-404{padding-top: 20px;}
.btn-404 a{padding: 3px 20px; font-size: 14px; display: inline-block; background-color: #EA4335; color: #fff; margin-right: 30px; border-radius: 4px; text-decoration: none;}
.btn-404 a:hover{opacity: .9;}
</style>
</head>
<body>
<div class="box-404">
<div><img src="/static/home/images/404.gif" width="500" height="300" alt="404"></div>
</div>
<div class="error-404">
<div class="title-404">出错啦!</div>
<div class="text-404">对不起,您要访问的页面不见了...</div>
<div class="btn-404"><a href="javascript:history.go(-1);">返回上一页</a><a href="/index">返回首页</a></div>
</div>
</body>
</html>

View File

@ -0,0 +1,107 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="renderer" content="webkit" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{:get_system_config('web','admin_title')}</title>
<link rel="stylesheet" href="{__LAYUI__}/css/layui.css?v={:get_system_config('web','version')}" media="all">
<style type="text/css">
html,body {width: 100%;height: 100%;background: #34a853;}
input:-webkit-autofill {
-webkit-box-shadow: 0 0 0px 1000px white inset;
}
#container {width: 100%;height: 100%;position: fixed;top: 0;left: 0;z-index: 999;color: #ffffff;
background: url({__IMG__}/bg.jpg);
background-size: cover;
background: url("{__IMG__}/bg_pattern.png"), -webkit-linear-gradient(to left, #34a853, #4285f4);
/* Chrome 10-25, Safari 5.1-6 */
background: url("{__IMG__}/bg_pattern.png"), linear-gradient(to left, #34a853, #4285f4);
/* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
}
.container h2 {font-size: 36px;padding: 36px 0;font-weight: 500;}
.login {width: 400px;text-align: center;position: absolute;top: 50%;left: 50%;margin-top: -240px;margin-left: -200px;border-radius: 12px;box-shadow: 0 2px 6px rgba(26, 26, 26, .36);
}
.login .top {width: 400px;height: 117px;background-color: #fbbc05;border-radius: 12px 12px 0 0;line-height: 117px;text-align: center;overflow: hidden;
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
.login .top .bg1 {display: inline-block;width: 72px;height: 72px;background: #fff;opacity: .1;border-radius: 0 72px 0 0;position: absolute;left: 0;top: 42px;}
.login .top .bg2 {display: inline-block;width: 92px;height: 92px;background: #fff;opacity: .1;border-radius: 50%;position: absolute;right: -16px;top: -16px;}
.login .bottom {background-color: #fff;padding: 30px 25px;border-radius: 0 0 12px 12px;}
.layui-input,.layui-textarea {height: 44px;border: 1px solid #ddd;}
.captcha_img img{width:142px; height:44px; cursor:pointer;}
.layui-btn {height: 48px;font-size: 16px;margin-top: 5px;background-color: #FF6347!important}
.foot {position: absolute; font-size: 12px; bottom: 28px;text-align: center;width: 100%;color: #d3e8fa;}
</style>
</head>
<body>
<div id="container">
<div class="login">
<div class="top">
<img src="{__IMG__}/login_logo.png" height="60" width="200">
<span class="bg1"></span>
<span class="bg2"></span>
</div>
<div class="bottom">
<form class="layui-form" id="gougu-login">
<div class="layui-form-item">
<input type="text" name="username" lay-verify="required" value="" placeholder="请输入账户" lay-reqText="请输入账户" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-item">
<input type="password" name="password" lay-verify="required" value="" placeholder="请输入密码" lay-reqText="请输入密码" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-item">
<div class="layui-input-inline" style="width:188px;">
<input type="text" name="captcha" lay-verify="required" placeholder="验证码" lay-reqText="请输入验证码" autocomplete="off" class="layui-input">
</div>
<div class="layui-input-inline captcha_img" style="width:142px; height:44px; margin-right:0">
{:captcha_img()}
<input type="hidden" value="{:make_token()}"/>
</div>
</div>
<button id="login-submit" class="layui-btn layui-btn-fluid layui-bg-cyan" lay-submit lay-filter="login-submit">登入系统</button>
</form>
</div>
</div>
<div class="foot">
{:get_system_config('web','copyright')} <a id="beian" href="//www.beian.miit.gov.cn" target="_blank"
rel="nofollow" style="margin-left: 15px;color:#d3e8fa;">{:get_system_config('web','icp')}</a>Powered by GouguCMS
</div>
</div>
<script src="{__LAYUI__}/layui.js?v={:get_system_config('web','version')}"></script>
<script type="text/javascript">
layui.use(['form'], function() {
var form = layui.form,
layer = layui.layer,
$ = layui.$;
form.on('submit(login-submit)', function(data) {
$.ajax({
url: "{:url('/home/login/login_submit')}",
data: $('#gougu-login').serialize(),
type: 'post',
async: false,
success: function(res) {
layer.tips(res.msg, '#login-submit');
if (res.code === 0) {
setTimeout(function() {
// parent.document.location.reload();
parent.document.location.href="/";
}, 1500);
} else {
$('[alt="captcha"]').click();
}
}
})
return false;
});
});
</script>
</body>
</html>

459
app/home/view/mail/add.html Normal file
View File

@ -0,0 +1,459 @@
{extend name="common/base"/}
{block name="style"}
<link rel="stylesheet" href="{__JS__}/module/dtree/dtree.css">
<link rel="stylesheet" href="{__JS__}/module/dtree/font/dtreefont.css">
{/block}
<!-- 主体 -->
{block name="body"}
<form class="layui-form body-content">
<h3 style="padding:5px 0;">发送消息</h3>
{if condition="$id eq 0"}
<table class="layui-table">
<tr>
<td class="layui-td-gray2">接收人类型</td>
<td>
<input type="radio" name="type" lay-filter="type" value="0" title="同事" checked>
<input type="radio" name="type" lay-filter="type" value="1" title="部门">
<input type="radio" name="type" lay-filter="type" value="2" title="岗位">
<input type="radio" name="type" lay-filter="type" value="3" title="全部">
</td>
</tr>
<tr id ="person">
<td class="layui-td-gray2">收件人<span style="color: red">*</span></td>
<td>
<input type="text" name="person_name" value="" lay-verify="required" lay-reqText="请选择收件人" placeholder="请选择收件人" readonly class="layui-input">
<input type="hidden" name="uids" value="">
<input type="hidden" name="dids" value="">
<input type="hidden" name="pids" value="">
</td>
</tr>
<tr>
<td class="layui-td-gray2">主题<span style="color: red">*</span></td>
<td>
<input type="text" name="name" value="" lay-verify="required" lay-reqText="请输入消息主题" placeholder="请输入消息主题" class="layui-input" lay-verify="required">
</td>
</tr>
<tr><td class="layui-td-gray2">发送内容<span style="color: red">*</span></td>
<td>
<textarea name="content" placeholder="请输入消息内容" class="layui-textarea" style="height: 200px;" lay-verify="required" lay-reqText="请输入消息内容"></textarea>
</td>
</tr>
<tr>
<td class="layui-td-gray2" style="vertical-align:top">消息附件</td>
<td>
<table class="layui-hide" id="schedule-document" lay-filter="schedule-document"></table>
<div class="layui-upload" style="max-width: 1000px;">
<button type="button" class="layui-btn layui-btn-normal layui-btn-sm" id="testList">选择文件(可多选)</button> <span style="color:#FF5722;margin-left: 10px;">最大只能上传300MB的文件超过300MB请压缩成多个文件上传。</span>
<div class="layui-upload-list" style="display:none;">
<table class="layui-table">
<thead>
<tr>
<th width="55%">文件名</th>
<th width="15%" style="text-align:center">文件大小</th>
<th width="20%" style="text-align:center">状态</th>
<th width="10%" style="text-align:center">操作</th>
</tr></thead>
<tbody id="demoList"></tbody>
</table>
<div style="margin-top:10px;">
<input type="hidden" class="layui-input" id="uploadId" name="file_ids" >
<button type="button" class="layui-btn layui-btn-sm" id="testListAction">开始上传</button>
</div>
</div>
</div>
</td>
</tr>
</table>
{else/}
<table class="layui-table">
<tr>
<td class="layui-td-gray2">接收人类型</td>
<td>
<input type="radio" name="type" lay-filter="type" value="0" title="同事" {eq name="$detail.type" value="0"}checked{/eq}>
<input type="radio" name="type" lay-filter="type" value="1" title="部门" {eq name="$detail.type" value="1"}checked{/eq}>
<input type="radio" name="type" lay-filter="type" value="2" title="岗位" {eq name="$detail.type" value="2"}checked{/eq}>
<input type="radio" name="type" lay-filter="type" value="3" title="全部" {eq name="$detail.type" value="3"}checked{/eq}>
</td>
</tr>
<tr id ="person" {eq name="$detail.type" value="3"}style="display:none;"{/eq}>
<td class="layui-td-gray2">收件人<span style="color: red">*</span></td>
<td>
{eq name="$detail.type" value="3"}
<input type="text" name="person_name" value="0" lay-verify="required" lay-reqText="请选择收件人" placeholder="请选择收件人" readonly class="layui-input">
{else/}
<input type="text" name="person_name" value="{$detail.person_name}" lay-verify="required" lay-reqText="请选择收件人" placeholder="请选择收件人" readonly class="layui-input">
{/eq}
<input type="hidden" name="uids" value="{$detail.type_user}">
<input type="hidden" name="dids" value="{$detail.type_user}">
<input type="hidden" name="pids" value="{$detail.type_user}">
</td>
</tr>
<tr>
<td class="layui-td-gray2">主题<span style="color: red">*</span></td>
<td>
<input type="text" name="name" value="{$detail.name}" lay-verify="required" lay-reqText="请输入消息主题" placeholder="请输入消息主题" class="layui-input" lay-verify="required">
</td>
</tr>
<tr><td class="layui-td-gray2">发送内容<span style="color: red">*</span></td>
<td>
<textarea name="content" placeholder="请输入消息内容" class="layui-textarea" style="height: 200px;" lay-verify="required" lay-reqText="请输入消息内容">{$detail.content}</textarea>
{if condition="($detail.fid > 0)"}
<table class="layui-table">
<tr>
<td class="layui-td-gray2">引用消息内容</td>
<td>{$detail.from_content}</td>
</tr>
{notempty name="$detail.from_file_array"}
<tr>
<td class="layui-td-gray2" style="vertical-align:top">引用消息附件</td>
<td>
<table class="layui-table" style="max-width: 680px;">
<thead>
<th width="70%">文件名</th>
<th width="20%" style="text-align:center">文件大小</th>
<th width="10%" style="text-align:center">操作</th>
</thead>
<tbody>
{volist name="$detail.from_file_array" id="vo"}
<tr>
<td>{$vo.name}</td>
<td style="text-align: center;">{$vo.filesize/1048576|round=2}MB</td>
<td style="text-align: center;"><a class="layui-btn layui-btn-xs layui-btn-normal" href="{$vo.filepath}" target="_blank">下载</a></td>
</tr>
{/volist}
</tbody>
</table>
</td>
</tr>
{/notempty}
</table>
{/if}
</td>
</tr>
<tr>
<td class="layui-td-gray2" style="vertical-align:top">消息附件</td>
<td>
<table class="layui-hide" id="schedule-document" lay-filter="schedule-document"></table>
<div class="layui-upload" style="max-width: 800px;">
<button type="button" class="layui-btn layui-btn-normal layui-btn-sm" id="testList">选择文件(可多选)</button> <span style="color:#FF5722;margin-left: 10px;">最大只能上传300MB的文件超过300MB请压缩成多个文件上传。</span>
<div class="layui-upload-list" {empty name="$file_array"}style="display:none;"{/empty}>
<table class="layui-table">
<thead>
<tr>
<th width="55%">文件名</th>
<th width="15%" style="text-align:center">文件大小</th>
<th width="20%" style="text-align:center">状态</th>
<th width="10%" style="text-align:center">操作</th>
</tr>
</thead>
<tbody id="demoList">
{notempty name="$file_array"}
{volist name="file_array" id="vo"}
<tr>
<td>{$vo.name}</td>
<td style="text-align: center;">{$vo.filesize/1048576|round=2}MB</td>
<td style="text-align: center;">已上传</td>
<td style="text-align: center;">
<a class="layui-btn layui-btn-xs layui-btn-danger demo-del">删除</a>
</td>
</tr>
{/volist}
{/notempty}
</tbody>
</table>
<div style="margin-top:10px;">
<input type="hidden" class="layui-input" id="uploadId" name="file_ids" value="{$detail.file_ids}">
<button type="button" class="layui-btn layui-btn-sm" id="testListAction">开始上传</button>
</div>
</div>
</div>
</td>
</tr>
</table>
{/if}
<div class="layui-form-item" style="padding-top:10px;">
<input type="hidden" value="{$id}" name="id">
<input type="hidden" value="{$fid}" name="fid">
<button class="layui-btn" lay-submit="" lay-filter="draftform">存为草稿</button>
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即发送</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
function init(layui){
var form = layui.form
,layer = layui.layer
,table = layui.table
,dtree = layui.dtree
,upload = layui.upload
,employeepicker = layui.employeepicker;
//监听保存到草稿并发送
form.on('submit(webform)', function(data){
$.ajax({
url:"{:url('home/mail/save')}",
type:'post',
data:data.field,
success:function(e){
if(e.code==0){
layer.msg('消息保存成功,正在发送中...');
$.ajax({
url:"{:url('home/mail/send')}",
type:'post',
data:{'id':e.data},
success:function(e){
if(e.code==0){
layer.confirm('发送成功,返回列表页吗?', {icon: 3, title:'提示'}, function(index){
parent.location.reload();
})
}else{
layer.msg(e.msg);
}
}
})
}else{
layer.msg(e.msg);
}
}
})
return false;
});
//监听保存到草稿
form.on('submit(draftform)', function(data){
$.ajax({
url:"{:url('home/mail/save')}",
type:'post',
data:data.field,
success:function(e){
if(e.code==0){
layer.confirm('保存草稿成功,返回列表页吗?', {icon: 3, title:'提示'}, function(index){
parent.location.reload();
});
}else{
layer.msg(e.msg);
}
}
})
return false;
});
var uploadId =[];
//多文件列表示例
var demoListView = $('#demoList')
,uploadListIns = upload.render({
elem: '#testList'
,url: "{:url('home/api/upload')}"
,accept: 'file'
,multiple: true
,auto: false
,bindAction: '#testListAction'
,data: {use:'file', action: 'project'}
,choose: function(obj){
var files = this.files = obj.pushFile(); //将每次选择的文件追加到文件队列
//读取本地文件
obj.preview(function(index, file, result){
var tr = $(['<tr id="upload-'+ index +'">'
,'<td>'+ file.name +'</td>'
,'<td align="center">'+ (file.size/(1024*1024)).toFixed(2) +'MB</td>'
,'<td align="center">等待上传</td>'
,'<td align="center">'
,'<span class="layui-btn layui-btn-xs demo-reload layui-hide" data-index="'+index+'">重传</span>'
,'<span class="layui-btn layui-btn-xs layui-btn-danger demo-delete">删除</span>'
,'</td>'
,'</tr>'].join(''));
//单个重传
tr.find('.demo-reload').on('click', function(){
var idx=$(this).data('index');
obj.upload(idx, file);
});
//删除
tr.find('.demo-delete').on('click', function(){
delete files[index]; //删除对应的文件
tr.remove();
uploadListIns.config.elem.next()[0].value = ''; //清空 input file 值,以免删除后出现同名文件不可选
});
$('.layui-upload-list').show();
demoListView.append(tr);
//上传成功后单个删除
tr.on('click','.demo-del', function(){
var index=$(this).parents('tr').index();
console.log(index);
uploadId.splice(index, 1);
$('#uploadId').val(uploadId.join(','));
tr.remove();
if(uploadId.length==0){
$('.layui-upload-list').hide();
}
});
});
}
,done: function(res, index, upload){
if(res.code == 0){ //上传成功
var tr = demoListView.find('tr#upload-'+ index)
,tds = tr.children();
tds.eq(2).html('<span style="color: #5FB878;">上传成功</span>');
uploadId.push(res.data.id);
tds.eq(3).html('<a class="layui-btn layui-btn-xs layui-btn-danger demo-del" data-index="'+(uploadId.length-1)+'">删除</a>');
$('#uploadId').val(uploadId.join(','));
return delete this.files[index]; //删除文件队列已经上传成功的文件
}
this.error(index, upload);
},
progress:function(percent,file,button,index){
var tr = demoListView.find('tr#upload-'+ index),tds = tr.children();
tds.eq(2).html('<span style="color: #5FB878;">上传中...</span>');
console.log(arguments);
}
,error: function(index, upload){
var tr = demoListView.find('tr#upload-'+ index),tds = tr.children();
tds.eq(2).html('<span style="color: #FF5722;">上传失败,请检查网络,或者文件是否过大?</span>');
tds.eq(3).find('.demo-reload').removeClass('layui-hide'); //显示重传
}
});
//选择收件人类型
form.on('radio(type)', function (data) {
$('[name="person_name"]').val('');
$('[name="dids"]').val('');
$('[name="uids"]').val('');
$('[name="auids"]').val('');
if(data.value==3){
$('#person').val('0').hide();
}
else{
$('#person').val('').show();
}
});
//选择对应人
$('[name="person_name"]').on('click',function(){
type = $("input[name='type']:checked").val();
if(type == 0){
addEmployee();
}else if(type == 1){
selectDepartment();
}else if(type == 2){
selectAuditor();
}
});
//添加人员
function addEmployee(){
var ids=$('[name="uids"]').val(),names=$('[name="person_name"]').val(),idsArray=[],namesArray=[];
if(ids!=''){
idsArray=ids.split(',');
namesArray=names.split(',');
}
employeepicker.init({
department_url:"{:url('/home/api/get_department_tree')}",
employee_url:"{:url('/home/api/get_employee')}",
ids:idsArray,
names:namesArray,
callback:function(ids,names){
$('[name="uids"]').val(ids.join(',')),
$('[name="person_name"]').val(names.join(','));
}
});
}
//选择部门
function selectDepartment(){
var tpl='<div style="width:382px; height:338px;overflow-y: auto;">\
<div id="checkemployeetree" style="padding:10px 0;"></div>\
</div>';
layer.open({
type:1,
title:'选择部门',
area:['400px','450px'],
content:tpl,
success:function(){
$.ajax({
url:"{:url('/home/api/get_department_tree')}",
type:'post',
success:function(res){
dtree.render({
elem: "#checkemployeetree",
data: res.trees,
icon: "2", //修改二级图标样式
checkbarType: "no-all", // 默认就是all其他的值为 no-all p-casc self only
checkbar: true //开启复选框
});
}
});
},
btn: ['确定'],
btnAlign:'c',
yes: function(){
var ids=[],names=[];
var check=dtree.getCheckbarNodesParam("checkemployeetree");
if(check.length==0){
layer.msg('请选择部门');
return;
}
for(var m=0; m<check.length; m++){
ids.push(check[m].nodeId);
names.push(check[m].context);
}
$('[name="person_name"]').val(names.join(','));
$('[name="dids"]').val(ids.join(','));
layer.closeAll();
}
})
}
//选择角色
function selectAuditor(){
layer.open({
title:'选择岗位',
type:1,
area:['360px','480px'],
content:'<div style="padding:5px 12px"><div id="vaeservice"></div></div>',
success:function(){
tableid=table.render({
elem: '#vaeservice'
,url:"{:url('/home/api/get_position')}"
,page: false //开启分页
,cols: [[
{type:'checkbox',title: '选择'}
,{field:'id', width:80, title: '编号', align:'center'}
,{field:'name',title: '岗位名称'}
]]
});
},
btn: ['确定'],
btnAlign:'c',
yes: function(){
var checkStatus = table.checkStatus(tableid.config.id);
var data = checkStatus.data,val = [],title=[];
if(data.length>0){
for ( var i = 0; i <data.length; i++){
val.push(data[i].id);
title.push(data[i].name);
}
$('[name="person_name"]').val(title.join(','));
$('[name="pids"]').val(val.join(','));
layer.closeAll();
}else{
layer.msg('请选择角色');
return;
}
}
})
}
}
</script>
{include file="common/layui" base='base' extend="['dtree','employeepicker']" callback="init" /}
{/block}
<!-- /脚本 -->

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