初始化代码

This commit is contained in:
lisong 2021-11-24 13:18:45 +08:00
commit 8bdeb2b252
3582 changed files with 615407 additions and 0 deletions

3
.gitignore vendored Executable file
View File

@ -0,0 +1,3 @@
.idea
.env
*.DS_Store

7
.htaccess Executable file
View File

@ -0,0 +1,7 @@
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?s=/$1 [QSA,PT,L]
</IfModule>

42
.travis.yml Executable file
View File

@ -0,0 +1,42 @@
sudo: false
language: php
branches:
only:
- stable
cache:
directories:
- $HOME/.composer/cache
before_install:
- composer self-update
install:
- composer install --no-dev --no-interaction --ignore-platform-reqs
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip .
- composer require --update-no-dev --no-interaction "topthink/think-image:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0"
- composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0"
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip .
script:
- php think unit
deploy:
provider: releases
api_key:
secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw=
file:
- ThinkPHP_Core.zip
- ThinkPHP_Full.zip
skip_cleanup: true
on:
tags: true

7
333.htaccess Executable file
View File

@ -0,0 +1,7 @@
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:$1]
</IfModule>

26
404.html Executable file
View File

@ -0,0 +1,26 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>404</title>
<style>
body{
background-color:#444;
font-size:14px;
}
h3{
font-size:60px;
color:#eee;
text-align:center;
padding-top:30px;
font-weight:normal;
}
</style>
</head>
<body>
<h3>404您请求的文件不存在!</h3>
</body>
</html>

32
LICENSE.txt Executable file
View File

@ -0,0 +1,32 @@
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.

45
README.md Executable file
View File

@ -0,0 +1,45 @@
## 功能一览
### 登录模块
- token验证
- 图形验证码
- 极验滑动验证
### 轮播模块
- 轮播管理
### 用户模块
- 用户管理
- 用户等级管理
### 新闻模块
- 文章管理
- 文章分类管理
- 标签管理
### 商城模块
- 品牌管理
- 商品管理
- 商品分类管理
- 订单管理
- 快递管理
- 收货地址管理
### 杂项演示
- 邮件发送
- 短信发送
- 二维码生成
### 微信模块
- 服务端验证
- 接收 & 回复用户消息
- 获取用户信息
- 发送模版消息
- 统一下单
- 更多...
### 人事管理
- 员工管理
- 部门管理
- 职位管理
### 系统管理
- 用户管理
- 角色管理
- 菜单管理
- 操作日志
- 个人资料
- 代码生成
3333333444

53
application/admin/common.php Executable file
View File

@ -0,0 +1,53 @@
<?php
const URL_CURRENT = 'url://current';
const URL_RELOAD = 'url://reload';
const URL_BACK = 'url://back';
use think\exception\HttpResponseException;
use think\Response;
use think\response\Redirect;
if (!function_exists('success')) {
function success($msg = '操作成功', $url = URL_BACK, $data = '', $wait = 0, array $header = [])
{
result(1, $msg, $data, $url, $wait, $header);
}
}
if (!function_exists('error')) {
function error($msg = '操作失败', $url = URL_CURRENT, $data = '', $wait = 0, array $header = [])
{
result(0, $msg, $data, $url, $wait, $header);
}
}
if (!function_exists('result')) {
function result($code = 0, $msg = 'unknown', $data = '', $url = null, $wait = 3, array $header = [])
{
if (request()->isPost()) {
$url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : url($url);
$result = [
'code' => $code,
'msg' => $msg,
'data' => $data,
'url' => $url,
'wait' => $wait,
];
$response = Response::create($result, 'json')->header($header);
throw new HttpResponseException($response);
}
if ($url === null) {
$url = request()->server('HTTP_REFERER') ?? 'admin/index/index';
}
$response = new Redirect($url);
$response->code(302)->params($data)->with([$code ? 'success_message' : 'error_message' => $msg, 'url' => $url]);
throw new HttpResponseException($response);
}
}

View File

@ -0,0 +1,53 @@
<?php
/**
* 后台操作日志控制器
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\controller;
use app\admin\model\AdminLog;
use app\admin\model\AdminUser;
use think\Request;
class AdminLogController extends Controller
{
public function index(Request $request, AdminLog $model)
{
$param = $request->param();
$data = $model->where(function ($query) use ($param) {
if (isset($param['create_time_range']) && !empty($param['create_time_range'])) {
$range = explode(' - ', $param['create_time_range']);
$query->whereTime('create_time', 'between', $range);
}
})
->scope('where', $param)
->paginate($this->admin['per_page'], false, ['query' => $request->get()]);
//关键词,排序等赋值
$this->assign($request->get());
$this->assign([
'data' => $data,
'page' => $data->render(),
'total' => $data->total(),
'admin_user_list' => AdminUser::all(),
]);
return $this->fetch();
}
//日志详情
public function view($id, AdminLog $model)
{
$data = $model::get($id);
$this->assign([
'data' => $data
]);
return $this->fetch();
}
}

View File

@ -0,0 +1,171 @@
<?php
/**
* 后台菜单控制器
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\controller;
use think\Request;
use app\admin\model\AdminMenu;
use app\admin\validate\AdminMenuValidate;
class AdminMenuController extends Controller
{
public function index(AdminMenu $model)
{
//查询所有菜单并以树的形式显示
$result = $model->order('sort_id asc, id asc')->column('*', 'id');
foreach ($result as $n => $r) {
$result[$n]['level'] = $this->getLevel($r['id'], $result);
$result[$n]['parent_id_node'] = $r['parent_id'] ? ' class="child-of-node-' . $r['parent_id'] . '"' : '';
$result[$n]['str_manage'] = '<a href="' . url('edit', ['id' => $r['id']]) . '" class="btn btn-primary btn-xs" title="修改" data-toggle="tooltip"><i class="fa fa-pencil"></i></a> ';
$result[$n]['str_manage'] .= '<a class="btn btn-danger btn-xs AjaxButton" data-id="' . $r['id'] . '" data-url="del.html" data-confirm-title="删除确认" data-confirm-content=\'您确定要删除ID为 <span class="text-red"> ' . $r['id'] . ' </span> 的数据吗\' data-toggle="tooltip" title="删除"><i class="fa fa-trash"></i></a>';
$result[$n]['is_show'] = (int)$r['is_show'] === 1 ? '显示' : '隐藏';
$result[$n]['log_method'] = $r['log_method'];
}
$str = "<tr id='node-\$id' data-level='\$level' \$parent_id_node><td><input type='checkbox' onclick='checkThis(this)'
name='data-checkbox' data-id='\$id\' class='checkbox data-list-check' value='\$id' placeholder='选择/取消'>
</td><td>\$id</td><td>\$spacer\$name</td><td>\$url</td>
<td>\$parent_id</td><td><i class='fa \$icon'></i><span>(\$icon)</span></td>
<td>\$sort_id</td><td>\$is_show</td><td>\$log_method</td><td class='td-do'>\$str_manage</td></tr>";
$this->initTree($result);
$data = $this->getTree(0, $str);
$this->assign('data', $data);
return $this->fetch('index');
}
public function add(Request $request, AdminMenu $model, AdminMenuValidate $validate)
{
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('add')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $model::create($param);
//如果
if (isset($param['is_more']) && $param['is_more'] == 1) {
$name = $param['more_name'];
$url = explode('/', $param['url']);
$str = '/';
$data = [
[
'parent_id' => $result->id,
'name' => '添加' . $name,
'url' => $url[0] . $str . $url[1] . $str . 'add',
'icon' => 'fa-plus',
'is_show' => 0,
'log_method' => 'POST',
],
[
'parent_id' => $result->id,
'name' => '修改' . $name,
'url' => $url[0] . $str . $url[1] . $str . 'edit',
'icon' => 'fa-pencil',
'is_show' => 0,
'log_method' => 'POST',
],
[
'parent_id' => $result->id,
'name' => '删除' . $name,
'url' => $url[0] . $str . $url[1] . $str . 'del',
'icon' => 'fa-trash',
'is_show' => 0,
'log_method' => 'POST',
]
];
$model->saveAll($data);
}
unset($url);
$url = URL_BACK;
if (isset($param['_create']) && $param['_create'] == 1) {
$url = URL_RELOAD;
}
return $result ? success('添加成功', $url) : error();
}
$parent_id = $request->param('parent_id') ?? 0;
$parents = $this->menu($parent_id);
$this->assign([
'parents' => $parents,
'log_method' => $model->logMethod
]);
return $this->fetch();
}
public function edit($id, Request $request, AdminMenu $model, AdminMenuValidate $validate)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('edit')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $data->save($param);
return $result ? success() : error();
}
$parent_id = $data->parent_id;
$parents = $this->menu($parent_id);
$this->assign([
'data' => $data,
'parents' => $parents,
'log_method' => $model->logMethod,
]);
return $this->fetch('add');
}
public function del($id, Request $request, AdminMenu $model)
{
//判断是否有子菜单
$have_son = $model->whereIn('parent_id', $id)->find();
if ($have_son) {
return error('有子菜单不可删除!');
}
if (count($model->noDeletionId) > 0) {
if (is_array($id)) {
if (array_intersect($model->noDeletionId, $id)) {
return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
}
} else if (in_array($id, $model->noDeletionId)) {
return error('ID为' . $id . '的数据无法删除');
}
}
if ($model->softDelete) {
$result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
} else {
$result = $model->whereIn('id', $id)->delete();
}
return $result ? success('操作成功', URL_RELOAD) : error();
}
//菜单选择 select树形选择
protected function menu($selected = 1, $current_id = 0)
{
$result = AdminMenu::where('id', '<>', $current_id)->order('sort_id', 'asc')->order('id', 'asc')->column('id,parent_id,name,sort_id', 'id');
foreach ($result as $r) {
$r['selected'] = (int)$r['id'] === (int)$selected ? 'selected' : '';
}
$str = "<option value='\$id' \$selected >\$spacer \$name</option>";
$this->initTree($result);
return $this->getTree(0, $str, $selected);
}
}

View File

@ -0,0 +1,190 @@
<?php
/**
* 后台角色控制器
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\controller;
use app\admin\model\AdminMenu;
use app\admin\model\AdminRole;
use app\admin\validate\AdminRoleValidate;
use think\Request;
class AdminRoleController extends Controller
{
public function index(Request $request, AdminRole $model)
{
$param = $request->param();
$data = $model->scope('where', $param)
->paginate($this->admin['per_page'], false, ['query' => $request->get()]);
//关键词,排序等赋值
$this->assign($request->get());
$this->assign([
'data' => $data,
'page' => $data->render(),
'total' => $data->total(),
]);
return $this->fetch();
}
//添加
public function add(Request $request, AdminRole $model, AdminRoleValidate $validate)
{
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('add')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $model::create($param);
$url = URL_BACK;
if (isset($param['_create']) && $param['_create'] == 1) {
$url = URL_RELOAD;
}
return $result ? success('添加成功', $url) : error();
}
return $this->fetch();
}
//修改
public function edit($id, Request $request, AdminRole $model, AdminRoleValidate $validate)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('edit')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $data->save($param);
return $result ? success() : error();
}
$this->assign([
'data' => $data
]);
return $this->fetch('add');
}
//删除
public function del($id, AdminRole $model)
{
if (count($model->noDeletionId) > 0) {
if (is_array($id)) {
if (array_intersect($model->noDeletionId, $id)) {
return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
}
} else if (in_array($id, $model->noDeletionId)) {
return error('ID为' . $id . '的数据无法删除');
}
}
if ($model->softDelete) {
$result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
} else {
$result = $model->whereIn('id', $id)->delete();
}
return $result ? success('操作成功', URL_RELOAD) : error();
}
//角色授权
public function access($id, Request $request, AdminRole $model)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
if (!isset($param['url'])) {
return error('请至少选择一项权限');
}
if (!in_array(1, $param['url'])) {
return error('首页权限必选');
}
if (false !== $data->save($param)) {
return success();
}
return error();
}
$menu = AdminMenu::order('sort_id', 'asc')->order('id', 'asc')->column('*', 'id');
$html = $this->authorizeHtml($menu, $data->url);
$this->assign([
'data' => $data,
'html' => $html,
]);
return $this->fetch();
}
//启用
public function enable($id, AdminRole $model)
{
$result = $model->whereIn('id', $id)->update(['status' => 1]);
return $result ? success('操作成功', URL_RELOAD) : error();
}
//禁用
public function disable($id, AdminRole $model)
{
$result = $model->whereIn('id', $id)->update(['status' => 0]);
return $result ? success('操作成功', URL_RELOAD) : error();
}
//生成授权html
protected function authorizeHtml($menu, $auth_menus = [])
{
foreach ($menu as $n => $t) {
$menu[$n]['checked'] = in_array($t['id'], $auth_menus) ? ' checked' : '';
$menu[$n]['level'] = $this->getLevel($t['id'], $menu);
$menu[$n]['width'] = 100 - $menu[$n]['level'];
}
$this->initTree($menu);
$this->text = [
'other' => "<label class='checkbox' >
<input \$checked name='url[]' value='\$id' level='\$level'
onclick='javascript:checkNode(this);' type='checkbox'>
\$name
</label>",
'0' => [
'0' => "<dl class='checkmod'>
<dt class='hd'>
<label class='checkbox'>
<input \$checked name='url[]' value='\$id' level='\$level'
onclick='javascript:checkNode(this);'
type='checkbox'>
\$name
</label>
</dt>
<dd class='bd'>",
'1' => '</dd></dl>',
],
'1' => [
'0' => "
<div class='menu_parent'>
<label class='checkbox'>
<input \$checked name='url[]' value='\$id' level='\$level'
onclick='javascript:checkNode(this);' type='checkbox'>
\$name
</label>
</div>
<div class='rule_check' style='width: \$width%;'>",
'1' => "</div><span class='child_row'></span>",
]
];
return $this->getAuthTreeAccess(0);
}
}

View File

@ -0,0 +1,170 @@
<?php
/**
* 后台用户控制器
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\controller;
use app\common\model\Attachment;
use think\Request;
use app\admin\model\AdminRole;
use app\admin\model\AdminUser;
use app\admin\validate\AdminUserValidate;
class AdminUserController extends Controller
{
//列表
public function index(Request $request, AdminUser $model)
{
$param = $request->param();
$data = $model->scope('where', $param)
->paginate($this->admin['per_page'], false, ['query' => $request->get()]);
//关键词,排序等赋值
$this->assign($request->get());
$this->assign([
'data' => $data,
'page' => $data->render(),
'total' => $data->total(),
]);
return $this->fetch();
}
//添加
public function add(Request $request, AdminUser $model, AdminUserValidate $validate)
{
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('add')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $model::create($param);
$url = URL_BACK;
if (isset($param['_create']) && $param['_create'] == 1) {
$url = URL_RELOAD;
}
return $result ? success('添加成功', $url) : error();
}
$role = AdminRole::all(function ($query) {
$query->column('id,name', 'id');
});
$this->assign([
'role' => $role
]);
return $this->fetch();
}
//修改
public function edit($id, Request $request, AdminUser $model, AdminUserValidate $validate)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('edit')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $data->save($param);
return $result ? success() : error();
}
$role = AdminRole::all(function ($query) {
$query->column('id,name', 'id');
});
$this->assign([
'data' => $data,
'role' => $role
]);
return $this->fetch('add');
}
//删除
public function del($id, AdminUser $model)
{
if (count($model->noDeletionId) > 0) {
if (is_array($id)) {
if (array_intersect($model->noDeletionId, $id)) {
return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
}
} else if (in_array($id, $model->noDeletionId)) {
return error('ID为' . $id . '的数据无法删除');
}
}
if ($model->softDelete) {
$result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
} else {
$result = $model->whereIn('id', $id)->delete();
}
return $result ? success('操作成功', URL_RELOAD) : error();
}
//启用
public function enable($id, AdminUser $model)
{
$result = $model->whereIn('id', $id)->update(['status' => 1]);
return $result ? success('操作成功', URL_RELOAD) : error();
}
//禁用
public function disable($id, AdminUser $model)
{
$result = $model->whereIn('id', $id)->update(['status' => 0]);
return $result ? success('操作成功', URL_RELOAD) : error();
}
//个人资料
public function profile(Request $request, AdminUser $model, AdminUserValidate $validate)
{
if ($request->isPost()) {
$param = $request->param();
if ($param['update_type'] === 'password') {
$validate_result = $validate->scene('password')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
if (!password_verify($param['password'], $this->user->password)) {
return error('当前密码不正确');
}
$param['password'] = $param['new_password'];
} else if ($param['update_type'] === 'avatar') {
if (!$request->file('avatar')) {
return error('请上传新头像');
}
$attachment = new Attachment();
$file = $attachment->upload('avatar');
if ($file) {
$param['avatar'] = $file->url;
} else {
return error($attachment->getError());
}
}
if (false !== $this->user->save($param)) {
return success('修改成功', URL_RELOAD);
}
return error();
}
return $this->fetch();
}
}

View File

@ -0,0 +1,103 @@
<?php
/**
* 文章分类控制器
*/
namespace app\admin\controller;
use think\Request;
use app\common\model\ArticleCategory;
use app\common\validate\ArticleCategoryValidate;
class ArticleCategoryController extends Controller
{
//列表
public function index(Request $request, ArticleCategory $model)
{
$data = $this->getTreeList($model);
$this->assign([
'data' => $data,
]);
return $this->fetch();
}
//添加
public function add(Request $request, ArticleCategory $model, ArticleCategoryValidate $validate)
{
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('add')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $model::create($param);
$url = URL_BACK;
if (isset($param['_create']) && $param['_create'] == 1) {
$url = URL_RELOAD;
}
return $result ? success('添加成功', $url) : error();
}
$this->assign([
'cat_list' => $model::where('parent_id', 0)->select(),
]);
return $this->fetch();
}
//修改
public function edit($id, Request $request, ArticleCategory $model, ArticleCategoryValidate $validate)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('edit')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $data->save($param);
return $result ? success() : error();
}
$this->assign([
'data' => $data,
'cat_list' => $model::where('parent_id', 0)->select(),
]);
return $this->fetch('add');
}
//删除
public function del($id, ArticleCategory $model)
{
if (count($model->noDeletionId) > 0) {
if (is_array($id)) {
if (array_intersect($model->noDeletionId, $id)) {
return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
}
} else if (in_array($id, $model->noDeletionId)) {
return error('ID为' . $id . '的数据无法删除');
}
}
if ($model->softDelete) {
$result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
} else {
$result = $model->whereIn('id', $id)->delete();
}
return $result ? success('操作成功', URL_RELOAD) : error();
}
}

View File

@ -0,0 +1,141 @@
<?php
/**
* 文章管理333333控制器
*/
namespace app\admin\controller;
use think\Request;
use app\common\model\Article;
use app\common\validate\ArticleValidate;
class ArticleController extends Controller
{
//列表
public function index(Request $request, Article $model)
{
$param = $request->param();
$model = $model->scope('where', $param);
$data = $model->paginate($this->admin['per_page'], false, ['query'=>$request->get()]);
//关键词,排序等赋值
$this->assign($request->get());
$this->assign([
'data' => $data,
'page' => $data->render(),
'total' => $data->total(),
]);
return $this->fetch();
}
//添加
public function add(Request $request, Article $model, ArticleValidate $validate)
{
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('add')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$param['content'] = $request->param(false)['content'];
//处理缩略图上传
$attachment_img = new \app\common\model\Attachment;
$file_img = $attachment_img->upload('img');
if ($file_img) {
$param['img'] = $file_img->url;
} else {
return error($attachment_img->getError());
}
$result = $model::create($param);
$url = URL_BACK;
if(isset($param['_create']) && $param['_create']==1){
$url = URL_RELOAD;
}
return $result ? success('添加成功',$url) : error();
}
return $this->fetch();
}
//修改
public function edit($id, Request $request, Article $model, ArticleValidate $validate)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('edit')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$param['content'] = $request->param(false)['content'];
//处理缩略图上传
if (!empty($_FILES['img']['name'])) {
$attachment_img = new \app\common\model\Attachment;
$file_img = $attachment_img->upload('img');
if ($file_img) {
$param['img'] = $file_img->url;
}
}
$result = $data->save($param);
return $result ? success() : error();
}
$this->assign([
'data' => $data,
]);
return $this->fetch('add');
}
//删除
public function del($id, Article $model)
{
if (count($model->noDeletionId) > 0) {
if (is_array($id)) {
if (array_intersect($model->noDeletionId, $id)) {
return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
}
} else if (in_array($id, $model->noDeletionId)) {
return error('ID为' . $id . '的数据无法删除');
}
}
if ($model->softDelete) {
$result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
} else {
$result = $model->whereIn('id', $id)->delete();
}
return $result ? success('操作成功', URL_RELOAD) : error();
}
//启用
public function enable($id,Article $model)
{
$result = $model->whereIn('id',$id)->update(['status'=>1]);
return $result ? success('操作成功', URL_RELOAD) : error();
}
//禁用
public function disable($id,Article $model)
{
$result = $model->whereIn('id',$id)->update(['status'=>0]);
return $result ? success('操作成功', URL_RELOAD) : error();
}
}

View File

@ -0,0 +1,151 @@
<?php
/**
* 后台登录退出控制器
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\controller;
use Exception;
use think\captcha\Captcha;
use think\Request;
use app\admin\model\AdminUser;
use app\admin\validate\AdminUserValidate;
use tools\GeeTest;
class AuthController extends Controller
{
protected $authExcept = [
'admin/auth/login',
'admin/auth/logout',
'admin/auth/captcha',
'admin/auth/initgeetest',
];
//登录
public function login(Request $request, AdminUser $model, AdminUserValidate $validate)
{
if ($request->isPost()) {
$login_config = config('admin.login');
$param = $request->param();
//如果需要验证码
if ($login_config['captcha'] > 0) {
if ($login_config['captcha'] == 1) {
if (!captcha_check($param['captcha'])) {
return error('验证码错误');
}
} else if ($login_config['captcha'] == 2) {
$config = config('geetest.');
$geeTest = new GeeTest($config['id'], $config['key']);
$data = array(
'user_id' => session('gt_uid'),
'client_type' => 'web',
'ip_address' => $request->ip(),
);
if (session('gt_server') == 1) {
$gee_test_result = $geeTest->successValidate($param['geetest_challenge'], $param['geetest_validate'], $param['geetest_seccode'], $data);
if (!$gee_test_result) {
return error('验证失败');
}
} else {
if (!$geeTest->failValidate($param['geetest_challenge'], $param['geetest_validate'])) {
return error('验证失败');
}
}
}
}
$validate_result = $validate->scene('login')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
//如果需要验证登录token
if ($login_config['token']) {
$token_validate = \think\Validate::make();
$token_validate_result = $token_validate->rule('__token__', 'token')
->check($param);
if (!$token_validate_result) {
return error($token_validate->getError());
}
}
try {
$user = $model::login($param);
} catch (Exception $e) {
return error($e->getMessage());
}
$remember = isset($param['remember']) ? true : false;
self::authLogin($user, $remember);
$redirect = session('redirect') ?? url('admin/index/index');
return success('登录成功', $redirect);
}
$this->admin['title'] = '登录';
$this->assign([
//登录设置,参考/config/admin/admin.php文件配置
'login_config' => config('admin.login'),
]);
return $this->fetch();
}
//退出
public function logout()
{
self::authLogout();
return redirect(url('admin/auth/login'));
}
//极验初始化
public function initGeeTest(Request $request)
{
$config = config('geetest.');
$geeTest = new GeeTest($config['id'], $config['key']);
$ip = $request->ip();
$ug = $request->header('user-agent');
$data = array(
'gt_uid' => md5($ip . $ug),
'client_type' => 'web',
'ip_address' => $ip,
);
$status = $geeTest->preProcess($data);
session('gt_server', $status);
session('gt_uid', $data['gt_uid']);
return success($status, URL_CURRENT, $geeTest->getResponse());
}
//ThinkPHP 图形验证码
public function captcha()
{
$config = [
// 验证码字体大小
'fontSize' => 30,
// 验证码位数
'length' => 4,
// 关闭验证码杂点
'useNoise' => false,
];
$captcha = new Captcha($config);
return $captcha->entry();
}
}

View File

@ -0,0 +1,123 @@
<?php
/**
* 品牌控制器
*/
namespace app\admin\controller;
use think\Request;
use app\common\model\Brand;
use app\common\validate\BrandValidate;
class BrandController extends Controller
{
//列表
public function index(Request $request, Brand $model)
{
$param = $request->param();
$model = $model->scope('where', $param);
$data = $model->paginate($this->admin['per_page'], false, ['query' => $request->get()]);
//关键词,排序等赋值
$this->assign($request->get());
$this->assign([
'data' => $data,
'page' => $data->render(),
'total' => $data->total(),
]);
return $this->fetch();
}
//添加
public function add(Request $request, Brand $model, BrandValidate $validate)
{
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('add')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
//处理图片上传
$attachment_img = new \app\common\model\Attachment;
$file_img = $attachment_img->upload('img');
if ($file_img) {
$param['img'] = $file_img->url;
} else {
return error($attachment_img->getError());
}
$result = $model::create($param);
$url = URL_BACK;
if (isset($param['_create']) && $param['_create'] == 1) {
$url = URL_RELOAD;
}
return $result ? success('添加成功', $url) : error();
}
return $this->fetch();
}
//修改
public function edit($id, Request $request, Brand $model, BrandValidate $validate)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('edit')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
//处理图片上传
if (!empty($_FILES['img']['name'])) {
$attachment_img = new \app\common\model\Attachment;
$file_img = $attachment_img->upload('img');
if ($file_img) {
$param['img'] = $file_img->url;
}
}
$result = $data->save($param);
return $result ? success() : error();
}
$this->assign([
'data' => $data,
]);
return $this->fetch('add');
}
//删除
public function del($id, Brand $model)
{
if (count($model->noDeletionId) > 0) {
if (is_array($id)) {
if (array_intersect($model->noDeletionId, $id)) {
return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
}
} else if (in_array($id, $model->noDeletionId)) {
return error('ID为' . $id . '的数据无法删除');
}
}
if ($model->softDelete) {
$result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
} else {
$result = $model->whereIn('id', $id)->delete();
}
return $result ? success('操作成功', URL_RELOAD) : error();
}
}

View File

@ -0,0 +1,147 @@
<?php
/**
* 后台基础控制器
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\controller;
use app\admin\model\AdminMenu;
use app\admin\model\AdminUser;
use app\admin\traits\{AdminAuth, AdminTree, PhpOffice};
class Controller extends \think\Controller
{
use AdminAuth, AdminTree, PhpOffice;
/**
* 当前url
* @var string
*/
protected $url;
/**
* 当前用户ID
* @var int
*/
protected $uid = 0;
/**
* 当前用户
* @var AdminUser
*/
protected $user;
/**
* 后台变量
* @var array
*/
protected $admin;
/**
* 无需验证权限的url
* @var array
*/
protected $authExcept = [
'admin/auth/login',
'admin/auth/logout',
'admin/editor/server',
];
//初始化基础控制器
protected function initialize()
{
$request = $this->request;
//获取当前访问url
$this->url = parse_name($request->module()) . '/' .
parse_name($request->controller()) . '/' .
parse_name($request->action());
//验证权限
if (!in_array($this->url, $this->authExcept)) {
if (!$this->isLogin()) {
error('未登录', 'auth/login');
} else if ($this->user->id !== 1 && !$this->authCheck($this->user)) {
error('无权限', $this->request->isGet() ? null : URL_CURRENT);
}
}
if ((int)$request->param('check_auth') === 1) {
success();
}
//记录日志
$menu = AdminMenu::get(['url' => $this->url]);
if ($menu) {
$this->admin['title'] = $menu->name;
if ($menu->log_method === $request->method()) {
$this->createAdminLog($this->user, $menu);
}
}
$this->admin['per_page'] = cookie('admin_per_page') ?? 10;
$this->admin['per_page'] = $this->admin['per_page'] < 100 ? $this->admin['per_page'] : 100;
}
//重写fetch
protected function fetch($template = '', $vars = [], $config = [])
{
$this->admin['pjax'] = $this->request->isPjax();
$this->admin['user'] = $this->user;
$this->setAdminInfo();
if (!$this->admin['pjax'] && 'admin/auth/login' !== $this->url) {
$this->admin['menu'] = $this->getLeftMenu($this->user);
}
$this->assign('debug', config('app.app_debug') ? 'true' : 'false');
$this->assign('cookie_prefix', config('cookie.prefix') ?? '');
$this->assign('admin', $this->admin);
return parent::fetch($template, $vars, $config);
}
//空方法
public function _empty()
{
$this->admin['title'] = '404';
return $this->fetch('template/404');
}
//设置前台显示的后台信息
protected function setAdminInfo()
{
if (!$this->admin['pjax']) {
$admin_info = [
'name' => config('admin.name'),
'author' => config('admin.author'),
'version' => config('admin.version'),
'short_name' => config('admin.short_name'),
];
cache('admin_info', json_encode($admin_info), 8640000);
} else {
$admin_info = cache('admin_info');
if (!$admin_info) {
$admin_info = [
'name' => config('admin.name'),
'author' => config('admin.author'),
'version' => config('admin.version'),
'short_name' => config('admin.short_name'),
];
} else {
$admin_info = json_decode($admin_info, true);
}
}
$this->admin = array_merge($this->admin, $admin_info);
}
}

View File

@ -0,0 +1,123 @@
<?php
/**
* 收货地址控制器
*/
namespace app\admin\controller;
use think\Request;
use app\common\model\DeliverAddress;
use app\common\model\User;
use yupoxiong\region\model\Region;
use app\common\validate\DeliverAddressValidate;
class DeliverAddressController extends Controller
{
//列表
public function index(Request $request, DeliverAddress $model)
{
$param = $request->param();
$model = $model->with('user,province,city,district,street')->scope('where', $param);
$data = $model->paginate($this->admin['per_page'], false, ['query' => $request->get()]);
//关键词,排序等赋值
$this->assign($request->get());
$this->assign([
'data' => $data,
'page' => $data->render(),
'total' => $data->total(),
]);
return $this->fetch();
}
//添加
public function add(Request $request, DeliverAddress $model, DeliverAddressValidate $validate, Region $region)
{
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('add')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $model::create($param);
$url = URL_BACK;
if (isset($param['_create']) && $param['_create'] == 1) {
$url = URL_RELOAD;
}
return $result ? success('添加成功', $url) : error();
}
$this->assign([
'user_list' => User::all(),
'province_list' => $region->getProvince(),
'city_list' => $region->getCity(1),
'district_list' => $region->getDistrict(1),
'street_list' => $region->getStreet(1),
]);
return $this->fetch();
}
//修改
public function edit($id, Request $request, DeliverAddress $model, DeliverAddressValidate $validate, Region $region)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('edit')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $data->save($param);
return $result ? success() : error();
}
$this->assign([
'data' => $data,
'user_list' => User::all(),
'province_list' => $region->getProvince(),
'city_list' => $region->getCity(1),
'district_list' => $region->getDistrict(1),
'street_list' => $region->getStreet(1),
]);
return $this->fetch('add');
}
//删除
public function del($id, DeliverAddress $model)
{
if (count($model->noDeletionId) > 0) {
if (is_array($id)) {
if (array_intersect($model->noDeletionId, $id)) {
return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
}
} else if (in_array($id, $model->noDeletionId)) {
return error('ID为' . $id . '的数据无法删除');
}
}
if ($model->softDelete) {
$result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
} else {
$result = $model->whereIn('id', $id)->delete();
}
return $result ? success('操作成功', URL_RELOAD) : error();
}
}

View File

@ -0,0 +1,175 @@
<?php
/**
* 常用功能集合
*/
namespace app\admin\controller;
use Endroid\QrCode\ErrorCorrectionLevel;
use Endroid\QrCode\LabelAlignment;
use Endroid\QrCode\QrCode;
use Overtrue\EasySms\EasySms;
use PHPMailer\PHPMailer\PHPMailer;
use think\Request;
class DemoController extends Controller
{
//邮件页面
public function email()
{
return $this->fetch();
}
//发送邮件功能
public function sendEmail(Request $request)
{
$param = $request->param();
$config = config('email.smtp');
$mail = new PHPMailer(true); // Passing `true` enables exceptions
try {
$address = $param['address'];
$subject = $param['subject'];
$content = $param['content'];
$full_content = $request->param(false)['content'];
//服务器配置
$mail->CharSet = "UTF-8"; //设定邮件编码
$mail->SMTPDebug = 0; // 调试模式输出
$mail->isSMTP(); // 使用SMTP
$mail->Host = $config['host']; // SMTP服务器
$mail->SMTPAuth = true; // 允许 SMTP 认证
$mail->Username = $config['username']; // SMTP 用户名 即邮箱的用户名
$mail->Password = $config['password']; // SMTP 密码 部分邮箱是授权码(例如163邮箱)
$mail->SMTPSecure = 'ssl'; // 允许 TLS 或者ssl协议
$mail->Port = 465; // 服务器端口 25 或者465 具体要看邮箱服务器支持
$mail->setFrom($config['address'], $config['name']); //发件人
$mail->addAddress($address, $address); // 收件人
//$mail->addAddress('ellen@example.com'); // 可添加多个收件人
$mail->addReplyTo($config['address'], $config['name']); //回复的时候回复给哪个邮箱 建议和发件人一致
//$mail->addCC('cc@example.com'); //抄送
//$mail->addBCC('bcc@example.com'); //密送
//发送附件
// $mail->addAttachment('../xy.zip'); // 添加附件
//$mail->addAttachment(app()->getRootPath() . 'public/uploads/attachment/20190902/6a673f554c694a41971fca94c7503315.jpg', 'test.jpg'); // 发送附件并且重命名
//Content
$mail->isHTML(true); // 是否以HTML文档格式发送 发送后客户端可直接显示对应HTML内容
$mail->Subject = $subject;
$mail->Body = $full_content;
$mail->AltBody = $content;
$mail->send();
$result = true;
$msg = '邮件发送成功';
} catch (\Exception $e) {
$msg = '邮件发送失败,错误信息:' . $mail->ErrorInfo;
$result = false;
}
return $result ? success('成功', URL_RELOAD, '') : error($msg);
}
//短信页面
public function sms()
{
return $this->fetch();
}
//发送短信功能
public function sendSms(Request $request)
{
$param = $request->param();
$config = config('sms.');
$easySms = new EasySms($config);
try {
$result = $easySms->send($param['mobile'], [
'template' => 'SMS_001',
'data' => [
'code' => 543260
],
]);
$success = true;
$msg = '发送成功';
} catch (\Exception $e) {
$success = false;
$msg = $e->getMessage();
}
if (!$success || $result['aliyun']['status'] !== 'success') {
return error($msg);
}
return success($msg);
}
//二维码页面
public function qrCode()
{
return $this->fetch();
}
//生成二维码功能
public function createQrCode(Request $request)
{
$param = $request->param();
$content = $param['content'] ?? '麻烦输入内容OK';
//创建码,$content为二维码内容
$qrCode = new QrCode($content);
//设置尺寸
$qrCode->setSize(300);
//可以设置binary,png,svg,eps,debug
$qrCode->setWriterByName('png');
//设置边距
$qrCode->setMargin(10);
//编码
$qrCode->setEncoding('UTF-8');
//容错等级
$qrCode->setErrorCorrectionLevel(new ErrorCorrectionLevel(ErrorCorrectionLevel::HIGH));
//前景色
$qrCode->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0]);
//背景色
$qrCode->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255, 'a' => 0]);
//标签
$qrCode->setLabel('Admin Demo QrCode', 16, null, LabelAlignment::CENTER);
//logo地址
$qrCode->setLogoPath(app()->getRootPath() . 'public/uploads/attachment/20190902/6a673f554c694a41971fca94c7503315.jpg');
//logo大小
$qrCode->setLogoSize(100, 100);
//块尺寸设置为整数默认为true
$qrCode->setRoundBlockSize(true);
//验证结果
$qrCode->setValidateResult(false);
//写入选项
$qrCode->setWriterOptions(['exclude_xml_declaration' => true]);
//直接输出图片
//header('Content-Type: '.$qrCode->getContentType());
//return $qrCode->writeString();
$file_name = random_int(1, 5);
//保存成文件
$qrCode->writeFile(app()->getRootPath() . 'public/demo/qrcode/' . $file_name . '.png');
$code_url = '/demo/qrcode/' . $file_name . '.png';
return success('生成成功', URL_CURRENT, ['qrcode' => $code_url]);
// Create a response object
}
}

