mirror of
https://gitee.com/zoujingli/ThinkAdmin.git
synced 2025-04-06 03:58:04 +08:00
Compare commits
244 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
70e3631702 | ||
|
3f532af683 | ||
|
88751808e0 | ||
|
d17430c97f | ||
|
5613c16d50 | ||
|
2c553ca8a9 | ||
|
a7e2b2b0ac | ||
|
02f7aa7962 | ||
|
7df16fb364 | ||
|
1e986f331b | ||
|
a2dd4c646f | ||
|
ecfb50a9ac | ||
|
d8a8907b57 | ||
|
7f5b387ace | ||
|
e57bb41588 | ||
|
aa17336fca | ||
|
42c9a06228 | ||
|
0148d85072 | ||
|
ada04f0246 | ||
|
3b85dd82c8 | ||
|
dd286a8747 | ||
|
b0e5e8e8d5 | ||
|
30cd9b9218 | ||
|
de741a9878 | ||
|
a181f7c1c0 | ||
|
c3798c2255 | ||
|
9bd3c21297 | ||
|
bfe944c663 | ||
|
fbdd008828 | ||
|
74f4484c59 | ||
|
2b40fdad93 | ||
|
19a92b4a16 | ||
|
8cc632c3de | ||
|
9f253a75bc | ||
|
32be486825 | ||
|
ec4e26ae45 | ||
|
3b4b462a76 | ||
|
be01a6f449 | ||
|
732f7e8b53 | ||
|
44400b039b | ||
|
44f8407aef | ||
|
0ad33cda04 | ||
|
4632ebbd7a | ||
|
bda62319a2 | ||
|
c2030658c2 | ||
|
d2b0185eb5 | ||
|
8baf6877b0 | ||
|
c0f019cd9c | ||
|
cb47bd0e53 | ||
|
1c958dce85 | ||
|
aa8480ae37 | ||
|
33f0574bcd | ||
|
082ac9d5c4 | ||
|
9180fb3e45 | ||
|
a31d5f62e7 | ||
|
a3067ab5fb | ||
|
7c79fe377b | ||
|
075c00fbf7 | ||
|
ba998bdb4b | ||
|
54bdb10d82 | ||
|
6f66ee345d | ||
|
99046439d4 | ||
|
0a51f6bb78 | ||
|
cfcb183117 | ||
|
c8f0343c2c | ||
|
649e6757f1 | ||
|
542ffc845d | ||
|
d92749b7d7 | ||
|
b7b3610b54 | ||
|
f00f9f629e | ||
|
294c8b82a6 | ||
|
6cbb687862 | ||
|
90228f0ff6 | ||
|
983496fd9c | ||
|
6ae1789cc5 | ||
|
d8b2170555 | ||
|
36ce2c7654 | ||
|
84379c459f | ||
|
1e46a7fad2 | ||
|
a3fad57138 | ||
|
3d9836d5d5 | ||
|
88e8b5d4a3 | ||
|
c3dcb3a9f6 | ||
|
4f8e4bf443 | ||
|
5e153a92a9 | ||
|
d32c23432d | ||
|
a47ef73a5b | ||
|
ea4e646185 | ||
|
1809e34661 | ||
|
c2b887cc45 | ||
|
9bae4fbf6a | ||
|
d84ec4fe6c | ||
|
6a41175e1d | ||
|
44950d42c0 | ||
|
642d73fbe8 | ||
|
0653cfcc4a | ||
|
ed74e6b8ad | ||
|
593316a927 | ||
|
02a1c421f4 | ||
|
8126c17197 | ||
|
ccd6d15bfb | ||
|
9f2b4a6b46 | ||
|
c1e26665bf | ||
|
b4d3be8785 | ||
|
7e8e721883 | ||
|
cfb3ff4938 | ||
|
bf6220d35f | ||
|
9326343474 | ||
|
7d778dc406 | ||
|
2efa2ebb33 | ||
|
2cd8bd973a | ||
|
790e0799ba | ||
|
eccba878bb | ||
|
ef9f90288d | ||
|
8ae4647205 | ||
|
c83bf37ac8 | ||
|
734c0fda04 | ||
|
191b4b6f38 | ||
|
fe3b002fa4 | ||
|
55c1dc17b3 | ||
|
9b5239ece8 | ||
|
cb1a1a263a | ||
|
ae8d38b509 | ||
|
9f1687f08c | ||
|
f371d9ca4b | ||
|
a2423ec433 | ||
|
7d4983ca43 | ||
|
58bbd06e15 | ||
|
9eb6077149 | ||
|
06ed50c94c | ||
|
e270e81223 | ||
|
b8ad663178 | ||
|
3d5f8afc1b | ||
|
c876adb1e9 | ||
|
d3d397ab9a | ||
|
e0e71532fa | ||
|
823780bdb2 | ||
|
484e9d9d19 | ||
|
30274cffeb | ||
|
2e5759fce5 | ||
|
5217883a26 | ||
|
3e6189ceb7 | ||
|
804889743a | ||
|
4424958455 | ||
|
2f0aadbe65 | ||
|
4c694cffc6 | ||
|
e6cd7009d3 | ||
|
5014ccabff | ||
|
258611060f | ||
|
f518828cdc | ||
|
d72c26cba7 | ||
|
01ef5bc0f5 | ||
|
f277d5fda3 | ||
|
18690abcec | ||
|
5474c0cc8d | ||
|
f25bbb8c85 | ||
|
b95f248c33 | ||
|
646baba0aa | ||
|
eb96f143c2 | ||
|
c5083b4f82 | ||
|
24ba7a3289 | ||
|
62d5037f4e | ||
|
cc3e774ae8 | ||
|
5c97e7149c | ||
|
180f044e37 | ||
|
6f2d88e27a | ||
|
9a97bdb8ab | ||
|
35b5999f60 | ||
|
45ec382ddc | ||
|
21b9e107c5 | ||
|
85b8c55b0a | ||
|
423a12e569 | ||
|
825163364b | ||
|
52d11305a2 | ||
|
48c49d6d01 | ||
|
4455a2224b | ||
|
5fb289558b | ||
|
4f3e8ac8a9 | ||
|
569e2338e3 | ||
|
179928801d | ||
|
cf7c4b6c34 | ||
|
7ad9baa59c | ||
|
1368f1e986 | ||
|
ac664a269d | ||
|
c10936ab9e | ||
|
9bbe01a4b8 | ||
|
3a0f5b1953 | ||
|
28818bc8e1 | ||
|
b6a0db5b74 | ||
|
93ecdbf432 | ||
|
17a27b59ed | ||
|
42a842f90c | ||
|
0ae6f142fd | ||
|
fc824777ab | ||
|
13c505bb03 | ||
|
2e2c8e1b49 | ||
|
e61f624ce6 | ||
|
54bfcfa4ba | ||
|
dbf43b440b | ||
|
4740c66768 | ||
|
b597feb6df | ||
|
28f7aef0b7 | ||
|
9dbaf69695 | ||
|
34262095fe | ||
|
1041c43fb1 | ||
|
4940a6be9c | ||
|
3d7aad2172 | ||
|
d5ab364422 | ||
|
0f035d771b | ||
|
aca4c270c0 | ||
|
5cd53110a3 | ||
|
7bf956c030 | ||
|
951133fa8b | ||
|
b44a92ba76 | ||
|
ef35f1d616 | ||
|
c67ced5b54 | ||
|
6f0f54845e | ||
|
ad17150edb | ||
|
ffbb29512f | ||
|
dd81cbf778 | ||
|
bb7d78078e | ||
|
c57bc6fb26 | ||
|
6f66b5cb3e | ||
|
095017c5f2 | ||
|
e53f6e25f9 | ||
|
928a4d8122 | ||
|
e0fc5216e6 | ||
|
191fced9ec | ||
|
6a7c9a2a0b | ||
|
a6709b275f | ||
|
d09a587f03 | ||
|
faa066cd44 | ||
|
bd0e87a1e7 | ||
|
bffaeb75bb | ||
|
7b7dda7827 | ||
|
5900ae17d4 | ||
|
6e5816ef67 | ||
|
65314f5aea | ||
|
224f68ab1b | ||
|
5c864c8989 | ||
|
607e13f8e4 | ||
|
e6d809445d | ||
|
4d820e1618 | ||
|
03902c68b6 |
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -1,3 +0,0 @@
|
||||
*.js linguist-language=php
|
||||
*.css linguist-language=php
|
||||
*.html linguist-language=php
|
40
.gitignore
vendored
40
.gitignore
vendored
@ -2,17 +2,33 @@
|
||||
.git
|
||||
.svn
|
||||
.idea
|
||||
.fleet
|
||||
.vscode
|
||||
*.log
|
||||
.DS_Store
|
||||
vendor
|
||||
runtime
|
||||
safefile
|
||||
nbproject
|
||||
composer.lock
|
||||
public/upload
|
||||
public/.user.ini
|
||||
public/favicon.ico
|
||||
public/static/theme/css/_*.css*
|
||||
public/static/theme/css/node_modules
|
||||
public/static/theme/css/package-lock.json
|
||||
|
||||
/vendor
|
||||
/runtime
|
||||
/safefile
|
||||
/nbproject
|
||||
/composer.lock
|
||||
!composer.json
|
||||
|
||||
/404.html
|
||||
/.user.ini
|
||||
/index.html
|
||||
/public/upload
|
||||
/public/404.html
|
||||
/public/.user.ini
|
||||
/public/index.html
|
||||
/public/favicon.ico
|
||||
/database/sqlite.db
|
||||
|
||||
think
|
||||
app/admin
|
||||
app/wechat
|
||||
public/index.php
|
||||
public/router.php
|
||||
public/static/plugs
|
||||
public/static/theme
|
||||
public/static/admin.js
|
||||
public/static/login.js
|
1101
SQL01-数据表结构.sql
1101
SQL01-数据表结构.sql
File diff suppressed because it is too large
Load Diff
7699
SQL02-数据初始化.sql
7699
SQL02-数据初始化.sql
File diff suppressed because it is too large
Load Diff
@ -1,96 +0,0 @@
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- 尝试创建微信自动回复数据表
|
||||
CREATE TABLE IF NOT EXISTS `wechat_auto`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '类型(text,image,news)',
|
||||
`time` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '延迟时间',
|
||||
`code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '消息编号',
|
||||
`appid` char(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '公众号APPID',
|
||||
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '文本内容',
|
||||
`image_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '图片链接',
|
||||
`voice_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '语音链接',
|
||||
`music_title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '音乐标题',
|
||||
`music_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '音乐链接',
|
||||
`music_image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '缩略图片',
|
||||
`music_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '音乐描述',
|
||||
`video_title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '视频标题',
|
||||
`video_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '视频URL',
|
||||
`video_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '视频描述',
|
||||
`news_id` bigint(20) UNSIGNED NULL DEFAULT NULL COMMENT '图文ID',
|
||||
`status` tinyint(1) UNSIGNED NULL DEFAULT 1 COMMENT '状态(0禁用,1启用)',
|
||||
`create_by` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '创建人',
|
||||
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `idx_wechat_auto_type` (`type`) USING BTREE,
|
||||
INDEX `idx_wechat_auto_keys` (`time`) USING BTREE,
|
||||
INDEX `idx_wechat_auto_appid` (`appid`) USING BTREE,
|
||||
INDEX `idx_wechat_auto_code` (`code`) USING BTREE
|
||||
) ENGINE = InnoDB
|
||||
AUTO_INCREMENT = 1
|
||||
CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci COMMENT = '微信-回复'
|
||||
ROW_FORMAT = COMPACT;
|
||||
|
||||
-- 调整字段名称长度
|
||||
ALTER TABLE `system_queue`
|
||||
MODIFY COLUMN `title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '任务名称' AFTER `code`;
|
||||
|
||||
-- 尝试创建数据字典数据表
|
||||
CREATE TABLE IF NOT EXISTS `system_base`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '数据类型',
|
||||
`code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '数据代码',
|
||||
`name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '数据名称',
|
||||
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '数据内容',
|
||||
`sort` bigint(20) NULL DEFAULT 0 COMMENT '排序权重',
|
||||
`status` tinyint(1) NULL DEFAULT 1 COMMENT '数据状态(0禁用,1启动)',
|
||||
`deleted` tinyint(1) NULL DEFAULT 0 COMMENT '删除状态(0正常,1已删)',
|
||||
`deleted_at` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '删除时间',
|
||||
`deleted_by` bigint(20) NULL DEFAULT 0 COMMENT '删除用户',
|
||||
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `idx_system_base_type` (`type`) USING BTREE,
|
||||
INDEX `idx_system_base_code` (`code`) USING BTREE,
|
||||
INDEX `idx_system_base_name` (`name`(191)) USING BTREE
|
||||
) ENGINE = InnoDB
|
||||
AUTO_INCREMENT = 1
|
||||
CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci COMMENT = '系统-字典'
|
||||
ROW_FORMAT = COMPACT;
|
||||
|
||||
-- 权限表增加身份权限字段
|
||||
ALTER TABLE `system_user`
|
||||
ADD COLUMN `usertype` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '用户类型' AFTER `id`;
|
||||
|
||||
-- 尝试创建系统文件数据表
|
||||
CREATE TABLE IF NOT EXISTS `system_file` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '上传类型',
|
||||
`hash` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '文件哈希',
|
||||
`name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '文件名称',
|
||||
`xext` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '文件后缀',
|
||||
`xurl` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '访问链接',
|
||||
`xkey` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '文件路径',
|
||||
`mime` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '文件类型',
|
||||
`size` bigint(20) NULL DEFAULT 0 COMMENT '文件大小',
|
||||
`uuid` bigint(20) NULL DEFAULT 0 COMMENT '用户编号',
|
||||
`isfast` tinyint(1) NULL DEFAULT 0 COMMENT '是否秒传',
|
||||
`issafe` tinyint(1) NULL DEFAULT 0 COMMENT '安全模式',
|
||||
`status` tinyint(1) NULL DEFAULT 1 COMMENT '上传状态(1悬空,2落地)',
|
||||
`create_at` datetime NULL DEFAULT NULL COMMENT '创建时间',
|
||||
`update_at` datetime NULL DEFAULT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `idx_system_file_type`(`type`) USING BTREE,
|
||||
INDEX `idx_system_file_hash`(`hash`) USING BTREE,
|
||||
INDEX `idx_system_file_uuid`(`uuid`) USING BTREE,
|
||||
INDEX `idx_system_file_xext`(`xext`) USING BTREE,
|
||||
INDEX `idx_system_file_status`(`status`) USING BTREE,
|
||||
INDEX `idx_system_file_issafe`(`issafe`) USING BTREE,
|
||||
INDEX `idx_system_file_isfast`(`isfast`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统-文件' ROW_FORMAT = COMPACT;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
@ -1,124 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use think\admin\Controller;
|
||||
use think\admin\helper\QueryHelper;
|
||||
use think\admin\model\SystemAuth;
|
||||
use think\admin\model\SystemNode;
|
||||
use think\admin\service\AdminService;
|
||||
|
||||
/**
|
||||
* 系统权限管理
|
||||
* Class Auth
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Auth extends Controller
|
||||
{
|
||||
/**
|
||||
* 系统权限管理
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
SystemAuth::mQuery()->layTable(function () {
|
||||
$this->title = '系统权限管理';
|
||||
}, function (QueryHelper $query) {
|
||||
$query->dateBetween('create_at')->like('title,desc')->equal('status,utype');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加系统权限
|
||||
* @auth true
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
SystemAuth::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑系统权限
|
||||
* @auth true
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
SystemAuth::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改权限状态
|
||||
* @auth true
|
||||
*/
|
||||
public function state()
|
||||
{
|
||||
SystemAuth::mSave($this->_vali([
|
||||
'status.in:0,1' => '状态值范围异常!',
|
||||
'status.require' => '状态值不能为空!',
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除系统权限
|
||||
* @auth true
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
SystemAuth::mDelete();
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限配置节点
|
||||
* @auth true
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function apply()
|
||||
{
|
||||
$map = $this->_vali(['auth.require#id' => '权限ID不能为空!']);
|
||||
if (input('action') === 'get') {
|
||||
if ($this->app->isDebug()) AdminService::clearCache();
|
||||
$nodes = SystemNode::mk()->where($map)->column('node');
|
||||
$this->success('获取权限节点成功!', AdminService::getTree($nodes));
|
||||
} elseif (input('action') === 'save') {
|
||||
[$post, $data] = [$this->request->post(), []];
|
||||
foreach ($post['nodes'] ?? [] as $node) {
|
||||
$data[] = ['auth' => $map['auth'], 'node' => $node];
|
||||
}
|
||||
SystemNode::mk()->where($map)->delete();
|
||||
SystemNode::mk()->insertAll($data);
|
||||
sysoplog('系统权限管理', "配置系统权限[{$map['auth']}]授权成功");
|
||||
$this->success('访问权限修改成功!', 'javascript:history.back()');
|
||||
} else {
|
||||
SystemAuth::mForm('apply');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单后置数据处理
|
||||
* @param array $data
|
||||
*/
|
||||
protected function _apply_form_filter(array &$data)
|
||||
{
|
||||
if ($this->request->isGet()) {
|
||||
$this->title = "编辑【{$data['title']}】授权";
|
||||
}
|
||||
}
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use think\admin\Controller;
|
||||
use think\admin\helper\QueryHelper;
|
||||
use think\admin\model\SystemBase;
|
||||
|
||||
/**
|
||||
* 数据字典管理
|
||||
* Class Base
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Base extends Controller
|
||||
{
|
||||
/**
|
||||
* 数据字典管理
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
SystemBase::mQuery()->layTable(function () {
|
||||
$this->title = '数据字典管理';
|
||||
$this->types = SystemBase::types();
|
||||
$this->type = $this->get['type'] ?? ($this->types[0] ?? '-');
|
||||
}, function (QueryHelper $query) {
|
||||
$query->where(['deleted' => 0])->equal('type');
|
||||
$query->like('code,name,status')->dateBetween('create_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加数据字典
|
||||
* @auth true
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
SystemBase::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑数据字典
|
||||
* @auth true
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
SystemBase::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单数据处理
|
||||
* @param array $data
|
||||
* @throws \think\db\exception\DbException
|
||||
*/
|
||||
protected function _form_filter(array &$data)
|
||||
{
|
||||
if ($this->request->isGet()) {
|
||||
$this->types = SystemBase::types();
|
||||
$this->types[] = '--- 新增类型 ---';
|
||||
$this->type = input('get.type') ?: ($this->types[0] ?? '-');
|
||||
} else {
|
||||
$map = [];
|
||||
$map[] = ['deleted', '=', 0];
|
||||
$map[] = ['code', '=', $data['code']];
|
||||
$map[] = ['type', '=', $data['type']];
|
||||
if (isset($data['id'])) $map[] = ['id', '<>', $data['id']];
|
||||
if (SystemBase::mk()->where($map)->count() > 0) {
|
||||
$this->error("同类型的数据编码已经存在!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改数据状态
|
||||
* @auth true
|
||||
*/
|
||||
public function state()
|
||||
{
|
||||
SystemBase::mSave($this->_vali([
|
||||
'status.in:0,1' => '状态值范围异常!',
|
||||
'status.require' => '状态值不能为空!',
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除数据记录
|
||||
* @auth true
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
SystemBase::mDelete();
|
||||
}
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use think\admin\Controller;
|
||||
use think\admin\service\AdminService;
|
||||
use think\admin\service\ModuleService;
|
||||
use think\admin\service\SystemService;
|
||||
use think\admin\storage\AliossStorage;
|
||||
use think\admin\storage\QiniuStorage;
|
||||
use think\admin\storage\TxcosStorage;
|
||||
|
||||
/**
|
||||
* 系统参数配置
|
||||
* Class Config
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Config extends Controller
|
||||
{
|
||||
const themes = [
|
||||
'default' => '默认色0',
|
||||
'white' => '简约白0',
|
||||
'red-1' => '玫瑰红1',
|
||||
'blue-1' => '深空蓝1',
|
||||
'green-1' => '小草绿1',
|
||||
'black-1' => '经典黑1',
|
||||
'red-2' => '玫瑰红2',
|
||||
'blue-2' => '深空蓝2',
|
||||
'green-2' => '小草绿2',
|
||||
'black-2' => '经典黑2',
|
||||
];
|
||||
|
||||
/**
|
||||
* 系统参数配置
|
||||
* @auth true
|
||||
* @menu true
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->title = '系统参数配置';
|
||||
$this->super = AdminService::isSuper();
|
||||
$this->version = ModuleService::getVersion();
|
||||
$this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改系统参数
|
||||
* @auth true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function system()
|
||||
{
|
||||
$this->_applyFormToken();
|
||||
if ($this->request->isGet()) {
|
||||
$this->title = '修改系统参数';
|
||||
$this->themes = static::themes;
|
||||
$this->fetch();
|
||||
} else {
|
||||
$post = $this->request->post();
|
||||
// 修改网站后台入口路径
|
||||
if (!empty($post['xpath'])) {
|
||||
if (!preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $post['xpath'])) {
|
||||
$this->error('后台入口名称需要是由英文字母开头!');
|
||||
}
|
||||
if ($post['xpath'] !== 'admin' && file_exists($this->app->getBasePath() . $post['xpath'])) {
|
||||
$this->error("后台入口名称{$post['xpath']}已经存在应用!");
|
||||
}
|
||||
SystemService::setRuntime(null, [$post['xpath'] => 'admin']);
|
||||
}
|
||||
// 修改网站 ICON 图标,替换 public/favicon.ico
|
||||
if (preg_match('#^https?://#', $icon = $post['site_icon'] ?? '')) try {
|
||||
SystemService::setFavicon($icon);
|
||||
} catch (\Exception $exception) {
|
||||
trace_file($exception);
|
||||
}
|
||||
// 数据数据到系统配置表
|
||||
foreach ($post as $k => $v) sysconf($k, $v);
|
||||
sysoplog('系统配置管理', "修改系统参数成功");
|
||||
$this->success('修改系统参数成功!', admuri('admin/config/index'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改文件存储
|
||||
* @auth true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function storage()
|
||||
{
|
||||
$this->_applyFormToken();
|
||||
if ($this->request->isGet()) {
|
||||
$this->type = input('type', 'local');
|
||||
if ($this->type === 'alioss') {
|
||||
$this->points = AliossStorage::region();
|
||||
} elseif ($this->type === 'qiniu') {
|
||||
$this->points = QiniuStorage::region();
|
||||
} elseif ($this->type === 'txcos') {
|
||||
$this->points = TxcosStorage::region();
|
||||
}
|
||||
$this->fetch("storage-{$this->type}");
|
||||
} else {
|
||||
$post = $this->request->post();
|
||||
if (!empty($post['storage']['allow_exts'])) {
|
||||
$deny = ['sh', 'asp', 'bat', 'cmd', 'exe', 'php'];
|
||||
$exts = array_unique(str2arr(strtolower($post['storage']['allow_exts'])));
|
||||
if (count(array_intersect($deny, $exts)) > 0) $this->error('禁止上传可执行的文件!');
|
||||
$post['storage']['allow_exts'] = join(',', $exts);
|
||||
}
|
||||
foreach ($post as $name => $value) sysconf($name, $value);
|
||||
sysoplog('系统配置管理', "修改系统存储参数");
|
||||
$this->success('修改文件存储成功!');
|
||||
}
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use think\admin\Controller;
|
||||
use think\admin\helper\QueryHelper;
|
||||
use think\admin\model\SystemFile;
|
||||
use think\admin\service\AdminService;
|
||||
use think\admin\Storage;
|
||||
|
||||
/**
|
||||
* 系统文件管理
|
||||
* Class File
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class File extends Controller
|
||||
{
|
||||
/**
|
||||
* 系统文件管理
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->types = Storage::types();
|
||||
SystemFile::mQuery()->layTable(function () {
|
||||
$this->title = '系统文件管理';
|
||||
$this->xexts = SystemFile::mk()->distinct()->column('xext');
|
||||
}, function (QueryHelper $query) {
|
||||
$query->like('name,hash,xext')->equal('type')->dateBetween('create_at');
|
||||
$query->where(['issafe' => 0, 'status' => 2, 'uuid' => AdminService::getUserId()]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据列表处理
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
protected function _page_filter(array &$data)
|
||||
{
|
||||
foreach ($data as &$vo) {
|
||||
$vo['ctype'] = $this->types[$vo['type']] ?? $vo['type'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除系统文件
|
||||
* @auth true
|
||||
* @return void
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
SystemFile::mDelete();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理重复文件
|
||||
* @auth true
|
||||
* @return void
|
||||
*/
|
||||
public function distinct()
|
||||
{
|
||||
$map = ['uuid' => AdminService::getUserId()];
|
||||
$db1 = SystemFile::mk()->fieldRaw('max(id) id')->where($map)->group('type,xkey');
|
||||
$db2 = $this->app->db->table($db1->buildSql())->alias('dt')->field('id');
|
||||
SystemFile::mk()->whereRaw("id not in {$db2->buildSql()}")->delete();
|
||||
SystemFile::mk()->where($map)->where(['status' => 1])->delete();
|
||||
$this->success('清理重复文件成功!');
|
||||
}
|
||||
}
|
@ -1,155 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use think\admin\Controller;
|
||||
use think\admin\model\SystemUser;
|
||||
use think\admin\service\AdminService;
|
||||
use think\admin\service\MenuService;
|
||||
|
||||
/**
|
||||
* 后台界面入口
|
||||
* Class Index
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Index extends Controller
|
||||
{
|
||||
/**
|
||||
* 显示后台首页
|
||||
* @throws \ReflectionException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
/*! 根据运行模式刷新权限 */
|
||||
AdminService::apply($this->app->isDebug());
|
||||
/*! 读取当前用户权限菜单树 */
|
||||
$this->menus = MenuService::getTree();
|
||||
/*! 判断当前用户的登录状态 */
|
||||
$this->login = AdminService::isLogin();
|
||||
/*! 菜单为空且未登录跳转到登录页 */
|
||||
if (empty($this->menus) && empty($this->login)) {
|
||||
$this->redirect(sysuri('admin/login/index'));
|
||||
} else {
|
||||
$this->title = '系统管理后台';
|
||||
$this->super = AdminService::isSuper();
|
||||
$this->theme = AdminService::getUserTheme();
|
||||
$this->fetch();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台主题切换
|
||||
* @login true
|
||||
* @return void
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function theme()
|
||||
{
|
||||
if ($this->request->isGet()) {
|
||||
$this->theme = AdminService::getUserTheme();
|
||||
$this->themes = Config::themes;
|
||||
$this->fetch();
|
||||
} else {
|
||||
$data = $this->_vali(['site_theme.require' => '主题名称不能为空!']);
|
||||
if (AdminService::setUserTheme($data['site_theme'])) {
|
||||
$this->success('主题配置保存成功!');
|
||||
} else {
|
||||
$this->error('主题配置保存失败!');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户资料
|
||||
* @login true
|
||||
* @param mixed $id 用户ID
|
||||
*/
|
||||
public function info($id = 0)
|
||||
{
|
||||
$this->_applyFormToken();
|
||||
if (AdminService::getUserId() === intval($id)) {
|
||||
SystemUser::mForm('admin@user/form', 'id', [], ['id' => $id]);
|
||||
} else {
|
||||
$this->error('只能修改自己的资料!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 资料修改表单处理
|
||||
* @param array $data
|
||||
*/
|
||||
protected function _info_form_filter(array &$data)
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
unset($data['username'], $data['authorize']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 资料修改结果处理
|
||||
* @param bool $status
|
||||
*/
|
||||
protected function _info_form_result(bool $status)
|
||||
{
|
||||
if ($status) {
|
||||
$this->success('用户资料修改成功!', 'javascript:location.reload()');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改当前用户密码
|
||||
* @login true
|
||||
* @param mixed $id
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function pass($id = 0)
|
||||
{
|
||||
$this->_applyFormToken();
|
||||
if (AdminService::getUserId() !== intval($id)) {
|
||||
$this->error('只能修改当前用户的密码!');
|
||||
}
|
||||
if ($this->app->request->isGet()) {
|
||||
$this->verify = true;
|
||||
SystemUser::mForm('admin@user/pass', 'id', [], ['id' => $id]);
|
||||
} else {
|
||||
$data = $this->_vali([
|
||||
'password.require' => '登录密码不能为空!',
|
||||
'repassword.require' => '重复密码不能为空!',
|
||||
'oldpassword.require' => '旧的密码不能为空!',
|
||||
'password.confirm:repassword' => '两次输入的密码不一致!',
|
||||
]);
|
||||
$user = SystemUser::mk()->find($id);
|
||||
if (empty($user)) $this->error('用户不存在!');
|
||||
if (md5($data['oldpassword']) !== $user['password']) {
|
||||
$this->error('旧密码验证失败,请重新输入!');
|
||||
}
|
||||
if ($user->save(['password' => md5($data['password'])])) {
|
||||
sysoplog('系统用户管理', "修改用户[{$user['id']}]密码成功");
|
||||
$this->success('密码修改成功,下次请使用新密码登录!', '');
|
||||
} else {
|
||||
$this->error('密码修改失败,请稍候再试!');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use think\admin\Controller;
|
||||
use think\admin\extend\CodeExtend;
|
||||
use think\admin\model\SystemUser;
|
||||
use think\admin\service\AdminService;
|
||||
use think\admin\service\CaptchaService;
|
||||
use think\admin\service\SystemService;
|
||||
|
||||
/**
|
||||
* 用户登录管理
|
||||
* Class Login
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Login extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* 后台登录入口
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
if ($this->app->request->isGet()) {
|
||||
if (AdminService::isLogin()) {
|
||||
$this->redirect(sysuri('admin/index/index'));
|
||||
} else {
|
||||
// 当前运行模式
|
||||
$this->developMode = SystemService::checkRunMode();
|
||||
// 后台背景处理
|
||||
$images = str2arr(sysconf('login_image') ?: '', '|') ?: [
|
||||
SystemService::uri('/static/theme/img/login/bg1.jpg'), SystemService::uri('/static/theme/img/login/bg2.jpg'),
|
||||
];
|
||||
$this->loginStyle = sprintf('style="background-image:url(%s)" data-bg-transition="%s"', $images[0], join(',', $images));
|
||||
// 登录验证令牌
|
||||
$this->captchaType = 'LoginCaptcha';
|
||||
$this->captchaToken = CodeExtend::uniqidDate(18);
|
||||
if (!$this->app->session->get('LoginInputSessionError')) {
|
||||
$this->app->session->set($this->captchaType, $this->captchaToken);
|
||||
}
|
||||
// 更新后台域名
|
||||
if ($this->request->domain(true) !== sysconf('base.site_host')) {
|
||||
sysconf('base.site_host', $this->request->domain(true));
|
||||
}
|
||||
// 加载登录模板
|
||||
$this->title = '系统登录';
|
||||
$this->fetch();
|
||||
}
|
||||
} else {
|
||||
$data = $this->_vali([
|
||||
'username.require' => '登录账号不能为空!',
|
||||
'username.min:4' => '登录账号不能少于4位字符!',
|
||||
'password.require' => '登录密码不能为空!',
|
||||
'password.min:4' => '登录密码不能少于4位字符!',
|
||||
'verify.require' => '图形验证码不能为空!',
|
||||
'uniqid.require' => '图形验证标识不能为空!',
|
||||
]);
|
||||
if (!CaptchaService::instance()->check($data['verify'], $data['uniqid'])) {
|
||||
$this->error('图形验证码验证失败,请重新输入!');
|
||||
}
|
||||
/*! 用户信息验证 */
|
||||
$map = ['username' => $data['username'], 'is_deleted' => 0];
|
||||
$user = SystemUser::mk()->where($map)->findOrEmpty();
|
||||
if ($user->isEmpty()) {
|
||||
$this->app->session->set('LoginInputSessionError', true);
|
||||
$this->error('登录账号或密码错误,请重新输入!');
|
||||
}
|
||||
if (empty($user['status'])) {
|
||||
$this->app->session->set('LoginInputSessionError', true);
|
||||
$this->error('账号已经被禁用,请联系管理员!');
|
||||
}
|
||||
if (md5("{$user['password']}{$data['uniqid']}") !== $data['password']) {
|
||||
$this->app->session->set('LoginInputSessionError', true);
|
||||
$this->error('登录账号或密码错误,请重新输入!');
|
||||
}
|
||||
$this->app->session->set('user', $user->toArray());
|
||||
$this->app->session->delete('LoginInputSessionError');
|
||||
$user->inc('login_num')->update([
|
||||
'login_at' => date('Y-m-d H:i:s'),
|
||||
'login_ip' => $this->app->request->ip(),
|
||||
]);
|
||||
sysoplog('系统用户登录', '登录系统后台成功');
|
||||
$this->success('登录成功', sysuri('admin/index/index'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成验证码
|
||||
*/
|
||||
public function captcha()
|
||||
{
|
||||
$input = $this->_vali([
|
||||
'type.require' => '验证码类型不能为空!',
|
||||
'token.require' => '验证码标识不能为空!',
|
||||
]);
|
||||
$image = CaptchaService::instance()->initialize();
|
||||
$captcha = ['image' => $image->getData(), 'uniqid' => $image->getUniqid()];
|
||||
if ($this->app->session->get($input['type']) === $input['token']) {
|
||||
$captcha['code'] = $image->getCode();
|
||||
$this->app->session->delete($input['type']);
|
||||
}
|
||||
$this->success('生成验证码成功', $captcha);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
public function out()
|
||||
{
|
||||
$this->app->session->clear();
|
||||
$this->app->session->destroy();
|
||||
$this->success('退出登录成功!', sysuri('admin/login/index'));
|
||||
}
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use think\admin\Controller;
|
||||
use think\admin\extend\DataExtend;
|
||||
use think\admin\model\SystemMenu;
|
||||
use think\admin\service\AdminService;
|
||||
use think\admin\service\MenuService;
|
||||
use think\admin\service\NodeService;
|
||||
|
||||
/**
|
||||
* 系统菜单管理
|
||||
* Class Menu
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Menu extends Controller
|
||||
{
|
||||
/**
|
||||
* 系统菜单管理
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->title = '系统菜单管理';
|
||||
$this->type = input('get.type', 'index');
|
||||
SystemMenu::mQuery()->layTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表数据处理
|
||||
* @param array $data
|
||||
*/
|
||||
protected function _index_page_filter(array &$data)
|
||||
{
|
||||
$data = DataExtend::arr2tree($data);
|
||||
// 回收站过滤有效菜单
|
||||
if ($this->type === 'recycle') foreach ($data as $k1 => &$p1) {
|
||||
if (!empty($p1['sub'])) foreach ($p1['sub'] as $k2 => &$p2) {
|
||||
if (!empty($p2['sub'])) foreach ($p2['sub'] as $k3 => $p3) {
|
||||
if ($p3['status'] > 0) unset($p2['sub'][$k3]);
|
||||
}
|
||||
if (empty($p2['sub']) && ($p2['url'] === '#' or $p2['status'] > 0)) unset($p1['sub'][$k2]);
|
||||
}
|
||||
if (empty($p1['sub']) && ($p1['url'] === '#' or $p1['status'] > 0)) unset($data[$k1]);
|
||||
}
|
||||
// 菜单数据树数据变平化
|
||||
$data = DataExtend::arr2table($data);
|
||||
foreach ($data as &$vo) {
|
||||
if ($vo['url'] !== '#' && !preg_match('/^(https?:)?(\/\/|\\\\)/i', $vo['url'])) {
|
||||
$vo['url'] = trim(url($vo['url']) . ($vo['params'] ? "?{$vo['params']}" : ''), '\\/');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加系统菜单
|
||||
* @auth true
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$this->_applyFormToken();
|
||||
SystemMenu::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑系统菜单
|
||||
* @auth true
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$this->_applyFormToken();
|
||||
SystemMenu::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单数据处理
|
||||
* @param array $vo
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
protected function _form_filter(array &$vo)
|
||||
{
|
||||
if ($this->request->isGet()) {
|
||||
/* 清理权限节点 */
|
||||
if ($isDebug = $this->app->isDebug()) {
|
||||
AdminService::clearCache();
|
||||
}
|
||||
/* 读取系统功能节点 */
|
||||
$this->auths = [];
|
||||
$this->nodes = MenuService::getList($isDebug);
|
||||
foreach (NodeService::getMethods($isDebug) as $node => $item) {
|
||||
if ($item['isauth'] && substr_count($node, '/') >= 2) {
|
||||
$this->auths[] = ['node' => $node, 'title' => $item['title']];
|
||||
}
|
||||
}
|
||||
/* 选择自己上级菜单 */
|
||||
$vo['pid'] = $vo['pid'] ?? input('pid', '0');
|
||||
/* 列出可选上级菜单 */
|
||||
$menus = SystemMenu::mk()->order('sort desc,id asc')->column('id,pid,icon,url,node,title,params', 'id');
|
||||
$this->menus = DataExtend::arr2table(array_merge($menus, [['id' => '0', 'pid' => '-1', 'url' => '#', 'title' => '顶部菜单']]));
|
||||
if (isset($vo['id'])) foreach ($this->menus as $menu) if ($menu['id'] === $vo['id']) $vo = $menu;
|
||||
foreach ($this->menus as $key => $menu) if ($menu['spt'] >= 3 || $menu['url'] !== '#') unset($this->menus[$key]);
|
||||
if (isset($vo['spt']) && isset($vo['spc']) && in_array($vo['spt'], [1, 2]) && $vo['spc'] > 0) {
|
||||
foreach ($this->menus as $key => $menu) if ($vo['spt'] <= $menu['spt']) unset($this->menus[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改菜单状态
|
||||
* @auth true
|
||||
*/
|
||||
public function state()
|
||||
{
|
||||
SystemMenu::mSave($this->_vali([
|
||||
'status.in:0,1' => '状态值范围异常!',
|
||||
'status.require' => '状态值不能为空!',
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除系统菜单
|
||||
* @auth true
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
SystemMenu::mDelete();
|
||||
}
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use think\admin\Controller;
|
||||
use think\admin\service\ModuleService;
|
||||
|
||||
/**
|
||||
* 系统模块管理
|
||||
* Class Module
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Module extends Controller
|
||||
{
|
||||
/**
|
||||
* 系统模块管理
|
||||
* @auth true
|
||||
* @menu true
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->title = '系统模块管理';
|
||||
$this->modules = ModuleService::change();
|
||||
$this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 安装更新模块
|
||||
* @auth true
|
||||
*/
|
||||
public function install()
|
||||
{
|
||||
$data = $this->_vali(['name.require' => '模块名称不能为空!']);
|
||||
[$state, $message] = ModuleService::install($data['name']);
|
||||
$state ? $this->success($message) : $this->error($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看模块更新
|
||||
* @auth true
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
$data = $this->_vali(['name.require' => '模块名称不能为空!']);
|
||||
$online = ModuleService::online();
|
||||
$locals = ModuleService::getModules();
|
||||
if (isset($online[$data['name']])) {
|
||||
$this->module = $online[$data['name']];
|
||||
$this->current = $locals[$data['name']] ?? [];
|
||||
$pattern = "|^(\d{4})\.(\d{2})\.(\d{2})\.(\d+)$|";
|
||||
$this->module['change'] = array_reverse($this->module['change']);
|
||||
foreach ($this->module['change'] as $version => &$change) {
|
||||
$change = ['content' => $change, 'version' => preg_replace($pattern, '$1年$2月$3日 更新', $version)];
|
||||
}
|
||||
$this->fetch();
|
||||
} else {
|
||||
$this->error('未查询到模块更新记录!');
|
||||
}
|
||||
}
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use Exception;
|
||||
use Ip2Region;
|
||||
use think\admin\Controller;
|
||||
use think\admin\helper\QueryHelper;
|
||||
use think\admin\model\SystemOplog;
|
||||
use think\exception\HttpResponseException;
|
||||
|
||||
/**
|
||||
* 系统日志管理
|
||||
* Class Oplog
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Oplog extends Controller
|
||||
{
|
||||
/**
|
||||
* 系统日志管理
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
SystemOplog::mQuery()->layTable(function () {
|
||||
$this->title = '系统日志管理';
|
||||
$columns = SystemOplog::mk()->column('action,username', 'id');
|
||||
$this->users = array_unique(array_column($columns, 'username'));
|
||||
$this->actions = array_unique(array_column($columns, 'action'));
|
||||
}, function (QueryHelper $query) {
|
||||
$query->dateBetween('create_at')->equal('username,action')->like('content,geoip,node');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表数据处理
|
||||
* @auth true
|
||||
* @param array $data
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function _index_page_filter(array &$data)
|
||||
{
|
||||
$region = new Ip2Region();
|
||||
foreach ($data as &$vo) {
|
||||
$isp = $region->btreeSearch($vo['geoip']);
|
||||
$vo['geoisp'] = str_replace(['内网IP', '0', '|'], '', $isp['region'] ?? '') ?: '-';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理系统日志
|
||||
* @auth true
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
try {
|
||||
SystemOplog::mQuery()->empty();
|
||||
sysoplog('系统运维管理', '成功清理所有日志');
|
||||
$this->success('日志清理成功!');
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (Exception $exception) {
|
||||
$this->error("日志清理失败,{$exception->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除系统日志
|
||||
* @auth true
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
SystemOplog::mDelete();
|
||||
}
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use Exception;
|
||||
use think\admin\Controller;
|
||||
use think\admin\helper\QueryHelper;
|
||||
use think\admin\model\SystemQueue;
|
||||
use think\admin\service\AdminService;
|
||||
use think\admin\service\ProcessService;
|
||||
use think\admin\service\QueueService;
|
||||
use think\exception\HttpResponseException;
|
||||
|
||||
/**
|
||||
* 系统任务管理
|
||||
* Class Queue
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Queue extends Controller
|
||||
{
|
||||
/**
|
||||
* 系统任务管理
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
SystemQueue::mQuery()->layTable(function () {
|
||||
$this->title = '系统任务管理';
|
||||
$this->iswin = ProcessService::iswin();
|
||||
if ($this->super = AdminService::isSuper()) {
|
||||
$this->command = ProcessService::think('xadmin:queue start');
|
||||
if (!$this->iswin && !empty($_SERVER['USER'])) {
|
||||
$this->command = "sudo -u {$_SERVER['USER']} {$this->command}";
|
||||
}
|
||||
}
|
||||
}, function (QueryHelper $query) {
|
||||
$query->equal('status')->like('code|title#title,command');
|
||||
$query->timeBetween('enter_time,exec_time')->dateBetween('create_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页数据回调处理
|
||||
* @param array $data
|
||||
* @param array $result
|
||||
* @return void
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
protected function _index_page_filter(array $data, array &$result)
|
||||
{
|
||||
$result['extra'] = ['dos' => 0, 'pre' => 0, 'oks' => 0, 'ers' => 0];
|
||||
SystemQueue::mk()->field('status,count(1) count')->group('status')->select()->map(function ($item) use (&$result) {
|
||||
if ($item['status'] === 1) $result['extra']['pre'] = $item['count'];
|
||||
if ($item['status'] === 2) $result['extra']['dos'] = $item['count'];
|
||||
if ($item['status'] === 3) $result['extra']['oks'] = $item['count'];
|
||||
if ($item['status'] === 4) $result['extra']['ers'] = $item['count'];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 重启系统任务
|
||||
* @auth true
|
||||
*/
|
||||
public function redo()
|
||||
{
|
||||
try {
|
||||
$data = $this->_vali(['code.require' => '任务编号不能为空!']);
|
||||
$queue = QueueService::instance()->initialize($data['code'])->reset();
|
||||
$queue->progress(1, '>>> 任务重置成功 <<<', 0.00);
|
||||
$this->success('任务重置成功!', $queue->code);
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (Exception $exception) {
|
||||
$this->error($exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理运行数据
|
||||
* @auth true
|
||||
*/
|
||||
public function clean()
|
||||
{
|
||||
$this->_queue('定时清理系统运行数据', "xadmin:queue clean", 0, [], 0, 3600);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除系统任务
|
||||
* @auth true
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
SystemQueue::mDelete();
|
||||
}
|
||||
}
|
@ -1,180 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use think\admin\Controller;
|
||||
use think\admin\helper\QueryHelper;
|
||||
use think\admin\model\SystemAuth;
|
||||
use think\admin\model\SystemBase;
|
||||
use think\admin\model\SystemUser;
|
||||
use think\admin\service\AdminService;
|
||||
use think\model\Relation;
|
||||
|
||||
/**
|
||||
* 系统用户管理
|
||||
* Class User
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class User extends Controller
|
||||
{
|
||||
/**
|
||||
* 系统用户管理
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->type = input('get.type', 'index');
|
||||
|
||||
// 创建快捷查询工具
|
||||
SystemUser::mQuery()->layTable(function () {
|
||||
$this->title = '系统用户管理';
|
||||
$this->bases = SystemBase::items('身份权限');
|
||||
}, function (QueryHelper $query) {
|
||||
|
||||
// 加载对应数据列表
|
||||
$query->where(['is_deleted' => 0, 'status' => intval($this->type === 'index')]);
|
||||
|
||||
// 关联用户身份资料
|
||||
$query->with(['userinfo' => function (Relation $relation) {
|
||||
$relation->field('code,name,content');
|
||||
}]);
|
||||
|
||||
// 数据列表搜索过滤
|
||||
$query->equal('status,usertype')->dateBetween('login_at,create_at');
|
||||
$query->like('username|nickname#username,contact_phone#phone,contact_mail#mail');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加系统用户
|
||||
* @auth true
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
SystemUser::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑系统用户
|
||||
* @auth true
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
SystemUser::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户密码
|
||||
* @auth true
|
||||
*/
|
||||
public function pass()
|
||||
{
|
||||
$this->_applyFormToken();
|
||||
if ($this->request->isGet()) {
|
||||
$this->verify = false;
|
||||
SystemUser::mForm('pass');
|
||||
} else {
|
||||
$data = $this->_vali([
|
||||
'id.require' => '用户ID不能为空!',
|
||||
'password.require' => '登录密码不能为空!',
|
||||
'repassword.require' => '重复密码不能为空!',
|
||||
'repassword.confirm:password' => '两次输入的密码不一致!',
|
||||
]);
|
||||
$user = SystemUser::mk()->findOrEmpty($data['id']);
|
||||
if ($user->isExists() && $user->save(['password' => md5($data['password'])])) {
|
||||
sysoplog('系统用户管理', "修改用户[{$data['id']}]密码成功");
|
||||
$this->success('密码修改成功,请使用新密码登录!', '');
|
||||
} else {
|
||||
$this->error('密码修改失败,请稍候再试!');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单数据处理
|
||||
* @param array $data
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
protected function _form_filter(array &$data)
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
// 账号权限绑定处理
|
||||
$data['authorize'] = arr2str($data['authorize'] ?? []);
|
||||
if (isset($data['id']) && $data['id'] > 0) {
|
||||
unset($data['username']);
|
||||
} else {
|
||||
// 检查账号是否重复
|
||||
if (empty($data['username'])) {
|
||||
$this->error('登录账号不能为空!');
|
||||
}
|
||||
$map = ['username' => $data['username'], 'is_deleted' => 0];
|
||||
if (SystemUser::mk()->where($map)->count() > 0) {
|
||||
$this->error("账号已经存在,请使用其它账号!");
|
||||
}
|
||||
// 新添加的用户密码与账号相同
|
||||
$data['password'] = md5($data['username']);
|
||||
}
|
||||
} else {
|
||||
// 权限绑定处理
|
||||
$data['authorize'] = str2arr($data['authorize'] ?? '');
|
||||
// 用户身份数据
|
||||
$this->bases = SystemBase::items('身份权限');
|
||||
// 用户权限管理
|
||||
$this->superName = AdminService::getSuperName();
|
||||
$this->authorizes = SystemAuth::items();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户状态
|
||||
* @auth true
|
||||
*/
|
||||
public function state()
|
||||
{
|
||||
$this->_checkInput();
|
||||
SystemUser::mSave($this->_vali([
|
||||
'status.in:0,1' => '状态值范围异常!',
|
||||
'status.require' => '状态值不能为空!',
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除系统用户
|
||||
* @auth true
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
$this->_checkInput();
|
||||
SystemUser::mDelete();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查输入变量
|
||||
*/
|
||||
private function _checkInput()
|
||||
{
|
||||
if (in_array('10000', str2arr(input('id', '')))) {
|
||||
$this->error('系统超级账号禁止删除!');
|
||||
}
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller\api;
|
||||
|
||||
use think\admin\Controller;
|
||||
use think\admin\service\AdminService;
|
||||
|
||||
/**
|
||||
* 通用插件管理
|
||||
* Class Plugs
|
||||
* @package app\admin\controller\api
|
||||
*/
|
||||
class Plugs extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* 图标选择器
|
||||
* @login true
|
||||
*/
|
||||
public function icon()
|
||||
{
|
||||
$this->title = '图标选择器';
|
||||
$this->field = $this->app->request->get('field', 'icon');
|
||||
$this->fetch(realpath(__DIR__ . '/../../view/api/icon.html'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 前端脚本变量
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function script(): \think\Response
|
||||
{
|
||||
$taDebug = $this->app->isDebug() ? 'true' : 'false';
|
||||
$taAdmin = sysuri('admin/index/index', [], false);
|
||||
$taEditor = sysconf('base.editor') ?: 'ckeditor4';
|
||||
return response(join("\n", [
|
||||
"window.taDebug = {$taDebug};",
|
||||
"window.taAdmin = '{$taAdmin}';",
|
||||
"window.taEditor = '{$taEditor}';",
|
||||
]))->contentType('application/x-javascript');
|
||||
}
|
||||
|
||||
/**
|
||||
* 优化数据库
|
||||
* @login true
|
||||
*/
|
||||
public function optimize()
|
||||
{
|
||||
if (AdminService::isSuper()) {
|
||||
sysoplog('系统运维管理', '创建数据库优化任务');
|
||||
$this->_queue('优化数据库所有数据表', 'xadmin:database optimize');
|
||||
} else {
|
||||
$this->error('只有超级管理员才能操作!');
|
||||
}
|
||||
}
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller\api;
|
||||
|
||||
use Exception;
|
||||
use think\admin\Controller;
|
||||
use think\admin\service\AdminService;
|
||||
use think\admin\service\QueueService;
|
||||
use think\exception\HttpResponseException;
|
||||
|
||||
/**
|
||||
* 后台任务通用接口
|
||||
* Class Queue
|
||||
* @package app\admin\controller\api
|
||||
*/
|
||||
class Queue extends Controller
|
||||
{
|
||||
/**
|
||||
* 任务进度查询
|
||||
* @login true
|
||||
* @throws \think\admin\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function progress()
|
||||
{
|
||||
$input = $this->_vali(['code.require' => '任务编号不能为空!']);
|
||||
$queue = QueueService::instance()->initialize($input['code']);
|
||||
$this->success('获取任务进度成功!', $queue->progress());
|
||||
}
|
||||
|
||||
/**
|
||||
* WIN停止监听进程
|
||||
* @login true
|
||||
*/
|
||||
public function stop()
|
||||
{
|
||||
try {
|
||||
$message = $this->app->console->call('xadmin:queue', ['stop'])->fetch();
|
||||
if (stripos($message, 'sent end signal to process')) {
|
||||
sysoplog('系统运维管理', '尝试停止后台服务主进程');
|
||||
$this->success('停止后台服务主进程成功!');
|
||||
} elseif (stripos($message, 'processes to stop')) {
|
||||
$this->success('没有找到需要停止的进程!');
|
||||
} else {
|
||||
$this->error(nl2br($message));
|
||||
}
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (Exception $exception) {
|
||||
$this->error($exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* WIN创建监听进程
|
||||
* @login true
|
||||
*/
|
||||
public function start()
|
||||
{
|
||||
try {
|
||||
$message = $this->app->console->call('xadmin:queue', ['start'])->fetch();
|
||||
if (stripos($message, 'daemons started successfully for pid')) {
|
||||
sysoplog('系统运维管理', '尝试启动后台服务主进程');
|
||||
$this->success('后台服务主进程启动成功!');
|
||||
} elseif (stripos($message, 'daemons already exist for pid')) {
|
||||
$this->success('后台服务主进程已经存在!');
|
||||
} else {
|
||||
$this->error(nl2br($message));
|
||||
}
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (Exception $exception) {
|
||||
$this->error($exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查任务状态
|
||||
* @login true
|
||||
*/
|
||||
public function status()
|
||||
{
|
||||
if (AdminService::isSuper()) try {
|
||||
$message = $this->app->console->call('xadmin:queue', ['status'])->fetch();
|
||||
if (preg_match('/process.*?\d+.*?running/', $message)) {
|
||||
echo "<span class='color-green pointer' data-tips-text='{$message}'>已启动</span>";
|
||||
} else {
|
||||
echo "<span class='color-red pointer' data-tips-text='{$message}'>未启动</span>";
|
||||
}
|
||||
} catch (Exception $exception) {
|
||||
echo "<span class='color-red pointer' data-tips-text='{$exception->getMessage()}'>异 常</span>";
|
||||
} else {
|
||||
echo "<span class='color-red pointer' data-tips-text='只有超级管理员才能操作!'>无权限</span>";
|
||||
}
|
||||
}
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller\api;
|
||||
|
||||
use think\admin\Controller;
|
||||
use think\admin\model\SystemConfig;
|
||||
use think\admin\service\AdminService;
|
||||
use think\admin\service\SystemService;
|
||||
use think\exception\HttpResponseException;
|
||||
|
||||
/**
|
||||
* 系统运行控制管理
|
||||
* Class System
|
||||
* @package app\admin\controller\api
|
||||
*/
|
||||
class System extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* 网站压缩发布
|
||||
* @login true
|
||||
*/
|
||||
public function push()
|
||||
{
|
||||
if (AdminService::isSuper()) try {
|
||||
AdminService::clearCache();
|
||||
SystemService::pushRuntime();
|
||||
sysoplog('系统运维管理', '刷新创建路由缓存');
|
||||
$this->success('网站缓存加速成功!', 'javascript:location.reload()');
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
$this->error($exception->getMessage());
|
||||
} else {
|
||||
$this->error('只有超级管理员才能操作!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理运行缓存
|
||||
* @login true
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
if (AdminService::isSuper()) try {
|
||||
AdminService::clearCache();
|
||||
SystemService::clearRuntime();
|
||||
sysoplog('系统运维管理', '清理网站日志缓存');
|
||||
$this->success('清空日志缓存成功!', 'javascript:location.reload()');
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
$this->error($exception->getMessage());
|
||||
} else {
|
||||
$this->error('只有超级管理员才能操作!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前运行模式
|
||||
* @login true
|
||||
*/
|
||||
public function debug()
|
||||
{
|
||||
if (AdminService::isSuper()) if (input('state')) {
|
||||
SystemService::setRuntime('product');
|
||||
sysoplog('系统运维管理', '开发模式切换为生产模式');
|
||||
$this->success('已切换为生产模式!', 'javascript:location.reload()');
|
||||
} else {
|
||||
SystemService::setRuntime('debug');
|
||||
sysoplog('系统运维管理', '生产模式切换为开发模式');
|
||||
$this->success('已切换为开发模式!', 'javascript:location.reload()');
|
||||
} else {
|
||||
$this->error('只有超级管理员才能操作!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改富文本编辑器
|
||||
* @return void
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function editor()
|
||||
{
|
||||
if (AdminService::isSuper()) {
|
||||
$editor = input('editor', 'auto');
|
||||
sysconf('base.editor', $editor);
|
||||
sysoplog('系统运维管理', "切换编辑器为{$editor}");
|
||||
$this->success('已切换后台编辑器!', 'javascript:location.reload()');
|
||||
} else {
|
||||
$this->error('只有超级管理员才能操作!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理系统配置
|
||||
* @login true
|
||||
*/
|
||||
public function config()
|
||||
{
|
||||
if (AdminService::isSuper()) try {
|
||||
[$tmpdata, $newdata] = [[], []];
|
||||
foreach (SystemConfig::mk()->order('type,name asc')->cursor() as $item) {
|
||||
$tmpdata[$item['type']][$item['name']] = $item['value'];
|
||||
}
|
||||
foreach ($tmpdata as $type => $items) foreach ($items as $name => $value) {
|
||||
$newdata[] = ['type' => $type, 'name' => $name, 'value' => $value];
|
||||
}
|
||||
$this->app->db->transaction(function () use ($newdata) {
|
||||
SystemConfig::mQuery()->empty()->insertAll($newdata);
|
||||
});
|
||||
$this->app->cache->delete('SystemConfig');
|
||||
sysoplog('系统运维管理', '清理系统配置参数');
|
||||
$this->success('清理系统配置成功!', 'javascript:location.reload()');
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
$this->error($exception->getMessage());
|
||||
} else {
|
||||
$this->error('只有超级管理员才能操作!');
|
||||
}
|
||||
}
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller\api;
|
||||
|
||||
use think\admin\Controller;
|
||||
use think\admin\service\ModuleService;
|
||||
use think\admin\service\SystemService;
|
||||
|
||||
/**
|
||||
* 安装服务端支持
|
||||
* Class Update
|
||||
* @package app\admin\controller\api
|
||||
*/
|
||||
class Update extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* 访问环境拦截
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
if (!SystemService::checkRunMode()) {
|
||||
$this->error('只允许访问本地或官方代码!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取文件内容
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
$filename = decode(input('encode', '0'));
|
||||
if (!ModuleService::checkAllowDownload($filename)) {
|
||||
$this->error('下载的文件不在认证规则中!');
|
||||
}
|
||||
if (file_exists($realname = $this->app->getRootPath() . $filename)) {
|
||||
$this->success('读取文件内容成功!', [
|
||||
'content' => base64_encode(file_get_contents($realname)),
|
||||
]);
|
||||
} else {
|
||||
$this->error('读取文件内容失败!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取文件列表
|
||||
*/
|
||||
public function node()
|
||||
{
|
||||
$this->success('获取文件列表成功!', ModuleService::getChanges(
|
||||
json_decode($this->request->post('rules', '[]', ''), true),
|
||||
json_decode($this->request->post('ignore', '[]', ''), true)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模块信息
|
||||
*/
|
||||
public function version()
|
||||
{
|
||||
$this->success('获取模块信息成功!', ModuleService::getModules());
|
||||
}
|
||||
}
|
@ -1,326 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller\api;
|
||||
|
||||
use think\admin\Controller;
|
||||
use think\admin\helper\QueryHelper;
|
||||
use think\admin\model\SystemFile;
|
||||
use think\admin\service\AdminService;
|
||||
use think\admin\Storage;
|
||||
use think\admin\storage\AliossStorage;
|
||||
use think\admin\storage\LocalStorage;
|
||||
use think\admin\storage\QiniuStorage;
|
||||
use think\admin\storage\TxcosStorage;
|
||||
use think\admin\storage\UpyunStorage;
|
||||
use think\exception\HttpResponseException;
|
||||
use think\file\UploadedFile;
|
||||
use think\Response;
|
||||
|
||||
/**
|
||||
* 文件上传接口
|
||||
* Class Upload
|
||||
* @package app\admin\controller\api
|
||||
*/
|
||||
class Upload extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* 文件上传脚本
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index(): Response
|
||||
{
|
||||
$data = ['exts' => []];
|
||||
foreach (str2arr(sysconf('storage.allow_exts')) as $ext) {
|
||||
$data['exts'][$ext] = Storage::mime($ext);
|
||||
}
|
||||
$template = realpath(__DIR__ . '/../../view/api/upload.js');
|
||||
$data['exts'] = json_encode($data['exts'], JSON_UNESCAPED_UNICODE);
|
||||
$data['nameType'] = sysconf('storage.name_type') ?: 'xmd5';
|
||||
return view($template, $data)->contentType('application/x-javascript');
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传检查
|
||||
* @login true
|
||||
* @throws \think\admin\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function state()
|
||||
{
|
||||
[$name, $safe] = [input('name'), $this->getSafe()];
|
||||
$data = ['uptype' => $this->getType(), 'safe' => intval($safe), 'key' => input('key')];
|
||||
$file = SystemFile::mk()->data($this->_vali([
|
||||
'xkey.value' => $data['key'],
|
||||
'type.value' => $this->getType(),
|
||||
'uuid.value' => AdminService::getUserId(),
|
||||
'name.require' => '名称不能为空!',
|
||||
'hash.require' => '哈希不能为空!',
|
||||
'xext.require' => '后缀不能为空!',
|
||||
'size.require' => '大小不能为空!',
|
||||
'mime.default' => '',
|
||||
'status.value' => 1,
|
||||
]));
|
||||
if (empty($file['mime'])) $file['mime'] = Storage::mime($file['xext']);
|
||||
$info = Storage::instance($data['uptype'])->info($data['key'], $safe, $name);
|
||||
if (is_array($info) && isset($info['url']) && isset($info['key'])) {
|
||||
$file->save(['xurl' => $info['url'], 'isfast' => 1, 'issafe' => $data['safe']]);
|
||||
$extr = ['id' => $file->id ?? 0, 'url' => $info['url'], 'key' => $info['key']];
|
||||
$this->success('文件已经上传', array_merge($data, $extr), 200);
|
||||
} elseif ('local' === $data['uptype']) {
|
||||
$data['url'] = LocalStorage::instance()->url($data['key'], $safe, $name);
|
||||
$data['server'] = LocalStorage::instance()->upload();
|
||||
} elseif ('qiniu' === $data['uptype']) {
|
||||
$data['url'] = QiniuStorage::instance()->url($data['key'], $safe, $name);
|
||||
$data['token'] = QiniuStorage::instance()->buildUploadToken($data['key'], 3600, $name);
|
||||
$data['server'] = QiniuStorage::instance()->upload();
|
||||
} elseif ('alioss' === $data['uptype']) {
|
||||
$token = AliossStorage::instance()->buildUploadToken($data['key'], 3600, $name);
|
||||
$data['url'] = $token['siteurl'];
|
||||
$data['policy'] = $token['policy'];
|
||||
$data['signature'] = $token['signature'];
|
||||
$data['OSSAccessKeyId'] = $token['keyid'];
|
||||
$data['server'] = AliossStorage::instance()->upload();
|
||||
} elseif ('txcos' === $data['uptype']) {
|
||||
$token = TxcosStorage::instance()->buildUploadToken($data['key'], 3600, $name);
|
||||
$data['url'] = $token['siteurl'];
|
||||
$data['q-ak'] = $token['q-ak'];
|
||||
$data['policy'] = $token['policy'];
|
||||
$data['q-key-time'] = $token['q-key-time'];
|
||||
$data['q-signature'] = $token['q-signature'];
|
||||
$data['q-sign-algorithm'] = $token['q-sign-algorithm'];
|
||||
$data['server'] = TxcosStorage::instance()->upload();
|
||||
} elseif ('upyun' === $data['uptype']) {
|
||||
$token = UpyunStorage::instance()->buildUploadToken($data['key'], 3600, $name, input('size'), input('hash'));
|
||||
$data['url'] = $token['siteurl'];
|
||||
$data['policy'] = $token['policy'];
|
||||
$data['authorization'] = $token['authorization'];
|
||||
$data['server'] = UpyunStorage::instance()->upload();
|
||||
}
|
||||
$file->save(['xurl' => $data['url'], 'isfast' => 0, 'issafe' => $data['safe']]);
|
||||
$this->success('获取上传授权参数', array_merge($data, ['id' => $file->id ?? 0]), 404);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新文件状态
|
||||
* @login true
|
||||
* @return void
|
||||
*/
|
||||
public function done()
|
||||
{
|
||||
$data = $this->_vali([
|
||||
'id.require' => '编号不能为空!',
|
||||
'hash.require' => '哈希不能为空!',
|
||||
'uuid.value' => AdminService::getUserId(),
|
||||
]);
|
||||
$file = SystemFile::mk()->where($data)->findOrEmpty();
|
||||
if ($file->isEmpty()) $this->error('文件不存在!');
|
||||
if ($file->save(['status' => 2])) {
|
||||
$this->success('更新成功!');
|
||||
} else {
|
||||
$this->error('更新失败!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件选择器
|
||||
* @login true
|
||||
* @return void
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function image()
|
||||
{
|
||||
SystemFile::mQuery()->layTable(function () {
|
||||
$this->title = '文件选择器';
|
||||
}, function (QueryHelper $query) {
|
||||
$query->where(['status' => 2, 'issafe' => 0, 'uuid' => AdminService::getUserId()]);
|
||||
$query->like('name,hash')->in('xext#type')->dateBetween('create_at')->order('id desc');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频选择器
|
||||
* @login true
|
||||
* @return void
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function video()
|
||||
{
|
||||
SystemFile::mQuery()->layTable(function () {
|
||||
$this->title = '文件选择器';
|
||||
}, function (QueryHelper $query) {
|
||||
$query->like('name,hash')->dateBetween('create_at')->order('id desc');
|
||||
$query->where(['status' => 2, 'issafe' => 0, 'uuid' => AdminService::getUserId()]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 文档选择器
|
||||
* @login true
|
||||
* @return void
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function document()
|
||||
{
|
||||
SystemFile::mQuery()->layTable(function () {
|
||||
$this->title = '文件选择器';
|
||||
}, function (QueryHelper $query) {
|
||||
$query->like('name,hash')->dateBetween('create_at')->order('id desc');
|
||||
$query->where(['status' => 2, 'issafe' => 0, 'uuid' => AdminService::getUserId()]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传入口
|
||||
* @login true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function file()
|
||||
{
|
||||
if (!($file = $this->getFile())->isValid()) {
|
||||
$this->error('文件上传异常,文件过大或未上传!');
|
||||
}
|
||||
$safeMode = $this->getSafe();
|
||||
$extension = strtolower($file->getOriginalExtension());
|
||||
$saveName = input('key') ?: Storage::name($file->getPathname(), $extension, '', 'md5_file');
|
||||
// 检查文件名称是否合法
|
||||
if (strpos($saveName, '../') !== false) {
|
||||
$this->error('文件路径不能出现跳级操作!');
|
||||
}
|
||||
// 检查文件后缀是否被恶意修改
|
||||
if (strtolower(pathinfo(parse_url($saveName, PHP_URL_PATH), PATHINFO_EXTENSION)) !== $extension) {
|
||||
$this->error('文件后缀异常,请重新上传文件!');
|
||||
}
|
||||
// 屏蔽禁止上传指定后缀的文件
|
||||
if (!in_array($extension, str2arr(sysconf('storage.allow_exts')))) {
|
||||
$this->error('文件类型受限,请在后台配置规则!');
|
||||
}
|
||||
if (in_array($extension, ['sh', 'asp', 'bat', 'cmd', 'exe', 'php'])) {
|
||||
$this->error('文件安全保护,禁止上传可执行文件!');
|
||||
}
|
||||
try {
|
||||
if ($this->getType() === 'local') {
|
||||
$local = LocalStorage::instance();
|
||||
$distName = $local->path($saveName, $safeMode);
|
||||
$file->move(dirname($distName), basename($distName));
|
||||
$info = $local->info($saveName, $safeMode, $file->getOriginalName());
|
||||
if (in_array($extension, ['jpg', 'gif', 'png', 'bmp', 'jpeg', 'wbmp'])) {
|
||||
if ($this->imgNotSafe($distName) && $local->del($saveName)) {
|
||||
$this->error('图片未通过安全检查!');
|
||||
}
|
||||
[$width, $height] = getimagesize($distName);
|
||||
if (($width < 1 || $height < 1) && $local->del($saveName)) {
|
||||
$this->error('读取图片的尺寸失败!');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$bina = file_get_contents($file->getPathname());
|
||||
$info = Storage::instance($this->getType())->set($saveName, $bina, $safeMode, $file->getOriginalName());
|
||||
}
|
||||
if (isset($info['url'])) {
|
||||
$this->success('文件上传成功!', ['url' => $safeMode ? $saveName : $info['url']]);
|
||||
} else {
|
||||
$this->error('文件处理失败,请稍候再试!');
|
||||
}
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
$this->error($exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件上传类型
|
||||
* @return boolean
|
||||
*/
|
||||
private function getSafe(): bool
|
||||
{
|
||||
return boolval(input('safe', '0'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件上传方式
|
||||
* @return string
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function getType(): string
|
||||
{
|
||||
$type = strtolower(input('uptype', ''));
|
||||
if (in_array($type, ['local', 'qiniu', 'alioss', 'txcos', 'uptype'])) {
|
||||
return $type;
|
||||
} else {
|
||||
return strtolower(sysconf('storage.type'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本地文件对象
|
||||
* @return UploadedFile|void
|
||||
*/
|
||||
private function getFile(): UploadedFile
|
||||
{
|
||||
try {
|
||||
$file = $this->request->file('file');
|
||||
if ($file instanceof UploadedFile) {
|
||||
return $file;
|
||||
} else {
|
||||
$this->error('未获取到上传的文件对象!');
|
||||
}
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
$this->error(lang($exception->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查图片是否安全
|
||||
* @param string $filename
|
||||
* @return boolean
|
||||
*/
|
||||
private function imgNotSafe(string $filename): bool
|
||||
{
|
||||
$source = fopen($filename, 'rb');
|
||||
if (($size = filesize($filename)) > 512) {
|
||||
$hexs = bin2hex(fread($source, 512));
|
||||
fseek($source, $size - 512);
|
||||
$hexs .= bin2hex(fread($source, 512));
|
||||
} else {
|
||||
$hexs = bin2hex(fread($source, $size));
|
||||
}
|
||||
if (is_resource($source)) fclose($source);
|
||||
$bins = hex2bin($hexs);
|
||||
/* 匹配十六进制中的 <% ( ) %> 或 <? ( ) ?> 或 <script | /script> */
|
||||
foreach (['<?php ', '<% ', '<script '] as $key) if (stripos($bins, $key) !== false) return true;
|
||||
return preg_match("/(3c25.*?28.*?29.*?253e)|(3c3f.*?28.*?29.*?3f3e)|(3C534352495054)|(2F5343524950543E)|(3C736372697074)|(2F7363726970743E)/is", $hexs);
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
* 系统模块初始化成功
|
||||
* 这次更新了许多内容哦
|
||||
* 少量更新,修复部分BUG
|
||||
* 修正系统用户搜索
|
||||
* 系统菜单支持外链
|
||||
* 修复任意下载问题
|
||||
* 优化模块管理机制
|
@ -1,3 +0,0 @@
|
||||
* 数据展示优化
|
||||
* 后台UI升级到最新版本
|
||||
* 后台文件上传机制优化
|
@ -1,10 +0,0 @@
|
||||
* 增加 .flex 及相关样式 class
|
||||
* 升级 layui-2.7 测试版本并增加了 flex 样式
|
||||
* 增加 .help-images 图片上传容器,支持单图或多图
|
||||
* 增加 .help-checks 多项选择器容器,支持 raido,checkbox
|
||||
* 修复 layui.form.checkbox 特殊情况下的异常
|
||||
* 修改 ui 主布局的阴影生成方式,修改 NotSelect 使用
|
||||
* 修改内容主容器(.think-page-body>.layui-body) 样式
|
||||
* 其他细节调整见 _config.less 文件及 _layout.less 文件
|
||||
* 修改系统任务管理界面,简化数据统计及状态检测数据展示
|
||||
* 优化 admin.js 加载 loding 显示,首次加载等待成功后再显示界面
|
@ -1,12 +0,0 @@
|
||||
* 框架核心服务层静态化重构,增加后台皮肤样式选择与配置
|
||||
* 升级 layui 版本到 2.7.4,引入 jszip 插件,引入图片压缩插件
|
||||
* 重构文件上传机制,增加文件记录,增加进度 tips 提示,增加图片压缩
|
||||
* 引入 ckeditor5 富文本编辑器,同时保存原 ckeditor4 版本,可后台切换
|
||||
* 全局改写 layTable 动态数据表格,支持静态刷新,同时兼容原生 table 方式
|
||||
* 增加 CORS 跨域规则配置,配置参数置放于 config/app.php,需要更新 ThinkLibrary
|
||||
* 修复 layui.table 导致基于 ThinkPHP 模板输出自动转义 XSS 过滤机制失效,需要更新 ThinkLibrary
|
||||
* 修复在模板中使用 {:input(NAME)} 取值而产生的 XSS 问题,模板取值更换为 {$get.NAME|default=''}
|
||||
* 修复 ckeditor4 配置文件,禁用所有标签的 on 事件,阻止 XSS 脚本注入,需要更新 ckeditor4/config.js
|
||||
* 修复上传入口的后缀验证,读取真实文件后缀与配置对比,阻止不合法的文件上传并存储到本地服务器
|
||||
* 修改 JsonRpc 接口异常处理机制,当服务端绑定 Exception 时,客户端将能收到 error 消息及异常数据
|
||||
* 修改 location.hash 访问机制,禁止直接访问外部 URL 资源链接,防止外部 XSS 攻击读取本地缓存数据
|
@ -1,51 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
return [
|
||||
'name' => 'admin',
|
||||
'vers' => '2022.03.06.01',
|
||||
'user' => '广州楚才信息科技有限公司',
|
||||
'link' => 'https://www.cuci.cc',
|
||||
'desc' => '系统管理模块,提供系统配置及应用模块管理。',
|
||||
'menu' => [
|
||||
[
|
||||
'name' => '应用管理',
|
||||
'subs' => [],
|
||||
],
|
||||
[
|
||||
'name' => '系统管理',
|
||||
'subs' => [
|
||||
[
|
||||
'name' => '系统配置',
|
||||
'subs' => [
|
||||
['name' => '系统参数配置', 'icon' => 'layui-icon layui-icon-set', 'path' => 'admin/config/index'],
|
||||
['name' => '系统任务管理', 'icon' => 'layui-icon layui-icon-log', 'path' => 'admin/queue/index'],
|
||||
['name' => '系统日志管理', 'icon' => 'layui-icon layui-icon-tabs', 'path' => 'admin/oplog/index'],
|
||||
['name' => '应用模块管理', 'icon' => 'layui-icon layui-icon-app', 'path' => 'admin/module/index'],
|
||||
['name' => '数据字典管理', 'icon' => 'layui-icon layui-icon-read', 'path' => 'admin/base/index'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => '权限管理',
|
||||
'subs' => [
|
||||
['name' => '访问权限管理', 'icon' => 'layui-icon layui-icon-vercode', 'path' => 'admin/auth/index'],
|
||||
['name' => '系统用户管理', 'icon' => 'layui-icon layui-icon-username', 'path' => 'admin/user/index'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "admin",
|
||||
"author": "Anyon",
|
||||
"version": "2022.07.11.01",
|
||||
"content": "ThinkAdmin 系统基础模块"
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
use think\admin\Library;
|
||||
use think\admin\service\SystemService;
|
||||
|
||||
/*! 非开发环境,清理限制文件 */
|
||||
if (Library::$sapp->request->isGet() && !SystemService::checkRunMode()) {
|
||||
@unlink(Library::$sapp->getBasePath() . 'admin/controller/api/Update.php');
|
||||
@unlink(Library::$sapp->getBasePath() . 'admin/route/demo.php');
|
||||
@rmdir(Library::$sapp->getBasePath() . 'admin/route');
|
||||
}
|
||||
|
||||
/*! 演示环境禁止操作路由绑定 */
|
||||
if (SystemService::checkRunMode('demo')) {
|
||||
Library::$sapp->route->post('index/pass', function () {
|
||||
return json(['code' => 0, 'info' => '演示环境禁止修改用户密码!']);
|
||||
});
|
||||
Library::$sapp->route->post('config/system', function () {
|
||||
return json(['code' => 0, 'info' => '演示环境禁止修改系统配置!']);
|
||||
});
|
||||
Library::$sapp->route->post('config/storage', function () {
|
||||
return json(['code' => 0, 'info' => '演示环境禁止修改系统配置!']);
|
||||
});
|
||||
Library::$sapp->route->post('menu', function () {
|
||||
return json(['code' => 0, 'info' => '演示环境禁止给菜单排序!']);
|
||||
});
|
||||
Library::$sapp->route->post('menu/index', function () {
|
||||
return json(['code' => 0, 'info' => '演示环境禁止给菜单排序!']);
|
||||
});
|
||||
Library::$sapp->route->post('menu/add', function () {
|
||||
return json(['code' => 0, 'info' => '演示环境禁止添加菜单!']);
|
||||
});
|
||||
Library::$sapp->route->post('menu/edit', function () {
|
||||
return json(['code' => 0, 'info' => '演示环境禁止编辑菜单!']);
|
||||
});
|
||||
Library::$sapp->route->post('menu/state', function () {
|
||||
return json(['code' => 0, 'info' => '演示环境禁止禁用菜单!']);
|
||||
});
|
||||
Library::$sapp->route->post('menu/remove', function () {
|
||||
return json(['code' => 0, 'info' => '演示环境禁止删除菜单!']);
|
||||
});
|
||||
Library::$sapp->route->post('user/pass', function () {
|
||||
return json(['code' => 0, 'info' => '演示环境禁止修改用户密码!']);
|
||||
});
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,307 +0,0 @@
|
||||
define(['md5', 'notify'], function (SparkMD5, Notify, allowMime) {
|
||||
allowMime = JSON.parse('{$exts|raw}');
|
||||
|
||||
function UploadAdapter(elem, done) {
|
||||
return new (function (elem, done, that) {
|
||||
|
||||
/*! 初始化变量 */
|
||||
that = this;
|
||||
this.option = {elem: $(elem), exts: [], mimes: []};
|
||||
this.option.size = this.option.elem.data('size') || 0;
|
||||
this.option.safe = this.option.elem.data('safe') ? 1 : 0;
|
||||
this.option.hide = this.option.elem.data('hload') ? 1 : 0;
|
||||
this.option.mult = this.option.elem.data('multiple') > 0;
|
||||
this.option.path = (this.option.elem.data('path') || '').replace(/\W/g, '');
|
||||
this.option.type = this.option.safe ? 'local' : this.option.elem.attr('data-uptype') || '';
|
||||
this.option.quality = parseFloat(this.option.elem.data('quality') || '1.0');
|
||||
this.option.maxWidth = parseInt(this.option.elem.data('max-width') || '0');
|
||||
this.option.maxHeight = parseInt(this.option.elem.data('max-height') || '0');
|
||||
this.option.cutWidth = parseInt(this.option.elem.data('cut-width') || '0');
|
||||
this.option.cutHeight = parseInt(this.option.elem.data('cut-height') || '0');
|
||||
|
||||
/*! 查找表单元素, 如果没有找到将不会自动写值 */
|
||||
if (!this.option.elem.data('input') && this.option.elem.data('field')) {
|
||||
this.$input = $('input[name="' + this.option.elem.data('field') + '"]:not([type=file])');
|
||||
this.option.elem.data('input', this.$input.size() > 0 ? this.$input.get(0) : null);
|
||||
}
|
||||
|
||||
/*! 文件选择筛选,使用 MIME 规则过滤文件列表 */
|
||||
$((this.option.elem.data('type') || '').split(',')).map(function (i, e) {
|
||||
if (allowMime[e]) that.option.exts.push(e), that.option.mimes.push(allowMime[e]);
|
||||
});
|
||||
|
||||
/*! 初始化上传组件 */
|
||||
this.adapter = new Adapter(this.option, layui.upload.render({
|
||||
url: '{:url("admin/api.upload/file")}', auto: false, elem: elem, accept: 'file', multiple: this.option.mult, exts: this.option.exts.join('|'), acceptMime: this.option.mimes.join(','), choose: function (obj) {
|
||||
obj.items = [], obj.files = obj.pushFile();
|
||||
layui.each(obj.files, function (idx, file) {
|
||||
obj.items.push(file);
|
||||
file.path = that.option.path;
|
||||
file.quality = that.option.quality;
|
||||
file.maxWidth = that.option.maxWidth;
|
||||
file.maxHeight = that.option.maxHeight;
|
||||
file.cutWidth = that.option.cutWidth;
|
||||
file.cutHeight = that.option.cutHeight;
|
||||
});
|
||||
that.adapter.event('upload.choose', obj.items);
|
||||
that.adapter.upload(obj.items, done);
|
||||
layui.each(obj.files, function (idx) {
|
||||
delete obj.files[idx];
|
||||
});
|
||||
}
|
||||
}));
|
||||
})(elem, done)
|
||||
}
|
||||
|
||||
// 创建对象
|
||||
UploadAdapter.adapter = window.AdminUploadAdapter = Adapter;
|
||||
|
||||
// 上传文件
|
||||
function Adapter(option, uploader) {
|
||||
this.uploader = uploader, this.config = function (option) {
|
||||
return (this.option = Object.assign({}, this.option || {}, option || {})), this;
|
||||
}, this.init = function (option) {
|
||||
this.uploader && this.uploader.config.elem.next().val('');
|
||||
this.files = {}, this.loader = 0, this.count = {total: 0, error: 0, success: 0};
|
||||
return this.config(option).config({safe: this.option.safe || 0, type: this.option.type || ''});
|
||||
}, this.init(option);
|
||||
}
|
||||
|
||||
// 文件推送
|
||||
Adapter.prototype.upload = function (files, done) {
|
||||
var that = this.init();
|
||||
layui.each(files, function (index, file) {
|
||||
that.count.total++, file.index = index, that.files[index] = file;
|
||||
if (that.option.size && file.size > that.option.size) {
|
||||
that.event('upload.error', {file: file}, file, '大小超限');
|
||||
} else if (!that.option.hide) {
|
||||
file.notify = new NotifyExtend(file);
|
||||
}
|
||||
}), layui.each(files, function (index, file) {
|
||||
// 禁传异常状态文件
|
||||
if (typeof file.xstate === 'number' && file.xstate === -1) return;
|
||||
// 图片限宽限高压缩
|
||||
if (/^image\//.test(file.type) && (file.maxWidth + file.maxHeight + file.cutWidth + file.cutHeight > 0 || file.quality !== 1)) {
|
||||
require(['compressor'], function (Compressor) {
|
||||
new Compressor(file, {
|
||||
quality: file.quality, resize: 'cover', width: file.cutWidth || 0, height: file.cutHeight || 0, maxWidth: file.maxWidth, maxHeight: file.maxHeight, success(blob) {
|
||||
blob.index = file.index, blob.notify = file.notify, blob.path = file.path, files[index] = blob;
|
||||
that.hash(files[index]).then(function (file) {
|
||||
that.event('upload.hash', file).request(file, done);
|
||||
});
|
||||
}, error: function () {
|
||||
that.event('upload.error', {file: file}, file, '压缩失败');
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
that.hash(file).then(function (file) {
|
||||
that.event('upload.hash', file).request(file, done);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 文件上传
|
||||
Adapter.prototype.request = function (file, done) {
|
||||
var that = this, data = {key: file.xkey, safe: that.option.safe, uptype: that.option.type};
|
||||
data.size = file.size, data.name = file.name, data.hash = file.xmd5, data.mime = file.type, data.xext = file.xext;
|
||||
jQuery.ajax("{:url('admin/api.upload/state')}", {
|
||||
data: data, method: 'post', success: function (ret) {
|
||||
file.id = ret.data.id || 0, file.xurl = ret.data.url;
|
||||
file.xsafe = ret.data.safe, file.xpath = ret.data.key, file.xtype = ret.data.uptype;
|
||||
if (parseInt(ret.code) === 404) {
|
||||
var uploader = {};
|
||||
uploader.url = ret.data.server;
|
||||
uploader.form = new FormData();
|
||||
uploader.form.append('key', ret.data.key);
|
||||
uploader.form.append('safe', ret.data.safe);
|
||||
uploader.form.append('uptype', ret.data.uptype);
|
||||
if (ret.data.uptype === 'qiniu') {
|
||||
uploader.form.append('token', ret.data.token);
|
||||
} else if (ret.data.uptype === 'alioss') {
|
||||
uploader.form.append('policy', ret.data['policy']);
|
||||
uploader.form.append('signature', ret.data['signature']);
|
||||
uploader.form.append('OSSAccessKeyId', ret.data['OSSAccessKeyId']);
|
||||
uploader.form.append('success_action_status', '200');
|
||||
uploader.form.append('Content-Disposition', 'inline;filename=' + encodeURIComponent(file.name));
|
||||
} else if (ret.data.uptype === 'txcos') {
|
||||
uploader.form.append('q-ak', ret.data['q-ak']);
|
||||
uploader.form.append('policy', ret.data['policy']);
|
||||
uploader.form.append('q-key-time', ret.data['q-key-time']);
|
||||
uploader.form.append('q-signature', ret.data['q-signature']);
|
||||
uploader.form.append('q-sign-algorithm', ret.data['q-sign-algorithm']);
|
||||
uploader.form.append('success_action_status', '200');
|
||||
uploader.form.append('Content-Disposition', 'inline;filename=' + encodeURIComponent(file.name));
|
||||
} else if (ret.data.uptype === 'upyun') {
|
||||
uploader.form.delete('key');
|
||||
uploader.form.delete('safe');
|
||||
uploader.form.delete('uptype');
|
||||
uploader.form.append('save-key', ret.data['key']);
|
||||
uploader.form.append('policy', ret.data['policy']);
|
||||
uploader.form.append('authorization', ret.data['authorization']);
|
||||
uploader.form.append('Content-Disposition', 'inline;filename=' + encodeURIComponent(file.name));
|
||||
}
|
||||
uploader.form.append('file', file, file.name), jQuery.ajax({
|
||||
url: uploader.url, data: uploader.form, type: 'post', xhr: function (xhr) {
|
||||
xhr = new XMLHttpRequest();
|
||||
return xhr.upload.addEventListener('progress', function (event) {
|
||||
file.xtotal = event.total, file.xloaded = event.loaded || 0;
|
||||
that.progress((file.xloaded / file.xtotal * 100).toFixed(2), file)
|
||||
}), xhr;
|
||||
}, contentType: false, error: function () {
|
||||
that.event('upload.error', {file: file}, file, '接口异常');
|
||||
}, processData: false, success: function (ret) {
|
||||
// 兼容数据格式
|
||||
if (typeof ret === 'string' && ret.length > 0) try {
|
||||
ret = JSON.parse(ret) || ret;
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
if (typeof ret !== 'object') {
|
||||
ret = {code: 1, url: file.xurl, info: '上传成功'};
|
||||
}
|
||||
/*! 检查单个文件上传返回的结果 */
|
||||
if (typeof ret === 'object' && ret.code < 1) {
|
||||
that.event('upload.error', {file: file}, file, ret.info || '上传失败');
|
||||
} else {
|
||||
that.done(ret, file.index, file, done, '上传成功');
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (parseInt(ret.code) === 200) {
|
||||
(file.xurl = ret.data.url), that.progress('100.00', file);
|
||||
that.done({code: 1, url: file.xurl, info: file.xstats}, file.index, file, done, '秒传成功');
|
||||
} else {
|
||||
that.event('upload.error', {file: file}, file, ret.info || ret.error.message || '上传出错!');
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 上传进度
|
||||
Adapter.prototype.progress = function (number, file) {
|
||||
this.event('upload.progress', {number: number, file: file});
|
||||
if (file.notify) file.notify.setProgress(number);
|
||||
};
|
||||
|
||||
// 上传结果
|
||||
Adapter.prototype.done = function (ret, idx, file, done, message) {
|
||||
/*! 检查单个文件上传返回的结果 */
|
||||
if (ret.code < 1) return $.msg.tips(ret.info || '文件上传失败!');
|
||||
if (typeof file.xurl !== 'string') return $.msg.tips('无效的文件上传对象!');
|
||||
jQuery.post("{:url('admin/api.upload/done')}", {id: file.id, hash: file.xmd5});
|
||||
/*! 单个文件上传成功结果处理 */
|
||||
if (typeof done === 'function') {
|
||||
done.call(this.option.elem, file.xurl, this.files['id']);
|
||||
} else if (this.option.mult < 1 && this.option.elem.data('input')) {
|
||||
$(this.option.elem.data('input')).val(file.xurl).trigger('change', file);
|
||||
}
|
||||
// 文件上传成功事件
|
||||
this.event('push', file.xurl).event('upload.done', {file: file, data: ret}, file, message);
|
||||
/*! 所有文件上传完成后结果处理 */
|
||||
if (this.count.success + this.count.error >= this.count.total) {
|
||||
this.option.hide || $.msg.close(this.loader);
|
||||
if (this.option.mult > 0 && this.option.elem.data('input')) {
|
||||
var urls = this.option.elem.data('input').value || [];
|
||||
if (typeof urls === 'string') urls = urls.split('|');
|
||||
for (var i in this.files) urls.push(this.files[i].xurl);
|
||||
$(this.option.elem.data('input')).val(urls.join('|')).trigger('change', this.files);
|
||||
}
|
||||
this.event('upload.complete', {file: this.files}, file).init().uploader && this.uploader.reload();
|
||||
}
|
||||
};
|
||||
|
||||
/*! 触发事件过程 */
|
||||
Adapter.prototype.event = function (name, data, file, message) {
|
||||
if (name === 'upload.error') {
|
||||
this.count.error++, file.xstate = -1, file.xstats = message;
|
||||
if (file.notify) file.notify.setError(message || file.xstats || '');
|
||||
} else if (name === 'upload.done') {
|
||||
this.count.success++, file.xstate = 1, file.xstats = message;
|
||||
if (file.notify) file.notify.setSuccess(message || file.xstats || '')
|
||||
}
|
||||
if (this.option.elem) {
|
||||
this.option.elem.triggerHandler(name, data);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* 计算文件 HASH 值
|
||||
* @param {File} file 文件对象
|
||||
* @return {Promise}
|
||||
*/
|
||||
Adapter.prototype.hash = function (file) {
|
||||
var defer = jQuery.Deferred();
|
||||
file.xext = file.name.indexOf('.') > -1 ? file.name.split('.').pop() : 'tmp';
|
||||
|
||||
/*! 兼容不能计算文件 HASH 的情况 */
|
||||
var IsDate = '{$nameType|default=""}'.indexOf('date') > -1;
|
||||
if (!window.FileReader || IsDate) return jQuery.when((function (xmd5, chars) {
|
||||
while (xmd5.length < 32) xmd5 += chars.charAt(Math.floor(Math.random() * chars.length));
|
||||
return SetFileXdata(file, xmd5, 6), defer.promise();
|
||||
})(layui.util.toDateString(Date.now(), 'yyyyMMddHHmmss-'), '0123456789'));
|
||||
|
||||
/*! 读取文件并计算 HASH 值 */
|
||||
return new LoadNextChunk(file).ReadAsChunk();
|
||||
|
||||
function SetFileXdata(file, xmd5, slice) {
|
||||
file.xmd5 = xmd5, file.xstate = 0, file.xstats = '';
|
||||
file.xkey = file.xmd5.substring(0, slice || 2) + '/' + file.xmd5.substring(slice || 2) + '.' + file.xext;
|
||||
if (file.path) file.xkey = file.path + '/' + file.xkey;
|
||||
return defer.resolve(file, file.xmd5, file.xkey), file;
|
||||
}
|
||||
|
||||
function LoadNextChunk(file) {
|
||||
var that = this, reader = new FileReader(), spark = new SparkMD5.ArrayBuffer();
|
||||
var slice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
|
||||
this.chunkIdx = 0, this.chunkSize = 2097152, this.chunkTotal = Math.ceil(file.size / this.chunkSize);
|
||||
reader.onload = function (event) {
|
||||
spark.append(event.target.result);
|
||||
++that.chunkIdx < that.chunkTotal ? that.ReadAsChunk() : SetFileXdata(file, spark.end());
|
||||
}, reader.onerror = function () {
|
||||
defer.reject();
|
||||
}, this.ReadAsChunk = function () {
|
||||
this.start = that.chunkIdx * that.chunkSize;
|
||||
this.loaded = this.start + that.chunkSize >= file.size ? file.size : this.start + that.chunkSize;
|
||||
reader.readAsArrayBuffer(slice.call(file, this.start, this.loaded));
|
||||
defer.notify(file, (this.loaded / file.size * 100).toFixed(2));
|
||||
return defer.promise();
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return UploadAdapter;
|
||||
|
||||
/**
|
||||
* 上传状态提示扩展插件
|
||||
* @param {File} file 文件对象
|
||||
* @constructor
|
||||
*/
|
||||
function NotifyExtend(file) {
|
||||
var that = this;
|
||||
this.notify = Notify.notify({width: 260, title: file.name, showProgress: true, description: '上传进度 <span data-upload-progress>0%</span>', type: 'default', position: 'top-right', closeTimeout: 0});
|
||||
this.$elem = $(this.notify.notification.nodes);
|
||||
this.$elem.find('.growl-notification__progress').addClass('is-visible');
|
||||
this.$elem.find('.growl-notification__progress-bar').addClass('transition');
|
||||
this.setProgress = function (number) {
|
||||
this.$elem.find('[data-upload-progress]').html(number + '%');
|
||||
this.$elem.find('.growl-notification__progress-bar').css({width: number + '%'});
|
||||
return this;
|
||||
}, this.setError = function (message) {
|
||||
this.$elem.find('.growl-notification__desc').html(message || '文件上传失败!');
|
||||
this.$elem.removeClass('growl-notification--default').addClass('growl-notification--error')
|
||||
return this.close();
|
||||
}, this.setSuccess = function (message) {
|
||||
this.setProgress('100.00');
|
||||
this.$elem.find('.growl-notification__desc').html(message || '文件上传成功!');
|
||||
this.$elem.removeClass('growl-notification--default').addClass('growl-notification--success');
|
||||
return this.close();
|
||||
}, this.close = function (timeout) {
|
||||
return setTimeout(function () {
|
||||
that.notify.close();
|
||||
}, timeout || 2000), this;
|
||||
};
|
||||
}
|
||||
});
|
@ -1,152 +0,0 @@
|
||||
<div class="image-dialog" id="ImageDialog">
|
||||
<div class="image-dialog-head">
|
||||
<div class="pull-left flex">
|
||||
<input class="layui-input margin-right-5" v-model="keys" style="height:30px;line-height:30px" placeholder="请输入搜索关键词">
|
||||
<a class="layui-btn layui-btn-sm layui-btn-normal" @click="search">搜 索</a>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<a class="layui-btn layui-btn-sm" @click="uploadImage">上传图片</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-dialog-body">
|
||||
<div class="image-dialog-item" v-for="x in items" v-if="show">
|
||||
<div class="uploadimage" :style="x.style" @click="setValue(x.xurl)"></div>
|
||||
<p class="image-dialog-item-name layui-elip" v-text="x.name"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-dialog-foot">
|
||||
<div id="ImageDialogPage" class="image-dialog-page"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.image-dialog-head {
|
||||
clear: both;
|
||||
height: 30px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
.image-dialog-body {
|
||||
height: 470px;
|
||||
background: #efefef;
|
||||
padding-top: 12px;
|
||||
padding-left: 12px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: flex-start;
|
||||
}
|
||||
|
||||
.image-dialog-item {
|
||||
position: relative;
|
||||
margin-right: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.image-dialog-item-name {
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
color: #fff;
|
||||
padding: 3px 10px;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
line-height: 1.5em;
|
||||
white-space: nowrap;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
.image-dialog-item .uploadimage {
|
||||
margin: 0;
|
||||
width: 145px;
|
||||
height: 145px;
|
||||
}
|
||||
|
||||
.image-dialog-foot {
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.image-dialog-page {
|
||||
height: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.image-dialog-page .layui-laypage a,
|
||||
.image-dialog-page .layui-laypage span {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
require(['vue'], function (vue) {
|
||||
var app = new vue({
|
||||
el: '#ImageDialog',
|
||||
data: {
|
||||
page: 1,
|
||||
limit: 15,
|
||||
show: false,
|
||||
$btn: null,
|
||||
keys: '',
|
||||
items: [],
|
||||
},
|
||||
created: function () {
|
||||
this.$btn = $('#{$get.id|default=""}');
|
||||
this.loadPage();
|
||||
},
|
||||
methods: {
|
||||
// 创建分页工具条
|
||||
addPage: function (count) {
|
||||
var that = this;
|
||||
this.show = true;
|
||||
layui.laypage.render({
|
||||
curr: this.page, count: count, limit: that.limit,
|
||||
layout: ['count', 'prev', 'page', 'next', 'refresh'],
|
||||
elem: 'ImageDialogPage', jump: function (obj, first) {
|
||||
if (!first) that.loadPage(that.page = obj.curr);
|
||||
},
|
||||
});
|
||||
},
|
||||
// 搜索刷新数据
|
||||
search: function () {
|
||||
this.page = 1;
|
||||
this.loadPage();
|
||||
},
|
||||
// 设置选择数据
|
||||
setValue: function (url) {
|
||||
this.$btn.trigger('choose', url);
|
||||
if (this.$btn.data('input')) $(this.$btn.data('input')).val(url).trigger('change', url);
|
||||
$('#ImageDialog').parents('.layui-layer-content').next().find('.layui-layer-close').trigger('click');
|
||||
},
|
||||
// 加载页面数据
|
||||
loadPage: function () {
|
||||
var that = this;
|
||||
this.params = {page: this.page, limit: this.limit, output: 'layui.table', name: this.keys || ''};
|
||||
$.form.load('{:url("image")}', this.params, 'get', function (ret) {
|
||||
that.addPage(ret.count);
|
||||
that.items = ret.data;
|
||||
that.items.forEach(function (item) {
|
||||
item.style = 'background-image:url(' + item.xurl + ')';
|
||||
});
|
||||
return false;
|
||||
});
|
||||
},
|
||||
// 上传图片文件
|
||||
uploadImage: function () {
|
||||
$('[data-field="image-dialog-upload-input"]').click();
|
||||
$('[name="image-dialog-upload-input"]').one('change', function (e) {
|
||||
app.setValue(e.currentTarget.value);
|
||||
// e.currentTarget.value 取上传后的值
|
||||
// app.page = 1;
|
||||
// app.loadPage();
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<label class="layui-hide">
|
||||
<!-- 图片上传组件 开始 -->
|
||||
<input class="layui-input" name="image-dialog-upload-input">
|
||||
<button class="layui-btn" data-file data-type="png,jpg,jpeg,gif" data-field="image-dialog-upload-input"></button>
|
||||
<!-- 图片上传组件 结束 -->
|
||||
</label>
|
@ -1,136 +0,0 @@
|
||||
<div class="image-dialog" id="ImageDialog">
|
||||
<div class="image-dialog-head">
|
||||
<div class="pull-left flex">
|
||||
<input class="layui-input margin-right-5" v-model="keys" style="height:30px;line-height:30px" placeholder="请输入搜索关键词">
|
||||
<a class="layui-btn layui-btn-sm layui-btn-normal" @click="search">搜 索</a>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<a class="layui-btn layui-btn-sm layui-btn-normal" @click="uploadImage">上传图片</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-dialog-body">
|
||||
<div class="image-dialog-item" v-for="x in list" @click="setItem(x)" style="display:none" v-show="show" :class="{'image-dialog-checked':x.checked}">
|
||||
<div class="uploadimage" :style="x.style"></div>
|
||||
<p class="image-dialog-item-name layui-elip" v-text="x.name"></p>
|
||||
<span class="image-dialog-item-size">{{formatSize(x.size)}}</span>
|
||||
<span class="image-dialog-item-type">{{x.xext.toUpperCase()}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-dialog-foot">
|
||||
<div id="ImageDialogPage" class="image-dialog-page"></div>
|
||||
<div id="ImageDialogButton layui-hide" class="image-dialog-button layui-btn layui-btn-normal" v-if="data.length>0" @click="confirm">
|
||||
已选 {{ data.length }} 张,确认
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
require(['vue'], function (vue) {
|
||||
var app = new vue({
|
||||
el: '#ImageDialog',
|
||||
data: {
|
||||
didx: 0,
|
||||
page: 1, limit: 15, show: false, mult: false,
|
||||
keys: '', list: [], data: [], idxs: {}, urls: [],
|
||||
},
|
||||
created: function () {
|
||||
this.didx = $.msg.mdx.pop();
|
||||
this.$btn = $('#{$get.id|default=""}');
|
||||
this.$ups = $('#ImageDialogUploadLayout [data-file]');
|
||||
this.mult = "{$get.file|default='image'}" === 'images';
|
||||
this.loadPage(), setTimeout(function () {
|
||||
$('#ImageDialogButton').removeClass('layui-hide');
|
||||
}, 1000);
|
||||
},
|
||||
methods: {
|
||||
// 搜索刷新数据
|
||||
search: function () {
|
||||
this.page = 1;
|
||||
this.loadPage();
|
||||
},
|
||||
// 确认选择数据
|
||||
confirm: function () {
|
||||
this.urls = [];
|
||||
this.data.forEach(function (file) {
|
||||
app.setValue(file.xurl);
|
||||
}), this.setInput();
|
||||
},
|
||||
// 格式文件大小
|
||||
formatSize: function (size) {
|
||||
return $.formatFileSize(size);
|
||||
},
|
||||
// 设置单项数据
|
||||
setItem: function (item) {
|
||||
if (!this.mult) {
|
||||
this.setValue(item.xurl).setInput();
|
||||
} else if ((item.checked = !this.idxs[item.id])) {
|
||||
(this.idxs[item.id] = item) && this.data.push(item);
|
||||
} else {
|
||||
delete this.idxs[item.id];
|
||||
this.data.forEach(function (temp, idx) {
|
||||
temp.id === item.id && app.data.splice(idx, 1);
|
||||
});
|
||||
}
|
||||
},
|
||||
// 更新列表数据
|
||||
setList: function (items, count) {
|
||||
this.list = items;
|
||||
this.list.forEach(function (item) {
|
||||
item.checked = !!app.idxs[item.id]
|
||||
item.style = 'background-image:url(' + item.xurl + ')';
|
||||
}), this.addPage(count);
|
||||
},
|
||||
// 设置选择数据
|
||||
setValue: function (xurl) {
|
||||
$.msg.close(this.didx);
|
||||
this.urls.push(xurl) && this.$btn.triggerHandler('push', xurl);
|
||||
return this;
|
||||
},
|
||||
// 设置输入表单
|
||||
setInput: function () {
|
||||
if (this.$btn.data('input')) {
|
||||
$(this.$btn.data('input')).val(this.urls.join('|')).trigger('change');
|
||||
}
|
||||
},
|
||||
// 创建分页工具条
|
||||
addPage: function (count) {
|
||||
this.show = true;
|
||||
layui.laypage.render({
|
||||
curr: this.page, count: count, limit: app.limit,
|
||||
layout: ['count', 'prev', 'page', 'next', 'refresh'],
|
||||
elem: 'ImageDialogPage', jump: function (obj, first) {
|
||||
if (!first) app.loadPage(app.page = obj.curr);
|
||||
},
|
||||
});
|
||||
},
|
||||
// 加载页面数据
|
||||
loadPage: function () {
|
||||
this.params = {page: this.page, limit: this.limit, output: 'layui.table', name: this.keys || ''};
|
||||
this.params.type = '{$get.type|default="gif,png,jpg,jpeg"}';
|
||||
$.form.load('{:url("image")}', this.params, 'get', function (ret) {
|
||||
return app.setList(ret.data, ret.count), false;
|
||||
});
|
||||
},
|
||||
// 上传图片文件
|
||||
uploadImage: function () {
|
||||
this.urls = [];
|
||||
this.$ups.off('push').on('push', function (e, xurl) {
|
||||
app.setValue(xurl);
|
||||
}).off('upload.complete').on('upload.complete', function () {
|
||||
app.setInput();
|
||||
}).click();
|
||||
},
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<label class="layui-hide" id="ImageDialogUploadLayout">
|
||||
<!-- 图片上传组件 开始 -->
|
||||
{if isset($get.file) && $get.file eq 'image'}
|
||||
<button class="layui-btn" data-file data-path="{$get.path|default=''}" data-type="png,jpg,jpeg,gif"></button>
|
||||
{else}
|
||||
<button class="layui-btn" data-file="mul" data-path="{$get.path|default=''}" data-type="png,jpg,jpeg,gif"></button>
|
||||
{/if}
|
||||
<!-- 图片上传组件 结束 -->
|
||||
</label>
|
@ -1,152 +0,0 @@
|
||||
<div class="image-dialog" id="ImageDialog">
|
||||
<div class="image-dialog-head">
|
||||
<div class="pull-left flex">
|
||||
<input class="layui-input margin-right-5" v-model="keys" style="height:30px;line-height:30px" placeholder="请输入搜索关键词">
|
||||
<a class="layui-btn layui-btn-sm layui-btn-normal" @click="search">搜 索</a>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<a class="layui-btn layui-btn-sm" @click="uploadImage">上传图片</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-dialog-body">
|
||||
<div class="image-dialog-item" v-for="x in items" v-if="show">
|
||||
<div class="uploadimage" :style="x.style" @click="setValue(x.xurl)"></div>
|
||||
<p class="image-dialog-item-name layui-elip" v-text="x.name"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-dialog-foot">
|
||||
<div id="ImageDialogPage" class="image-dialog-page"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.image-dialog-head {
|
||||
clear: both;
|
||||
height: 30px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
.image-dialog-body {
|
||||
height: 470px;
|
||||
background: #efefef;
|
||||
padding-top: 12px;
|
||||
padding-left: 12px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: flex-start;
|
||||
}
|
||||
|
||||
.image-dialog-item {
|
||||
position: relative;
|
||||
margin-right: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.image-dialog-item-name {
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
color: #fff;
|
||||
padding: 3px 10px;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
line-height: 1.5em;
|
||||
white-space: nowrap;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
.image-dialog-item .uploadimage {
|
||||
margin: 0;
|
||||
width: 145px;
|
||||
height: 145px;
|
||||
}
|
||||
|
||||
.image-dialog-foot {
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.image-dialog-page {
|
||||
height: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.image-dialog-page .layui-laypage a,
|
||||
.image-dialog-page .layui-laypage span {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
require(['vue'], function (vue) {
|
||||
var app = new vue({
|
||||
el: '#ImageDialog',
|
||||
data: {
|
||||
page: 1,
|
||||
limit: 15,
|
||||
show: false,
|
||||
$btn: null,
|
||||
keys: '',
|
||||
items: [],
|
||||
},
|
||||
created: function () {
|
||||
this.$btn = $('#{$get.id|default=""}');
|
||||
this.loadPage();
|
||||
},
|
||||
methods: {
|
||||
// 创建分页工具条
|
||||
addPage: function (count) {
|
||||
var that = this;
|
||||
this.show = true;
|
||||
layui.laypage.render({
|
||||
curr: this.page, count: count, limit: that.limit,
|
||||
layout: ['count', 'prev', 'page', 'next', 'refresh'],
|
||||
elem: 'ImageDialogPage', jump: function (obj, first) {
|
||||
if (!first) that.loadPage(that.page = obj.curr);
|
||||
},
|
||||
});
|
||||
},
|
||||
// 搜索刷新数据
|
||||
search: function () {
|
||||
this.page = 1;
|
||||
this.loadPage();
|
||||
},
|
||||
// 设置选择数据
|
||||
setValue: function (url) {
|
||||
this.$btn.trigger('choose', url);
|
||||
if (this.$btn.data('input')) $(this.$btn.data('input')).val(url).trigger('change', url);
|
||||
$('#ImageDialog').parents('.layui-layer-content').next().find('.layui-layer-close').trigger('click');
|
||||
},
|
||||
// 加载页面数据
|
||||
loadPage: function () {
|
||||
var that = this;
|
||||
this.params = {page: this.page, limit: this.limit, output: 'layui.table', name: this.keys || ''};
|
||||
$.form.load('{:url("image")}', this.params, 'get', function (ret) {
|
||||
that.addPage(ret.count);
|
||||
that.items = ret.data;
|
||||
that.items.forEach(function (item) {
|
||||
item.style = 'background-image:url(' + item.xurl + ')';
|
||||
});
|
||||
return false;
|
||||
});
|
||||
},
|
||||
// 上传图片文件
|
||||
uploadImage: function () {
|
||||
$('[data-field="image-dialog-upload-input"]').click();
|
||||
$('[name="image-dialog-upload-input"]').one('change', function (e) {
|
||||
app.setValue(e.currentTarget.value);
|
||||
// e.currentTarget.value 取上传后的值
|
||||
// app.page = 1;
|
||||
// app.loadPage();
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<label class="layui-hide">
|
||||
<!-- 图片上传组件 开始 -->
|
||||
<input class="layui-input" name="image-dialog-upload-input">
|
||||
<button class="layui-btn" data-file data-type="png,jpg,jpeg,gif" data-field="image-dialog-upload-input"></button>
|
||||
<!-- 图片上传组件 结束 -->
|
||||
</label>
|
@ -1,104 +0,0 @@
|
||||
{extend name='main'}
|
||||
|
||||
{block name="content"}
|
||||
<div class="think-box-shadow">
|
||||
<ul id="zTree" class="ztree notselect"></ul>
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="layui-form-item text-center">
|
||||
<button class="layui-btn" data-submit-role type='button'>保存数据</button>
|
||||
<button class="layui-btn layui-btn-danger" type='button' onclick="window.history.back()">取消编辑</button>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
{block name="script"}
|
||||
<script>
|
||||
require(['jquery.ztree'], function () {
|
||||
new function () {
|
||||
var that = this;
|
||||
this.data = {}, this.ztree = null, this.setting = {
|
||||
view: {showLine: false, showIcon: false, dblClickExpand: false},
|
||||
check: {enable: true, nocheck: false, chkboxType: {"Y": "ps", "N": "ps"}}, callback: {
|
||||
beforeClick: function (id, node) {
|
||||
node.children.length < 1 ? that.ztree.checkNode(node, !node.checked, null, true) : that.ztree.expandNode(node);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
this.renderChildren = function (list, level) {
|
||||
var childrens = [];
|
||||
for (var i in list) childrens.push({
|
||||
open: true, node: list[i].node, name: list[i].title || list[i].node,
|
||||
checked: list[i].checked || false, children: this.renderChildren(list[i]._sub_, level + 1)
|
||||
});
|
||||
return childrens;
|
||||
};
|
||||
this.getData = function () {
|
||||
$.form.load('{:url("apply")}', {id: '{$vo.id}', action: 'get'}, 'post', function (ret) {
|
||||
return (that.data = that.renderChildren(ret.data, 1)), that.showTree(), false;
|
||||
});
|
||||
};
|
||||
this.showTree = function () {
|
||||
this.ztree = $.fn.zTree.init($("#zTree"), this.setting, this.data);
|
||||
while (true) {
|
||||
var nodes = this.ztree.getNodesByFilter(function (node) {
|
||||
return (!node.node && node.children.length < 1);
|
||||
});
|
||||
if (nodes.length < 1) break;
|
||||
for (var i in nodes) this.ztree.removeNode(nodes[i]);
|
||||
}
|
||||
};
|
||||
this.submit = function () {
|
||||
var nodes = [], data = this.ztree.getCheckedNodes(true);
|
||||
for (var i in data) if (data[i].node) nodes.push(data[i].node);
|
||||
$.form.load('{:url("apply")}', {id: '{$vo.id}', action: 'save', nodes: nodes}, 'post');
|
||||
};
|
||||
// 刷新数据
|
||||
this.getData();
|
||||
// 提交表单
|
||||
$('[data-submit-role]').on('click', function () {
|
||||
that.submit();
|
||||
});
|
||||
};
|
||||
});
|
||||
</script>
|
||||
{/block}
|
||||
|
||||
{block name="style"}
|
||||
<style>
|
||||
ul.ztree li {
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
ul.ztree li span.button.switch {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
ul.ztree ul ul li {
|
||||
display: inline-block;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
ul.ztree > li {
|
||||
padding: 15px 25px 15px 15px;
|
||||
}
|
||||
|
||||
ul.ztree > li > ul {
|
||||
margin-top: 12px;
|
||||
border-top: 1px solid rgba(0, 0, 0, .1);
|
||||
}
|
||||
|
||||
ul.ztree > li > ul > li {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
ul.ztree > li > a > span {
|
||||
font-weight: 700;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
ul.ztree .level2 .button.level2 {
|
||||
background: 0 0;
|
||||
}
|
||||
</style>
|
||||
{/block}
|
@ -1,25 +0,0 @@
|
||||
<form action="{:sysuri()}" method="post" data-auto="true" class="layui-form layui-card" data-table-id="RoleTable">
|
||||
|
||||
<div class="layui-card-body padding-left-40">
|
||||
|
||||
<label class="layui-form-item relative block">
|
||||
<span class="help-label"><b>权限名称</b>Permission Name</span>
|
||||
<input maxlength="100" class="layui-input" name="title" value='{$vo.title|default=""}' required placeholder="请输入权限名称">
|
||||
<span class="help-block">访问权限名称需要保持不重复,在给用户授权时需要根据名称选择!</span>
|
||||
</label>
|
||||
|
||||
<label class="layui-form-item relative block">
|
||||
<span class="help-label"><b>权限描述</b>Permission Description</span>
|
||||
<textarea placeholder="请输入权限描述" maxlength="200" class="layui-textarea" name="desc">{$vo.desc|default=""}</textarea>
|
||||
</label>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
{notempty name='vo.id'}<input type='hidden' value='{$vo.id}' name='id'>{/notempty}
|
||||
|
||||
<div class="layui-form-item text-center">
|
||||
<button class="layui-btn" type='submit'>保存数据</button>
|
||||
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
|
||||
</div>
|
||||
</form>
|
@ -1,80 +0,0 @@
|
||||
{extend name='table'}
|
||||
|
||||
{block name="button"}
|
||||
<!--{if auth("add")}-->
|
||||
<button data-modal='{:url("add")}' data-width="600px" data-table-id="RoleTable" class='layui-btn layui-btn-sm layui-btn-primary'>添加权限</button>
|
||||
<!--{/if}-->
|
||||
|
||||
<!--{if auth("remove")}-->
|
||||
<button data-action='{:url("remove")}' data-table-id="RoleTable" data-rule="id#{id}" data-confirm="确定要批量删除权限吗?" class='layui-btn layui-btn-sm layui-btn-primary'>批量删除</button>
|
||||
<!--{/if}-->
|
||||
{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="think-box-shadow">
|
||||
{include file='auth/index_search'}
|
||||
<table id="RoleTable" data-url="{:sysuri()}" data-target-search="form.form-search"></table>
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
{block name='script'}
|
||||
<script>
|
||||
$(function () {
|
||||
// 初始化表格组件
|
||||
$('#RoleTable').layTable({
|
||||
even: true, height: 'full',
|
||||
sort: {field: 'sort desc,id', type: 'desc'},
|
||||
cols: [[
|
||||
{checkbox: true, fixed: true},
|
||||
{field: 'sort', title: '排序权重', align: 'center', width: 100, sort: true, templet: '#SortInputRoleTableTpl'},
|
||||
{field: 'title', title: '权限名称', align: 'center', minWidth: 140},
|
||||
{field: 'desc', title: '权限描述', align: 'center', minWidth: 110, templet: '<div>{{d.desc||"-"}}</div>'},
|
||||
{field: 'status', title: '权限状态', align: 'center', minWidth: 110, templet: '#StatusSwitchRoleTableTpl'},
|
||||
{field: 'create_at', title: '创建时间', align: 'center', minWidth: 170, sort: true},
|
||||
{toolbar: '#ToolbarRoleTableTpl', title: '操作面板', align: 'center', minWidth: 210, fixed: 'right'},
|
||||
]]
|
||||
});
|
||||
|
||||
// 数据状态切换操作
|
||||
layui.form.on('switch(StatusSwitchRoleTable)', function (obj) {
|
||||
var data = {id: obj.value, status: obj.elem.checked > 0 ? 1 : 0};
|
||||
$.form.load("{:url('state')}", data, 'post', function (ret) {
|
||||
if (ret.code < 1) $.msg.error(ret.info, 3, function () {
|
||||
$('#RoleTable').trigger('reload');
|
||||
});
|
||||
return false;
|
||||
}, false);
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<!-- 列表排序权重模板 -->
|
||||
<script type="text/html" id="SortInputRoleTableTpl">
|
||||
<input type="number" min="0" data-blur-number="0" data-action-blur="{:sysuri()}" data-value="id#{{d.id}};action#sort;sort#{value}" data-loading="false" value="{{d.sort}}" class="layui-input text-center">
|
||||
</script>
|
||||
|
||||
<!-- 数据状态切换模板 -->
|
||||
<script type="text/html" id="StatusSwitchRoleTableTpl">
|
||||
<!--{if auth("state")}-->
|
||||
<input type="checkbox" value="{{d.id}}" lay-skin="switch" lay-text="已激活|已禁用" lay-filter="StatusSwitchRoleTable" {{-d.status>0?'checked':''}}>
|
||||
<!--{else}-->
|
||||
{{-d.status ? '<b class="color-green">已启用</b>' : '<b class="color-red">已禁用</b>'}}
|
||||
<!--{/if}-->
|
||||
</script>
|
||||
|
||||
<!-- 数据操作工具条模板 -->
|
||||
<script type="text/html" id="ToolbarRoleTableTpl">
|
||||
<!--{if auth('edit')}-->
|
||||
<a class="layui-btn layui-btn-primary layui-btn-sm" data-event-dbclick data-width="600px" data-title="编辑权限" data-modal='{:url("edit")}?id={{d.id}}'>编 辑</a>
|
||||
<!--{/if}-->
|
||||
|
||||
<!--{if auth("apply")}-->
|
||||
<a class="layui-btn layui-btn-normal layui-btn-sm" data-open='{:url("apply")}?id={{d.id}}'>授 权</a>
|
||||
<!--{/if}-->
|
||||
|
||||
<!--{if auth("remove")}-->
|
||||
<a class="layui-btn layui-btn-danger layui-btn-sm" data-confirm="确定要删除权限吗?" data-action="{:url('remove')}" data-value="id#{{d.id}}">删 除</a>
|
||||
<!--{/if}-->
|
||||
</script>
|
||||
{/block}
|
@ -1,45 +0,0 @@
|
||||
<fieldset>
|
||||
<legend>条件搜索</legend>
|
||||
<form class="layui-form layui-form-pane form-search" action="{:sysuri()}" onsubmit="return false" method="get" autocomplete="off">
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">权限名称</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="title" value="{$get.title|default=''}" placeholder="请输入权限名称" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">权限描述</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="desc" value="{$get.desc|default=''}" placeholder="请输入权限描述" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">使用状态</label>
|
||||
<div class="layui-input-inline">
|
||||
<select class="layui-select" name="status">
|
||||
<option value=''>-- 全部状态 --</option>
|
||||
{foreach ['已禁用的权限','已激活的权限'] as $k=>$v}
|
||||
{if isset($get.status) and $get.status eq $k.""}
|
||||
<option selected value="{$k}">{$v}</option>
|
||||
{else}
|
||||
<option value="{$k}">{$v}</option>
|
||||
{/if}{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">创建时间</label>
|
||||
<div class="layui-input-inline">
|
||||
<input data-date-range name="create_at" value="{$get.create_at|default=''}" placeholder="请选择创建时间" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<button class="layui-btn layui-btn-primary"><i class="layui-icon"></i> 搜 索</button>
|
||||
</div>
|
||||
</form>
|
||||
</fieldset>
|
@ -1,68 +0,0 @@
|
||||
<form action="{:sysuri()}" method="post" data-auto="true" class="layui-form layui-card" data-table-id="BaseTable">
|
||||
|
||||
<div class="layui-card-body padding-left-40">
|
||||
|
||||
<div class="layui-form-item label-required-prev">
|
||||
<div class="help-label"><b>数据类型</b>DataType</div>
|
||||
{if isset($vo.type)}
|
||||
<label><input readonly value="{$vo.type|default=''}" class="layui-input think-bg-gray"></label>
|
||||
{else}
|
||||
<select class="layui-select" lay-filter="DataType">
|
||||
{foreach $types as $type}{if (isset($vo.type) and $type eq $vo.type) or ($type eq input('get.type'))}
|
||||
<option selected value="{$type}">{$type}</option>
|
||||
{else}
|
||||
<option value="{$type}">{$type}</option>
|
||||
{/if}{/foreach}
|
||||
</select>
|
||||
<script>
|
||||
(function (callable) {
|
||||
layui.form.on('select(DataType)', callable);
|
||||
callable({value: "{$vo.type|default=''}" || $('[lay-filter=DataType]').val()});
|
||||
})(function (data) {
|
||||
if (data.value === '--- 新增类型 ---') {
|
||||
$('#DataTypeInput').removeClass('layui-hide').find('input').val('').focus();
|
||||
} else {
|
||||
$('#DataTypeInput').addClass('layui-hide').find('input').val(data.value);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{/if}
|
||||
<p class="help-block">请选择数据类型,数据创建后不能再次修改哦 ~</p>
|
||||
<div id="DataTypeInput" class="layui-hide relative">
|
||||
<input class="layui-input" maxlength="20" name="type" required placeholder="请输入数据类型" value="{$vo.type|default=''}">
|
||||
<p class="help-block">请输入新的数据类型,数据创建后不能再次修改哦 ~</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label class="layui-form-item relative block">
|
||||
<span class="help-label"><b>数据编码</b>DataCode</span>
|
||||
{if isset($vo.code)}
|
||||
<input readonly maxlength="100" class="layui-input think-bg-gray" name="code" value='{$vo.code|default=""}' required placeholder="请输入数据编码">
|
||||
{else}
|
||||
<input maxlength="100" class="layui-input" name="code" value='{$vo.code|default=""}' required placeholder="请输入数据编码">
|
||||
{/if}
|
||||
<span class="help-block">请输入新的数据编码,数据创建后不能再次修改,同种数据类型的数据编码不能出现重复 ~</span>
|
||||
</label>
|
||||
|
||||
<label class="layui-form-item relative block">
|
||||
<span class="help-label"><b>数据名称</b>DataName</span>
|
||||
<input maxlength="500" class="layui-input" name="name" value='{$vo.name|default=""}' required placeholder="请输入数据名称">
|
||||
<span class="help-block">请输入当前数据名称,请尽量保持名称的唯一性,数据名称尽量不要出现重复 ~</span>
|
||||
</label>
|
||||
|
||||
<label class="layui-form-item relative block">
|
||||
<span class="help-label"><b>数据内容</b>DataContent</span>
|
||||
<textarea name="content" class="layui-textarea" placeholder="请输入数据内容">{$vo.content|default=''}</textarea>
|
||||
</label>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
{notempty name='vo.id'}<input type='hidden' value='{$vo.id}' name='id'>{/notempty}
|
||||
|
||||
<div class="layui-form-item text-center">
|
||||
<button class="layui-btn" type='submit'>保存数据</button>
|
||||
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
|
||||
</div>
|
||||
|
||||
</form>
|
@ -1,86 +0,0 @@
|
||||
{extend name='table'}
|
||||
|
||||
{block name="button"}
|
||||
<!--{if auth("add")}-->
|
||||
<button data-table-id="BaseTable" data-modal='{:url("add")}?type={$type|default=""}' class='layui-btn layui-btn-sm layui-btn-primary'>添加数据</button>
|
||||
<!--{/if}-->
|
||||
|
||||
<!--{if auth("remove")}-->
|
||||
<button data-table-id="BaseTable" data-action='{:url("remove")}' data-rule="id#{id}" data-confirm="确定要批量删除数据吗?" class='layui-btn layui-btn-sm layui-btn-primary'>批量删除</button>
|
||||
<!--{/if}-->
|
||||
{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="layui-tab layui-tab-card">
|
||||
<ul class="layui-tab-title">
|
||||
{foreach $types as $t}{if isset($type) and $type eq $t}
|
||||
<li class="layui-this" data-open="{:sysuri()}?type={$t}">{$t}</li>
|
||||
{else}
|
||||
<li data-open="{:sysuri()}?type={$t}">{$t}</li>
|
||||
{/if}{/foreach}
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
{include file='base/index_search'}
|
||||
<table id="BaseTable" data-url="{:sysuri()}" data-target-search="form.form-search"></table>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
{block name='script'}
|
||||
<script>
|
||||
$(function () {
|
||||
// 初始化表格组件
|
||||
$('#BaseTable').layTable({
|
||||
even: true, height: 'full',
|
||||
sort: {field: 'sort desc,id', type: 'asc'},
|
||||
where: {type: '{$type|default=""}'},
|
||||
cols: [[
|
||||
{checkbox: true, fixed: true},
|
||||
{field: 'sort', title: '排序权重', width: 100, align: 'center', sort: true, templet: '#SortInputTpl'},
|
||||
// {field: 'type', title: '数据类型', minWidth: 140, align: 'center'},
|
||||
{field: 'code', title: '数据编码', width: '20%', align: 'left'},
|
||||
{field: 'name', title: '数据名称', width: '30%', align: 'left'},
|
||||
{field: 'status', title: '数据状态', minWidth: 110, align: 'center', templet: '#StatusSwitchTpl'},
|
||||
{field: 'create_at', title: '创建时间', minWidth: 170, align: 'center', sort: true},
|
||||
{toolbar: '#toolbar', align: 'center', minWidth: 150, title: '数据操作', fixed: 'right'},
|
||||
]]
|
||||
});
|
||||
|
||||
// 数据状态切换操作
|
||||
layui.form.on('switch(StatusSwitch)', function (obj) {
|
||||
var data = {id: obj.value, status: obj.elem.checked > 0 ? 1 : 0};
|
||||
$.form.load("{:url('state')}", data, 'post', function (ret) {
|
||||
if (ret.code < 1) $.msg.error(ret.info, 3, function () {
|
||||
$('#BaseTable').trigger('reload');
|
||||
});
|
||||
return false;
|
||||
}, false);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- 列表排序权重模板 -->
|
||||
<script type="text/html" id="SortInputTpl">
|
||||
<input type="number" min="0" data-blur-number="0" data-action-blur="{:sysuri()}" data-value="id#{{d.id}};action#sort;sort#{value}" data-loading="false" value="{{d.sort}}" class="layui-input text-center">
|
||||
</script>
|
||||
|
||||
<!-- 数据状态切换模板 -->
|
||||
<script type="text/html" id="StatusSwitchTpl">
|
||||
<!--{if auth("state")}-->
|
||||
<input type="checkbox" value="{{d.id}}" lay-skin="switch" lay-text="已激活|已禁用" lay-filter="StatusSwitch" {{-d.status>0?'checked':''}}>
|
||||
<!--{else}-->
|
||||
{{-d.status ? '<b class="color-green">已启用</b>' : '<b class="color-red">已禁用</b>'}}
|
||||
<!--{/if}-->
|
||||
</script>
|
||||
|
||||
<!-- 数据操作工具条模板 -->
|
||||
<script type="text/html" id="toolbar">
|
||||
<!--{if auth('edit')}-->
|
||||
<a class="layui-btn layui-btn-primary layui-btn-sm" data-event-dbclick data-title="编辑数据" data-modal='{:url("edit")}?id={{d.id}}'>编 辑</a>
|
||||
<!--{/if}-->
|
||||
|
||||
<!--{if auth("remove")}-->
|
||||
<a class="layui-btn layui-btn-danger layui-btn-sm" data-confirm="确定要删除数据吗?" data-action="{:url('remove')}" data-value="id#{{d.id}}">删 除</a>
|
||||
<!--{/if}-->
|
||||
</script>
|
||||
{/block}
|
@ -1,42 +0,0 @@
|
||||
<form class="layui-form layui-form-pane form-search" action="{:sysuri()}" onsubmit="return false" method="get" autocomplete="off">
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">数据编码</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="code" value="{$get.code|default=''}" placeholder="请输入数据编码" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">数据名称</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="name" value="{$get.name|default=''}" placeholder="请输入数据名称" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">使用状态</label>
|
||||
<div class="layui-input-inline">
|
||||
<select class="layui-select" name="status">
|
||||
<option value=''>-- 状态 --</option>
|
||||
{foreach ['已禁用的权限','已激活的权限'] as $k=>$v}
|
||||
{if isset($get.status) and $get.status eq $k.""}
|
||||
<option selected value="{$k}">{$v}</option>
|
||||
{else}
|
||||
<option value="{$k}">{$v}</option>
|
||||
{/if}{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">创建时间</label>
|
||||
<div class="layui-input-inline">
|
||||
<input data-date-range name="create_at" value="{$get.create_at|default=''}" placeholder="请选择创建时间" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<button class="layui-btn layui-btn-primary"><i class="layui-icon"></i> 搜 索</button>
|
||||
</div>
|
||||
</form>
|
@ -1,179 +0,0 @@
|
||||
{extend name="main"}
|
||||
|
||||
{block name="button"}
|
||||
<!--{if isset($super) and $super}-->
|
||||
<a class="layui-btn layui-btn-sm layui-btn-primary" data-load="{:url('admin/api.system/config')}">清理无效配置</a>
|
||||
<!--{/if}-->
|
||||
|
||||
<!--{if auth('system')}-->
|
||||
<a class="layui-btn layui-btn-sm layui-btn-primary" data-modal="{:url('system')}">修改系统参数</a>
|
||||
<!--{/if}-->
|
||||
{/block}
|
||||
|
||||
{block name="content"}
|
||||
<!--{notempty name='super'}-->
|
||||
<div class="layui-card padding-20 shadow">
|
||||
<div class="layui-card-header notselect">
|
||||
<b>运行模式</b><span class="color-desc font-s12 padding-left-5">Run Mode</span>
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-btn-group shadow-mini nowrap">
|
||||
<!--{if $app->isDebug()}-->
|
||||
<a class="layui-btn layui-btn-sm layui-btn-active">以开发模式运行</a>
|
||||
<a class="layui-btn layui-btn-sm layui-btn-primary" data-confirm="确定要切换到生产模式运行吗?" data-load="{:url('admin/api.system/debug')}?state=1">以生产模式运行</a>
|
||||
<!--{else}-->
|
||||
<a class="layui-btn layui-btn-sm layui-btn-primary" data-confirm="确定要切换到开发模式运行吗?" data-load="{:url('admin/api.system/debug')}?state=0">以开发模式运行</a>
|
||||
<a class="layui-btn layui-btn-sm layui-btn-active">以生产模式运行</a>
|
||||
<!--{/if}-->
|
||||
</div>
|
||||
<div class="margin-top-20">
|
||||
<p><b>开发模式</b>:开发人员或在功能调试时使用,系统异常时会显示详细的错误信息,同时还会记录操作日志及数据库 SQL 语句信息。</p>
|
||||
<p><b>生产模式</b>:项目正式部署上线后使用,系统异常时统一显示 “{:config('app.error_message')}”,只记录重要的异常日志信息,强烈推荐上线后使用此模式。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card padding-20 shadow">
|
||||
<div class="layui-card-header notselect">
|
||||
<b>富编辑器</b><span class="color-desc font-s12 padding-left-5">Rich Text Editor</span>
|
||||
</div>
|
||||
<div class="layui-card-body layui-clear">
|
||||
<div class="layui-btn-group shadow-mini nowrap">
|
||||
{if !in_array(sysconf('base.editor'),['ckeditor4','ckeditor5','auto'])}{php}sysconf('base.editor','ckeditor4');{/php}{/if}
|
||||
{foreach ['ckeditor4'=>'CKEditor4','ckeditor5'=>'CKEditor5','auto'=>'自适应模式'] as $k => $v}{if sysconf('base.editor') eq $k}
|
||||
{if auth('storage')}<a data-title="配置{$v}" class="layui-btn layui-btn-sm layui-btn-active">{$v}</a>{else}<a class="layui-btn layui-btn-sm layui-btn-active">{$v}</a>{/if}
|
||||
{else}
|
||||
{if auth('storage')}<a data-title="配置{$v}" data-action="{:url('admin/api.system/editor')}" data-value="editor#{$k}" class="layui-btn layui-btn-sm layui-btn-primary">{$v}</a>{else}<a class="layui-btn layui-btn-sm layui-btn-primary">{$v}</a>{/if}
|
||||
{/if}{/foreach}
|
||||
</div>
|
||||
<div class="margin-top-20 nowrap full-width pull-left">
|
||||
<p><b>CKEditor4</b>:旧版本编辑器,对浏览器兼容较好,但内容编辑体验稍有不足。</p>
|
||||
<p><b>CKEditor5</b>:新版本编辑器,只支持新特性浏览器,对内容编辑体验较好,推荐使用。</p>
|
||||
<p><b>自适应模式</b>:优先使用新版本编辑器,若浏览器不支持新版本时自动降级为旧版本编辑器。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--{/notempty}-->
|
||||
|
||||
<div class="layui-card padding-20 shadow">
|
||||
<div class="layui-card-header notselect">
|
||||
<b>存储引擎</b><span class="color-desc font-s12 padding-left-5">Storage Engine</span>
|
||||
</div>
|
||||
<!-- 初始化存储配置 -->
|
||||
{if !sysconf('storage.type')}{php}sysconf('storage.type','local');{/php}{/if}
|
||||
{if !sysconf('storage.link_type')}{php}sysconf('storage.link_type','none');{/php}{/if}
|
||||
{if !sysconf('storage.name_type')}{php}sysconf('storage.name_type','xmd5');{/php}{/if}
|
||||
{if !sysconf('storage.allow_exts')}{php}sysconf('storage.allow_exts','doc,gif,ico,jpg,mp3,mp4,p12,pem,png,rar,xls,xlsx');{/php}{/if}
|
||||
{if !sysconf('storage.local_http_protocol')}{php}sysconf('storage.local_http_protocol','http');{/php}{/if}
|
||||
<div class="layui-card-body layui-clear">
|
||||
<div class="layui-btn-group shadow-mini nowrap">
|
||||
{foreach ['local'=>'本地服务器存储','qiniu'=>'七牛云对象存储','upyun'=>'又拍云USS存储','alioss'=>'阿里云OSS存储','txcos'=>'腾讯云COS存储'] as $k => $v}{if sysconf('storage.type') eq $k}
|
||||
{if auth('storage')}<a data-title="配置{$v}" data-modal="{:url('storage')}?type={$k}" class="layui-btn layui-btn-sm layui-btn-active">{$v}</a>{else}<a class="layui-btn layui-btn-sm layui-btn-active">{$v}</a>{/if}
|
||||
{else}
|
||||
{if auth('storage')}<a data-title="配置{$v}" data-modal="{:url('storage')}?type={$k}" class="layui-btn layui-btn-sm layui-btn-primary">{$v}</a>{else}<a class="layui-btn layui-btn-sm layui-btn-primary">{$v}</a>{/if}
|
||||
{/if}{/foreach}
|
||||
</div>
|
||||
<div class="margin-top-20 nowrap full-width pull-left">
|
||||
<p><b>本地服务器存储</b>:文件直接上传到本地服务器的 `static/upload` 目录,不支持大文件上传,占用服务器磁盘空间,访问时消耗服务器带宽流量。</p>
|
||||
<p><b>七牛云对象存储</b>:文件直接上传到七牛云存储空间,支持大文件上传,不占用服务器空间及服务器带宽流量,支持 CDN 加速访问,访问量大时推荐使用。</p>
|
||||
<p><b>又拍云USS存储</b>:文件直接上传到又拍云 USS 存储空间,支持大文件上传,不占用服务器空间及服务器带宽流量,支持 CDN 加速访问,访问量大时推荐使用。</p>
|
||||
<p><b>阿里云OSS存储</b>:文件直接上传到阿里云 OSS 存储空间,支持大文件上传,不占用服务器空间及服务器带宽流量,支持 CDN 加速访问,访问量大时推荐使用。</p>
|
||||
<p><b>腾讯云COS存储</b>:文件直接上传到腾讯云 COS 存储空间,支持大文件上传,不占用服务器空间及服务器带宽流量,支持 CDN 加速访问,访问量大时推荐使用。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card padding-20 shadow">
|
||||
<div class="layui-card-header notselect">
|
||||
<b>系统参数</b><span class="color-desc font-s12 padding-left-5">System Parameter</span>
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-form-item">
|
||||
<div class="help-label"><b>网站名称</b>Website</div>
|
||||
<label class="relative block">
|
||||
<input readonly value="{:sysconf('site_name')}" class="layui-input layui-bg-gray">
|
||||
<a data-copy="{:sysconf('site_name')}" class="layui-icon layui-icon-release input-right-icon"></a>
|
||||
</label>
|
||||
<div class="help-block">网站名称及网站图标,将显示在浏览器的标签上。</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="help-label"><b>管理程序名称</b>Name</div>
|
||||
<label class="relative block">
|
||||
<input readonly value="{:sysconf('app_name')}" class="layui-input layui-bg-gray">
|
||||
<a data-copy="{:sysconf('app_name')}" class="layui-icon layui-icon-release input-right-icon"></a>
|
||||
</label>
|
||||
<div class="help-block">管理程序名称,将显示在后台左上角标题。</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="help-label"><b>管理程序版本</b>Version</div>
|
||||
<label class="relative block">
|
||||
<input readonly value="{:sysconf('app_version')}" class="layui-input layui-bg-gray">
|
||||
<a data-copy="{:sysconf('app_version')}" class="layui-icon layui-icon-release input-right-icon"></a>
|
||||
</label>
|
||||
<div class="help-block">管理程序版本,将显示在后台左上角标题。</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="help-label"><b>公网备案号</b>Baian</div>
|
||||
<label class="relative block">
|
||||
<input readonly value="{:sysconf('beian')?:'-'}" class="layui-input layui-bg-gray">
|
||||
<a data-copy="{:sysconf('beian')}" class="layui-icon layui-icon-release input-right-icon"></a>
|
||||
</label>
|
||||
<p class="help-block">公网备案号,可以在 <a target="_blank" href="https://beian.miit.gov.cn">备案管理中心</a> 查询获取,将在登录页面下面显示。</p>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="help-label"><b>网站备案号</b>Miitbeian</div>
|
||||
<label class="relative block">
|
||||
<input readonly value="{:sysconf('miitbeian')?:'-'}" class="layui-input layui-bg-gray">
|
||||
<a data-copy="{:sysconf('miitbeian')}" class="layui-icon layui-icon-release input-right-icon"></a>
|
||||
</label>
|
||||
<div class="help-block">网站备案号,可以在 <a target="_blank" href="https://beian.miit.gov.cn">备案管理中心</a> 查询获取,将显示在登录页面下面。</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="help-label"><b>网站版权信息</b>Copyright</div>
|
||||
<label class="relative block">
|
||||
<input readonly value="{:sysconf('site_copy')}" class="layui-input layui-bg-gray">
|
||||
<a data-copy="{:sysconf('site_copy')}" class="layui-icon layui-icon-release input-right-icon"></a>
|
||||
</label>
|
||||
<div class="help-block">网站版权信息,在后台登录页面显示版本信息并链接到备案到信息备案管理系统。</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--{if $app->isDebug()}-->
|
||||
<div class="layui-card padding-20 shadow">
|
||||
<div class="layui-card-header notselect">
|
||||
<b>系统信息</b><span class="color-desc font-s12 padding-left-5">System Information</span>
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<table class="layui-table" lay-even>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th class="nowrap text-center">核心框架</th>
|
||||
<td><a target="_blank" href="https://www.thinkphp.cn">ThinkPHP Version {$app->version()}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="nowrap text-center">管理程序</th>
|
||||
<td><a target="_blank" href="https://thinkadmin.top">ThinkAdmin Version {$version|default='6.0.0'}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="nowrap text-center">服务器信息</th>
|
||||
<td>{:php_uname()}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="nowrap text-center">服务器软件</th>
|
||||
<td>{$request->server('SERVER_SOFTWARE',php_sapi_name())}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="nowrap text-center">PHP 版本</th>
|
||||
<td>PHP Version {$Think.const.PHP_VERSION}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="nowrap text-center">MySQL 版本</th>
|
||||
<td>MySQL Version {$app->db->query('SELECT VERSION()')[0]['VERSION()']}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<!--{/if}-->
|
||||
{/block}
|
@ -1,45 +0,0 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label label-required">
|
||||
<b class="color-green">命名方式</b><br><span class="nowrap color-desc">NameType</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
{foreach ['xmd5'=>'文件哈希值 ( 支持秒传 )','date'=>'日期+随机 ( 普通上传 )'] as $k=>$v}
|
||||
<label class="think-radio notselect">
|
||||
{if sysconf('storage.name_type') eq $k}
|
||||
<input checked type="radio" name="storage.name_type" value="{$k}" lay-ignore> {$v}
|
||||
{else}
|
||||
<input type="radio" name="storage.name_type" value="{$k}" lay-ignore> {$v}
|
||||
{/if}
|
||||
</label>
|
||||
{/foreach}
|
||||
<p class="help-block">类型为“文件哈希”时可以实现文件秒传功能,同一个文件只需上传一次节省存储空间,推荐使用。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label label-required">
|
||||
<b class="color-green">链接类型</b><br><span class="nowrap color-desc">LinkType</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
{foreach ['none'=>'简洁链接','full'=>'完整链接','none+compress'=>'简洁并压缩图片','full+compress'=>'完整并压缩图片'] as $k=>$v}
|
||||
<label class="think-radio notselect">
|
||||
{if sysconf('storage.link_type') eq $k}
|
||||
<input checked type="radio" name="storage.link_type" value="{$k}" lay-ignore> {$v}
|
||||
{else}
|
||||
<input type="radio" name="storage.link_type" value="{$k}" lay-ignore> {$v}
|
||||
{/if}
|
||||
</label>
|
||||
{/foreach}
|
||||
<p class="help-block">类型为“简洁链接”时链接将只返回 hash 地址,而“完整链接”将携带参数保留文件名,图片压缩功能云平台会单独收费。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.allow_exts">
|
||||
<b class="color-green">允许类型</b><br><span class="nowrap color-desc">AllowExts</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.allow_exts" type="text" name="storage.allow_exts" required value="{:sysconf('storage.allow_exts')}" placeholder="请输入系统文件上传后缀" class="layui-input">
|
||||
<p class="help-block">设置系统允许上传文件的后缀,多个以英文逗号隔开如:png,jpg,rar,doc,未设置允许上传的后缀</p>
|
||||
</div>
|
||||
</div>
|
@ -1,96 +0,0 @@
|
||||
<form action="{:sysuri()}" method="post" data-auto="true" class="layui-form layui-card">
|
||||
<div class="layui-card-body padding-top-20">
|
||||
|
||||
<div class="color-text layui-code text-center layui-bg-gray" style="border-left-width:1px;margin:0 0 15px 40px">
|
||||
<p class="margin-bottom-5 font-w7">文件将上传到 <a target="_blank" href="https://www.aliyun.com/minisite/goods?taskCode=shareNew2205&recordId=3646641&userCode=ztlqlu4v">阿里云</a> OSS 存储,需要配置 OSS 公开访问及跨域策略</p>
|
||||
<p>配置跨域访问 CORS 规则,设置:来源 Origin 为 *,允许 Methods 为 POST,允许 Headers 为 *</p>
|
||||
</div>
|
||||
|
||||
{include file='config/storage-0'}
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label label-required">
|
||||
<b class="color-green">访问协议</b><br><span class="nowrap color-desc">Protocol</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
{if !sysconf('storage.alioss_http_protocol')}{php}sysconf('storage.alioss_http_protocol','http');{/php}{/if}
|
||||
{foreach ['http'=>'HTTP','https'=>'HTTPS','auto'=>"AUTO"] as $protocol=>$remark}
|
||||
<label class="think-radio">
|
||||
{if sysconf('storage.alioss_http_protocol') eq $protocol}
|
||||
<input checked type="radio" name="storage.alioss_http_protocol" value="{$protocol}" lay-ignore> {$remark}
|
||||
{else}
|
||||
<input type="radio" name="storage.alioss_http_protocol" value="{$protocol}" lay-ignore> {$remark}
|
||||
{/if}
|
||||
</label>
|
||||
{/foreach}
|
||||
<p class="help-block">阿里云OSS存储访问协议,其中 HTTPS 需要配置证书才能使用(AUTO 为相对协议)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">
|
||||
<b class="color-green">存储区域</b><br><span class="nowrap color-desc label-required">Region</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<select class="layui-select" name="storage.alioss_point" lay-search>
|
||||
{foreach $points as $point => $title}
|
||||
{if sysconf('storage.alioss_point') eq $point}
|
||||
<option selected value="{$point}">{$title}( {$point} )</option>
|
||||
{else}
|
||||
<option value="{$point}">{$title}( {$point} )</option>
|
||||
{/if}{/foreach}
|
||||
</select>
|
||||
<p class="help-block">阿里云OSS存储空间所在区域,需要严格对应储存所在区域才能上传文件</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.alioss_bucket">
|
||||
<b class="color-green">空间名称</b><br><span class="nowrap color-desc">Bucket</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.alioss_bucket" type="text" name="storage.alioss_bucket" required value="{:sysconf('storage.alioss_bucket')}" placeholder="请输入阿里云OSS存储 Bucket (空间名称)" class="layui-input">
|
||||
<p class="help-block">填写阿里云OSS存储空间名称,如:think-admin-oss(需要是全区唯一的值,不存在时会自动创建)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.alioss_http_domain">
|
||||
<b class="color-green">访问域名</b><br><span class="nowrap color-desc">Domain</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.alioss_http_domain" type="text" name="storage.alioss_http_domain" required value="{:sysconf('storage.alioss_http_domain')}" placeholder="请输入阿里云OSS存储 Domain (访问域名)" class="layui-input">
|
||||
<p class="help-block">填写阿里云OSS存储外部访问域名,如:static.alioss.thinkadmin.top</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.alioss_access_key">
|
||||
<b class="color-green">访问密钥</b><br><span class="nowrap color-desc">AccessKey</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.alioss_access_key" type="text" name="storage.alioss_access_key" required value="{:sysconf('storage.alioss_access_key')}" placeholder="请输入阿里云OSS存储 AccessKey (访问密钥)" class="layui-input">
|
||||
<p class="help-block">可以在 [ 阿里云 > 个人中心 ] 设置并获取到访问密钥</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.alioss_secret_key">
|
||||
<b class="color-green">安全密钥</b><br><span class="nowrap color-desc">SecretKey</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.alioss_secret_key" type="text" name="storage.alioss_secret_key" required value="{:sysconf('storage.alioss_secret_key')}" maxlength="43" placeholder="请输入阿里云OSS存储 SecretKey (安全密钥)" class="layui-input">
|
||||
<p class="help-block">可以在 [ 阿里云 > 个人中心 ] 设置并获取到安全密钥</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed margin-left-40"></div>
|
||||
<input type="hidden" name="storage.type" value="alioss">
|
||||
|
||||
<div class="layui-form-item text-center padding-left-40">
|
||||
<button class="layui-btn" type="submit">保存配置</button>
|
||||
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消修改吗?" data-close>取消修改</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
@ -1,49 +0,0 @@
|
||||
<form action="{:sysuri()}" method="post" data-auto="true" class="layui-form layui-card">
|
||||
<div class="layui-card-body padding-top-20">
|
||||
|
||||
<div class="color-text layui-code text-center layui-bg-gray" style="border-left-width:1px;margin:0 0 15px 40px">
|
||||
<p class="margin-bottom-5 font-w7">文件将存储在本地服务器,默认保存在 public/upload 目录,文件以 HASH 命名。</p>
|
||||
<p>文件存储的目录需要有读写权限,有足够的存储空间。<span class="color-red">特别注意,本地存储暂不支持图片压缩!</span></p>
|
||||
</div>
|
||||
|
||||
{include file='config/storage-0'}
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label label-required">
|
||||
<b class="color-green">访问协议</b><br><span class="nowrap color-desc">Protocol</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
{if !sysconf('storage.local_http_protocol')}{php}sysconf('storage.local_http_protocol','http');{/php}{/if}
|
||||
{foreach ['follow'=>'FOLLOW','http'=>'HTTP','https'=>'HTTPS','path'=>'PATH','auto'=>'AUTO'] as $protocol=>$remark}
|
||||
<label class="think-radio">
|
||||
{if sysconf('storage.local_http_protocol') eq $protocol}
|
||||
<input checked type="radio" name="storage.local_http_protocol" value="{$protocol}" lay-ignore> {$remark}
|
||||
{else}
|
||||
<input type="radio" name="storage.local_http_protocol" value="{$protocol}" lay-ignore> {$remark}
|
||||
{/if}
|
||||
</label>
|
||||
{/foreach}
|
||||
<p class="help-block">本地存储访问协议,其中 HTTPS 需要配置证书才能使用( FOLLOW 跟随系统,PATH 文件路径,AUTO 相对协议 )</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.local_http_domain">
|
||||
<b class="color-green">访问域名</b><br><span class="nowrap color-desc">Domain</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.local_http_domain" type="text" name="storage.local_http_domain" value="{:sysconf('storage.local_http_domain')}" placeholder="请输入上传后的访问域名 (非必填项)" class="layui-input">
|
||||
<p class="help-block">填写上传后的访问域名(不指定时根据当前访问地址自动计算),如:static.thinkadmin.top</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed margin-left-40"></div>
|
||||
<input type="hidden" name="storage.type" value="local">
|
||||
|
||||
<div class="layui-form-item text-center padding-left-40">
|
||||
<button class="layui-btn" type="submit">保存配置</button>
|
||||
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消修改吗?" data-close>取消修改</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
@ -1,95 +0,0 @@
|
||||
<form action="{:sysuri()}" method="post" data-auto="true" class="layui-form layui-card">
|
||||
<div class="layui-card-body padding-top-20">
|
||||
|
||||
<div class="color-text layui-code text-center layui-bg-gray" style="border-left-width:1px;margin:0 0 15px 40px">
|
||||
<p class="margin-bottom-5 font-w7">文件将上传到 <a target="_blank" href="https://s.qiniu.com/rYr26v">七牛云</a> 存储,对象存储需要配置为公开访问的 Bucket 空间</p>
|
||||
完成实名认证后可获得 10G 免费存储空间哦!<a target="_blank" href="https://s.qiniu.com/rYr26v">我要免费申请</a>
|
||||
</div>
|
||||
|
||||
{include file='config/storage-0'}
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label label-required">
|
||||
<b class="color-green">访问协议</b><br><span class="nowrap color-desc">Protocol</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
{if !sysconf('storage.qiniu_http_protocol')}{php}sysconf('storage.qiniu_http_protocol','http');{/php}{/if}
|
||||
{foreach ['http'=>'HTTP','https'=>'HTTPS','auto'=>"AUTO"] as $protocol=>$remark}
|
||||
<label class="think-radio">
|
||||
{if sysconf('storage.qiniu_http_protocol') eq $protocol}
|
||||
<input checked type="radio" name="storage.qiniu_http_protocol" value="{$protocol}" lay-ignore> {$remark}
|
||||
{else}
|
||||
<input type="radio" name="storage.qiniu_http_protocol" value="{$protocol}" lay-ignore> {$remark}
|
||||
{/if}
|
||||
</label>
|
||||
{/foreach}
|
||||
<p class="help-block">七牛云存储访问协议,其中 HTTPS 需要配置证书才能使用( AUTO 为相对协议 )</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">
|
||||
<b class="color-green">存储区域</b><br><span class="nowrap color-desc label-required">Region</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<select class="layui-select" name="storage.qiniu_region" lay-search>
|
||||
{foreach $points as $point => $title}
|
||||
{if sysconf('storage.qiniu_region') eq $point}
|
||||
<option selected value="{$point}">{$title}( {$point} )</option>
|
||||
{else}
|
||||
<option value="{$point}">{$title}( {$point} )</option>
|
||||
{/if}{/foreach}
|
||||
</select>
|
||||
<p class="help-block">七牛云存储空间所在区域,需要严格对应储存所在区域才能上传文件</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.qiniu_bucket">
|
||||
<b class="color-green">空间名称</b><br><span class="nowrap color-desc">Bucket</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.qiniu_bucket" type="text" name="storage.qiniu_bucket" required value="{:sysconf('storage.qiniu_bucket')}" placeholder="请输入七牛云存储 Bucket (空间名称)" class="layui-input">
|
||||
<p class="help-block">填写七牛云存储空间名称,如:static</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.qiniu_http_domain">
|
||||
<b class="color-green">访问域名</b><br><span class="nowrap color-desc">Domain</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.qiniu_http_domain" type="text" name="storage.qiniu_http_domain" required value="{:sysconf('storage.qiniu_http_domain')}" placeholder="请输入七牛云存储 Domain (访问域名)" class="layui-input">
|
||||
<p class="help-block">填写七牛云存储访问域名,如:static.qiniu.thinkadmin.top</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.qiniu_access_key">
|
||||
<b class="color-green">访问密钥</b><br><span class="nowrap color-desc">AccessKey</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.qiniu_access_key" type="text" name="storage.qiniu_access_key" required value="{:sysconf('storage.qiniu_access_key')}" placeholder="请输入七牛云授权 AccessKey (访问密钥)" class="layui-input">
|
||||
<p class="help-block">可以在 [ 七牛云 > 个人中心 ] 设置并获取到访问密钥</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.qiniu_secret_key">
|
||||
<b class="color-green">安全密钥</b><br><span class="nowrap color-desc">SecretKey</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.qiniu_secret_key" type="text" name="storage.qiniu_secret_key" required value="{:sysconf('storage.qiniu_secret_key')}" maxlength="43" placeholder="请输入七牛云授权 SecretKey (安全密钥)" class="layui-input">
|
||||
<p class="help-block">可以在 [ 七牛云 > 个人中心 ] 设置并获取到安全密钥</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed margin-left-40"></div>
|
||||
<input type="hidden" name="storage.type" value="qiniu">
|
||||
|
||||
<div class="layui-form-item text-center padding-left-40">
|
||||
<button class="layui-btn" type="submit">保存配置</button>
|
||||
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消修改吗?" data-close>取消修改</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,96 +0,0 @@
|
||||
<form action="{:sysuri()}" method="post" data-auto="true" class="layui-form layui-card">
|
||||
<div class="layui-card-body padding-top-20">
|
||||
|
||||
<div class="color-text layui-code text-center layui-bg-gray" style="border-left-width:1px;margin:0 0 15px 40px">
|
||||
<p class="margin-bottom-5 font-w7">文件将上传到 <a target="_blank" href="https://curl.qcloud.com/4t0Mbw2K">腾讯云</a> COS 存储,需要配置 COS 公有读私有写访问权限及跨域策略</p>
|
||||
<p>配置跨域访问 CORS 规则,设置来源 Origin 为 *,允许 Methods 为 POST,允许 Headers 为 *</p>
|
||||
</div>
|
||||
|
||||
{include file='config/storage-0'}
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label label-required">
|
||||
<b class="color-green">访问协议</b><br><span class="nowrap color-desc">Protocol</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
{if !sysconf('storage.txcos_http_protocol')}{php}sysconf('storage.txcos_http_protocol','http');{/php}{/if}
|
||||
{foreach ['http'=>'HTTP','https'=>'HTTPS','auto'=>"AUTO"] as $protocol=>$remark}
|
||||
<label class="think-radio">
|
||||
{if sysconf('storage.txcos_http_protocol') eq $protocol}
|
||||
<input checked type="radio" name="storage.txcos_http_protocol" value="{$protocol}" lay-ignore> {$remark}
|
||||
{else}
|
||||
<input type="radio" name="storage.txcos_http_protocol" value="{$protocol}" lay-ignore> {$remark}
|
||||
{/if}
|
||||
</label>
|
||||
{/foreach}
|
||||
<p class="help-block">腾讯云COS存储访问协议,其中 HTTPS 需要配置证书才能使用( AUTO 为相对协议 )</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">
|
||||
<b class="color-green">存储区域</b><br><span class="nowrap color-desc label-required">Region</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<select class="layui-select" name="storage.txcos_point" lay-search>
|
||||
{foreach $points as $point => $title}
|
||||
{if sysconf('storage.txcos_point') eq $point}
|
||||
<option selected value="{$point}">{$title}( {$point} )</option>
|
||||
{else}
|
||||
<option value="{$point}">{$title}( {$point} )</option>
|
||||
{/if}{/foreach}
|
||||
</select>
|
||||
<p class="help-block">腾讯云COS存储空间所在区域,需要严格对应储存所在区域才能上传文件</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.txcos_bucket">
|
||||
<b class="color-green">空间名称</b><br><span class="nowrap color-desc">Bucket</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.txcos_bucket" type="text" name="storage.txcos_bucket" required value="{:sysconf('storage.txcos_bucket')}" placeholder="请输入腾讯云COS存储 Bucket" class="layui-input">
|
||||
<p class="help-block">填写腾讯云COS存储空间名称,如:thinkadmin-1251143395</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.txcos_http_domain">
|
||||
<b class="color-green">访问域名</b><br><span class="nowrap color-desc">Domain</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.txcos_http_domain" type="text" name="storage.txcos_http_domain" required value="{:sysconf('storage.txcos_http_domain')}" placeholder="请输入腾讯云COS存储 Domain" class="layui-input">
|
||||
<p class="help-block">填写腾讯云COS存储外部访问域名,如:static.txcos.thinkadmin.top</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.txcos_access_key">
|
||||
<b class="color-green">访问密钥</b><br><span class="nowrap color-desc">AccessKey</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.txcos_access_key" type="text" name="storage.txcos_access_key" required value="{:sysconf('storage.txcos_access_key')}" placeholder="请输入腾讯云COS存储 AccessKey" class="layui-input">
|
||||
<p class="help-block">可以在 [ 腾讯云 > 个人中心 ] 设置并获取到访问密钥</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.txcos_secret_key">
|
||||
<b class="color-green">安全密钥</b><br><span class="nowrap color-desc">SecretKey</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.txcos_secret_key" type="text" name="storage.txcos_secret_key" required value="{:sysconf('storage.txcos_secret_key')}" maxlength="43" placeholder="请输入腾讯云COS存储 SecretKey" class="layui-input">
|
||||
<p class="help-block">可以在 [ 腾讯云 > 个人中心 ] 设置并获取到安全密钥</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed margin-left-40"></div>
|
||||
<input type="hidden" name="storage.type" value="txcos">
|
||||
|
||||
<div class="layui-form-item text-center padding-left-40">
|
||||
<button class="layui-btn" type="submit">保存配置</button>
|
||||
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消修改吗?" data-close>取消修改</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
@ -1,79 +0,0 @@
|
||||
<form action="{:sysuri()}" method="post" data-auto="true" class="layui-form layui-card">
|
||||
<div class="layui-card-body padding-top-20">
|
||||
|
||||
<div class="color-text layui-code text-center layui-bg-gray" style="border-left-width:1px;margin:0 0 15px 40px">
|
||||
<p class="margin-bottom-5 font-w7">文件将上传到 <a target="_blank" href="https://console.upyun.com/register/?invite=PN1cRmjRb">又拍云</a> USS 存储,需要配置 USS 公开访问及跨域策略</p>
|
||||
<p>配置跨域访问 CORS 规则,设置来源 Origin 为 *,允许 Methods 为 POST,允许 Headers 为 *</p>
|
||||
</div>
|
||||
|
||||
{include file='config/storage-0'}
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label label-required">
|
||||
<b class="color-green">访问协议</b><br><span class="nowrap color-desc">Protocol</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
{if !sysconf('storage.upyun_http_protocol')}{php}sysconf('storage.upyun_http_protocol','http');{/php}{/if}
|
||||
{foreach ['http'=>'HTTP','https'=>'HTTPS','auto'=>"AUTO"] as $protocol=>$remark}
|
||||
<label class="think-radio">
|
||||
{if sysconf('storage.upyun_http_protocol') eq $protocol}
|
||||
<input checked type="radio" name="storage.upyun_http_protocol" value="{$protocol}" lay-ignore> {$remark}
|
||||
{else}
|
||||
<input type="radio" name="storage.upyun_http_protocol" value="{$protocol}" lay-ignore> {$remark}
|
||||
{/if}
|
||||
</label>
|
||||
{/foreach}
|
||||
<p class="help-block">又拍云存储访问协议,其中 HTTPS 需要配置证书才能使用(AUTO 为相对协议)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.upyun_bucket">
|
||||
<b class="color-green">空间名称</b><br><span class="nowrap color-desc">Bucket</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.upyun_bucket" name="storage.upyun_bucket" required value="{:sysconf('storage.upyun_bucket')}" placeholder="请输入又拍云存储 Bucket (空间名称)" class="layui-input">
|
||||
<p class="help-block">填写又拍云存储空间名称,如:think-admin-uss(需要是全区唯一的值,不存在时会自动创建)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.upyun_http_domain">
|
||||
<b class="color-green">访问域名</b><br><span class="nowrap color-desc">Domain</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.upyun_http_domain" name="storage.upyun_http_domain" required value="{:sysconf('storage.upyun_http_domain')}" placeholder="请输入又拍云存储 Domain (访问域名)" class="layui-input">
|
||||
<p class="help-block">填写又拍云存储外部访问域名,如:static.uss.thinkadmin.top</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.upyun_access_key">
|
||||
<b class="color-green">操作账号</b><br><span class="nowrap color-desc">Username</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.upyun_access_key" name="storage.upyun_access_key" required value="{:sysconf('storage.upyun_access_key')}" maxlength="100" placeholder="请输入又拍云存储 Username (操作员账号)" class="layui-input">
|
||||
<p class="help-block">可以在 [ 账户管理 > 操作员 ] 设置操作员账号并将空间给予授权。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" for="storage.upyun_secret_key">
|
||||
<b class="color-green">操作密码</b><br><span class="nowrap color-desc">Password</span>
|
||||
</label>
|
||||
<div class="layui-input-block">
|
||||
<input id="storage.upyun_secret_key" name="storage.upyun_secret_key" required value="{:sysconf('storage.upyun_secret_key')}" maxlength="100" placeholder="请输入又拍云存储 Password (操作员密码)" class="layui-input">
|
||||
<p class="help-block">可以在 [ 账户管理 > 操作员 ] 设置操作员密码并将空间给予授权</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed margin-left-40"></div>
|
||||
<input type="hidden" name="storage.type" value="upyun">
|
||||
|
||||
<div class="layui-form-item text-center padding-left-40">
|
||||
<button class="layui-btn" type="submit">保存配置</button>
|
||||
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消修改吗?" data-close>取消修改</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
@ -1,113 +0,0 @@
|
||||
<form action="{:sysuri()}" method="post" data-auto="true" class="layui-form layui-card">
|
||||
<div class="layui-card-body padding-left-40">
|
||||
|
||||
<div class="layui-row layui-col-space15 margin-bottom-5">
|
||||
<div class="layui-col-xs4 padding-bottom-0">
|
||||
<label class="relative block">
|
||||
<span class="help-label"><b>登录表单标题</b>Login Name</span>
|
||||
<input name="login_name" required placeholder="请输入登录页面的表单标题" value="{:sysconf('login_name')?:'系统管理'}" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
<div class="layui-col-xs4 padding-bottom-0">
|
||||
<div class="help-label label-required-prev"><b>后台登录入口</b>Login Entry</div>
|
||||
<label class="layui-input relative block nowrap label-required-null">
|
||||
<span>{:sysuri('@',[],false,true)}</span>
|
||||
<input autofocus required pattern="[a-zA-Z_][a-zA-Z0-9_]*" placeholder="请输入后台登录入口" class="layui-input inline-block padding-0 border-0" style="width:100px;background:none" value="{:substr(sysuri('admin/index/index',[],false), strlen(sysuri('@')))}" name="xpath">
|
||||
</label>
|
||||
</div>
|
||||
<div class="layui-col-xs4 padding-bottom-0">
|
||||
<div class="help-label label-required-prev"><b>后台默认配色</b>Theme Style</div>
|
||||
<select class="layui-select" name="site_theme" lay-filter="SiteTheme">
|
||||
{foreach $themes as $k=>$v}{if sysconf('base.site_theme') eq $k}
|
||||
<option selected value="{$k}">{$v}</option>
|
||||
{else}
|
||||
<option value="{$k}">{$v}</option>
|
||||
{/if}{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-col-xs12 padding-top-0 padding-bottom-0">
|
||||
<span class="help-block">后台登录入口是由英文字母开头,且不能有相同名称的模块,设置之后原地址不能继续访问,请谨慎配置 ~</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item margin-bottom-5">
|
||||
<div class="help-label"><b>登录背景图片</b>Background Image</div>
|
||||
<div class="layui-textarea help-images">
|
||||
<input type="hidden" value="{:sysconf('login_image')}" name="login_image">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item margin-bottom-5">
|
||||
<div class="help-label label-required-prev"><b>浏览器小图标</b>Browser Icon</div>
|
||||
<label class="relative block label-required-null">
|
||||
<input class="layui-input" required pattern="^(http|/)" placeholder="请上传浏览器图标" value="{:sysconf('site_icon')}" name="site_icon">
|
||||
<a class="input-right-icon layui-icon layui-icon-upload-drag" data-file="btn" data-type="png,jpg,jpeg" data-field="site_icon"></a>
|
||||
</label>
|
||||
<div class="help-block sub-span-blue">
|
||||
建议上传 <span>128x128</span> 或 <span>256x256</span> 的 <span>JPG</span>,<span>PNG</span>,<span>JPEG</span> 图片,保存后会自动生成 <span>48x48</span> 的 <span>ICO</span> 文件 ~
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-row layui-col-space15 margin-bottom-5">
|
||||
<div class="layui-col-xs4 padding-bottom-0">
|
||||
<label class="layui-form-item margin-bottom-5 relative block">
|
||||
<span class="help-label"><b>网站名称</b>Site Name</span>
|
||||
<input name="site_name" required placeholder="请输入网站名称" value="{:sysconf('site_name')}" class="layui-input">
|
||||
<span class="help-block">网站名称将显示在浏览器的标签上 ~</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="layui-col-xs4 padding-bottom-0">
|
||||
<label class="layui-form-item margin-bottom-5 relative block">
|
||||
<span class="help-label"><b>后台程序名称</b>App Name</span>
|
||||
<input name="app_name" required placeholder="请输入程序名称" value="{:sysconf('app_name')}" class="layui-input">
|
||||
<span class="help-block">管理程序名称显示在后台左上标题处 ~</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="layui-col-xs4 padding-bottom-0">
|
||||
<label class="layui-form-item margin-bottom-5 relative block">
|
||||
<span class="help-label"><b>后台程序版本</b>App Version</span>
|
||||
<input name="app_version" placeholder="请输入程序版本" value="{:sysconf('app_version')}" class="layui-input">
|
||||
<span class="help-block">管理程序版本显示在后台左上标题处 ~</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="layui-col-xs4 padding-top-0 padding-bottom-0">
|
||||
<label class="relative block">
|
||||
<span class="help-label"><b>公网安备号</b>Baian</span>
|
||||
<input name="beian" placeholder="请输入公网安备号" value="{:sysconf('beian')}" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
<div class="layui-col-xs4 padding-top-0 padding-bottom-0">
|
||||
<label class="relative block">
|
||||
<span class="help-label"><b>网站备案号</b>Miitbeian</span>
|
||||
<input name="miitbeian" placeholder="请输入网站备案号" value="{:sysconf('miitbeian')}" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
<div class="layui-col-xs4 padding-top-0 padding-bottom-0">
|
||||
<label class="relative block">
|
||||
<span class="help-label"><b>网站版权信息</b>Copyright</span>
|
||||
<input name="site_copy" required placeholder="请输入版权信息" value="{:sysconf('site_copy')}" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
<div class="layui-col-xs12 help-block padding-top-0">
|
||||
网站备案号和公安备案号可以在<a target="_blank" href="https://beian.miit.gov.cn">备案管理中心</a>查询并获取,网站上线时必需配置备案号,备案号会链接到信息备案管理系统 ~
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="layui-form-item text-center">
|
||||
<button class="layui-btn" type="submit">保存配置</button>
|
||||
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消修改吗?" data-close>取消修改</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
$('[name=login_image]').uploadMultipleImage();
|
||||
layui.form.on('select(SiteTheme)', function (data) {
|
||||
var alls = '', prox = 'layui-layout-theme-', curt = prox + data.value;
|
||||
$(data.elem.options).map(function () {
|
||||
if (this.value !== data.value) alls += ' ' + prox + this.value;
|
||||
});
|
||||
$('.layui-layout-body').removeClass(alls).addClass(curt)
|
||||
});
|
||||
</script>
|
@ -1,568 +0,0 @@
|
||||
<?php
|
||||
|
||||
if (!function_exists('parse_padding')) {
|
||||
function parse_padding($source)
|
||||
{
|
||||
$length = strlen(strval(count($source['source']) + $source['first']));
|
||||
return 40 + ($length - 1) * 8;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('parse_class')) {
|
||||
function parse_class($name): string
|
||||
{
|
||||
$names = explode('\\', $name);
|
||||
return '<abbr title="' . $name . '">' . end($names) . '</abbr>';
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('parse_file')) {
|
||||
function parse_file($file, $line): string
|
||||
{
|
||||
return '<a class="toggle" title="' . "{$file} line {$line}" . '">' . basename($file) . " line {$line}" . '</a>';
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('parse_args')) {
|
||||
function parse_args($args): string
|
||||
{
|
||||
$result = [];
|
||||
foreach ($args as $key => $item) {
|
||||
switch (true) {
|
||||
case is_object($item):
|
||||
$value = sprintf('<em>object</em>(%s)', parse_class(get_class($item)));
|
||||
break;
|
||||
case is_array($item):
|
||||
if (count($item) > 3) {
|
||||
$value = sprintf('[%s, ...]', parse_args(array_slice($item, 0, 3)));
|
||||
} else {
|
||||
$value = sprintf('[%s]', parse_args($item));
|
||||
}
|
||||
break;
|
||||
case is_string($item):
|
||||
if (strlen($item) > 20) {
|
||||
$value = sprintf(
|
||||
'\'<a class="toggle" title="%s">%s...</a>\'',
|
||||
htmlentities($item),
|
||||
htmlentities(substr($item, 0, 20))
|
||||
);
|
||||
} else {
|
||||
$value = sprintf("'%s'", htmlentities($item));
|
||||
}
|
||||
break;
|
||||
case is_int($item):
|
||||
case is_float($item):
|
||||
$value = $item;
|
||||
break;
|
||||
case is_null($item):
|
||||
$value = '<em>null</em>';
|
||||
break;
|
||||
case is_bool($item):
|
||||
$value = '<em>' . ($item ? 'true' : 'false') . '</em>';
|
||||
break;
|
||||
case is_resource($item):
|
||||
$value = '<em>resource</em>';
|
||||
break;
|
||||
default:
|
||||
$value = htmlentities(str_replace("\n", '', var_export(strval($item), true)));
|
||||
break;
|
||||
}
|
||||
|
||||
$result[] = is_int($key) ? $value : "'{$key}' => {$value}";
|
||||
}
|
||||
|
||||
return implode(', ', $result);
|
||||
}
|
||||
}
|
||||
if (!function_exists('echo_value')) {
|
||||
function echo_value($val)
|
||||
{
|
||||
if (is_array($val) || is_object($val)) {
|
||||
echo htmlentities(json_encode($val, JSON_PRETTY_PRINT));
|
||||
} elseif (is_bool($val)) {
|
||||
echo $val ? 'true' : 'false';
|
||||
} elseif (is_scalar($val)) {
|
||||
echo htmlentities($val);
|
||||
} else {
|
||||
echo 'Resource';
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>系统发生错误</title>
|
||||
<meta name="robots" content="noindex,nofollow"/>
|
||||
<style>
|
||||
/* Base */
|
||||
body {
|
||||
color: #333;
|
||||
font: 16px Verdana, "Helvetica Neue", helvetica, Arial, 'Microsoft YaHei', sans-serif;
|
||||
margin: 0;
|
||||
padding: 0 20px 20px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 10px 0 0;
|
||||
font-size: 28px;
|
||||
font-weight: 500;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #4288ce;
|
||||
font-weight: 400;
|
||||
padding: 6px 0;
|
||||
margin: 6px 0 0;
|
||||
font-size: 18px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 12px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
abbr {
|
||||
cursor: help;
|
||||
text-decoration: underline;
|
||||
text-decoration-style: dotted;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #868686;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.line-error {
|
||||
background: #f8cbcb;
|
||||
}
|
||||
|
||||
.echo table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.echo pre {
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
font-size: 85%;
|
||||
line-height: 1.45;
|
||||
background-color: #f7f7f7;
|
||||
border: 0;
|
||||
border-radius: 3px;
|
||||
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
}
|
||||
|
||||
.echo pre > pre {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Exception Info */
|
||||
.exception {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.exception .message {
|
||||
padding: 12px;
|
||||
border: 1px solid #ddd;
|
||||
border-bottom: 0 none;
|
||||
line-height: 18px;
|
||||
font-size: 16px;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
font-family: Consolas, "Liberation Mono", Courier, Verdana, "微软雅黑", serif;
|
||||
}
|
||||
|
||||
.exception .code {
|
||||
float: left;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
margin-right: 12px;
|
||||
padding: 16px;
|
||||
border-radius: 4px;
|
||||
background: #999;
|
||||
}
|
||||
|
||||
.exception .source-code {
|
||||
padding: 6px;
|
||||
border: 1px solid #ddd;
|
||||
|
||||
background: #f9f9f9;
|
||||
overflow-x: auto;
|
||||
|
||||
}
|
||||
|
||||
.exception .source-code pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.exception .source-code pre ol {
|
||||
margin: 0;
|
||||
color: #4288ce;
|
||||
display: inline-block;
|
||||
min-width: 100%;
|
||||
box-sizing: border-box;
|
||||
font-size: 14px;
|
||||
font-family: "Century Gothic", Consolas, "Liberation Mono", Courier, Verdana, serif;
|
||||
padding-left: <?php echo (isset($source) && ! empty($source)) ? parse_padding($source): 40;?> px;
|
||||
}
|
||||
|
||||
.exception .source-code pre li {
|
||||
border-left: 1px solid #ddd;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.exception .source-code pre code {
|
||||
color: #333;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
border-left: 1px solid #fff;
|
||||
font-size: 14px;
|
||||
font-family: Consolas, "Liberation Mono", Courier, Verdana, "微软雅黑", serif;
|
||||
}
|
||||
|
||||
.exception .trace {
|
||||
padding: 6px;
|
||||
border: 1px solid #ddd;
|
||||
border-top: 0 none;
|
||||
line-height: 16px;
|
||||
font-size: 14px;
|
||||
font-family: Consolas, "Liberation Mono", Courier, Verdana, "微软雅黑", serif;
|
||||
}
|
||||
|
||||
.exception .trace h2:hover {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.exception .trace ol {
|
||||
margin: 12px;
|
||||
}
|
||||
|
||||
.exception .trace ol li {
|
||||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
.exception div:last-child {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
|
||||
/* Exception Variables */
|
||||
.exception-var table {
|
||||
width: 100%;
|
||||
margin: 12px 0;
|
||||
box-sizing: border-box;
|
||||
table-layout: fixed;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.exception-var table caption {
|
||||
text-align: left;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
.exception-var table caption small {
|
||||
font-weight: 300;
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.exception-var table tbody {
|
||||
font-size: 13px;
|
||||
font-family: Consolas, "Liberation Mono", Courier, "微软雅黑", serif;
|
||||
}
|
||||
|
||||
.exception-var table td {
|
||||
padding: 0 6px;
|
||||
vertical-align: top;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.exception-var table td:first-child {
|
||||
width: 28%;
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.exception-var table td pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Copyright Info */
|
||||
.copyright {
|
||||
margin-top: 24px;
|
||||
padding: 12px 0;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
/* SPAN elements with the classes below are added by prettyprint. */
|
||||
pre.prettyprint .pln {
|
||||
color: #000
|
||||
}
|
||||
|
||||
/* plain text */
|
||||
pre.prettyprint .str {
|
||||
color: #080
|
||||
}
|
||||
|
||||
/* string content */
|
||||
pre.prettyprint .kwd {
|
||||
color: #008
|
||||
}
|
||||
|
||||
/* a keyword */
|
||||
pre.prettyprint .com {
|
||||
color: #800
|
||||
}
|
||||
|
||||
/* a comment */
|
||||
pre.prettyprint .typ {
|
||||
color: #606
|
||||
}
|
||||
|
||||
/* a type name */
|
||||
pre.prettyprint .lit {
|
||||
color: #066
|
||||
}
|
||||
|
||||
/* a literal value */
|
||||
/* punctuation, lisp open bracket, lisp close bracket */
|
||||
pre.prettyprint .pun, pre.prettyprint .opn, pre.prettyprint .clo {
|
||||
color: #660
|
||||
}
|
||||
|
||||
pre.prettyprint .tag {
|
||||
color: #008
|
||||
}
|
||||
|
||||
/* a markup tag name */
|
||||
pre.prettyprint .atn {
|
||||
color: #606
|
||||
}
|
||||
|
||||
/* a markup attribute name */
|
||||
pre.prettyprint .atv {
|
||||
color: #080
|
||||
}
|
||||
|
||||
/* a markup attribute value */
|
||||
pre.prettyprint .dec, pre.prettyprint .var {
|
||||
color: #606
|
||||
}
|
||||
|
||||
/* a declaration; a variable name */
|
||||
pre.prettyprint .fun {
|
||||
color: red
|
||||
}
|
||||
|
||||
/* a function name */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php if (\think\facade\App::isDebug()) { ?>
|
||||
<?php foreach ($traces as $index => $trace) { ?>
|
||||
<div class="exception">
|
||||
<div class="message">
|
||||
<div class="info">
|
||||
<div>
|
||||
<h2><?php echo "#{$index} [{$trace['code']}]" . sprintf('%s in %s', parse_class($trace['name']), parse_file($trace['file'], $trace['line'])); ?></h2>
|
||||
</div>
|
||||
<div><h1><?php echo nl2br(htmlentities($trace['message'])); ?></h1></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php if (!empty($trace['source'])) { ?>
|
||||
<div class="source-code">
|
||||
<pre class="prettyprint lang-php">
|
||||
<ol start="<?php echo $trace['source']['first']; ?>"><!--<?php foreach ((array)$trace['source']['source'] as $key => $value) { ?>--><li class="line-<?php echo " {$index}-" . ($key + $trace['source']['first']) . ($trace['line'] === $key + $trace['source']['first'] ? ' line-error' : ''); ?>"><code><?php echo htmlentities($value); ?></code></li><!--<?php } ?>--></ol>
|
||||
</pre>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<div class="trace">
|
||||
<h2 data-expand="<?php echo 0 === $index ? '1' : '0'; ?>">Call Stack</h2>
|
||||
<ol>
|
||||
<li><?php echo sprintf('in %s', parse_file($trace['file'], $trace['line'])); ?></li>
|
||||
<?php foreach ((array)$trace['trace'] as $value) { ?>
|
||||
<li>
|
||||
<?php
|
||||
// Show Function
|
||||
if ($value['function']) {
|
||||
echo sprintf('at %s%s%s(%s)', isset($value['class']) ? parse_class($value['class']) : '', $value['type'] ?? '', $value['function'], isset($value['args']) ? parse_args($value['args']) : '');
|
||||
}
|
||||
|
||||
// Show line
|
||||
if (isset($value['file']) && isset($value['line'])) {
|
||||
echo sprintf(' in %s', parse_file($value['file'], $value['line']));
|
||||
}
|
||||
?>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<?php } else { ?>
|
||||
<div class="exception">
|
||||
<div class="info"><h1><?php echo htmlentities(isset($message) ? $message : ''); ?></h1></div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?php if (!empty($datas)) { ?>
|
||||
<div class="exception-var">
|
||||
<h2>Exception Datas</h2>
|
||||
<?php foreach ((array)$datas as $label => $value) { ?>
|
||||
<table>
|
||||
<?php if (empty($value)) { ?>
|
||||
<caption><?php echo $label; ?><small>empty</small></caption>
|
||||
<?php } else { ?>
|
||||
<caption><?php echo $label; ?></caption>
|
||||
<tbody>
|
||||
<?php foreach ((array)$value as $key => $val) { ?>
|
||||
<tr>
|
||||
<td><?php echo htmlentities($key); ?></td>
|
||||
<td><?php echo_value($val); ?></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
<?php } ?>
|
||||
</table>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?php if (!empty($tables)) { ?>
|
||||
<div class="exception-var">
|
||||
<h2>Environment Variables</h2>
|
||||
<?php foreach ((array)$tables as $label => $value) { ?>
|
||||
<table>
|
||||
<?php if (empty($value)) { ?>
|
||||
<caption><?php echo $label; ?><small>empty</small></caption>
|
||||
<?php } else { ?>
|
||||
<caption><?php echo $label; ?></caption>
|
||||
<tbody>
|
||||
<?php foreach ((array)$value as $key => $val) { ?>
|
||||
<tr>
|
||||
<td><?php echo htmlentities($key); ?></td>
|
||||
<td><?php echo_value($val); ?></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
<?php } ?>
|
||||
</table>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?php if (\think\facade\App::isDebug()) { ?>
|
||||
<script>
|
||||
function $(selector, node) {
|
||||
var elements;
|
||||
node = node || document;
|
||||
if (document.querySelectorAll) {
|
||||
elements = node.querySelectorAll(selector);
|
||||
} else {
|
||||
switch (selector.substr(0, 1)) {
|
||||
case '#':
|
||||
elements = [node.getElementById(selector.substr(1))];
|
||||
break;
|
||||
case '.':
|
||||
if (document.getElementsByClassName) {
|
||||
elements = node.getElementsByClassName(selector.substr(1));
|
||||
} else {
|
||||
elements = get_elements_by_class(selector.substr(1), node);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
elements = node.getElementsByTagName();
|
||||
}
|
||||
}
|
||||
return elements;
|
||||
|
||||
function get_elements_by_class(search_class, node, tag) {
|
||||
var elements = [], eles,
|
||||
pattern = new RegExp('(^|\\s)' + search_class + '(\\s|$)');
|
||||
|
||||
node = node || document;
|
||||
tag = tag || '*';
|
||||
|
||||
eles = node.getElementsByTagName(tag);
|
||||
for (var i = 0; i < eles.length; i++) {
|
||||
if (pattern.test(eles[i].className)) {
|
||||
elements.push(eles[i])
|
||||
}
|
||||
}
|
||||
|
||||
return elements;
|
||||
}
|
||||
}
|
||||
|
||||
$.getScript = function (src, func) {
|
||||
var script = document.createElement('script');
|
||||
|
||||
script.async = 'async';
|
||||
script.src = src;
|
||||
script.onload = func || function () {
|
||||
};
|
||||
|
||||
$('head')[0].appendChild(script);
|
||||
}
|
||||
|
||||
;(function () {
|
||||
var files = $('.toggle');
|
||||
var ol = $('ol', $('.prettyprint')[0]);
|
||||
var li = $('li', ol[0]);
|
||||
|
||||
// 短路径和长路径变换
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
files[i].ondblclick = function () {
|
||||
var title = this.title;
|
||||
|
||||
this.title = this.innerHTML;
|
||||
this.innerHTML = title;
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
var expand = function (dom, expand) {
|
||||
var ol = $('ol', dom.parentNode)[0];
|
||||
expand = undefined === expand ? dom.attributes['data-expand'].value === '0' : undefined;
|
||||
if (expand) {
|
||||
dom.attributes['data-expand'].value = '1';
|
||||
ol.style.display = 'none';
|
||||
dom.innerText = 'Call Stack (展开)';
|
||||
} else {
|
||||
dom.attributes['data-expand'].value = '0';
|
||||
ol.style.display = 'block';
|
||||
dom.innerText = 'Call Stack (折叠)';
|
||||
}
|
||||
};
|
||||
var traces = $('.trace');
|
||||
for (var i = 0; i < traces.length; i++) {
|
||||
var h2 = $('h2', traces[i])[0];
|
||||
expand(h2);
|
||||
h2.onclick = function () {
|
||||
expand(this);
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
$.getScript('//cdn.bootcss.com/prettify/r298/prettify.min.js', function () {
|
||||
prettyPrint();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<?php } ?>
|
||||
</body>
|
||||
</html>
|
@ -1,62 +0,0 @@
|
||||
{extend name='table'}
|
||||
|
||||
{block name="button"}
|
||||
<!--{if auth("distinct")}-->
|
||||
<a data-table-id="FileTable" data-load='{:url("distinct")}' class='layui-btn layui-btn-sm layui-btn-primary'>清理重复</a>
|
||||
<!--{/if}-->
|
||||
<!--{if auth("remove")}-->
|
||||
<a data-confirm="确定永久删除这些账号吗?" data-table-id="FileTable" data-action='{:url("remove")}' data-rule="id#{id}" class='layui-btn layui-btn-sm layui-btn-primary'>批量删除</a>
|
||||
<!--{/if}-->
|
||||
{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="think-box-shadow">
|
||||
{include file='file/index_search'}
|
||||
<table id="FileTable" data-url="{:sysuri('index')}" data-target-search="form.form-search"></table>
|
||||
</div>
|
||||
<script>
|
||||
$(function () {
|
||||
$('#FileTable').layTable({
|
||||
even: true, height: 'full',
|
||||
sort: {field: 'id', type: 'desc'},
|
||||
cols: [[
|
||||
{checkbox: true, fixed: true},
|
||||
{field: 'id', title: 'ID', width: 80, align: 'center', sort: true},
|
||||
{field: 'name', title: '文件名称', width: '12%', align: 'center'},
|
||||
{field: 'hash', title: '文件哈希', width: '15%', align: 'center', templet: '<div><code>{{d.hash}}</code></div>'},
|
||||
{
|
||||
field: 'size', title: '文件大小', align: 'center', width: '8%', sort: true, templet: function (d) {
|
||||
return $.formatFileSize(d.size)
|
||||
}
|
||||
},
|
||||
{field: 'xext', title: '文件后缀', align: 'center', width: '8%', sort: true},
|
||||
{
|
||||
field: 'xurl', title: '查看文件', width: '8%', align: 'center', templet: function (d) {
|
||||
if (typeof d.mime === 'string' && /^image\//.test(d.mime)) {
|
||||
return laytpl('<div class="headimg headimg-no headimg-ss margin-0" data-tips-hover data-tips-image="{{d.xurl}}" style="background-image:url({{d.xurl}})"></div>').render(d)
|
||||
} else if (typeof d.mime === 'string' && /^(video|audio)\//.test(d.mime)) {
|
||||
return laytpl('<div><a target="_blank" data-iframe="{{d.xurl}}" data-title="查看媒体">查看</a></div>').render(d);
|
||||
} else {
|
||||
return laytpl('<div><a target="_blank" href="{{d.xurl}}">查看</a></div>').render(d);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'isfast', title: '上传方式', align: 'center', width: '8%', templet: function (d) {
|
||||
return d.isfast ? '<b class="color-green">秒传</b>' : '<b class="color-blue">普通</b>';
|
||||
}
|
||||
},
|
||||
{field: 'ctype', title: '存储方式', align: 'center', width: '10%'},
|
||||
{field: 'create_at', title: '上传时间', align: 'center', width: '15%', sort: true},
|
||||
{toolbar: '#toolbar', title: '操作面板', align: 'center', minWidth: 90, fixed: 'right'}
|
||||
]]
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="toolbar">
|
||||
<!--{if auth("remove")}-->
|
||||
<a class="layui-btn layui-btn-sm layui-btn-danger" data-action="{:url('remove')}" data-value="id#{{d.id}}">删 除</a>
|
||||
<!--{/if}-->
|
||||
</script>
|
||||
{/block}
|
@ -1,58 +0,0 @@
|
||||
<fieldset>
|
||||
<legend>条件搜索</legend>
|
||||
<form class="layui-form layui-form-pane form-search" action="{:sysuri()}" onsubmit="return false" method="get" autocomplete="off">
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">文件名称</label>
|
||||
<label class="layui-input-inline">
|
||||
<input name="name" value="{$get.name|default=''}" placeholder="请输入文件名称" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">文件哈希</label>
|
||||
<label class="layui-input-inline">
|
||||
<input name="hash" value="{$get.hash|default=''}" placeholder="请输入文件哈希" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">文件后缀</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="xext" lay-search class="layui-select">
|
||||
<option value=''>-- 全部后缀 --</option>
|
||||
{foreach $xexts as $v}{if isset($get.xext) and $k eq $get.xext}
|
||||
<option selected value="{$v}">{$v}</option>
|
||||
{else}
|
||||
<option value="{$v}">{$v}</option>
|
||||
{/if}{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">存储方式</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="type" lay-search class="layui-select">
|
||||
<option value=''>-- 全部方式 --</option>
|
||||
{foreach $types as $k=>$v}{if isset($get.type) and $k eq $get.type}
|
||||
<option selected value="{$k}">{$v}</option>
|
||||
{else}
|
||||
<option value="{$k}">{$v}</option>
|
||||
{/if}{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">上传时间</label>
|
||||
<div class="layui-input-inline">
|
||||
<input data-date-range name="create_at" value="{$get.create_at|default=''}" placeholder="请选择上传时间" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<button class="layui-btn layui-btn-primary"><i class="layui-icon"></i> 搜 索</button>
|
||||
</div>
|
||||
</form>
|
||||
</fieldset>
|
@ -1,32 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<title>{block name="title"}{$title|default=''}{if !empty($title)} · {/if}{:sysconf('site_name')}{/block}</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=0.4">
|
||||
<link rel="stylesheet" href="__ROOT__/static/plugs/layui/css/layui.css?at={:date('md')}">
|
||||
<link rel="stylesheet" href="__ROOT__/static/theme/css/iconfont.css?at={:date('md')}">
|
||||
<link rel="stylesheet" href="__ROOT__/static/theme/css/console.css?at={:date('md')}">
|
||||
<link rel="stylesheet" href="__ROOT__/static/extra/style.css?at={:date('md')}">
|
||||
{block name="style"}{/block}
|
||||
<script src="__ROOT__/static/plugs/jquery/pace.min.js"></script>
|
||||
<script src="{:url('admin/api.plugs/script',[],false,false)}"></script>
|
||||
</head>
|
||||
<body class="layui-layout-body">
|
||||
{block name='body'}
|
||||
<div class="layui-layout layui-layout-admin layui-layout-left-hide">
|
||||
<div class="layui-body think-bg-white margin-0 padding-0" style="top:0">{block name='content'}{/block}</div>
|
||||
</div>
|
||||
{/block}
|
||||
<script src="__ROOT__/static/plugs/layui/layui.js"></script>
|
||||
<script src="__ROOT__/static/plugs/require/require.js"></script>
|
||||
<script src="__ROOT__/static/admin.js"></script>
|
||||
<script src="__ROOT__/static/extra/script.js"></script>
|
||||
{block name='script'}{/block}
|
||||
</body>
|
||||
</html>
|
@ -1,50 +0,0 @@
|
||||
<div class="layui-side">
|
||||
<a class="layui-side-target" data-target-menu-type></a>
|
||||
<a class="layui-logo layui-elip" href="{:sysuri('@')}" title="{:sysconf('app_name')}">
|
||||
<span class="headimg headimg-no headimg-xs" data-lazy-src="{:sysconf('site_icon')}"></span>
|
||||
<span class="headtxt">{:sysconf('app_name')} {if sysconf('app_version')}<sup>{:sysconf('app_version')}</sup>{/if}</span>
|
||||
</a>
|
||||
<div class="layui-side-scroll">
|
||||
<div class="layui-side-icon">
|
||||
{foreach $menus as $one}
|
||||
<div>
|
||||
<a data-menu-node="m-{$one.id}" data-open="{$one.url}" data-target-tips="{$one.title|default=''}">
|
||||
{notempty name='one.icon'}<i class="{$one.icon|default=''}"></i>{/notempty}
|
||||
<span>{$one.title|default=''}</span>
|
||||
</a>
|
||||
</div>
|
||||
{/foreach}
|
||||
</div>
|
||||
<div class="layui-side-tree">
|
||||
{foreach $menus as $one}{notempty name='one.sub'}
|
||||
<ul class="layui-nav layui-nav-tree layui-hide" data-menu-layout="m-{$one.id}">
|
||||
{foreach $one.sub as $two}{empty name='two.sub'}
|
||||
<li class="layui-nav-item">
|
||||
<a data-target-tips="{$two.title}" data-menu-node="m-{$one.id}-{$two.id}" data-open="{$two.url}">
|
||||
<span class='nav-icon {$two.icon|default="layui-icon layui-icon-senior"}'></span>
|
||||
<span class="nav-text">{$two.title|default=''}</span>
|
||||
</a>
|
||||
</li>
|
||||
{else}
|
||||
<li class="layui-nav-item" data-submenu-layout='m-{$one.id}-{$two.id}'>
|
||||
<a data-target-tips="{$two.title}">
|
||||
<span class='nav-icon layui-hide {$two.icon|default="layui-icon layui-icon-triangle-d"}'></span>
|
||||
<span class="nav-text">{$two.title|default=''}</span>
|
||||
</a>
|
||||
<dl class="layui-nav-child">
|
||||
{foreach $two.sub as $thr}
|
||||
<dd>
|
||||
<a data-target-tips="{$thr.title}" data-open="{$thr.url}" data-menu-node="m-{$one.id}-{$two.id}-{$thr.id}">
|
||||
<span class='nav-icon {$thr.icon|default="layui-icon layui-icon-senior"}'></span>
|
||||
<span class="nav-text">{$thr.title|default=''}</span>
|
||||
</a>
|
||||
</dd>
|
||||
{/foreach}
|
||||
</dl>
|
||||
</li>
|
||||
{/empty}{/foreach}
|
||||
</ul>
|
||||
{/notempty}{/foreach}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,44 +0,0 @@
|
||||
<div class="layui-header">
|
||||
<ul class="layui-nav layui-layout-left">
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
<a class="text-center" data-target-menu-type>
|
||||
<i class="layui-icon layui-icon-spread-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
<a class="layui-logo-hide layui-elip" href="{:sysuri('@')}" title="{:sysconf('app_name')}">
|
||||
<span class="headimg headimg-no headimg-xs" data-lazy-src="{:sysconf('site_icon')}"></span>
|
||||
</a>
|
||||
</li>
|
||||
{foreach $menus as $one}
|
||||
<li class="layui-nav-item">
|
||||
<a data-menu-node="m-{$one.id}" data-open="{$one.url}"><span>{$one.title|default=''}</span></a>
|
||||
</li>
|
||||
{/foreach}
|
||||
</ul>
|
||||
<ul class="layui-nav layui-layout-right">
|
||||
<li lay-unselect class="layui-nav-item"><a data-reload><i class="layui-icon layui-icon-refresh-3"></i></a></li>
|
||||
{if session('user.username')}
|
||||
<li class="layui-nav-item">
|
||||
<dl class="layui-nav-child">
|
||||
<dd lay-unselect><a data-modal="{:sysuri('admin/index/info',['id'=>session('user.id')])}"><i class="layui-icon layui-icon-set-fill"></i> 基本资料</a></dd>
|
||||
<dd lay-unselect><a data-modal="{:sysuri('admin/index/pass',['id'=>session('user.id')])}"><i class="layui-icon layui-icon-component"></i> 安全设置</a></dd>
|
||||
{if isset($super) and $super}
|
||||
<dd lay-unselect><a data-load="{:sysuri('admin/api.system/push')}"><i class="layui-icon layui-icon-template-1"></i> 缓存加速</a></dd>
|
||||
<dd lay-unselect><a data-load="{:sysuri('admin/api.system/clear')}"><i class="layui-icon layui-icon-fonts-clear"></i> 清理缓存</a></dd>
|
||||
{/if}
|
||||
<dd lay-unselect><a data-width="520px" data-modal="{:sysuri('admin/index/theme')}"><i class="layui-icon layui-icon-theme"></i> 配色方案</a></dd>
|
||||
<dd lay-unselect><a data-load="{:sysuri('admin/login/out')}" data-confirm="确定要退出登录吗?"><i class="layui-icon layui-icon-release"></i> 退出登录</a></dd>
|
||||
</dl>
|
||||
<a class="layui-elip">
|
||||
<span class="headimg" data-lazy-src="{:htmlentities(session('user.headimg'))}"></span>
|
||||
<span>{:htmlentities(session('user.nickname')?:session('user.username'))}</span>
|
||||
</a>
|
||||
</li>
|
||||
{else}
|
||||
<li class="layui-nav-item">
|
||||
<a data-href="{:sysuri('admin/login/index')}"><i class="layui-icon layui-icon-username"></i> 立即登录</a>
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
</div>
|
@ -1,62 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
|
||||
<head>
|
||||
<title>{block name="title"}{$title|default=''}{if !empty($title)} · {/if}{:sysconf('site_name')}{/block}</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=0.4">
|
||||
<link rel="stylesheet" href="__ROOT__/static/plugs/layui/css/layui.css?at={:date('md')}">
|
||||
<link rel="stylesheet" href="__ROOT__/static/theme/css/iconfont.css?at={:date('md')}">
|
||||
<link rel="stylesheet" href="__ROOT__/static/theme/css/console.css?at={:date('md')}">
|
||||
<link rel="stylesheet" href="__ROOT__/static/extra/style.css?at={:date('md')}">
|
||||
{block name="style"}{/block}
|
||||
<script src="__ROOT__/static/plugs/jquery/pace.min.js"></script>
|
||||
<script src="{:url('admin/api.plugs/script',[],false,false)}"></script>
|
||||
</head>
|
||||
|
||||
<body class="layui-layout-body layui-layout-theme-{$theme|default='default'}">
|
||||
|
||||
{block name='body'}
|
||||
<div class="layui-layout layui-layout-admin layui-layout-left-hide">
|
||||
|
||||
<!-- 左则菜单 开始 -->
|
||||
{include file="index/index-left"}
|
||||
<!-- 左则菜单 结束 -->
|
||||
|
||||
<!-- 顶部菜单 开始 -->
|
||||
{include file='index/index-top'}
|
||||
<!-- 顶部菜单 结束 -->
|
||||
|
||||
<!-- 主体内容 开始 -->
|
||||
<div class="layui-body">
|
||||
<div class="think-page-body">
|
||||
{block name='content'}{/block}
|
||||
</div>
|
||||
<!-- 页面加载动画 -->
|
||||
<div class="think-page-loader layui-hide">
|
||||
<div class="loader"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 主体内容 结束 -->
|
||||
</div>
|
||||
|
||||
<!-- 加载动画 开始 -->
|
||||
<div class="think-page-loader">
|
||||
<div class="loader"></div>
|
||||
</div>
|
||||
<!-- 加载动画 结束 -->
|
||||
|
||||
{/block}
|
||||
<script src="__ROOT__/static/plugs/layui/layui.js"></script>
|
||||
<script src="__ROOT__/static/plugs/require/require.js"></script>
|
||||
<script src="__ROOT__/static/admin.js"></script>
|
||||
<script src="__ROOT__/static/extra/script.js"></script>
|
||||
{block name='script'}{/block}
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,36 +0,0 @@
|
||||
<form action="{:sysuri()}" method="post" data-auto="true" class="layui-form layui-card" id="theme">
|
||||
<div class="layui-card-body padding-left-40">
|
||||
|
||||
<div class="layui-form-item margin-bottom-5 label-required-prev">
|
||||
<div class="help-label"><b>后台配色方案</b>Theme Style</div>
|
||||
<div class="layui-textarea think-bg-gray" style="min-height:unset">
|
||||
{foreach $themes as $k=>$v}
|
||||
<label class="think-radio">
|
||||
{if isset($theme) and $theme eq $k}
|
||||
<input name="site_theme" type="radio" value="{$k}" lay-ignore checked> {$v}
|
||||
{else}
|
||||
<input name="site_theme" type="radio" value="{$k}" lay-ignore> {$v}
|
||||
{/if}
|
||||
</label>
|
||||
{/foreach}
|
||||
</div>
|
||||
<p class="help-block">切换配色方案,需要保存成功后配色方案才会永久生效,下次登录也会有效哦 ~</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="layui-form-item text-center">
|
||||
<button class="layui-btn" type="submit">保存配置</button>
|
||||
<button class="layui-btn layui-btn-danger" type='button' data-close>取消修改</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
$('form#theme input[name=site_theme]').on('click', function () {
|
||||
var alls = '', that = this, prox = 'layui-layout-theme-', curt = prox + that.value;
|
||||
$('form#theme input[name=site_theme]').map(function () {
|
||||
if (this.value !== that.value) alls += ' ' + prox + this.value;
|
||||
});
|
||||
$('.layui-layout-body').removeClass(alls).addClass(curt)
|
||||
});
|
||||
</script>
|
@ -1,57 +0,0 @@
|
||||
{extend name="index/index"}
|
||||
|
||||
{block name='style'}
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1">
|
||||
<script>if (location.href.indexOf('#') > -1) location.replace(location.href.split('#')[0])</script>
|
||||
<link rel="stylesheet" href="__ROOT__/static/theme/css/login.css">
|
||||
{/block}
|
||||
|
||||
{block name="body"}
|
||||
<div class="login-container" {$loginStyle|raw}>
|
||||
<div class="header notselect layui-hide-xs">
|
||||
<a href="{:url('@')}" class="title">{:sysconf('app_name')}<span>{:sysconf('app_version')}</span></a>
|
||||
{notempty name='developMode'}
|
||||
<a class="pull-right layui-anim layui-anim-fadein" target="_blank" href='https://gitee.com/zoujingli/ThinkAdmin'>
|
||||
<img src='https://gitee.com/zoujingli/ThinkAdmin/widgets/widget_1.svg' alt='Fork me on Gitee'>
|
||||
</a>
|
||||
{/notempty}
|
||||
</div>
|
||||
<form data-login-form onsubmit="return false" method="post" class="layui-anim layui-anim-upbit" autocomplete="off">
|
||||
<h2 class="notselect">{:sysconf('login_name')?:'系统管理'}</h2>
|
||||
<ul>
|
||||
<li class="username">
|
||||
<label class="label-required-null">
|
||||
<i class="layui-icon layui-icon-username"></i>
|
||||
<input class="layui-input" required pattern="^\S{4,}$" name="username" autofocus autocomplete="off" placeholder="登录账号" title="请输入登录账号">
|
||||
</label>
|
||||
</li>
|
||||
<li class="password">
|
||||
<label class="label-required-null">
|
||||
<i class="layui-icon layui-icon-password"></i>
|
||||
<input class="layui-input" required pattern="^\S{4,}$" name="password" maxlength="32" type="password" autocomplete="off" placeholder="登录密码" title="请输入登录密码">
|
||||
</label>
|
||||
</li>
|
||||
<li class="verify layui-hide">
|
||||
<label class="inline-block relative label-required-null">
|
||||
<i class="layui-icon layui-icon-picture-fine"></i>
|
||||
<input class="layui-input" required pattern="^\S{4,}$" name="verify" maxlength="4" autocomplete="off" placeholder="验证码" title="请输入验证码">
|
||||
</label>
|
||||
<label data-captcha="{:url('admin/login/captcha',[],false)}" data-field-verify="verify" data-field-uniqid="uniqid" data-captcha-type="{$captchaType}" data-captcha-token="{$captchaToken}"></label>
|
||||
</li>
|
||||
<li class="text-center padding-top-20">
|
||||
<button type="submit" class="layui-btn layui-disabled full-width" data-form-loaded="立即登入">正在载入</button>
|
||||
</li>
|
||||
</ul>
|
||||
</form>
|
||||
<div class="footer notselect">
|
||||
<p class="layui-hide-xs">推荐使用 <a target="_blank" href="https://www.google.cn/chrome">Google Chrome</a> 或 <a target="_blank" href="https://www.microsoft.com/zh-cn/edge#platform">Microsoft Edge</a> 浏览器访问</p>
|
||||
{:sysconf('site_copy')}
|
||||
{if sysconf('beian')}<span class="padding-5">|</span><a target="_blank" href="https://beian.miit.gov.cn/">{:sysconf('beian')}</a>{/if}
|
||||
{if sysconf('miitbeian')}<span class="padding-5">|</span><a target="_blank" href="https://beian.miit.gov.cn/">{:sysconf('miitbeian')}</a>{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
{block name='script'}
|
||||
<script src="__ROOT__/static/login.js"></script>
|
||||
{/block}
|
@ -1,18 +0,0 @@
|
||||
<div class="layui-card">
|
||||
{block name='style'}{/block}
|
||||
{block name='header'}
|
||||
{notempty name='title'}
|
||||
<div class="layui-card-header">
|
||||
<span class="layui-icon font-s10 color-desc margin-right-5"></span>{$title|default=''}
|
||||
<div class="pull-right">{block name='button'}{/block}</div>
|
||||
</div>
|
||||
{/notempty}
|
||||
{/block}
|
||||
<div class="layui-card-line"></div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-card-html">
|
||||
{block name='content'}{/block}
|
||||
</div>
|
||||
</div>
|
||||
{block name='script'}{/block}
|
||||
</div>
|
@ -1,97 +0,0 @@
|
||||
<form action="{:sysuri()}" method="post" data-auto="true" class="layui-form layui-card" data-table-id="MenuTable">
|
||||
|
||||
<div class="layui-card-body">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label label-required-next">上级菜单</label>
|
||||
<div class="layui-input-block">
|
||||
<select name='pid' class='layui-select' lay-search>
|
||||
{foreach $menus as $menu}{eq name='menu.id' value='$vo.pid|default=0'}
|
||||
<option selected value='{$menu.id}'>{$menu.spl|raw}{$menu.title}</option>
|
||||
{else}
|
||||
<option value='{$menu.id}'>{$menu.spl|raw}{$menu.title}</option>
|
||||
{/eq}{/foreach}
|
||||
</select>
|
||||
<p class="help-block"><b>必选</b>,请选择上级菜单或顶级菜单 ( 目前最多支持三级菜单 )</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">菜单名称</label>
|
||||
<div class="layui-input-block">
|
||||
<input name="title" value='{$vo.title|default=""}' required placeholder="请输入菜单名称" class="layui-input">
|
||||
<p class="help-block"><b>必选</b>,请填写菜单名称 ( 如:系统管理 ),建议字符不要太长,一般 4-6 个汉字</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">菜单链接</label>
|
||||
<div class="layui-input-block">
|
||||
<input onblur="this.value=this.value === ''?'#':this.value" name="url" required placeholder="请输入菜单链接" value="{$vo.url|default='#'}" class="layui-input">
|
||||
<p class="help-block">
|
||||
<b>必选</b>,请填写链接地址或选择系统节点 ( 如:https://domain.com/admin/user/index.html 或 admin/user/index )
|
||||
<br>当填写链接地址时,以下面的 “权限节点” 来判断菜单自动隐藏或显示,注意未填写 “权限节点” 时将不会隐藏该菜单哦
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">链接参数</label>
|
||||
<div class="layui-input-block">
|
||||
<input name="params" placeholder="请输入链接参数" value="{$vo.params|default=''}" class="layui-input">
|
||||
<p class="help-block"><b>可选</b>,设置菜单链接的 GET 访问参数 ( 如:name=1&age=3 )</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">权限节点</label>
|
||||
<div class="layui-input-block">
|
||||
<input name="node" placeholder="请输入权限节点" value="{$vo.node|default=''}" class="layui-input">
|
||||
<p class="help-block"><b>可选</b>,请填写系统权限节点 ( 如:admin/user/index ),未填写时默认解释"菜单链接"判断是否拥有访问权限;</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">菜单图标</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-input-inline">
|
||||
<input placeholder="请输入或选择图标" name="icon" value='{$vo.icon|default=""}' class="layui-input">
|
||||
</div>
|
||||
<span style="padding:0 12px;min-width:45px" class='layui-btn layui-btn-primary'>
|
||||
<i style="font-size:1.2em;margin:0;float:none" class='{$vo.icon|default=""}'></i>
|
||||
</span>
|
||||
<button data-icon='icon' type='button' class='layui-btn layui-btn-primary'>选择图标</button>
|
||||
<p class="help-block"><b>可选</b>,设置菜单选项前置图标,目前支持 layui 字体图标及 iconfont 定制字体图标。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
{notempty name='vo.id'}<input type='hidden' value='{$vo.id}' name='id'>{/notempty}
|
||||
|
||||
<div class="layui-form-item text-center">
|
||||
<button class="layui-btn" type='submit'>保存数据</button>
|
||||
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
require(['jquery.autocompleter'], function () {
|
||||
$('[name="icon"]').on('change', function () {
|
||||
$(this).parent().next().find('i').get(0).className = this.value
|
||||
}), $('input[name=url]').autocompleter({
|
||||
limit: 6, highlightMatches: true, template: '{{ label }} <span> {{ title }} </span>', callback: function (node) {
|
||||
$('input[name=node]').val(node);
|
||||
}, source: (function (subjects, data) {
|
||||
for (var i in subjects) data.push({value: subjects[i].node, label: subjects[i].node, title: subjects[i].title});
|
||||
return data;
|
||||
})(JSON.parse('{$nodes|raw|json_encode}'), [])
|
||||
}), $('input[name=node]').autocompleter({
|
||||
limit: 5, highlightMatches: true, template: '{{ label }} <span> {{ title }} </span>', source: (function (subjects, data) {
|
||||
for (var i in subjects) data.push({value: subjects[i].node, label: subjects[i].node, title: subjects[i].title});
|
||||
return data;
|
||||
})(JSON.parse('{$auths|raw|json_encode}'), [])
|
||||
});
|
||||
});
|
||||
</script>
|
@ -1,123 +0,0 @@
|
||||
{extend name='table'}
|
||||
|
||||
{block name="button"}
|
||||
<!--{if $type eq 'index' and auth("add")}-->
|
||||
<button data-modal='{:url("add")}' data-table-id="MenuTable" class='layui-btn layui-btn-sm layui-btn-primary'>添加菜单</button>
|
||||
<!--{/if}-->
|
||||
|
||||
<!--{if $type eq 'index' and auth("state")}-->
|
||||
<button data-action='{:url("state")}' data-table-id="MenuTable" data-rule="id#{sps};status#0" class='layui-btn layui-btn-sm layui-btn-primary'>禁用菜单</button>
|
||||
<!--{/if}-->
|
||||
|
||||
<!--{if $type eq 'recycle' and auth("state")}-->
|
||||
<button data-action='{:url("state")}' data-table-id="MenuTable" data-rule="id#{spp};status#1" class='layui-btn layui-btn-sm layui-btn-primary'>激活菜单</button>
|
||||
<!--{/if}-->
|
||||
{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="layui-tab layui-tab-card">
|
||||
<ul class="layui-tab-title">
|
||||
{foreach ['index'=>'系统菜单','recycle'=>'回 收 站'] as $k=>$v}
|
||||
{if isset($type) and $type eq $k}
|
||||
<li class="layui-this" data-open="{:url('index')}?type={$k}">{$v}</li>
|
||||
{else}
|
||||
<li data-open="{:url('index')}?type={$k}">{$v}</li>
|
||||
{/if}{/foreach}
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<table id="MenuTable" data-url="{:sysuri()}" data-target-search="form.form-search"></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(function () {
|
||||
$('#MenuTable').layTable({
|
||||
even: true, height: 'full', page: false,
|
||||
sort: {field: 'sort desc,id', type: 'asc'},
|
||||
where: {type: '{$type|default="index"}'},
|
||||
filter: function (items) {
|
||||
var type = this.where.type;
|
||||
return items.filter(function (item) {
|
||||
return !(type === 'index' && item.status === 0);
|
||||
});
|
||||
},
|
||||
cols: [[
|
||||
{checkbox: true, field: 'sps'},
|
||||
{field: 'sort', title: '排序权重', width: 100, align: 'center', templet: '#SortInputTpl'},
|
||||
{
|
||||
field: 'icon', title: '图 标', width: 80, align: 'center', templet: function (d) {
|
||||
return layui.laytpl('<i class="{{d.icon}} font-s18"></i>').render(d);
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'title', title: '菜单名称', minWidth: 220, templet: function (d) {
|
||||
return layui.laytpl('<span class="color-desc">{{d.spl}}</span>{{d.title}}').render(d);
|
||||
}
|
||||
},
|
||||
{field: 'url', title: '跳转链接', minWidth: 200},
|
||||
{field: 'status', title: '菜单状态', minWidth: 120, align: 'center', templet: '#StatusSwitchTpl'},
|
||||
// {field: 'create_at', title: '创建时间', minWidth: 170, align: 'center'},
|
||||
{toolbar: '#toolbar', title: '操作面板', minWidth: 150, align: 'center', fixed: 'right'},
|
||||
]]
|
||||
});
|
||||
|
||||
// 数据状态切换操作
|
||||
layui.form.on('switch(StatusSwitch)', function (object) {
|
||||
object.data = {status: object.elem.checked > 0 ? 1 : 0};
|
||||
object.data.id = object.value.split('|')[object.data.status] || object.value;
|
||||
$.form.load("{:url('state')}", object.data, 'post', function (ret) {
|
||||
if (ret.code < 1) $.msg.error(ret.info, 3, function () {
|
||||
$('#MenuTable').trigger('reload');
|
||||
}); else {
|
||||
$('#MenuTable').trigger('reload');
|
||||
}
|
||||
return false;
|
||||
}, false);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- 数据状态切换模板 -->
|
||||
<script type="text/html" id="StatusSwitchTpl">
|
||||
<!--{if auth("state")}-->
|
||||
{{# if( "{$type|default='index'}"==='index' || (d.spc<1 || d.status<1)){ }}
|
||||
<input type="checkbox" value="{{d.sps}}|{{d.spp}}" lay-text="已激活|已禁用" lay-filter="StatusSwitch" lay-skin="switch" {{-d.status>0?'checked':''}}>
|
||||
{{# }else{ }}
|
||||
{{-d.status ? '<b class="color-green">已激活</b>' : '<b class="color-red">已禁用</b>'}}
|
||||
{{# } }}
|
||||
<!--{else}-->
|
||||
{{-d.status ? '<b class="color-green">已激活</b>' : '<b class="color-red">已禁用</b>'}}
|
||||
<!--{/if}-->
|
||||
</script>
|
||||
|
||||
<!-- 列表排序权重模板 -->
|
||||
<script type="text/html" id="SortInputTpl">
|
||||
<input type="number" min="0" data-blur-number="0" data-action-blur="{:sysuri()}" data-value="id#{{d.id}};action#sort;sort#{value}" data-loading="false" value="{{d.sort}}" class="layui-input text-center">
|
||||
</script>
|
||||
|
||||
<!-- 操控面板的模板 -->
|
||||
<script type="text/html" id="toolbar">
|
||||
|
||||
<!-- {if isset($type) and $type eq 'index'} -->
|
||||
<!-- {if auth('add')} -->
|
||||
{{# if(d.spt<2){ }}
|
||||
<a class="layui-btn layui-btn-sm layui-btn-primary" data-title="添加系统菜单" data-modal='{:url("add")}?pid={{d.id}}'>添 加</a>
|
||||
{{# }else{ }}
|
||||
<a class="layui-btn layui-btn-sm layui-btn-disabled">添 加</a>
|
||||
{{# } }}
|
||||
<!-- {/if} -->
|
||||
{if auth('edit')}
|
||||
<a class="layui-btn layui-btn-sm" data-event-dbclick data-title="编辑系统菜单" data-modal='{:url("edit")}?id={{d.id}}'>编 辑</a>
|
||||
{/if}
|
||||
<!-- {else} -->
|
||||
{if auth('remove')}
|
||||
{{# if( (d.spc<1 || d.status<1)){ }}
|
||||
<a class="layui-btn layui-btn-sm layui-btn-danger" data-confirm="确定要删除菜单吗?" data-action="{:url('remove')}" data-value="id#{{d.sps}}">删 除</a>
|
||||
{{# }else{ }}
|
||||
<a class="layui-btn layui-btn-disabled layui-btn-sm">删 除</a>
|
||||
{{# } }}
|
||||
{/if}
|
||||
<!-- {/if} -->
|
||||
|
||||
</script>
|
||||
{/block}
|
@ -1,44 +0,0 @@
|
||||
<form action="{:sysuri()}" method="post" data-auto="true" class="layui-form layui-card">
|
||||
<div class="layui-card-body padding-left-40">
|
||||
<div class="layui-textarea border-0 font-s14 layui-bg-gray padding-top-20 padding-left-20">
|
||||
<div class="layui-row margin-bottom-15">
|
||||
<div class="layui-col-xs6">模块名称:<b class="color-green">{$module.name}</b></div>
|
||||
<div class="layui-col-xs6">开发作者:<b class="color-green">{$module.author}</b></div>
|
||||
</div>
|
||||
<div class="layui-row margin-bottom-15">
|
||||
<div class="layui-col-xs6">最新版本:<b class="color-green">{$module.version}</b></div>
|
||||
<div class="layui-col-xs6">{if isset($current.version)}已安装版本:<b class="color-green">{$current.version}</b>{/if}</div>
|
||||
</div>
|
||||
<div class="margin-bottom-15">模块描述:{$module.content}</div>
|
||||
</div>
|
||||
<ul class="layui-timeline margin-top-30 margin-bottom-30" style="max-height:400px;overflow:auto">
|
||||
{foreach $module.change as $version=>$change}
|
||||
<li class="layui-timeline-item">
|
||||
{if isset($current.version) and $current.version eq $version}
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
{else}
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
{/if}
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h3 class="layui-timeline-title">
|
||||
版本号 {$version} <span class="margin-left-10 font-s13 color-desc">{$change.version|default=''}</span>
|
||||
</h3>
|
||||
<div data-marked>
|
||||
{$change.content|default=''|raw}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{/foreach}
|
||||
<li class="layui-timeline-item"></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
require(['marked'], function (marked) {
|
||||
$('[data-marked]').map(function () {
|
||||
if (this.marked) return; else this.marked = true;
|
||||
this.innerHTML = marked.parse(this.innerHTML);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</form>
|
@ -1,42 +0,0 @@
|
||||
{extend name='main'}
|
||||
|
||||
{block name="content"}
|
||||
<div class="think-box-shadow">
|
||||
<table class="layui-table margin-top-15" lay-skin="line">
|
||||
{notempty name='modules'}
|
||||
<thead>
|
||||
<tr>
|
||||
<th class='text-left nowrap'>模块名称</th>
|
||||
<th class='text-left nowrap'>模块描述</th>
|
||||
<th class='text-left nowrap'>当前版本</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
{/notempty}
|
||||
<tbody>
|
||||
{foreach $modules as $key=>$vo}
|
||||
<tr>
|
||||
<td class='text-left nowrap'>{$vo.name}</td>
|
||||
<td class='text-left nowrap'>{$vo.content}</td>
|
||||
<td class='text-left nowrap'>
|
||||
<div class="inline-block pointer" data-title="查看模块版本" data-modal="{:url('change')}?name={$vo.name}">
|
||||
{if isset($vo.local)} {$vo.local.version}
|
||||
{if $vo.version > $vo.local.version}
|
||||
<span class="color-red margin-left-5">{$vo.version}</span>
|
||||
{else}
|
||||
<span class="color-desc margin-left-5">{$vo.type_desc}</span>
|
||||
{/if}
|
||||
{else}<span class="color-desc margin-left-5">{$vo.type_desc}</span>{/if}
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-left">
|
||||
{if $vo.type_code eq 1} <a class="layui-btn layui-btn-xs" data-action="{:url('install')}" data-value="name#{$vo.name}">安 装</a>{/if}
|
||||
{if $vo.type_code eq 2} <a class="layui-btn layui-btn-xs" data-action="{:url('install')}" data-value="name#{$vo.name}">更 新</a>{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
{empty name='modules'}<span class="notdata">没有记录哦</span>{else}{$pagehtml|raw|default=''}{/empty}
|
||||
</div>
|
||||
{/block}
|
@ -1,58 +0,0 @@
|
||||
<fieldset>
|
||||
<legend>条件搜索</legend>
|
||||
<form class="layui-form layui-form-pane form-search" action="{:sysuri()}" onsubmit="return false" method="get" autocomplete="off">
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">任务编号</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="code" value="{$get.code|default=''}" placeholder="请输入任务编号" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">任务名称</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="title" value="{$get.title|default=''}" placeholder="请输入任务名称" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">任务指令</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="command" value="{$get.command|default=''}" placeholder="请输入任务指令" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">任务状态</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="status" class="layui-select">
|
||||
{foreach [''=>'-- 全部状态 --','1'=>'待处理','2'=>'处理中','3'=>'处理完成','4'=>'处理失败'] as $k=>$v}
|
||||
{if isset($get.status) and $get.status eq $k}
|
||||
<option selected value="{$k}">{$v}</option>
|
||||
{else}
|
||||
<option value="{$k}">{$v}</option>
|
||||
{/if}
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">计划时间</label>
|
||||
<div class="layui-input-inline">
|
||||
<input data-date-range name="exec_time" value="{$get.exec_time|default=''}" placeholder="请选择计划时间" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">执行时间</label>
|
||||
<div class="layui-input-inline">
|
||||
<input data-date-range name="enter_time" value="{$get.enter_time|default=''}" placeholder="请选择执行时间" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">创建时间</label>
|
||||
<div class="layui-input-inline">
|
||||
<input data-date-range name="create_at" value="{$get.create_at|default=''}" placeholder="请选择创建时间" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-inline">
|
||||
<button class="layui-btn layui-btn-primary"><i class="layui-icon"></i> 搜 索</button>
|
||||
</div>
|
||||
</form>
|
||||
</fieldset>
|
@ -1,47 +0,0 @@
|
||||
{extend name='table'}
|
||||
|
||||
{block name="button"}
|
||||
<!--{if auth("remove")}-->
|
||||
<button data-table-id="OplogTable" data-action='{:url("remove")}' data-rule="id#{id}" data-confirm="确定要删除选中的日志吗?" class='layui-btn layui-btn-sm layui-btn-primary'>批量删除</button>
|
||||
<!--{/if}-->
|
||||
|
||||
<!--{if auth("clear")}-->
|
||||
<button data-table-id="OplogTable" data-load='{:url("clear")}' data-confirm="确定要清空所有日志吗?" class='layui-btn layui-btn-sm layui-btn-primary'>清空日志</button>
|
||||
<!--{/if}-->
|
||||
{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="think-box-shadow">
|
||||
{include file='oplog/index_search'}
|
||||
<table id="OplogTable" data-url="{:sysuri()}" data-target-search="form.form-search"></table>
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
{block name='script'}
|
||||
<script>
|
||||
$(function () {
|
||||
$('#OplogTable').layTable({
|
||||
even: true, height: 'full',
|
||||
sort: {field: 'id', type: 'desc'},
|
||||
cols: [[
|
||||
{checkbox: true},
|
||||
{field: 'id', title: 'ID', width: 80, sort: true, align: 'center'},
|
||||
{field: 'username', title: '操作账号', minWidth: 100, sort: true, align: 'center'},
|
||||
{field: 'node', title: '操作节点', minWidth: 120},
|
||||
{field: 'action', title: '操作行为', minWidth: 120},
|
||||
{field: 'content', title: '操作描述', minWidth: 150},
|
||||
{field: 'geoip', title: '访问地址', minWidth: 100},
|
||||
{field: 'geoisp', title: '网络服务商', minWidth: 100},
|
||||
{field: 'create_at', title: '操作时间', minWidth: 170, align: 'center', sort: true},
|
||||
{toolbar: '#toolbar', title: '操作面板', align: 'center', minWidth: 80, fixed: 'right'}
|
||||
]]
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="toolbar">
|
||||
<!--{if auth('remove')}-->
|
||||
<a data-action='{:url("remove")}' data-value="id#{{d.id}}" data-confirm="确认要删除这条记录吗?" class="layui-btn layui-btn-sm layui-btn-danger">删 除</a>
|
||||
<!--{/if}-->
|
||||
</script>
|
||||
{/block}
|
@ -1,129 +0,0 @@
|
||||
<fieldset>
|
||||
<legend>条件搜索</legend>
|
||||
<form class="layui-form layui-form-pane form-search" action="{:sysuri()}" onsubmit="return false" method="get" autocomplete="off">
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">操作账号</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name='username' lay-search class="layui-select">
|
||||
<option value=''>-- 全部账号 --</option>
|
||||
{foreach $users as $user}{if $user eq input('get.username')}
|
||||
<option selected value="{$user}">{$user}</option>
|
||||
{else}
|
||||
<option value="{$user}">{$user}</option>
|
||||
{/if}{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">操作行为</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="action" lay-search class="layui-select">
|
||||
<option value=''>-- 全部行为 --</option>
|
||||
{foreach $actions as $action}{if $action eq input('get.action')}
|
||||
<option selected value="{$action}">{$action}</option>
|
||||
{else}
|
||||
<option value="{$action}">{$action}</option>
|
||||
{/if}{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">操作节点</label>
|
||||
<label class="layui-input-inline">
|
||||
<input name="node" value="{$get.node|default=''}" placeholder="请输入操作内容" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">操作描述</label>
|
||||
<label class="layui-input-inline">
|
||||
<input name="content" value="{$get.content|default=''}" placeholder="请输入操作内容" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">访问地址</label>
|
||||
<label class="layui-input-inline">
|
||||
<input name="geoip" value="{$get.geoip|default=''}" placeholder="请输入访问地址" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">操作时间</label>
|
||||
<label class="layui-input-inline">
|
||||
<input data-date-range name="create_at" value="{$get.create_at|default=''}" placeholder="请选择操作时间" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<button type="submit" class="layui-btn layui-btn-primary"><i class="layui-icon"></i> 搜 索</button>
|
||||
<button type="button" data-form-export="{:url('index')}?type={$type|default=''}" class="layui-btn layui-btn-primary">
|
||||
<i class="layui-icon layui-icon-export"></i> 导 出
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</fieldset>
|
||||
|
||||
<script>
|
||||
require(['excel'], function (excel) {
|
||||
excel.bind(function (data) {
|
||||
|
||||
// 设置表格内容
|
||||
data.forEach(function (item, index) {
|
||||
data[index] = [item.id, item.username, item.node, item.geoip, item.geoisp, item.action, item.content, item.create_at];
|
||||
});
|
||||
|
||||
// 设置表头内容
|
||||
data.unshift(['ID', '操作账号', '访问节点', '访问IP地址', '访问地理区域', '访问操作', '操作内容', '操作时间']);
|
||||
|
||||
// 自动计算列序号
|
||||
var lastCol = layui.excel.numToTitle(data[0].length || 0);
|
||||
|
||||
// 设置表头样式
|
||||
layui.excel.setExportCellStyle(data, 'A1:' + lastCol + '1', {
|
||||
s: {
|
||||
font: {sz: 12, bold: true, color: {rgb: "FFFFFF"}, name: '微软雅黑', shadow: true},
|
||||
fill: {bgColor: {indexed: 64}, fgColor: {rgb: "5FB878"}},
|
||||
alignment: {vertical: 'center', horizontal: 'center'}
|
||||
}
|
||||
});
|
||||
|
||||
// 设置内容样式
|
||||
var style1 = {
|
||||
font: {sz: 10, shadow: true, name: '微软雅黑'},
|
||||
fill: {bgColor: {indexed: 64}, fgColor: {rgb: "EAEAEA"}},
|
||||
alignment: {vertical: 'center', horizontal: 'center'}
|
||||
}, style2 = {
|
||||
font: {sz: 10, shadow: true, name: '微软雅黑'},
|
||||
fill: {bgColor: {indexed: 64}, fgColor: {rgb: "FFFFFF"}},
|
||||
alignment: {vertical: 'center', horizontal: 'center'}
|
||||
};
|
||||
// 动态应用样式
|
||||
layui.excel.setExportCellStyle(data, 'A2:' + lastCol + data.length, {s: style1}, function (raw, cell, list, conf, rows, cols) {
|
||||
// @var raw 原有单元格数据
|
||||
// @var cell 新的单元格数据
|
||||
// @var list 所在行数据列表
|
||||
// @var conf 当前样式配置
|
||||
// @var rows 当前行的标号
|
||||
// @var cols 当前列的标号
|
||||
return (rows % 2 === 0) ? cell : (Object.assign({}, cell, {s: style2}));
|
||||
});
|
||||
|
||||
// 设置表格行宽高,需要设置最后的行或列宽高,否则部分不生效 ???
|
||||
var rowsC = {1: 33}, colsC = {A: 60, B: 80, C: 99, E: 80, G: 120};
|
||||
rowsC[data.length] = 28, colsC[lastCol] = 160;
|
||||
this.options.extend = {
|
||||
'!rows': layui.excel.makeRowConfig(rowsC, 28), // 设置每行高度,默认 33
|
||||
'!cols': layui.excel.makeColConfig(colsC, 99), // 设置每行宽度,默认 99
|
||||
};
|
||||
|
||||
// 其他更多样式,可以配置 this.options.extend 参数,每次执行 bind 会被重置
|
||||
// 在线文档:http://excel.wj2015.com/_book/docs/%E5%87%BD%E6%95%B0%E5%88%97%E8%A1%A8/%E6%A0%B7%E5%BC%8F%E8%AE%BE%E7%BD%AE%E7%9B%B8%E5%85%B3%E5%87%BD%E6%95%B0.html
|
||||
|
||||
return data;
|
||||
}, '操作日志' + layui.util.toDateString(Date.now(), '_yyyyMMdd_HHmmss'));
|
||||
});
|
||||
</script>
|
@ -1,117 +0,0 @@
|
||||
{extend name='table'}
|
||||
|
||||
{block name="button"}
|
||||
<!--{if isset($super) and $super}-->
|
||||
<a data-table-id="QueueTable" class="layui-btn layui-btn-sm layui-btn-primary" data-queue="{:url('admin/api.plugs/optimize')}">优化数据库</a>
|
||||
<!--{/if}-->
|
||||
|
||||
<!--{if isset($super) and $super and $iswin}-->
|
||||
<button data-load='{:url("admin/api.queue/start")}' class='layui-btn layui-btn-sm layui-btn-primary'>开启服务</button>
|
||||
<button data-load='{:url("admin/api.queue/stop")}' class='layui-btn layui-btn-sm layui-btn-primary'>关闭服务</button>
|
||||
<!--{/if}-->
|
||||
|
||||
<!--{if auth("clean")}-->
|
||||
<button data-table-id="QueueTable" data-queue='{:url("clean")}' class='layui-btn layui-btn-sm layui-btn-primary'>定时清理</button>
|
||||
<!--{/if}-->
|
||||
|
||||
<!--{if auth("remove")}-->
|
||||
<button data-table-id="QueueTable" data-action='{:url("remove")}' data-rule="id#{id}" data-confirm="确定批量删除记录吗?" class='layui-btn layui-btn-sm layui-btn-primary'>批量删除</button>
|
||||
<!--{/if}-->
|
||||
{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="think-box-notify">
|
||||
<!--{if isset($super) and $super}-->
|
||||
<b>服务状态:</b><b class="margin-right-5" data-queue-message><span class="color-desc">检查中</span></b>
|
||||
<b data-tips-text="点击可复制【服务启动指令】" class="layui-icon pointer margin-right-20" data-copy="{$command|default=''}"></b>
|
||||
<script>$('[data-queue-message]').load('{:sysuri("admin/api.queue/status")}');</script>
|
||||
<!--{/if}-->
|
||||
<b>任务统计:</b>待处理 <b class="color-text" data-extra="pre">{$total.pre|default=0}</b> 个任务,处理中 <b class="color-blue" data-extra="dos">{$total.dos|default=0}</b> 个任务,已完成 <b class="color-green" data-extra="oks">{$total.oks|default=0}</b> 个任务,已失败 <b class="color-red" data-extra="ers">{$total.ers|default=0}</b> 个任务。
|
||||
</div>
|
||||
<div class="think-box-shadow">
|
||||
{include file='queue/index_search'}
|
||||
<table id="QueueTable" data-line="2" data-url="{:sysuri()}" data-target-search="form.form-search"></table>
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
{block name='script'}
|
||||
<script>
|
||||
$(function () {
|
||||
$('#QueueTable').layTable({
|
||||
even: true, height: 'full',
|
||||
sort: {field: 'loops_time desc,id', type: 'desc'},
|
||||
// 扩展数据处理,需要返回原 items 数据
|
||||
filter: function (items, result) {
|
||||
return result && result.extra && $('[data-extra]').map(function () {
|
||||
this.innerHTML = result.extra[this.dataset.extra] || 0;
|
||||
}), items;
|
||||
},
|
||||
cols: [[
|
||||
{checkbox: true, fixed: 'left'},
|
||||
{
|
||||
field: 'id', title: '任务名称', width: '25%', sort: true, templet: function (d) {
|
||||
if (d.loops_time > 0) {
|
||||
d.one = '<span class="layui-badge think-bg-blue">循</span>';
|
||||
} else {
|
||||
d.one = '<span class="layui-badge think-bg-red">次</span>';
|
||||
}
|
||||
if (d.rscript === 1) {
|
||||
d.two = '<span class="layui-badge layui-bg-green">复</span>';
|
||||
} else {
|
||||
d.two = '<span class="layui-badge think-bg-violet">单</span>';
|
||||
}
|
||||
return laytpl('{{-d.one}}任务编号:<b>{{d.code}}</b><br>{{-d.two}}任务名称:{{d.title}}').render(d);
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'exec_time', title: '任务计划', width: '25%', templet: function (d) {
|
||||
d.html = '执行指令:' + d.command + '<br>计划执行:' + d.exec_time;
|
||||
if (d.loops_time > 0) {
|
||||
return d.html + ' ( 每 <b class="color-blue">' + d.loops_time + '</b> 秒 ) ';
|
||||
} else {
|
||||
return d.html + ' <span class="color-desc">( 单次任务 )</span> ';
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'loops_time', title: '执行状态', width: '30%', templet: function (d) {
|
||||
d.html = ([
|
||||
'<span class="pull-left layui-badge layui-badge-middle layui-bg-gray">未知</span>',
|
||||
'<span class="pull-left layui-badge layui-badge-middle layui-bg-black">等待</span>',
|
||||
'<span class="pull-left layui-badge layui-badge-middle layui-bg-blue">执行</span>',
|
||||
'<span class="pull-left layui-badge layui-badge-middle layui-bg-green">完成</span>',
|
||||
'<span class="pull-left layui-badge layui-badge-middle layui-bg-red">失败</span>',
|
||||
][d.status] || '') + '执行时间:';
|
||||
d.enter_time = d.enter_time || '', d.outer_time = d.outer_time || '0.0000';
|
||||
if (d.enter_time.length > 12) {
|
||||
d.html += d.enter_time.substring(12) + '<span class="color-desc"> ( 耗时 ' + d.outer_time + ' ) </span>';
|
||||
d.html += ' 已执行 <b class="color-blue">' + (d.attempts || 0) + '</b> 次';
|
||||
} else {
|
||||
d.html += '<span class="color-desc">任务未执行</span>'
|
||||
}
|
||||
return d.html + '<br>执行结果:<span class="color-blue">' + (d.exec_desc || '<span class="color-desc">未获取到执行结果</span>') + '</span>';
|
||||
}
|
||||
},
|
||||
{toolbar: '#toolbar', title: '操作面板', align: 'center', minWidth: 210, fixed: 'right'}
|
||||
]]
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="toolbar">
|
||||
|
||||
<!--{if auth('redo')}-->
|
||||
{{# if(d.status===4||d.status===3){ }}
|
||||
<a class="layui-btn layui-btn-sm" data-confirm="确定要重置该任务吗?" data-queue="{:url('redo')}?code={{d.code}}">重 置</a>
|
||||
{{# }else{ }}
|
||||
<a class="layui-btn layui-btn-sm layui-btn-disabled">重 置</a>
|
||||
{{# } }}
|
||||
<!--{/if}-->
|
||||
|
||||
<!--{if auth('remove')}-->
|
||||
<a class='layui-btn layui-btn-sm layui-btn-danger' data-confirm="确定要删除该任务吗?" data-action='{:url("remove")}' data-value="id#{{d.id}}">删 除</a>
|
||||
<!--{/if}-->
|
||||
|
||||
<a class='layui-btn layui-btn-sm layui-btn-normal' onclick="$.loadQueue('{{d.code}}',false,this)">日 志</a>
|
||||
</script>
|
||||
{/block}
|
@ -1,59 +0,0 @@
|
||||
<fieldset>
|
||||
<legend>条件搜索</legend>
|
||||
<form class="layui-form layui-form-pane form-search" action="{:sysuri()}" onsubmit="return false" method="get" autocomplete="off">
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">编号名称</label>
|
||||
<label class="layui-input-inline">
|
||||
<input name="title" value="{$get.title|default=''}" placeholder="请输入名称或编号" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">任务指令</label>
|
||||
<label class="layui-input-inline">
|
||||
<input name="command" value="{$get.command|default=''}" placeholder="请输入任务指令" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">任务状态</label>
|
||||
<label class="layui-input-inline">
|
||||
<select name="status" class="layui-select">
|
||||
<option value=''>-- 全部任务 --</option>
|
||||
{foreach ['1'=>'等待处理','2'=>'正在处理','3'=>'处理完成','4'=>'处理失败'] as $k=>$v}
|
||||
{if isset($get.status) and $get.status eq $k}
|
||||
<option selected value="{$k}">{$v}</option>
|
||||
{else}
|
||||
<option value="{$k}">{$v}</option>
|
||||
{/if}{/foreach}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">计划时间</label>
|
||||
<label class="layui-input-inline">
|
||||
<input data-date-range name="exec_time" value="{$get.exec_time|default=''}" placeholder="请选择计划时间" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline layui-hide">
|
||||
<label class="layui-form-label">执行时间</label>
|
||||
<label class="layui-input-inline">
|
||||
<input data-date-range name="enter_time" value="{$get.enter_time|default=''}" placeholder="请选择执行时间" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline layui-hide">
|
||||
<label class="layui-form-label">创建时间</label>
|
||||
<label class="layui-input-inline">
|
||||
<input data-date-range name="create_at" value="{$get.create_at|default=''}" placeholder="请选择创建时间" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<button class="layui-btn layui-btn-primary"><i class="layui-icon"></i> 搜 索</button>
|
||||
</div>
|
||||
</form>
|
||||
</fieldset>
|
@ -1,18 +0,0 @@
|
||||
<div class="layui-card">
|
||||
{block name='style'}{/block}
|
||||
{block name='header'}
|
||||
{notempty name='title'}
|
||||
<div class="layui-card-header">
|
||||
<span class="layui-icon font-s10 color-desc margin-right-5"></span>{$title|default=''}
|
||||
<div class="pull-right">{block name='button'}{/block}</div>
|
||||
</div>
|
||||
{/notempty}
|
||||
{/block}
|
||||
<div class="layui-card-line"></div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-card-table">
|
||||
{block name='content'}{/block}
|
||||
</div>
|
||||
</div>
|
||||
{block name='script'}{/block}
|
||||
</div>
|
@ -1,114 +0,0 @@
|
||||
<form action="{:sysuri()}" method="post" data-auto="true" class="layui-form layui-card" data-table-id="UserTable">
|
||||
<div class="layui-card-body padding-left-40">
|
||||
|
||||
<fieldset class="layui-bg-gray">
|
||||
<legend><b class="layui-badge think-bg-violet">用户账号</b></legend>
|
||||
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div class="layui-col-xs2 text-center padding-top-15">
|
||||
<input type="hidden" data-cut-width="500" data-cut-height="500" data-max-width="500" data-max-height="500" name="headimg" value="{$vo.headimg|default=''}">
|
||||
<script>$('[name=headimg]').uploadOneImage();</script>
|
||||
</div>
|
||||
<div class="layui-col-xs5">
|
||||
<label class="block relative">
|
||||
<span class="help-label"><b>登录账号</b>User Name</span>
|
||||
{if isset($vo) and isset($vo.username)}
|
||||
<input disabled value='{$vo.username|default=""}' required class="layui-input think-bg-gray">
|
||||
{else}
|
||||
<input name="username" value='{$vo.username|default=""}' required pattern="^.{4,}$" placeholder="请输入登录账号" class="layui-input">
|
||||
{/if}
|
||||
<span class="help-block">登录账号不能重复并且创建后不能再次修改哦。</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="layui-col-xs5">
|
||||
<label class="block relative">
|
||||
<span class="help-label"><b>用户名称</b>Nick Name</span>
|
||||
<input name="nickname" value='{$vo.nickname|default=""}' required placeholder="请输入用户名称" class="layui-input">
|
||||
<span class="help-block">用于区分用户数据的用户名称,请尽量不要重复。</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
|
||||
{if !empty($bases) || !empty($authorizes)}
|
||||
<fieldset class="layui-bg-gray">
|
||||
<legend><b class="layui-badge think-bg-violet">用户权限</b></legend>
|
||||
{if !empty($bases)}
|
||||
<div class="layui-form-item">
|
||||
<div class="help-label"><b>角色身份</b>Role Identity</div>
|
||||
<div class="layui-textarea help-checks">
|
||||
{foreach $bases as $base}
|
||||
<label class="think-checkbox">
|
||||
{if isset($vo.usertype) and $vo.usertype eq $base.code}
|
||||
<input type="radio" checked name="usertype" value="{$base.code}" lay-ignore>{$base.name}
|
||||
{else}
|
||||
<input type="radio" name="usertype" value="{$base.code}" lay-ignore>{$base.name}
|
||||
{/if}
|
||||
</label>
|
||||
{/foreach}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{if !empty($authorizes)}
|
||||
<div class="layui-form-item">
|
||||
<div class="help-label"><b>访问权限</b>Role Permission</div>
|
||||
<div class="layui-textarea help-checks">
|
||||
{if isset($vo.username) and $vo.username eq $superName}
|
||||
<span class="color-desc padding-left-5">超级用户拥所有访问权限,不需要配置权限。</span>
|
||||
{else}{foreach $authorizes as $authorize}
|
||||
<label class="think-checkbox">
|
||||
{if in_array($authorize.id, $vo.authorize)}
|
||||
<input type="checkbox" checked name="authorize[]" value="{$authorize.id}" lay-ignore>{$authorize.title}
|
||||
{else}
|
||||
<input type="checkbox" name="authorize[]" value="{$authorize.id}" lay-ignore>{$authorize.title}
|
||||
{/if}
|
||||
</label>
|
||||
{/foreach}{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</fieldset>
|
||||
{/if}
|
||||
|
||||
<fieldset class="layui-bg-gray">
|
||||
<legend><b class="layui-badge think-bg-violet">用户资料</b></legend>
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div class="layui-col-xs4">
|
||||
<label class="relative block">
|
||||
<span class="help-label"><b>联系邮箱</b>Contact Email</span>
|
||||
<input name="contact_mail" pattern="^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$" value='{$vo.contact_mail|default=""}' placeholder="请输入联系电子邮箱" class="layui-input">
|
||||
<span class="color-desc">可选,请填写用户常用的电子邮箱</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="layui-col-xs4">
|
||||
<label class="relative block">
|
||||
<span class="help-label"><b>联系手机</b>Contact Mobile</span>
|
||||
<input type="tel" maxlength="11" name="contact_phone" value='{$vo.contact_phone|default=""}' pattern="^1[3-9][0-9]{9}$" placeholder="请输入用户联系手机" class="layui-input">
|
||||
<span class="color-desc">可选,请填写用户常用的联系手机号</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="layui-col-xs4">
|
||||
<label class="relative block">
|
||||
<span class="help-label"><b>联系QQ</b>Contact QQ</span>
|
||||
<input name="contact_qq" pattern="^\d{6,}$" value='{$vo.contact_qq|default=""}' placeholder="请输入常用的联系QQ" class="layui-input">
|
||||
<span class="color-desc">可选,请填写用户常用的联系QQ号</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<label class="layui-form-item block relative margin-top-10">
|
||||
<span class="help-label"><b>用户描述</b>User Remark</span>
|
||||
<textarea placeholder="请输入用户描述" class="layui-textarea" name="describe">{$vo.describe|default=""}</textarea>
|
||||
</label>
|
||||
</fieldset>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
{notempty name='vo.id'}<input type='hidden' value='{$vo.id}' name='id'>{/notempty}
|
||||
|
||||
<div class="layui-form-item text-center">
|
||||
<button class="layui-btn" type='submit'>保存数据</button>
|
||||
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
|
||||
</div>
|
||||
</form>
|
@ -1,116 +0,0 @@
|
||||
{extend name='table'}
|
||||
|
||||
{block name="button"}
|
||||
{if isset($type) and $type eq 'index'}
|
||||
<!--{if auth("add")}-->
|
||||
<button data-modal='{:url("add")}' data-title="添加用户" class='layui-btn layui-btn-sm layui-btn-primary'>添加用户</button>
|
||||
<!--{/if}-->
|
||||
<!--{if auth("state")}-->
|
||||
<a data-confirm="确定要启用该用户吗?" data-table-id="UserTable" data-action="{:url('state')}" data-rule="id#{id};status#0" class='layui-btn layui-btn-sm layui-btn-primary'>批量禁用</a>
|
||||
<!--{/if}-->
|
||||
{else}
|
||||
<!--{if auth("state")}-->
|
||||
<a data-confirm="确定要恢复这些账号吗?" data-table-id="UserTable" data-action="{:url('state')}" data-rule="id#{id};status#1" class='layui-btn layui-btn-sm layui-btn-primary'>批量恢复</a>
|
||||
<!--{/if}-->
|
||||
<!--{if auth("remove")}-->
|
||||
<a data-confirm="确定永久删除这些账号吗?" data-table-id="UserTable" data-action='{:url("remove")}' data-rule="id#{id}" class='layui-btn layui-btn-sm layui-btn-primary'>批量删除</a>
|
||||
<!--{/if}-->
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="layui-tab layui-tab-card">
|
||||
<ul class="layui-tab-title">
|
||||
{foreach ['index'=>'系统用户','recycle'=>'回 收 站'] as $k=>$v}{if isset($type) and $type eq $k}
|
||||
<li data-open="{:url('index')}?type={$k}" class="layui-this">{$v}</li>
|
||||
{else}
|
||||
<li data-open="{:url('index')}?type={$k}">{$v}</li>
|
||||
{/if}{/foreach}
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
{include file='user/index_search'}
|
||||
<table id="UserTable" data-url="{:sysuri('index')}" data-target-search="form.form-search"></table>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(function () {
|
||||
$('#UserTable').layTable({
|
||||
even: true, height: 'full',
|
||||
sort: {field: 'sort desc,id', type: 'desc'},
|
||||
where: {type: '{$type|default="index"}'},
|
||||
cols: [[
|
||||
{checkbox: true, fixed: true},
|
||||
{field: 'sort', title: '排序权重', width: 100, align: 'center', sort: true, templet: '#SortInputTpl'},
|
||||
{
|
||||
field: 'headimg', title: '头像', width: 60, align: 'center', templet: function (d) {
|
||||
if (!d.headimg) return '-';
|
||||
return layui.laytpl('<div class="headimg headimg-ss shadow-inset margin-0" data-tips-image data-tips-hover data-lazy-src="{{d.headimg}}"></div>').render(d);
|
||||
}
|
||||
},
|
||||
{field: 'username', title: '登录账号', minWidth: 100, align: 'center', templet: '<div>{{d.username||"-"}}</div>'},
|
||||
{field: 'nickname', title: '用户名称', minWidth: 100, align: 'center', templet: '<div>{{d.nickname||"-"}}</div>'},
|
||||
/* {notempty name='bases'} */
|
||||
{
|
||||
field: 'usertype', title: '角色身份', minWidth: 100, align: 'center', templet: function (d) {
|
||||
d.userinfo = d.userinfo || {};
|
||||
return d.userinfo.code ? (d.userinfo.name + ' ( ' + d.userinfo.code + ' ) ') : '-';
|
||||
}
|
||||
},
|
||||
/* {/notempty} */
|
||||
// {field: 'contact_mail', title: '联系邮箱', minWidth: 80, templet: '<div>{{d.contact_mail||"-"}}</div>'},
|
||||
// {field: 'contact_phone', title: '联系电话', minWidth: 80, templet: '<div>{{d.contact_phone||"-"}}</div>'},
|
||||
{field: 'status', title: '账号状态', align: 'center', minWidth: 110, templet: '#StatusSwitchTpl'},
|
||||
{field: 'login_num', title: '登录次数', align: 'center', minWidth: 100, sort: true},
|
||||
{field: 'login_at', title: '最后登录', align: 'center', minWidth: 170, sort: true},
|
||||
{field: 'create_at', title: '创建时间', align: 'center', minWidth: 170, sort: true},
|
||||
{toolbar: '#toolbar', title: '操作面板', align: 'center', minWidth: 150, fixed: 'right'}
|
||||
]]
|
||||
});
|
||||
|
||||
// 数据状态切换操作
|
||||
layui.form.on('switch(StatusSwitch)', function (obj) {
|
||||
var data = {id: obj.value, status: obj.elem.checked > 0 ? 1 : 0};
|
||||
$.form.load("{:url('state')}", data, 'post', function (ret) {
|
||||
if (ret.code < 1) $.msg.error(ret.info, 3, function () {
|
||||
$('#UserTable').trigger('reload');
|
||||
}); else {
|
||||
$('#UserTable').trigger('reload')
|
||||
}
|
||||
return false;
|
||||
}, false);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- 数据状态切换模板 -->
|
||||
<script type="text/html" id="StatusSwitchTpl">
|
||||
<!--{if auth("state")}-->
|
||||
<input type="checkbox" value="{{d.id}}" lay-skin="switch" lay-text="已激活|已禁用" lay-filter="StatusSwitch" {{-d.status>0?'checked':''}}>
|
||||
<!--{else}-->
|
||||
{{-d.status ? '<b class="color-green">已启用</b>' : '<b class="color-red">已禁用</b>'}}
|
||||
<!--{/if}-->
|
||||
</script>
|
||||
|
||||
<!-- 列表排序权重模板 -->
|
||||
<script type="text/html" id="SortInputTpl">
|
||||
<input type="number" min="0" data-blur-number="0" data-action-blur="{:sysuri()}" data-value="id#{{d.id}};action#sort;sort#{value}" data-loading="false" value="{{d.sort}}" class="layui-input text-center">
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="toolbar">
|
||||
{if isset($type) and $type eq 'index'}
|
||||
<!--{if auth("edit")}-->
|
||||
<a class="layui-btn layui-btn-sm" data-event-dbclick data-title="编辑用户" data-modal='{:url("edit")}?id={{d.id}}'>编 辑</a>
|
||||
<!--{/if}-->
|
||||
<!--{if auth("pass")}-->
|
||||
<a class="layui-btn layui-btn-sm layui-btn-normal" data-title="设置密码" data-modal='{:url("pass")}?id={{d.id}}'>密 码</a>
|
||||
<!--{/if}-->
|
||||
{else}
|
||||
<!--{if auth("edit")}-->
|
||||
<a class="layui-btn layui-btn-sm" data-event-dbclick data-title="编辑用户" data-modal='{:url("edit")}?id={{d.id}}'>编 辑</a>
|
||||
<!--{/if}-->
|
||||
<!--{if auth("remove")}-->
|
||||
<a class="layui-btn layui-btn-sm layui-btn-danger" data-confirm="确定要永久删除此账号吗?" data-action="{:url('remove')}" data-value="id#{{d.id}}">删 除</a>
|
||||
<!--{/if}-->
|
||||
{/if}
|
||||
</script>
|
||||
{/block}
|
@ -1,58 +0,0 @@
|
||||
<form class="layui-form layui-form-pane form-search" action="{:sysuri()}" onsubmit="return false" method="get" autocomplete="off">
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">账号名称</label>
|
||||
<label class="layui-input-inline">
|
||||
<input name="username" value="{$get.username|default=''}" placeholder="请输入账号或名称" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!--{notempty name='bases'}-->
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">角色身份</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="usertype" lay-search class="layui-select">
|
||||
<option value=''>-- 全部 --</option>
|
||||
{foreach $bases as $base}{if $base.code eq input('get.usertype')}
|
||||
<option selected value="{$base.code|default=''}">{$base.name|default=''} ( {$base.code|default=''} )</option>
|
||||
{else}
|
||||
<option value="{$base.code|default=''}">{$base.name|default=''} ( {$base.code|default=''} )</option>
|
||||
{/if}{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<!--{/notempty}-->
|
||||
|
||||
<div class="layui-form-item layui-inline layui-hide">
|
||||
<label class="layui-form-label">联系手机</label>
|
||||
<label class="layui-input-inline">
|
||||
<input name="phone" value="{$get.phone|default=''}" placeholder="请输入联系手机" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline layui-hide">
|
||||
<label class="layui-form-label">联系邮箱</label>
|
||||
<label class="layui-input-inline">
|
||||
<input name="mail" value="{$get.mail|default=''}" placeholder="请输入联系邮箱" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">最后登录</label>
|
||||
<div class="layui-input-inline">
|
||||
<input data-date-range name="login_at" value="{$get.login_at|default=''}" placeholder="请选择登录时间" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">创建时间</label>
|
||||
<div class="layui-input-inline">
|
||||
<input data-date-range name="create_at" value="{$get.create_at|default=''}" placeholder="请选择创建时间" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<input type="hidden" name="type" value="{$type|default='index'}">
|
||||
<button class="layui-btn layui-btn-primary"><i class="layui-icon"></i> 搜 索</button>
|
||||
</div>
|
||||
</form>
|
@ -1,50 +0,0 @@
|
||||
<form action="{:sysuri()}" method="post" data-auto="true" class="layui-form layui-card" data-table-id="UserTable">
|
||||
<div class="layui-card-body padding-left-40">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="relative block">
|
||||
<span class="help-label"><b>登录用户账号</b>Username</span>
|
||||
<!--{if isset($vo) and isset($vo.username)}-->
|
||||
<input disabled value='{$vo.username|default=""}' class="layui-input think-bg-gray">
|
||||
<!--{else}-->
|
||||
<input name="username" value='{$vo.username|default=""}' required pattern="^.{4,}$" placeholder="请输入4位及以上字符登录用户账号" class="layui-input">
|
||||
<!--{/if}-->
|
||||
</label>
|
||||
<p class="help-block">登录用户账号创建后,不允许再次修改。</p>
|
||||
</div>
|
||||
|
||||
<!--{if $verify}-->
|
||||
<div class="layui-form-item">
|
||||
<label class="relative block">
|
||||
<span class="help-label"><b>旧的登录密码</b>Old Password</span>
|
||||
<input type="password" autofocus name="oldpassword" value='' pattern="^\S{1,}$" required placeholder="请输入旧的登录密码" class="layui-input">
|
||||
</label>
|
||||
<p class="color-desc">请输入旧密码来验证修改权限,旧密码不限制格式。</p>
|
||||
</div>
|
||||
<!--{/if}-->
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="relative block">
|
||||
<span class="help-label"><b>新的登录密码</b>New Password</span>
|
||||
<input type="password" name="password" maxlength="32" pattern="^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,32}$" required placeholder="请输入新的登录密码" class="layui-input">
|
||||
</label>
|
||||
<p class="color-desc">密码必须包含大小写字母、数字、符号的任意两者组合。</p>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="relative block">
|
||||
<span class="help-label"><b>重复登录密码</b>Repeat Password</span>
|
||||
<input type="password" name="repassword" maxlength="32" pattern="^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,32}$" required placeholder="请重复输入登录密码" class="layui-input">
|
||||
</label>
|
||||
<p class="color-desc">密码必须包含大小写字母、数字、符号的任意两者组合。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
{notempty name='vo.id'}<input type='hidden' value='{$vo.id}' name='id'>{/notempty}
|
||||
|
||||
<div class="layui-form-item text-center">
|
||||
<button class="layui-btn" type='submit'>保存数据</button>
|
||||
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
|
||||
</div>
|
||||
</form>
|
@ -1,81 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\command;
|
||||
|
||||
use app\data\model\ShopOrder;
|
||||
use app\data\model\ShopOrderItem;
|
||||
use app\data\service\OrderService;
|
||||
use think\admin\Command;
|
||||
use think\admin\Exception;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 商城订单自动清理
|
||||
* Class OrderClean
|
||||
* @package app\data\command
|
||||
*/
|
||||
class OrderClean extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('xdata:OrderClean');
|
||||
$this->setDescription('批量清理商城订单数据');
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务指令执行
|
||||
* @param Input $input
|
||||
* @param Output $output
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$this->_autoCancelOrder();
|
||||
$this->_autoRemoveOrder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动取消30分钟未支付的订单
|
||||
* @throws Exception
|
||||
*/
|
||||
private function _autoCancelOrder()
|
||||
{
|
||||
try {
|
||||
$map = [['status', '<', 3], ['payment_status', '=', 0]];
|
||||
$map[] = ['create_at', '<', date('Y-m-d H:i:s', strtotime('-30 minutes'))];
|
||||
[$count, $total] = [0, ($result = ShopOrder::mk()->where($map)->select())->count()];
|
||||
$result->map(function (Model $item) use ($total, &$count) {
|
||||
$this->queue->message($total, ++$count, "开始取消未支付的订单 {$item['order_no']}");
|
||||
$item->save(['status' => 0, 'cancel_status' => 1, 'cancel_datetime' => date('Y-m-d H:i:s'), 'cancel_remark' => '自动取消30分钟未完成支付']);
|
||||
OrderService::stock($item['order_no']);
|
||||
$this->queue->message($total, $count, "完成取消未支付的订单 {$item['order_no']}", 1);
|
||||
});
|
||||
} catch (\Exception $exception) {
|
||||
$this->queue->error($exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动清理已经取消的订单
|
||||
* @throws Exception
|
||||
*/
|
||||
private function _autoRemoveOrder()
|
||||
{
|
||||
try {
|
||||
$map = [['status', '=', 0], ['payment_status', '=', 0]];
|
||||
$map[] = ['create_at', '<', date('Y-m-d H:i:s', strtotime('-3 days'))];
|
||||
[$count, $total] = [0, ($result = ShopOrder::mk()->where($map)->select())->count()];
|
||||
$result->map(function (Model $item) use ($total, &$count) {
|
||||
$this->queue->message($total, ++$count, "开始清理已取消的订单 {$item['order_no']}");
|
||||
ShopOrder::mk()->where(['order_no' => $item['order_no']])->delete();
|
||||
ShopOrderItem::mk()->where(['order_no' => $item['order_no']])->delete();
|
||||
$this->queue->message($total, $count, "完成清理已取消的订单 {$item['order_no']}", 1);
|
||||
});
|
||||
} catch (\Exception $exception) {
|
||||
$this->queue->error($exception->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\command;
|
||||
|
||||
use app\data\model\DataUser;
|
||||
use app\data\service\UserUpgradeService;
|
||||
use think\admin\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Argument;
|
||||
use think\console\Output;
|
||||
|
||||
/**
|
||||
* 更新用户代理关系
|
||||
* Class UserAgent
|
||||
* @package app\data\command
|
||||
*/
|
||||
class UserAgent extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('xdata:UserAgent');
|
||||
$this->addArgument('uuid', Argument::OPTIONAL, '目标用户', '');
|
||||
$this->addArgument('puid', Argument::OPTIONAL, '上级代理', '');
|
||||
$this->setDescription('重新设置用户上级代理, 参数:UUID PUID');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Input $input
|
||||
* @param Output $output
|
||||
* @return void
|
||||
* @throws \think\admin\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
[$uuid, $puid] = [$input->getArgument('uuid'), $input->getArgument('puid')];
|
||||
if (empty($uuid)) $this->setQueueError("参数UID无效,请传入正确的参数!");
|
||||
if (empty($puid)) $this->setQueueError("参数PID无效,请传入正确的参数!");
|
||||
|
||||
// 检查当前用户资料
|
||||
$user = DataUser::mk()->where(['id' => $uuid])->find();
|
||||
if (empty($user)) $this->setQueueError("读取用户数据失败!");
|
||||
|
||||
// 检查上级代理用户
|
||||
$parant = DataUser::mk()->where(['id' => $puid])->find();
|
||||
if (empty($parant)) $this->setQueueError('读取代理数据失败!');
|
||||
|
||||
// 检查异常关系处理
|
||||
if (stripos($parant['path'], "-{$user['id']}-")) {
|
||||
$this->setQueueError('不能把下级设置为代理!');
|
||||
}
|
||||
|
||||
// 更新自己的代理关系
|
||||
$path1 = rtrim($parant['path'] ?: '-', '-') . "-{$parant['id']}-";
|
||||
DataUser::mk()->where(['id' => $user['id']])->update([
|
||||
'path' => $path1, 'layer' => substr_count($path1, '-'),
|
||||
'pid0' => $parant['id'], 'pid1' => $parant['id'], 'pid2' => $parant['pid1'],
|
||||
]);
|
||||
UserUpgradeService::upgrade($user['id'], true);
|
||||
$this->setQueueMessage(1, 1, "更新指定用户[{$user['id']}]代理绑定成功!");
|
||||
|
||||
// 更新下级的代理关系
|
||||
$path2 = "{$user['path']}{$user['id']}-";
|
||||
[$total, $count] = [DataUser::mk()->whereLike('path', "{$path2}%")->count(), 0];
|
||||
foreach (DataUser::mk()->whereLike('path', "{$path2}%")->order('layer desc')->select() as $vo) {
|
||||
$this->setQueueMessage($total, ++$count, "开始更新下级用户[{$vo['id']}]代理绑定!");
|
||||
// 更新下级用户代理数据
|
||||
$path3 = preg_replace("#^{$path2}#", "{$path1}{$user['id']}-", $vo['path']);
|
||||
$attrs = array_reverse(str2arr($path3, '-'));
|
||||
DataUser::mk()->where(['id' => $vo['id']])->update([
|
||||
'path' => $path3, 'layer' => substr_count($path3, '-'),
|
||||
'pid0' => $attrs[0] ?? 0, 'pid1' => $attrs[0] ?? 0, 'pid2' => $attrs[1] ?? 0,
|
||||
]);
|
||||
$this->setQueueMessage($total, $count, "完成更新下级用户[{$vo['id']}]代理绑定!", 1);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\command;
|
||||
|
||||
use app\data\model\DataUser;
|
||||
use app\data\service\UserBalanceService;
|
||||
use app\data\service\UserRebateService;
|
||||
use think\admin\Command;
|
||||
use think\admin\Exception;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
|
||||
/**
|
||||
* 用户余额及返利重算处理
|
||||
* Class UserBalance
|
||||
* @package app\data\command
|
||||
*/
|
||||
class UserAmount extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('xdata:UserAmount');
|
||||
$this->setDescription('批量重新计算余额返利');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Input $input
|
||||
* @param Output $output
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
[$total, $count, $error] = [DataUser::mk()->count(), 0, 0];
|
||||
foreach (DataUser::mk()->field('id')->cursor() as $user) try {
|
||||
$this->queue->message($total, ++$count, "刷新用户 [{$user['id']}] 余额及返利开始");
|
||||
UserRebateService::amount($user['id']) && UserBalanceService::amount($user['id']);
|
||||
$this->queue->message($total, $count, "刷新用户 [{$user['id']}] 余额及返利完成", 1);
|
||||
} catch (\Exception $exception) {
|
||||
$error++;
|
||||
$this->queue->message($total, $count, "刷新用户 [{$user['id']}] 余额及返利失败, {$exception->getMessage()}", 1);
|
||||
}
|
||||
$this->setQueueSuccess("此次共处理 {$total} 个刷新操作, 其中有 {$error} 个刷新失败。");
|
||||
}
|
||||
}
|
@ -1,262 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\command;
|
||||
|
||||
use app\data\model\DataUser;
|
||||
use app\data\model\DataUserTransfer;
|
||||
use app\data\service\UserRebateService;
|
||||
use think\admin\Command;
|
||||
use think\admin\Exception;
|
||||
use think\admin\storage\LocalStorage;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
use WePay\Transfers;
|
||||
use WePay\TransfersBank;
|
||||
|
||||
/**
|
||||
* 用户提现处理
|
||||
* Class UserTransfer
|
||||
* @package app\data\command
|
||||
*/
|
||||
class UserTransfer extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('xdata:UserTransfer');
|
||||
$this->setDescription('批量执行线上打款操作');
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行微信提现操作
|
||||
* @param Input $input
|
||||
* @param Output $output
|
||||
* @return void
|
||||
* @throws \think\admin\Exception
|
||||
*/
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$map = [['type', 'in', ['wechat_banks', 'wechat_wallet']], ['status', 'in', [3, 4]]];
|
||||
[$total, $count, $error] = [DataUserTransfer::mk()->where($map)->count(), 0, 0];
|
||||
foreach (DataUserTransfer::mk()->where($map)->cursor() as $vo) try {
|
||||
$this->queue->message($total, ++$count, "开始处理订单 {$vo['code']} 提现");
|
||||
if ($vo['status'] === 3) {
|
||||
$this->queue->message($total, $count, "尝试处理订单 {$vo['code']} 打款", 1);
|
||||
if ($vo['type'] === 'wechat_banks') {
|
||||
[$config, $result] = $this->createTransferBank($vo);
|
||||
} else {
|
||||
[$config, $result] = $this->createTransferWallet($vo);
|
||||
}
|
||||
if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
|
||||
DataUserTransfer::mk()->where(['code' => $vo['code']])->update([
|
||||
'status' => 4,
|
||||
'appid' => $config['appid'],
|
||||
'openid' => $config['openid'],
|
||||
'trade_no' => $result['partner_trade_no'],
|
||||
'trade_time' => $result['payment_time'] ?? date('Y-m-d H:i:s'),
|
||||
'change_time' => date('Y-m-d H:i:s'),
|
||||
'change_desc' => '创建微信提现成功',
|
||||
]);
|
||||
} else {
|
||||
DataUserTransfer::mk()->where(['code' => $vo['code']])->update([
|
||||
'change_time' => date('Y-m-d H:i:s'), 'change_desc' => $result['err_code_des'] ?? '线上提现失败',
|
||||
]);
|
||||
}
|
||||
} elseif ($vo['status'] === 4) {
|
||||
$this->queue->message($total, $count, "刷新提现订单 {$vo['code']} 状态", 1);
|
||||
if ($vo['type'] === 'wechat_banks') {
|
||||
$this->queryTransferBank($vo);
|
||||
} else {
|
||||
$this->queryTransferWallet($vo);
|
||||
}
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
$error++;
|
||||
$this->queue->message($total, $count, "处理提现订单 {$vo['code']} 失败, {$exception->getMessage()}", 1);
|
||||
DataUserTransfer::mk()->where(['code' => $vo['code']])->update([
|
||||
'change_time' => date('Y-m-d H:i:s'), 'change_desc' => $exception->getMessage(),
|
||||
]);
|
||||
}
|
||||
$this->setQueueSuccess("此次共处理 {$total} 笔提现操作, 其中有 {$error} 笔处理失败。");
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试提现转账到银行卡
|
||||
* @param array $item
|
||||
* @return array [config, result]
|
||||
* @throws \WeChat\Exceptions\InvalidDecryptException
|
||||
* @throws \WeChat\Exceptions\InvalidResponseException
|
||||
* @throws \WeChat\Exceptions\LocalCacheException
|
||||
* @throws \think\admin\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function createTransferBank(array $item): array
|
||||
{
|
||||
$config = $this->getConfig($item['uuid']);
|
||||
return [$config, TransfersBank::instance($config)->create([
|
||||
'partner_trade_no' => $item['code'],
|
||||
'enc_bank_no' => $item['bank_code'],
|
||||
'enc_true_name' => $item['bank_user'],
|
||||
'bank_code' => $item['bank_wseq'],
|
||||
'amount' => intval($item['amount'] - $item['charge_amount']) * 100,
|
||||
'desc' => '微信银行卡提现',
|
||||
])];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信提现参数
|
||||
* @param int $uuid
|
||||
* @return array
|
||||
* @throws \think\admin\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function getConfig(int $uuid): array
|
||||
{
|
||||
$data = sysdata('TransferWxpay');
|
||||
if (empty($data)) throw new Exception('未配置微信提现商户');
|
||||
// 商户证书文件处理
|
||||
$local = LocalStorage::instance();
|
||||
if (!$local->has($file1 = "{$data['wechat_mch_id']}_key.pem", true)) {
|
||||
$local->set($file1, $data['wechat_mch_key_text'], true);
|
||||
}
|
||||
if (!$local->has($file2 = "{$data['wechat_mch_id']}_cert.pem", true)) {
|
||||
$local->set($file2, $data['wechat_mch_cert_text'], true);
|
||||
}
|
||||
// 获取用户支付信息
|
||||
$result = $this->getWechatInfo($uuid, $data['wechat_type']);
|
||||
if (empty($result)) throw new Exception('无法读取打款数据');
|
||||
return [
|
||||
'appid' => $result[0],
|
||||
'openid' => $result[1],
|
||||
'mch_id' => $data['wechat_mch_id'],
|
||||
'mch_key' => $data['wechat_mch_key'],
|
||||
'ssl_key' => $local->path($file1, true),
|
||||
'ssl_cer' => $local->path($file2, true),
|
||||
'cache_path' => $this->app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR . 'wechat',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据配置获取用户OPENID
|
||||
* @param int $uuid
|
||||
* @param string $type
|
||||
* @return mixed|null
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function getWechatInfo(int $uuid, string $type): ?array
|
||||
{
|
||||
$user = DataUser::mk()->where(['id' => $uuid])->find();
|
||||
if (empty($user)) return null;
|
||||
$appid1 = sysconf('data.wxapp_appid');
|
||||
if (strtolower(sysconf('wechat.type')) === 'api') {
|
||||
$appid2 = sysconf('wechat.appid');
|
||||
} else {
|
||||
$appid2 = sysconf('wechat.thr_appid');
|
||||
}
|
||||
if ($type === 'normal') {
|
||||
if (!empty($user['openid1'])) return [$appid1, $user['openid1']];
|
||||
if (!empty($user['openid2'])) return [$appid2, $user['openid2']];
|
||||
}
|
||||
if ($type === 'wxapp' && !empty($user['openid1'])) {
|
||||
return [$appid1, $user['openid1']];
|
||||
}
|
||||
if ($type === 'wechat' && !empty($user['openid2'])) {
|
||||
return [$appid2, $user['openid2']];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试提现转账到微信钱包
|
||||
* @param array $item
|
||||
* @return array [config, result]
|
||||
* @throws \WeChat\Exceptions\InvalidResponseException
|
||||
* @throws \WeChat\Exceptions\LocalCacheException
|
||||
* @throws \think\admin\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function createTransferWallet(array $item): array
|
||||
{
|
||||
$config = $this->getConfig($item['uuid']);
|
||||
return [$config, Transfers::instance($config)->create([
|
||||
'openid' => $config['openid'],
|
||||
'amount' => intval($item['amount'] - $item['charge_amount']) * 100,
|
||||
'partner_trade_no' => $item['code'],
|
||||
'spbill_create_ip' => '127.0.0.1',
|
||||
'check_name' => 'NO_CHECK',
|
||||
'desc' => '微信余额提现',
|
||||
])];
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询更新提现打款状态
|
||||
* @param array $item
|
||||
* @throws \WeChat\Exceptions\InvalidResponseException
|
||||
* @throws \WeChat\Exceptions\LocalCacheException
|
||||
* @throws \think\admin\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function queryTransferBank(array $item)
|
||||
{
|
||||
$config = $this->getConfig($item['uuid']);
|
||||
[$config['appid'], $config['openid']] = [$item['appid'], $item['openid']];
|
||||
$result = TransfersBank::instance($config)->query($item['trade_no']);
|
||||
if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
|
||||
if ($result['status'] === 'SUCCESS') {
|
||||
DataUserTransfer::mk()->where(['code' => $item['code']])->update([
|
||||
'status' => 5,
|
||||
'appid' => $config['appid'],
|
||||
'openid' => $config['openid'],
|
||||
'trade_time' => $result['pay_succ_time'] ?: date('Y-m-d H:i:s'),
|
||||
'change_time' => date('Y-m-d H:i:s'),
|
||||
'change_desc' => '微信提现打款成功',
|
||||
]);
|
||||
}
|
||||
if (in_array($result['status'], ['FAILED', 'BANK_FAIL'])) {
|
||||
DataUserTransfer::mk()->where(['code' => $item['code']])->update([
|
||||
'status' => 0,
|
||||
'change_time' => date('Y-m-d H:i:s'),
|
||||
'change_desc' => '微信提现打款失败',
|
||||
]);
|
||||
// 刷新用户可提现余额
|
||||
UserRebateService::amount($item['uuid']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询更新提现打款状态
|
||||
* @param array $item
|
||||
* @throws \WeChat\Exceptions\InvalidResponseException
|
||||
* @throws \WeChat\Exceptions\LocalCacheException
|
||||
* @throws \think\admin\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function queryTransferWallet(array $item)
|
||||
{
|
||||
$config = $this->getConfig($item['uuid']);
|
||||
[$config['appid'], $config['openid']] = [$item['appid'], $item['openid']];
|
||||
$result = Transfers::instance($config)->query($item['trade_no']);
|
||||
if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
|
||||
DataUserTransfer::mk()->where(['code' => $item['code']])->update([
|
||||
'status' => 5,
|
||||
'appid' => $config['appid'],
|
||||
'openid' => $config['openid'],
|
||||
'trade_time' => $result['payment_time'],
|
||||
'change_time' => date('Y-m-d H:i:s'),
|
||||
'change_desc' => '微信提现打款成功',
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\command;
|
||||
|
||||
use app\data\model\DataUser;
|
||||
use app\data\service\UserUpgradeService;
|
||||
use think\admin\Command;
|
||||
use think\admin\Exception;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
|
||||
/**
|
||||
* 用户等级重算处理
|
||||
* Class UserLevel
|
||||
* @package app\data\command
|
||||
*/
|
||||
class UserUpgrade extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('xdata:UserUpgrade');
|
||||
$this->setDescription('批量重新计算用户等级');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Input $input
|
||||
* @param Output $output
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
try {
|
||||
[$total, $count] = [DataUser::mk()->count(), 0];
|
||||
foreach (DataUser::mk()->field('id')->cursor() as $user) {
|
||||
$this->queue->message($total, ++$count, "正在计算用户 [{$user['id']}] 的等级");
|
||||
UserUpgradeService::upgrade($user['id']);
|
||||
$this->queue->message($total, $count, "完成计算用户 [{$user['id']}] 的等级", 1);
|
||||
}
|
||||
$this->setQueueSuccess("此次共重新计算 {$total} 个用户等级。");
|
||||
} catch (Exception $exception) {
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
$this->setQueueError($exception->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\api;
|
||||
|
||||
use app\data\service\UserAdminService;
|
||||
use app\data\service\UserTokenService;
|
||||
use think\admin\Controller;
|
||||
use think\exception\HttpResponseException;
|
||||
|
||||
/**
|
||||
* 接口授权认证基类
|
||||
* Class Auth
|
||||
* @package app\data\controller\api
|
||||
*/
|
||||
abstract class Auth extends Controller
|
||||
{
|
||||
/**
|
||||
* 当前接口请求终端类型
|
||||
* >>>>>>>>>>>>>>>>>>>>>>
|
||||
* >>> api-name 接口类型
|
||||
* >>> api-token 接口认证
|
||||
* >>>>>>>>>>>>>>>>>>>>>>
|
||||
* --- 手机浏览器访问 wap
|
||||
* --- 电脑浏览器访问 web
|
||||
* --- 微信小程序访问 wxapp
|
||||
* --- 微信服务号访问 wechat
|
||||
* --- 苹果应用接口访问 isoapp
|
||||
* --- 安卓应用接口访问 android
|
||||
* @var string
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* 当前用户编号
|
||||
* @var integer
|
||||
*/
|
||||
protected $uuid;
|
||||
|
||||
/**
|
||||
* 当前用户数据
|
||||
* @var array
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* 控制器初始化
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
// 检查接口类型
|
||||
$this->type = $this->request->header('api-name');
|
||||
if (empty($this->type)) $this->error("接口类型异常!");
|
||||
if (!isset(UserAdminService::TYPES[$this->type])) {
|
||||
$this->error("接口类型[{$this->type}]未定义!");
|
||||
}
|
||||
// 读取用户数据
|
||||
$this->user = $this->getUser();
|
||||
$this->uuid = $this->user['id'] ?? '';
|
||||
if (empty($this->uuid)) {
|
||||
$this->error('用户登录失败!', '{-null-}', 401);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户数据
|
||||
* @return array
|
||||
*/
|
||||
protected function getUser(): array
|
||||
{
|
||||
try {
|
||||
if (empty($this->uuid)) {
|
||||
$token = $this->request->header('api-token');
|
||||
if (empty($token)) $this->error('登录认证不能为空!');
|
||||
[$state, $info, $this->uuid] = UserTokenService::check($this->type, $token);
|
||||
if (empty($state)) $this->error($info, '{-null-}', 401);
|
||||
}
|
||||
return UserAdminService::get($this->uuid, $this->type);
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
trace_file($exception);
|
||||
$this->error($exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示用户禁用提示
|
||||
*/
|
||||
protected function checkUserStatus()
|
||||
{
|
||||
if (empty($this->user['status'])) {
|
||||
$this->error('账户已被冻结!');
|
||||
}
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\api;
|
||||
|
||||
use app\data\model\BaseUserMessage;
|
||||
use think\admin\Controller;
|
||||
use think\admin\helper\QueryHelper;
|
||||
use think\admin\model\SystemBase;
|
||||
|
||||
/**
|
||||
* 基础数据接口
|
||||
* Class Data
|
||||
* @package app\data\controller\api
|
||||
*/
|
||||
class Data extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* 获取指定数据
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
$data = $this->_vali(['name.require' => '数据名称不能为空!']);
|
||||
$extra = ['about', 'slider', 'agreement', 'cropper']; // 其他数据
|
||||
if (in_array($data['name'], $extra) || isset(SystemBase::items('页面内容')[$data['name']])) {
|
||||
$this->success('获取数据对象', sysdata($data['name']));
|
||||
} else {
|
||||
$this->error('获取数据失败', []);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片内容数据
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getSlider()
|
||||
{
|
||||
$this->keys = input('keys', '首页图片');
|
||||
if (isset(SystemBase::items('图片内容')[$this->keys])) {
|
||||
$this->success('获取图片内容', sysdata($this->keys));
|
||||
} else {
|
||||
$this->error('获取图片失败', []);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统通知数据
|
||||
*/
|
||||
public function getNotify()
|
||||
{
|
||||
BaseUserMessage::mQuery(null, function (QueryHelper $query) {
|
||||
if (($id = input('id')) > 0) {
|
||||
BaseUserMessage::mk()->where(['id' => $id])->inc('num_read')->update([]);
|
||||
}
|
||||
$query->equal('id')->where(['status' => 1, 'deleted' => 0]);
|
||||
$this->success('获取系统通知', $query->order('sort desc,id desc')->page(true, false, false, 20));
|
||||
});
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\api;
|
||||
|
||||
use app\data\model\ShopGoods;
|
||||
use app\data\model\ShopGoodsCate;
|
||||
use app\data\model\ShopGoodsMark;
|
||||
use app\data\service\ExpressService;
|
||||
use app\data\service\GoodsService;
|
||||
use think\admin\Controller;
|
||||
|
||||
/**
|
||||
* 商品数据接口
|
||||
* Class Goods
|
||||
* @package app\data\controller\api
|
||||
*/
|
||||
class Goods extends Controller
|
||||
{
|
||||
/**
|
||||
* 获取分类数据
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getCate()
|
||||
{
|
||||
$this->success('获取分类成功', ShopGoodsCate::treeData());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取标签数据
|
||||
*/
|
||||
public function getMark()
|
||||
{
|
||||
$this->success('获取标签成功', ShopGoodsMark::items());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品数据
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getGoods()
|
||||
{
|
||||
// 更新访问统计
|
||||
$map = $this->_vali(['code.default' => '']);
|
||||
if ($map['code']) ShopGoods::mk()->where($map)->inc('num_read')->update([]);
|
||||
// 商品数据处理
|
||||
$query = ShopGoods::mQuery()->like('name,marks,cateids,payment')->equal('code,vip_entry');
|
||||
$result = $query->where(['deleted' => 0, 'status' => 1])->order('sort desc,id desc')->page(true, false, false, 10);
|
||||
if (count($result['list']) > 0) GoodsService::bindData($result['list']);
|
||||
$this->success('获取商品数据', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配送区域
|
||||
*/
|
||||
public function getRegion()
|
||||
{
|
||||
$this->success('获取区域成功', ExpressService::region(3, 1));
|
||||
}
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\api;
|
||||
|
||||
use app\data\model\DataUser;
|
||||
use app\data\service\MessageService;
|
||||
use app\data\service\UserAdminService;
|
||||
use think\admin\Controller;
|
||||
|
||||
/**
|
||||
* 用户登录注册接口
|
||||
* Class Login
|
||||
* @package app\data\controller\api
|
||||
*/
|
||||
class Login extends Controller
|
||||
{
|
||||
/**
|
||||
* 接口认证类型
|
||||
* @var string
|
||||
*/
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* 控制器初始化
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
// 接收接口类型
|
||||
$this->type = $this->request->request('api');
|
||||
$this->type = $this->type ?: $this->request->header('api-name');
|
||||
$this->type = $this->type ?: $this->request->header('api-type');
|
||||
$this->type = $this->type ?: UserAdminService::API_TYPE_WAP;
|
||||
if (empty(UserAdminService::TYPES[$this->type])) {
|
||||
$this->error("接口支付[{$this->type}]未定义规则!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登录接口
|
||||
* @throws \think\admin\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function in()
|
||||
{
|
||||
$data = $this->_vali([
|
||||
'phone.mobile' => '手机号码格式错误!',
|
||||
'phone.require' => '手机号码不能为空!',
|
||||
'password.require' => '登录密码不能为空!',
|
||||
]);
|
||||
$map = ['deleted' => 0, 'phone' => $data['phone']];
|
||||
$user = DataUser::mk()->where($map)->findOrEmpty();
|
||||
if ($user->isEmpty()) $this->error('该手机号还没有注册哦!');
|
||||
if (empty($user['status'])) $this->error('该用户账号状态异常!');
|
||||
if (md5($data['password']) === $user['password']) {
|
||||
$this->success('手机登录成功!', UserAdminService::set($map, [], $this->type, true));
|
||||
} else {
|
||||
$this->error('账号登录失败,请稍候再试!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户统一注册入口
|
||||
* @throws \think\admin\Exception
|
||||
* @throws \think\db\exception\DbException
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$data = $this->_vali([
|
||||
'region_province.default' => '',
|
||||
'region_city.default' => '',
|
||||
'region_area.default' => '',
|
||||
'username.default' => '',
|
||||
'phone.mobile' => '手机格式错误!',
|
||||
'phone.require' => '手机不能为空!',
|
||||
'verify.require' => '验证码不能为空!',
|
||||
'password.require' => '登录密码不能为空!',
|
||||
]);
|
||||
if (!MessageService::instance()->checkVerifyCode($data['verify'], $data['phone'])) {
|
||||
$this->error('手机短信验证失败!');
|
||||
}
|
||||
$map = ['phone' => $data['phone'], 'deleted' => 0];
|
||||
if (DataUser::mk()->where($map)->count() > 0) {
|
||||
$this->error('手机号已注册,请使用其它手机号!');
|
||||
}
|
||||
$data['password'] = md5($data['password']);
|
||||
$user = UserAdminService::set($map, $data, $this->type, true);
|
||||
empty($user) ? $this->error('手机注册失败!') : $this->success('用户注册成功!', $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送短信验证码
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function sendsms()
|
||||
{
|
||||
$data = $this->_vali([
|
||||
'phone.mobile' => '手机号格式错误!',
|
||||
'phone.require' => '手机号不能为空!',
|
||||
'secure.require' => '安全码不能为空!',
|
||||
]);
|
||||
if ($data['secure'] !== sysconf('zt.secure_code')) $this->error('接口安全码错误!');
|
||||
[$state, $message, $data] = MessageService::instance()->sendVerifyCode($data['phone']);
|
||||
$state ? $this->success($message, $data) : $this->error($message, $data);
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\api;
|
||||
|
||||
use app\data\model\DataNewsItem;
|
||||
use app\data\model\DataNewsMark;
|
||||
use app\data\model\DataNewsXCollect;
|
||||
use app\data\service\NewsService;
|
||||
use think\admin\Controller;
|
||||
|
||||
/**
|
||||
* 文章接口控制器
|
||||
* Class News
|
||||
* @package app\data\controller\api
|
||||
*/
|
||||
class News extends Controller
|
||||
{
|
||||
/**
|
||||
* 获取文章标签列表
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getMark()
|
||||
{
|
||||
$query = DataNewsMark::mQuery()->like('name');
|
||||
$query->where(['status' => 1, 'deleted' => 0])->withoutField('sort,status,deleted');
|
||||
$this->success('获取文章标签', $query->order('sort desc,id desc')->page(false, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文章内容列表
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getItem()
|
||||
{
|
||||
if ($code = input('code', '')) {
|
||||
DataNewsItem::mk()->where(['code' => $code])->inc('num_read')->update([]);
|
||||
if (($uuid = input('uuid', 0)) > 0) {
|
||||
$data = ['uuid' => $uuid, 'code' => $code, 'type' => 3, 'status' => 2];
|
||||
DataNewsXCollect::mk()->where($data)->delete();
|
||||
DataNewsXCollect::mk()->insert($data);
|
||||
}
|
||||
}
|
||||
$query = DataNewsItem::mQuery()->like('name,mark')->equal('id,code');
|
||||
$query->where(['deleted' => 0, 'status' => 1])->withoutField('sort,status,deleted');
|
||||
$result = $query->order('sort desc,id desc')->page(true, false, false, 15);
|
||||
NewsService::buildData($result['list'], input('uuid', 0));
|
||||
$this->success('获取文章内容', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文章评论
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getComment()
|
||||
{
|
||||
$map = $this->_vali(['code.require' => '文章不能为空!']);
|
||||
$query = DataNewsXCollect::mQuery()->where(['type' => 4, 'status' => 2]);
|
||||
$result = $query->where($map)->order('id desc')->page(true, false, false, 15);
|
||||
NewsService::buildListByUidAndCode($result['list']);
|
||||
$this->success('获取评论成功', $result);
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\api;
|
||||
|
||||
use app\data\service\payment\AlipayPaymentService;
|
||||
use app\data\service\payment\JoinpayPaymentService;
|
||||
use app\data\service\payment\WechatPaymentService;
|
||||
use think\admin\Controller;
|
||||
|
||||
/**
|
||||
* 异步通知处理
|
||||
* Class Notify
|
||||
* @package app\data\controller\api
|
||||
*/
|
||||
class Notify extends Controller
|
||||
{
|
||||
/**
|
||||
* 微信支付通知
|
||||
* @param string $scene 支付场景
|
||||
* @param string $param 支付参数
|
||||
* @return string
|
||||
* @throws \think\admin\Exception
|
||||
*/
|
||||
public function wxpay(string $scene = 'order', string $param = ''): string
|
||||
{
|
||||
if (strtolower($scene) === 'order') {
|
||||
return WechatPaymentService::instance($param)->notify();
|
||||
} else {
|
||||
return 'success';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付宝支付通知
|
||||
* @param string $scene 支付场景
|
||||
* @param string $param 支付参数
|
||||
* @return string
|
||||
* @throws \think\admin\Exception
|
||||
*/
|
||||
public function alipay(string $scene = 'order', string $param = ''): string
|
||||
{
|
||||
if (strtolower($scene) === 'order') {
|
||||
return AlipayPaymentService::instance($param)->notify();
|
||||
} else {
|
||||
return 'success';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 汇聚支付通知
|
||||
* @param string $scene 支付场景
|
||||
* @param string $param 支付参数
|
||||
* @return string
|
||||
* @throws \think\admin\Exception
|
||||
*/
|
||||
public function joinpay(string $scene = 'order', string $param = ''): string
|
||||
{
|
||||
if (strtolower($scene) === 'order') {
|
||||
return JoinpayPaymentService::instance($param)->notify();
|
||||
} else {
|
||||
return 'success';
|
||||
}
|
||||
}
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\api;
|
||||
|
||||
use app\data\service\UserAdminService;
|
||||
use app\wechat\service\WechatService;
|
||||
use think\admin\Controller;
|
||||
use think\Response;
|
||||
|
||||
/**
|
||||
* 微信服务号入口
|
||||
* Class Wechat
|
||||
* @package app\data\controller\api
|
||||
* @example 域名请修改为自己的地址,放到网页代码合适位置
|
||||
* <meta name="referrer" content="always">
|
||||
* <script referrerpolicy="unsafe-url" src="https://your.domain.com/data/api.wechat/oauth?mode=1"></script>
|
||||
*
|
||||
* 授权模式支持两种模块,参数 mode=0 时为静默授权,mode=1 时为完整授权
|
||||
* 注意:回跳地址默认从 Header 中的 http_referer 获取,也可以传 source 参数
|
||||
*/
|
||||
class Wechat extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* 接口认证类型
|
||||
* @var string
|
||||
*/
|
||||
private $type = UserAdminService::API_TYPE_WECHAT;
|
||||
|
||||
/**
|
||||
* 唯一绑定字段
|
||||
* @var string
|
||||
*/
|
||||
private $field;
|
||||
|
||||
/**
|
||||
* 控制器初始化
|
||||
* @return $this
|
||||
*/
|
||||
protected function initialize(): Wechat
|
||||
{
|
||||
if (empty(UserAdminService::TYPES[$this->type]['auth'])) {
|
||||
$this->error("接口类型[{$this->type}]没有定义规则");
|
||||
} else {
|
||||
$this->field = UserAdminService::TYPES[$this->type]['auth'];
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 JSSDK 签名
|
||||
* @throws \WeChat\Exceptions\InvalidResponseException
|
||||
* @throws \WeChat\Exceptions\LocalCacheException
|
||||
* @throws \think\admin\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function jssdk()
|
||||
{
|
||||
$url = input('source') ?: $this->request->server('http_referer');
|
||||
$this->success('获取签名参数', WechatService::instance()->getWebJssdkSign($url));
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载网页授权数据
|
||||
* @return Response
|
||||
* @throws \WeChat\Exceptions\InvalidResponseException
|
||||
* @throws \WeChat\Exceptions\LocalCacheException
|
||||
* @throws \think\admin\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function oauth(): Response
|
||||
{
|
||||
$source = input('source') ?: $this->request->server('http_referer');
|
||||
[$mode, $script, $wechat] = [input('mode', 1), [], WechatService::instance()];
|
||||
$result = $wechat->getWebOauthInfo($source ?: $this->request->url(true), $mode, false);
|
||||
if (empty($result['openid'])) {
|
||||
$script[] = 'alert("Wechat WebOauth failed.")';
|
||||
} else {
|
||||
$data = $result['fansinfo'] ?? [];
|
||||
$data[$this->field] = $data['openid'];
|
||||
$data['base_sex'] = ['未知', '男', '女'][$data['sex']] ?? '未知';
|
||||
if (isset($result['unionid'])) $data['unionid'] = $result['unionid'];
|
||||
if (isset($data['headimgurl'])) $data['headimg'] = $data['headimgurl'];
|
||||
$map = UserAdminService::getUserUniMap($this->field, $data[$this->field], $data['unionid'] ?? '');
|
||||
$result['userinfo'] = UserAdminService::set($map, array_merge($map, $data), $this->type, true);
|
||||
$script[] = "window.WeChatOpenid='{$result['openid']}'";
|
||||
$script[] = 'window.WeChatFansInfo=' . json_encode($result['fansinfo'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
$script[] = 'window.WeChatUserInfo=' . json_encode($result['userinfo'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
}
|
||||
$script[] = '';
|
||||
return Response::create(join(";\n", $script))->contentType('application/x-javascript');
|
||||
}
|
||||
|
||||
/**
|
||||
* 网页授权测试
|
||||
* 使用网页直接访问此链接
|
||||
* @return string
|
||||
*/
|
||||
public function otest(): string
|
||||
{
|
||||
return <<<EOL
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>微信网页授权测试</title>
|
||||
<meta name="referrer" content="always">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
|
||||
<style>pre{padding:20px;overflow:auto;margin-top:10px;background:#ccc;border-radius:6px;}</style>
|
||||
</head>
|
||||
<body>
|
||||
<div>当前链接</div>
|
||||
<pre>{$this->request->scheme()}://{$this->request->host()}/data/api.wechat/oauth?mode=1</pre>
|
||||
|
||||
<div style="margin-top:30px">粉丝数据</div>
|
||||
<pre id="fansdata">待网页授权,加载粉丝数据...</pre>
|
||||
|
||||
<div style="margin-top:30px">用户数据</div>
|
||||
<pre id="userdata">待网页授权,加载用户数据...</pre>
|
||||
|
||||
<script referrerpolicy="unsafe-url" src="//{$this->request->host()}/data/api.wechat/oauth?mode=1"></script>
|
||||
<script>
|
||||
if(typeof window.WeChatFansInfo === 'object'){
|
||||
document.getElementById('fansdata').innerText = JSON.stringify(window.WeChatFansInfo, null, 2);
|
||||
}
|
||||
if(typeof window.WeChatUserInfo === 'object'){
|
||||
document.getElementById('userdata').innerText = JSON.stringify(window.WeChatUserInfo, null, 2);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
EOL;
|
||||
}
|
||||
}
|
@ -1,200 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\api;
|
||||
|
||||
use app\data\service\UserAdminService;
|
||||
use think\admin\Controller;
|
||||
use think\exception\HttpResponseException;
|
||||
use think\Response;
|
||||
use WeMini\Crypt;
|
||||
use WeMini\Live;
|
||||
use WeMini\Qrcode;
|
||||
|
||||
/**
|
||||
* 微信小程序入口
|
||||
* Class Wxapp
|
||||
* @package app\data\controller\api
|
||||
*/
|
||||
class Wxapp extends Controller
|
||||
{
|
||||
/**
|
||||
* 接口认证类型
|
||||
* @var string
|
||||
*/
|
||||
private $type = UserAdminService::API_TYPE_WXAPP;
|
||||
|
||||
/**
|
||||
* 唯一绑定字段
|
||||
* @var string
|
||||
*/
|
||||
private $field;
|
||||
|
||||
/**
|
||||
* 小程序配置参数
|
||||
* @var array
|
||||
*/
|
||||
private $cfg;
|
||||
|
||||
/**
|
||||
* 接口服务初始化
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
$opt = sysdata('wxapp');
|
||||
$this->cfg = [
|
||||
'appid' => $opt['appid'] ?? '',
|
||||
'appsecret' => $opt['appkey'] ?? '',
|
||||
'cache_path' => $this->app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR . 'wechat',
|
||||
];
|
||||
if (empty(UserAdminService::TYPES[$this->type]['auth'])) {
|
||||
$this->error("接口类型[{$this->type}]没有定义规则");
|
||||
} else {
|
||||
$this->field = UserAdminService::TYPES[$this->type]['auth'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权Code换取会话信息
|
||||
* @throws \think\admin\Exception
|
||||
* @throws \think\db\exception\DbException
|
||||
*/
|
||||
public function session()
|
||||
{
|
||||
$input = $this->_vali(['code.require' => '登录凭证CODE不能为空!']);
|
||||
[$openid, $unionid, $session] = $this->applySessionKey($input['code']);
|
||||
$map = UserAdminService::getUserUniMap($this->field, $openid, $unionid);
|
||||
$data = [$this->field => $openid, 'session_key' => $session];
|
||||
if (!empty($unionid)) $data['unionid'] = $unionid;
|
||||
$this->success('授权换取成功!', UserAdminService::set($map, $data, $this->type, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 小程序数据解密
|
||||
*/
|
||||
public function decode()
|
||||
{
|
||||
try {
|
||||
$input = $this->_vali([
|
||||
'iv.require' => '解密向量不能为空!',
|
||||
'code.require' => '授权CODE不能为空!',
|
||||
'encrypted.require' => '加密内容不能为空!',
|
||||
]);
|
||||
[$openid, $unionid, $input['session_key']] = $this->applySessionKey($input['code']);
|
||||
$result = Crypt::instance($this->cfg)->decode($input['iv'], $input['session_key'], $input['encrypted']);
|
||||
if (is_array($result) && isset($result['avatarUrl']) && isset($result['nickName'])) {
|
||||
$data = [$this->field => $openid, 'nickname' => $result['nickName'], 'headimg' => $result['avatarUrl']];
|
||||
$data['base_sex'] = ['-', '男', '女'][$result['gender']] ?? '-';
|
||||
if (!empty($unionid)) $data['unionid'] = $unionid;
|
||||
$map = UserAdminService::getUserUniMap($this->field, $openid, $unionid);
|
||||
$this->success('数据解密成功!', UserAdminService::set($map, $data, $this->type, true));
|
||||
} elseif (is_array($result)) {
|
||||
$this->success('数据解密成功!', $result);
|
||||
} else {
|
||||
$this->error('数据处理失败,请稍候再试!');
|
||||
}
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
trace_file($exception);
|
||||
$this->error("数据处理失败,{$exception->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权CODE换取会话信息
|
||||
* @param string $code 换取授权CODE
|
||||
* @return array [openid, sessionkey]
|
||||
*/
|
||||
private function applySessionKey(string $code): array
|
||||
{
|
||||
try {
|
||||
$cache = $this->app->cache->get($code, []);
|
||||
if (isset($cache['openid']) && isset($cache['session_key'])) {
|
||||
return [$cache['openid'], $cache['unionid'] ?? '', $cache['session_key']];
|
||||
}
|
||||
$result = Crypt::instance($this->cfg)->session($code);
|
||||
if (isset($result['openid']) && isset($result['session_key'])) {
|
||||
$this->app->cache->set($code, $result, 60);
|
||||
return [$result['openid'], $result['unionid'] ?? '', $result['session_key']];
|
||||
} elseif (isset($result['errmsg'])) {
|
||||
$this->error($result['errmsg']);
|
||||
} else {
|
||||
$this->error("授权换取失败,请稍候再试!");
|
||||
}
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
trace_file($exception);
|
||||
$this->error("授权换取失败,{$exception->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小程序码
|
||||
*/
|
||||
public function qrcode(): Response
|
||||
{
|
||||
try {
|
||||
$data = $this->_vali([
|
||||
'size.default' => 430,
|
||||
'type.default' => 'base64',
|
||||
'path.require' => '跳转路径不能为空!',
|
||||
]);
|
||||
$result = Qrcode::instance($this->cfg)->createMiniPath($data['path'], $data['size']);
|
||||
if ($data['type'] === 'base64') {
|
||||
$this->success('生成小程序码成功!', [
|
||||
'base64' => 'data:image/png;base64,' . base64_encode($result),
|
||||
]);
|
||||
} else {
|
||||
return response($result)->contentType('image/png');
|
||||
}
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
trace_file($exception);
|
||||
$this->error($exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取直播列表
|
||||
*/
|
||||
public function getLiveList()
|
||||
{
|
||||
try {
|
||||
$data = $this->_vali(['start.default' => 0, 'limit.default' => 10]);
|
||||
$list = Live::instance($this->cfg)->getLiveList($data['start'], $data['limit']);
|
||||
$this->success('获取直播列表成功!', $list);
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
trace_file($exception);
|
||||
$this->error($exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取回放源视频
|
||||
*/
|
||||
public function getLiveInfo()
|
||||
{
|
||||
try {
|
||||
$data = $this->_vali([
|
||||
'start.default' => 0,
|
||||
'limit.default' => 10,
|
||||
'action.default' => 'get_replay',
|
||||
'room_id.require' => '直播间不能为空',
|
||||
]);
|
||||
$result = Live::instance($this->cfg)->getLiveInfo($data);
|
||||
$this->success('获取回放视频成功!', $result);
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
trace_file($exception);
|
||||
$this->error($exception->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\api\auth;
|
||||
|
||||
use app\data\controller\api\Auth;
|
||||
use app\data\model\DataUserAddress;
|
||||
use think\admin\extend\CodeExtend;
|
||||
|
||||
/**
|
||||
* 用户收货地址管理
|
||||
* Class Address
|
||||
* @package app\data\controller\api\auth
|
||||
*/
|
||||
class Address extends Auth
|
||||
{
|
||||
/**
|
||||
* 添加收货地址
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function set()
|
||||
{
|
||||
$data = $this->_vali([
|
||||
'uuid.value' => $this->uuid,
|
||||
'type.default' => 0,
|
||||
'code.default' => '',
|
||||
'idcode.default' => '', // 身份证号码
|
||||
'idimg1.default' => '', // 身份证正面
|
||||
'idimg2.default' => '', // 身份证反面
|
||||
'type.in:0,1' => '地址状态不在范围!',
|
||||
'name.require' => '收货姓名不能为空!',
|
||||
'phone.mobile' => '收货手机格式错误!',
|
||||
'phone.require' => '收货手机不能为空!',
|
||||
'province.require' => '地址省份不能为空!',
|
||||
'city.require' => '地址城市不能为空!',
|
||||
'area.require' => '地址区域不能为空!',
|
||||
'address.require' => '详情地址不能为空!',
|
||||
'deleted.value' => 0,
|
||||
]);
|
||||
if (empty($data['code'])) {
|
||||
unset($data['code']);
|
||||
$count = DataUserAddress::mk()->where($data)->count();
|
||||
if ($count > 0) $this->error('抱歉,该地址已经存在!');
|
||||
$data['code'] = CodeExtend::uniqidDate(20, 'A');
|
||||
if (DataUserAddress::mk()->insert($data) === false) {
|
||||
$this->error('添加地址失败!');
|
||||
}
|
||||
} else {
|
||||
$map = ['uuid' => $this->uuid, 'code' => $data['code']];
|
||||
$addr = DataUserAddress::mk()->where($map)->find();
|
||||
if (empty($addr)) $this->error('修改地址不存在!');
|
||||
DataUserAddress::mk()->where($map)->update($data);
|
||||
}
|
||||
// 去除其它默认选项
|
||||
if (isset($data['type']) && $data['type'] > 0) {
|
||||
$map = [['uuid', '=', $this->uuid], ['code', '<>', $data['code']]];
|
||||
DataUserAddress::mk()->where($map)->update(['type' => 0]);
|
||||
}
|
||||
$this->success('地址保存成功!', $this->getAddress($data['code']));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取收货地址
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
$query = DataUserAddress::mQuery()->withoutField('deleted');
|
||||
$query->equal('code')->where(['uuid' => $this->uuid, 'deleted' => 0]);
|
||||
$result = $query->order('type desc,id desc')->page(false, false, false, 15);
|
||||
$this->success('获取地址数据!', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改地址状态
|
||||
*/
|
||||
public function state()
|
||||
{
|
||||
$data = $this->_vali([
|
||||
'uuid.value' => $this->uuid,
|
||||
'type.in:0,1' => '地址状态不在范围!',
|
||||
'type.require' => '地址状态不能为空!',
|
||||
'code.require' => '地址编号不能为空!',
|
||||
]);
|
||||
// 检查地址是否存在
|
||||
$map = ['uuid' => $data['uuid'], 'code' => $data['code']];
|
||||
if (DataUserAddress::mk()->where($map)->count() < 1) {
|
||||
$this->error('修改的地址不存在!');
|
||||
}
|
||||
// 更新默认地址状态
|
||||
$data['type'] = intval($data['type']);
|
||||
DataUserAddress::mk()->where($map)->update(['type' => $data['type']]);
|
||||
// 去除其它默认选项
|
||||
if ($data['type'] > 0) {
|
||||
$map = [['uuid', '=', $this->uuid], ['code', '<>', $data['code']]];
|
||||
DataUserAddress::mk()->where($map)->update(['type' => 0]);
|
||||
}
|
||||
$this->success('默认设置成功!', $this->getAddress($data['code']));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除收货地址
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
$map = $this->_vali([
|
||||
'uuid.value' => $this->uuid,
|
||||
'code.require' => '地址不能为空!',
|
||||
]);
|
||||
$item = DataUserAddress::mk()->where($map)->findOrEmpty();
|
||||
if ($item->isEmpty()) $this->error('需要删除的地址不存在!');
|
||||
if ($item->save(['deleted' => 1]) !== false) {
|
||||
$this->success('删除地址成功!');
|
||||
} else {
|
||||
$this->error('删除地址失败!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定的地址
|
||||
* @param string $code
|
||||
* @return null|array
|
||||
*/
|
||||
private function getAddress(string $code): array
|
||||
{
|
||||
$map = ['code' => $code, 'uuid' => $this->uuid, 'deleted' => 0];
|
||||
return DataUserAddress::mk()->withoutField('deleted')->where($map)->findOrEmpty()->toArray();
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\api\auth;
|
||||
|
||||
use app\data\controller\api\Auth;
|
||||
use app\data\model\DataUserBalance;
|
||||
use think\admin\helper\QueryHelper;
|
||||
|
||||
/**
|
||||
* 用户余额转账
|
||||
* Class Balance
|
||||
* @package app\data\controller\api\auth
|
||||
*/
|
||||
class Balance extends Auth
|
||||
{
|
||||
/**
|
||||
* 获取用户余额记录
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
DataUserBalance::mQuery(null, function (QueryHelper $query) {
|
||||
$query->withoutField('deleted,create_by');
|
||||
$query->where(['uuid' => $this->uuid, 'deleted' => 0])->like('create_at#date');
|
||||
$this->success('获取数据成功', $query->order('id desc')->page(true, false, false, 10));
|
||||
});
|
||||
}
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\api\auth;
|
||||
|
||||
use app\data\controller\api\Auth;
|
||||
use app\data\model\BaseUserUpgrade;
|
||||
use app\data\model\DataUser;
|
||||
use app\data\service\UserAdminService;
|
||||
use app\data\service\UserUpgradeService;
|
||||
use think\admin\Storage;
|
||||
use think\exception\HttpResponseException;
|
||||
|
||||
/**
|
||||
* 用户资料管理
|
||||
* Class Center
|
||||
* @package app\data\controller\api\auth
|
||||
*/
|
||||
class Center extends Auth
|
||||
{
|
||||
/**
|
||||
* 更新用户资料
|
||||
*/
|
||||
public function set()
|
||||
{
|
||||
$data = $this->_vali([
|
||||
'headimg.default' => '',
|
||||
'username.default' => '',
|
||||
'base_age.default' => '',
|
||||
'base_sex.default' => '',
|
||||
'base_height.default' => '',
|
||||
'base_weight.default' => '',
|
||||
'base_birthday.default' => '',
|
||||
]);
|
||||
foreach ($data as $key => $vo) if ($vo === '') unset($data[$key]);
|
||||
if (empty($data)) $this->error('没有修改的数据!');
|
||||
if (DataUser::mk()->where(['id' => $this->uuid])->update($data) !== false) {
|
||||
$this->success('更新资料成功!', $this->getUser());
|
||||
} else {
|
||||
$this->error('更新资料失败!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户资料
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
$this->success('获取用户资料', $this->getUser());
|
||||
}
|
||||
|
||||
/**
|
||||
* Base64 图片上传
|
||||
*/
|
||||
public function image()
|
||||
{
|
||||
try {
|
||||
$data = $this->_vali(['base64.require' => '图片内容不为空!']);
|
||||
if (preg_match($preg = '|^data:image/(.*?);base64,|i', $data['base64'])) {
|
||||
[$ext, $img] = explode('|||', preg_replace($preg, '$1|||', $data['base64']));
|
||||
if (empty($ext) || !in_array(strtolower($ext), ['png', 'jpg', 'jpeg'])) {
|
||||
$this->error('图片格式异常!');
|
||||
}
|
||||
$name = Storage::name($img, $ext, 'image/');
|
||||
$info = Storage::instance()->set($name, base64_decode($img));
|
||||
$this->success('图片上传成功!', ['url' => $info['url']]);
|
||||
} else {
|
||||
$this->error('解析内容失败!');
|
||||
}
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
trace_file($exception);
|
||||
$this->error($exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 二进制文件上传
|
||||
* @throws \think\admin\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function upload()
|
||||
{
|
||||
$file = $this->request->file('file');
|
||||
if (empty($file)) $this->error('文件上传异常!');
|
||||
$extension = strtolower($file->getOriginalExtension());
|
||||
if (in_array($extension, ['php', 'sh'])) $this->error('禁止上传此类文件!');
|
||||
$bina = file_get_contents($file->getRealPath());
|
||||
$name = Storage::name($file->getPathname(), $extension, '', 'md5_file');
|
||||
$info = Storage::instance()->set($name, $bina, false, $file->getOriginalName());
|
||||
if (is_array($info) && isset($info['url'])) {
|
||||
$this->success('文件上传成功!', $info);
|
||||
} else {
|
||||
$this->error('文件上传失败!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户等级
|
||||
*/
|
||||
public function levels()
|
||||
{
|
||||
$levels = BaseUserUpgrade::items();
|
||||
$this->success('获取用户等级', array_values($levels));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取我邀请的朋友
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getFrom()
|
||||
{
|
||||
$map = [];
|
||||
$map[] = ['deleted', '=', 0];
|
||||
$map[] = ['path', 'like', "%-{$this->uuid}-%"];
|
||||
// 查询邀请的朋友
|
||||
$query = DataUser::mQuery()->like('nickname|username#nickname')->equal('vip_code,pids,pid1,id#uuid');
|
||||
$query->field('id,pid0,pid1,pid2,pids,username,nickname,headimg,order_amount_total,teams_amount_total,teams_amount_direct,teams_amount_indirect,teams_users_total,teams_users_direct,teams_users_indirect,rebate_total,rebate_used,rebate_lock,create_at');
|
||||
$result = $query->where($map)->order('id desc')->page(true, false, false, 15);
|
||||
// 统计当前用户所有下属数
|
||||
$total = DataUser::mk()->where($map)->count();
|
||||
// 统计当前用户本月下属数
|
||||
$map[] = ['create_at', 'like', date('Y-m-%')];
|
||||
$month = DataUser::mk()->where($map)->count();
|
||||
// 返回结果列表数据及统计
|
||||
$result['total'] = ['user_total' => $total, 'user_month' => $month];
|
||||
$this->success('获取我邀请的朋友', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定用户邀请人
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function bindFrom()
|
||||
{
|
||||
$data = $this->_vali(['from.require' => '邀请人不能为空']);
|
||||
[$state, $message] = UserUpgradeService::bindAgent($this->uuid, $data['from'], 0);
|
||||
if ($state) {
|
||||
$this->success($message, UserAdminService::total($this->uuid));
|
||||
} else {
|
||||
$this->error($message, UserAdminService::total($this->uuid));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,209 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\api\auth;
|
||||
|
||||
use app\data\controller\api\Auth;
|
||||
use app\data\model\DataNewsXCollect;
|
||||
use app\data\service\NewsService;
|
||||
|
||||
/**
|
||||
* 文章评论内容
|
||||
* Class News
|
||||
* @package app\data\controller\api\auth
|
||||
*/
|
||||
class News extends Auth
|
||||
{
|
||||
|
||||
/**
|
||||
* 用户评论内容
|
||||
*/
|
||||
public function addComment()
|
||||
{
|
||||
$data = $this->_vali([
|
||||
'uuid.value' => $this->uuid,
|
||||
'type.value' => 4,
|
||||
'status.value' => 1,
|
||||
'code.require' => '文章不能为空!',
|
||||
'reply.require' => '评论不能为空!',
|
||||
]);
|
||||
if (DataNewsXCollect::mk()->insert($data) !== false) {
|
||||
NewsService::syncNewsTotal($data['code']);
|
||||
$this->success('添加评论成功!');
|
||||
} else {
|
||||
$this->error('添加评论失败!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取我的评论
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getComment()
|
||||
{
|
||||
$query = DataNewsXCollect::mQuery()->where(['uuid' => $this->uuid, 'type' => 4]);
|
||||
$result = $query->whereIn('status', [1, 2])->order('id desc')->page(true, false);
|
||||
NewsService::buildListByUidAndCode($result);
|
||||
$this->success('获取评论列表成功', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除内容评论
|
||||
*/
|
||||
public function delComment()
|
||||
{
|
||||
$data = $this->_vali([
|
||||
'uuid.value' => $this->uuid,
|
||||
'type.value' => 4,
|
||||
'id.require' => '评论编号不能为空!',
|
||||
'code.require' => '文章编号不能为空!',
|
||||
]);
|
||||
if (DataNewsXCollect::mk()->where($data)->delete() !== false) {
|
||||
$this->success('评论删除成功!');
|
||||
} else {
|
||||
$this->error('认证删除失败!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加内容收藏
|
||||
*/
|
||||
public function addCollect()
|
||||
{
|
||||
$data = $this->_vali([
|
||||
'uuid.value' => $this->uuid,
|
||||
'type.value' => 1,
|
||||
'status.value' => 2,
|
||||
'code.require' => '文章编号不能为空!',
|
||||
]);
|
||||
if (DataNewsXCollect::mk()->where($data)->count() > 0) {
|
||||
$this->success('您已收藏!');
|
||||
}
|
||||
if (DataNewsXCollect::mk()->insert($data) !== false) {
|
||||
NewsService::syncNewsTotal($data['code']);
|
||||
$this->success('收藏成功!');
|
||||
} else {
|
||||
$this->error('收藏失败!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消收藏文章
|
||||
*/
|
||||
public function delCollect()
|
||||
{
|
||||
$data = $this->_vali([
|
||||
'uuid.value' => $this->uuid,
|
||||
'type.value' => 1,
|
||||
'code.require' => '文章编号不能为空!',
|
||||
]);
|
||||
if (DataNewsXCollect::mk()->where($data)->delete() !== false) {
|
||||
NewsService::syncNewsTotal($data['code']);
|
||||
$this->success('取消收藏成功!');
|
||||
} else {
|
||||
$this->error('取消收藏失败!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户收藏的资讯
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getCollect()
|
||||
{
|
||||
$map = ['uuid' => $this->uuid, 'type' => 1];
|
||||
$query = DataNewsXCollect::mQuery()->where($map);
|
||||
$result = $query->order('id desc')->page(true, false, false, 15);
|
||||
NewsService::buildListByUidAndCode($result['list']);
|
||||
$this->success('获取收藏记录成功!', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加内容点赞
|
||||
*/
|
||||
public function addLike()
|
||||
{
|
||||
$data = $this->_vali([
|
||||
'uuid.value' => $this->uuid,
|
||||
'type.value' => 2,
|
||||
'status.value' => 2,
|
||||
'code.require' => '文章编号不能为空!',
|
||||
]);
|
||||
if (DataNewsXCollect::mk()->where($data)->count() > 0) {
|
||||
$this->success('您已点赞!');
|
||||
}
|
||||
if (DataNewsXCollect::mk()->insert($data) !== false) {
|
||||
NewsService::syncNewsTotal($data['code']);
|
||||
$this->success('点赞成功!');
|
||||
} else {
|
||||
$this->error('点赞失败!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消内容点赞
|
||||
*/
|
||||
public function delLike()
|
||||
{
|
||||
$data = $this->_vali([
|
||||
'uuid.value' => $this->uuid,
|
||||
'type.value' => 2,
|
||||
'code.require' => '文章编号不能为空!',
|
||||
]);
|
||||
if (DataNewsXCollect::mk()->where($data)->delete() !== false) {
|
||||
NewsService::syncNewsTotal($data['code']);
|
||||
$this->success('取消点赞成功!');
|
||||
} else {
|
||||
$this->error('取消点赞失败!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户收藏的资讯
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getLike()
|
||||
{
|
||||
$query = DataNewsXCollect::mQuery();
|
||||
$query->where(['uuid' => $this->uuid, 'type' => 2, 'status' => 2]);
|
||||
$result = $query->order('id desc')->page(true, false, false, 15);
|
||||
NewsService::buildListByUidAndCode($result['list']);
|
||||
$this->success('获取点赞记录成功!', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加用户的浏览历史
|
||||
*/
|
||||
public function addHistory()
|
||||
{
|
||||
$data = $this->_vali([
|
||||
'uuid.value' => $this->uuid,
|
||||
'type.value' => 2,
|
||||
'status.value' => 2,
|
||||
'code.require' => '文章编号不能为空!',
|
||||
]);
|
||||
DataNewsXCollect::mk()->where($data)->delete();
|
||||
DataNewsXCollect::mk()->insert($data);
|
||||
$this->success('添加浏览历史成功!');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户的浏览历史
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getHistory()
|
||||
{
|
||||
$query = DataNewsXCollect::mQuery();
|
||||
$query->where(['uuid' => $this->uuid, 'type' => 3, 'status' => 2]);
|
||||
$result = $query->order('id desc')->page(true, false, false, 15);
|
||||
NewsService::buildListByUidAndCode($result['list']);
|
||||
$this->success('获取浏览历史成功!', $result);
|
||||
}
|
||||
}
|
@ -1,496 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\api\auth;
|
||||
|
||||
use app\data\controller\api\Auth;
|
||||
use app\data\model\BaseUserPayment;
|
||||
use app\data\model\DataUser;
|
||||
use app\data\model\DataUserAddress;
|
||||
use app\data\model\ShopGoods;
|
||||
use app\data\model\ShopGoodsItem;
|
||||
use app\data\model\ShopOrder;
|
||||
use app\data\model\ShopOrderItem;
|
||||
use app\data\model\ShopOrderSend;
|
||||
use app\data\service\ExpressService;
|
||||
use app\data\service\GoodsService;
|
||||
use app\data\service\OrderService;
|
||||
use app\data\service\PaymentService;
|
||||
use app\data\service\UserAdminService;
|
||||
use think\admin\extend\CodeExtend;
|
||||
use think\exception\HttpResponseException;
|
||||
|
||||
/**
|
||||
* 用户订单数据接口
|
||||
* Class Order
|
||||
* @package app\data\controller\api\auth
|
||||
*/
|
||||
class Order extends Auth
|
||||
{
|
||||
/**
|
||||
* 控制器初始化
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
if (empty($this->user['status'])) {
|
||||
$this->error('账户已被冻结,不能操作订单数据哦!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单列表
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
$map = ['uuid' => $this->uuid, 'deleted_status' => 0];
|
||||
$query = ShopOrder::mQuery()->in('status')->equal('order_no');
|
||||
$result = $query->where($map)->order('id desc')->page(true, false, false, 20);
|
||||
if (count($result['list']) > 0) OrderService::buildData($result['list']);
|
||||
$this->success('获取订单数据成功!', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户创建订单
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
// 检查用户状态
|
||||
$this->checkUserStatus();
|
||||
// 商品规则
|
||||
$rules = $this->request->post('items', '');
|
||||
if (empty($rules)) $this->error('商品不能为空');
|
||||
// 订单数据
|
||||
[$items, $order, $truckType, $allowPayments] = [[], [], -1, null];
|
||||
$order['uuid'] = $this->uuid;
|
||||
$order['order_no'] = CodeExtend::uniqidDate(18, 'N');
|
||||
// 代理处理
|
||||
$order['puid1'] = input('from', $this->user['pid1']);
|
||||
if ($order['puid1'] == $this->uuid) $order['puid1'] = 0;
|
||||
if ($order['puid1'] > 0) {
|
||||
$map = ['id' => $order['puid1'], 'status' => 1];
|
||||
$order['puid2'] = DataUser::mk()->where($map)->value('pid2');
|
||||
if (is_null($order['puid2'])) $this->error('代理异常');
|
||||
}
|
||||
// 订单商品处理
|
||||
foreach (explode('||', $rules) as $rule) {
|
||||
[$code, $spec, $count] = explode('@', $rule);
|
||||
// 商品信息检查
|
||||
$goodsInfo = ShopGoods::mk()->where(['code' => $code, 'status' => 1, 'deleted' => 0])->find();
|
||||
$goodsItem = ShopGoodsItem::mk()->where(['status' => 1, 'goods_code' => $code, 'goods_spec' => $spec])->find();
|
||||
if (empty($goodsInfo) || empty($goodsItem)) $this->error('商品查询异常');
|
||||
// 商品类型检查
|
||||
if ($truckType < 0) $truckType = $goodsInfo['truck_type'];
|
||||
if ($truckType !== $goodsInfo['truck_type']) $this->error('不能混合下单');
|
||||
// 限制购买数量
|
||||
if (isset($goodsInfo['limit_max_num']) && $goodsInfo['limit_max_num'] > 0) {
|
||||
$map = [['a.uuid', '=', $this->uuid], ['a.status', 'in', [2, 3, 4, 5]], ['b.goods_code', '=', $goodsInfo['code']]];
|
||||
$buys = ShopOrder::mk()->alias('a')->join('store_order_item b', 'a.order_no=b.order_no')->where($map)->sum('b.stock_sales');
|
||||
if ($buys + $count > $goodsInfo['limit_max_num']) $this->error('超过限购数量');
|
||||
}
|
||||
// 限制购买身份
|
||||
if ($goodsInfo['limit_low_vip'] > $this->user['vip_code']) $this->error('用户等级不够');
|
||||
// 商品库存检查
|
||||
if ($goodsItem['stock_sales'] + $count > $goodsItem['stock_total']) $this->error('商品库存不足');
|
||||
// 支付支付处理
|
||||
$_allowPayments = [];
|
||||
foreach (str2arr($goodsInfo['payment']) as $code) {
|
||||
if (is_null($allowPayments) || in_array($code, $allowPayments)) $_allowPayments[] = $code;
|
||||
}
|
||||
if (empty($_allowPayments)) {
|
||||
$this->error('订单无法统一支付');
|
||||
} else {
|
||||
$allowPayments = $_allowPayments;
|
||||
}
|
||||
// 商品折扣处理
|
||||
[$discountId, $discountRate] = OrderService::discount($goodsInfo['discount_id'], $this->user['vip_code']);
|
||||
// 订单详情处理
|
||||
$items[] = [
|
||||
'uuid' => $order['uuid'],
|
||||
'order_no' => $order['order_no'],
|
||||
// 商品信息字段
|
||||
'goods_name' => $goodsInfo['name'],
|
||||
'goods_cover' => $goodsInfo['cover'],
|
||||
'goods_payment' => $goodsInfo['payment'],
|
||||
'goods_sku' => $goodsItem['goods_sku'],
|
||||
'goods_code' => $goodsItem['goods_code'],
|
||||
'goods_spec' => $goodsItem['goods_spec'],
|
||||
// 库存数量处理
|
||||
'stock_sales' => $count,
|
||||
// 快递发货数据
|
||||
'truck_type' => $goodsInfo['truck_type'],
|
||||
'truck_code' => $goodsInfo['truck_code'],
|
||||
'truck_number' => $goodsInfo['rebate_type'] > 0 ? $goodsItem['number_express'] * $count : 0,
|
||||
// 商品费用字段
|
||||
'price_market' => $goodsItem['price_market'],
|
||||
'price_selling' => $goodsItem['price_selling'],
|
||||
'total_market' => $goodsItem['price_market'] * $count,
|
||||
'total_selling' => $goodsItem['price_selling'] * $count,
|
||||
// 奖励金额积分
|
||||
'reward_balance' => $goodsItem['reward_balance'] * $count,
|
||||
'reward_integral' => $goodsItem['reward_integral'] * $count,
|
||||
// 绑定用户等级
|
||||
'vip_name' => $this->user['vip_name'],
|
||||
'vip_code' => $this->user['vip_code'],
|
||||
// 是否入会礼包
|
||||
'vip_entry' => $goodsInfo['vip_entry'],
|
||||
'vip_upgrade' => $goodsInfo['vip_upgrade'],
|
||||
// 是否参与返利
|
||||
'rebate_type' => $goodsInfo['rebate_type'],
|
||||
'rebate_amount' => $goodsInfo['rebate_type'] > 0 ? $goodsItem['price_selling'] * $count : 0,
|
||||
// 等级优惠方案
|
||||
'discount_id' => $discountId,
|
||||
'discount_rate' => $discountRate,
|
||||
'discount_amount' => $discountRate * $goodsItem['price_selling'] * $count / 100,
|
||||
];
|
||||
}
|
||||
try {
|
||||
$order['payment_allow'] = arr2str($allowPayments);
|
||||
$order['rebate_amount'] = array_sum(array_column($items, 'rebate_amount'));
|
||||
$order['reward_balance'] = array_sum(array_column($items, 'reward_balance'));
|
||||
|
||||
// 订单发货类型
|
||||
$order['status'] = $truckType ? 1 : 2;
|
||||
$order['truck_type'] = $truckType;
|
||||
// 统计商品数量
|
||||
$order['number_goods'] = array_sum(array_column($items, 'stock_sales'));
|
||||
$order['number_express'] = array_sum(array_column($items, 'truck_number'));
|
||||
// 统计商品金额
|
||||
$order['amount_goods'] = array_sum(array_column($items, 'total_selling'));
|
||||
// 优惠后的金额
|
||||
$order['amount_discount'] = array_sum(array_column($items, 'discount_amount'));
|
||||
// 订单随机免减
|
||||
$order['amount_reduct'] = OrderService::getReduct();
|
||||
if ($order['amount_reduct'] > $order['amount_goods']) {
|
||||
$order['amount_reduct'] = $order['amount_goods'];
|
||||
}
|
||||
// 统计订单金额
|
||||
$order['amount_real'] = $order['amount_discount'] - $order['amount_reduct'];
|
||||
$order['amount_total'] = $order['amount_goods'];
|
||||
// 写入商品数据
|
||||
$this->app->db->transaction(function () use ($order, $items) {
|
||||
ShopOrder::mk()->insert($order);
|
||||
ShopOrderItem::mk()->insertAll($items);
|
||||
});
|
||||
// 同步商品库存销量
|
||||
foreach (array_unique(array_column($items, 'goods_code')) as $code) {
|
||||
GoodsService::stock($code);
|
||||
}
|
||||
// 触发订单创建事件
|
||||
$this->app->event->trigger('ShopOrderCreate', $order['order_no']);
|
||||
// 组装订单商品数据
|
||||
$order['items'] = $items;
|
||||
// 返回处理成功数据
|
||||
$this->success('商品下单成功', $order);
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
$this->error("商品下单失败,{$exception->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户折扣
|
||||
*/
|
||||
public function discount()
|
||||
{
|
||||
$data = $this->_vali(['discount.require' => '折扣编号不能为空!']);
|
||||
[, $rate] = OrderService::discount(intval($data['discount']), $this->user['vip_code']);
|
||||
$this->success('获取用户折扣', ['rate' => $rate]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模拟计算订单运费
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function express()
|
||||
{
|
||||
$data = $this->_vali([
|
||||
'uuid.value' => $this->uuid,
|
||||
'code.require' => '地址不能为空',
|
||||
'order_no.require' => '单号不能为空',
|
||||
]);
|
||||
|
||||
// 用户收货地址
|
||||
$map = ['uuid' => $this->uuid, 'code' => $data['code']];
|
||||
$addr = DataUserAddress::mk()->where($map)->find();
|
||||
if (empty($addr)) $this->error('收货地址异常');
|
||||
|
||||
// 订单状态检查
|
||||
$map = ['uuid' => $this->uuid, 'order_no' => $data['order_no']];
|
||||
$tCount = ShopOrderItem::mk()->where($map)->sum('truck_number');
|
||||
|
||||
// 根据地址计算运费
|
||||
$map = ['status' => 1, 'deleted' => 0, 'order_no' => $data['order_no']];
|
||||
$tCode = ShopOrderItem::mk()->where($map)->column('truck_code');
|
||||
[$amount, , , $remark] = ExpressService::amount($tCode, $addr['province'], $addr['city'], $tCount);
|
||||
$this->success('计算运费成功', ['amount' => $amount, 'remark' => $remark]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单信息完成
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function perfect()
|
||||
{
|
||||
$data = $this->_vali([
|
||||
'uuid.value' => $this->uuid,
|
||||
'code.require' => '地址不能为空',
|
||||
'order_no.require' => '单号不能为空',
|
||||
]);
|
||||
|
||||
// 用户收货地址
|
||||
$map = ['uuid' => $this->uuid, 'code' => $data['code'], 'deleted' => 0];
|
||||
$addr = DataUserAddress::mk()->where($map)->find();
|
||||
if (empty($addr)) $this->error('收货地址异常');
|
||||
|
||||
// 订单状态检查
|
||||
$map1 = ['uuid' => $this->uuid, 'order_no' => $data['order_no']];
|
||||
$order = ShopOrder::mk()->where($map1)->whereIn('status', [1, 2])->find();
|
||||
if (empty($order)) $this->error('不能修改地址');
|
||||
if (empty($order['truck_type'])) $this->success('无需快递配送', ['order_no' => $order['order_no']]);
|
||||
|
||||
// 根据地址计算运费
|
||||
$map2 = ['status' => 1, 'deleted' => 0, 'order_no' => $data['order_no']];
|
||||
$tCount = ShopOrderItem::mk()->where($map1)->sum('truck_number');
|
||||
$tCodes = ShopOrderItem::mk()->where($map2)->column('truck_code');
|
||||
[$amount, $tCount, $tCode, $remark] = ExpressService::amount($tCodes, $addr['province'], $addr['city'], $tCount);
|
||||
|
||||
// 创建订单发货信息
|
||||
$express = [
|
||||
'template_code' => $tCode, 'template_count' => $tCount, 'uuid' => $this->uuid,
|
||||
'template_remark' => $remark, 'template_amount' => $amount, 'status' => 1,
|
||||
];
|
||||
$express['order_no'] = $data['order_no'];
|
||||
$express['address_code'] = $data['code'];
|
||||
$express['address_datetime'] = date('Y-m-d H:i:s');
|
||||
|
||||
// 收货人信息
|
||||
$express['address_name'] = $addr['name'];
|
||||
$express['address_phone'] = $addr['phone'];
|
||||
$express['address_idcode'] = $addr['idcode'];
|
||||
$express['address_idimg1'] = $addr['idimg1'];
|
||||
$express['address_idimg2'] = $addr['idimg2'];
|
||||
|
||||
// 收货地址信息
|
||||
$express['address_province'] = $addr['province'];
|
||||
$express['address_city'] = $addr['city'];
|
||||
$express['address_area'] = $addr['area'];
|
||||
$express['address_content'] = $addr['address'];
|
||||
|
||||
ShopOrderSend::mUpdate($express, 'order_no');
|
||||
data_save(ShopOrderSend::class, $express, 'order_no');
|
||||
// 组装更新订单数据
|
||||
$update = ['status' => 2, 'amount_express' => $express['template_amount']];
|
||||
// 重新计算订单金额
|
||||
$update['amount_real'] = $order['amount_discount'] + $amount - $order['amount_reduct'];
|
||||
$update['amount_total'] = $order['amount_goods'] + $amount;
|
||||
// 支付金额不能为零
|
||||
if ($update['amount_real'] <= 0) $update['amount_real'] = 0.00;
|
||||
if ($update['amount_total'] <= 0) $update['amount_total'] = 0.00;
|
||||
// 更新用户订单数据
|
||||
$map = ['uuid' => $this->uuid, 'order_no' => $data['order_no']];
|
||||
if (ShopOrder::mk()->where($map)->update($update) !== false) {
|
||||
// 触发订单确认事件
|
||||
$this->app->event->trigger('ShopOrderPerfect', $order['order_no']);
|
||||
// 返回处理成功数据
|
||||
$this->success('订单确认成功', ['order_no' => $order['order_no']]);
|
||||
} else {
|
||||
$this->error('订单确认失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支付支付数据
|
||||
*/
|
||||
public function channel()
|
||||
{
|
||||
$data = $this->_vali(['uuid.value' => $this->uuid, 'order_no.require' => '单号不能为空']);
|
||||
$payments = ShopOrder::mk()->where($data)->value('payment_allow');
|
||||
if (empty($payments)) $this->error('获取订单支付参数失败');
|
||||
// 读取支付通道配置
|
||||
$query = BaseUserPayment::mk()->where(['status' => 1, 'deleted' => 0]);
|
||||
$query->whereIn('code', str2arr($payments))->whereIn('type', PaymentService::getTypeApi($this->type));
|
||||
$result = $query->order('sort desc,id desc')->column('type,code,name,cover,content,remark', 'code');
|
||||
foreach ($result as &$vo) $vo['content'] = ['voucher_qrcode' => json_decode($vo['content'])->voucher_qrcode ?? ''];
|
||||
$this->success('获取支付参数数据', array_values($result));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单支付状态
|
||||
* @throws \think\db\exception\DbException
|
||||
*/
|
||||
public function payment()
|
||||
{
|
||||
$data = $this->_vali([
|
||||
'uuid.value' => $this->uuid,
|
||||
'order_no.require' => '单号不能为空',
|
||||
'order_remark.default' => '',
|
||||
'payment_code.require' => '支付不能为空',
|
||||
'payment_back.default' => '', # 支付回跳地址
|
||||
'payment_image.default' => '', # 支付凭证图片
|
||||
]);
|
||||
[$map, $order] = $this->getOrderData();
|
||||
if ($order['status'] !== 2) $this->error('不能发起支付');
|
||||
if ($order['payment_status'] > 0) $this->error('已经完成支付');
|
||||
// 更新订单备注
|
||||
if (!empty($data['order_remark'])) {
|
||||
ShopOrder::mk()->where($map)->update([
|
||||
'order_remark' => $data['order_remark'],
|
||||
]);
|
||||
}
|
||||
// 自动处理用户字段
|
||||
$openid = '';
|
||||
if (in_array($this->type, [UserAdminService::API_TYPE_WXAPP, UserAdminService::API_TYPE_WECHAT])) {
|
||||
$openid = $this->user[UserAdminService::TYPES[$this->type]['auth']] ?? '';
|
||||
if (empty($openid)) $this->error("发起支付失败");
|
||||
}
|
||||
try {
|
||||
// 返回订单数据及支付发起参数
|
||||
$type = $order['amount_real'] <= 0 ? 'empty' : $data['payment_code'];
|
||||
$param = PaymentService::instance($type)->create($openid, $order['order_no'], $order['amount_real'], '商城订单支付', '', $data['payment_back'], $data['payment_image']);
|
||||
$this->success('获取支付参数', ['order' => ShopOrder::mk()->where($map)->find() ?: new \stdClass(), 'param' => $param]);
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
$this->error($exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 主动取消未支付的订单
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function cancel()
|
||||
{
|
||||
[$map, $order] = $this->getOrderData();
|
||||
if (in_array($order['status'], [1, 2, 3])) {
|
||||
$result = ShopOrder::mk()->where($map)->update([
|
||||
'status' => 0,
|
||||
'cancel_status' => 1,
|
||||
'cancel_remark' => '用户主动取消订单',
|
||||
'cancel_datetime' => date('Y-m-d H:i:s'),
|
||||
]);
|
||||
if ($result !== false && OrderService::stock($order['order_no'])) {
|
||||
// 触发订单取消事件
|
||||
$this->app->event->trigger('ShopOrderCancel', $order['order_no']);
|
||||
// 返回处理成功数据
|
||||
$this->success('订单取消成功');
|
||||
} else {
|
||||
$this->error('订单取消失败');
|
||||
}
|
||||
} else {
|
||||
$this->error('订单不可取消');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户主动删除已取消的订单
|
||||
* @throws \think\db\exception\DbException
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
[$map, $order] = $this->getOrderData();
|
||||
if (empty($order)) $this->error('读取订单失败');
|
||||
if ($order['status'] == 0) {
|
||||
$result = ShopOrder::mk()->where($map)->update([
|
||||
'status' => 0,
|
||||
'deleted_status' => 1,
|
||||
'deleted_remark' => '用户主动删除订单',
|
||||
'deleted_datetime' => date('Y-m-d H:i:s'),
|
||||
]);
|
||||
if ($result !== false) {
|
||||
// 触发订单删除事件
|
||||
$this->app->event->trigger('ShopOrderRemove', $order['order_no']);
|
||||
// 返回处理成功数据
|
||||
$this->success('订单删除成功');
|
||||
} else {
|
||||
$this->error('订单删除失败');
|
||||
}
|
||||
} else {
|
||||
$this->error('订单不可删除');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单确认收货
|
||||
* @throws \think\db\exception\DbException
|
||||
*/
|
||||
public function confirm()
|
||||
{
|
||||
[$map, $order] = $this->getOrderData();
|
||||
if ($order['status'] == 5) {
|
||||
if (ShopOrder::mk()->where($map)->update(['status' => 6]) !== false) {
|
||||
// 触发订单确认事件
|
||||
$this->app->event->trigger('ShopOrderConfirm', $order['order_no']);
|
||||
// 返回处理成功数据
|
||||
$this->success('订单确认成功');
|
||||
} else {
|
||||
$this->error('订单确认失败');
|
||||
}
|
||||
} else {
|
||||
$this->error('订单确认失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取输入订单
|
||||
* @return array [map, order]
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function getOrderData(): array
|
||||
{
|
||||
$map = $this->_vali([
|
||||
'uuid.value' => $this->uuid,
|
||||
'order_no.require' => '单号不能为空',
|
||||
]);
|
||||
$order = ShopOrder::mk()->where($map)->find();
|
||||
if (empty($order)) $this->error('读取订单失败');
|
||||
return [$map, $order];
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单状态统计
|
||||
*/
|
||||
public function total()
|
||||
{
|
||||
$data = ['t0' => 0, 't1' => 0, 't2' => 0, 't3' => 0, 't4' => 0, 't5' => 0, 't6' => 0];
|
||||
$query = ShopOrder::mk()->where(['uuid' => $this->uuid, 'deleted_status' => 0]);
|
||||
foreach ($query->field('status,count(1) count')->group('status')->cursor() as $item) {
|
||||
$data["t{$item['status']}"] = $item['count'];
|
||||
}
|
||||
$this->success('获取订单统计', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 物流追踪查询
|
||||
*/
|
||||
public function track()
|
||||
{
|
||||
try {
|
||||
$data = $this->_vali([
|
||||
'code.require' => '快递不能为空',
|
||||
'number.require' => '单号不能为空'
|
||||
]);
|
||||
$result = ExpressService::query($data['code'], $data['number']);
|
||||
empty($result['code']) ? $this->error($result['info']) : $this->success('快递追踪信息', $result);
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
$this->error($exception->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\api\auth;
|
||||
|
||||
use app\data\controller\api\Auth;
|
||||
use app\data\model\BaseUserUpgrade;
|
||||
use app\data\model\DataUserRebate;
|
||||
use app\data\service\RebateService;
|
||||
|
||||
/**
|
||||
* 用户返利管理
|
||||
* Class Rebate
|
||||
* @package app\data\controller\api\auth
|
||||
*/
|
||||
class Rebate extends Auth
|
||||
{
|
||||
/**
|
||||
* 获取用户返利记录
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
$date = trim(input('date', date('Y-m')), '-');
|
||||
[$map, $year] = [['uuid' => $this->uuid], substr($date, 0, 4)];
|
||||
$query = DataUserRebate::mQuery()->where($map)->equal('type,status')->whereLike('date', "{$date}%");
|
||||
$this->success('获取返利统计', array_merge($query->order('id desc')->page(true, false, false, 10), [
|
||||
'total' => [
|
||||
'年度' => DataUserRebate::mQuery()->where($map)->equal('type,status')->whereLike('date', "{$year}%")->db()->sum('amount'),
|
||||
'月度' => DataUserRebate::mQuery()->where($map)->equal('type,status')->whereLike('date', "{$date}%")->db()->sum('amount'),
|
||||
],
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取我的奖励
|
||||
*/
|
||||
public function prize()
|
||||
{
|
||||
[$map, $data] = [['number' => $this->user['vip_code']], []];
|
||||
$prizes = DataUserRebate::mk()->group('name')->column('name');
|
||||
$rebate = BaseUserUpgrade::mk()->where($map)->value('rebate_rule', '');
|
||||
$codemap = array_merge($prizes, str2arr($rebate));
|
||||
foreach (RebateService::PRIZES as $prize) {
|
||||
if (in_array($prize['code'], $codemap)) $data[] = $prize;
|
||||
}
|
||||
$this->success('获取我的奖励', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取奖励配置
|
||||
*/
|
||||
public function prizes()
|
||||
{
|
||||
$this->success('获取系统奖励', array_values(RebateService::PRIZES));
|
||||
}
|
||||
}
|
@ -1,162 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\api\auth;
|
||||
|
||||
use app\data\controller\api\Auth;
|
||||
use app\data\model\DataUserTransfer;
|
||||
use app\data\service\UserRebateService;
|
||||
use app\data\service\UserTransferService;
|
||||
use think\admin\extend\CodeExtend;
|
||||
|
||||
/**
|
||||
* 用户提现接口
|
||||
* Class Transfer
|
||||
* @package app\data\controller\api\auth
|
||||
*/
|
||||
class Transfer extends Auth
|
||||
{
|
||||
/**
|
||||
* 提交提现处理
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
// 检查用户状态
|
||||
$this->checkUserStatus();
|
||||
// 接收输入数据
|
||||
$data = $this->_vali([
|
||||
'type.require' => '提现方式不能为空!',
|
||||
'amount.require' => '提现金额不能为空!',
|
||||
'remark.default' => '用户提交提现申请!',
|
||||
]);
|
||||
$state = UserTransferService::config('status');
|
||||
if (empty($state)) $this->error('提现还没有开启!');
|
||||
$transfers = UserTransferService::config('transfer');
|
||||
if (empty($transfers[$data['type']]['state'])) $this->error('提现方式已停用!');
|
||||
// 提现数据补充
|
||||
$data['uuid'] = $this->uuid;
|
||||
$data['date'] = date('Y-m-d');
|
||||
$data['code'] = CodeExtend::uniqidDate(20, 'T');
|
||||
// 提现状态处理
|
||||
if (empty($transfers[$data['type']]['state']['audit'])) {
|
||||
$data['status'] = 1;
|
||||
$data['audit_status'] = 0;
|
||||
} else {
|
||||
$data['status'] = 3;
|
||||
$data['audit_status'] = 1;
|
||||
$data['audit_remark'] = '提现免审核';
|
||||
$data['audit_datetime'] = date('Y-m-d H:i:s');
|
||||
}
|
||||
// 扣除手续费
|
||||
$chargeRate = floatval(UserTransferService::config('charge'));
|
||||
$data['charge_rate'] = $chargeRate;
|
||||
$data['charge_amount'] = $chargeRate * $data['amount'] / 100;
|
||||
// 检查可提现余额
|
||||
[$total, $count] = UserRebateService::amount($this->uuid);
|
||||
if ($total - $count < $data['amount']) $this->error('可提现余额不足!');
|
||||
// 提现方式处理
|
||||
if ($data['type'] == 'alipay_account') {
|
||||
$data = array_merge($data, $this->_vali([
|
||||
'alipay_user.require' => '开户姓名不能为空!',
|
||||
'alipay_code.require' => '支付账号不能为空!',
|
||||
]));
|
||||
} elseif (in_array($data['type'], ['wechat_qrcode', 'alipay_qrcode'])) {
|
||||
$data = array_merge($data, $this->_vali([
|
||||
'qrcode.require' => '收款码不能为空!',
|
||||
]));
|
||||
} elseif (in_array($data['type'], ['wechat_banks', 'transfer_banks'])) {
|
||||
$data = array_merge($data, $this->_vali([
|
||||
'bank_wseq.require' => '银行编号不能为空!',
|
||||
'bank_name.require' => '银行名称不能为空!',
|
||||
'bank_user.require' => '开户账号不能为空!',
|
||||
'bank_bran.require' => '银行分行不能为空!',
|
||||
'bank_code.require' => '银行卡号不能为空!',
|
||||
]));
|
||||
} elseif ($data['type'] != 'wechat_wallet') {
|
||||
$this->error('转账方式不存在!');
|
||||
}
|
||||
// 当日提现次数限制
|
||||
$map = ['uuid' => $this->uuid, 'type' => $data['type'], 'date' => $data['date']];
|
||||
$count = DataUserTransfer::mk()->where($map)->count();
|
||||
if ($count >= $transfers[$data['type']]['dayNumber']) $this->error("当日提现次数受限");
|
||||
// 提现金额范围控制
|
||||
if ($transfers[$data['type']]['minAmount'] > $data['amount']) {
|
||||
$this->error("不能少于{$transfers[$data['type']]['minAmount']}元");
|
||||
}
|
||||
if ($transfers[$data['type']]['maxAmount'] < $data['amount']) {
|
||||
$this->error("不能大于{$transfers[$data['type']]['maxAmount']}元");
|
||||
}
|
||||
// 写入用户提现数据
|
||||
if (DataUserTransfer::mk()->insert($data) !== false) {
|
||||
UserRebateService::amount($this->uuid);
|
||||
$this->success('提现申请成功');
|
||||
} else {
|
||||
$this->error('提现申请失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户提现记录
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
$query = DataUserTransfer::mQuery()->where(['uuid' => $this->uuid]);
|
||||
$result = $query->like('date,code')->in('status')->order('id desc')->page(true, false, false, 10);
|
||||
// 统计历史数据
|
||||
$map = [['uuid', '=', $this->uuid], ['status', '>', 0]];
|
||||
[$total, $count, $locks] = UserRebateService::amount($this->uuid);
|
||||
$this->success('获取提现成功', array_merge($result, [
|
||||
'total' => [
|
||||
'锁定' => $locks,
|
||||
'可提' => $total - $count,
|
||||
'上月' => DataUserTransfer::mk()->where($map)->whereLike('date', date("Y-m-%", strtotime('-1 month')))->sum('amount'),
|
||||
'本月' => DataUserTransfer::mk()->where($map)->whereLike('date', date("Y-m-%"))->sum('amount'),
|
||||
'全年' => DataUserTransfer::mk()->where($map)->whereLike('date', date("Y-%"))->sum('amount'),
|
||||
],
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户取消提现
|
||||
*/
|
||||
public function cancel()
|
||||
{
|
||||
$data = $this->_vali(['uuid.value' => $this->uuid, 'code.require' => '单号不能为空!']);
|
||||
DataUserTransfer::mk()->where($data)->whereIn('status', [1, 2, 3])->update([
|
||||
'status' => 0, 'change_time' => date("Y-m-d H:i:s"), 'change_desc' => '用户主动取消提现',
|
||||
]);
|
||||
UserRebateService::amount($this->uuid);
|
||||
$this->success('取消提现成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户确认提现
|
||||
*/
|
||||
public function confirm()
|
||||
{
|
||||
$data = $this->_vali(['uuid.value' => $this->uuid, 'code.require' => '单号不能为空!']);
|
||||
DataUserTransfer::mk()->where($data)->whereIn('status', [4])->update([
|
||||
'status' => 5, 'change_time' => date("Y-m-d H:i:s"), 'change_desc' => '用户主动确认收款',
|
||||
]);
|
||||
UserRebateService::amount($this->uuid);
|
||||
$this->success('确认收款成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户提现配置
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function config()
|
||||
{
|
||||
$data = UserTransferService::config();
|
||||
$data['banks'] = UserTransferService::instance()->banks();
|
||||
$this->success('获取用户提现配置', $data);
|
||||
}
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\base;
|
||||
|
||||
use think\admin\Controller;
|
||||
|
||||
/**
|
||||
* 应用参数配置
|
||||
* Class Config
|
||||
* @package app\data\controller\base
|
||||
*/
|
||||
class Config extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* 微信小程序配置
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function wxapp()
|
||||
{
|
||||
$this->skey = 'wxapp';
|
||||
$this->title = '微信小程序配置';
|
||||
$this->__sysdata('wxapp');
|
||||
}
|
||||
|
||||
/**
|
||||
* 邀请二维码设置
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function cropper()
|
||||
{
|
||||
$this->skey = 'cropper';
|
||||
$this->title = '邀请二维码设置';
|
||||
$this->__sysdata('cropper');
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示并保存数据
|
||||
* @param string $template 模板文件
|
||||
* @param string $history 跳转处理
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function __sysdata(string $template, string $history = '')
|
||||
{
|
||||
if ($this->request->isGet()) {
|
||||
$this->data = sysdata($this->skey);
|
||||
$this->fetch($template);
|
||||
}
|
||||
if ($this->request->isPost()) {
|
||||
if (is_string(input('data'))) {
|
||||
$data = json_decode(input('data'), true) ?: [];
|
||||
} else {
|
||||
$data = $this->request->post();
|
||||
}
|
||||
if (sysdata($this->skey, $data) !== false) {
|
||||
$this->success('内容保存成功!', $history);
|
||||
} else {
|
||||
$this->error('内容保存失败,请稍候再试!');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\base;
|
||||
|
||||
use app\data\model\BaseUserDiscount;
|
||||
use app\data\model\BaseUserUpgrade;
|
||||
use app\data\service\UserUpgradeService;
|
||||
use think\admin\Controller;
|
||||
use think\admin\helper\QueryHelper;
|
||||
|
||||
/**
|
||||
* 折扣方案管理
|
||||
* Class Discount
|
||||
* @package app\data\controller\base
|
||||
*/
|
||||
class Discount extends Controller
|
||||
{
|
||||
/**
|
||||
* 折扣方案管理
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->type = input('get.type', 'index');
|
||||
BaseUserDiscount::mQuery()->layTable(function () {
|
||||
$this->title = '折扣方案管理';
|
||||
}, function (QueryHelper $query) {
|
||||
$query->where(['status' => intval($this->type === 'index'), 'deleted' => 0]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加折扣方案
|
||||
* @auth true
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
BaseUserDiscount::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑折扣方案
|
||||
* @auth true
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
BaseUserDiscount::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单数据处理
|
||||
* @param array $vo
|
||||
*/
|
||||
protected function _form_filter(array &$vo)
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$rule = [];
|
||||
foreach ($vo as $k => $v) if (stripos($k, '_level_') !== false) {
|
||||
[, $level] = explode('_level_', $k);
|
||||
$rule[] = ['level' => $level, 'discount' => $v];
|
||||
}
|
||||
$vo['items'] = json_encode($rule, JSON_UNESCAPED_UNICODE);
|
||||
} else {
|
||||
$this->levels = BaseUserUpgrade::items();
|
||||
if (empty($this->levels)) $this->error('未配置用户等级!');
|
||||
foreach ($vo['items'] ?? [] as $item) {
|
||||
$vo["_level_{$item['level']}"] = $item['discount'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改折扣方案状态
|
||||
* @auth true
|
||||
*/
|
||||
public function state()
|
||||
{
|
||||
BaseUserDiscount::mSave();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除折扣方案配置
|
||||
* @auth true
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
BaseUserDiscount::mDelete();
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\base;
|
||||
|
||||
use app\data\model\BaseUserMessage;
|
||||
use think\admin\Controller;
|
||||
use think\admin\helper\QueryHelper;
|
||||
|
||||
/**
|
||||
* 系统通知管理
|
||||
* Class Notify
|
||||
* @package app\data\controller\base
|
||||
*/
|
||||
class Message extends Controller
|
||||
{
|
||||
/**
|
||||
* 系统通知管理
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
BaseUserMessage::mQuery()->layTable(function () {
|
||||
$this->title = '系统通知管理';
|
||||
}, function (QueryHelper $query) {
|
||||
$query->where(['deleted' => 0]);
|
||||
$query->like('name')->equal('status')->dateBetween('create_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加系统通知
|
||||
* @auth true
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$this->title = '添加系统通知';
|
||||
BaseUserMessage::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑系统通知
|
||||
* @auth true
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$this->title = '编辑系统通知';
|
||||
BaseUserMessage::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单结果处理
|
||||
* @param boolean $state
|
||||
*/
|
||||
protected function _form_result(bool $state)
|
||||
{
|
||||
if ($state) {
|
||||
$this->success('内容保存成功!', 'javascript:history.back()');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改通知状态
|
||||
* @auth true
|
||||
*/
|
||||
public function state()
|
||||
{
|
||||
BaseUserMessage::mSave($this->_vali([
|
||||
'status.in:0,1' => '状态值范围异常!',
|
||||
'status.require' => '状态值不能为空!',
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除系统通知
|
||||
* @auth true
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
BaseUserMessage::mDelete();
|
||||
}
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\base;
|
||||
|
||||
use think\admin\Controller;
|
||||
use think\admin\model\SystemBase;
|
||||
|
||||
/**
|
||||
* 页面内容管理
|
||||
* Class Pager
|
||||
* @package app\data\controller\base
|
||||
*/
|
||||
class Pager extends Controller
|
||||
{
|
||||
/**
|
||||
* 字典类型
|
||||
* @var string
|
||||
*/
|
||||
protected $type = '页面内容';
|
||||
|
||||
/**
|
||||
* 页面类型
|
||||
* @var array
|
||||
*/
|
||||
protected $types = [];
|
||||
|
||||
/**
|
||||
* 控制器初始化
|
||||
* @return void
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
$this->types = SystemBase::mk()->items($this->type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 内容页面管理
|
||||
* @auth true
|
||||
* @menu true
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->title = '内容页面管理';
|
||||
$this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 内容页面编辑
|
||||
* @auth true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$this->skey = input('get.type', '');
|
||||
$this->base = $this->types[$this->skey] ?? [];
|
||||
if (empty($this->base)) $this->error('未配置基础数据!');
|
||||
$this->title = "编辑{$this->base['name']}";
|
||||
$this->sysdata();
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示并保存数据
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function sysdata()
|
||||
{
|
||||
if ($this->request->isGet()) {
|
||||
$this->data = sysdata($this->skey);
|
||||
$this->fetch('form');
|
||||
} elseif ($this->request->isPost()) {
|
||||
if (is_string(input('data'))) {
|
||||
$data = json_decode(input('data'), true) ?: [];
|
||||
} else {
|
||||
$data = $this->request->post();
|
||||
}
|
||||
if (sysdata($this->skey, $data) !== false) {
|
||||
$this->success('内容保存成功!', 'javascript:history.back()');
|
||||
} else {
|
||||
$this->error('内容保存失败,请稍候再试!');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,134 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\base;
|
||||
|
||||
use app\data\model\BaseUserPayment;
|
||||
use app\data\service\PaymentService;
|
||||
use app\data\service\UserAdminService;
|
||||
use think\admin\Controller;
|
||||
use think\admin\extend\CodeExtend;
|
||||
use think\admin\helper\QueryHelper;
|
||||
|
||||
/**
|
||||
* 支付通道管理
|
||||
* Class Payment
|
||||
* @package app\data\controller\base
|
||||
*/
|
||||
class Payment extends Controller
|
||||
{
|
||||
/**
|
||||
* 支付通道类型
|
||||
* @var array
|
||||
*/
|
||||
protected $types = PaymentService::TYPES;
|
||||
|
||||
/**
|
||||
* 支付通道管理
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->type = input('get.type', 'index');
|
||||
BaseUserPayment::mQuery()->layTable(function () {
|
||||
$this->title = '支付通道管理';
|
||||
}, function (QueryHelper $query) {
|
||||
$query->where(['status' => intval($this->type === 'index'), 'deleted' => 0]);
|
||||
$query->like('name,code')->equal('status,type#ptype')->dateBetween('create_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支付名称
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
protected function _page_filter(array &$data)
|
||||
{
|
||||
foreach ($data as &$vo) {
|
||||
$vo['ntype'] = $this->types[$vo['type']]['name'] ?? $vo['type'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加支付通道
|
||||
* @auth true
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$this->title = '添加支付通道';
|
||||
BaseUserPayment::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑支付通道
|
||||
* @auth true
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$this->title = '编辑支付通道';
|
||||
BaseUserPayment::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据表单处理
|
||||
* @param array $data
|
||||
*/
|
||||
protected function _form_filter(array &$data)
|
||||
{
|
||||
if (empty($data['code'])) {
|
||||
$data['code'] = CodeExtend::uniqidNumber(20, 'M');
|
||||
}
|
||||
if ($this->request->isGet()) {
|
||||
$this->payments = [];
|
||||
foreach ($this->types as $k => $vo) {
|
||||
$allow = [];
|
||||
foreach ($vo['bind'] as $api) if (isset(UserAdminService::TYPES[$api])) {
|
||||
$allow[$api] = UserAdminService::TYPES[$api]['name'];
|
||||
}
|
||||
if (empty($allow)) continue;
|
||||
$this->payments[$k] = array_merge($vo, ['allow' => join('、', $allow)]);
|
||||
}
|
||||
$data['content'] = json_decode($data['content'] ?? '[]', true) ?: [];
|
||||
} else {
|
||||
if (empty($data['type'])) $this->error('请选择支付通道并配置参数!');
|
||||
if (empty($data['cover'])) $this->error('请上传支付方式图标!');
|
||||
$data['content'] = json_encode($this->request->post() ?: [], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单结果处理
|
||||
* @param boolean $state
|
||||
*/
|
||||
protected function _form_result(bool $state)
|
||||
{
|
||||
if ($state) {
|
||||
$this->success('支付通道保存成功!', 'javascript:history.back()');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改通道状态
|
||||
* @auth true
|
||||
*/
|
||||
public function state()
|
||||
{
|
||||
BaseUserPayment::mSave($this->_vali([
|
||||
'status.in:0,1' => '状态值范围异常!',
|
||||
'status.require' => '状态值不能为空!',
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除支付通道
|
||||
* @auth true
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
BaseUserPayment::mDelete();
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\base;
|
||||
|
||||
use think\admin\Controller;
|
||||
use think\admin\model\SystemBase;
|
||||
|
||||
/**
|
||||
* 图片内容管理
|
||||
* Class Slider
|
||||
* @package app\data\controller\base
|
||||
*/
|
||||
class Slider extends Controller
|
||||
{
|
||||
/**
|
||||
* 跳转规则定义
|
||||
* @var string[]
|
||||
*/
|
||||
protected $rules = [
|
||||
'#' => ['name' => '不跳转'],
|
||||
'LK' => ['name' => '自定义链接'],
|
||||
'NL' => ['name' => '新闻资讯列表'],
|
||||
'NS' => ['name' => '新闻资讯详情', 'node' => 'data/news.item/select'],
|
||||
];
|
||||
|
||||
/**
|
||||
* 数据类型
|
||||
* @var string
|
||||
*/
|
||||
protected $type = '图片内容';
|
||||
|
||||
/**
|
||||
* 页面类型
|
||||
* @var array
|
||||
*/
|
||||
protected $types = [];
|
||||
|
||||
/**
|
||||
* 控制器初始化
|
||||
* @return void
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
$this->types = SystemBase::mk()->items($this->type);
|
||||
foreach ($this->types as &$type) {
|
||||
if (preg_match('/^(.*?)#(\d+)$/', $type['name'], $matches)) {
|
||||
$type['name'] = $matches[1];
|
||||
$type['number'] = $matches[2];
|
||||
} else {
|
||||
$type['number'] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片内容管理
|
||||
* @auth true
|
||||
* @menu true
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->title = '图片内容管理';
|
||||
$this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑图片内容
|
||||
* @auth true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$this->skey = input('get.type', '');
|
||||
$this->base = $this->types[$this->skey] ?? [];
|
||||
if (empty($this->base)) $this->error('未配置基础数据!');
|
||||
$this->number = $this->base['number'];
|
||||
$this->sysdata();
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存图片内容
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function sysdata()
|
||||
{
|
||||
if ($this->request->isGet()) {
|
||||
$this->data = sysdata($this->skey);
|
||||
$this->title = "{$this->base['name']}管理";
|
||||
$this->fetch('form');
|
||||
} else {
|
||||
if (sysdata($this->skey, json_decode(input('data'), true))) {
|
||||
$this->success("{$this->base['name']}保存成功!");
|
||||
} else {
|
||||
$this->error("{$this->base['name']}保存失败,请稍候再试!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,156 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\base;
|
||||
|
||||
use app\data\model\BaseUserUpgrade;
|
||||
use app\data\service\RebateService;
|
||||
use think\admin\Controller;
|
||||
|
||||
/**
|
||||
* 用户等级管理
|
||||
* Class Upgrade
|
||||
* @package app\data\controller\base
|
||||
*/
|
||||
class Upgrade extends Controller
|
||||
{
|
||||
/**
|
||||
* 用户等级管理
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->title = '用户等级管理';
|
||||
BaseUserUpgrade::mQuery()->like('name')->equal('status')->dateBetween('create_at')->layTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加用户等级
|
||||
* @auth true
|
||||
* @return void
|
||||
* @throws \think\db\exception\DbException
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$this->max = BaseUserUpgrade::maxNumber() + 1;
|
||||
BaseUserUpgrade::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑用户等级
|
||||
* @auth true
|
||||
* @return void
|
||||
* @throws \think\db\exception\DbException
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$this->max = BaseUserUpgrade::maxNumber();
|
||||
BaseUserUpgrade::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单数据处理
|
||||
* @param array $vo
|
||||
* @throws \think\db\exception\DbException
|
||||
*/
|
||||
protected function _form_filter(array &$vo)
|
||||
{
|
||||
if ($this->request->isGet()) {
|
||||
$this->prizes = RebateService::PRIZES;
|
||||
$vo['number'] = $vo['number'] ?? BaseUserUpgrade::maxNumber();
|
||||
} else {
|
||||
$vo['utime'] = time();
|
||||
// 用户升级条件开关
|
||||
$vo['goods_vip_status'] = isset($vo['goods_vip_status']) ? 1 : 0;
|
||||
$vo['teams_users_status'] = isset($vo['teams_users_status']) ? 1 : 0;
|
||||
$vo['teams_direct_status'] = isset($vo['teams_direct_status']) ? 1 : 0;
|
||||
$vo['teams_indirect_status'] = isset($vo['teams_indirect_status']) ? 1 : 0;
|
||||
$vo['order_amount_status'] = isset($vo['order_amount_status']) ? 1 : 0;
|
||||
// 默认等级去除条件
|
||||
if (empty($vo['number'])) {
|
||||
$vo['rebate_rule'] = [];
|
||||
foreach ($vo as $k => &$v) if (is_numeric(stripos($k, '_status'))) $v = 0;
|
||||
}
|
||||
// 根据数量判断状态
|
||||
$vo['teams_users_status'] = intval($vo['teams_users_status'] && $vo['teams_users_number'] > 0);
|
||||
$vo['teams_direct_status'] = intval($vo['teams_direct_status'] && $vo['teams_direct_number'] > 0);
|
||||
$vo['teams_indirect_status'] = intval($vo['teams_indirect_status'] && $vo['teams_indirect_number'] > 0);
|
||||
$vo['order_amount_status'] = intval($vo['order_amount_status'] && $vo['order_amount_number'] > 0);
|
||||
// 检查升级条件配置
|
||||
$count = 0;
|
||||
foreach ($vo as $k => $v) if (is_numeric(stripos($k, '_status'))) $count += $v;
|
||||
if (empty($count) && $vo['number'] > 0) $this->error('升级条件不能为空!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单结果处理
|
||||
* @param boolean $state
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function _form_result(bool $state)
|
||||
{
|
||||
if ($state) {
|
||||
$isasc = input('old_number', 0) <= input('number', 0);
|
||||
$order = $isasc ? 'number asc,utime asc' : 'number asc,utime desc';
|
||||
foreach (BaseUserUpgrade::mk()->order($order)->select() as $number => $upgrade) {
|
||||
$upgrade->save(['number' => $number]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重算用户等级
|
||||
* @auth true
|
||||
*/
|
||||
public function sync()
|
||||
{
|
||||
$this->_queue('重新计算所有用户等级', 'xdata:UserUpgrade');
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改等级状态
|
||||
* @auth true
|
||||
*/
|
||||
public function state()
|
||||
{
|
||||
BaseUserUpgrade::mSave();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户等级
|
||||
* @auth true
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
BaseUserUpgrade::mDelete();
|
||||
}
|
||||
|
||||
/**
|
||||
* 状态变更处理
|
||||
* @auth true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
protected function _save_result()
|
||||
{
|
||||
$this->_form_result(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除结果处理
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
protected function _delete_result()
|
||||
{
|
||||
$this->_form_result(true);
|
||||
}
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\data\controller\base\postage;
|
||||
|
||||
use app\data\model\BasePostageCompany;
|
||||
use app\data\service\ExpressService;
|
||||
use think\admin\Controller;
|
||||
use think\admin\helper\QueryHelper;
|
||||
use think\exception\HttpResponseException;
|
||||
|
||||
/**
|
||||
* 快递公司管理
|
||||
* Class Company
|
||||
* @package app\data\controller\base\postage
|
||||
*/
|
||||
class Company extends Controller
|
||||
{
|
||||
/**
|
||||
* 快递公司管理
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->type = input('get.type', 'index');
|
||||
BasePostageCompany::mQuery()->layTable(function () {
|
||||
$this->title = '快递公司管理';
|
||||
}, function (QueryHelper $query) {
|
||||
$query->where(['deleted' => 0, 'status' => intval($this->type === 'index')]);
|
||||
$query->like('name,code_1|code_3#code')->equal('status')->dateBetween('create_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加快递公司
|
||||
* @auth true
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$this->title = '添加快递公司';
|
||||
BasePostageCompany::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑快递公司
|
||||
* @auth true
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$this->title = '编辑快递公司';
|
||||
BasePostageCompany::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步字段编号
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
protected function _form_filter(array &$data)
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
if (empty($data['code_2'])) {
|
||||
$data['code_2'] = $data['code_3'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改快递公司状态
|
||||
* @auth true
|
||||
*/
|
||||
public function state()
|
||||
{
|
||||
BasePostageCompany::mSave($this->_vali([
|
||||
'status.in:0,1' => '状态值范围异常!',
|
||||
'status.require' => '状态值不能为空!',
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除快递公司
|
||||
* @auth true
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
BasePostageCompany::mDelete();
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步快递公司
|
||||
* @auth true
|
||||
*/
|
||||
public function sync()
|
||||
{
|
||||
try {
|
||||
$result = ExpressService::company();
|
||||
if (empty($result['code'])) $this->error($result['info']);
|
||||
foreach ($result['data'] as $vo) BasePostageCompany::mUpdate([
|
||||
'name' => $vo['title'],
|
||||
'code_1' => $vo['code_1'],
|
||||
'code_2' => $vo['code_2'],
|
||||
'code_3' => $vo['code_3'],
|
||||
'deleted' => 0,
|
||||
], 'code_1');
|
||||
$this->success('同步快递公司成功!');
|
||||
} catch (HttpResponseException $exception) {
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
$this->error('同步快递公司数据失败!');
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user