View File

@ -0,0 +1,24 @@
<?php
/**
* 编辑器server
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\controller;
use think\Request;
use tools\UEditor;
class EditorController extends Controller
{
//编辑器上传等url
public function server(Request $request)
{
$param = $request->param();
$config = config('ueditor.');
$action = $param['action'];
$editor = new UEditor($config);
return $editor->server($action);
}
}

View File

@ -0,0 +1,17 @@
<?php
/**
* 访问空控制器,用于访问不存在的控制器跳转
* @author yupoxiong <i@yufuping.com>
*/
namespace app\admin\controller;
class ErrorController extends Controller
{
public function index()
{
$this->admin['title'] = '404';
return $this->fetch('template/404');
}
}

View File

@ -0,0 +1,105 @@
<?php
/**
* 快递控制器
*/
namespace app\admin\controller;
use think\Request;
use app\common\model\Express;
use app\common\validate\ExpressValidate;
class ExpressController extends Controller
{
//列表
public function index(Request $request, Express $model)
{
$param = $request->param();
$model = $model->scope('where', $param);
$data = $model->paginate($this->admin['per_page'], false, ['query' => $request->get()]);
//关键词,排序等赋值
$this->assign($request->get());
$this->assign([
'data' => $data,
'page' => $data->render(),
'total' => $data->total(),
]);
return $this->fetch();
}
//添加
public function add(Request $request, Express $model, ExpressValidate $validate)
{
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('add')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $model::create($param);
$url = URL_BACK;
if (isset($param['_create']) && $param['_create'] == 1) {
$url = URL_RELOAD;
}
return $result ? success('添加成功', $url) : error();
}
return $this->fetch();
}
//修改
public function edit($id, Request $request, Express $model, ExpressValidate $validate)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('edit')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $data->save($param);
return $result ? success() : error();
}
$this->assign([
'data' => $data,
]);
return $this->fetch('add');
}
//删除
public function del($id, Express $model)
{
if (count($model->noDeletionId) > 0) {
if (is_array($id)) {
if (array_intersect($model->noDeletionId, $id)) {
return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
}
} else if (in_array($id, $model->noDeletionId)) {
return error('ID为' . $id . '的数据无法删除');
}
}
if ($model->softDelete) {
$result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
} else {
$result = $model->whereIn('id', $id)->delete();
}
return $result ? success('操作成功', URL_RELOAD) : error();
}
}

View File

@ -0,0 +1,54 @@
<?php
/**
* 文件控制器(暂未完成)
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\controller;
use think\facade\Env;
use think\Request;
class FileController extends Controller
{
protected $authExcept = [
'admin/file/icon',
];
//文件列表
public function index(Request $request)
{
}
//文件上传
public function upload()
{
$file = request()->file('file');
}
//上传图片修改
public function icon(Request $request)
{
$param = $request->param();
$file = request()->file('image');
if($file){
$info = $file->validate(['size'=>10*1024*1024,'ext'=>'jpg,png,gif'])->move(Env::get('root_path').'public/uploads/attachment');
if($info){
$data['avatar_logo_thum']='';
$data['avatar_logo']='';
if($param['type']==1){
$width=$param['width'] ?? '200';
$heigh=$param['heigh'] ?? '200';
$avatar_thum=thumbnail_img($info,$width,$heigh,'attachment');
$data['avatar_logo_thum']=$avatar_thum;
}
$data['avatar_logo']='/uploads/attachment/'.$info->getSaveName();
return success('上传成功','',$data);
}else{
// 上传失败获取错误信息
return client_error($file->getError());
}
}else{
return client_error('请上传图片');
}
}
}

View File

@ -0,0 +1,293 @@
<?php
/**
* 代码自动生成控制器
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\controller;
use app\admin\model\AdminMenu;
use Error;
use Exception;
use generate\field\Ip;
use generate\field\Map;
use generate\field\Province;
use generate\field\Url;
use generate\field\File;
use generate\field\Icon;
use generate\field\Year;
use generate\field\Text;
use generate\field\Date;
use generate\field\Color;
use generate\field\Email;
use generate\field\Field;
use generate\field\Radio;
use generate\field\Image;
use generate\field\Select;
use generate\field\Mobile;
use generate\field\IdCard;
use generate\field\Number;
use generate\field\Editor;
use generate\field\Datetime;
use generate\field\Checkbox;
use generate\field\Password;
use generate\field\Textarea;
use generate\field\YearMonth;
use generate\field\YearRange;
use generate\field\MultiFile;
use generate\field\DateRange;
use generate\field\MultiImage;
use generate\field\SwitchField;
use generate\field\MultiSelect;
use generate\field\DatetimeRange;
use generate\field\YearMonthRange;
use think\Db;
use think\db\Connection;
use think\Request;
use generate\Generate;
class GenerateController extends Controller
{
//首页
public function index()
{
return $this->fetch();
}
//自动生成页面
public function add()
{
$this->assign([
'table' => (new Generate())->getTable(),
'menus' => $this->menu(10000),
]);
return $this->fetch();
}
//获取表数据
public function getTable()
{
return success('success', URL_CURRENT, (new Generate())->getTable());
}
public function getMenu()
{
return success('success', URL_CURRENT, (new Generate())->getMenu());
}
//自动生成代码接口
public function create(Request $request)
{
$param = $request->param();
$data = [
'table' => $param['table_name'],
'cn_name' => $param['cn_name'],
'menu' => [
//创建菜单-1为不创建0为顶级菜单
'create' => $param['create_menu'],
'menu' => $param['create_menu_list']
],
'controller' => [
'module' => 'admin',
'create' => $param['create_controller'] ?? 0,
'name' => $param['controller_name'],
'action' => $param['controller_action_list'],
],
'model' => [
'module' => 'common',
'create' => $param['create_model'] ?? 0,
'name' => $param['model_name'],
'timestamp' => $param['auto_timestamp'] ?? 0,
'soft_delete' => $param['soft_delete'] ?? 0,
],
'validate' => [
'module' => 'common',
'create' => $param['create_validate'] ?? 0,
'name' => $param['validate_name'],
],
'view' => [
'enable' => $param['list_enable'] ?? 0,
'delete' => $param['list_delete'] ?? 0,
'create' => $param['list_create'] ?? 0,
'export' => $param['list_export'] ?? 0,
],
];
/**
* 字段数据组装
*/
$field_data = [];
foreach ($param['field_name'] as $key => $value) {
$field_data[] = [
//字段名
'field_name' => $param['field_name'][$key][0],
//字段类型
'field_type' => $param['field_type'][$key][0],
//表单名称/中文名称
'form_name' => $param['form_name'][$key][0] ?? '',
//是否为列表字段
'is_list' => $param['is_list'][$key][0] ?? 0,
//是否为列表搜索字段
'is_search' => $param['is_search'][$key][0] ?? 0,
//是否为表单字段
'is_form' => $param['is_form'][$key][0] ?? 0,
//表单类型
'form_type' => $param['form_type'][$key][0] ?? 0,
//验证规则
'form_validate' => $param['form_validate'][$key] ?? 0,
//默认值
'field_default' => $param['field_default'][$key][0] ?? 0,
//获取器/修改器
'getter_setter' => $param['getter_setter'][$key][0] ?? 0,
//是否参与列表排序
'list_sort' => $param['list_sort'][$key][0] ?? 0,
//验证场景
'field_scene' => $param['field_scene'][$key] ?? 0,
//关联
'is_relation' => $param['is_relation'][$key][0] ?? 0,
//关联类型
'relation_type' => $param['relation_type'][$key][0] ?? 1,
//关联表
'relation_table' => $param['relation_table'][$key][0] ?? '',
//关联显示字段
'relation_show' => $param['relation_show'][$key][0] ?? 'name',
];
}
$data['data'] = $field_data;
//已经组装好data,先生成表,再生成模型,验证器,控制器,视图
$generate = new Generate($data);
$msg = '生成成功';
$result = false;
try {
$generate->run();
$result = true;
} catch (Exception $e) {
$msg = $e->getMessage();
}
return $result ? success($msg, URL_CURRENT) : error($msg);
}
//自动生成form表单字段
public function form()
{
return $this->fetch();
}
//生成表单字段html接口
public function formField(Request $request)
{
$param = $request->param();
if (empty($param['form_name']) || empty($param['field_name']) || empty($param['form_type'])) {
return error('信息不完整');
}
$result = false;
try {
if ($param['form_type'] === 'switch') {
$param['form_type'] = 'switch_field';
}
$param['field_default'] = '';
$class_name = parse_name($param['form_type'], 1);
$class = '\\generate\\field\\' . $class_name;
$data = $class::create($param);
$result = true;
$msg = '生成表单html成功';
} catch (Exception $exception) {
$msg = $exception->getMessage();
} catch (Error $error) {
$msg = $error->getMessage();
}
return $result ? success($msg, URL_CURRENT, $data) : error($msg);
}
//根据字段返回相关表单类型和验证
public function getField(Request $request)
{
$param = $request->param();
$name = $param['name'];
$data = (new Generate())->getAll($name);
return success('success', URL_CURRENT, $data);
}
//获取验证select内容
/**
* @param Request $request
* @return \think\response\Json|void
*/
public function getValidateSelect(Request $request)
{
$param = $request->param();
$result = false;
try {
if ($param['form_type'] === 'switch') {
$param['form_type'] = 'switch_field';
}
$class_name = parse_name($param['form_type'], 1);
$class = '\\generate\\field\\' . $class_name;
$data = $class::rule();
$result = true;
$msg = '获取字段验证规则成功';
} catch (Exception $exception) {
$msg = $exception->getMessage();
} catch (Error $error) {
$msg = $error->getMessage();
}
return $result ? success($msg, URL_CURRENT, $data) : error($msg);
}
//菜单选择
protected function menu($selected = 1, $current_id = 0)
{
$result = AdminMenu::where('id', '<>', $current_id)->order('sort_id', 'asc')->order('id', 'asc')->column('id,parent_id,name,sort_id', 'id');
foreach ($result as $r) {
$r['selected'] = (int)$r['id'] === (int)$selected ? 'selected' : '';
}
$str = "<option value='\$id' \$selected >\$spacer \$name</option>";
$this->initTree($result);
return $this->getTree(0, $str, $selected);
}
}

View File

@ -0,0 +1,170 @@
<?php
/**
* 商品规格设置控制器
*/
namespace app\admin\controller;
use think\Request;
use app\common\model\GoodsAttrCategory;
use app\common\model\GoodsAttr;
use think\db;
use app\common\validate\GoodsAttrCategoryValidate;
class GoodsAttrCategoryController extends Controller
{
//列表
public function index(Request $request, GoodsAttrCategory $model)
{
$param = $request->param();
$model = $model->scope('where', $param);
$data = $model->paginate($this->admin['per_page'], false, ['query'=>$request->get()]);
//关键词,排序等赋值
$this->assign($request->get());
$this->assign([
'data' => $data,
'page' => $data->render(),
'total' => $data->total(),
]);
return $this->fetch();
}
//添加
public function add(Request $request, GoodsAttrCategory $model,GoodsAttr $gamodel, GoodsAttrCategoryValidate $validate)
{
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('add')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$attrcategory['name']=$param['name'];
// 启动事务
$model->startTrans();
try{
$result = $model::create($attrcategory);
$class_id=$result->id;
$field_data = [];
foreach ($param['attr_name'] as $key => $value) {
$field_data[] = [
'attr_name' => $param['attr_name'][$key][0],
'attr_class_id' => $class_id,
'attr_index' =>0,
'attr_values' =>'',
'sort_order' => $param['sort_order'][$key][0] ?? 255,
];
}
$gamodel::insertAll($field_data);
// 提交事务
$model->commit();
}catch(\Exception $e){
// 回滚事务
$model->rollback();
return error('添加失败');
}
$url = URL_BACK;
if(isset($param['_create']) && $param['_create']==1){
$url = URL_RELOAD;
}
return success('添加成功',$url);
}
$this->assign([
'gamodel_count'=>0,
]);
return $this->fetch();
}
//修改
public function edit($id, Request $request, GoodsAttrCategory $model,GoodsAttr $gamodel, GoodsAttrCategoryValidate $validate)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('edit')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$attrcategory['name']=$param['name'];
// 启动事务
$model->startTrans();
try{
$model->where('id',$id)->update($attrcategory);
$where[]=array('attr_class_id','=',$id);
Db::table('goods_attr')->where($where)->delete();
$field_data = [];
foreach ($param['attr_name'] as $key => $value) {
$field_data[] = [
'attr_name' => $param['attr_name'][$key][0],
'attr_class_id' => $id,
'attr_index' =>0,
'attr_values' =>'',
'sort_order' => $param['sort_order'][$key][0] ?? 255,
];
}
$gamodel::insertAll($field_data);
// 提交事务
$model->commit();
}catch(\Exception $e){
$msg='提交失败';
// 回滚事务
$model->rollback();
return error($msg);//
}
$result = $data->save($param);
return $result ? success() : error();
}
$gamodel_list=$gamodel->field('attr_name,sort_order')->where(array('attr_class_id'=>$id))->select();
$gamodel_l=array();
foreach ($gamodel_list as $k1 =>$v1) {
$key=$k1+1;
$gamodel_l[$key]['attr_name']=$v1['attr_name'];
$gamodel_l[$key]['sort_order']=$v1['sort_order'];
}
$this->assign([
'data' => $data,
'gamodel_list'=>$gamodel_l,
'gamodel_count'=>count($gamodel_list),
]);
return $this->fetch('add');
}
//删除
public function del($id, GoodsAttrCategory $model)
{
if (count($model->noDeletionId) > 0) {
if (is_array($id)) {
if (array_intersect($model->noDeletionId, $id)) {
return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
}
} else if (in_array($id, $model->noDeletionId)) {
return error('ID为' . $id . '的数据无法删除');
}
}
if ($model->softDelete) {
$result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
} else {
$result = $model->whereIn('id', $id)->delete();
}
return $result ? success('操作成功', URL_RELOAD) : error();
}
//获取规格分类下的规格
public function get_attr()
{
}
}

View File

@ -0,0 +1,101 @@
<?php
/**
* 商品分类控制器
*/
namespace app\admin\controller;
use think\Request;
use app\common\model\GoodsCategory;
use app\common\validate\GoodsCategoryValidate;
class GoodsCategoryController extends Controller
{
//列表
public function index(GoodsCategory $model)
{
$data = $this->getTreeList($model);
$this->assign([
'data' => $data,
]);
return $this->fetch();
}
//添加
public function add(Request $request, GoodsCategory $model, GoodsCategoryValidate $validate)
{
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('add')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $model::create($param);
$url = URL_BACK;
if (isset($param['_create']) && $param['_create'] == 1) {
$url = URL_RELOAD;
}
return $result ? success('添加成功', $url) : error();
}
$this->assign([
'cat_list' => $this->getSelectList($model),
]);
return $this->fetch();
}
//修改
public function edit($id, Request $request, GoodsCategory $model, GoodsCategoryValidate $validate)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('edit')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $data->save($param);
return $result ? success() : error();
}
$this->assign([
'data' => $data,
'cat_list' => $this->getSelectList($model, $data->parent_id),
]);
return $this->fetch('add');
}
//删除
public function del($id, GoodsCategory $model)
{
if (count($model->noDeletionId) > 0) {
if (is_array($id)) {
if (array_intersect($model->noDeletionId, $id)) {
return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
}
} else if (in_array($id, $model->noDeletionId)) {
return error('ID为' . $id . '的数据无法删除');
}
}
if ($model->softDelete) {
$result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
} else {
$result = $model->whereIn('id', $id)->delete();
}
return $result ? success('操作成功', URL_RELOAD) : error();
}
}

View File

@ -0,0 +1,139 @@
<?php
/**
* 商品控制器
*/
namespace app\admin\controller;
use think\Request;
use app\common\model\Goods;
use app\common\model\GoodsCategory;
use app\common\model\Brand;
use app\common\model\GoodsAttrCategory;
use app\common\validate\GoodsValidate;
class GoodsController extends Controller
{
//列表
public function index(Request $request, Goods $model)
{
$param = $request->param();
$model = $model->with('goods_category,brand')->scope('where', $param);
$data = $model->paginate($this->admin['per_page'], false, ['query' => $request->get()]);
//关键词,排序等赋值
$this->assign($request->get());
$this->assign([
'data' => $data,
'page' => $data->render(),
'total' => $data->total(),
]);
return $this->fetch();
}
//添加
public function add(Request $request, Goods $model, GoodsValidate $validate)
{
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('add')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$param['attr'] = $request->param(false)['attr'];
$param['detail'] = $request->param(false)['detail'];
//处理图片上传
$attachment_img = new \app\common\model\Attachment;
$file_img = $attachment_img->upload('img');
if ($file_img) {
$param['img'] = $file_img->url;
} else {
return error($attachment_img->getError());
}
$result = $model::create($param);
$url = URL_BACK;
if (isset($param['_create']) && $param['_create'] == 1) {
$url = URL_RELOAD;
}
return $result ? success('添加成功', $url) : error();
}
$this->assign([
'goods_category_list' => $this->getSelectList(new GoodsCategory),
'brand_list' => Brand::all(),
'imgurl_list'=>array(),
]);
return $this->fetch();
}
//修改
public function edit($id, Request $request, Goods $model, GoodsValidate $validate)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('edit')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$param['attr'] = $request->param(false)['attr'];
$param['detail'] = $request->param(false)['detail'];
//处理图片上传
if (!empty($_FILES['img']['name'])) {
$attachment_img = new \app\common\model\Attachment;
$file_img = $attachment_img->upload('img');
if ($file_img) {
$param['img'] = $file_img->url;
}
}
$result = $data->save($param);
return $result ? success() : error();
}
$this->assign([
'data' => $data,
'goods_category_list' => $this->getSelectList(new GoodsCategory, $data->goods_category_id),
'brand_list' => Brand::all(),
'goodsattrcategory_list' => GoodsAttrCategory::all(),
'imgurl_list'=>array(),
]);
return $this->fetch('add');
}
//删除
public function del($id, Goods $model)
{
if (count($model->noDeletionId) > 0) {
if (is_array($id)) {
if (array_intersect($model->noDeletionId, $id)) {
return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
}
} else if (in_array($id, $model->noDeletionId)) {
return error('ID为' . $id . '的数据无法删除');
}
}
if ($model->softDelete) {
$result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
} else {
$result = $model->whereIn('id', $id)->delete();
}
return $result ? success('操作成功', URL_RELOAD) : error();
}
}

View File

@ -0,0 +1,63 @@
<?php
/**
* 后台首页控制器
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\controller;
use app\admin\model\AdminLog;
use app\admin\model\AdminMenu;
use app\admin\model\AdminRole;
use app\admin\model\AdminUser;
use tools\SystemInfo;
use think\Request;
class IndexController extends Controller
{
public function index(Request $request)
{
//默认密码修改检测
$password_danger = 0;
if (config('admin.password_warning') && $this->user->id == 1 && password_verify('super-admin', $this->user->password)) {
$password_danger = 1;
}
/**
* 首页数据展示,可自行替换
*/
$this->assign([
//后台用户数量
'admin_user_count' => AdminUser::count(),
//后台角色数量
'admin_role_count' => AdminRole::count(),
//后台菜单数量
'admin_menu_count' => AdminMenu::count(),
//后台日志数量
'admin_log_count' => AdminLog::count(),
]);
//是否显示欢迎信息
$welcome_info = config('admin.welcome_info');
if ($welcome_info) {
$this->admin['name'] = config('admin.name');
}
$this->assign([
//系统信息
'system_info' => SystemInfo::getSystemInfo(),
//访问信息
'visitor_info' => $request,
//默认密码警告
'password_danger' => $password_danger,
//当前用户
'user' => $this->user,
//欢迎信息
'welcome_info' => $welcome_info
]);
return $this->fetch();
}
}

View File

@ -0,0 +1,129 @@
<?php
/**
* 订单控制器
*/
namespace app\admin\controller;
use app\common\model\DeliverAddress;
use app\common\model\Express;
use app\common\model\Goods;
use app\common\model\Order;
use app\common\model\OrderGoods;
use app\common\model\User;
use app\common\validate\OrderValidate;
use think\Db;
use think\Request;
class OrderController extends Controller
{
//列表
public function index(Request $request, Order $model)
{
$param = $request->param();
$model = $model->with('user,express')->scope('where', $param);
$data = $model->paginate($this->admin['per_page'], false, ['query' => $request->get()]);
//关键词,排序等赋值
$this->assign($request->get());
$this->assign([
'data' => $data,
'page' => $data->render(),
'total' => $data->total(),
]);
return $this->fetch();
}
//添加
public function add(Request $request, Order $model, OrderValidate $validate)
{
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('add')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $model::create($param);
$url = URL_BACK;
if (isset($param['_create']) && $param['_create'] == 1) {
$url = URL_RELOAD;
}
return $result ? success('添加成功', $url) : error();
}
$this->assign([
'user_list' => User::all(),
'express_list' => Express::all(),
]);
return $this->fetch();
}
//修改
public function edit($id, Request $request, Order $model, OrderValidate $validate)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('edit')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $data->save($param);
return $result ? success() : error();
}
$this->assign([
'data' => $data,
'user_list' => User::all(),
'express_list' => Express::all(),
]);
return $this->fetch('add');
}
//删除
public function del($id, Order $model)
{
if (count($model->noDeletionId) > 0) {
if (is_array($id)) {
if (array_intersect($model->noDeletionId, $id)) {
return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
}
} else if (in_array($id, $model->noDeletionId)) {
return error('ID为' . $id . '的数据无法删除');
}
}
if ($model->softDelete) {
$result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
} else {
$result = $model->whereIn('id', $id)->delete();
}
return $result ? success('操作成功', URL_RELOAD) : error();
}
//订单详情
public function detail($id, Order $model)
{
$data = $model::get($id);
$this->assign([
'data' => $data
]);
return $this->fetch();
}
}

View File

@ -0,0 +1,39 @@
<?php
/**
* 公共控制器
*/
namespace app\admin\controller;
use app\common\model\Article;
use app\common\model\Goods;
use think\Request;
class PubController extends Controller
{
protected $authExcept = [
'admin/pub/getslidetargetdata'
];
public function getSlideTargetData(Request $request)
{
$param = $request->param();
switch ($param['type_id']) {
case 1:
$data = Goods::all();
break;
case 2:
$data = Article::all();
break;
default:
$data = Goods::all();
break;
}
return success('success', URL_CURRENT, $data);
}
}

View File

@ -0,0 +1,127 @@
<?php
/**
* 轮播控制器
*/
namespace app\admin\controller;
use think\Request;
use app\common\model\Slide;
use app\common\validate\SlideValidate;
class SlideController extends Controller
{
//列表
public function index(Request $request, Slide $model)
{
$param = $request->param();
$model = $model->scope('where', $param);
$data = $model->paginate($this->admin['per_page'], false, ['query' => $request->get()]);
//关键词,排序等赋值
$this->assign($request->get());
$this->assign([
'data' => $data,
'page' => $data->render(),
'total' => $data->total(),
]);
return $this->fetch();
}
//添加
public function add(Request $request, Slide $model, SlideValidate $validate)
{
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('add')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
//处理图片上传
$attachment_img = new \app\common\model\Attachment;
$file_img = $attachment_img->upload('img');
if ($file_img) {
$param['img'] = $file_img->url;
} else {
return error($attachment_img->getError());
}
$result = $model::create($param);
$url = URL_BACK;
if (isset($param['_create']) && $param['_create'] == 1) {
$url = URL_RELOAD;
}
return $result ? success('添加成功', $url) : error();
}
$this->assign([
'jump_type' => $model->jumpType,
]);
return $this->fetch();
}
//修改
public function edit($id, Request $request, Slide $model, SlideValidate $validate)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('edit')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
//处理图片上传
if (!empty($_FILES['img']['name'])) {
$attachment_img = new \app\common\model\Attachment;
$file_img = $attachment_img->upload('img');
if ($file_img) {
$param['img'] = $file_img->url;
}
}
$result = $data->save($param);
return $result ? success() : error();
}
$this->assign([
'data' => $data,
'jump_type' => $model->jumpType,
]);
return $this->fetch('add');
}
//删除
public function del($id, Slide $model)
{
if (count($model->noDeletionId) > 0) {
if (is_array($id)) {
if (array_intersect($model->noDeletionId, $id)) {
return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
}
} else if (in_array($id, $model->noDeletionId)) {
return error('ID为' . $id . '的数据无法删除');
}
}
if ($model->softDelete) {
$result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
} else {
$result = $model->whereIn('id', $id)->delete();
}
return $result ? success('操作成功', URL_RELOAD) : error();
}
}

View File

@ -0,0 +1,20 @@
<?php
/**
* 统计示例控制器
*/
namespace app\admin\controller;
class StatisticsController extends Controller
{
//统计概览
public function index()
{
return $this->fetch();
}
}

View File

@ -0,0 +1,105 @@
<?php
/**
* 标签控制器
*/
namespace app\admin\controller;
use think\Request;
use app\common\model\Tag;
use app\common\validate\TagValidate;
class TagController extends Controller
{
//列表
public function index(Request $request, Tag $model)
{
$param = $request->param();
$model = $model->scope('where', $param);
$data = $model->paginate($this->admin['per_page'], false, ['query' => $request->get()]);
//关键词,排序等赋值
$this->assign($request->get());
$this->assign([
'data' => $data,
'page' => $data->render(),
'total' => $data->total(),
]);
return $this->fetch();
}
//添加
public function add(Request $request, Tag $model, TagValidate $validate)
{
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('add')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $model::create($param);
$url = URL_BACK;
if (isset($param['_create']) && $param['_create'] == 1) {
$url = URL_RELOAD;
}
return $result ? success('添加成功', $url) : error();
}
return $this->fetch();
}
//修改
public function edit($id, Request $request, Tag $model, TagValidate $validate)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('edit')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $data->save($param);
return $result ? success() : error();
}
$this->assign([
'data' => $data,
]);
return $this->fetch('add');
}
//删除
public function del($id, Tag $model)
{
if (count($model->noDeletionId) > 0) {
if (is_array($id)) {
if (array_intersect($model->noDeletionId, $id)) {
return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
}
} else if (in_array($id, $model->noDeletionId)) {
return error('ID为' . $id . '的数据无法删除');
}
}
if ($model->softDelete) {
$result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
} else {
$result = $model->whereIn('id', $id)->delete();
}
return $result ? success('操作成功', URL_RELOAD) : error();
}
}

View File

@ -0,0 +1,131 @@
<?php
/**
* 测试控制器
*/
namespace app\admin\controller;
use think\Request;
use app\common\model\Test;
use app\common\validate\TestValidate;
class TestController extends Controller
{
//列表
public function index(Request $request, Test $model)
{
$param = $request->param();
$model = $model->scope('where', $param);
if (isset($param['export_data']) && $param['export_data'] == 1) {
$header = ['ID','',];
$body = [];
$data = $model->select();
foreach ($data as $item) {
$record = [];
$record['id'] = $item->id;
$record['name'] = $item->name;
$body[] = $record;
}
return $this->exportData($header, $body, 'test-' . date('Y-m-d-H-i-s'));
}
$data = $model->paginate($this->admin['per_page'], false, ['query'=>$request->get()]);
//关键词,排序等赋值
$this->assign($request->get());
$this->assign([
'data' => $data,
'page' => $data->render(),
'total' => $data->total(),
]);
return $this->fetch();
}
//添加
public function add(Request $request, Test $model, TestValidate $validate)
{
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('add')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $model::create($param);
$url = URL_BACK;
if(isset($param['_create']) && $param['_create']==1){
$url = URL_RELOAD;
}
return $result ? success('添加成功',$url) : error();
}
return $this->fetch();
}
//修改
public function edit($id, Request $request, Test $model, TestValidate $validate)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('edit')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
$result = $data->save($param);
return $result ? success() : error();
}
$this->assign([
'data' => $data,
]);
return $this->fetch('add');
}
//删除
public function del($id, Test $model)
{
if (count($model->noDeletionId) > 0) {
if (is_array($id)) {
if (array_intersect($model->noDeletionId, $id)) {
return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
}
} else if (in_array($id, $model->noDeletionId)) {
return error('ID为' . $id . '的数据无法删除');
}
}
if ($model->softDelete) {
$result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
} else {
$result = $model->whereIn('id', $id)->delete();
}
return $result ? success('操作成功', URL_RELOAD) : error();
}
//启用
public function enable($id,Test $model)
{
$result = $model->whereIn('id',$id)->update(['status'=>1]);
return $result ? success('操作成功', URL_RELOAD) : error();
}
//禁用
public function disable($id,Test $model)
{
$result = $model->whereIn('id',$id)->update(['status'=>0]);
return $result ? success('操作成功', URL_RELOAD) : error();
}
}

View File

@ -0,0 +1,160 @@
<?php
/**
* 用户控制器
*/
namespace app\admin\controller;
use think\Request;
use app\common\model\User;
use app\common\model\UserLevel;
use app\common\validate\UserValidate;
class UserController extends Controller
{
//列表
public function index(Request $request, User $model)
{
$param = $request->param();
$model = $model->with('user_level')->scope('where', $param);
if (isset($param['export_data']) && $param['export_data'] == 1) {
$header = ['ID', '头像', '用户等级', '用户名', '手机号', '昵称', '是否启用', '创建时间',];
$body = [];
$data = $model->select();
foreach ($data as $item) {
$record = [];
$record['id'] = $item->id;
$record['avatar'] = $item->avatar;
$record['user_level_id'] = $item->user_level->name ?? '';
$record['username'] = $item->username;
$record['mobile'] = $item->mobile;
$record['nickname'] = $item->nickname;
$record['status'] = $item->status_text;
$record['create_time'] = $item->create_time;
$body[] = $record;
}
return $this->exportData($header, $body, 'user-' . date('Y-m-d-H-i-s'));
}
$data = $model->paginate($this->admin['per_page'], false, ['query' => $request->get()]);
//关键词,排序等赋值
$this->assign($request->get());
$this->assign([
'data' => $data,
'page' => $data->render(),
'total' => $data->total(),
]);
return $this->fetch();
}
//添加
public function add(Request $request, User $model, UserValidate $validate)
{
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('add')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
//处理头像上传
$attachment_avatar = new \app\common\model\Attachment;
$file_avatar = $attachment_avatar->upload('avatar');
if ($file_avatar) {
$param['avatar'] = $file_avatar->url;
} else {
return error($attachment_avatar->getError());
}
$result = $model::create($param);
$url = URL_BACK;
if (isset($param['_create']) && $param['_create'] == 1) {
$url = URL_RELOAD;
}
return $result ? success('添加成功', $url) : error();
}
$this->assign([
'user_level_list' => UserLevel::all(),
]);
return $this->fetch();
}
//修改
public function edit($id, Request $request, User $model, UserValidate $validate)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('edit')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
//处理头像上传
if (!empty($_FILES['avatar']['name'])) {
$attachment_avatar = new \app\common\model\Attachment;
$file_avatar = $attachment_avatar->upload('avatar');
if ($file_avatar) {
$param['avatar'] = $file_avatar->url;
}
}
$result = $data->save($param);
return $result ? success() : error();
}
$this->assign([
'data' => $data,
'user_level_list' => UserLevel::all(),
]);
return $this->fetch('add');
}
//删除
public function del($id, User $model)
{
if (count($model->noDeletionId) > 0) {
if (is_array($id)) {
if (array_intersect($model->noDeletionId, $id)) {
return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
}
} else if (in_array($id, $model->noDeletionId)) {
return error('ID为' . $id . '的数据无法删除');
}
}
if ($model->softDelete) {
$result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
} else {
$result = $model->whereIn('id', $id)->delete();
}
return $result ? success('操作成功', URL_RELOAD) : error();
}
//启用
public function enable($id, User $model)
{
$result = $model->whereIn('id', $id)->update(['status' => 1]);
return $result ? success('操作成功', URL_RELOAD) : error();
}
//禁用
public function disable($id, User $model)
{
$result = $model->whereIn('id', $id)->update(['status' => 0]);
return $result ? success('操作成功', URL_RELOAD) : error();
}
}

View File

@ -0,0 +1,152 @@
<?php
/**
* 用户等级控制器
*/
namespace app\admin\controller;
use think\Request;
use app\common\model\UserLevel;
use app\common\validate\UserLevelValidate;
class UserLevelController extends Controller
{
//列表
public function index(Request $request, UserLevel $model)
{
$param = $request->param();
$model = $model->scope('where', $param);
if (isset($param['export_data']) && $param['export_data'] == 1) {
$header = ['ID', '名称', '简介', '图片', '是否启用', '创建时间',];
$body = [];
$data = $model->select();
foreach ($data as $item) {
$record = [];
$record['id'] = $item->id;
$record['name'] = $item->name;
$record['description'] = $item->description;
$record['img'] = $item->img;
$record['status'] = $item->status_text;
$record['create_time'] = $item->create_time;
$body[] = $record;
}
return $this->exportData($header, $body, 'user_level-' . date('Y-m-d-H-i-s'));
}
$data = $model->paginate($this->admin['per_page'], false, ['query' => $request->get()]);
//关键词,排序等赋值
$this->assign($request->get());
$this->assign([
'data' => $data,
'page' => $data->render(),
'total' => $data->total(),
]);
return $this->fetch();
}
//添加
public function add(Request $request, UserLevel $model, UserLevelValidate $validate)
{
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('add')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
//处理图片上传
$attachment_img = new \app\common\model\Attachment;
$file_img = $attachment_img->upload('img');
if ($file_img) {
$param['img'] = $file_img->url;
} else {
return error($attachment_img->getError());
}
$result = $model::create($param);
$url = URL_BACK;
if (isset($param['_create']) && $param['_create'] == 1) {
$url = URL_RELOAD;
}
return $result ? success('添加成功', $url) : error();
}
return $this->fetch();
}
//修改
public function edit($id, Request $request, UserLevel $model, UserLevelValidate $validate)
{
$data = $model::get($id);
if ($request->isPost()) {
$param = $request->param();
$validate_result = $validate->scene('edit')->check($param);
if (!$validate_result) {
return error($validate->getError());
}
//处理图片上传
if (!empty($_FILES['img']['name'])) {
$attachment_img = new \app\common\model\Attachment;
$file_img = $attachment_img->upload('img');
if ($file_img) {
$param['img'] = $file_img->url;
}
}
$result = $data->save($param);
return $result ? success() : error();
}
$this->assign([
'data' => $data,
]);
return $this->fetch('add');
}
//删除
public function del($id, UserLevel $model)
{
if (count($model->noDeletionId) > 0) {
if (is_array($id)) {
if (array_intersect($model->noDeletionId, $id)) {
return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
}
} else if (in_array($id, $model->noDeletionId)) {
return error('ID为' . $id . '的数据无法删除');
}
}
if ($model->softDelete) {
$result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
} else {
$result = $model->whereIn('id', $id)->delete();
}
return $result ? success('操作成功', URL_RELOAD) : error();
}
//启用
public function enable($id, UserLevel $model)
{
$result = $model->whereIn('id', $id)->update(['status' => 1]);
return $result ? success('操作成功', URL_RELOAD) : error();
}
//禁用
public function disable($id, UserLevel $model)
{
$result = $model->whereIn('id', $id)->update(['status' => 0]);
return $result ? success('操作成功', URL_RELOAD) : error();
}
}

View File

@ -0,0 +1,159 @@
<?php
/**
* 微信相关功能
*/
namespace app\admin\controller;
use EasyWeChat\Factory;
class WeChatController extends Controller
{
//功能概述
public function index()
{
return $this->fetch();
}
//服务端验证
public function server()
{
$config = config('wechat.');
$app = Factory::officialAccount($config);
$response = $app->server->serve();
// 将响应输出
return $response->send();
}
//接收 & 回复用户消息
public function msg()
{
$config = config('wechat.');
$app = Factory::officialAccount($config);
$app->server->push(function ($message) {
return "你好哇";
});
$response = $app->server->serve();
// 将响应输出
$response->send(); // Laravel 里请使用return $response;
}
//获取用户信息
public function user()
{
$config = config('wechat.');
$app = Factory::officialAccount($config);
$user = $app->user->get('用户的openID');
}
//发送模版消息
public function templateMsg()
{
$config = config('wechat.');
$app = Factory::officialAccount($config);
$app->template_message->send([
'touser' => 'user-openid',
'template_id' => 'template-id',
'url' => 'https://easywechat.org',
'miniprogram' => [
'appid' => 'xxxxxxx',
'pagepath' => 'pages/xxx',
],
'data' => [
'key1' => 'VALUE',
'key2' => 'VALUE2',
],
]);
}
//拉黑用户
public function block()
{
$config = config('wechat.');
$app = Factory::officialAccount($config);
$app->user->block('openidxxxxx');
// 或者多个用户
$app->user->block(['openid1', 'openid2', 'openid3',]);
}
//统一下单
public function pay()
{
$config = config('wechat.');
$app = Factory::payment($config);
$result = $app->order->unify([
'body' => '腾讯充值中心-QQ会员充值',
'out_trade_no' => '20150806125346',
'total_fee' => 88,
'spbill_create_ip' => '123.12.12.123', // 可选如不传该参数SDK 将会自动获取相应 IP 地址
'notify_url' => 'https://pay.weixin.qq.com/wxpay/pay.action', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
'openid' => 'oUpF8uMuAJO_M2pxb1Q9zNjWeS6o',
]);
}
//根据微信订单号退款
public function refundByTransactionId()
{
$config = config('wechat.');
$app = Factory::payment($config);
$result = $app->refund->byTransactionId('transaction-id-xxx', 'refund-no-xxx', 10000, 10000, [
// 可在此处传入其他参数,详细参数见微信支付文档
'refund_desc' => '商品已售完',
]);
}
//根据商户订单号退款
public function refundByOutTradeNo()
{
$config = config('wechat.');
$app = Factory::payment($config);
$result = $app->refund->byOutTradeNumber('out-trade-no-xxx', 'refund-no-xxx', 20000, 1000, [
// 可在此处传入其他参数,详细参数见微信支付文档
'refund_desc' => '退运费',
]);
}
//发送普通红包
public function redPacket()
{
$config = config('wechat.');
$app = Factory::payment($config);
$redpack = $app->redpack;
$redpackData = [
'mch_billno' => 'xy123456',
'send_name' => '测试红包',
're_openid' => 'oxTWIuGaIt6gTKsQRLau2M0yL16E',
'total_num' => 1, //固定为1可不传
'total_amount' => 100, //单位为分不小于100
'wishing' => '祝福语',
'client_ip' => '192.168.0.1', //可不传,不传则由 SDK 取当前客户端 IP
'act_name' => '测试活动',
'remark' => '测试备注',
// ...
];
$result = $redpack->sendNormal($redpackData);
}
}

View File

@ -0,0 +1,47 @@
<?php
/**
* 后台操作日志模型
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\model;
class AdminLog extends Model
{
protected $name = 'admin_log';
public $softDelete = false;
public $methodText = [
1=>'GET',
2=>'POST',
3=>'PUT',
4=>'DELETE',
];
protected $autoWriteTimestamp = true;
protected $updateTime= false;
protected $searchField = [
'name',
'url',
'log_ip'
];
protected $whereField = [
'admin_user_id'
];
//关联用户
public function adminUser()
{
return $this->belongsTo(AdminUser::class, 'admin_user_id', 'id');
}
//关联详情
public function adminLogData()
{
return $this->hasOne(AdminLogData::class,'admin_log_id','id');
}
}

View File

@ -0,0 +1,29 @@
<?php
/**
* 后台管理员操作日志数据模型
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\model;
use tools\Crypt;
class AdminLogData extends Model
{
protected $name = 'admin_log_data';
public $softDelete = false;
//关联log
public function adminLog()
{
return $this->belongsTo('app\admin\AdminLog','admin_log_id','id');
}
public function getDataAttr($value)
{
$data = Crypt::decrypt($value, config('app.app_key'));
return json_encode(json_decode($data, true), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
}
}

View File

@ -0,0 +1,28 @@
<?php
/**
* 后台菜单(权限)模型
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\model;
class AdminMenu extends Model
{
protected $name = 'admin_menu';
public $softDelete = false;
public $logMethod = [
0 => '不记录',
1 => 'GET',
2 => 'POST',
3 => 'PUT',
4 => 'DELETE'
];
public $noDeletionId = [
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
];
}

View File

@ -0,0 +1,41 @@
<?php
/**
* 后台角色模型
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\model;
class AdminRole extends Model
{
protected $name = 'admin_role';
public $softDelete = false;
protected $searchField = [
'name',
'description'
];
public $noDeletionId = [
1
];
public static function init()
{
//添加首页,系统管理,个人资料菜单/权限
self::event('before_insert', static function ($data) {
$data->url = [1,2,18];
});
}
protected function getUrlAttr($value)
{
return $value !== '' ? explode(',', $value) : [];
}
protected function setUrlAttr($value)
{
return $value !== '' ? implode(',', $value) : [];
}
}

View File

@ -0,0 +1,142 @@
<?php
/**
* 后台用户模型
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\model;
use think\model\concern\SoftDelete;
/**
* @property int id
* @property mixed sign_str
* @property mixed auth_url
* @property mixed role
* @property string password
*/
class AdminUser extends Model
{
use SoftDelete;
protected $name = 'admin_user';
protected $searchField = [
'nickname',
'username'
];
public $noDeletionId = [
1, 2
];
public static function init()
{
//添加自动加密密码
self::event('before_insert', static function ($data) {
$data->password = password_hash($data->password, 1);
});
//修改密码自动加密
self::event('before_update', function ($data) {
$old = (new static())::get($data->id);
if ($data->password !== $old->password) {
$data->password = password_hash($data->password, 1);
}
});
}
//关联操作日志
public function adminLog()
{
return $this->hasMany(AdminLog::class, 'admin_user_id', 'id');
}
//角色获取器
protected function getRoleAttr($value)
{
return explode(',', $value);
}
//角色修改器
protected function setRoleAttr($value)
{
return implode(',', $value);
}
//用户角色名称
protected function getRoleTextAttr($value, $data)
{
return AdminRole::where('id', 'in', $data['role'])->column('id,name', 'id');
}
/**
* 获取已授权url
* @param $value
* @param $data
* @return array
*/
protected function getAuthUrlAttr($value, $data)
{
$role_urls = AdminRole::where('id', 'in', $data['role'])->where('status', 1)->column('url');
$url_id_str = '';
foreach ($role_urls as $key => $val) {
$url_id_str .= $key == 0 ? $val : ',' . $val;
}
$url_id = array_unique(explode(',', $url_id_str));
$auth_url = [];
if (count($url_id) > 0) {
$auth_url = AdminMenu::where('id', 'in', $url_id)->column('url');
}
return $auth_url;
}
//加密字符串,用在登录的时候加密处理
protected function getSignStrAttr($value, $data)
{
$ua = request()->header('user-agent');
return sha1($data['id'] . $data['username'] . $ua);
}
//获取当前用户已授权的显示菜单
public function getShowMenu()
{
if ($this->id === 1) {
return AdminMenu::where('is_show', 1)->order('sort_id', 'asc')->order('id', 'asc')->column('id,parent_id,name,url,icon,sort_id', 'id');
}
$role_urls = AdminRole::where('id', 'in', $this->role)->where('status', 1)->column('url');
$url_id_str = '';
foreach ($role_urls as $key => $val) {
$url_id_str .= $key == 0 ? $val : ',' . $val;
}
$url_id = array_unique(explode(',', $url_id_str));
return AdminMenu::where('id', 'in', $url_id)->where('is_show', 1)->order('sort_id', 'asc')->order('id', 'asc')->column('id,parent_id,name,url,icon,sort_id', 'id');
}
//用户登录
public static function login($param)
{
$username = $param['username'];
$password = $param['password'];
$user = self::get(['username' => $username]);
if (!$user) {
exception('用户不存在');
}
if (!password_verify($password, $user->password)) {
exception('密码错误');
}
if ((int)$user->status !== 1) {
exception('用户被冻结');
}
return $user;
}
}

View File

@ -0,0 +1,66 @@
<?php
/**
* 后台基础模型
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\model;
use think\db\Query;
class Model extends \think\Model
{
//是否字段,使用场景:用户的是否冻结,文章是否为热门等等。
const BOOLEAN_TEXT = [0 => '否', 1 => '是'];
//是否为软删除
public $softDelete = true;
//软删除字段默认值
protected $defaultSoftDelete = 0;
//可搜索字段
protected $searchField = [];
//可作为条件的字段
protected $whereField = [];
//禁止删除的数据id
public $noDeletionId = [];
/**
* 查询处理
* @var Query $query
* @var array $param
*/
public function scopeWhere($query, $param)
{
//关键词like搜索
$keywords = $param['_keywords'] ?? '';
if (!empty($keywords) && count($this->searchField) > 0) {
$this->searchField = implode('|', $this->searchField);
$query->where($this->searchField, 'like', '%' . $keywords . '%');
}
//字段条件查询
if (count($this->whereField) > 0 && count($param) > 0) {
foreach ($param as $key => $value) {
if (!empty($value) && in_array($key, $this->whereField)) {
$query->where($key, $value);
}
}
}
//排序
$order = $param['_order'] ?? '';
$by = $param['_by'] ?? 'desc';
$query->order($order ?: 'id', $by ?: 'desc');
}
//状态获取器
public function getStatusTextAttr($value, $data)
{
return self::BOOLEAN_TEXT[$data['status']];
}
}

View File

@ -0,0 +1,133 @@
<?php
/**
* 登录、退出、记录日志相关
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\traits;
use app\admin\model\AdminLog;
use app\admin\model\AdminUser;
use tools\Crypt;
use tools\SafeCookie;
use think\facade\Session;
trait AdminAuth
{
public static $admin_user_id = 'admin_user_id';
public static $admin_user_id_sign = 'admin_user_sign';
//是否登录
protected function isLogin()
{
//这里要写个判断数据库的才行
$admin_user_id = Session::get(self::$admin_user_id);
$user = false;
$this->user = &$user;
if (empty($admin_user_id)) {
if (SafeCookie::has(self::$admin_user_id) && SafeCookie::has(self::$admin_user_id_sign)) {
$admin_user_id = SafeCookie::get(self::$admin_user_id);
$sign = SafeCookie::get(self::$admin_user_id_sign);
$user = AdminUser::get($admin_user_id);
if ($user && $user->sign_str === $sign) {
Session::set(self::$admin_user_id, $admin_user_id);
Session::set(self::$admin_user_id_sign, $sign);
return true;
}
}
return false;
}
$user = AdminUser::get($admin_user_id);
if(!$user) {
return false;
}
$this->uid = $user->id;
return Session::get(self::$admin_user_id_sign) === $user->sign_str;
}
/**
* session 与cookie登录
* @param $user AdminUser
* @param bool $remember
* @return bool
*/
public static function authLogin($user, $remember = false)
{
Session::set(self::$admin_user_id, $user->id);
Session::set(self::$admin_user_id_sign, $user->sign_str);
//记住登录
if ($remember === true) {
SafeCookie::set(self::$admin_user_id, $user->id);
SafeCookie::set(self::$admin_user_id_sign, $user->sign_str);
} else if (SafeCookie::has(self::$admin_user_id) || SafeCookie::has(self::$admin_user_id_sign)) {
SafeCookie::delete(self::$admin_user_id);
SafeCookie::delete(self::$admin_user_id_sign);
}
//记录登录日志
self::loginLog($user);
return true;
}
//退出
public static function authLogout()
{
Session::delete(self::$admin_user_id);
Session::delete(self::$admin_user_id_sign);
if (SafeCookie::has(self::$admin_user_id) || SafeCookie::has(self::$admin_user_id_sign)) {
SafeCookie::delete(self::$admin_user_id);
SafeCookie::delete(self::$admin_user_id_sign);
}
return true;
}
/**
* 权限检查
* @param $user AdminUser
* @return bool
*/
public function authCheck($user)
{
return in_array($this->url, $this->authExcept, true) || in_array($this->url, $user->auth_url, true);
}
//登录记录
public static function loginLog($user)
{
$data = AdminLog::create([
'admin_user_id' => $user->id,
'name' => '登录',
'url' => 'admin/auth/login',
'log_method' => 'POST',
'log_ip' => request()->ip()
]);
$crypt_data = Crypt::encrypt(json_encode(request()->param()), config('app.app_key'));
$log_data = [
'data' => $crypt_data
];
$data->adminLogData()->save($log_data);
}
//创建操作日志
public function createAdminLog($user, $menu)
{
$data = [
'admin_user_id' => $user->id,
'name' => $menu->name,
'log_method' => $menu->log_method,
'url' => request()->pathinfo(),
'log_ip' => request()->ip()
];
$log = AdminLog::create($data);
//加密数据,防脱库
$crypt_data = Crypt::encrypt(json_encode(request()->param()), config('app.app_key'));
$log_data = [
'data' => $crypt_data
];
$log->adminLogData()->save($log_data);
}
}

View File

@ -0,0 +1,375 @@
<?php
/**
* 后台tree左侧菜单菜单列表权限操作相关
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\traits;
use app\admin\model\AdminUser;
trait AdminTree
{
public $text, $html;
/**
* 生成树型结构所需要的2维数组
* @var array
*/
public $array;
/**
* 生成树型结构所需修饰符号,可以换成图片
* @var array
*/
public $icon = array('│', '├', '└');
public $space = '&nbsp;&nbsp;';
/**
* @access private
*/
public $ret = '';
/**
* 构造函数,初始化类
* @param array $arr
* @return bool
*/
public function initTree($arr=[])
{
$this->array = $arr;
$this->ret = '';
$this->html = '';
return is_array($arr);
}
/**
* 得到树型结构
* @param int $my_id 表示获得这个ID下的所有子级
* @param string $str 生成树型结构的基本代码,例如:"<option value=\$id \$selected>\$spacer\$name</option>"
* @param int $sid 被选中的ID比如在做树型下拉框的时候需要用到
* @param string $adds
* @param string $str_group
* @return string
*/
public function getTree($my_id, $str, $sid = 0, $adds = '', $str_group = '')
{
$parent_id = '';
$n_str = '';
$number = 1;
$child = $this->getChild($my_id);
if (is_array($child)) {
$total = count($child);
foreach ($child as $id => $value) {
$j = $k = '';
if ($number == $total) {
$j .= $this->icon[2];
} else {
$j .= $this->icon[1];
$k = $adds ? $this->icon[0] : '';
}
$spacer = $adds ? $adds . $j : '';
$selected = $id == $sid ? 'selected' : '';
extract($value);
0 == $parent_id && $str_group ? eval("\$n_str = \"$str_group\";") : eval("\$n_str = \"$str\";");
$this->ret .= $n_str;
$space = $this->space;
$this->getTree($id, $str, $sid, $adds . $k . $space, $str_group);
$number++;
}
}
return $this->ret;
}
/**
* 获取后台左侧菜单
* @param $my_id
* @param $current_id
* @param $parent_ids
* @return mixed
*/
public function get_authTree($my_id, $current_id, $parent_ids)
{
$n_str = '';
$child = $this->getChild($my_id);
if (is_array($child)) {
$menu = current($child);
//获取当前等级的html
$text = $this->text[$menu['level']] ?? end($this->text);
foreach ($child as $k => $v) {
@extract($v);
//如果有下级菜单
if ($this->getChild($k)) {
if (in_array($k, $parent_ids, true)) {
//如果下级菜单是当前页面
eval("\$n_str = \"$text[1]\";");
$this->html .= $n_str;
} else {
//如果下级菜单不是当前页面
eval("\$n_str = \"$text[0]\";");
$this->html .= $n_str;
}
self::get_authTree($k, $current_id, $parent_ids);
eval("\$n_str = \"$text[2]\";");
$this->html .= $n_str;
} else if ($k == $current_id) {
$a = $this->text['current'];
eval("\$n_str = \"$a\";");
$this->html .= $n_str;
} else {
$a = $this->text['other'];
eval("\$n_str = \"$a\";");
$this->html .= $n_str;
}
}
}
return $this->html;
}
/**
* 得到子级数组
* @param int $pid
* @return bool|array
*/
public function getChild($pid)
{
$result = [];
foreach ($this->array as $key => $value) {
if ($value['parent_id'] == $pid) {
$result[$key] = $value;
}
}
return $result;
}
/**
* 递归获取级别
* @param int $id ID
* @param array $array 所有菜单
* @param int $i 所在级别
* @return int
*/
public function getLevel($id, $array, $i = 0)
{
if ($array[$id]['parent_id'] == 0 || empty($array[$array[$id]['parent_id']]) || $array[$id]['parent_id'] == $id) {
return $i;
}
$i++;
return self::getLevel($array[$id]['parent_id'], $array, $i);
}
//获取权限树
public function getAuthTreeAccess($my_id)
{
$id = '';
$n_str = '';
$child = $this->getChild($my_id);
if (is_array($child)) {
$level = current($child);
$text = $this->text[$level['level']] ?? end($this->text);
foreach ($child as $k => $v) {
@extract($v);
if ($this->getChild($k)) {
eval("\$n_str = \"$text[0]\";");
$this->html .= $n_str;
self::getAuthTreeAccess($k);
eval("\$n_str = \"$text[1]\";");
$this->html .= $n_str;
} else {
$a = $this->text['other'];
eval("\$n_str = \"$a\";");
$this->html .= $n_str;
}
}
}
return $this->html;
}
/**
* 获取左侧菜单
* @param $user AdminUser
* @return mixed
*/
protected function getLeftMenu($user)
{
$menu = $user->getShowMenu();
$max_level = 0;
$current_id = 1;
$parent_ids = array(0 => 0);
foreach ($menu as $k => $v) {
if ($v['url'] == $this->url) {
$parent_ids = $this->getMenuParent($menu, $v['id']);
$current_id = $v['id'];
}
}
if ($parent_ids == false) {
$parent_ids = array(0 => 0);
}
foreach ($menu as $k => $v) {
$url = url($v['url']);
$menu[$k]['icon'] = $v['icon'];
$menu[$k]['level'] = $this->getLevel($v['id'], $menu);
$max_level = $max_level <= $menu[$k]['level'] ? $menu[$k]['level'] : $max_level;
$menu[$k]['url'] = $url;
}
$this->initTree($menu);
$text_base_one = "<li class='treeview";
$text_hover = ' active';
$text_base_two = "'><a href='javascript:void(0);'>
<i class='fa \$icon'></i>
<span>
\$name
</span>
<span class='pull-right-container'><i class='fa fa-angle-left pull-right'></i></span>
</a><ul class='treeview-menu";
$text_open = ' menu-open';
$text_base_three = "'>";
$text_base_four = '<li';
$text_hover_li = " class='active'";
$text_base_five = ">
<a href='\$url'>
<i class='fa \$icon'></i>
<span>\$name</span>
</a>
</li>";
$text_0 = $text_base_one . $text_base_two . $text_base_three;
$text_1 = $text_base_one . $text_hover . $text_base_two . $text_open . $text_base_three;
$text_2 = '</ul></li>';
$text_current = $text_base_four . $text_hover_li . $text_base_five;
$text_other = $text_base_four . $text_base_five;
for ($i = 0; $i <= $max_level; $i++) {
$this->text[$i]['0'] = $text_0;
$this->text[$i]['1'] = $text_1;
$this->text[$i]['2'] = $text_2;
}
$this->text['current'] = $text_current;
$this->text['other'] = $text_other;
return $this->get_authTree(0, $current_id, $parent_ids);
}
//获取父级菜单
protected function getMenuParent($arr, $my_id, $parent_ids = array())
{
$a = array();
if (is_array($arr)) {
foreach ($arr as $id => $a) {
if (($a['id'] === $my_id) && $a['parent_id'] !== 0) {
$parent_ids[] = $a['parent_id'];
$parent_ids = $this->getMenuParent($arr, $a['parent_id'], $parent_ids);
}
}
}
return !empty($parent_ids) ? $parent_ids : false;
}
//获取当前导航
protected function getCurrentNav($arr, $my_id, $parent_ids = array(), $current_nav = '')
{
$a = array();
if (is_array($arr)) {
foreach ($arr as $id => $a) {
if (($a['id'] === $my_id) && $a['parent_id'] !== 0) {
$parent_ids[] = $a['parent_id'];
$ru = '<li><a><i class="fa ' . $a['icon'] . '"></i> ' . $a['name'] . '</a></li>';
$current_nav = $ru . $current_nav;
$temp_result = $this->getCurrentNav($arr, $a['parent_id'], $parent_ids, $current_nav);
$parent_ids = $temp_result[0];
$current_nav = $temp_result[1];
}
}
}
return !empty([$parent_ids, $current_nav]) ? [$parent_ids, $current_nav] : false;
}
/**
* 获取树形数据列表
* @param $model
* @return string
*/
protected function getTreeList($model)
{
$data = $model->column('id,name,parent_id', 'id');
foreach ($data as $key => $value) {
//左侧选择
$data[$key]['select_html'] = '<td>
<input type="checkbox" onclick="checkThis(this)" name="data-checkbox"
data-id="' . $value['id'] . '" class="checkbox data-list-check" value="' . $value['id'] . '"
placeholder="选择/取消">
</td>';
//右侧操作
$data[$key]['todo_html'] = '<td class="td-do">
<a href="' . url('edit', ['id' => $value['id']]) . '"
class="btn btn-primary btn-xs" title="修改" data-toggle="tooltip">
<i class="fa fa-pencil"></i>
</a>
<a class="btn btn-danger btn-xs AjaxButton" data-toggle="tooltip" title="删除"
data-id="' . $value['id'] . '" data-confirm-title="删除确认"
data-confirm-content=\'您确定要删除ID为 <span class="text-red">' . $value['id'] . '</span> 的数据吗\'
data-url="' . url('del') . '" >
<i class="fa fa-trash"></i>
</a>
</td>';
}
$this->initTree($data);
$html = "<tr>
\$select_html
<td>\$id</td>
<td>\$spacer \$name</td>
\$todo_html
</tr>";
return $this->getTree(0, $html);
}
/**
* 获取树形选择列表
* @param $model
* @param int $selected
* @return string
*/
protected function getSelectList($model, $selected = 0)
{
$data = $model->column('id,parent_id,name', 'id');
$html = "<option value='\$id' \$selected >\$spacer \$name</option>";
$this->initTree($data);
return $this->getTree(0, $html, $selected);
}
}

View File

@ -0,0 +1,12 @@
<?php
/**
* 登录验证码
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\traits;
class LoginCaptcha
{
}

View File

@ -0,0 +1,81 @@
<?php
/**
* phpOffice相关操作
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\traits;
use Exception;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
trait PhpOffice
{
public function exportData($head, $body, $name = '', $version = '2007',$title='导出记录')
{
try {
// 输出 Excel 文件头
if(empty($name)){
$name =date('Y-m-d-H-i-s');
}
$spreadsheet = new Spreadsheet();
$sheetPHPExcel = $spreadsheet->setActiveSheetIndex(0);
$char_index = range('A', 'Z');
//处理超过26列
$a = 'A';
foreach ($char_index as $item){
$char_index[] = $a . $item;
}
// Excel 表格头
foreach ($head as $key => $val) {
$sheetPHPExcel->setCellValue("{$char_index[$key]}1", $val);
}
$spreadsheet->getActiveSheet()->setTitle($title);
// Excel body 部分
foreach ($body as $key => $val) {
$row = $key + 2;
$col = 0;
foreach ($val as $k => $v) {
$spreadsheet->getActiveSheet()->setCellValue("{$char_index[$col]}{$row}", $v);
$col++;
}
}
// 版本差异信息
$version_opt = [
'2007' => [
'mime' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'ext' => '.xlsx',
'write_type' => 'Xlsx',
],
'2003' => ['mime' => 'application/vnd.ms-excel',
'ext' => '.xls',
'write_type' => 'Xls',
],
'pdf' => ['mime' => 'application/pdf',
'ext' => '.pdf',
'write_type' => 'PDF',
],
'ods' => ['mime' => 'application/vnd.oasis.opendocument.spreadsheet',
'ext' => '.ods',
'write_type' => 'OpenDocument',
],
];
header('Content-Type: ' . $version_opt[$version]['mime']);
header('Content-Disposition: attachment;filename="' . $name . $version_opt[$version]['ext'] . '"');
header('Cache-Control: max-age=0');
$objWriter = IOFactory::createWriter($spreadsheet, 'Xlsx');
return $objWriter->save('php://output');
} catch (Exception $e) {
return $e->getMessage();
}
}
}

View File

@ -0,0 +1,29 @@
<?php
/**
* 后台菜单证类
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\validate;
class AdminMenuValidate extends Validate
{
protected $rule = [
'parent_id|上级' => 'require|egt:0',
'name|名称' => 'require',
'url|url' => 'require|unique:admin_menu',
'icon|图标' => 'require',
'sort_id|排序' => 'require',
'is_show|是否显示' => 'require',
'log_method|记录类型' => 'require',
];
protected $message = [
'parent_id.egt' => '请选择上级菜单',
];
protected $scene = [
'add' => ['parent_id', 'title', 'url', 'icon', 'sort_id', 'is_show', 'log_method'],
'edit' => ['parent_id', 'title', 'url', 'icon', 'sort_id', 'is_show', 'log_method'],
];
}

View File

@ -0,0 +1,21 @@
<?php
/**
* 后台角色验证类
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\validate;
class AdminRoleValidate extends Validate
{
protected $rule = [
'name|名称' => 'require|unique:admin_role',
'description|介绍' => 'require',
'rules|权限' => 'require',
];
protected $scene = [
'add' => ['name', 'description'],
'edit' => ['name', 'description'],
];
}

View File

@ -0,0 +1,38 @@
<?php
/**
* 后台用户验类
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\validate;
class AdminUserValidate extends Validate
{
protected $rule = [
'username|帐号' => 'require|unique:admin_user',
'password|密码' => 'require',
'new_password|新密码' => 'require',
'renew_password|确认新密码' => 'require|confirm:new_password',
'nickname|昵称' => 'require',
'role|角色' => 'require',
'status|状态' => 'require',
];
protected $message = [
'role.require' => '请选择角色',
];
protected $scene = [
'add' => ['username', 'password', 'nickname', 'role'],
'edit' => ['username', 'nickname', 'role'],
'password' => ['password', 'new_password', 'renew_password'],
'nickname' => ['nickname'],
];
public function sceneLogin()
{
$this->only(['username', 'password'])
->remove('username', 'unique');
}
}

View File

@ -0,0 +1,12 @@
<?php
/**
* 后台基础验证类
* @author yupoxiong<i@yufuping.com>
*/
namespace app\admin\validate;
class Validate extends \think\Validate
{
}

View File

@ -0,0 +1,125 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body">
<form class="form-inline searchForm" id="searchForm" action="{:url('index')}" method="GET">
<div class="form-group">
<input value="{$_keywords ? $_keywords : '' ;}"
name="_keywords" id="_keywords" class="form-control input-sm" placeholder="操作/URL/IP">
</div>
<div class="form-group">
<select name="admin_user_id" id="admin_user_id" class="form-control input-sm">
<option value="">选择用户</option>
{foreach name='admin_user_list' id='item'}
<option value="{$item.id}"
{if isset($admin_user_id)&& $admin_user_id==$item.id}selected{/if}
>
{$item.nickname}[{$item.username}]
</option>
{/foreach}
</select>
</div>
<script>
$('#admin_user_id').select2();
</script>
<div class="form-group">
<input value="{$create_time_range ?? '' ;}"
name="create_time_range" id="create_time_range" class="form-control input-sm date-range" placeholder="日期">
</div>
<div class="form-group">
<button class="btn btn-sm btn-primary" type="submit"><i class="fa fa-search"></i> 查询
</button>
</div>
<div class="form-group">
<button onclick="clearSearchForm()" class="btn btn-sm btn-default" type="button"><i
class="fa fa-eraser"></i> 清空
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body table-responsive">
<table class="table table-hover table-bordered datatable" width="100%">
<thead>
<tr>
<th>ID</th>
<th>用户</th>
<th>操作</th>
<th>URL</th>
<th>请求方式</th>
<th>IP</th>
<th>日期</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{foreach name='data' item='list'}
<tr>
<td>{$list.id}</td>
<td>{$list->adminUser->nickname}</td>
<td>{$list.name}</td>
<td>{$list.url}</td>
<td>{$list.log_method}</td>
<td>{$list.log_ip}</td>
<td>{$list.create_time}</td>
<td class="td-do">
<a data-id="{$list.id}" data-url="view" data-confirm="2" data-type="2"
class="btn btn-default btn-xs AjaxButton" title="查看详情" data-toggle="tooltip">
<i class="fa fa-eye"></i>
</a>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<!-- 数据列表底部 -->
<div class="box-footer">
{$page|raw}
<label class="control-label pull-right" style="margin-right: 10px; font-weight: 100;">
<small>共{$total}条记录</small>&nbsp;
<small>每页显示</small>
&nbsp;
<select class="input-sm" onchange="changePerPage(this)">
<option value="10" {if $admin.per_page==10}selected{/if}>10</option>
<option value="20" {if $admin.per_page==20}selected{/if}>20</option>
<option value="30" {if $admin.per_page==30}selected{/if}>30</option>
<option value="50" {if $admin.per_page==50}selected{/if}>50</option>
<option value="100" {if $admin.per_page==100}selected{/if}>100</option>
</select>
&nbsp;
<small>条记录</small>
</label>
</div>
</div>
</div>
</div>
</section>
<script>
laydate.render({
elem: '.date-range'
,range: true
,type:'datetime'
});
</script>
{/block}

View File

@ -0,0 +1,53 @@
{include file='public/head_css'}
{include file='public/head_js'}
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body table-responsive no-padding">
<table class="table table-bordered table-striped">
<tbody>
<tr>
<th colspan="4" class="text-bold text-center">日志摘要</th>
</tr>
<tr>
<td class="text-bold">日志ID</td>
<td>{$data.id}</td>
</tr>
<tr>
<td class="text-bold">操作用户</td>
<td>{$data->adminUser->nickname}</td>
</tr>
<tr>
<td class="text-bold">操作</td>
<td>{$data.name}</td>
</tr>
<tr>
<td class="text-bold">url</td>
<td>{$data.url}</td>
</tr>
<tr>
<td class="text-bold">类型</td>
<td>{$data.log_method}</td>
</tr>
<tr>
<td class="text-bold">ip</td>
<td>{$data.log_ip}</td>
</tr>
<tr>
<td class="text-bold">日期</td>
<td>{$data.create_time}</td>
</tr>
<tr style="border-top:2px solid #d2d6de;">
<th colspan="2" class="text-bold text-center">数据详情</th>
</tr>
<tr>
<td colspan="2" >
<pre>{$data.adminLogData.data}</pre>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,213 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
<!-- 表单头部 -->
<div class="box-header with-border">
<div class="btn-group">
<a class="btn flat btn-sm btn-default BackButton">
<i class="fa fa-arrow-left"></i>
返回
</a>
</div>
</div>
<form id="dataForm" class="dataForm form-horizontal" action="" method="post"
enctype="multipart/form-data">
<div class="box-body">
<div class="fields-group">
<div class="form-group">
<label for="parent_id" class="col-sm-2 control-label">上级菜单</label>
<div class="col-sm-10 col-md-4">
<select name="parent_id" id="parent_id" class="form-control select2">
<option value="0">/</option>
{$parents|raw}
</select>
</div>
</div>
<script>
$('#parent_id').select2();
</script>
<div class="form-group">
<label for="name" class="col-sm-2 control-label">名称</label>
<div class="col-sm-10 col-md-4">
<input maxlength="50" id="name" name="name" value="{$data.name|default=''}"
class="form-control" placeholder="请输入菜单名称">
</div>
</div>
<div class="form-group">
<label for="url" class="col-sm-2 control-label">url</label>
<div class="col-sm-10 col-md-4">
<input maxlength="100" id="url" name="url" value="{$data.url|default=''}"
class="form-control" placeholder="菜单url">
</div>
</div>
<div class="form-group">
<label for="icon" class="col-sm-2 control-label">图标</label>
<div class="col-sm-10 col-md-4">
<div class="input-group iconpicker-container">
<span class="input-group-addon"><i class="fa fa-pencil"></i></span>
<input maxlength="30" id="icon" name="icon"
value="{$data.icon|default='fa-list'}" class="form-control "
placeholder="请输入图标class">
</div>
</div>
</div>
<script>
$('#icon').iconpicker({placement: 'bottomLeft'});
</script>
<div class="form-group">
<label for="sort_id" class="col-sm-2 control-label">排序</label>
<div class="col-sm-10 col-md-4">
<div class="input-group">
<input max="9999" min="1" type="number" id="sort_id" name="sort_id"
value="{$data.sort_id|default='1000'}"
class="form-control input-number field-number" placeholder="默认1000">
</div>
</div>
</div>
<script>
$('#sort_id')
.bootstrapNumber({
upClass: 'success',
downClass: 'primary',
center: true
});
</script>
<div class="form-group">
<label for="is_show" class="col-sm-2 control-label">是否显示</label>
<div class="col-sm-10 col-md-4">
<input class="input-switch" id="is_show" value="1"
{if !isset($data) || ($data.is_show==1)}checked{/if} type="checkbox"/>
<input class="switch" name="is_show" value="{$data.is_show|default='1'}"
placeholder="" hidden/>
</div>
</div>
<script>
$('#is_show').bootstrapSwitch({
onText: "是",
offText: "否",
onColor: "success",
offColor: "danger",
onSwitchChange: function (event, state) {
$(event.target).closest('.bootstrap-switch').next().val(state ? '1' : '0').change();
}
});
</script>
<div class="form-group">
<label for="log_method" class="col-sm-2 control-label">日志请求方式</label>
<div class="col-sm-10 col-md-4">
<select name="log_method" id="log_method" class="form-control select2">
{foreach name='log_method' item='item'}
<option value="{$item}" {if isset($data) && $data.log_method==$item}selected{/if}>
{$item}
</option>
{/foreach}
</select>
</div>
</div>
<script>
$('#log_method').select2();
</script>
{if !isset($data)}
<div class="form-group">
<label for="is_more" class="col-sm-2 control-label">是否自动生成增删改菜单</label>
<div class="col-sm-10 col-md-4">
<input id="is_more" class="input-switch" placeholder="" type="checkbox"/>
<input class="switch" name="is_more" value="0" hidden/>
</div>
</div>
<script>
$('#is_more').bootstrapSwitch({
onText: "是",
offText: "否",
onColor: "success",
offColor: "danger",
onSwitchChange: function (event, state) {
$(event.target).closest('.bootstrap-switch').next().val(state ? '1' : '0').change();
}
});
</script>
<div class="form-group">
<label for="more_name" class="col-sm-2 control-label">增删改操作名称</label>
<div class="col-sm-10 col-md-4">
<input maxlength="50" id="more_name" name="more_name"
value="{$data.more_name|default=''}" class="form-control"
placeholder="请输入操作名称">
</div>
</div>
{/if}
</div>
</div>
<!--表单底部-->
<div class="box-footer">
{:token()}
<div class="col-sm-2">
</div>
<div class="col-sm-10 col-md-4">
{if !isset($data)}
<div class="btn-group pull-right">
<label class="createContinue">
<input type="checkbox" value="1" id="_create" name="_create"
title="继续添加数据">继续添加</label>
</div>
{/if}
<div class="btn-group">
<button type="submit" class="btn flat btn-info dataFormSubmit">
保存
</button>
</div>
<div class="btn-group">
<button type="reset" class="btn flat btn-default dataFormReset">
重置
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<script>
$("#dataForm").validate({
rules: {
name: {
required: true,
},
url: {
required: true
},
icon: {
required: true
},
sort_id: {
required: true
}
},
messages: {
name: {
required: "名称不能为空",
},
url: {
required: "url不能为空",
},
icon: {
required: "图标不能为空",
},
sort_id: {
required: "排序不能为空",
},
},
});
</script>
{/block}

View File

@ -0,0 +1,51 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box">
<!--列表头部-->
<div class="box-header">
<div>
<a title="添加" data-toggle="tooltip" class="btn btn-primary btn-sm " href="{:url('add')}">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-danger btn-sm AjaxButton" data-toggle="tooltip" title="删除选中数据" data-confirm-title="删除确认" data-confirm-content="您确定要删除选中的数据吗?" data-id="checked" data-url="{:url('del')}">
<i class="fa fa-trash"></i> 删除
</a>
<a class="btn btn-success btn-sm ReloadButton" data-toggle="tooltip" title="刷新" data-id="checked" data-url="{:url('del')}">
<i class="fa fa-refresh"></i> 刷新
</a>
</div>
</div>
<!--数据内容-->
<div class="box-body table-responsive">
<table class="table table-hover table-bordered datatable" width="100%">
<thead>
<tr>
<th>
<input id="dataCheckAll" type="checkbox" onclick="checkAll(this)" class="checkbox" placeholder="全选/取消">
</th>
<th>ID</th>
<th>菜单名称</th>
<th>url</th>
<th>父级ID</th>
<th>图标</th>
<th>排序</th>
<th>状态</th>
<th>日志记录方式</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{$data|raw}
</tbody>
</table>
</div>
</div>
</div>
</div>
</section>
{/block}

View File

@ -0,0 +1,137 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
{css href="__ADMIN_CSS__/access.css" /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
<!-- 表单头部 -->
<div class="box-header with-border">
<div class="btn-group">
<a class="btn flat btn-sm btn-default BackButton">
<i class="fa fa-arrow-left"></i>
返回
</a>
</div>
</div>
<div class="box-header with-border">
<h3 class="box-title">【{$data->name|raw}】授权</h3>
<label class="checkbox" for="check_all">
<input class="checkbox-inline" type="checkbox" name="check_all" id="check_all">全选
</label>
</div>
<div class="box-body" id="all_check">
<form id="dataForm" class="form-horizontal dataForm" action="" method="post" enctype="multipart/form-data">
<div class="box-body">
<div class="table_full">
<table width="100%" cellspacing="0">
<tbody>
{$html|raw}
</tbody>
</table>
</div>
</div>
<!--表单底部-->
<div class="box-footer">
{:token()}
<div class="col-sm-2">
</div>
<div class="col-sm-10 col-md-4">
<div class="btn-group">
<button type="submit" class="btn flat btn-info dataFormSubmit">
保存
</button>
</div>
<div class="btn-group">
<button type="reset" class="btn flat btn-default dataFormReset">
重置
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<script>
$("#check_all").click(function(){
if(this.checked){
$("#all_check").find(":checkbox").prop("checked", true);
}else{
$("#all_check").find(":checkbox").prop("checked", false);
}
});
function checkNode(obj) {
var level_bottom;
var chk = $("input[type='checkbox']");
var count = chk.length;
var num = chk.index(obj);
var level_top = level_bottom = chk.eq(num).attr('level');
for (var i = num; i >= 0; i--) {
var le = chk.eq(i).attr('level');
if (eval(le) < eval(level_top)) {
chk.eq(i).prop("checked", true);
level_top = level_top - 1;
}
}
for (var j = num + 1; j < count; j++) {
le = chk.eq(j).attr('level');
if (chk.eq(num).prop("checked")) {
if (eval(le) > eval(level_bottom)) {
chk.eq(j).prop("checked", true);
}
else if (eval(le) == eval(level_bottom)) {
break;
}
} else {
if (eval(le) > eval(level_bottom)) {
chk.eq(j).prop("checked", false);
} else if (eval(le) == eval(level_bottom)) {
break;
}
}
}
var all_length = $("input[name='menu_id[]']").length;
var checked_length = $("input[name='menu_id[]']:checked").length;
console.log(all_length);
console.log(checked_length);
if(all_length==checked_length){
$("#check_all").prop("checked",true);
}else{
$("#check_all").prop("checked",false);
}
}
</script>
</div>
</section>
<script>
$("#dataForm").validate({
rules: {
'url[]': {
required: true
}
},
messages: {
'url[]': {
required: "请选择权限",
},
},
});
</script>
{/block}

View File

@ -0,0 +1,112 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
<!-- 表单头部 -->
<div class="box-header with-border">
<div class="btn-group">
<a class="btn flat btn-sm btn-default BackButton">
<i class="fa fa-arrow-left"></i>
返回
</a>
</div>
</div>
<form id="dataForm" class="form-horizontal dataForm" action="" method="post"
enctype="multipart/form-data">
<div class="box-body">
<div class="form-group">
<label for="name" class="col-sm-2 control-label">名称</label>
<div class="col-sm-10 col-md-4">
<input maxlength="50" id="name" name="name" value="{$data.name|default=''}"
class="form-control" placeholder="请输入名称">
</div>
</div>
<div class="form-group">
<label for="description" class="col-sm-2 control-label">简介</label>
<div class="col-sm-10 col-md-4">
<input maxlength="50" id="description" name="description"
value="{$data.description|default=''}" class="form-control" placeholder="请输入简介">
</div>
</div>
<div class="form-group">
<label for="status" class="col-sm-2 control-label">启用状态</label>
<div class="col-sm-10 col-md-4">
<input class="input-switch" id="status" value="1" {if(!isset($data) ||$data.status==1)}checked{/if} type="checkbox" />
<input class="switch field-switch" placeholder="启用状态" name="status" value="{$data.status|default='1'}" hidden />
</div>
</div>
<script>
$('#status').bootstrapSwitch({
onText: "是",
offText: "否",
onColor: "success",
offColor: "danger",
onSwitchChange: function (event, state) {
$(event.target).closest('.bootstrap-switch').next().val(state ? '1' : '0').change();
}
});
</script>
</div>
<!--表单底部-->
<div class="box-footer">
{:token()}
<div class="col-sm-2">
</div>
<div class="col-sm-10 col-md-4">
{if !isset($data)}
<div class="btn-group pull-right">
<label class="createContinue">
<input type="checkbox" value="1" id="_create" name="_create"
title="继续添加数据">继续添加</label>
</div>
{/if}
<div class="btn-group">
<button type="submit" class="btn flat btn-info dataFormSubmit">
保存
</button>
</div>
<div class="btn-group">
<button type="reset" class="btn flat btn-default dataFormReset">
重置
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<script>
$("#dataForm").validate({
rules: {
name: {
required: true,
},
description: {
required: true
}
},
messages: {
name: {
required: "名称不能为空",
},
description: {
required: "简介不能为空",
}
},
});
</script>
{/block}

View File

@ -0,0 +1,153 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body">
<form class="form-inline searchForm" id="searchForm" action="{:url('index')}" method="GET">
<div class="form-group">
<input value="{$_keywords ? $_keywords : '' ;}"
name="_keywords" id="_keywords" class="form-control input-sm" placeholder="名称/简介">
</div>
<div class="form-group">
<button class="btn btn-sm btn-primary" type="submit"><i class="fa fa-search"></i> 查询
</button>
</div>
<div class="form-group">
<button onclick="clearSearchForm()" class="btn btn-sm btn-default" type="button"><i
class="fa fa-eraser"></i> 清空查询
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="box">
<!--数据列表顶部-->
<div class="box-header">
<div>
<a title="添加" data-toggle="tooltip" class="btn btn-primary btn-sm " href="{:url('add')}">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-danger btn-sm AjaxButton" data-toggle="tooltip" title="删除选中数据"
data-confirm-title="删除确认" data-confirm-content="您确定要删除选中的数据吗?" data-id="checked"
data-url="{:url('del')}">
<i class="fa fa-trash"></i> 删除
</a>
<a class="btn btn-success btn-sm AjaxButton" data-toggle="tooltip" title="启用选中数据"
data-confirm-title="启用确认" data-confirm-content="您确定要启用选中的数据吗?" data-id="checked"
data-url="{:url('enable')}">
<i class="fa fa-circle"></i> 启用
</a>
<a class="btn btn-warning btn-sm AjaxButton" data-toggle="tooltip" title="禁用选中数据"
data-confirm-title="禁用确认" data-confirm-content="您确定要禁用选中的数据吗?" data-id="checked"
data-url="{:url('disable')}">
<i class="fa fa-circle"></i> 禁用
</a>
<a class="btn btn-success btn-sm ReloadButton" data-toggle="tooltip" title="刷新"
data-id="checked" data-url="{:url('del')}">
<i class="fa fa-refresh"></i> 刷新
</a>
</div>
</div>
<div class="box-body table-responsive">
<table class="table table-hover table-bordered datatable" width="100%">
<thead>
<tr>
<th>
<input id="dataCheckAll" type="checkbox" onclick="checkAll(this)" class="checkbox"
placeholder="全选/取消">
</th>
<th>ID</th>
<th>名称</th>
<th>简介</th>
<th>是否启用</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{foreach name="data" item="item"}
<tr>
<td>
<input type="checkbox" onclick="checkThis(this)" name="data-checkbox"
data-id="{$item.id}" class="checkbox data-list-check" value="{$item.id}"
placeholder="选择/取消">
</td>
<td>{$item.id}</td>
<td>{$item.name}</td>
<td>{$item.description}</td>
<td>{$item.status_text}</td>
<td class="td-do">
<a href="{:url('admin_role/access',['id'=>$item.id])}"
class="btn btn-warning btn-xs" data-toggle="tooltip" title="授权">
<i class="fa fa-key"></i>
</a>
<a href="{:url('admin_role/edit',['id'=>$item.id])}"
class="btn btn-primary btn-xs" title="修改" data-toggle="tooltip">
<i class="fa fa-pencil"></i>
</a>
<a class="btn btn-danger btn-xs AjaxButton" data-toggle="tooltip" title="删除"
data-id="{$item.id}" data-confirm-title="删除确认"
data-confirm-content='您确定要删除ID为 <span class="text-red">{$item.id}</span> 的数据吗'
data-url="{:url('del')}">
<i class="fa fa-trash"></i>
</a>
{if $item.status==1}
<a class="btn btn-warning btn-xs AjaxButton" data-toggle="tooltip" title="禁用"
data-id="{$item.id}" data-confirm-title="禁用确认"
data-confirm-content='您确定要禁用ID为 <span class="text-red">{$item.id}</span> 的数据吗'
data-url="{:url('disable')}">
<i class="fa fa-circle"></i>
</a>
{else/}
<a class="btn btn-success btn-xs AjaxButton" data-toggle="tooltip" title="启用"
data-id="{$item.id}" data-confirm-title="启用确认"
data-confirm-content='您确定要启用ID为 <span class="text-red">{$item.id}</span> 的数据吗'
data-url="{:url('enable')}">
<i class="fa fa-circle"></i>
</a>
{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<!-- 数据列表底部 -->
<div class="box-footer">
{$page|raw}
<label class="control-label pull-right" style="margin-right: 10px; font-weight: 100;">
<small>共{$total}条记录</small>&nbsp;
<small>每页显示</small>
&nbsp;
<select class="input-sm" onchange="changePerPage(this)">
<option value="10" {if $admin.per_page==10}selected{/if}>10</option>
<option value="20" {if $admin.per_page==20}selected{/if}>20</option>
<option value="30" {if $admin.per_page==30}selected{/if}>30</option>
<option value="50" {if $admin.per_page==50}selected{/if}>50</option>
<option value="100" {if $admin.per_page==100}selected{/if}>100</option>
</select>
&nbsp;
<small>条记录</small>
</label>
</div>
</div>
</div>
</div>
</section>
{/block}

View File

@ -0,0 +1,155 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
<!-- 表单头部 -->
<div class="box-header with-border">
<div class="btn-group">
<a class="btn flat btn-sm btn-default BackButton">
<i class="fa fa-arrow-left"></i>
返回
</a>
</div>
</div>
<form id="dataForm" class="form-horizontal dataForm" action="" method="post"
enctype="multipart/form-data">
<div class="box-body">
<div class="form-group">
<label for="role" class="col-sm-2 control-label">角色</label>
<div class="col-sm-10 col-md-4">
<select name="role[]" id="role" class="form-control field-multi-select"
multiple="multiple">
{foreach name='role' item='item'}
<option value="{$item.id}" {if isset($data) && in_array($item.id,$data.role)}selected{/if}>
{$item.name}
</option>
{/foreach}
</select>
</div>
</div>
<script>
$('#role').select2();
</script>
<div class="form-group">
<label for="nickname" class="col-sm-2 control-label">昵称</label>
<div class="col-sm-10 col-md-4">
<input maxlength="50" id="nickname" name="nickname" value="{$data.nickname|default=''}"
class="form-control" placeholder="请输入昵称">
</div>
</div>
<div class="form-group">
<label for="username" class="col-sm-2 control-label">账号</label>
<div class="col-sm-10 col-md-4">
<input maxlength="50" id="username" autocomplete="off" name="username"
value="{$data.username|default=''}" class="form-control" placeholder="请输入账号">
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-2 control-label">密码</label>
<div class="col-sm-10 col-md-4">
<input maxlength="255" id="password" autocomplete="off" type="password" name="password"
value="{$data.password|default=''}" class="form-control" placeholder="请输入密码">
</div>
</div>
<div class="form-group">
<label for="status" class="col-sm-2 control-label">启用状态</label>
<div class="col-sm-10 col-md-4">
<input class="input-switch" id="status" value="1" {if(!isset($data)
||$data.status==1)}checked{/if} type="checkbox"/>
<input class="switch field-switch" name="status" value="{$data.status|default='1'}"
hidden/>
</div>
</div>
<script>
$('#status').bootstrapSwitch({
onText: "是",
offText: "否",
onColor: "success",
offColor: "danger",
onSwitchChange: function (event, state) {
$(event.target).closest('.bootstrap-switch').next().val(state ? '1' : '0').change();
}
});
</script>
</div>
<!--表单底部-->
<div class="box-footer">
{:token()}
<div class="col-sm-2">
</div>
<div class="col-sm-10 col-md-4">
{if !isset($data)}
<div class="btn-group pull-right">
<label class="createContinue">
<input type="checkbox" value="1" id="_create" name="_create"
title="继续添加数据">继续添加</label>
</div>
{/if}
<div class="btn-group">
<button type="submit" class="btn flat btn-info dataFormSubmit">
保存
</button>
</div>
<div class="btn-group">
<button type="reset" class="btn flat btn-default dataFormReset">
重置
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<script>
$("#dataForm").validate({
rules: {
nickname: {
required: true,
minlength: 2
},
username: {
required: true,
minlength: 2
},
password: {
required: true,
minlength: 6
},
},
messages: {
nickname: {
required: "请输入昵称",
minlength: "名称长度不能小于2"
},
username: {
required: "请输入账号",
minlength: "用户名长度不能小于2"
},
password: {
required: "请输入密码",
minlength: "密码长度不能小于6"
},
},
});
</script>
{/block}

View File

@ -0,0 +1,148 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body">
<form class="form-inline searchForm" id="searchForm" action="{:url('index')}" method="GET">
<div class="form-group">
<input value="{$_keywords ? $_keywords : '' ;}"
name="_keywords" id="_keywords" class="form-control input-sm" placeholder="昵称/账号">
</div>
<div class="form-group">
<button class="btn btn-sm btn-primary" type="submit"><i class="fa fa-search"></i> 查询
</button>
</div>
<div class="form-group">
<button onclick="clearSearchForm()" class="btn btn-sm btn-default" type="button"><i
class="fa fa-eraser"></i> 清空查询
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="box">
<!--数据列表顶部-->
<div class="box-header">
<div>
<a title="添加" data-toggle="tooltip" class="btn btn-primary btn-sm " href="{:url('add')}">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-danger btn-sm AjaxButton" data-toggle="tooltip" title="删除选中数据" data-confirm-title="删除确认" data-confirm-content="您确定要删除选中的数据吗?" data-id="checked" data-url="{:url('del')}">
<i class="fa fa-trash"></i> 删除
</a>
<a class="btn btn-success btn-sm AjaxButton" data-toggle="tooltip" title="启用选中数据"
data-confirm-title="启用确认" data-confirm-content="您确定要启用选中的数据吗?" data-id="checked"
data-url="{:url('enable')}">
<i class="fa fa-circle"></i> 启用
</a>
<a class="btn btn-warning btn-sm AjaxButton" data-toggle="tooltip" title="禁用选中数据"
data-confirm-title="禁用确认" data-confirm-content="您确定要禁用选中的数据吗?" data-id="checked"
data-url="{:url('disable')}">
<i class="fa fa-circle"></i> 禁用
</a>
<a class="btn btn-success btn-sm ReloadButton" data-toggle="tooltip" title="刷新" data-id="checked" data-url="{:url('del')}">
<i class="fa fa-refresh"></i> 刷新
</a>
</div>
</div>
<div class="box-body table-responsive">
<table class="table table-hover table-bordered datatable" width="100%">
<thead>
<tr>
<th>
<input id="dataCheckAll" type="checkbox" onclick="checkAll(this)" class="checkbox" placeholder="全选/取消">
</th>
<th>ID</th>
<th>昵称</th>
<th>账号</th>
<th>角色</th>
<th>是否启用</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{foreach name="data" item="item"}
<tr>
<td>
<input type="checkbox" onclick="checkThis(this)" name="data-checkbox"
data-id="{$item.id}" class="checkbox data-list-check" value="{$item.id}"
placeholder="选择/取消">
</td>
<td>{$item.id}</td>
<td>{$item.nickname}</td>
<td>{$item.username}</td>
<td>
{foreach name='item.role_text' id='role'}
<small class="label bg-blue">{$role}</small>
{/foreach}
</td>
<td>{$item.status_text}</td>
<td class="td-do">
<a href="{:url('admin_user/edit',['id'=>$item.id])}"
class="btn btn-primary btn-xs" title="修改" data-toggle="tooltip">
<i class="fa fa-pencil"></i>
</a>
<a class="btn btn-danger btn-xs AjaxButton" data-toggle="tooltip" title="删除" data-id="{$item.id}" data-confirm-title="删除确认" data-confirm-content='您确定要删除ID为 <span class="text-red">{$item.id}</span> 的数据吗' data-url="{:url('del')}">
<i class="fa fa-trash"></i>
</a>
{if $item.status==1}
<a class="btn btn-warning btn-xs AjaxButton" data-toggle="tooltip" title="禁用"
data-id="{$item.id}" data-confirm-title="禁用确认"
data-confirm-content='您确定要禁用ID为 <span class="text-red">{$item.id}</span> 的数据吗'
data-url="{:url('disable')}">
<i class="fa fa-circle"></i>
</a>
{else/}
<a class="btn btn-success btn-xs AjaxButton" data-toggle="tooltip" title="启用"
data-id="{$item.id}" data-confirm-title="启用确认"
data-confirm-content='您确定要启用ID为 <span class="text-red">{$item.id}</span> 的数据吗'
data-url="{:url('enable')}">
<i class="fa fa-circle"></i>
</a>
{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<!-- 数据列表底部 -->
<div class="box-footer">
{$page|raw}
<label class="control-label pull-right" style="margin-right: 10px; font-weight: 100;">
<small>共{$total}条记录</small>&nbsp;
<small>每页显示</small>
&nbsp;
<select class="input-sm" onchange="changePerPage(this)">
<option value="10" {if $admin.per_page==10}selected{/if}>10</option>
<option value="20" {if $admin.per_page==20}selected{/if}>20</option>
<option value="30" {if $admin.per_page==30}selected{/if}>30</option>
<option value="50" {if $admin.per_page==50}selected{/if}>50</option>
<option value="100" {if $admin.per_page==100}selected{/if}>100</option>
</select>
&nbsp;
<small>条记录</small>
</label>
</div>
</div>
</div>
</div>
</section>
{/block}

View File

@ -0,0 +1,168 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-3">
<div class="box box-primary">
<div class="box-body box-profile">
<img class="profile-user-img img-responsive img-circle" src="{$admin.user.avatar}" alt="头像">
<h3 class="profile-username text-center">{$admin.user.nickname}</h3>
<p class="text-muted text-center">{$admin.user.username}</p>
<p>
{foreach name='admin.user.role_text' id='role'}
<small class="label bg-blue">{$role}</small>
{/foreach}
</p>
</div>
</div>
</div>
<div class="col-md-9">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li class="active"><a href="#profile" data-toggle="tab" aria-expanded="true">个人信息</a></li>
<li class=""><a href="#privacy" data-toggle="tab" aria-expanded="false">修改密码</a></li>
<li class=""><a href="#avatars" data-toggle="tab" aria-expanded="false">修改头像</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="profile">
<form class="dataForm form-horizontal" id="dataForm1" action="" method="post">
<input type="hidden" value="profile" name="update_type" placeholder="请勿修改">
<div class="form-group">
<label for="nickname" class="col-sm-2 control-label">昵称</label>
<div class="col-sm-10 col-md-4">
<input class="form-control" value="{$admin.user.nickname}" name="nickname"
id="nickname" maxlength="30"
placeholder="请输入昵称">
</div>
</div>
{:token()}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-danger">保存</button>
</div>
</div>
</form>
</div>
<div class="tab-pane" id="privacy">
<form class="dataForm form-horizontal" id="dataForm2" action="" method="post">
<input type="hidden" value="password" name="update_type" placeholder="请勿修改">
<div class="form-group">
<label for="password" class="col-sm-2 control-label">当前密码</label>
<div class="col-sm-10 col-md-4">
<input type="password" autocomplete='password' class="form-control" name="password" id="password"
placeholder="请输入当前密码">
</div>
</div>
<div class="form-group">
<label for="new_password" class="col-sm-2 control-label">新密码</label>
<div class="col-sm-10 col-md-4">
<input type="password" class="form-control" autocomplete='off' name="new_password" id="new_password"
placeholder="请输入新密码">
</div>
</div>
<div class="form-group">
<label for="renew_password" class="col-sm-2 control-label">确认新密码</label>
<div class="col-sm-10 col-md-4">
<input type="password" class="form-control" autocomplete='off' name="renew_password" id="renew_password"
placeholder="再次输入新密码">
</div>
</div>
{:token()}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-danger">保存</button>
</div>
</div>
</form>
</div>
<div class="tab-pane" id="avatars">
<form class="dataForm form-horizontal" id="dataForm3" action="" method="post" enctype="multipart/form-data">
<input type="hidden" value="avatar" name="update_type" placeholder="请勿淘气修改">
<div class="form-group">
<label for="avatar" class="col-sm-2 control-label">头像</label>
<div class="col-sm-10 col-md-4">
<input type="file" class="form-control" name="avatar" id="avatar"
placeholder="头像可空">
</div>
</div>
{:token()}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-danger">保存</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
<script>
$("#dataForm1").validate({
rules: {
nickname: {
required: true,
minlength: 2,
maxlength: 10
}
},
messages: {
nickname: {
required: "请输入昵称",
minlength: "昵称长度不能小于2",
maxlength: "昵称长度不能大于10"
}
}
});
$("#dataForm2").validate({
rules: {
password: {
required: true,
minlength: 6
},
new_password: {
required: true,
minlength: 6
},
renew_password: {
required: true,
minlength: 6
}
},
messages: {
password: {
required: "请输入当前密码",
minlength: "当前密码长度不能小于6"
},
new_password: {
required: "请输入新密码",
minlength: "新密码长度不能小于6"
},
renew_password: {
required: "请输入确认新密码",
minlength: "确认新密码长度不能小于6"
}
}
});
$("#dataForm3").validate({
rules: {
avatar: {
required: true
}
},
messages: {
avatar: {
required: "请选择文件"
}
}
});
</script>
{/block}

View File

@ -0,0 +1,243 @@
{extend name='public/base' /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
<!-- 表单头部 -->
<div class="box-header with-border">
<div class="btn-group">
<a class="btn flat btn-sm btn-default BackButton">
<i class="fa fa-arrow-left"></i>
返回
</a>
</div>
</div>
<!-- 表单 -->
<form id="dataForm" class="form-horizontal dataForm" action="" method="post" enctype="multipart/form-data">
<!-- 表单字段区域 -->
<div class="box-body">
<div class="form-group">
<label for="name" class="col-sm-2 control-label">标题</label>
<div class="col-sm-10 col-md-4">
<input id="name" name="name" value="{$data.name|default=''}" placeholder="请输入标题" type="text" class="form-control field-text">
</div>
</div>
<div class="form-group">
<label for="user_id" class="col-sm-2 control-label">发布人</label>
<div class="col-sm-10 col-md-4">
<select name="user_id" id="user_id" class="form-control field-select" data-placeholder="请选择发布人">
<option value=""></option>
</select>
</div>
</div>
<script>
$('#user_id').select2();
</script>
<div class="form-group">
<label for="article_category_id" class="col-sm-2 control-label">所属分类</label>
<div class="col-sm-10 col-md-4">
<select name="article_category_id" id="article_category_id" class="form-control field-select" data-placeholder="请选择所属分类">
<option value=""></option>
</select>
</div>
</div>
<script>
$('#article_category_id').select2();
</script>
<div class="form-group">
<label for="description" class="col-sm-2 control-label">简介</label>
<div class="col-sm-10 col-md-4">
<input id="description" name="description" value="{$data.description|default=''}" placeholder="请输入简介" type="text" class="form-control field-text">
</div>
</div>
<div class="form-group">
<label for="content" class="col-sm-2 control-label">内容</label>
<div class="col-sm-10">
<script id="content" name="content" type="text/plain">{$data.content|raw|default=''}</script>
</div>
</div>
<script>
UE.delEditor('content');
var UE_content = UE.getEditor('content',{
serverUrl :UEServer
});
</script>
<div class="form-group">
<label for="is_top" class="col-sm-2 control-label">是否置顶</label>
<div class="col-sm-10 col-md-4">
<input class="input-switch" id="is_top" value="1" {if(!isset($data) ||$data.is_top==1)}checked{/if} type="checkbox" />
<input class="switch field-switch" placeholder="是否置顶" name="is_top" value="{$data.is_top|default='1'}" hidden />
</div>
</div>
<script>
$('#is_top').bootstrapSwitch({
onText: "是",
offText: "否",
onColor: "success",
offColor: "danger",
onSwitchChange: function (event, state) {
$(event.target).closest('.bootstrap-switch').next().val(state ? '1' : '0').change();
}
});
</script><div class="form-group">
<label for="is_hot" class="col-sm-2 control-label">是否热门</label>
<div class="col-sm-10 col-md-4">
<input class="input-switch" id="is_hot" value="1" {if(!isset($data) ||$data.is_hot==1)}checked{/if} type="checkbox" />
<input class="switch field-switch" placeholder="是否热门" name="is_hot" value="{$data.is_hot|default='1'}" hidden />
</div>
</div>
<script>
$('#is_hot').bootstrapSwitch({
onText: "是",
offText: "否",
onColor: "success",
offColor: "danger",
onSwitchChange: function (event, state) {
$(event.target).closest('.bootstrap-switch').next().val(state ? '1' : '0').change();
}
});
</script> <div class="form-group">
<label for="img" class="col-sm-2 control-label">缩略图</label>
<div class="col-sm-10 col-md-4">
<input id="img" name="img" placeholder="请上传缩略图" {if isset($data.img)}data-initial-preview="{$data.img}"{/if} type="file" class="form-control field-image" >
</div>
</div>
<script>
$('#img').fileinput({
language: 'zh',
overwriteInitial: true,
browseLabel: '浏览',
initialPreviewAsData: true,
dropZoneEnabled: false,
showUpload:false,
showRemove: false,
allowedFileTypes:['image'],
maxFileSize:10240,
});
</script>
<div class="form-group">
<label for="sort_number" class="col-sm-2 control-label">排序</label>
<div class="col-sm-10 col-md-4">
<input id="sort_number" name="sort_number" value="{$data.sort_number|default='1000'}" placeholder="请输入排序" type="text" class="form-control field-text">
</div>
</div>
<div class="form-group">
<label for="view_count" class="col-sm-2 control-label">浏览数</label>
<div class="col-sm-10 col-md-4">
<div class="input-group">
<input id="view_count" name="view_count" value="{$data.view_count|default='0'}" placeholder="请输入浏览数" type="number" class="form-control field-number">
</div>
</div>
</div>
<script>
$('#view_count')
.bootstrapNumber({
upClass: 'success',
downClass: 'primary',
center: true
});
</script>
</div>
<!-- 表单底部 -->
<div class="box-footer">
{:token()}
<div class="col-sm-2">
</div>
<div class="col-sm-10 col-md-4">
{if !isset($data)}
<div class="btn-group pull-right">
<label class="createContinue">
<input type="checkbox" value="1" id="_create" name="_create"
title="继续添加数据">继续添加</label>
</div>
{/if}
<div class="btn-group">
<button type="submit" class="btn flat btn-info dataFormSubmit">
保存
</button>
</div>
<div class="btn-group">
<button type="reset" class="btn flat btn-default dataFormReset">
重置
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<script>
/** 表单验证 **/
$('#dataForm').validate({
rules: {
'name': {
required: true,
},
'user_id': {
required: true,
},
'article_category_id': {
required: true,
},
'description': {
required: true,
},
'content': {
required: true,
},
'is_top': {
required: true,
},
'is_hot': {
required: true,
},
'sort_number': {
required: true,
},
'view_count': {
required: true,
},
},
messages: {
'name': {
required: "标题不能为空",
},
'user_id': {
required: "发布人不能为空",
},
'article_category_id': {
required: "所属分类不能为空",
},
'description': {
required: "简介不能为空",
},
'content': {
required: "内容不能为空",
},
'is_top': {
required: "是否置顶不能为空",
},
'is_hot': {
required: "是否热门不能为空",
},
'sort_number': {
required: "排序不能为空",
},
'view_count': {
required: "浏览数不能为空",
},
}
});
</script>
{/block}

View File

@ -0,0 +1,138 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<!--数据列表页面-->
<section class="content">
<!--顶部搜索筛选-->
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body">
<form class="form-inline searchForm" id="searchForm" action="{:url('index')}" method="GET">
<div class="form-group">
<input value="{$_keywords ? $_keywords : '' ;}"
name="_keywords" id="_keywords" class="form-control input-sm" placeholder="标题/简介">
</div>
<div class="form-group">
<button class="btn btn-sm btn-primary" type="submit"><i class="fa fa-search"></i> 查询
</button>
</div>
<div class="form-group">
<button onclick="clearSearchForm()" class="btn btn-sm btn-default" type="button"><i
class="fa fa-eraser"></i> 清空查询
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="box">
<!--数据列表顶部-->
<div class="box-header">
<div>
<a title="添加" data-toggle="tooltip" class="btn btn-primary btn-sm " href="{:url('add')}">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-danger btn-sm AjaxButton" data-toggle="tooltip" title="删除选中数据" data-confirm-title="删除确认" data-confirm-content="您确定要删除选中的数据吗?" data-id="checked" data-url="{:url('del')}">
<i class="fa fa-trash"></i> 删除
</a>
<a class="btn btn-success btn-sm ReloadButton" data-toggle="tooltip" title="刷新">
<i class="fa fa-refresh"></i> 刷新
</a>
</div>
</div>
<div class="box-body table-responsive">
<table class="table table-hover table-bordered datatable" width="100%">
<thead>
<tr>
<th>
<input id="dataCheckAll" type="checkbox" onclick="checkAll(this)" class="checkbox" placeholder="全选/取消">
</th>
<th>ID</th>
<th>标题</th>
<th>发布人</th>
<th>所属分类</th>
<th>简介</th>
<th>是否置顶</th>
<th>是否热门</th>
<th>缩略图</th>
<th>排序</th>
<th>浏览数</th>
<th>发布时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{foreach name="data" item="item"}
<tr>
<td>
<input type="checkbox" onclick="checkThis(this)" name="data-checkbox" data-id="{$item.id}" class="checkbox data-list-check" value="{$item.id}" placeholder="选择/取消">
</td>
<td>{$item.id}</td>
<td>{$item.name}</td>
<td>{$item.user_id}</td>
<td>{$item.article_category_id}</td>
<td>{$item.description}</td>
<td>{$item.is_top_text}</td>
<td>{$item.is_hot_text}</td>
<td><img class="dataListImg" src="{$item.img}"></td>
<td>{$item.sort_number}</td>
<td>{$item.view_count}</td>
<td>{$item.create_time}</td>
<td class="td-do">
<a href="{:url('edit',['id'=>$item.id])}"
class="btn btn-primary btn-xs" title="修改" data-toggle="tooltip">
<i class="fa fa-pencil"></i>
</a>
<a class="btn btn-danger btn-xs AjaxButton" data-toggle="tooltip" title="删除" data-id="{$item.id}" data-confirm-title="删除确认" data-confirm-content='您确定要删除ID为 <span class="text-red">{$item.id}</span> 的数据吗' data-url="{:url('del')}">
<i class="fa fa-trash"></i>
</a>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<!-- 数据列表底部 -->
<div class="box-footer">
{$page|raw}
<label class="control-label pull-right" style="margin-right: 10px; font-weight: 100;">
<small>共{$total}条记录</small>&nbsp;
<small>每页显示</small>
&nbsp;
<select class="input-sm" onchange="changePerPage(this)">
<option value="10" {if $admin.per_page==10}selected{/if}>10</option>
<option value="20" {if $admin.per_page==20}selected{/if}>20</option>
<option value="30" {if $admin.per_page==30}selected{/if}>30</option>
<option value="50" {if $admin.per_page==50}selected{/if}>50</option>
<option value="100" {if $admin.per_page==100}selected{/if}>100</option>
</select>
&nbsp;
<small>条记录</small>
</label>
</div>
</div>
</div>
</div>
</section>
{/block}

View File

@ -0,0 +1,100 @@
{extend name='public/base' /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
<!-- 表单头部 -->
<div class="box-header with-border">
<div class="btn-group">
<a class="btn flat btn-sm btn-default BackButton">
<i class="fa fa-arrow-left"></i>
返回
</a>
</div>
</div>
<!-- 表单 -->
<form id="dataForm" class="form-horizontal dataForm" action="" method="post"
enctype="multipart/form-data">
<!-- 表单字段区域 -->
<div class="box-body">
<div class="form-group">
<label for="parent_id" class="col-sm-2 control-label">上级分类</label>
<div class="col-sm-10 col-md-4">
<select name="parent_id" id="parent_id" class="form-control field-select"
data-placeholder="请选择上级分类">
<option value="0">顶级分类</option>
{foreach name='cat_list' id='item'}
<option value="{$item.id}" {if isset($data)&& $data.parent_id==$item.id}selected{/if}>{$item.name}</option>
{/foreach}
</select>
</div>
</div>
<script>
$('#parent_id').select2();
</script>
<div class="form-group">
<label for="name" class="col-sm-2 control-label">名称</label>
<div class="col-sm-10 col-md-4">
<input id="name" name="name" value="{$data.name|default=''}" placeholder="请输入名称"
type="text" class="form-control field-text">
</div>
</div>
</div>
<!-- 表单底部 -->
<div class="box-footer">
{:token()}
<div class="col-sm-2">
</div>
<div class="col-sm-10 col-md-4">
{if !isset($data)}
<div class="btn-group pull-right">
<label class="createContinue">
<input type="checkbox" value="1" id="_create" name="_create"
title="继续添加数据">继续添加</label>
</div>
{/if}
<div class="btn-group">
<button type="submit" class="btn flat btn-info dataFormSubmit">
保存
</button>
</div>
<div class="btn-group">
<button type="reset" class="btn flat btn-default dataFormReset">
重置
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<script>
/** 表单验证 **/
$('#dataForm').validate({
rules: {
'parent_id': {
required: true,
},
'name': {
required: true,
},
},
messages: {
'parent_id': {
required: "上级分类不能为空",
},
'name': {
required: "名称不能为空",
},
}
});
</script>
{/block}

View File

@ -0,0 +1,83 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<!--数据列表页面-->
<section class="content">
<!--顶部搜索筛选-->
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body">
<form class="form-inline searchForm" id="searchForm" action="{:url('index')}" method="GET">
<div class="form-group">
<input value="{$_keywords ? $_keywords : '' ;}"
name="_keywords" id="_keywords" class="form-control input-sm" placeholder="名称">
</div>
<div class="form-group">
<button class="btn btn-sm btn-primary" type="submit"><i class="fa fa-search"></i> 查询
</button>
</div>
<div class="form-group">
<button onclick="clearSearchForm()" class="btn btn-sm btn-default" type="button"><i
class="fa fa-eraser"></i> 清空查询
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="box">
<!--数据列表顶部-->
<div class="box-header">
<div>
<a title="添加" data-toggle="tooltip" class="btn btn-primary btn-sm " href="{:url('add')}">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-danger btn-sm AjaxButton" data-toggle="tooltip" title="删除选中数据"
data-confirm-title="删除确认" data-confirm-content="您确定要删除选中的数据吗?" data-id="checked"
data-url="{:url('del')}">
<i class="fa fa-trash"></i> 删除
</a>
<a class="btn btn-success btn-sm ReloadButton" data-toggle="tooltip" title="刷新">
<i class="fa fa-refresh"></i> 刷新
</a>
</div>
</div>
<div class="box-body table-responsive">
<table class="table table-hover table-bordered datatable" width="100%">
<thead>
<tr>
<th>
<input id="dataCheckAll" type="checkbox" onclick="checkAll(this)" class="checkbox"
placeholder="全选/取消">
</th>
<th>ID</th>
<th>名称</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{$data|raw}
</tbody>
</table>
</div>
</div>
</div>
</div>
</section>
{/block}

View File

@ -0,0 +1,26 @@
<div class="row" style="margin-bottom: 15px;">
<div class="col-sm-8">
<input type="text" id="captcha" class=" form-control" name="captcha" placeholder="验证码" maxlength="6">
</div>
<div class="col-sm-4" style="padding-left: 0">
<img style="width: 100%" src="{:url('auth/captcha')}" alt="图形验证码" id="captchaImg" height="34" onclick="refreshCaptcha('captchaImg')">
</div>
</div>
<script>
function refreshCaptcha(dom) {
let $dom = $('#'+dom);
$dom.attr('src','{:url("auth/captcha")}?'+img_name_random());
}
//图片后缀随机数
function img_name_random() {
var rand_one = parseInt(100 * Math.random());
var rand_two = parseInt(100 * Math.random());
return String(rand_one) + String(rand_two);
}
</script>

View File

@ -0,0 +1,53 @@
{js href="__ADMIN_PLUGINS__/gee-test/gee-test.min.js" /}
<div id="wait" class="text-center" style="height: 44px;font-size: 18px;">
正在加载验证码...
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group text-center">
<div id="embed-captcha" style="width: 300px;margin: 0 auto;;"></div>
</div>
</div>
</div>
<script>
var handlerEmbed = function (captchaObj) {
$("#loginButton").click(function (e) {
var validate = captchaObj.getValidate();
if (!validate) {
layer.msg('请先完成验证',{icon:2});
e.preventDefault();
}
});
// 将验证码加到id为captcha的元素里同时会有三个input的值geetest_challenge, geetest_validate, geetest_seccode
captchaObj.appendTo("#embed-captcha");
captchaObj.onReady(function () {
//$("#loginButton").attr("disabled",false);
$("#wait").hide();
});
};
$(function () {
$.ajax({
// 获取idchallengesuccess是否启用failback
url: "{:url('auth/initGeeTest')}",
type: "POST",
dataType: "JSON",
success: function (result) {
let data = result.data;
// 使用initGeetest接口
// 参数1配置参数
// 参数2回调回调的第一个参数验证码对象之后可以使用它做appendTo之类的事件
initGeetest({
with: '300px',
gt: data.gt,
challenge: data.challenge,
new_captcha: data.new_captcha,
product: "embed", // 产品形式包括floatembedpopup。注意只对PC版验证码有效
offline: !data.success // 表示用户后台检测极验服务器是否宕机,一般不需要关注
}, handlerEmbed);
}
});
});
</script>

View File

@ -0,0 +1,160 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="renderer" content="webkit">
<title>{$admin.title} | {$admin.name|default='OneWeekBackend'}</title>
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
{css href="__ADMIN_PLUGINS__/bootstrap/css/bootstrap.min.css" /}
{css href="__ADMIN_PLUGINS__/font-awesome/css/font-awesome.min.css" /}
{css href="__ADMIN_CSS__/AdminLTE.min.css" /}
{css href="__ADMIN_CSS__/admin.css" /}
<!-- 如果有登录背景 -->
{if $login_config.background}
<style>
.login-page{
background-color: #ececec;
background-image: url({$login_config.background});
background-repeat: no-repeat;
background-size: cover;
background-attachment: fixed;
background-position: 50% 50%;
}
</style>
{/if}
<script>
var adminDebug = {$debug};
</script>
{js href="__ADMIN_PLUGINS__/jquery/jquery.min.js" /}
{js href="__ADMIN_PLUGINS__/bootstrap/js/bootstrap.min.js" /}
{js href="__ADMIN_PLUGINS__/jquery-validation/jquery.validate.min.js" /}
{js href="__ADMIN_PLUGINS__/jquery-validation/localization/messages_zh.min.js" /}
{js href="__ADMIN_PLUGINS__/layer/layer.js" /}
{js href="__ADMIN_JS__/admin.js" /}
<!--[if lt IE 9]>
{js href="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js" /}
{js href="https://oss.maxcdn.com/respond/1.4.2/respond.min.js" /}
<![endif]-->
</head>
<body class="hold-transition login-page">
<div class="login-box">
<div class="login-logo">
<a>{$admin.name|default=''}</a>
</div>
<div class="login-box-body">
<p class="login-box-msg">登录</p>
<form class="dataForm" id="dataForm" action="" method="post">
<div class="form-group has-feedback">
<input name="username" id="username" type="text" class="form-control" placeholder="用户名">
<span class="glyphicon glyphicon-user form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input name="password" id="password" type="password" class="form-control" placeholder="密码">
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
{if $login_config.token}
{:token()}
{/if}
{if $login_config.captcha==1}
{include file='auth/captcha' /}
{else/}
{if $login_config.captcha==2}
{include file='auth/gee_test' /}
{/if}
{/if}
<div class="row">
<div class="col-xs-8">
<div class="checkbox">
<label>
<input id="remember" name="remember" value="1" type="checkbox"> 记住我
</label>
</div>
</div>
<div class="col-xs-4">
{:token()}
<button type="submit" id="loginButton" class="btn btn-primary btn-block btn-flat">登录</button>
</div>
</div>
</form>
</div>
</div>
<div id="browser_warning" style="display: none">
<div class=" margin text-center">
<p class="text-red ">请使用现代浏览器(谷歌浏览器、360极速或其他国产浏览器极速模式)操作本后台!</p>
<a class="btn btn-success" target="_blank" href="https://www.google.cn/chrome/" data-toggle="tooltip"
title="点击去下载谷歌浏览器">谷歌浏览器</a>
<a class="btn btn-success" target="_blank" href="https://browser.360.cn/ee/index.html" data-toggle="tooltip"
title="点击去下载360极速浏览器">360极速浏览器</a>
<a class="btn btn-success" target="_blank" href="https://browser.qq.com/" title="点击去下载QQ浏览器"
data-toggle="tooltip">QQ浏览器</a>
</div>
</div>
<script>
$(document).ready(function () {
$("#dataForm").validate({
rules: {
username: {
required: true,
minlength: 2
},
password: {
required: true,
minlength: 6
},
},
messages: {
username: {
required: "请输入用户名",
minlength: "用户名长度不能小于2"
},
password: {
required: "请输入密码",
minlength: "密码长度不能小于6"
},
}
});
$('#username').focus();
});
checkBrowser();
/*检查浏览器*/
function checkBrowser() {
if (isIE()) {
console.log('古代浏览器');
layer.open({
type: 1,
content: $('#browser_warning').html(),
icon: 5,
title: '警告',
area: ['500px', '300px'],
closeBtn: 0,
moveType: 1,
resize: false
});
} else {
console.log('现代浏览器');
}
}
function isIE() {
return !!window.ActiveXObject || "ActiveXObject" in window;
}
</script>
</body>
</html>

View File

@ -0,0 +1,95 @@
{extend name='public/base' /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
<!-- 表单头部 -->
<div class="box-header with-border">
<div class="btn-group">
<a class="btn flat btn-sm btn-default BackButton">
<i class="fa fa-arrow-left"></i>
返回
</a>
</div>
</div>
<!-- 表单 -->
<form id="dataForm" class="form-horizontal dataForm" action="" method="post" enctype="multipart/form-data">
<!-- 表单字段区域 -->
<div class="box-body">
<div class="form-group">
<label for="name" class="col-sm-2 control-label">名称</label>
<div class="col-sm-10 col-md-4">
<input id="name" name="name" value="{$data.name|default=''}" placeholder="请输入名称" type="text" class="form-control field-text">
</div>
</div>
<div class="form-group">
<label for="img" class="col-sm-2 control-label">图片</label>
<div class="col-sm-10 col-md-4">
<input id="img" name="img" placeholder="请上传图片" {if isset($data.img)}data-initial-preview="{$data.img}"{/if} type="file" class="form-control field-image" >
</div>
</div>
<script>
$('#img').fileinput({
language: 'zh',
overwriteInitial: true,
browseLabel: '浏览',
initialPreviewAsData: true,
dropZoneEnabled: false,
showUpload:false,
showRemove: false,
allowedFileTypes:['image'],
maxFileSize:10240,
});
</script>
</div>
<!-- 表单底部 -->
<div class="box-footer">
{:token()}
<div class="col-sm-2">
</div>
<div class="col-sm-10 col-md-4">
{if !isset($data)}
<div class="btn-group pull-right">
<label class="createContinue">
<input type="checkbox" value="1" id="_create" name="_create"
title="继续添加数据">继续添加</label>
</div>
{/if}
<div class="btn-group">
<button type="submit" class="btn flat btn-info dataFormSubmit">
保存
</button>
</div>
<div class="btn-group">
<button type="reset" class="btn flat btn-default dataFormReset">
重置
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<script>
/** 表单验证 **/
$('#dataForm').validate({
rules: {
'name': {
required: true,
},
},
messages: {
'name': {
required: "名称不能为空",
},
}
});
</script>
{/block}

View File

@ -0,0 +1,131 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<!--数据列表页面-->
<section class="content">
<!--顶部搜索筛选-->
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body">
<form class="form-inline searchForm" id="searchForm" action="{:url('index')}" method="GET">
<div class="form-group">
<input value="{$_keywords ? $_keywords : '' ;}"
name="_keywords" id="_keywords" class="form-control input-sm" placeholder="名称">
</div>
<div class="form-group">
<button class="btn btn-sm btn-primary" type="submit"><i class="fa fa-search"></i> 查询
</button>
</div>
<div class="form-group">
<button onclick="clearSearchForm()" class="btn btn-sm btn-default" type="button"><i
class="fa fa-eraser"></i> 清空查询
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="box">
<!--数据列表顶部-->
<div class="box-header">
<div>
<a title="添加" data-toggle="tooltip" class="btn btn-primary btn-sm " href="{:url('add')}">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-danger btn-sm AjaxButton" data-toggle="tooltip" title="删除选中数据"
data-confirm-title="删除确认" data-confirm-content="您确定要删除选中的数据吗?" data-id="checked"
data-url="{:url('del')}">
<i class="fa fa-trash"></i> 删除
</a>
<a class="btn btn-success btn-sm ReloadButton" data-toggle="tooltip" title="刷新">
<i class="fa fa-refresh"></i> 刷新
</a>
</div>
</div>
<div class="box-body table-responsive">
<table class="table table-hover table-bordered datatable" width="100%">
<thead>
<tr>
<th>
<input id="dataCheckAll" type="checkbox" onclick="checkAll(this)" class="checkbox"
placeholder="全选/取消">
</th>
<th>ID</th>
<th>名称</th>
<th>图片</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{foreach name="data" item="item"}
<tr>
<td>
<input type="checkbox" onclick="checkThis(this)" name="data-checkbox"
data-id="{$item.id}" class="checkbox data-list-check" value="{$item.id}"
placeholder="选择/取消">
</td>
<td>{$item.id}</td>
<td>{$item.name}</td>
<td><img class="dataListImg" src="{$item.img}"></td>
<td>{$item.create_time}</td>
<td class="td-do">
<a href="{:url('edit',['id'=>$item.id])}"
class="btn btn-primary btn-xs" title="修改" data-toggle="tooltip">
<i class="fa fa-pencil"></i>
</a>
<a class="btn btn-danger btn-xs AjaxButton" data-toggle="tooltip" title="删除"
data-id="{$item.id}" data-confirm-title="删除确认"
data-confirm-content='您确定要删除ID为 <span class="text-red">{$item.id}</span> 的数据吗'
data-url="{:url('del')}">
<i class="fa fa-trash"></i>
</a>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<!-- 数据列表底部 -->
<div class="box-footer">
{$page|raw}
<label class="control-label pull-right" style="margin-right: 10px; font-weight: 100;">
<small>共{$total}条记录</small>&nbsp;
<small>每页显示</small>
&nbsp;
<select class="input-sm" onchange="changePerPage(this)">
<option value="10" {if $admin.per_page==10}selected{/if}>10</option>
<option value="20" {if $admin.per_page==20}selected{/if}>20</option>
<option value="30" {if $admin.per_page==30}selected{/if}>30</option>
<option value="50" {if $admin.per_page==50}selected{/if}>50</option>
<option value="100" {if $admin.per_page==100}selected{/if}>100</option>
</select>
&nbsp;
<small>条记录</small>
</label>
</div>
</div>
</div>
</div>
</section>
{/block}

View File

@ -0,0 +1,282 @@
{extend name='public/base' /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
<!-- 表单头部 -->
<div class="box-header with-border">
<div class="btn-group">
<a class="btn flat btn-sm btn-default BackButton">
<i class="fa fa-arrow-left"></i>
返回
</a>
</div>
</div>
<!-- 表单 -->
<form id="dataForm" class="form-horizontal dataForm" action="" method="post"
enctype="multipart/form-data">
<!-- 表单字段区域 -->
<div class="box-body">
<div class="form-group">
<label for="user_id" class="col-sm-2 control-label">用户</label>
<div class="col-sm-10 col-md-4">
<select name="user_id" id="user_id" class="form-control field-select"
data-placeholder="请选择用户">
<option value=""></option>
{foreach name='user_list' id='item'}
<option value="{$item.id}" {if isset($data) &&
$data.user_id==$item.id}selected{/if}>
{$item.nickname}
</option>
{/foreach}
</select>
</div>
</div>
<script>
$('#user_id').select2();
</script>
<div class="form-group">
<label for="name" class="col-sm-2 control-label">姓名</label>
<div class="col-sm-10 col-md-4">
<input id="name" name="name" value="{$data.name|default=''}" placeholder="请输入姓名"
type="text" class="form-control field-text">
</div>
</div>
<div class="form-group">
<label for="mobile" class="col-sm-2 control-label">手机号</label>
<div class="col-sm-10 col-md-4">
<input id="mobile" name="mobile" value="{$data.mobile|default=''}" placeholder="请输入手机号"
type="tel" maxlength="11" class="form-control field-mobile">
</div>
</div>
<div class="form-group">
<label for="province_id" class="col-sm-2 control-label"></label>
<div class="col-sm-10 col-md-4">
<select name="province_id" id="province_id" class="form-control field-select"
data-placeholder="请选择省" onchange="getRegion(this.value,1)">
<option value=""></option>
{foreach name='province_list' id='item'}
<option value="{$item.id}" {if isset($data) &&
$data.province_id==$item.id}selected{/if}>
{$item.name}
</option>
{/foreach}
</select>
</div>
</div>
<script>
$('#province_id').select2();
</script>
<div class="form-group">
<label for="city_id" class="col-sm-2 control-label"></label>
<div class="col-sm-10 col-md-4">
<select name="city_id" id="city_id" class="form-control field-select"
data-placeholder="请选择市" onchange="getRegion(this.value,2)">
<option value=""></option>
{foreach name='city_list' id='item'}
<option value="{$item.id}" {if isset($data) &&
$data.city_id==$item.id}selected{/if}>
{$item.name}
</option>
{/foreach}
</select>
</div>
</div>
<script>
$('#city_id').select2();
</script>
<div class="form-group">
<label for="district_id" class="col-sm-2 control-label"></label>
<div class="col-sm-10 col-md-4">
<select name="district_id" id="district_id" class="form-control field-select"
data-placeholder="请选择区" onchange="getRegion(this.value,3)">
<option value=""></option>
{foreach name='district_list' id='item'}
<option value="{$item.id}" {if isset($data) &&
$data.district_id==$item.id}selected{/if}>
{$item.name}
</option>
{/foreach}
</select>
</div>
</div>
<script>
$('#district_id').select2();
</script>
<div class="form-group">
<label for="street_id" class="col-sm-2 control-label">街道</label>
<div class="col-sm-10 col-md-4">
<select name="street_id" id="street_id" class="form-control field-select"
data-placeholder="请选择街道" onchange="getRegion(this.value,4)">
<option value=""></option>
{foreach name='street_list' id='item'}
<option value="{$item.id}" {if isset($data) &&
$data.street_id==$item.id}selected{/if}>
{$item.name}
</option>
{/foreach}
</select>
</div>
</div>
<script>
$('#street_id').select2();
</script>
<div class="form-group">
<label for="detail" class="col-sm-2 control-label">详细地址</label>
<div class="col-sm-10 col-md-4">
<input id="detail" name="detail" value="{$data.detail|default=''}" placeholder="请输入详细地址"
type="text" class="form-control field-text">
</div>
</div>
<div class="form-group">
<label for="is_default" class="col-sm-2 control-label">是否默认</label>
<div class="col-sm-10 col-md-4">
<input class="input-switch" id="is_default" value="1" {if(!isset($data)
||$data.is_default==1)}checked{/if} type="checkbox"/>
<input class="switch field-switch" placeholder="是否默认" name="is_default"
value="{$data.is_default|default='0'}" hidden/>
</div>
</div>
<script>
$('#is_default').bootstrapSwitch({
onText: "是",
offText: "否",
onColor: "success",
offColor: "danger",
onSwitchChange: function (event, state) {
$(event.target).closest('.bootstrap-switch').next().val(state ? '1' : '0').change();
}
});
</script>
</div>
<!-- 表单底部 -->
<div class="box-footer">
{:token()}
<div class="col-sm-2">
</div>
<div class="col-sm-10 col-md-4">
{if !isset($data)}
<div class="btn-group pull-right">
<label class="createContinue">
<input type="checkbox" value="1" id="_create" name="_create"
title="继续添加数据">继续添加</label>
</div>
{/if}
<div class="btn-group">
<button type="submit" class="btn flat btn-info dataFormSubmit">
保存
</button>
</div>
<div class="btn-group">
<button type="reset" class="btn flat btn-default dataFormReset">
重置
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<script>
/** 表单验证 **/
$('#dataForm').validate({
rules: {
'user_id': {
required: true,
},
'name': {
required: true,
},
'mobile': {
required: true,
},
'province_id': {
required: true,
},
'city_id': {
required: true,
},
'district_id': {
required: true,
},
'street_id': {
required: true,
},
'detail': {
required: true,
},
'is_default': {
required: true,
},
},
messages: {
'user_id': {
required: "用户不能为空",
},
'name': {
required: "姓名不能为空",
},
'mobile': {
required: "手机号不能为空",
},
'province_id': {
required: "省不能为空",
},
'city_id': {
required: "市不能为空",
},
'district_id': {
required: "区不能为空",
},
'street_id': {
required: "街道不能为空",
},
'detail': {
required: "详细地址不能为空",
},
'is_default': {
required: "是否默认不能为空",
},
}
});
</script>
<script>
var regionId = ['#province_id', '#city_id', '#district_id', '#street_id'];
var regionHtml = ['请选择省', '请选择市', '请选择区(县)', '请选择街道'];
$(function () {
getRegion(0, 0);
});
function getRegion(parent_id, level) {
clearSon(level);
var html = '<option value="-1">' + regionHtml[level] + '</option>';
$.post('/region/getRegion', {parent_id: parent_id, level: level}, function (result) {
$.each(result, function (index, item) {
html += '<option value="' + item.id + '">' + item.name + '</option>'
});
$(regionId[level]).html(html);
$('.field-select').select2();
});
}
function clearSon(level) {
for (var i = level + 1; i <= 4; i++) {
var html = '<option value="-1">' + regionHtml[i] + '</option>';
$(regionId[i]).html(html);
$('.field-select').select2();
}
}
</script>
{/block}

View File

@ -0,0 +1,138 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<!--数据列表页面-->
<section class="content">
<!--顶部搜索筛选-->
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body">
<form class="form-inline searchForm" id="searchForm" action="{:url('index')}" method="GET">
<div class="form-group">
<input value="{$_keywords ? $_keywords : '' ;}"
name="_keywords" id="_keywords" class="form-control input-sm" placeholder="姓名/手机号">
</div>
<div class="form-group">
<button class="btn btn-sm btn-primary" type="submit"><i class="fa fa-search"></i> 查询
</button>
</div>
<div class="form-group">
<button onclick="clearSearchForm()" class="btn btn-sm btn-default" type="button"><i
class="fa fa-eraser"></i> 清空查询
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="box">
<!--数据列表顶部-->
<div class="box-header">
<div>
<a title="添加" data-toggle="tooltip" class="btn btn-primary btn-sm " href="{:url('add')}">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-danger btn-sm AjaxButton" data-toggle="tooltip" title="删除选中数据" data-confirm-title="删除确认" data-confirm-content="您确定要删除选中的数据吗?" data-id="checked" data-url="{:url('del')}">
<i class="fa fa-trash"></i> 删除
</a>
<a class="btn btn-success btn-sm ReloadButton" data-toggle="tooltip" title="刷新">
<i class="fa fa-refresh"></i> 刷新
</a>
</div>
</div>
<div class="box-body table-responsive">
<table class="table table-hover table-bordered datatable" width="100%">
<thead>
<tr>
<th>
<input id="dataCheckAll" type="checkbox" onclick="checkAll(this)" class="checkbox" placeholder="全选/取消">
</th>
<th>ID</th>
<th>用户</th>
<th>姓名</th>
<th>手机号</th>
<th></th>
<th></th>
<th></th>
<th>街道</th>
<th>详细地址</th>
<th>是否默认</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{foreach name="data" item="item"}
<tr>
<td>
<input type="checkbox" onclick="checkThis(this)" name="data-checkbox" data-id="{$item.id}" class="checkbox data-list-check" value="{$item.id}" placeholder="选择/取消">
</td>
<td>{$item.id}</td>
<td>{$item.user.nickname|default=''}</td>
<td>{$item.name}</td>
<td>{$item.mobile}</td>
<td>{$item.province.name|default=''}</td>
<td>{$item.city.name|default=''}</td>
<td>{$item.district.name|default=''}</td>
<td>{$item.street.name|default=''}</td>
<td>{$item.detail}</td>
<td>{$item.is_default_text}</td>
<td>{$item.create_time}</td>
<td class="td-do">
<a href="{:url('edit',['id'=>$item.id])}"
class="btn btn-primary btn-xs" title="修改" data-toggle="tooltip">
<i class="fa fa-pencil"></i>
</a>
<a class="btn btn-danger btn-xs AjaxButton" data-toggle="tooltip" title="删除" data-id="{$item.id}" data-confirm-title="删除确认" data-confirm-content='您确定要删除ID为 <span class="text-red">{$item.id}</span> 的数据吗' data-url="{:url('del')}">
<i class="fa fa-trash"></i>
</a>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<!-- 数据列表底部 -->
<div class="box-footer">
{$page|raw}
<label class="control-label pull-right" style="margin-right: 10px; font-weight: 100;">
<small>共{$total}条记录</small>&nbsp;
<small>每页显示</small>
&nbsp;
<select class="input-sm" onchange="changePerPage(this)">
<option value="10" {if $admin.per_page==10}selected{/if}>10</option>
<option value="20" {if $admin.per_page==20}selected{/if}>20</option>
<option value="30" {if $admin.per_page==30}selected{/if}>30</option>
<option value="50" {if $admin.per_page==50}selected{/if}>50</option>
<option value="100" {if $admin.per_page==100}selected{/if}>100</option>
</select>
&nbsp;
<small>条记录</small>
</label>
</div>
</div>
</div>
</div>
</section>
{/block}

View File

@ -0,0 +1,92 @@
<!--空白页面参考模版-->
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box">
<form id="dataForm" class="dataForm form-horizontal" action="{:url('sendEmail')}" method="post"
enctype="multipart/form-data">
<!-- /.box-header -->
<div class="box-body">
<div class="fields-group">
<div class="form-group">
<label for="address" class="col-sm-2 control-label">收信人</label>
<div class="col-sm-8">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-user"></i></span>
<input maxlength="300" id="address" name="address" class="form-control"
placeholder="多个地址请用英文逗号隔开">
</div>
</div>
</div>
<div class="form-group">
<label for="subject" class="col-sm-2 control-label">主题</label>
<div class="col-sm-8">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-file-text"></i></span>
<input maxlength="300" id="subject" name="subject"
class="form-control"
placeholder="主题">
</div>
</div>
</div>
<div class="form-group">
<label for="subject" class="col-sm-2 control-label">邮件正文</label>
<div class="col-sm-8">
<textarea id="content" name="content" class="form-control" style="height: 300px"
placeholder="邮件正文"></textarea>
</div>
</div>
<div class="form-group">
<label for="subject" class="col-sm-2 control-label">附件</label>
<div class="col-sm-8">
<div class="input-group">
<div class="btn btn-default btn-file">
<i class="fa fa-paperclip"></i>点击上传
<input type="file" id="attachment" name="attachment"
accept="image/jpeg,image/png,image/gif,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet">
</div>
<small class="help-block">最大不超过2MB</small>
</div>
</div>
</div>
</div>
</div>
<div class="box-footer">
{:token()}
<div class="col-sm-2">
</div>
<div class="col-sm-10 col-md-4">
<div class="btn-group">
<button type="submit" class="btn flat btn-info dataFormSubmit">
保存
</button>
</div>
<div class="btn-group">
<button type="reset" class="btn flat btn-default dataFormReset">
重置
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<script>
$('#dataForm').validate();
</script>
{/block}

View File

@ -0,0 +1,164 @@
<!--空白页面参考模版-->
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
{js href="__ADMIN_PLUGINS__/jquery-qrcode/jquery-qrcode.min.js" /}
<section class="content">
<div class="row">
<div class="col-md-6">
<div class="box">
<div class="box-header">
<h3 class="box-title">前端生成二维码</h3>
</div>
<form id="frontDataForm" class="dataForm form-horizontal" method="post" onsubmit="return frontCreate()" enctype="multipart/form-data">
<div class="box-body">
<div class="fields-group">
<div class="form-group">
<label for="frontContent" class="col-sm-2 control-label">内容</label>
<div class="col-sm-8">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-pencil"></i></span>
<input name="content" id="frontContent" maxlength="210" class="form-control" placeholder="请输入文字或网址,按回车键生成">
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="box">
<div class="box-header">
<h3 class="box-title">生成结果</h3>
</div>
<div class="box-body">
<div style="text-align: center">
<div id="frontResult"></div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="box">
<div class="box-header">
<h3 class="box-title">PHP生成二维码</h3>
</div>
<form id="dataForm" class="dataForm form-horizontal" method="post" onsubmit="return create()" enctype="multipart/form-data">
<div class="box-body">
<div class="fields-group">
<div class="form-group">
<label for="content" class="col-sm-2 control-label">内容</label>
<div class="col-sm-8">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-pencil"></i></span>
<input name="content" id="content" maxlength="210" class="form-control" placeholder="请输入文字或网址,按回车键生成">
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="box">
<div class="box-header">
<h3 class="box-title">生成结果</h3>
</div>
<div class="box-body">
<div style="text-align: center">
<img src="" id="result">
</div>
</div>
</div>
</div>
</div>
<img id="qrLogo" style="display: none;" src="/uploads/attachment/20190902/6a673f554c694a41971fca94c7503315.jpg">
<script>
function frontCreate() {
var content = $("#frontContent").val();
//jquery-qrcode 文档地址 https://larsjung.de/jquery-qrcode/
$('#frontResult').qrcode({
width: "300",
height: "300",
mode:4,
mSize: 0.3,
text: toUtf8(content),
image:$('#qrLogo')[0]
});
return false;
}
//php生成
function create() {
var content = $("#content").val();
$.ajax({
url: '{:url("createQrCode")}',
type: "post",
data: {
content:content
},
dataType: 'json',
cache: false,
async:false,
success: function (result) {
console.log(result);
if(result.code==1){
$("#result").attr('src',result.data.qrcode+"?"+img_name_random());
}else {
layer.msg(result.msg,{icon:2});
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
layer.msg('系统异常,请稍后重试',{icon:2});
}
});
return false;
}
//图片后缀随机数
function img_name_random() {
var rand_one = parseInt(100 * Math.random());
var rand_two = parseInt(100 * Math.random());
return String(rand_one) + String(rand_two);
}
function toUtf8(str) {
var out, i, len, c;
out = "";
len = str.length;
for(i = 0; i < len; i++) {
c = str.charCodeAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i);
} else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
}
}
return out;
}
</script>
</section>
{/block}

View File

@ -0,0 +1,70 @@
<!--空白页面参考模版-->
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box">
<form id="dataForm" class="dataForm form-horizontal" method="post" onsubmit="return send()"
enctype="multipart/form-data">
<div class="box-body">
<div class="fields-group">
<div class="form-group">
<label for="mobile" class="col-sm-2 control-label">手机号</label>
<div class="col-sm-8">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-pencil"></i></span>
<input name="mobile" id="mobile" maxlength="11" class="form-control"
placeholder="请输手机号">
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="box">
<div class="box-header">
<h3 class="box-title">发送结果</h3>
</div>
<div class="box-body">
<div style="text-align: center" id="result">
</div>
</div>
</div>
</div>
</div>
<script>
function send() {
var mobile = $("#mobile").val();
$.ajax({
url: '{:url("sendSms")}',
type: "post",
data: {
mobile: mobile
},
dataType: 'json',
cache: false,
async: false,
success: function (result) {
$("#result").html(result.msg);
layer.msg(result.msg);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
layer.msg("系统异常,请稍后重试");
}
});
return false;
}
</script>
</section>
{/block}

View File

@ -0,0 +1,91 @@
{extend name='public/base' /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
<!-- 表单头部 -->
<div class="box-header with-border">
<div class="btn-group">
<a class="btn flat btn-sm btn-default BackButton">
<i class="fa fa-arrow-left"></i>
返回
</a>
</div>
</div>
<!-- 表单 -->
<form id="dataForm" class="form-horizontal dataForm" action="" method="post"
enctype="multipart/form-data">
<!-- 表单字段区域 -->
<div class="box-body">
<div class="form-group">
<label for="name" class="col-sm-2 control-label">名称</label>
<div class="col-sm-10 col-md-4">
<input id="name" name="name" value="{$data.name|default=''}" placeholder="请输入名称"
type="text" class="form-control field-text">
</div>
</div>
<div class="form-group">
<label for="code" class="col-sm-2 control-label">编码</label>
<div class="col-sm-10 col-md-4">
<input id="code" name="code" value="{$data.code|default=''}" placeholder="请输入编码"
type="text" class="form-control field-text">
</div>
</div>
</div>
<!-- 表单底部 -->
<div class="box-footer">
{:token()}
<div class="col-sm-2">
</div>
<div class="col-sm-10 col-md-4">
{if !isset($data)}
<div class="btn-group pull-right">
<label class="createContinue">
<input type="checkbox" value="1" id="_create" name="_create"
title="继续添加数据">继续添加</label>
</div>
{/if}
<div class="btn-group">
<button type="submit" class="btn flat btn-info dataFormSubmit">
保存
</button>
</div>
<div class="btn-group">
<button type="reset" class="btn flat btn-default dataFormReset">
重置
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<script>
/** 表单验证 **/
$('#dataForm').validate({
rules: {
'name': {
required: true,
},
'code': {
required: true,
},
},
messages: {
'name': {
required: "名称不能为空",
},
'code': {
required: "编码不能为空",
},
}
});
</script>
{/block}

View File

@ -0,0 +1,124 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<!--数据列表页面-->
<section class="content">
<!--顶部搜索筛选-->
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body">
<form class="form-inline searchForm" id="searchForm" action="{:url('index')}" method="GET">
<div class="form-group">
<input value="{$_keywords ? $_keywords : '' ;}"
name="_keywords" id="_keywords" class="form-control input-sm" placeholder="名称">
</div>
<div class="form-group">
<button class="btn btn-sm btn-primary" type="submit"><i class="fa fa-search"></i> 查询
</button>
</div>
<div class="form-group">
<button onclick="clearSearchForm()" class="btn btn-sm btn-default" type="button"><i
class="fa fa-eraser"></i> 清空查询
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="box">
<!--数据列表顶部-->
<div class="box-header">
<div>
<a title="添加" data-toggle="tooltip" class="btn btn-primary btn-sm " href="{:url('add')}">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-danger btn-sm AjaxButton" data-toggle="tooltip" title="删除选中数据" data-confirm-title="删除确认" data-confirm-content="您确定要删除选中的数据吗?" data-id="checked" data-url="{:url('del')}">
<i class="fa fa-trash"></i> 删除
</a>
<a class="btn btn-success btn-sm ReloadButton" data-toggle="tooltip" title="刷新">
<i class="fa fa-refresh"></i> 刷新
</a>
</div>
</div>
<div class="box-body table-responsive">
<table class="table table-hover table-bordered datatable" width="100%">
<thead>
<tr>
<th>
<input id="dataCheckAll" type="checkbox" onclick="checkAll(this)" class="checkbox" placeholder="全选/取消">
</th>
<th>ID</th>
<th>名称</th>
<th>编码</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{foreach name="data" item="item"}
<tr>
<td>
<input type="checkbox" onclick="checkThis(this)" name="data-checkbox" data-id="{$item.id}" class="checkbox data-list-check" value="{$item.id}" placeholder="选择/取消">
</td>
<td>{$item.id}</td>
<td>{$item.name}</td>
<td>{$item.code}</td>
<td>{$item.create_time}</td>
<td class="td-do">
<a href="{:url('edit',['id'=>$item.id])}"
class="btn btn-primary btn-xs" title="修改" data-toggle="tooltip">
<i class="fa fa-pencil"></i>
</a>
<a class="btn btn-danger btn-xs AjaxButton" data-toggle="tooltip" title="删除" data-id="{$item.id}" data-confirm-title="删除确认" data-confirm-content='您确定要删除ID为 <span class="text-red">{$item.id}</span> 的数据吗' data-url="{:url('del')}">
<i class="fa fa-trash"></i>
</a>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<!-- 数据列表底部 -->
<div class="box-footer">
{$page|raw}
<label class="control-label pull-right" style="margin-right: 10px; font-weight: 100;">
<small>共{$total}条记录</small>&nbsp;
<small>每页显示</small>
&nbsp;
<select class="input-sm" onchange="changePerPage(this)">
<option value="10" {if $admin.per_page==10}selected{/if}>10</option>
<option value="20" {if $admin.per_page==20}selected{/if}>20</option>
<option value="30" {if $admin.per_page==30}selected{/if}>30</option>
<option value="50" {if $admin.per_page==50}selected{/if}>50</option>
<option value="100" {if $admin.per_page==100}selected{/if}>100</option>
</select>
&nbsp;
<small>条记录</small>
</label>
</div>
</div>
</div>
</div>
</section>
{/block}

View File

@ -0,0 +1,810 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<script>
//收起左侧菜单,留出更大空间
if (!$('body').hasClass('sidebar-collapse')) {
$('body').addClass('sidebar-collapse');
}
</script>
<section class="content">
<style scoped>
#dataBody th, #dataBody td {
min-width: 60px;
}
td label {
font-weight: normal;
}
.box-header .select2 {
min-width: 130px;
}
.form-type-th {
min-width: 150px;
}
.form-validate-th {
min-width: 200px;
}
.form-validate-label, .form-validate-select, .form-type-label, .form-type-select {
width: 100%;
}
#create_menu_list {
min-width: 400px;
}
#controller_action_list {
min-width: 400px;
}
.form-inline .form-group {
margin-right: 20px;
}
.extend-div {
display: none;
position: absolute;
z-index: 2;
}
#model_relation .form-group {
margin-bottom: 10px;
}
.more-setting .extend-div {
width: 570px;
margin-right: 0;
margin-left: -500px;
}
.more-setting .more-from {
margin-bottom: 20px;
}
.modelRelationDiv .form-group .form-control {
margin-right: 20px;
}
</style>
<form id="dataForm" class="dataForm" action="create" method="post">
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">代码自动生成</h3>
</div>
<!-- 表和菜单 -->
<div class="box-header with-border">
<div class="form-inline">
<div class="form-group">
<label for="table_name">选择表</label>
<select data-id="table_name" name="table_name" class="select2 form-control input-sm"
id="table_name" data-placeholder="请选择表">
<option value=""></option>
{foreach name='table' id='item'}
<option value="{$item}">{$item}</option>
{/foreach}
</select>
<button onclick="refreshTable()" type="button" class="btn btn-flat btn-success"
data-toggle="tooltip" title="刷新表数据">
<i class="fa fa-refresh"></i>
</button>
</div>
<div class="form-group">
<label for="cn_name">中文名</label>
<input name="cn_name" id="cn_name" class="form-control input-sm" placeholder="请填写中文名"
title="表及功能的中文名字,例如用户表,就填写[用户]" data-toggle="tooltip">
</div>
<div class="form-group checkbox">
<label><input checked type="checkbox" value="1" id="auto_class_name"
name="auto_class_name"
title="自动生成控制器|模型|验证器类名" data-toggle="tooltip">自动生成类名</label>
</div>
<div class="form-group checkbox">
<label><input checked type="checkbox" value="1" id="list_delete"
name="list_delete"
title="列表删除功能" data-toggle="tooltip">列表删除</label>
</div>
<div class="form-group checkbox">
<label><input checked type="checkbox" value="1" id="list_create"
name="list_create"
title="列表添加功能" data-toggle="tooltip">列表添加</label>
</div>
<div class="form-group checkbox">
<label><input checked type="checkbox" value="1" id="list_refresh"
name="list_refresh"
title="列表刷新功能" data-toggle="tooltip">列表刷新</label>
</div>
<div class="form-group checkbox">
<label><input type="checkbox" value="1" id="list_export"
name="list_export"
title="列表导出功能" data-toggle="tooltip">列表导出</label>
</div>
<div class="form-group checkbox">
<label><input type="checkbox" value="1" id="list_enable"
name="list_enable"
title="列表启用/禁用功能" data-toggle="tooltip">列表启用/禁用</label>
</div>
</div>
</div>
<!-- 控制器 -->
<div class="box-header with-border">
<div class="form-inline">
<div class="form-group">
<label for="create_menu">菜 单</label>
<select data-id="create_menu" name="create_menu" class="select2 form-control input-sm"
id="create_menu" data-placeholder="不选择为不生成菜单">
<option value="-1">不生成</option>
<option value="0">顶级菜单</option>
{$menus|raw}
</select>
<button onclick="refreshMenu()" type="button" class="btn btn-flat btn-success"
data-toggle="tooltip" title="刷新菜单">
<i class="fa fa-refresh"></i>
</button>
</div>
<div class="form-group">
<label for="create_menu_list">菜单选择</label>
<select name="create_menu_list[]" class="select2 form-control input-sm"
id="create_menu_list" multiple="multiple" data-placeholder="默认生成增删改菜单">
<option value="1" disabled selected>列表</option>
<option value="2" selected>添加</option>
<option value="3" selected>修改</option>
<option value="4" selected>删除</option>
<option value="5">启用/禁用</option>
</select>
</div>
</div>
</div>
<div class="box-header with-border">
<div class="form-inline">
<div class="form-group">
<label for="create_controller">控制器</label>
<select data-id="create_controller" name="create_controller"
class="select2 form-control input-sm"
id="create_controller" data-placeholder="默认生成">
<option value="1">生成</option>
<option value="0">不生成</option>
</select>
</div>
<div class="form-group">
<label for="controller_name">控制器名</label>
<input name="controller_name" id="controller_name"
class="form-control input-sm" title="默认会根据表名自动生成" placeholder="请填写控制器名"
data-toggle="tooltip">
</div>
<div class="form-group">
<label for="controller_action_list">控制器方法</label>
<select name="controller_action_list[]" class="select2 form-control input-sm"
id="controller_action_list" multiple="multiple" data-placeholder="默认生成增删改方法">
<option value="1" selected>列表</option>
<option value="2" selected>添加</option>
<option value="3" selected>修改</option>
<option value="4" selected>删除</option>
<option value="5">启用/禁用</option>
</select>
</div>
</div>
</div>
<div class="box-header with-border">
<div class="form-inline">
<div class="form-group">
<label for="create_model">模 型</label>
<select data-id="create_model" name="create_model" class="select2 form-control input-sm"
id="create_model" data-placeholder="默认生成">
<option value="1">生成</option>
<option value="0">不生成</option>
</select>
</div>
<div class="form-group">
<label for="model_name">模型名</label>
<input name="model_name" id="model_name" class="form-control input-sm"
placeholder="模型名" title="默认会根据表名自动生成" data-toggle="tooltip">
</div>
<div class="form-group checkbox">
<label><input checked type="checkbox" value="1" name="auto_timestamp"
title="自动添加create_time和update_time字段" data-toggle="tooltip">自动时间戳</label>
</div>
<div class="form-group checkbox">
<label><input checked type="checkbox" value="1" name="soft_delete"
title="自动添加delete_time字段默认为0" data-toggle="tooltip">软删除</label>
</div>
<div>
</div>
</div>
</div>
<div class="box-header with-border">
<div class="form-inline">
<div class="form-group">
<label for="create_validate">验证器</label>
<select data-id="create_validate" name="create_validate"
class="select2 form-control input-sm"
id="create_validate" data-placeholder="默认生成">
<option value="1">生成</option>
<option value="0">不生成</option>
</select>
</div>
<div class="form-group">
<label for="validate_name">验证器名</label>
<input name="validate_name" id="validate_name" class="form-control input-sm"
placeholder="验证器名" title="默认会根据表名自动生成" data-toggle="tooltip">
</div>
</div>
</div>
<div class="box-body table-responsive">
<table id="dataList" class="table table-hover table-bordered datatable" width="100%">
<thead>
<tr class="input-type">
<th>操作</th>
<th title="字段名为小写下划线形式">字段</th>
<th title="字段类型例如varchar(255),int(10),decimal(12,2)">类型</th>
<th title="中文名称例如username为用户名">名称</th>
<th title="是否在列表页显示">列表</th>
<th title="是否为列表页搜索字段">搜索</th>
<th title="是否为添加/修改页字段">表单</th>
<th class="form-type-th" title="表单类型">表单类型</th>
<th class="form-validate-th" title="表单验证">表单验证</th>
<th title="字段更多设置">更多</th>
</tr>
</thead>
<tbody id="dataBody">
</tbody>
</table>
</div>
<div class="box-footer">
<a class="btn btn-primary btn-sm btn-success" onclick="addNewField(null,2)">添加一行</a>
<button class="btn btn-primary btn-sm pull-right" type="submit">提交</button>
</div>
</div>
</div>
</div>
</form>
<table>
<tbody id="data-template" style="display: none">
<tr>
<td>
<a class="btn btn-xs btn-primary" onclick="addNewField(this,1)">插入</a>
<a class="btn btn-xs btn-success" onclick="addNewField(this,2)">追加</a>
<a class="btn btn-xs btn-danger" onclick="delThisField(this,1)">删除</a>
</td>
<td>
<label>
<input class="form-control" name="field_nameFORM_INDEX[]" value="" placeholder="字段"
>
</label>
</td>
<td>
<label>
<input class="form-control field-type" value="" name="field_typeFORM_INDEX[]"
placeholder="字段类型例如varchar(255),int(10),decimal(12,2)">
</label>
</td>
<td>
<label>
<input class="form-control" name="form_nameFORM_INDEX[]" placeholder="名称">
</label>
</td>
<td>
<label class="bodyFormCheckbox">
<input type="checkbox" value="1" id="is_listFORM_INDEX[]" name="is_listFORM_INDEX[]">列表
</label>
</td>
<td>
<label class="bodyFormCheckbox">
<input type="checkbox" value="1" id="is_searchFORM_INDEX[]" name="is_searchFORM_INDEX[]">搜索
</label>
</td>
<td>
<label class="bodyFormCheckbox">
<input type="checkbox" value="1" id="is_formFORM_INDEX[]" name="is_formFORM_INDEX[]">表单
</label>
</td>
<td>
<label class="form-type-label">
<select class="form-control select2 form-type-select" name="form_typeFORM_INDEX[]"
onchange="selectField(this)">
<option value="text">文本[text]</option>
<option value="number">数字[number]</option>
<option value="password">密码[password]</option>
<option value="mobile">手机号[mobile]</option>
<option value="email">邮箱[email]</option>
<option value="id_card">身份证号[id_card]</option>
<option value="url">网址[url]</option>
<option value="ip">IP地址[ip]</option>
<option value="textarea">文本域[textarea]</option>
<option value="checkbox">复选[checkbox]</option>
<option value="switch">开关[switch]</option>
<option value="radio">单选[radio]</option>
<option value="select">选择列表[select]</option>
<option value="multi_select">多项选择列表[multi-select]</option>
<option value="image">图片上传[image]</option>
<option value="multi_image">多图上传[multi-image]</option>
<option value="file">文件上传[file]</option>
<option value="multi_file">多文件上传[multi-file]</option>
<option value="date">日期[date]</option>
<option value="date_range">日期范围[date-range]</option>
<option value="datetime">日期时间[datetime]</option>
<option value="datetime_range">日期时间范围[datetime-range]</option>
<option value="year">年[year]</option>
<option value="year_range">年范围[year-range]</option>
<option value="year_month">年月[year-month]</option>
<option value="year_month_range">年月范围[year-month-range]</option>
<option value="map">地图选点[map]</option>
<option value="color">颜色选择[color]</option>
<option value="icon">图标选择[icon]</option>
<option value="editor">富文本编辑器[editor]</option>
</select>
</label>
</td>
<td class="form-validate-td">
<label class="form-validate-label">
<select class="form-control form-validate-select select2" multiple="multiple"
name="form_validateFORM_INDEX[]">
<option value="required">非空</option>
<!--当前采用微信号的规则6至20位以字母开头字母数字减号下划线 /^[a-zA-Z]([-_a-zA-Z0-9]{5,19})+$/-->
<option value="account">账号</option>
<!--验证简单中文名字2-4个汉字 /[\u4E00-\u9FA5]{2,4}/如有特殊名字请手动更改规则长度-->
<option value="cn_name">中文姓名</option>
<!--/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$/-->
<option value="car_number">车牌号</option>
</select>
</label>
</td>
<td class="more-setting" data-id="INDEX_ID">
<!-- 这里放更多设置
例如datedate_time类型的自动加时间转换功能
is_xxx同时是switch的字段自动加is_xxx_text功能
-->
<a class="btn btn-default btn-sm setting-more" data-id="INDEX_ID">更多设置</a>
<div class="extend-div" id="field_setting_div_INDEX_ID" data-id="INDEX_ID">
<div class="box box-warning box-solid">
<div class="box-header with-border">
<h3 class="box-title">字段更多设置</h3>
</div>
<div class="box-body" id="field_setting_INDEX_ID">
<div class="more-from">
<div class="form-inline">
<div class="form-group">
<label for="field_defaultINEDEX_ID">默认值</label>
<input name="field_defaultFORM_INDEX[]"
class="form-control input-sm"
id="field_defaultINEDEX_ID" placeholder="请填写默认值">
</div>
<div class="form-group">
<label for="getter_setterFORM_INDEX">获取/修改器</label>
<select name="getter_setterFORM_INDEX[]"
class="select2 form-control input-sm"
id="getter_setterFORM_INDEX" data-placeholder="获取/修改器">
<option value=""></option>
<option value="datetime">datetime</option>
<option value="switch">switch</option>
<option value="date">date</option>
</select>
</div>
<div class="form-group checkbox">
<label><input type="checkbox" value="1" name="list_sortFORM_INDEX[]"
title="是否参与列表排序" data-toggle="tooltip">列表排序</label>
</div>
</div>
</div>
<hr/>
<div class="more-from">
<div class="form-inline">
<div class="form-group">
<label for="is_relationFORM_INDEX">关联设置</label>
<select name="is_relationFORM_INDEX[]"
class="select2 form-control input-sm"
id="is_relationFORM_INDEX" data-placeholder="是否关联字段"
onchange="selectRelation(this)"
data-relation-table="relation_tableFORM_INDEX[]"
data-relation-show="relation_showFORM_INDEX[]">
<option value="0">非关联字段</option>
<option value="1">关联外键</option>
<option value="2">关联主键</option>
</select>
</div>
<div class="form-group">
<select name="relation_typeFORM_INDEX[]"
class="select2 form-control input-sm"
id="relation_typeFORM_INDEX" title="暂时只支持一对一和一对多" data-toggle="tooltip"
data-placeholder="关联方式">
<option value="1">一对多</option>
<option value="2">一对一</option>
</select>
</div>
<div class="form-group">
<input readonly name="relation_showFORM_INDEX[]"
class="form-control input-sm"
id="relation_showINEDEX_ID"
title="belongsTo填写例如文章发布人user_id要显示成User模型的nickname填写nickname即可"
data-toggle="tooltip" placeholder="关联显示字段">
</div>
<div class="form-group">
<input readonly name="relation_tableFORM_INDEX[]"
class="form-control input-sm"
id="relation_tableINEDEX_ID"
title="一般此字段为idbelongsTo的无须填写hasOne/hasMany填写此字段关联多个模型务必使用英文逗号隔开例如用户关联多篇文章多个积分记录可以写成article,integral_log"
data-toggle="tooltip" placeholder="关联表/模型,用英文逗号隔开">
</div>
</div>
</div>
<hr/>
<div class="more-from">
<div class="form-inline">
<div class="form-group">
<label for="field_sceneINEDEX_ID">验证场景</label>
<select style="min-width: 380px;width: 420px;" name="field_sceneFORM_INDEX[]"
class="select2 form-control input-sm"
id="field_sceneINEDEX_ID" multiple="multiple"
data-placeholder="默认选择三大模块">
<option value="admin_add" selected>admin_add</option>
<option value="admin_edit" selected>admin_edit</option>
<option value="api_add" selected>api_add</option>
<option value="api_edit" selected>api_edit</option>
<option value="index_add" selected>index_add</option>
<option value="index_edit" selected>index_edit</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</section>
<script>
//刷新数据库表
function refreshTable() {
$.post('{:url("admin/generate/getTable")}', function (result) {
let html = '<option value=""></option>';
$.each(result.data, function (index, item) {
html += '<option value="' + item + '">' + item + '</option>';
});
$('#table_name').html(html).select2();
});
}
//表单索引
var formIndex = 0;
$(function () {
//获取表信息和字段等,进行页面填充
$("#table_name").on('change', function () {
getField($(this).val());
});
//列表启用/禁止关联菜单和控制器
$('#list_enable').change(function () {
console.log('启用/禁止选项');
let checked = $(this).is(':checked');
let $menu_list = $('#create_menu_list');
let $action_list = $('#controller_action_list');
$menu_list.find("option[value='5']").attr("selected", checked);
$action_list.find("option[value='5']").attr("selected", checked);
$menu_list.select2();
$action_list.select2();
});
//默认添加一行空的字段
addNewField(null, 1);
});
//添加新的字段
function addNewField(obj, type) {
formIndex++;
let template = $("#data-template").html().replace(/FORM_INDEX/g, '[' + formIndex + ']').replace(/INDEX_ID/g, formIndex);
if (obj == null) {
$("#dataBody").append(template);
} else {
if (type === 1) {
$(obj).parent().parent().before(template);
} else {
$(obj).parent().parent().after(template);
}
}
//刷新 dataBody DOM后的操作
dataBodyRefreshed();
}
//删除当前字段
function delThisField(obj) {
layer.confirm('您确认删除本行吗?', {title: '删除确认', closeBtn: 1, icon: 3}, function () {
$(obj).parent().parent().remove();
layer.closeAll();
});
}
//提交验证
$("#dataForm").validate({
rules: {
table_name: {
required: true,
},
cn_name: {
required: true,
},
},
messages: {
table_name: {
required: "表名不能为空",
},
cn_name: {
required: "中文名不能为空",
},
},
});
//选择表
$('#table_name').select2();
//生成菜单列表
$('#create_menu_list').select2();
//是否生成控制器
$('#create_controller').select2();
//是否生成模型
$('#create_model').select2();
//是否生成验证器
$('#create_validate').select2();
//控制器方法表
$('#controller_action_list').select2();
//选择父级菜单
$('#create_menu').select2();
//获取表信息
function getField(name) {
$.post('getField', {name: name}, function (result) {
if (result.code === 1) {
let $dataBody = $("#dataBody");
if (adminDebug) {
console.time('表信息与相关DOM操作耗时');
}
let controller = result.data.controller;
let model = result.data.model;
let validate = result.data.validate;
let field = result.data.field;
if (adminDebug) {
console.log('字段数量:' + field.length);
}
let table = result.data.table;
//中文名
$('#cn_name').val(table.cn_name);
//如果是自动生成类名
if ($('#auto_class_name').is(':checked')) {
$("#controller_name").val(controller.name);
$("#model_name").val(model.name);
$("#validate_name").val(validate.name);
}
$dataBody.html('');
//字段名
let field_name = "#data-template input[name='field_nameFORM_INDEX[]']";
//字段类型
let field_type = "#data-template input[name='field_typeFORM_INDEX[]']";
//是否为列表字段
let field_list = "#data-template [name='is_listFORM_INDEX[]']";
//是否为搜索字段
let field_search = "#data-template [name='is_searchFORM_INDEX[]']";
//是否为表单字段
let field_form = "#data-template [name='is_formFORM_INDEX[]']";
//中文名称
let form_name = "#data-template [name='form_nameFORM_INDEX[]']";
//表单类型
let form_type = "#data-template [name='form_typeFORM_INDEX[]']";
//表单验证
let form_validate = "#data-template [name='form_validateFORM_INDEX[]']";
//字段默认值
let field_form_default = "#data-template [name='field_defaultFORM_INDEX[]']";
//获取器/修改器
let getter_setter = "#data-template [name='getter_setterFORM_INDEX[]']";
//列表排序
let list_sort = "#data-template [name='list_sortFORM_INDEX[]']";
//
let listHtml = '';
$.each(field, function (index, item) {
//字段名
$(field_name).attr('value', item.name);
//字段类型
$(field_type).attr('value', item.field_type);
//中文名称
$(form_name).attr('value', item.cn_name);
//默认值
$(field_form_default).attr('value', item.default);
//表单类型
$(form_type).val(item.form_type);
//是否为列表字段
if (item.is_list === 1) {
$(field_list).attr('checked', true);
} else {
$(field_list).attr('checked', false);
}
//是否为搜索字段
if (item.is_search === 1) {
$(field_search).attr('checked', true);
} else {
$(field_search).attr('checked', false);
}
//是否为表单字段
if (item.is_form === 1) {
$(field_form).attr('checked', true);
} else {
$(field_form).attr('checked', false);
}
//表单类型
$(form_type).find("option[value='" + item.form_type + "']").attr("selected", true);
//表单验证内容
$(form_validate).html(item.validate_html);
//表单选项
$(form_validate).find("option[value='required']").attr("selected", true);
//获取器/修改器
if (item.getter_setter !== false) {
$(getter_setter).find("option[value='" + item.getter_setter + "']").attr("selected", true);
}
//优化生成DOM慢的问题
formIndex++;
listHtml += $("#data-template").html().replace(/FORM_INDEX/g, '[' + formIndex + ']').replace(/INDEX_ID/g, formIndex);
if (getter_setter !== false) {
$(getter_setter).find("option[value='" + item.getter_setter + "']").attr("selected", false);
}
$(form_type).find("option[value='" + item.form_type + "']").attr("selected", false);
$(field_name).attr('value', '');
$(field_type).attr('value', '');
$(form_validate).empty();
});
$dataBody.append(listHtml);
dataBodyRefreshed();
if (adminDebug) {
console.timeEnd('表信息与相关DOM操作耗时');
}
}
});
}
//表单元素类型改变
function selectField(field) {
let $field = $(field);
let form_type = $field.val();
console.log(form_type);
let $validate_select = $field.parent().parent().next().find('.form-validate-select');
$.post('getValidateSelect', {form_type: form_type}, function (result) {
if (1 === result.code) {
$validate_select.html(result.data);
$validate_select.select2();
} else {
layer.msg(result.msg);
}
});
}
//刷新菜单
function refreshMenu() {
//目前还没写,争取尽快完善
}
//字段更多设置
$("#pjax-container").off('click').on('click', '.setting-more', function () {
let $dom = $('#field_setting_div_' + $(this).data('id'));
$dom.is(":hidden") ? $dom.show() : $dom.hide();
});
//选择关联类型防呆设计
function selectRelation(obj) {
let $obj = $(obj);
let relation_type = parseInt($obj.val());
let relation_show = $obj.data('relationShow');
let relation_table = $obj.data('relationTable');
if (relation_type === 1) {
$('input[name="' + relation_table + '"]').attr('readonly', 'readonly');
$('input[name="' + relation_show + '"]').removeAttr('readonly');
} else if (relation_type === 2) {
$('input[name="' + relation_show + '"]').attr('readonly', 'readonly');
$('input[name="' + relation_table + '"]').removeAttr('readonly');
} else {
$('input[name="' + relation_table + '"]').attr('readonly', 'readonly');
$('input[name="' + relation_show + '"]').attr('readonly', 'readonly');
}
}
//列表刷新后的操作
function dataBodyRefreshed() {
$('[data-toggle="tooltip"]').tooltip();
$('#dataBody .select2').select2();
}
</script>
{/block}

View File

@ -0,0 +1,218 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-6">
<div class="box box-primary">
<!-- 表单头部 -->
<div class="box-header with-border">
<div class="btn-group">
<a class="btn flat btn-sm btn-default BackButton">
<i class="fa fa-arrow-left"></i>
返回
</a>
</div>
</div>
<form id="dataForm" class="form-horizontal dataForm" action="formField" method="post"
enctype="multipart/form-data">
<div class="box-body">
<div class="form-group">
<label for="form_name" class="col-sm-2 control-label">名称</label>
<div class="col-sm-10 col-md-4">
<input maxlength="50" id="form_name" autocomplete="off" name="form_name"
class="form-control" placeholder="请输入名称">
</div>
</div>
<div class="form-group">
<label for="field_name" class="col-sm-2 control-label">字段</label>
<div class="col-sm-10 col-md-4">
<input maxlength="50" id="field_name" autocomplete="off" name="field_name"
class="form-control" placeholder="请输入字段">
</div>
</div>
<div class="form-group">
<label for="form_type" class="col-sm-2 control-label">类型</label>
<div class="col-sm-10 col-md-4">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-list"></i></span>
<select class="form-control select2 form-type-select" id="form_type"
name="form_type">
<option value="text">文本[text]</option>
<option value="number">数字[number]</option>
<option value="password">密码[password]</option>
<option value="mobile">手机号[mobile]</option>
<option value="email">邮箱[email]</option>
<option value="id_card">身份证号[id_card]</option>
<option value="url">网址[url]</option>
<option value="ip">IP地址[ip]</option>
<option value="texterea">文本域[textarea]</option>
<option value="checkbox">复选[checkbox]</option>
<option value="switch">开关[switch]</option>
<option value="radio">单选[radio]</option>
<option value="select">选择列表[select]</option>
<option value="multi_select">多项选择列表[multi-select]</option>
<option value="image">图片上传[image]</option>
<option value="multi_image">多图上传[multi-image]</option>
<option value="file">文件上传[file]</option>
<option value="multi_file">多文件上传[multi-file]</option>
<option value="date">日期[date]</option>
<option value="date_range">日期范围[date-range]</option>
<option value="datetime">日期时间[datetime]</option>
<option value="datetime_range">日期时间范围[datetime-range]</option>
<option value="year">年[year]</option>
<option value="year_range">年范围[year-range]</option>
<option value="year_month">年月[year-month]</option>
<option value="year_month_range">年月范围[year-month-range]</option>
<option value="map">地图选点[map]</option>
<option value="color">颜色选择[color]</option>
<option value="icon">图标选择[icon]</option>
<option value="editor">富文本编辑器[editor]</option>
<option value="province_city_district">省市区[三级联动]</option>
</select>
</div>
</div>
</div>
<script>
$('#form_type').select2();
</script>
</div>
<div class="box-footer">
{:token()}
<div class="col-sm-2">
</div>
<div class="col-sm-10 col-md-4">
<div class="btn-group">
<button type="submit" class="btn flat btn-info dataFormSubmit">
生成
</button>
</div>
<div class="btn-group">
<button type="reset" class="btn flat btn-default dataFormReset">
重置
</button>
</div>
</div>
</div>
</form>
</div>
</div>
<div class="col-md-6">
<div class="box box-solid">
<div class="box-header with-border">
<h3 class="box-title">生成结果</h3>
</div>
<div class="box-body">
<textarea id="code" style="width: 100%" placeholder="生成结果" rows="6"></textarea>
</div>
<div class="box-footer">
<div class="col-sm-2">
</div>
<div class="col-sm-10 col-md-4">
<div class="btn-group">
<button class="clipboard-btn btn flat btn-info" data-clipboard-target="#code">
复制到剪切板
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<script>
// button的class的值
var clipboardDemos = new ClipboardJS('.clipboard-btn');
clipboardDemos.on('success', function (e) {
e.clearSelection();
console.info('Action:', e.action);
console.info('Text:', e.text);
console.info('Trigger:', e.trigger);
layer.msg('复制成功');
});
clipboardDemos.on('error', function (e) {
console.error('Action:', e.action);
console.error('Trigger:', e.trigger);
console.log('复制失败');
});
</script>
<script>
$(function () {
/**
* ajax表单提交
*/
$(".dataForm").submit(function (e) {
e.preventDefault();
var loadT = layer.msg('正在提交,请稍候…', {icon: 16, time: 0, shade: [0.3, "#000"]});
var form_action = $(this).attr('action');
var form_method = $(this).attr('method');
var form_data = new FormData($(this)[0]);
console.log('%cajax submit start!', ';color:#333333');
console.log('action:' + form_action);
console.log('method:' + form_method);
console.log('data:' + form_data);
$.ajax({
url: form_action,
dataType: 'json',
type: form_method,
data: form_data,
contentType: false,
processData: false,
success: function (result) {
layer.close(loadT);
layer.msg(result.msg, {
icon: result.code ? 1 : 2
});
console.log('submit success!');
if (result.code === 1) {
addCode(result.data);
console.log('%cresult success', ';color:#00a65a');
} else {
addCode('');
console.log('%cresult fail', ';color:#f39c12');
}
},
error: function (xhr, type, errorThrown) {
//异常处理;
console.log('%csubmit fail!', ';color:#dd4b39');
console.log();
console.log("type:" + type + ",readyState:" + xhr.readyState + ",status:" + xhr.status);
console.log("url:" + form_action);
console.log("data:" + form_data);
layer.close(loadT);
layer.msg('访问错误,代码' + xhr.status, {icon: 2});
}
}
);
return false;
}
);
});
function addCode(code) {
//$('#code').html(code);
$('#code').val(code);
}
</script>
{/block}

View File

@ -0,0 +1,29 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-3 col-sm-6 col-xs-12">
<div class="info-box">
<span class="info-box-icon bg-aqua"><i class="fa fa-file-code-o"></i></span>
<div class="info-box-content">
<span class="info-box-text">代码自动生成</span>
<a href="{:url('generate/add')}" class="info-box-number">点击跳转</a>
</div>
</div>
</div>
<div class="col-md-3 col-sm-6 col-xs-12">
<div class="info-box">
<span class="info-box-icon bg-red"><i class="fa fa-code"></i></span>
<div class="info-box-content">
<span class="info-box-text">表单字段生成</span>
<a href="{:url('generate/form')}" class="info-box-number">点击跳转</a>
</div>
</div>
</div>
</div>
</section>
{/block}

View File

@ -0,0 +1,376 @@
{extend name='public/base' /}
{block name='content'}
{include file='public/content_header' /}
<script src="https://www.layuicdn.com/layui/layui.js"></script>
<link rel="stylesheet" type="text/css" href="https://www.layuicdn.com/layui/css/layui.css">
<style type="text/css">
/* 图片展示
----------------------------------------------- */
ul.albums {
display: block;
min-height: 1px;
height: auto;
overflow: hidden;
padding: 5px 0;
margin: 0 15px;
border: 1px dashed #ccc;
}
ul.albums li {
position: relative;
display: inline-block;
padding: 5px;
border: 1px solid #e5e5e5;
margin: 5px 0 0 20px;
cursor: pointer;
}
ul.albums li a.btn-close {
display: block;
position: absolute;
z-index: 2;
top: -8px;
right: -10px;
width: 20px;
height: 20px;
}
ul.albums li a.btn-fm{width: 100px;
display:none;
height: 100px;
border: 0px;
opacity: 0.5;
background-color: #000;
line-height: 100px;
text-align: center;
color: #fff;
position: absolute;}
ul.albums li:hover a.btn-fm{ display: block; }
ul.albums li a.btn-fm_z{
display:none;
color: #ccc;
border: 0px;
background-color: #000;
position: absolute;
bottom: 5px;
left: 5px;
opacity: 0.6;
width: 40px;
text-align: center;
}
</style>
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
<!-- 表单头部 -->
<div class="box-header with-border">
<div class="btn-group">
<a class="btn flat btn-sm btn-default BackButton">
<i class="fa fa-arrow-left"></i>
返回
</a>
</div>
</div>
<!-- 表单 -->
<form id="dataForm" class="form-horizontal dataForm" action="" method="post"
enctype="multipart/form-data">
<div class="box-body" style="height: 725px;">
<div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
<ul class="layui-tab-title">
<li class="layui-this">基本设置</li>
<li>商品详情</li>
<li>分销设置</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<div class="form-group">
<label for="name" class="col-sm-2 control-label">商品名称</label>
<div class="col-sm-10 col-md-4">
<input id="name" name="name" value="{$data.name|default=''}" placeholder="请输入商品名称" type="text" class="form-control field-text">
</div>
</div>
<div class="form-group">
<label for="goods_category_id" class="col-sm-2 control-label">所属分类</label>
<div class="col-sm-10 col-md-4">
<select name="goods_category_id" id="goods_category_id"
class="form-control field-select" data-placeholder="请选择所属分类">
<option value=""></option>
{$goods_category_list|raw}
</select>
</div>
</div>
<script>
$('#goods_category_id').select2();
</script>
<div class="form-group">
<label for="img" class="col-sm-2 control-label">上传图片</label>
<ul class="albums" id="albums">
{foreach name="imgurl_list" item="img1"}
<li class="img">
<a class="btn-close layui-btn-primary" title="删除" href="javascript:void(0)" onclick="removeImg(this)">
<i class="layui-icon" style="font-size: 20px; line-height: 20px;"></i>
</a>
<a class="btn-fm layui-btn-primary" title="设为封面" href="javascript:void(0)" onclick="removeImg_l(this)">设置为封面</a>
<a class="btn-fm_z layui-btn-primary" {if $img1.is_cover == 1}style="display: block;"{/if} title="封面" href="javascript:void(0)">封面</a>
<img src="{$img1['thumb_image']}" width="100" height="100">
<input type="hidden" name="ori_img[]" class="ori_img" value="{$img1['ori_image']}">
<input type="hidden" name="thumb_img[]" class="thumb_img" class="inputAlbums" value="{$img1['thumb_image']}">
</li>
{/foreach}
<li id="nophoto" ><img src="/static/admin/images/nophoto_100x100.png"></li>
</ul>
<input type="hidden" name="ori_fm_img" id="ori_fm_img" value="{$ori_img|default=''}">
<input type="hidden" name="thumb_img_f" id="thumb_img_f" value="{$thumb_img|default=''}">
</div>
<script type="text/javascript">
layui.use(['upload','laydate','form'], function(){
var form = layui.form;
var upload = layui.upload;
//执行实例
upload.render({
elem: '#nophoto' //绑定元素
,url: "{:url('file/icon')}" //接口url
,data:{type:1,width:750,heigh:461}
,field:'image'
,multiple: true
,done: function(res){
var html='';
html+='<li class="img">';
html+='<a class="btn-close layui-btn-primary" title="删除" href="javascript:void(0)" onclick="removeImg(this)">';
html+='<i class="layui-icon" style="font-size: 20px; line-height: 20px;">&#xe640;</i>';
html+='</a>';
html+='<a class="btn-fm layui-btn-primary" title="设为封面" href="javascript:void(0)" onclick="removeImg_l(this)" img="">设置为封面</a>';
html+='<a class="btn-fm_z layui-btn-primary" title="封面" href="javascript:void(0)">封面</a>';
html+='<img src="'+res.data.avatar_logo_thum+'" width="100" height="100">'
html+='<input type="hidden" name="ori_img[]" class="ori_img" value="'+res.data.avatar_logo+'">';
html+='<input type="hidden" name="thumb_img[]" class="thumb_img" class="inputAlbums" value="'+res.data.avatar_logo_thum+'">';
html+='</li>';
$(".albums").prepend(html);
}
,error: function(){
layer.tips('图片错误', '#btn');
return false;
}
});
});
function removeImg(obj){
$(obj).parent().remove();
var img=$('.img').length;
if(img==5){
$('#nophoto').hide();
}else{
$('#nophoto').show();
}
var ori_img=$(obj).siblings('.ori_img').val();
var thumb_img=$('#thumb_img').val();
if(ori_img==ori_fm_img){
$('#ori_fm_img').val('');
$('#thumb_img_f').val('');
}
}
function removeImg_l(obj){
var thumb_img=$(obj).siblings('.thumb_img').val();
var ori_img=$(obj).siblings('.ori_img').val();
$('#ori_fm_img').val(ori_img);
$('#thumb_img_f').val(thumb_img);
$('.btn-fm_z').css('display','none');
$(obj).siblings('.btn-fm_z').css('display','block');
}
</script>
<div class="form-group">
<label for="price" class="col-sm-2 control-label">售价</label>
<div class="col-sm-10 col-md-4">
<input id="price" name="price" value="{$data.price|default='0.00'}"
placeholder="请输入售价" type="number" class="form-control field-number">
</div>
</div>
<div class="form-group">
<label for="attr" class="col-sm-2 control-label">规格</label>
<div class="col-sm-10 col-md-4">
<input id="attr" name="attr" value="{$data.attr|default=''}"
placeholder="请输入规格" type="text" class="form-control field-number">
</div>
</div>
<div class="form-group">
<label for="stock" class="col-sm-2 control-label">库存</label>
<div class="col-sm-10 col-md-4">
<input id="stock" name="stock" value="{$data.stock|default='100'}"
placeholder="请输入库存" type="number" class="form-control field-number">
</div>
</div>
<script>
$('#stock')
.bootstrapNumber({
upClass: 'success',
downClass: 'primary',
center: true
});
</script>
<div class="form-group">
<label for="status" class="col-sm-2 control-label">是否上架</label>
<div class="col-sm-10 col-md-4">
<input class="input-switch" id="status" value="1" {if(!isset($data)
||$data.status==1)}checked{/if} type="checkbox"/>
<input class="switch field-switch" placeholder="是否上架" name="status"
value="{$data.status|default='1'}" hidden/>
</div>
</div>
<script>
$('#status').bootstrapSwitch({
onText: "是",
offText: "否",
onColor: "success",
offColor: "danger",
onSwitchChange: function (event, state) {
$(event.target).closest('.bootstrap-switch').next().val(state ? '1' : '0').change();
}
});
</script>
<div class="form-group">
<label for="sort_number" class="col-sm-2 control-label">排序(升序)</label>
<div class="col-sm-10 col-md-4">
<input id="sort_number" name="sort_number" value="{$data.sort_number|default='1000'}"
placeholder="请输入排序(升序)" type="text" class="form-control field-text">
</div>
</div>
<script>
$('#sort_number')
.bootstrapNumber({
upClass: 'success',
downClass: 'primary',
center: true
});
</script>
</div>
<div class="layui-tab-item">
<div class="form-group">
<label for="detail" class="col-sm-2 control-label">商品详情</label>
<div class="col-sm-10">
<script id="detail" name="detail" type="text/plain">{$data.detail|raw|default=''}</script>
</div>
</div>
<script>
UE.delEditor('detail');
var ue = UE.getEditor('detail',{
serverUrl :UEServer,
});
ue.ready(function() {
ue.setHeight(500); //设置高度
});
</script>
</div>
<div class="layui-tab-item">
4
</div>
</div>
</div>
</div>
<!-- 表单底部 -->
<div class="box-footer">
{:token()}
<div class="col-sm-2">
</div>
<div class="col-sm-10 col-md-4">
{if !isset($data)}
<div class="btn-group pull-right">
<label class="createContinue">
<input type="checkbox" value="1" id="_create" name="_create"
title="继续添加数据">继续添加</label>
</div>
{/if}
<div class="btn-group">
<button type="submit" class="btn flat btn-info dataFormSubmit">
保存
</button>
</div>
<div class="btn-group">
<button type="reset" class="btn flat btn-default dataFormReset">
重置
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<script>
/** 表单验证 **/
$('#dataForm').validate({
rules: {
'goods_category_id': {
required: true,
},
'brand_id': {
required: true,
},
'name': {
required: true,
},
'origin_price': {
required: true,
},
'price': {
required: true,
},
'attr': {
required: true,
},
'detail': {
required: true,
},
'weight': {
required: true,
},
'stock': {
required: true,
},
'sort_number': {
required: true,
},
'status': {
required: true,
},
},
messages: {
'goods_category_id': {
required: "所属分类不能为空",
},
'brand_id': {
required: "品牌不能为空",
},
'name': {
required: "名称不能为空",
},
'origin_price': {
required: "原价不能为空",
},
'price': {
required: "售价不能为空",
},
'attr': {
required: "规格不能为空",
},
'detail': {
required: "详情不能为空",
},
'weight': {
required: "重量不能为空",
},
'stock': {
required: "库存不能为空",
},
'sort_number': {
required: "排序(升序不能为空",
},
'status': {
required: "是否上架不能为空",
},
}
});
</script>
{/block}

View File

@ -0,0 +1,176 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<!--数据列表页面-->
<section class="content">
<!--顶部搜索筛选-->
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body">
<form class="form-inline searchForm" id="searchForm" action="{:url('index')}" method="GET">
<div class="form-group">
<input value="{$_keywords ? $_keywords : '' ;}"
name="_keywords" id="_keywords" class="form-control input-sm" placeholder="名称">
</div>
<div class="form-group">
<select name="_order" id="_order" class="form-control input-sm index-order">
<option value="">排序字段</option>
<option value="id" {if isset($_order) && $_order=='id'}selected{/if}>ID</option>
<option value="origin_price" {if isset($_order) &&
$_order=='origin_price'}selected{/if}>原价
</option>
<option value="price" {if isset($_order) && $_order=='price'}selected{/if}>售价</option>
<option value="weight" {if isset($_order) && $_order=='weight'}selected{/if}>重量</option>
<option value="stock" {if isset($_order) && $_order=='stock'}selected{/if}>库存</option>
<option value="sort_number" {if isset($_order) && $_order=='sort_number'}selected{/if}>
排序(升序
</option>
<option value="status" {if isset($_order) && $_order=='status'}selected{/if}>是否上架
</option>
</select>
</div>
<div class="form-group">
<select name="_by" id="_by" class="form-control input-sm index-order">
<option value="">排序方式</option>
<option value="desc" {if isset($_by) && $_by=='desc'}selected{/if}>倒序</option>
<option value="asc" {if isset($_by) && $_by=='asc'}selected{/if}>正序</option>
</select>
</div>
<script>
$('#_order').select2();
$('#_by').select2();
</script>
<div class="form-group">
<button class="btn btn-sm btn-primary" type="submit"><i class="fa fa-search"></i> 查询
</button>
</div>
<div class="form-group">
<button onclick="clearSearchForm()" class="btn btn-sm btn-default" type="button"><i
class="fa fa-eraser"></i> 清空查询
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="box">
<!--数据列表顶部-->
<div class="box-header">
<div>
<a title="添加" data-toggle="tooltip" class="btn btn-primary btn-sm " href="{:url('add')}">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-danger btn-sm AjaxButton" data-toggle="tooltip" title="删除选中数据"
data-confirm-title="删除确认" data-confirm-content="您确定要删除选中的数据吗?" data-id="checked"
data-url="{:url('del')}">
<i class="fa fa-trash"></i> 删除
</a>
<a class="btn btn-success btn-sm ReloadButton" data-toggle="tooltip" title="刷新">
<i class="fa fa-refresh"></i> 刷新
</a>
</div>
</div>
<div class="box-body table-responsive">
<table class="table table-hover table-bordered datatable" width="100%">
<thead>
<tr>
<th>
<input id="dataCheckAll" type="checkbox" onclick="checkAll(this)" class="checkbox"
placeholder="全选/取消">
</th>
<th>ID</th>
<th>图片</th>
<th>名称</th>
<th>所属分类</th>
<th>品牌</th>
<th>原价</th>
<th>售价</th>
<th>重量(克)</th>
<th>库存</th>
<th>排序(升序)</th>
<th>是否上架</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{foreach name="data" item="item"}
<tr>
<td>
<input type="checkbox" onclick="checkThis(this)" name="data-checkbox"
data-id="{$item.id}" class="checkbox data-list-check" value="{$item.id}"
placeholder="选择/取消">
</td>
<td>{$item.id}</td>
<td><img class="dataListImg" src="{$item.img}"></td>
<td>{$item.name}</td>
<td>{$item.goods_category.name|default=''}</td>
<td>{$item.brand.name|default=''}</td>
<td>{$item.origin_price}</td>
<td>{$item.price}</td>
<td>{$item.weight}</td>
<td>{$item.stock}</td>
<td>{$item.sort_number}</td>
<td>{$item.status_text}</td>
<td>{$item.create_time}</td>
<td class="td-do">
<a href="{:url('edit',['id'=>$item.id])}"
class="btn btn-primary btn-xs" title="修改" data-toggle="tooltip">
<i class="fa fa-pencil"></i>
</a>
<a class="btn btn-danger btn-xs AjaxButton" data-toggle="tooltip" title="删除"
data-id="{$item.id}" data-confirm-title="删除确认"
data-confirm-content='您确定要删除ID为 <span class="text-red">{$item.id}</span> 的数据吗'
data-url="{:url('del')}">
<i class="fa fa-trash"></i>
</a>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<!-- 数据列表底部 -->
<div class="box-footer">
{$page|raw}
<label class="control-label pull-right" style="margin-right: 10px; font-weight: 100;">
<small>共{$total}条记录</small>&nbsp;
<small>每页显示</small>
&nbsp;
<select class="input-sm" onchange="changePerPage(this)">
<option value="10" {if $admin.per_page==10}selected{/if}>10</option>
<option value="20" {if $admin.per_page==20}selected{/if}>20</option>
<option value="30" {if $admin.per_page==30}selected{/if}>30</option>
<option value="50" {if $admin.per_page==50}selected{/if}>50</option>
<option value="100" {if $admin.per_page==100}selected{/if}>100</option>
</select>
&nbsp;
<small>条记录</small>
</label>
</div>
</div>
</div>
</div>
</section>
{/block}

View File

@ -0,0 +1,170 @@
{extend name='public/base' /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
<!-- 表单头部 -->
<div class="box-header with-border">
<div class="btn-group">
<a class="btn flat btn-sm btn-default BackButton">
<i class="fa fa-arrow-left"></i>
返回
</a>
</div>
</div>
<!-- 表单 -->
<form id="dataForm" class="form-horizontal dataForm" action="" method="post" enctype="multipart/form-data">
<!-- 表单字段区域 -->
<div class="box-body">
<div class="form-group box-header with-border">
<label for="name" class="col-sm-2 control-label">规格分类名称</label>
<div class="col-sm-10 col-md-4">
<input id="name" name="name" value="{$data.name|default=''}" placeholder="请输入名称" type="text" class="form-control field-text">
</div>
</div>
<div class="box-body table-responsive">
<table id="dataList" class="table table-hover table-bordered datatable" width="100%">
<thead>
<tr class="input-type">
<th>操作</th>
<th title="规格名称">规格名称</th>
<th title="排序">排序</th>
</tr>
</thead>
<tbody id="dataBody">
{foreach name='gamodel_list' key='k' id='item1'}
<tr>
<td>
<a class="btn btn-xs btn-success" onclick="addNewField(this,2)">追加</a>
<a class="btn btn-xs btn-danger" onclick="delThisField(this,1)">删除</a>
</td>
<td>
<label>
<input class="form-control field-type" value="{$item1.attr_name}" name="attr_name[{$k}][]"
placeholder="请输入规格名称">
</label>
</td>
<td>
<label>
<input class="form-control field-type" value="{$item1.sort_order}" name="sort_order[{$k}][]"
placeholder="请输入排序">
</label>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
</div>
<!-- 表单底部 -->
<div class="box-footer">
{:token()}
<div class="col-sm-2">
</div>
<div class="col-sm-10 col-md-4">
{if !isset($data)}
<div class="btn-group pull-right">
<label class="createContinue">
<input type="checkbox" value="1" id="_create" name="_create"
title="继续添加数据">继续添加</label>
</div>
{/if}
<div class="btn-group">
<button type="submit" class="btn flat btn-info dataFormSubmit">
保存
</button>
</div>
<div class="btn-group">
<button type="reset" class="btn flat btn-default dataFormReset">
重置
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<table>
<tbody id="data-template" style="display: none">
<tr>
<td>
<a class="btn btn-xs btn-success" onclick="addNewField(this,2)">追加</a>
<a class="btn btn-xs btn-danger" onclick="delThisField(this,1)">删除</a>
</td>
<td>
<label>
<input class="form-control" name="attr_nameFORM_INDEX[]" value="" placeholder="规格名称"
>
</label>
</td>
<td>
<label>
<input class="form-control" name="sort_orderFORM_INDEX[]" value="" placeholder="排序"
>
</label>
</td>
</tr>
</tbody>
</table>
</section>
<script>
/** 表单验证 **/
$('#dataForm').validate({
rules: {
'name': {
required: true,
},
},
messages: {
'name': {
required: "名称不能为空",
},
}
});
//表单索引
var formIndex ='{$gamodel_count}';
$(function () {
//默认添加一行空的字段
if(formIndex==0){
addNewField(null, 1);
}else{
dataBodyRefreshed();
}
});
//添加新的字段
function addNewField(obj, type) {
formIndex++;
let template = $("#data-template").html().replace(/FORM_INDEX/g, '[' + formIndex + ']').replace(/INDEX_ID/g, formIndex);
if (obj == null) {
$("#dataBody").append(template);
} else {
if (type === 1) {
$(obj).parent().parent().before(template);
} else {
$(obj).parent().parent().after(template);
}
}
//刷新 dataBody DOM后的操作
dataBodyRefreshed();
}
//列表刷新后的操作
function dataBodyRefreshed() {
$('[data-toggle="tooltip"]').tooltip();
}
//删除当前字段
function delThisField(obj) {
layer.confirm('您确认删除本行吗?', {title: '删除确认', closeBtn: 1, icon: 3}, function () {
$(obj).parent().parent().remove();
layer.closeAll();
});
}
</script>
{/block}

View File

@ -0,0 +1,118 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<!--数据列表页面-->
<section class="content">
<!--顶部搜索筛选-->
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body">
<form class="form-inline searchForm" id="searchForm" action="{:url('index')}" method="GET">
<div class="form-group">
<input value="{$_keywords ? $_keywords : '' ;}"
name="_keywords" id="_keywords" class="form-control input-sm" placeholder="名称">
</div>
<div class="form-group">
<button class="btn btn-sm btn-primary" type="submit"><i class="fa fa-search"></i> 查询
</button>
</div>
<div class="form-group">
<button onclick="clearSearchForm()" class="btn btn-sm btn-default" type="button"><i
class="fa fa-eraser"></i> 清空查询
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="box">
<!--数据列表顶部-->
<div class="box-header">
<div>
<a title="添加" data-toggle="tooltip" class="btn btn-primary btn-sm " href="{:url('add')}">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-danger btn-sm AjaxButton" data-toggle="tooltip" title="删除选中数据" data-confirm-title="删除确认" data-confirm-content="您确定要删除选中的数据吗?" data-id="checked" data-url="{:url('del')}">
<i class="fa fa-trash"></i> 删除
</a>
<a class="btn btn-success btn-sm ReloadButton" data-toggle="tooltip" title="刷新">
<i class="fa fa-refresh"></i> 刷新
</a>
</div>
</div>
<div class="box-body table-responsive">
<table class="table table-hover table-bordered datatable" width="100%">
<thead>
<tr>
<th>
<input id="dataCheckAll" type="checkbox" onclick="checkAll(this)" class="checkbox" placeholder="全选/取消">
</th>
<th>名称</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{foreach name="data" item="item"}
<tr>
<td>
<input type="checkbox" onclick="checkThis(this)" name="data-checkbox" data-id="{$item.id}" class="checkbox data-list-check" value="{$item.id}" placeholder="选择/取消">
</td>
<td>{$item.name}</td>
<td class="td-do">
<a href="{:url('edit',['id'=>$item.id])}"
class="btn btn-primary btn-xs" title="修改" data-toggle="tooltip">
<i class="fa fa-pencil"></i>
</a>
<a class="btn btn-danger btn-xs AjaxButton" data-toggle="tooltip" title="删除" data-id="{$item.id}" data-confirm-title="删除确认" data-confirm-content='您确定要删除ID为 <span class="text-red">{$item.id}</span> 的数据吗' data-url="{:url('del')}">
<i class="fa fa-trash"></i>
</a>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<!-- 数据列表底部 -->
<div class="box-footer">
{$page|raw}
<label class="control-label pull-right" style="margin-right: 10px; font-weight: 100;">
<small>共{$total}条记录</small>&nbsp;
<small>每页显示</small>
&nbsp;
<select class="input-sm" onchange="changePerPage(this)">
<option value="10" {if $admin.per_page==10}selected{/if}>10</option>
<option value="20" {if $admin.per_page==20}selected{/if}>20</option>
<option value="30" {if $admin.per_page==30}selected{/if}>30</option>
<option value="50" {if $admin.per_page==50}selected{/if}>50</option>
<option value="100" {if $admin.per_page==100}selected{/if}>100</option>
</select>
&nbsp;
<small>条记录</small>
</label>
</div>
</div>
</div>
</div>
</section>
{/block}

View File

@ -0,0 +1,98 @@
{extend name='public/base' /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
<!-- 表单头部 -->
<div class="box-header with-border">
<div class="btn-group">
<a class="btn flat btn-sm btn-default BackButton">
<i class="fa fa-arrow-left"></i>
返回
</a>
</div>
</div>
<!-- 表单 -->
<form id="dataForm" class="form-horizontal dataForm" action="" method="post"
enctype="multipart/form-data">
<!-- 表单字段区域 -->
<div class="box-body">
<div class="form-group">
<label for="parent_id" class="col-sm-2 control-label">上级分类</label>
<div class="col-sm-10 col-md-4">
<select name="parent_id" id="parent_id" class="form-control field-select"
data-placeholder="请选择上级分类">
<option value="0">顶级分类</option>
{$cat_list|raw}
</select>
</div>
</div>
<script>
$('#parent_id').select2();
</script>
<div class="form-group">
<label for="name" class="col-sm-2 control-label">名称</label>
<div class="col-sm-10 col-md-4">
<input id="name" name="name" value="{$data.name|default=''}" placeholder="请输入名称"
type="text" class="form-control field-text">
</div>
</div>
</div>
<!-- 表单底部 -->
<div class="box-footer">
{:token()}
<div class="col-sm-2">
</div>
<div class="col-sm-10 col-md-4">
{if !isset($data)}
<div class="btn-group pull-right">
<label class="createContinue">
<input type="checkbox" value="1" id="_create" name="_create"
title="继续添加数据">继续添加</label>
</div>
{/if}
<div class="btn-group">
<button type="submit" class="btn flat btn-info dataFormSubmit">
保存
</button>
</div>
<div class="btn-group">
<button type="reset" class="btn flat btn-default dataFormReset">
重置
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<script>
/** 表单验证 **/
$('#dataForm').validate({
rules: {
'parent_id': {
required: true,
},
'name': {
required: true,
},
},
messages: {
'parent_id': {
required: "上级分类不能为空",
},
'name': {
required: "名称不能为空",
},
}
});
</script>
{/block}

View File

@ -0,0 +1,85 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<!--数据列表页面-->
<section class="content">
<!--顶部搜索筛选-->
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body">
<form class="form-inline searchForm" id="searchForm" action="{:url('index')}" method="GET">
<div class="form-group">
<input value="{$_keywords ? $_keywords : '' ;}"
name="_keywords" id="_keywords" class="form-control input-sm" placeholder="名称">
</div>
<div class="form-group">
<button class="btn btn-sm btn-primary" type="submit"><i class="fa fa-search"></i> 查询
</button>
</div>
<div class="form-group">
<button onclick="clearSearchForm()" class="btn btn-sm btn-default" type="button"><i
class="fa fa-eraser"></i> 清空查询
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="box">
<!--数据列表顶部-->
<div class="box-header">
<div>
<a title="添加" data-toggle="tooltip" class="btn btn-primary btn-sm " href="{:url('add')}">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-danger btn-sm AjaxButton" data-toggle="tooltip" title="删除选中数据"
data-confirm-title="删除确认" data-confirm-content="您确定要删除选中的数据吗?" data-id="checked"
data-url="{:url('del')}">
<i class="fa fa-trash"></i> 删除
</a>
<a class="btn btn-success btn-sm ReloadButton" data-toggle="tooltip" title="刷新">
<i class="fa fa-refresh"></i> 刷新
</a>
</div>
</div>
<div class="box-body table-responsive">
<table class="table table-hover table-bordered datatable" width="100%">
<thead>
<tr>
<th>
<input id="dataCheckAll" type="checkbox" onclick="checkAll(this)" class="checkbox"
placeholder="全选/取消">
</th>
<th>ID</th>
<th>名称</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{$data|raw}
</tbody>
</table>
</div>
</div>
</div>
</div>
</section>
{/block}

View File

@ -0,0 +1,252 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
{if $welcome_info}
<div class="row">
<div class="pad margin no-print">
<div class="callout callout-info">
<h4><i class="fa fa-info"></i> 你好,{$user.nickname|default='管理员'}:</h4>
欢迎来到{$admin.name|default='后台管理系统'},左侧为菜单区域,右侧为功能区。
</div>
</div>
</div>
{/if}
<div class="row">
<div class="col-md-3 col-sm-6 col-xs-12">
<div class="info-box">
<span class="info-box-icon bg-aqua">
<i class="fa fa-user"></i>
</span>
<div class="info-box-content">
<span class="info-box-text">后台用户</span>
<span class="info-box-number">{$admin_user_count|default='0'}</span>
</div>
</div>
</div>
<div class="col-md-3 col-sm-6 col-xs-12">
<div class="info-box">
<span class="info-box-icon bg-red">
<i class="fa fa-users"></i>
</span>
<div class="info-box-content">
<span class="info-box-text">后台角色</span>
<span class="info-box-number">{$admin_role_count|default='0'}</span>
</div>
</div>
</div>
<div class="col-md-3 col-sm-6 col-xs-12">
<div class="info-box">
<span class="info-box-icon bg-green">
<i class="fa fa-list"></i>
</span>
<div class="info-box-content">
<span class="info-box-text">后台菜单</span>
<span class="info-box-number">{$admin_menu_count|default='0'}</span>
</div>
</div>
</div>
<div class="clearfix visible-sm-block"></div>
<div class="col-md-3 col-sm-6 col-xs-12">
<div class="info-box">
<span class="info-box-icon bg-yellow">
<i class="fa fa-keyboard-o"></i>
</span>
<div class="info-box-content">
<span class="info-box-text">操作日志</span>
<span class="info-box-number">{$admin_log_count|default='0'}</span>
</div>
</div>
</div>
</div>
<div class="row">
<section class="col-lg-7 connectedSortable" id="sortable1">
<div class="box sortable-widget" id="user_info">
<div class="box-header with-border">
<h3 class="box-title">访问信息</h3>
</div>
<div class="box-body">
<table class="table table-bordered table-striped">
<tbody>
<tr>
<th>用户系统</th>
<td>{$system_info.user_os}</td>
<th>用户IP</th>
<td>{$system_info.user_ip}</td>
</tr>
<tr>
<th>浏览器</th>
<td>{$system_info.user_browser}</td>
<th>所在城市</th>
<td>{$system_info.user_ip_address}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="box sortable-widget" id="system_info">
<div class="box-header with-border">
<h3 class="box-title">系统信息</h3>
</div>
<div class="box-body">
<table class="table table-bordered table-striped">
<tbody>
<tr>
<th>服务器系统</th>
<td>{$system_info.server_os}</td>
<th>服务器IP</th>
<td>{$system_info.server_ip}</td>
</tr>
<tr>
<th>PHP版本</th>
<td>{$system_info.php_version}</td>
<th>运行内存限制</th>
<td>{$system_info.memory_limit}</td>
</tr>
<tr>
<th>最大文件上传限制</th>
<td>{$system_info.upload_max_filesize}</td>
<th>单次上传数量限制</th>
<td>{$system_info.max_file_uploads}</td>
</tr>
<tr>
<th>最大POST限制</th>
<td>{$system_info.post_max_size}</td>
<th>项目磁盘剩余容量</th>
<td>{$system_info.disk_free}</td>
</tr>
<tr>
<th>ThinkPHP版本</th>
<td>{$system_info.think_version}</td>
<th>后台系统版本</th>
<td>{$system_info.admin_version}</td>
</tr>
<tr>
<th>MySql版本</th>
<td>{$system_info.db_version}</td>
<th>PHP当前运行模式</th>
<td>{$system_info.php_sapi_name}</td>
</tr>
<tr>
<th>PHP当前时区</th>
<td>{$system_info.timezone}</td>
<th>PHP当前时间</th>
<td>{$system_info.date_time}</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<section class="col-lg-5 connectedSortable" id="composer_info">
<div class="box sortable-widget" id="widget2">
<div class="box-header with-border">
<h3 class="box-title">依赖关系</h3>
</div>
<div class="box-body">
<table class="table table-bordered table-striped">
<tbody>
{foreach name='system_info.require_list' id='item'}
<tr>
<th>{$key}</th>
<td>{$item}</td>
</tr>
{/foreach}
{foreach name='system_info.require_dev_list' id='item'}
<tr>
<th>{$key}</th>
<td>{$item}</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
</div>
</section>
</div>
</section>
<script>
var passwordDanger = {$password_danger};
var sortableChanged = false;
var sortableIds = [];
$(function () {
$('.connectedSortable').sortable({
placeholder: 'sort-highlight',
connectWith: '.connectedSortable',
handle: '.box-header',
forcePlaceholderSize: true,
zIndex: 999999,
update: function (event, ui) {
sortableChanged = true;
let ids1 = $('#sortable1').sortable('toArray');
let ids2 = $('#sortable2').sortable('toArray');
$.each(ids2, function (index, item) {
ids1.push(item);
});
sortableIds = ids1;
console.log(sortableIds);
/* $.ajax({
type: "post",
url: "",
data: {image_ids},
dataType: "json",
success: function(result) {
window.location.reload(); //后台获取到数据刷新页面
}
});*/
}
});
$('.connectedSortable .box-header, .connectedSortable .nav-tabs-custom').css('cursor', 'move');
//密码修改检查
if(parseInt(passwordDanger)===1){
layer.confirm('系统检测到超级管理员默认密码未修改,是否马上去修改?',{title:'风险提示',closeBtn:1,icon:7},function(){
$.pjax({
url: '/admin/admin_user/profile.html#privacy',
container: '#pjax-container'
});
layer.closeAll();
});
}
});
</script>
{/block}

View File

@ -0,0 +1,349 @@
{extend name='public/base' /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
<!-- 表单头部 -->
<div class="box-header with-border">
<div class="btn-group">
<a class="btn flat btn-sm btn-default BackButton">
<i class="fa fa-arrow-left"></i>
返回
</a>
</div>
</div>
<!-- 表单 -->
<form id="dataForm" class="form-horizontal dataForm" action="" method="post" enctype="multipart/form-data">
<!-- 表单字段区域 -->
<div class="box-body">
<div class="form-group">
<label for="order_no" class="col-sm-2 control-label">订单编号</label>
<div class="col-sm-10 col-md-4">
<input id="order_no" name="order_no" value="{$data.order_no|default=''}" placeholder="请输入订单编号" type="text" class="form-control field-text">
</div>
</div>
<div class="form-group">
<label for="user_id" class="col-sm-2 control-label">下单用户</label>
<div class="col-sm-10 col-md-4">
<select name="user_id" id="user_id" class="form-control field-select" data-placeholder="请选择下单用户">
<option value=""></option>
{foreach name='user_list' id='item'}
<option value="{$item.id}" {if isset($data) && $data.user_id==$item.id}selected{/if}>
{$item.nickname}
</option>
{/foreach}
</select>
</div>
</div>
<script>
$('#user_id').select2();
</script>
<div class="form-group">
<label for="order_price" class="col-sm-2 control-label">订单金额</label>
<div class="col-sm-10 col-md-4">
<div class="input-group">
<input id="order_price" name="order_price" value="{$data.order_price|default='0.00'}" placeholder="请输入订单金额" type="number" class="form-control field-number">
</div>
</div>
</div>
<script>
$('#order_price')
.bootstrapNumber({
upClass: 'success',
downClass: 'primary',
center: true
});
</script>
<div class="form-group">
<label for="pay_price" class="col-sm-2 control-label">支付金额</label>
<div class="col-sm-10 col-md-4">
<div class="input-group">
<input id="pay_price" name="pay_price" value="{$data.pay_price|default='0.00'}" placeholder="请输入支付金额" type="number" class="form-control field-number">
</div>
</div>
</div>
<script>
$('#pay_price')
.bootstrapNumber({
upClass: 'success',
downClass: 'primary',
center: true
});
</script>
<div class="form-group">
<label for="goods_price" class="col-sm-2 control-label">商品总额</label>
<div class="col-sm-10 col-md-4">
<div class="input-group">
<input id="goods_price" name="goods_price" value="{$data.goods_price|default='0.00'}" placeholder="请输入商品总额" type="number" class="form-control field-number">
</div>
</div>
</div>
<script>
$('#goods_price')
.bootstrapNumber({
upClass: 'success',
downClass: 'primary',
center: true
});
</script>
<div class="form-group">
<label for="express_price" class="col-sm-2 control-label">运费</label>
<div class="col-sm-10 col-md-4">
<div class="input-group">
<input id="express_price" name="express_price" value="{$data.express_price|default='0.00'}" placeholder="请输入运费" type="number" class="form-control field-number">
</div>
</div>
</div>
<script>
$('#express_price')
.bootstrapNumber({
upClass: 'success',
downClass: 'primary',
center: true
});
</script>
<div class="form-group">
<label for="name" class="col-sm-2 control-label">姓名</label>
<div class="col-sm-10 col-md-4">
<input id="name" name="name" value="{$data.name|default=''}" placeholder="请输入姓名" type="text" class="form-control field-text">
</div>
</div>
<div class="form-group">
<label for="mobile" class="col-sm-2 control-label">手机号</label>
<div class="col-sm-10 col-md-4">
<input id="mobile" name="mobile" value="{$data.mobile|default=''}" placeholder="请输入手机号" type="tel" maxlength="11" class="form-control field-mobile">
</div>
</div>
<div class="form-group">
<label for="address" class="col-sm-2 control-label">收货地址</label>
<div class="col-sm-10 col-md-4">
<input id="address" name="address" value="{$data.address|default=''}" placeholder="请输入收货地址" type="text" class="form-control field-text">
</div>
</div>
<div class="form-group">
<label for="express_id" class="col-sm-2 control-label">快递公司</label>
<div class="col-sm-10 col-md-4">
<select name="express_id" id="express_id" class="form-control field-select" data-placeholder="请选择快递公司">
<option value=""></option>
{foreach name='express_list' id='item'}
<option value="{$item.id}" {if isset($data) && $data.express_id==$item.id}selected{/if}>
{$item.name}
</option>
{/foreach}
</select>
</div>
</div>
<script>
$('#express_id').select2();
</script>
<div class="form-group">
<label for="express_no" class="col-sm-2 control-label">快递单号</label>
<div class="col-sm-10 col-md-4">
<input id="express_no" name="express_no" value="{$data.express_no|default='0'}" placeholder="请输入快递单号" type="text" class="form-control field-text">
</div>
</div>
<div class="form-group">
<label for="pay_channel" class="col-sm-2 control-label">支付渠道</label>
<div class="col-sm-10 col-md-4">
<input id="pay_channel" name="pay_channel" value="{$data.pay_channel|default='1'}" placeholder="请输入支付渠道" type="text" class="form-control field-text">
</div>
</div>
<div class="form-group">
<label for="pay_status" class="col-sm-2 control-label">支付状态</label>
<div class="col-sm-10 col-md-4">
<input id="pay_status" name="pay_status" value="{$data.pay_status|default='0'}" placeholder="请输入支付状态" type="text" class="form-control field-text">
</div>
</div>
<div class="form-group">
<label for="pay_time" class="col-sm-2 control-label">付款时间</label>
<div class="col-sm-10 col-md-4">
<input id="pay_time" name="pay_time" value="{$data.pay_time|default='0'}" placeholder="请选择付款时间" type="text" class="form-control filed-datetime">
</div>
</div>
<script>
laydate.render({
elem: '#pay_time',
type: 'datetime',
value: '{$data.pay_time|default="1900-01-01 00:00:00"}'
});
</script>
<div class="form-group">
<label for="deliver_status" class="col-sm-2 control-label">发货状态</label>
<div class="col-sm-10 col-md-4">
<input id="deliver_status" name="deliver_status" value="{$data.deliver_status|default='0'}" placeholder="请输入发货状态" type="text" class="form-control field-text">
</div>
</div>
<div class="form-group">
<label for="deliver_time" class="col-sm-2 control-label">发货时间</label>
<div class="col-sm-10 col-md-4">
<input id="deliver_time" name="deliver_time" value="{$data.deliver_time|default='0'}" placeholder="请选择发货时间" type="text" class="form-control filed-datetime">
</div>
</div>
<script>
laydate.render({
elem: '#deliver_time',
type: 'datetime',
value: '{$data.deliver_time|default="1900-01-01 00:00:00"}'
});
</script>
<div class="form-group">
<label for="receive_time" class="col-sm-2 control-label">收货时间</label>
<div class="col-sm-10 col-md-4">
<input id="receive_time" name="receive_time" value="{$data.receive_time|default='0'}" placeholder="请选择收货时间" type="text" class="form-control filed-datetime">
</div>
</div>
<script>
laydate.render({
elem: '#receive_time',
type: 'datetime',
value: '{$data.receive_time|default="1900-01-01 00:00:00"}'
});
</script>
</div>
<!-- 表单底部 -->
<div class="box-footer">
{:token()}
<div class="col-sm-2">
</div>
<div class="col-sm-10 col-md-4">
{if !isset($data)}
<div class="btn-group pull-right">
<label class="createContinue">
<input type="checkbox" value="1" id="_create" name="_create"
title="继续添加数据">继续添加</label>
</div>
{/if}
<div class="btn-group">
<button type="submit" class="btn flat btn-info dataFormSubmit">
保存
</button>
</div>
<div class="btn-group">
<button type="reset" class="btn flat btn-default dataFormReset">
重置
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<script>
/** 表单验证 **/
$('#dataForm').validate({
rules: {
'order_no': {
required: true,
},
'user_id': {
required: true,
},
'order_price': {
required: true,
},
'pay_price': {
required: true,
},
'goods_price': {
required: true,
},
'express_price': {
required: true,
},
'name': {
required: true,
},
'mobile': {
required: true,
},
'address': {
required: true,
},
'express_id': {
required: true,
},
'express_no': {
required: true,
},
'pay_channel': {
required: true,
},
'pay_status': {
required: true,
},
'pay_time': {
required: true,
},
'deliver_status': {
required: true,
},
'deliver_time': {
required: true,
},
'receive_time': {
required: true,
},
},
messages: {
'order_no': {
required: "订单编号不能为空",
},
'user_id': {
required: "下单用户不能为空",
},
'order_price': {
required: "订单金额不能为空",
},
'pay_price': {
required: "支付金额不能为空",
},
'goods_price': {
required: "商品总额不能为空",
},
'express_price': {
required: "运费不能为空",
},
'name': {
required: "姓名不能为空",
},
'mobile': {
required: "手机号不能为空",
},
'address': {
required: "收货地址不能为空",
},
'express_id': {
required: "快递公司不能为空",
},
'express_no': {
required: "快递单号不能为空",
},
'pay_channel': {
required: "支付渠道不能为空",
},
'pay_status': {
required: "支付状态不能为空",
},
'pay_time': {
required: "付款时间不能为空",
},
'deliver_status': {
required: "发货状态不能为空",
},
'deliver_time': {
required: "发货时间不能为空",
},
'receive_time': {
required: "收货时间不能为空",
},
}
});
</script>
{/block}

View File

@ -0,0 +1,113 @@
<!--空白页面参考模版-->
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box">
<!--数据列表顶部-->
<div class="box-header">
<div class="btn-group">
<a class="btn flat btn-sm btn-default BackButton">
<i class="fa fa-arrow-left"></i>
返回
</a>
</div>
</div>
<div class="box-body table-responsive">
<table class="table table-hover table-bordered dataTable no-padding" width="100%">
<tbody>
<tr>
<th colspan="10" class="text-center bg-blue">基本信息</th>
</tr>
<tr>
<th>订单ID</th>
<td>{$data.id}</td>
<th>订单号</th>
<td>{$data.order_no}</td>
<th>订单金额</th>
<td>{$data.order_price}</td>
<th>下单人</th>
<td>{$data.user.nickname|default=''}[{$data.user.mobile|default=''}]</td>
<th>下单时间</th>
<td>{$data.create_time}</td>
</tr>
<tr>
<th colspan="10" class="text-center bg-blue">支付信息</th>
</tr>
<tr>
<th>应付金额</th>
<td>{$data.pay_price}</td>
<th>支付方式</th>
<td>{$data.pay_channel_text}</td>
<th>实付金额</th>
<td>{$data.pay_price}</td>
<th>支付状态</th>
<td>{$data.pay_status_text}</td>
<th>付款时间</th>
<td>{$data.pay_time}</td>
</tr>
<tr>
<th colspan="10" class="text-center bg-blue">商品信息</th>
</tr>
<tr>
<th colspan="4">名称</th>
<th colspan="2">价格</th>
<th colspan="2">数量</th>
<th colspan="2">小记</th>
</tr>
{foreach name='data.orderGoods' item='item'}
<tr>
<td colspan="4">{$item.name}</td>
<td colspan="2">{$item.price}</td>
<td colspan="2">{$item.number}</td>
<td colspan="2">{$item.total_price}</td>
</tr>
{/foreach}
<tr>
<th colspan="10" class="text-center bg-blue">收货信息</th>
</tr>
<tr>
<th>发货状态</th>
<td>{$data.deliver_status_text}</td>
<th>收货人姓名</th>
<td>{$data.name}</td>
<th>订收货人手机号</th>
<td>{$data.mobile}</td>
<th>收货地址</th>
<td>{$data.full_address}</td>
<th>快递单号</th>
<td>{$data.express_no}[{$data.express.name|default=''}]</td>
</tr>
</tbody>
</table>
</div>
<!-- 数据列表底部 -->
<div class="box-footer">
</div>
</div>
</div>
</div>
</section>
{/block}

View File

@ -0,0 +1,120 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<!--数据列表页面-->
<section class="content">
<!--顶部搜索筛选-->
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body">
<form class="form-inline searchForm" id="searchForm" action="{:url('index')}" method="GET">
<div class="form-group">
<input value="{$_keywords ? $_keywords : '' ;}"
name="_keywords" id="_keywords" class="form-control input-sm" placeholder="订单号/手机号">
</div>
<div class="form-group">
<button class="btn btn-sm btn-primary" type="submit"><i class="fa fa-search"></i> 查询
</button>
</div>
<div class="form-group">
<button onclick="clearSearchForm()" class="btn btn-sm btn-default" type="button"><i
class="fa fa-eraser"></i> 清空查询
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="box">
<!--数据列表顶部-->
<div class="box-header">
<div>
<a class="btn btn-success btn-sm ReloadButton" data-toggle="tooltip" title="刷新">
<i class="fa fa-refresh"></i> 刷新
</a>
</div>
</div>
<div class="box-body table-responsive">
<table class="table table-hover table-bordered datatable" width="100%">
<thead>
<tr>
<th>ID</th>
<th>订单编号</th>
<th>下单用户</th>
<th>订单金额</th>
<th>收货人姓名</th>
<th>收货手机号</th>
<th>收货地址</th>
<th>支付渠道</th>
<th>支付状态</th>
<th>发货状态</th>
<th>下单时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{foreach name="data" item="item"}
<tr>
<td>{$item.id}</td>
<td>{$item.order_no}</td>
<td>{$item.user.nickname|default=''}</td>
<td>{$item.order_price}</td>
<td>{$item.name}</td>
<td>{$item.mobile}</td>
<td>{$item.address}</td>
<td>{$item.pay_channel_text}</td>
<td>{$item.pay_status_text}</td>
<td>{$item.deliver_status_text}</td>
<td>{$item.create_time}</td>
<td class="td-do">
<a href="{:url('detail',['id'=>$item.id])}"
class="btn btn-primary btn-xs" title="订单详情" data-toggle="tooltip">
<i class="fa fa-info-circle"></i>
</a>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<!-- 数据列表底部 -->
<div class="box-footer">
{$page|raw}
<label class="control-label pull-right" style="margin-right: 10px; font-weight: 100;">
<small>共{$total}条记录</small>&nbsp;
<small>每页显示</small>
&nbsp;
<select class="input-sm" onchange="changePerPage(this)">
<option value="10" {if $admin.per_page==10}selected{/if}>10</option>
<option value="20" {if $admin.per_page==20}selected{/if}>20</option>
<option value="30" {if $admin.per_page==30}selected{/if}>30</option>
<option value="50" {if $admin.per_page==50}selected{/if}>50</option>
<option value="100" {if $admin.per_page==100}selected{/if}>100</option>
</select>
&nbsp;
<small>条记录</small>
</label>
</div>
</div>
</div>
</div>
</section>
{/block}

View File

@ -0,0 +1,53 @@
{if !$admin.pjax}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="renderer" content="webkit">
{/if}
{block name='title'}
<title>{$admin.title|default='Admin'} | {$admin.name|default='Admin'}</title>
{/block}
{if !$admin.pjax}
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
{include file='public/head_css' /}
{include file='public/head_js' /}
</head>
<body class="hold-transition skin-blue sidebar-mini">
<div class="wrapper">
{/if}
<!-- 顶部 -->
{block name='header'}
{include file='public/header' /}
{/block}
<!-- 左侧 -->
{block name='sidebar'}
{include file='public/sidebar' /}
{/block}
<!-- 内容 -->
<div class="content-wrapper" id="pjax-container">
{block name='content'}
{/block}
</div>
{block name='footer'}
{include file='public/footer' /}
{/block}
{block name='control_sidebar'}
{include file='public/control_sidebar' /}
{/block}
{if !$admin.pjax}
</div>
{/if}
{if !$admin.pjax}
</body>
</html>
{/if}

View File

@ -0,0 +1,32 @@
<!--内容头部-->
<section class="content-header">
<h1>
{$admin.title|default='admin'|raw}
</h1>
<ol class="breadcrumb">
<li><a href="{:url('index/index')}"><i class="fa fa-dashboard"></i> 主页</a></li>
<li class="active">{$admin.title|default='Admin'|raw}</li>
</ol>
</section>
{if $Think.session.error_message}
<!--如果有错误或者成功的消息-->
<script>
layer.msg('{$Think.session.error_message}',{icon:2});
$.pjax({
url: "{$Think.session.url}",
container: '#pjax-container'
});
</script>
{/if}
{if $Think.session.success_message}
<script>
layer.msg('{$Think.session.success_message}',{icon:1});
$.pjax({
url: '{$Think.session.url}',
container: '#pjax-container'
});
</script>
{/if}

View File

@ -0,0 +1,12 @@
<!--侧边栏-->
{if !$admin.pjax}
<aside class="control-sidebar control-sidebar-dark">
<ul class="nav nav-tabs nav-justified control-sidebar-tabs">
</ul>
<div class="tab-content">
<div class="tab-pane" id="control-sidebar-home-tab">
</div>
</div>
</aside>
<div class="control-sidebar-bg"></div>
{/if}

View File

@ -0,0 +1,10 @@
<!--页面底部-->
{if !$admin.pjax}
<footer class="main-footer">
<div class="pull-right hidden-xs">
<b>Version</b> {$admin.version|default='1.0'}
</div>
<strong>Copyright &copy; 2020 <a href="{$admin.link|default='#'}">{$admin.author|default='admin'}</a>.</strong> All rights
reserved.
</footer>
{/if}

View File

@ -0,0 +1,18 @@
<!--头部css-->
{css href="__ADMIN_PLUGINS__/bootstrap/css/bootstrap.min.css" /}
{js href="__ADMIN_PLUGINS__/bootstrap-switch/css/bootstrap-switch.min.css" /}
{css href="__ADMIN_PLUGINS__/font-awesome/css/font-awesome.min.css" /}
{css href="__ADMIN_PLUGINS__/iconpicker/css/iconpicker.min.css" /}
{css href="__ADMIN_PLUGINS__/select2/css/select2.min.css" /}
{css href="__ADMIN_PLUGINS__/fileinput/css/fileinput.min.css" /}
{css href="__ADMIN_PLUGINS__/bootstrap-colorpicker/css/bootstrap-colorpicker.min.css" /}
{css href="__ADMIN_CSS__/AdminLTE.min.css" /}
{css href="__ADMIN_CSS__/admin.css" /}
{css href="__ADMIN_CSS__/_all-skins.min.css" /}
{css href="__ADMIN_CSS__/skins.css" /}
{css href="__ADMIN_PLUGINS__/nprogress/nprogress.css" /}
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->

View File

@ -0,0 +1,47 @@
<!--头部js-->
{if !$admin.pjax}
{js href="__ADMIN_PLUGINS__/js-cookie/js.cookie-2.2.0.min.js" /}
{js href="__ADMIN_PLUGINS__/jquery/jquery.min.js" /}
{js href="__ADMIN_PLUGINS__/jquery-ui/jquery-ui.min.js" /}
{js href="__ADMIN_PLUGINS__/layer/layer.js" /}
{js href="__ADMIN_PLUGINS__/laydate/laydate.js" /}
{js href="__ADMIN_PLUGINS__/bootstrap/js/bootstrap.min.js" /}
{js href="__ADMIN_PLUGINS__/jquery-slimscroll/jquery.slimscroll.min.js" /}
{js href="__ADMIN_PLUGINS__/jquery-validation/jquery.validate.min.js" /}
{js href="__ADMIN_PLUGINS__/jquery-validation/localization/messages_zh.min.js" /}
{js href="__ADMIN_PLUGINS__/bootstrap-switch/js/bootstrap-switch.min.js" /}
{js href="__ADMIN_PLUGINS__/bootstrap-number/bootstrap-number.min.js" /}
{js href="__ADMIN_PLUGINS__/fastclick/fastclick.min.js" /}
{js href="__ADMIN_PLUGINS__/select2/js/select2.full.min.js" /}
{js href="__ADMIN_PLUGINS__/nprogress/nprogress.min.js" /}
{js href="__ADMIN_PLUGINS__/iconpicker/js/iconpicker.min.js" /}
{js href="__ADMIN_PLUGINS__/ueditor/ueditor.config.js" /}
{js href="__ADMIN_PLUGINS__/ueditor/ueditor.all.min.js" /}
{js href="__ADMIN_PLUGINS__/ueditor/lang/zh-cn/zh-cn.min.js" /}
{js href="__ADMIN_PLUGINS__/clipboard/clipboard.min.js" /}
{js href="__ADMIN_PLUGINS__/bootstrap-colorpicker/js/bootstrap-colorpicker.min.js" /}
{js href="__ADMIN_PLUGINS__/viewer/viewer.min.js" /}
{js href="__ADMIN_PLUGINS__/viewer/jquery-viewer.min.js" /}
{js href="__ADMIN_JS__/tag/jquery.tag-editor.js" /}
{css href="__ADMIN_JS__/tag/jquery.tag-editor.css" /}
<!--勿必把地图api key更换成自己的-->
<script type="text/javascript" src='//webapi.amap.com/maps?v=1.4.15&key=cccf8ea926e153be0a013d55edd47c11&plugin=AMap.ToolBar'></script>
<!-- UI组件库 1.0 -->
<script src="//webapi.amap.com/ui/1.0/main.js?v=1.0.11"></script>
<script>
//是否为debug模式
var adminDebug = {$debug};
//cookie前缀
var cookiePrefix = '{$cookie_prefix}';
//UEditor server地址
var UEServer = "{:url('editor/server')}";
//列表页当前选择的ID
var dataSelectIds = [];
</script>
{js href="__ADMIN_JS__/adminlte.min.js" /}
{js href="__ADMIN_JS__/jquery.pjax.js" /}
{js href="__ADMIN_JS__/admin.js" /}
{js href="__ADMIN_JS__/demo.js" /}
{js href="__ADMIN_JS__/app.js" /}
{/if}

View File

@ -0,0 +1,54 @@
<!--网页头部-->
{if !$admin.pjax}
<header class="main-header">
<a class="logo">
<span class="logo-mini">{$admin.short_name|default='Backend'}</span>
<span class="logo-lg">{$admin.name|default='Backend'}</span>
</a>
<nav class="navbar navbar-static-top">
<a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<div class="navbar-custom-menu">
<ul class="nav navbar-nav">
<li class="dropdown messages-menu">
<a href="#" class="dropdown-toggle ReloadButton" title="刷新页面" data-toggle="dropdown">
<i class="fa fa-refresh"></i>
</a>
</li>
<li class="dropdown user user-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<img src="{$admin.user.avatar|default='__ADMIN_IMAGES__/avatar.png'}" class="user-image" alt="用户头像">
<span class="hidden-xs">{$admin.user.nickname|default=''}</span>
</a>
<ul class="dropdown-menu">
<li class="user-header">
<img src="{$admin.user.avatar|default='__ADMIN_IMAGES__/avatar.png'}" class="img-circle" alt="用户头像">
<p>
{$admin.user.nickname|default=''}
<small>{$admin.user.username|default=''}</small>
</p>
</li>
<li class="user-footer">
<div class="pull-left">
<a href="{:url('admin_user/profile')}" class="btn btn-default btn-flat">个人资料</a>
</div>
<div class="pull-right">
<a href="{:url('auth/logout')}" class="btn btn-default btn-flat">退出</a>
</div>
</li>
</ul>
</li>
<li>
<a href="#" data-toggle="control-sidebar"><i class="fa fa-gears"></i></a>
</li>
</ul>
</div>
</nav>
</header>
{/if}

View File

@ -0,0 +1,30 @@
<!--左侧菜单-->
{if !$admin.pjax}
<aside class="main-sidebar">
<section class="sidebar">
<div class="user-panel">
<div class="pull-left image">
<img src="{$admin.user.avatar|default='__BACKEND_IMAGES__/avatar.png'}" class="img-circle" alt="用户头像">
</div>
<div class="pull-left info">
<p>{$admin.user.nickname|default=''}</p>
<a><i class="fa fa-circle text-success"></i> 在线</a>
</div>
</div>
<form method="get" class="sidebar-form" id="sidebar-form">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="搜索菜单" id="search-input">
<span class="input-group-btn">
<button type="submit" name="search" id="search-btn" class="btn btn-flat">
<i class="fa fa-search"></i>
</button>
</span>
</div>
</form>
<ul class="sidebar-menu" data-widget="tree">
<li class="header">导航菜单</li>
{$admin.menu|default=''|raw}
</ul>
</section>
</aside>
{/if}

View File

@ -0,0 +1,179 @@
{extend name='public/base' /}
{block name='content'}
{include file='public/content_header' /}
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
<!-- 表单头部 -->
<div class="box-header with-border">
<div class="btn-group">
<a class="btn flat btn-sm btn-default BackButton">
<i class="fa fa-arrow-left"></i>
返回
</a>
</div>
</div>
<!-- 表单 -->
<form id="dataForm" class="form-horizontal dataForm" action="" method="post"
enctype="multipart/form-data">
<!-- 表单字段区域 -->
<div class="box-body">
<div class="form-group">
<label for="name" class="col-sm-2 control-label">名称</label>
<div class="col-sm-10 col-md-4">
<input id="name" name="name" value="{$data.name|default=''}" placeholder="请输入名称"
type="text" class="form-control field-text">
</div>
</div>
<div class="form-group">
<label for="img" class="col-sm-2 control-label">图片</label>
<div class="col-sm-10 col-md-4">
<input id="img" name="img" placeholder="请上传图片" type="file"
class="form-control field-image" data-initial-preview="{$data.img|default=''}">
</div>
</div>
<script>
$('#img').fileinput({
language: 'zh',
overwriteInitial: true,
browseLabel: '浏览',
initialPreviewAsData: true,
dropZoneEnabled: false,
showUpload: false,
showRemove: false,
allowedFileTypes: ['image'],
maxFileSize: 10240,
});
</script>
<div class="form-group">
<label for="jump_type" class="col-sm-2 control-label">跳转类型</label>
<div class="col-sm-10 col-md-4">
<select name="jump_type" id="jump_type" class="form-control field-select"
data-placeholder="请选择跳转类型" onchange="getTargetList(this.value)">
<option value=""></option>
{foreach name='jump_type' id='item'}
<option value="{$item.id}" {if isset($data) &&
$data.jump_type==$item.id}selected{/if}>{$item.name}
</option>
{/foreach}
</select>
</div>
</div>
<script>
$('#jump_type').select2();
</script>
<div class="form-group">
<label for="jump_target" class="col-sm-2 control-label">跳转目标</label>
<div class="col-sm-10 col-md-4">
<select name="jump_target" id="jump_target" class="form-control field-select">
</select>
</div>
</div>
<script>
$('#jump_target').select2({
placeholder: '请选择跳转目标'
});
</script>
<div class="form-group">
<label for="sort_number" class="col-sm-2 control-label">排序</label>
<div class="col-sm-10 col-md-4">
<input id="sort_number" name="sort_number" value="{$data.sort_number|default='1000'}"
placeholder="请输入排序" type="text" class="form-control field-text">
</div>
</div>
</div>
<!-- 表单底部 -->
<div class="box-footer">
{:token()}
<div class="col-sm-2">
</div>
<div class="col-sm-10 col-md-4">
{if !isset($data)}
<div class="btn-group pull-right">
<label class="createContinue">
<input type="checkbox" value="1" id="_create" name="_create"
title="继续添加数据">继续添加</label>
</div>
{/if}
<div class="btn-group">
<button type="submit" class="btn flat btn-info dataFormSubmit">
保存
</button>
</div>
<div class="btn-group">
<button type="reset" class="btn flat btn-default dataFormReset">
重置
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<script>
/** 表单验证 **/
$('#dataForm').validate({
rules: {
'name': {
required: true,
},
'jump_type': {
required: true,
},
'jump_target': {
required: true,
},
'sort_number': {
required: true,
},
},
messages: {
'name': {
required: "名称不能为空",
},
'jump_type': {
required: "跳转类型不能为空",
},
'jump_target': {
required: "跳转目标不能为空",
},
'sort_number': {
required: "排序不能为空",
},
}
});
function getTargetList(id) {
var html ='';
var $jump_target = $('#jump_target');
id = parseInt(id);
if (id !== 3) {
$.post('{:url("pub/getSlideTargetData")}', {type_id: id}, function (result) {
$.each(result.data,function (index, item) {
html+='<option value="'+item.id+'">'+item.name+'</option>';
});
$jump_target.html(html);
$jump_target.select2();
});
}else{
$jump_target.html(html);
$jump_target.select2({
tags:true,
placeholder:'请输入需要跳转的网址',
});
}
}
</script>
{/block}

View File

@ -0,0 +1,137 @@
{extend name="public/base" /}
{block name='content'}
{include file='public/content_header' /}
<!--数据列表页面-->
<section class="content">
<!--顶部搜索筛选-->
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body">
<form class="form-inline searchForm" id="searchForm" action="{:url('index')}" method="GET">
<div class="form-group">
<input value="{$_keywords ? $_keywords : '' ;}"
name="_keywords" id="_keywords" class="form-control input-sm" placeholder="名称">
</div>
<div class="form-group">
<button class="btn btn-sm btn-primary" type="submit"><i class="fa fa-search"></i> 查询
</button>
</div>
<div class="form-group">
<button onclick="clearSearchForm()" class="btn btn-sm btn-default" type="button"><i
class="fa fa-eraser"></i> 清空查询
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="box">
<!--数据列表顶部-->
<div class="box-header">
<div>
<a title="添加" data-toggle="tooltip" class="btn btn-primary btn-sm " href="{:url('add')}">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-danger btn-sm AjaxButton" data-toggle="tooltip" title="删除选中数据"
data-confirm-title="删除确认" data-confirm-content="您确定要删除选中的数据吗?" data-id="checked"
data-url="{:url('del')}">
<i class="fa fa-trash"></i> 删除
</a>
<a class="btn btn-success btn-sm ReloadButton" data-toggle="tooltip" title="刷新">
<i class="fa fa-refresh"></i> 刷新
</a>
</div>
</div>
<div class="box-body table-responsive">
<table class="table table-hover table-bordered datatable" width="100%">
<thead>
<tr>
<th>
<input id="dataCheckAll" type="checkbox" onclick="checkAll(this)" class="checkbox"
placeholder="全选/取消">
</th>
<th>ID</th>
<th>名称</th>
<th>图片</th>
<th>跳转类型</th>
<th>跳转目标</th>
<th>排序</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{foreach name="data" item="item"}
<tr>
<td>
<input type="checkbox" onclick="checkThis(this)" name="data-checkbox"
data-id="{$item.id}" class="checkbox data-list-check" value="{$item.id}"
placeholder="选择/取消">
</td>
<td>{$item.id}</td>
<td>{$item.name}</td>
<td><img class="dataListImg" src="{$item.img}"></td>
<td>{$item.jump_type_text}</td>
<td>{$item.jump_target_text}</td>
<td>{$item.sort_number}</td>
<td>{$item.create_time}</td>
<td class="td-do">
<a href="{:url('edit',['id'=>$item.id])}"
class="btn btn-primary btn-xs" title="修改" data-toggle="tooltip">
<i class="fa fa-pencil"></i>
</a>
<a class="btn btn-danger btn-xs AjaxButton" data-toggle="tooltip" title="删除"
data-id="{$item.id}" data-confirm-title="删除确认"
data-confirm-content='您确定要删除ID为 <span class="text-red">{$item.id}</span> 的数据吗'
data-url="{:url('del')}">
<i class="fa fa-trash"></i>
</a>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<!-- 数据列表底部 -->
<div class="box-footer">
{$page|raw}
<label class="control-label pull-right" style="margin-right: 10px; font-weight: 100;">
<small>共{$total}条记录</small>&nbsp;
<small>每页显示</small>
&nbsp;
<select class="input-sm" onchange="changePerPage(this)">
<option value="10" {if $admin.per_page==10}selected{/if}>10</option>
<option value="20" {if $admin.per_page==20}selected{/if}>20</option>
<option value="30" {if $admin.per_page==30}selected{/if}>30</option>
<option value="50" {if $admin.per_page==50}selected{/if}>50</option>
<option value="100" {if $admin.per_page==100}selected{/if}>100</option>
</select>
&nbsp;
<small>条记录</small>
</label>
</div>
</div>
</div>
</div>
</section>
{/block}

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