Compare commits

..

No commits in common. "f1c12215c287501a4be54b2abaeefe0dd4aaa7ef" and "5d5305a454777ab7122e82003008dfb41b9b94a0" have entirely different histories.

67 changed files with 1182 additions and 2007 deletions

File diff suppressed because it is too large Load Diff

View File

@ -7613,54 +7613,98 @@ CREATE TABLE `system_menu`
-- ----------------------------
-- Records of system_menu
-- ----------------------------
INSERT INTO `system_menu` VALUES (1, 0, '控制台', '', '', '#', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (2, 1, '数据管理', '', '', '#', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (3, 2, '数据统计报表', 'layui-icon layui-icon-theme', 'data/total.portal/index', 'data/total.portal/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (4, 2, '轮播图片管理', 'layui-icon layui-icon-carousel', 'data/base.slider/index', 'data/base.slider/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (5, 2, '页面内容管理', 'layui-icon layui-icon-read', 'data/base.pager/index', 'data/base.pager/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (6, 2, '文章内容管理', 'layui-icon layui-icon-template', 'data/news.item/index', 'data/news.item/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (7, 2, '支付参数管理', 'layui-icon layui-icon-rmb', 'data/base.payment/index', 'data/base.payment/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (8, 2, '系统通知管理', 'layui-icon layui-icon-notice', 'data/base.message/index', 'data/base.message/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (9, 2, '微信小程序配置', 'layui-icon layui-icon-set', 'data/base.config/wxapp', 'data/base.config/wxapp', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (10, 2, '邀请二维码设置', 'layui-icon layui-icon-cols', 'data/base.config/cropper', 'data/base.config/cropper', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (11, 1, '用户管理', '', '', '#', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (12, 11, '会员用户管理', 'layui-icon layui-icon-user', 'data/user.admin/index', 'data/user.admin/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (13, 11, '余额充值管理', 'layui-icon layui-icon-rmb', 'data/user.balance/index', 'data/user.balance/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (14, 11, '用户返利管理', 'layui-icon layui-icon-transfer', 'data/user.rebate/index', 'data/user.rebate/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (15, 11, '用户提现管理', 'layui-icon layui-icon-component', 'data/user.transfer/index', 'data/user.transfer/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (16, 11, '用户等级管理', 'layui-icon layui-icon-senior', 'data/base.upgrade/index', 'data/base.upgrade/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (17, 11, '用户折扣方案', 'layui-icon layui-icon-set', 'data/base.discount/index', 'data/base.discount/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (18, 1, '商城管理', '', '', '#', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (19, 18, '商品数据管理', 'layui-icon layui-icon-star', 'data/shop.goods/index', 'data/shop.goods/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (20, 18, '商品分类管理', 'layui-icon layui-icon-tabs', 'data/shop.cate/index', 'data/shop.cate/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (21, 18, '订单数据管理', 'layui-icon layui-icon-template', 'data/shop.order/index', 'data/shop.order/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (22, 18, '订单发货管理', 'layui-icon layui-icon-transfer', 'data/shop.send/index', 'data/shop.send/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (23, 18, '快递公司管理', 'layui-icon layui-icon-website', 'data/base.postage.company/index', 'data/base.postage.company/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (24, 18, '邮费模板管理', 'layui-icon layui-icon-template-1', 'data/base.postage.template/index', 'data/base.postage.template/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (25, 0, '微信管理', '', '', '#', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (26, 25, '微信管理', '', '', '#', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (27, 26, '微信接口配置', 'layui-icon layui-icon-set', '', 'wechat/config/options', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (28, 26, '微信支付配置', 'layui-icon layui-icon-rmb', '', 'wechat/config/payment', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (29, 25, '微信定制', '', '', '#', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (30, 29, '微信粉丝管理', 'layui-icon layui-icon-username', '', 'wechat/fans/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (31, 29, '微信图文管理', 'layui-icon layui-icon-template-1', '', 'wechat/news/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (32, 29, '微信菜单配置', 'layui-icon layui-icon-cellphone', '', 'wechat/menu/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (33, 29, '回复规则管理', 'layui-icon layui-icon-engine', '', 'wechat/keys/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (34, 29, '关注回复配置', 'layui-icon layui-icon-senior', '', 'wechat/keys/subscribe', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (35, 29, '默认回复配置', 'layui-icon layui-icon-util', '', 'wechat/keys/defaults', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (36, 29, '关注自动回复', 'layui-icon layui-icon-release', 'wechat/auto/index', 'wechat/auto/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (37, 0, '系统管理', '', '', '#', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (38, 37, '系统配置', '', '', '#', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (39, 38, '系统参数配置', 'layui-icon layui-icon-set', '', 'admin/config/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (40, 38, '系统任务管理', 'layui-icon layui-icon-log', '', 'admin/queue/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (41, 38, '系统日志管理', 'layui-icon layui-icon-form', '', 'admin/oplog/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (42, 38, '数据字典管理', 'layui-icon layui-icon-code-circle', 'admin/base/index', 'admin/base/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (43, 38, '系统文件管理', 'layui-icon layui-icon-carousel', 'admin/file/index', 'admin/file/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (44, 38, '系统菜单管理', 'layui-icon layui-icon-layouts', '', 'admin/menu/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (45, 37, '权限管理', '', '', '#', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (46, 45, '访问权限管理', 'layui-icon layui-icon-vercode', '', 'admin/auth/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu` VALUES (47, 45, '系统用户管理', 'layui-icon layui-icon-username', '', 'admin/user/index', '', '_self', 0, 1, '2022-06-27 14:29:17');
INSERT INTO `system_menu`
VALUES (1, 0, '控制台', '', '', '#', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (2, 1, '数据管理', '', '', '#', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (3, 2, '数据统计报表', 'layui-icon layui-icon-theme', 'data/total.portal/index', 'data/total.portal/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (4, 2, '轮播图片管理', 'layui-icon layui-icon-carousel', 'data/base.slider/index', 'data/base.slider/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (5, 2, '页面内容管理', 'layui-icon layui-icon-read', 'data/base.pager/index', 'data/base.pager/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (6, 2, '文章内容管理', 'layui-icon layui-icon-template', 'data/news.item/index', 'data/news.item/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (7, 2, '支付参数管理', 'layui-icon layui-icon-rmb', 'data/base.payment/index', 'data/base.payment/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (8, 2, '系统通知管理', 'layui-icon layui-icon-notice', 'data/base.message/index', 'data/base.message/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (9, 2, '微信小程序配置', 'layui-icon layui-icon-set', 'data/base.config/wxapp', 'data/base.config/wxapp', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (10, 2, '邀请二维码设置', 'layui-icon layui-icon-cols', 'data/base.config/cropper', 'data/base.config/cropper', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (11, 1, '用户管理', '', '', '#', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (12, 11, '会员用户管理', 'layui-icon layui-icon-user', 'data/user.admin/index', 'data/user.admin/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (13, 11, '余额充值管理', 'layui-icon layui-icon-rmb', 'data/user.balance/index', 'data/user.balance/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (14, 11, '用户返利管理', 'layui-icon layui-icon-transfer', 'data/user.rebate/index', 'data/user.rebate/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (15, 11, '用户提现管理', 'layui-icon layui-icon-component', 'data/user.transfer/index', 'data/user.transfer/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (16, 11, '用户等级管理', 'layui-icon layui-icon-senior', 'data/base.upgrade/index', 'data/base.upgrade/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (17, 11, '用户折扣方案', 'layui-icon layui-icon-set', 'data/base.discount/index', 'data/base.discount/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (18, 1, '商城管理', '', '', '#', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (19, 18, '商品数据管理', 'layui-icon layui-icon-star', 'data/shop.goods/index', 'data/shop.goods/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (20, 18, '商品分类管理', 'layui-icon layui-icon-tabs', 'data/shop.cate/index', 'data/shop.cate/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (21, 18, '订单数据管理', 'layui-icon layui-icon-template', 'data/shop.order/index', 'data/shop.order/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (22, 18, '订单发货管理', 'layui-icon layui-icon-transfer', 'data/shop.send/index', 'data/shop.send/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (23, 18, '快递公司管理', 'layui-icon layui-icon-website', 'data/base.postage.company/index', 'data/base.postage.company/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (24, 18, '邮费模板管理', 'layui-icon layui-icon-template-1', 'data/base.postage.template/index', 'data/base.postage.template/index', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (25, 0, '微信管理', '', '', '#', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (26, 25, '微信管理', '', '', '#', '', '_self', 0, 1, '2022-03-04 20:34:40');
INSERT INTO `system_menu`
VALUES (27, 26, '微信接口配置', 'layui-icon layui-icon-set', '', 'wechat/config/options', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (28, 26, '微信支付配置', 'layui-icon layui-icon-rmb', '', 'wechat/config/payment', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (29, 25, '微信定制', '', '', '#', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (30, 29, '微信粉丝管理', 'layui-icon layui-icon-username', '', 'wechat/fans/index', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (31, 29, '微信图文管理', 'layui-icon layui-icon-template-1', '', 'wechat/news/index', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (32, 29, '微信菜单配置', 'layui-icon layui-icon-cellphone', '', 'wechat/menu/index', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (33, 29, '回复规则管理', 'layui-icon layui-icon-engine', '', 'wechat/keys/index', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (34, 29, '关注回复配置', 'layui-icon layui-icon-senior', '', 'wechat/keys/subscribe', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (35, 29, '默认回复配置', 'layui-icon layui-icon-util', '', 'wechat/keys/defaults', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (36, 29, '关注自动回复', 'layui-icon layui-icon-release', 'wechat/auto/index', 'wechat/auto/index', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (37, 0, '系统管理', '', '', '#', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (38, 37, '系统配置', '', '', '#', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (39, 38, '系统参数配置', 'layui-icon layui-icon-set', '', 'admin/config/index', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (40, 38, '系统任务管理', 'layui-icon layui-icon-log', '', 'admin/queue/index', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (41, 38, '系统日志管理', 'layui-icon layui-icon-form', '', 'admin/oplog/index', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (42, 38, '数据字典管理', 'layui-icon layui-icon-code-circle', 'admin/base/index', 'admin/base/index', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (43, 38, '系统菜单管理', 'layui-icon layui-icon-layouts', '', 'admin/menu/index', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (44, 37, '权限管理', '', '', '#', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (45, 44, '访问权限管理', 'layui-icon layui-icon-vercode', '', 'admin/auth/index', '', '_self', 0, 1, '2022-03-04 20:34:41');
INSERT INTO `system_menu`
VALUES (46, 44, '系统用户管理', 'layui-icon layui-icon-username', '', 'admin/user/index', '', '_self', 0, 1, '2022-03-04 20:34:41');
-- ----------------------------
-- Table structure for system_user

View File

@ -66,31 +66,4 @@ CREATE TABLE IF NOT EXISTS `system_base`
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;

View File

@ -94,9 +94,10 @@ class Auth extends Controller
{
$map = $this->_vali(['auth.require#id' => '权限ID不能为空']);
if (input('action') === 'get') {
if ($this->app->isDebug()) AdminService::clearCache();
$admin = AdminService::instance();
if ($this->app->isDebug()) $admin->clearCache();
$nodes = SystemNode::mk()->where($map)->column('node');
$this->success('获取权限节点成功!', AdminService::getTree($nodes));
$this->success('获取权限节点成功!', $admin->getTree($nodes));
} elseif (input('action') === 'save') {
[$post, $data] = [$this->request->post(), []];
foreach ($post['nodes'] ?? [] as $node) {

View File

@ -52,8 +52,8 @@ class Config extends Controller
public function index()
{
$this->title = '系统参数配置';
$this->super = AdminService::isSuper();
$this->version = ModuleService::getVersion();
$this->super = AdminService::instance()->isSuper();
$this->version = ModuleService::instance()->getVersion();
$this->fetch();
}
@ -81,11 +81,11 @@ class Config extends Controller
if ($post['xpath'] !== 'admin' && file_exists($this->app->getBasePath() . $post['xpath'])) {
$this->error("后台入口名称{$post['xpath']}已经存在应用!");
}
SystemService::setRuntime(null, [$post['xpath'] => 'admin']);
SystemService::instance()->setRuntime(null, [$post['xpath'] => 'admin']);
}
// 修改网站 ICON 图标文件,替换 public/favicon.ico 文件
if (preg_match('#^https?://#', $icon = $post['site_icon'] ?? '')) try {
SystemService::setFavicon($icon);
SystemService::instance()->setFavicon($icon);
} catch (\Exception $exception) {
trace_file($exception);
$this->error($exception->getMessage());

View File

@ -1,83 +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;
/**
* 系统文件管理
* Class File
* @package app\admin\controller
*/
class File extends Controller
{
/**
* 存储方式处理
* @var string[]
*/
protected $types = [
'local' => '本地服务器存储',
'qiniu' => '七牛云对象存储',
'upyun' => '又拍云USS存储',
'alioss' => '阿里云OSS存储',
'txcos' => '腾讯云COS存储'
];
/**
* 系统文件管理
* @auth true
* @menu true
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
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();
}
}

View File

@ -38,18 +38,19 @@ class Index extends Controller
public function index()
{
/*! 根据运行模式刷新权限 */
AdminService::apply($this->app->isDebug());
$debug = $this->app->isDebug();
AdminService::instance()->apply($debug);
/*! 读取当前用户权限菜单树 */
$this->menus = MenuService::getTree();
$this->menus = MenuService::instance()->getTree();
/*! 判断当前用户的登录状态 */
$this->login = AdminService::isLogin();
$this->login = AdminService::instance()->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->super = AdminService::instance()->isSuper();
$this->theme = AdminService::instance()->getUserTheme();
$this->fetch();
}
}
@ -65,12 +66,12 @@ class Index extends Controller
public function theme()
{
if ($this->request->isGet()) {
$this->theme = AdminService::getUserTheme();
$this->theme = AdminService::instance()->getUserTheme();
$this->themes = Config::themes;
$this->fetch();
} else {
$data = $this->_vali(['site_theme.require' => '主题名称不能为空!']);
if (AdminService::setUserTheme($data['site_theme'])) {
if (AdminService::instance()->setUserTheme($data['site_theme'])) {
$this->success('主题配置保存成功!');
} else {
$this->error('主题配置保存失败!');
@ -86,7 +87,7 @@ class Index extends Controller
public function info($id = 0)
{
$this->_applyFormToken();
if (AdminService::getUserId() === intval($id)) {
if (AdminService::instance()->getUserId() === intval($id)) {
SystemUser::mForm('admin@user/form', 'id', [], ['id' => $id]);
} else {
$this->error('只能修改自己的资料!');
@ -115,7 +116,7 @@ class Index extends Controller
public function pass($id = 0)
{
$this->_applyFormToken();
if (AdminService::getUserId() !== intval($id)) {
if (AdminService::instance()->getUserId() !== intval($id)) {
$this->error('只能修改当前用户的密码!');
}
if ($this->app->request->isGet()) {

View File

@ -40,14 +40,15 @@ class Login extends Controller
public function index()
{
if ($this->app->request->isGet()) {
if (AdminService::isLogin()) {
if (AdminService::instance()->isLogin()) {
$this->redirect(sysuri('admin/index/index'));
} else {
// 当前运行模式
$this->developMode = SystemService::checkRunMode();
$system = SystemService::instance();
$this->developMode = $system->checkRunMode();
// 后台背景处理
$images = str2arr(sysconf('login_image') ?: '', '|') ?: [
SystemService::uri('/static/theme/img/login/bg1.jpg'), SystemService::uri('/static/theme/img/login/bg2.jpg'),
$system->uri('/static/theme/img/login/bg1.jpg'), $system->uri('/static/theme/img/login/bg2.jpg'),
];
$this->loginStyle = sprintf('style="background-image:url(%s)" data-bg-transition="%s"', $images[0], join(',', $images));
// 登录验证令牌

View File

@ -101,18 +101,18 @@ class Menu extends Controller
if ($this->request->isGet()) {
/* 清理权限节点 */
if ($isDebug = $this->app->isDebug()) {
AdminService::clearCache();
AdminService::instance()->clearCache();
}
/* 选择自己上级菜单 */
$vo['pid'] = $vo['pid'] ?? input('pid', '0');
/* 读取系统功能节点 */
$this->auths = [];
$this->nodes = MenuService::getList($isDebug);
foreach (NodeService::getMethods($isDebug) as $node => $item) {
$this->nodes = MenuService::instance()->getList($isDebug);
foreach (NodeService::instance()->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' => '顶部菜单']]));

View File

@ -34,7 +34,7 @@ class Module extends Controller
public function index()
{
$this->title = '系统模块管理';
$this->modules = ModuleService::change();
$this->modules = ModuleService::instance()->change();
$this->fetch();
}
@ -45,7 +45,7 @@ class Module extends Controller
public function install()
{
$data = $this->_vali(['name.require' => '模块名称不能为空!']);
[$state, $message] = ModuleService::install($data['name']);
[$state, $message] = ModuleService::instance()->install($data['name']);
$state ? $this->success($message) : $this->error($message);
}
@ -56,8 +56,8 @@ class Module extends Controller
public function change()
{
$data = $this->_vali(['name.require' => '模块名称不能为空!']);
$online = ModuleService::online();
$locals = ModuleService::getModules();
$online = ModuleService::instance()->online();
$locals = ModuleService::instance()->getModules();
if (isset($online[$data['name']])) {
$this->module = $online[$data['name']];
$this->current = $locals[$data['name']] ?? [];

View File

@ -44,11 +44,13 @@ class Queue extends Controller
{
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}";
$this->iswin = ProcessService::instance()->iswin();
if ($this->super = AdminService::instance()->isSuper()) {
$process = ProcessService::instance();
if ($process->iswin() || empty($_SERVER['USER'])) {
$this->command = $process->think('xadmin:queue start');
} else {
$this->command = "sudo -u {$_SERVER['USER']} {$process->think('xadmin:queue start')}";
}
}
}, function (QueryHelper $query) {

View File

@ -143,7 +143,7 @@ class User extends Controller
// 用户身份数据
$this->bases = SystemBase::items('身份权限');
// 用户权限管理
$this->superName = AdminService::getSuperName();
$this->superName = AdminService::instance()->getSuperName();
$this->authorizes = SystemAuth::items();
}
}

View File

@ -44,7 +44,7 @@ class Plugs extends Controller
*/
public function optimize()
{
if (AdminService::isSuper()) {
if (AdminService::instance()->isSuper()) {
sysoplog('系统运维管理', '创建数据库优化任务');
$this->_queue('优化数据库所有数据表', 'xadmin:database optimize');
} else {

View File

@ -96,7 +96,7 @@ class Queue extends Controller
*/
public function status()
{
if (AdminService::isSuper()) try {
if (AdminService::instance()->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>";

View File

@ -36,9 +36,9 @@ class Runtime extends Controller
*/
public function push()
{
if (AdminService::isSuper()) try {
AdminService::clearCache();
SystemService::pushRuntime();
if (AdminService::instance()->isSuper()) try {
AdminService::instance()->clearCache();
SystemService::instance()->pushRuntime();
sysoplog('系统运维管理', '刷新创建路由缓存');
$this->success('网站缓存加速成功!', 'javascript:location.reload()');
} catch (HttpResponseException $exception) {
@ -56,9 +56,9 @@ class Runtime extends Controller
*/
public function clear()
{
if (AdminService::isSuper()) try {
AdminService::clearCache();
SystemService::clearRuntime();
if (AdminService::instance()->isSuper()) try {
AdminService::instance()->clearCache();
SystemService::instance()->clearRuntime();
sysoplog('系统运维管理', '清理网站日志缓存');
$this->success('清空日志缓存成功!', 'javascript:location.reload()');
} catch (HttpResponseException $exception) {
@ -76,12 +76,12 @@ class Runtime extends Controller
*/
public function debug()
{
if (AdminService::isSuper()) if (input('state')) {
SystemService::setRuntime('product');
if (AdminService::instance()->isSuper()) if (input('state')) {
SystemService::instance()->setRuntime('product');
sysoplog('系统运维管理', '开发模式切换为生产模式');
$this->success('已切换为生产模式!', 'javascript:location.reload()');
} else {
SystemService::setRuntime('debug');
SystemService::instance()->setRuntime('debug');
sysoplog('系统运维管理', '生产模式切换为开发模式');
$this->success('已切换为开发模式!', 'javascript:location.reload()');
} else {
@ -98,7 +98,7 @@ class Runtime extends Controller
*/
public function editor()
{
if (AdminService::isSuper()) {
if (AdminService::instance()->isSuper()) {
$editor = input('editor', 'auto');
sysconf('base.editor', $editor);
sysoplog('系统运维管理', "切换编辑器为{$editor}");
@ -114,7 +114,7 @@ class Runtime extends Controller
*/
public function config()
{
if (AdminService::isSuper()) try {
if (AdminService::instance()->isSuper()) try {
[$tmpdata, $newdata] = [[], []];
foreach (SystemConfig::mk()->order('type,name asc')->cursor() as $item) {
$tmpdata[$item['type']][$item['name']] = $item['value'];

View File

@ -33,7 +33,7 @@ class Update extends Controller
*/
protected function initialize()
{
if (!SystemService::checkRunMode()) {
if (!SystemService::instance()->checkRunMode()) {
$this->error('只允许访问本地或官方代码!');
}
}
@ -44,7 +44,7 @@ class Update extends Controller
public function get()
{
$filename = decode(input('encode', '0'));
if (!ModuleService::checkAllowDownload($filename)) {
if (!ModuleService::instance()->checkAllowDownload($filename)) {
$this->error('下载的文件不在认证规则中!');
}
if (file_exists($realname = $this->app->getRootPath() . $filename)) {
@ -61,7 +61,7 @@ class Update extends Controller
*/
public function node()
{
$this->success('获取文件列表成功!', ModuleService::getChanges(
$this->success('获取文件列表成功!', ModuleService::instance()->getChanges(
json_decode($this->request->post('rules', '[]', ''), true),
json_decode($this->request->post('ignore', '[]', ''), true)
));
@ -72,6 +72,6 @@ class Update extends Controller
*/
public function version()
{
$this->success('获取模块信息成功!', ModuleService::getModules());
$this->success('获取模块信息成功!', ModuleService::instance()->getModules());
}
}

View File

@ -72,7 +72,7 @@ class Upload extends Controller
$file = SystemFile::mk()->data($this->_vali([
'xkey.value' => $data['key'],
'type.value' => $this->getType(),
'uuid.value' => AdminService::getUserId(),
'uuid.value' => AdminService::instance()->getUserId(),
'name.require' => '名称不能为空!',
'hash.require' => '哈希不能为空!',
'xext.require' => '后缀不能为空!',
@ -129,7 +129,7 @@ class Upload extends Controller
'id.require' => '编号不能为空!',
'hash.require' => '哈希不能为空!',
]);
$data['uuid'] = AdminService::getUserId();
$data['uuid'] = AdminService::instance()->getUserId();
$file = SystemFile::mk()->where($data)->findOrEmpty();
if ($file->isEmpty()) $this->error('文件不存在!');
if ($file->save(['status' => 2])) {
@ -147,49 +147,13 @@ class Upload extends Controller
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function image()
public function modal()
{
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 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()]);
$query->where(['status' => 2])->order('id desc');
$query->like('name,hash')->dateBetween('create_at');
});
}

View File

@ -19,14 +19,14 @@ use think\App;
invoke(function (App $app) {
/*! 非开发环境,清理限制文件 */
if ($app->request->isGet() && !SystemService::checkRunMode()) {
if ($app->request->isGet() && !SystemService::instance()->checkRunMode()) {
@unlink("{$app->getBasePath()}admin/controller/api/Update.php");
@unlink("{$app->getBasePath()}admin/route/demo.php");
@rmdir("{$app->getBasePath()}admin/route");
return;
}
/*! 演示环境禁止操作路由绑定 */
if (SystemService::checkRunMode('demo')) {
if (SystemService::instance()->checkRunMode('demo')) {
$app->route->post('index/pass', function () {
return json(['code' => 0, 'info' => '演示环境禁止修改用户密码!']);
});
@ -58,4 +58,5 @@ invoke(function (App $app) {
return json(['code' => 0, 'info' => '演示环境禁止修改用户密码!']);
});
}
});

View File

@ -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>

View File

@ -1,151 +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 list" 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,
keys: '',
list: [],
},
created: function () {
this.$btn = $('#{$get.id|default=""}');
this.loadPage();
},
methods: {
// 搜索刷新数据
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');
},
// 创建分页工具条
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);
},
});
},
// 加载页面数据
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.list = ret.data;
that.list.forEach(function (item) {
item.style = 'background-image:url(' + item.xurl + ')';
});
that.addPage(ret.count);
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>

View File

@ -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>

View File

@ -2,7 +2,7 @@
{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>
<button data-modal='{:url("add")}' data-table-id="RoleTable" class='layui-btn layui-btn-sm layui-btn-primary'>添加权限</button>
<!--{/if}-->
<!--{if auth("remove")}-->
@ -66,7 +66,7 @@
<!-- 数据操作工具条模板 -->
<script type="text/html" id="ToolbarRoleTableTpl">
<!--{if auth('edit')}-->
<a class="layui-btn layui-btn-primary layui-btn-sm" data-width="600px" data-title="编辑权限" data-modal='{:url("edit")}?id={{d.id}}'> </a>
<a class="layui-btn layui-btn-primary layui-btn-sm" data-title="编辑权限" data-modal='{:url("edit")}?id={{d.id}}'> </a>
<!--{/if}-->
<!--{if auth("apply")}-->

View File

@ -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" 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>

View File

@ -1,64 +0,0 @@
{extend name='table'}
{block name="button"}
<!--{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 formatSize(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 {
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'}
]]
});
});
function formatSize(size, fixed, units) {
var unit;
units = units || ['B', 'K', 'M', 'G', 'TB'];
while ((unit = units.shift()) && size > 1024) size = size / 1024;
return (unit === 'B' ? size : size.toFixed(fixed === undefined ? 2 : fixed)) + unit;
}
</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}

View File

@ -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">&#xe615;</i> 搜 索</button>
</div>
</form>
</fieldset>

View File

@ -37,7 +37,7 @@
{block name='script'}
<style>
#QueueTable + div tbody .layui-table-cell {
height: 56px;
height: 44px;
line-height: 22px;
}

View File

@ -58,7 +58,7 @@ class UserAgent extends Command
'path' => $path1, 'layer' => substr_count($path1, '-'),
'pid0' => $parant['id'], 'pid1' => $parant['id'], 'pid2' => $parant['pid1'],
]);
UserUpgradeService::upgrade($user['id'], true);
UserUpgradeService::instance()->upgrade($user['id'], true);
$this->setQueueMessage(1, 1, "更新指定用户[{$user['id']}]代理绑定成功!");
// 更新下级的代理关系

View File

@ -34,7 +34,7 @@ class UserUpgrade extends Command
[$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']);
UserUpgradeService::instance()->upgrade($user['id']);
$this->queue->message($total, $count, "完成计算用户 [{$user['id']}] 的等级", 1);
}
$this->setQueueSuccess("此次共重新计算 {$total} 个用户等级。");

View File

@ -47,7 +47,7 @@ class News extends Controller
$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));
NewsService::instance()->buildData($result['list'], input('uuid', 0));
$this->success('获取文章内容', $result);
}
@ -62,7 +62,7 @@ class News extends Controller
$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']);
NewsService::instance()->buildListByUidAndCode($result['list']);
$this->success('获取评论成功', $result);
}
}

View File

@ -140,7 +140,7 @@ class Center extends Auth
public function bindFrom()
{
$data = $this->_vali(['from.require' => '邀请人不能为空']);
[$state, $message] = UserUpgradeService::bindAgent($this->uuid, $data['from'], 0);
[$state, $message] = UserUpgradeService::instance()->bindAgent($this->uuid, $data['from'], 0);
if ($state) {
$this->success($message, UserAdminService::total($this->uuid));
} else {

View File

@ -27,7 +27,7 @@ class News extends Auth
'reply.require' => '评论不能为空!',
]);
if (DataNewsXCollect::mk()->insert($data) !== false) {
NewsService::syncNewsTotal($data['code']);
NewsService::instance()->syncNewsTotal($data['code']);
$this->success('添加评论成功!');
} else {
$this->error('添加评论失败!');
@ -44,7 +44,7 @@ class News extends Auth
{
$query = DataNewsXCollect::mQuery()->where(['uuid' => $this->uuid, 'type' => 4]);
$result = $query->whereIn('status', [1, 2])->order('id desc')->page(true, false);
NewsService::buildListByUidAndCode($result);
NewsService::instance()->buildListByUidAndCode($result);
$this->success('获取评论列表成功', $result);
}
@ -81,7 +81,7 @@ class News extends Auth
$this->success('您已收藏!');
}
if (DataNewsXCollect::mk()->insert($data) !== false) {
NewsService::syncNewsTotal($data['code']);
NewsService::instance()->syncNewsTotal($data['code']);
$this->success('收藏成功!');
} else {
$this->error('收藏失败!');
@ -99,7 +99,7 @@ class News extends Auth
'code.require' => '文章编号不能为空!',
]);
if (DataNewsXCollect::mk()->where($data)->delete() !== false) {
NewsService::syncNewsTotal($data['code']);
NewsService::instance()->syncNewsTotal($data['code']);
$this->success('取消收藏成功!');
} else {
$this->error('取消收藏失败!');
@ -117,7 +117,7 @@ class News extends Auth
$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']);
NewsService::instance()->buildListByUidAndCode($result['list']);
$this->success('获取收藏记录成功!', $result);
}
@ -136,7 +136,7 @@ class News extends Auth
$this->success('您已点赞!');
}
if (DataNewsXCollect::mk()->insert($data) !== false) {
NewsService::syncNewsTotal($data['code']);
NewsService::instance()->syncNewsTotal($data['code']);
$this->success('点赞成功!');
} else {
$this->error('点赞失败!');
@ -154,7 +154,7 @@ class News extends Auth
'code.require' => '文章编号不能为空!',
]);
if (DataNewsXCollect::mk()->where($data)->delete() !== false) {
NewsService::syncNewsTotal($data['code']);
NewsService::instance()->syncNewsTotal($data['code']);
$this->success('取消点赞成功!');
} else {
$this->error('取消点赞失败!');
@ -172,7 +172,7 @@ class News extends Auth
$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']);
NewsService::instance()->buildListByUidAndCode($result['list']);
$this->success('获取点赞记录成功!', $result);
}
@ -203,7 +203,7 @@ class News extends Auth
$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']);
NewsService::instance()->buildListByUidAndCode($result['list']);
$this->success('获取浏览历史成功!', $result);
}
}

View File

@ -48,7 +48,7 @@ class Order extends Auth
$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']);
if (count($result['list']) > 0) OrderService::instance()->buildData($result['list']);
$this->success('获取订单数据成功!', $result);
}
@ -108,7 +108,7 @@ class Order extends Auth
$allowPayments = $_allowPayments;
}
// 商品折扣处理
[$discountId, $discountRate] = OrderService::discount($goodsInfo['discount_id'], $this->user['vip_code']);
[$discountId, $discountRate] = OrderService::instance()->discount($goodsInfo['discount_id'], $this->user['vip_code']);
// 订单详情处理
$items[] = [
'uuid' => $order['uuid'],
@ -165,7 +165,7 @@ class Order extends Auth
// 优惠后的金额
$order['amount_discount'] = array_sum(array_column($items, 'discount_amount'));
// 订单随机免减
$order['amount_reduct'] = OrderService::getReduct();
$order['amount_reduct'] = OrderService::instance()->getReduct();
if ($order['amount_reduct'] > $order['amount_goods']) {
$order['amount_reduct'] = $order['amount_goods'];
}
@ -200,7 +200,7 @@ class Order extends Auth
public function discount()
{
$data = $this->_vali(['discount.require' => '折扣编号不能为空!']);
[, $rate] = OrderService::discount(intval($data['discount']), $this->user['vip_code']);
[, $rate] = OrderService::instance()->discount(intval($data['discount']), $this->user['vip_code']);
$this->success('获取用户折扣', ['rate' => $rate]);
}
@ -230,7 +230,7 @@ class Order extends Auth
// 根据地址计算运费
$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);
[$amount, , , $remark] = ExpressService::instance()->amount($tCode, $addr['province'], $addr['city'], $tCount);
$this->success('计算运费成功', ['amount' => $amount, 'remark' => $remark]);
}
@ -263,7 +263,7 @@ class Order extends Auth
$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);
[$amount, $tCount, $tCode, $remark] = ExpressService::instance()->amount($tCodes, $addr['province'], $addr['city'], $tCount);
// 创建订单发货信息
$express = [

View File

@ -31,9 +31,9 @@ class Transfer extends Auth
'amount.require' => '提现金额不能为空!',
'remark.default' => '用户提交提现申请!',
]);
$state = UserTransferService::config('status');
$state = UserTransferService::instance()->config('status');
if (empty($state)) $this->error('提现还没有开启!');
$transfers = UserTransferService::config('transfer');
$transfers = UserTransferService::instance()->config('transfer');
if (empty($transfers[$data['type']]['state'])) $this->error('提现方式已停用!');
// 提现数据补充
$data['uuid'] = $this->uuid;
@ -50,7 +50,7 @@ class Transfer extends Auth
$data['audit_datetime'] = date('Y-m-d H:i:s');
}
// 扣除手续费
$chargeRate = floatval(UserTransferService::config('charge'));
$chargeRate = floatval(UserTransferService::instance()->config('charge'));
$data['charge_rate'] = $chargeRate;
$data['charge_amount'] = $chargeRate * $data['amount'] / 100;
// 检查可提现余额

View File

@ -96,7 +96,7 @@ class Company extends Controller
public function sync()
{
try {
$result = ExpressService::company();
$result = ExpressService::instance()->company();
if (empty($result['code'])) $this->error($result['info']);
foreach ($result['data'] as $vo) BasePostageCompany::mUpdate([
'name' => $vo['title'],

View File

@ -43,7 +43,7 @@ class Template extends Controller
{
if ($this->request->isGet()) {
$this->title = '配送区域管理';
$this->citys = ExpressService::region(3, null);
$this->citys = ExpressService::instance()->region(3, null);
$this->fetch('form_region');
} else {
$data = $this->_vali(['nos.default' => '', 'oks.default' => '']);
@ -83,7 +83,7 @@ class Template extends Controller
$data['code'] = CodeExtend::uniqidDate(12, 'T');
}
if ($this->request->isGet()) {
$this->citys = ExpressService::region(2, 1);
$this->citys = ExpressService::instance()->region(2, 1);
}
}

View File

@ -42,7 +42,7 @@ class Item extends Controller
*/
protected function _page_filter(array &$data)
{
NewsService::buildData($data);
NewsService::instance()->buildData($data);
}
/**

View File

@ -138,7 +138,7 @@ class Goods extends Controller
// 其他表单数据
$this->marks = ShopGoodsMark::items();
$this->cates = ShopGoodsCate::treeTable(true);
$this->trucks = ExpressService::templates();
$this->trucks = ExpressService::instance()->templates();
$this->upgrades = BaseUserUpgrade::items();
$this->payments = BaseUserPayment::mk()->where(['status' => 1, 'deleted' => 0])->order('sort desc,id desc')->column('type,code,name', 'code');
$this->discounts = BaseUserDiscount::mk()->where(['status' => 1, 'deleted' => 0])->order('sort desc,id desc')->column('id,name,items', 'id');

View File

@ -71,7 +71,7 @@ class Send extends Controller
*/
protected function _index_page_filter(array &$data)
{
OrderService::buildData($data, false);
OrderService::instance()->buildData($data, false);
$orders = array_unique(array_column($data, 'order_no'));
$orderList = ShopOrder::mk()->whereIn('order_no', $orders)->column('*', 'order_no');
foreach ($data as &$vo) $vo['order'] = $orderList[$vo['order_no']] ?? [];
@ -149,7 +149,7 @@ class Send extends Controller
{
try {
$data = $this->_vali(['code.require' => '快递不能为空!', 'number.require' => '单号不能为空!']);
$this->result = ExpressService::query($data['code'], $data['number']);
$this->result = ExpressService::instance()->query($data['code'], $data['number']);
if (empty($this->result['code'])) $this->error($this->result['info']);
$this->fetch('truck_query');
} catch (HttpResponseException $exception) {

View File

@ -105,7 +105,7 @@ class Admin extends Controller
$map = $this->_vali(['id.require' => '用户ID不能为空']);
$user = DataUser::mk()->where($map)->find();
if (empty($user) || empty($user['pid0'])) $this->error('用户不符合操作要求!');
[$status, $message] = UserUpgradeService::bindAgent($user['id'], $user['pid0']);
[$status, $message] = UserUpgradeService::instance()->bindAgent($user['id'], $user['pid0']);
$status && sysoplog('前端用户管理', "修改用户[{$map['id']}]的代理为永久状态");
empty($status) ? $this->error($message) : $this->success($message);
}
@ -125,7 +125,7 @@ class Admin extends Controller
// 修改指定用户代理数据
$user->save(['pid0' => 0, 'pid1' => 0, 'pid2' => 0, 'pids' => 1, 'path' => '-', 'layer' => 1]);
// 刷新用户等级及上级等级
UserUpgradeService::upgrade($user['id'], true);
UserUpgradeService::instance()->upgrade($user['id'], true);
sysoplog('前端用户管理', "设置用户[{$map['id']}]为总部用户");
$this->success('设为总部用户成功!');
}
@ -156,7 +156,7 @@ class Admin extends Controller
$query->like('phone,username|nickname#username')->whereRaw('vip_code>0')->equal('status,vip_code')->dateBetween('create_at')->page();
} else {
$data = $this->_vali(['pid.require' => '待绑定代理不能为空!', 'uuid.require' => '待操作用户不能为空!']);
[$status, $message] = UserUpgradeService::bindAgent($data['uuid'], $data['pid'], 2);
[$status, $message] = UserUpgradeService::instance()->bindAgent($data['uuid'], $data['pid'], 2);
$status && sysoplog('前端用户管理', "修改用户[{$data['uuid']}]的代理为用户[{$data['pid']}]");
empty($status) ? $this->error($message) : $this->success($message);
}

View File

@ -88,7 +88,7 @@ class Balance extends Controller
$this->upgrades = BaseUserUpgrade::items();
}
if ($this->request->isPost()) {
$data['create_by'] = AdminService::getUserId();
$data['create_by'] = AdminService::instance()->getUserId();
if (empty(floatval($data['amount'])) && empty($data['upgrade'])) {
$this->error('金额为零并且没有升级行为!');
}
@ -105,7 +105,7 @@ class Balance extends Controller
{
if ($state && isset($data['uuid'])) {
UserBalanceService::amount($data['uuid']);
UserUpgradeService::upgrade($data['uuid']);
UserUpgradeService::instance()->upgrade($data['uuid']);
}
}
@ -129,7 +129,7 @@ class Balance extends Controller
$map = [['id', 'in', str2arr(input('id', ''))]];
foreach (DataUserBalance::mk()->where($map)->cursor() as $vo) {
UserBalanceService::amount($vo['uuid']);
UserUpgradeService::upgrade($vo['uuid']);
UserUpgradeService::instance()->upgrade($vo['uuid']);
}
}
}

View File

@ -56,7 +56,7 @@ class Rebate extends Controller
$userItem = DataUser::mk()->whereIn('id', array_unique($uids))->select();
$goodsItem = ShopOrderItem::mk()->whereIn('order_no', array_unique(array_column($data, 'order_no')))->select();
foreach ($data as &$vo) {
$vo['type'] = RebateService::name($vo['type']);
$vo['type'] = RebateService::instance()->name($vo['type']);
[$vo['user'], $vo['agent'], $vo['list']] = [[], [], []];
foreach ($userItem as $user) {
if ($user['id'] === $vo['uuid']) $vo['agent'] = $user;

View File

@ -83,7 +83,7 @@ class Transfer extends Controller
public function index()
{
$this->title = '用户提现管理';
$this->transfer = UserTransferService::amount(0);
$this->transfer = UserTransferService::instance()->amount(0);
// 创建查询对象
$query = DataUserTransfer::mQuery()->order('id desc');
// 用户条件搜索
@ -157,7 +157,7 @@ class Transfer extends Controller
$data['trade_no'] = CodeExtend::uniqidDate(20);
$data['trade_time'] = date('Y-m-d H:i:s');
$data['change_time'] = date('Y-m-d H:i:s');
$data['change_desc'] = ($data['remark'] ?: '线下打款成功') . ' By ' . AdminService::getUserName();
$data['change_desc'] = ($data['remark'] ?: '线下打款成功') . ' By ' . AdminService::instance()->getUserName();
}
if (DataUserTransfer::mk()->strict(false)->where($map)->update($data) !== false) {
$this->success('操作成功');

View File

@ -57,7 +57,7 @@ class NewsService extends Service
* @param integer $uuid 用户UID
* @return array
*/
public static function buildData(array &$list, int $uuid = 0): array
public function buildData(array &$list, int $uuid = 0): array
{
if (count($list) > 0) {
[$code2, $code1] = [[], []];

View File

@ -63,7 +63,7 @@ class OrderService extends Service
// 尝试绑定代理用户
if (empty($user['pids']) && ($order['puid1'] > 0 || $user['pid1'] > 0)) {
$puid1 = $order['puid1'] > 0 ? $order['puid1'] : $user['pid0'];
UserUpgradeService::bindAgent($user['id'], $puid1);
UserUpgradeService::instance()->bindAgent($user['id'], $puid1);
}
// 重置用户信息并绑定订单
$user = DataUser::mk()->where(['id' => $order['uuid']])->find();
@ -73,7 +73,7 @@ class OrderService extends Service
]);
}
// 重新计算用户等级
UserUpgradeService::upgrade($user['id'], true, $orderNo);
UserUpgradeService::instance()->upgrade($user['id'], true, $orderNo);
return [$user, $order, $entry];
}

View File

@ -50,7 +50,7 @@ class UserRebateService extends Service
if (empty($order)) return [0, '需处理的订单状态异常!'];
$map = [['status', '=', 0], ['order_no', 'like', "{$orderNo}%"]];
DataUserRebate::mk()->where($map)->update(['status' => 1]);
if (UserUpgradeService::upgrade($order['uuid'])) {
if (UserUpgradeService::instance()->upgrade($order['uuid'])) {
return [1, '重新计算用户金额成功!'];
} else {
return [0, '重新计算用户金额失败!'];

View File

@ -7,7 +7,6 @@ use app\data\model\DataUser;
use app\data\model\DataUserBalance;
use app\data\model\ShopOrder;
use app\data\model\ShopOrderItem;
use think\admin\Library;
use think\admin\Service;
/**
@ -28,7 +27,7 @@ class UserUpgradeService extends Service
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function bindAgent(int $uuid, int $pid0 = 0, int $mode = 1): array
public function bindAgent(int $uuid, int $pid0 = 0, int $mode = 1): array
{
$user = DataUser::mk()->where(['id' => $uuid])->find();
if (empty($user)) return [0, '查询用户资料失败'];
@ -42,7 +41,7 @@ class UserUpgradeService extends Service
if (empty($agent['vip_code'])) return [0, '代理无推荐资格'];
if (strpos($agent['path'], "-{$uuid}-") !== false) return [0, '不能绑定下属'];
try {
Library::$sapp->db->transaction(function () use ($user, $agent, $mode) {
$this->app->db->transaction(function () use ($user, $agent, $mode) {
// 更新用户代理
$path1 = rtrim($agent['path'] ?: '-', '-') . "-{$agent['id']}-";
$user->save(['pid0' => $agent['id'], 'pid1' => $agent['id'], 'pid2' => $agent['pid1'], 'pids' => $mode > 0 ? 1 : 0, 'path' => $path1, 'layer' => substr_count($path1, '-')]);
@ -55,7 +54,7 @@ class UserUpgradeService extends Service
}
}
});
static::upgrade($user['id']);
$this->upgrade($user['id']);
return [1, '绑定代理成功'];
} catch (\Exception $exception) {
return [0, "绑定代理失败, {$exception->getMessage()}"];
@ -72,7 +71,7 @@ class UserUpgradeService extends Service
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function upgrade(int $uuid, bool $parent = true, ?string $orderNo = null): bool
public function upgrade(int $uuid, bool $parent = true, ?string $orderNo = null): bool
{
$user = DataUser::mk()->where(['id' => $uuid])->find();
if (empty($user)) return true;
@ -134,9 +133,9 @@ class UserUpgradeService extends Service
if ($data['vip_code'] !== $user['vip_code']) $data['vip_datetime'] = date('Y-m-d H:i:s');
DataUser::mk()->where(['id' => $uuid])->update($data);
// 用户升级事件
if ($user['vip_code'] < $vipCode) Library::$sapp->event->trigger('UserUpgradeLevel', [
if ($user['vip_code'] < $vipCode) $this->app->event->trigger('UserUpgradeLevel', [
'uuid' => $user['id'], 'order_no' => $orderNo, 'vip_code_old' => $user['vip_code'], 'vip_code_new' => $vipCode,
]);
return !($parent && $user['pid1'] > 0) || static::upgrade($user['pid1'], false);
return !($parent && $user['pid1'] > 0) || $this->upgrade($user['pid1'], false);
}
}

View File

@ -89,17 +89,17 @@ class Auto extends Command
$result = $this->sendMessage('text', ['content' => $data['content']]);
}
if ($type === 'voice' && !empty($data['voice_url'])) {
if ($mediaId = MediaService::upload($data['voice_url'], 'voice')) {
if ($mediaId = MediaService::instance()->upload($data['voice_url'], 'voice')) {
$result = $this->sendMessage('voice', ['media_id' => $mediaId]);
}
}
if ($type === 'image' && !empty($data['image_url'])) {
if ($mediaId = MediaService::upload($data['image_url'], 'image')) {
if ($mediaId = MediaService::instance()->upload($data['image_url'], 'image')) {
$result = $this->sendMessage('image', ['media_id' => $mediaId]);
}
}
if ($type === 'news') {
[$item, $news] = [MediaService::news($data['news_id']), []];
[$item, $news] = [MediaService::instance()->news($data['news_id']), []];
if (isset($item['articles']) && is_array($item['articles'])) {
$host = sysconf('base.site_host') ?: true;
foreach ($item['articles'] as $vo) if (empty($news)) $news[] = [
@ -110,7 +110,7 @@ class Auto extends Command
}
}
if ($type === 'music' && !empty($data['music_url']) && !empty($data['music_title']) && !empty($data['music_desc'])) {
$mediaId = $data['music_image'] ? MediaService::upload($data['music_image'], 'image') : '';
$mediaId = $data['music_image'] ? MediaService::instance()->upload($data['music_image'], 'image') : '';
$result = $this->sendMessage('music', [
'hqmusicurl' => $data['music_url'], 'musicurl' => $data['music_url'],
'description' => $data['music_desc'], 'title' => $data['music_title'], 'thumb_media_id' => $mediaId,
@ -118,7 +118,7 @@ class Auto extends Command
}
if ($type === 'video' && !empty($data['video_url']) && !empty($data['video_desc']) && !empty($data['video_title'])) {
$video = ['title' => $data['video_title'], 'introduction' => $data['video_desc']];
if ($mediaId = MediaService::upload($data['video_url'], 'video', $video)) {
if ($mediaId = MediaService::instance()->upload($data['video_url'], 'video', $video)) {
$result = $this->sendMessage('video', ['media_id' => $mediaId, 'title' => $data['video_title'], 'description' => $data['video_desc']]);
}
}

View File

@ -66,7 +66,7 @@ class Fans extends Command
*/
protected function _list(string $next = '', int $done = 0): string
{
$appid = WechatService::getAppid();
$appid = WechatService::instance()->getAppid();
$this->output->comment('开始获取微信用户数据');
while (is_string($next)) {
$result = WechatService::WeChatUser()->getUserList($next);
@ -76,7 +76,7 @@ class Fans extends Command
if (is_array($info) && !empty($info['user_info_list'])) {
foreach ($info['user_info_list'] as $user) if (isset($user['nickname'])) {
$this->queue->message($result['total'], ++$done, "-> {$user['openid']} {$user['nickname']}");
FansService::set($user, $appid);
FansService::instance()->set($user, $appid);
}
}
}
@ -137,7 +137,7 @@ class Fans extends Command
*/
public function _tags(int $done = 0): string
{
$appid = WechatService::getAppid();
$appid = WechatService::instance()->getAppid();
$this->output->comment('开始获取微信用户标签数据');
if (is_array($list = WechatService::WeChatTags()->getTags()) && !empty($list['tags'])) {
$count = count($list['tags']);

View File

@ -43,7 +43,7 @@ class Fans extends Controller
WechatFans::mQuery()->layTable(function () {
$this->title = '微信用户管理';
}, function (QueryHelper $query) {
$query->where(['appid' => WechatService::getAppid()]);
$query->where(['appid' => WechatService::instance()->getAppid()]);
$query->like('nickname')->equal('subscribe,is_black')->dateBetween('subscribe_at');
});
}

View File

@ -53,7 +53,7 @@ class News extends Controller
protected function _page_filter(array &$data)
{
foreach ($data as &$vo) {
$vo = MediaService::news($vo['id']);
$vo = MediaService::instance()->news($vo['id']);
}
}
@ -77,7 +77,7 @@ class News extends Controller
$this->fetch('form');
} else {
$update = [
'create_by' => AdminService::getUserId(),
'create_by' => AdminService::instance()->getUserId(),
'article_id' => $this->_buildArticle($this->request->post('data', [])),
];
if (WechatNews::mk()->insert($update) !== false) {
@ -101,7 +101,7 @@ class News extends Controller
if (empty($this->id)) $this->error('参数错误,请稍候再试!');
if ($this->request->isGet()) {
if ($this->request->get('output') === 'json') {
$this->success('获取数据成功!', MediaService::news($this->id));
$this->success('获取数据成功!', MediaService::instance()->news($this->id));
} else {
$this->title = '编辑图文';
$this->fetch('form');

View File

@ -50,12 +50,12 @@ class Js extends Controller
{
$mode = $this->request->get('mode', 1);
$source = $this->request->server('http_referer') ?: $this->request->url(true);
$userinfo = WechatService::getWebOauthInfo($source, $mode, false);
$userinfo = WechatService::instance()->getWebOauthInfo($source, $mode, false);
if (empty($userinfo['openid'])) {
$content = 'alert("Wechat webOauth failed.")';
} else {
$this->openid = $userinfo['openid'];
$this->params = json_encode(WechatService::getWebJssdkSign($source));
$this->params = json_encode(WechatService::instance()->getWebJssdkSign($source));
$this->fansinfo = json_encode($userinfo['fansinfo'] ?? [], JSON_UNESCAPED_UNICODE);
// 生成数据授权令牌
$this->token = uniqid('oauth') . rand(10000, 99999);
@ -78,7 +78,7 @@ class Js extends Controller
public function sdk()
{
$data = $this->_vali(['url.require' => '签名地址不能为空!']);
$this->success('获取签名参数', WechatService::getWebJssdkSign($data['url']));
$this->success('获取签名参数', WechatService::instance()->getWebJssdkSign($data['url']));
}
/**

View File

@ -72,7 +72,7 @@ class Login extends Controller
$this->mode = input('mode', '0');
if (stripos($this->code, $this->prefix) === 0) {
$this->url = $this->request->url(true);
$this->fans = WechatService::getWebOauthInfo($this->url, $this->mode);
$this->fans = WechatService::instance()->getWebOauthInfo($this->url, $this->mode);
if (is_array($this->fans) && isset($this->fans['openid'])) {
$this->fans['token'] = md5(uniqid('t', true) . rand(10000, 99999));
$this->app->cache->set("wxlogin{$this->code}", $this->fans, $this->expire);

View File

@ -93,7 +93,7 @@ class Push extends Controller
public function index(): string
{
try {
if (WechatService::getType() === 'thr') {
if (WechatService::instance()->getType() === 'thr') {
$this->forceJson = true; // 直接返回JSON数据到SERVICE
$this->forceCustom = false; // 直接使用客服消息模式推送
$this->appid = $this->request->post('appid', '', null);
@ -106,7 +106,7 @@ class Push extends Controller
} else {
$this->forceJson = false; // 直接返回JSON对象数据
$this->forceCustom = false; // 直接使用客服消息推送
$this->appid = WechatService::getAppid();
$this->appid = WechatService::instance()->getAppid();
$this->wechat = WechatService::WeChatReceive();
$this->openid = $this->wechat->getOpenid();
$this->encrypt = $this->wechat->isEncrypt();
@ -215,13 +215,13 @@ class Push extends Controller
case 'customservice':
return $this->_sendMessage('customservice', ['content' => $data['content']], false);
case 'voice':
if (empty($data['voice_url']) || !($mediaId = MediaService::upload($data['voice_url'], 'voice'))) return false;
if (empty($data['voice_url']) || !($mediaId = MediaService::instance()->upload($data['voice_url'], 'voice'))) return false;
return $this->_sendMessage('voice', ['media_id' => $mediaId], $custom);
case 'image':
if (empty($data['image_url']) || !($mediaId = MediaService::upload($data['image_url'], 'image'))) return false;
if (empty($data['image_url']) || !($mediaId = MediaService::instance()->upload($data['image_url'], 'image'))) return false;
return $this->_sendMessage('image', ['media_id' => $mediaId], $custom);
case 'news':
[$news, $articles] = [MediaService::news($data['news_id']), []];
[$news, $articles] = [MediaService::instance()->news($data['news_id']), []];
if (empty($news['articles'])) return false;
foreach ($news['articles'] as $vo) $articles[] = [
'url' => url("@wechat/api.view/item/id/{$vo['id']}", [], false, true)->build(),
@ -230,7 +230,7 @@ class Push extends Controller
return $this->_sendMessage('news', ['articles' => $articles], $custom);
case 'music':
if (empty($data['music_url']) || empty($data['music_title']) || empty($data['music_desc'])) return false;
$mediaId = $data['music_image'] ? MediaService::upload($data['music_image'], 'image') : '';
$mediaId = $data['music_image'] ? MediaService::instance()->upload($data['music_image'], 'image') : '';
return $this->_sendMessage('music', [
'hqmusicurl' => $data['music_url'], 'musicurl' => $data['music_url'],
'description' => $data['music_desc'], 'title' => $data['music_title'], 'thumb_media_id' => $mediaId,
@ -238,7 +238,7 @@ class Push extends Controller
case 'video':
if (empty($data['video_url']) || empty($data['video_desc']) || empty($data['video_title'])) return false;
$video = ['title' => $data['video_title'], 'introduction' => $data['video_desc']];
if (!($mediaId = MediaService::upload($data['video_url'], 'video', $video))) return false;
if (!($mediaId = MediaService::instance()->upload($data['video_url'], 'video', $video))) return false;
return $this->_sendMessage('video', ['media_id' => $mediaId, 'title' => $data['video_title'], 'description' => $data['video_desc']], $custom);
default:
return false;
@ -309,13 +309,13 @@ class Push extends Controller
if ($state) {
try {
$user = WechatService::WeChatUser()->getUserInfo($this->openid);
return FansService::set(array_merge($user, ['subscribe' => 1, 'appid' => $this->appid]));
return FansService::instance()->set(array_merge($user, ['subscribe' => 1, 'appid' => $this->appid]));
} catch (\Exception $exception) {
$this->app->log->error(__METHOD__ . " {$this->openid} get userinfo faild. {$exception->getMessage()}");
return false;
}
} else {
return FansService::set(['subscribe' => 0, 'openid' => $this->openid, 'appid' => $this->appid]);
return FansService::instance()->set(['subscribe' => 0, 'openid' => $this->openid, 'appid' => $this->appid]);
}
}

View File

@ -115,7 +115,7 @@ class Test extends Controller
public function oauth()
{
$this->url = $this->request->url(true);
$this->fans = WechatService::getWebOauthInfo($this->url, 1);
$this->fans = WechatService::instance()->getWebOauthInfo($this->url, 1);
$this->fetch();
}
@ -130,7 +130,7 @@ class Test extends Controller
*/
public function jssdk()
{
$this->options = WechatService::getWebJssdkSign();
$this->options = WechatService::instance()->getWebJssdkSign();
$this->fetch();
}
@ -188,7 +188,7 @@ class Test extends Controller
{
$this->url = $this->request->url(true);
$this->pay = WechatService::WePayOrder();
$user = WechatService::getWebOauthInfo($this->url);
$user = WechatService::instance()->getWebOauthInfo($this->url);
if (empty($user['openid'])) return '<h3>网页授权获取OPENID失败</h3>';
// 生成预支付码
$result = $this->pay->create([
@ -203,7 +203,7 @@ class Test extends Controller
// 数据参数格式化
$resultJson = var_export($result, true);
$optionJson = json_encode($this->pay->jsapiParams($result['prepay_id']), JSON_UNESCAPED_UNICODE);
$configJson = json_encode(WechatService::getWebJssdkSign(), JSON_UNESCAPED_UNICODE);
$configJson = json_encode(WechatService::instance()->getWebJssdkSign(), JSON_UNESCAPED_UNICODE);
return <<<HTML
<pre>
当前用户OPENID: {$user['openid']}

View File

@ -38,7 +38,7 @@ class View extends Controller
public function news($id = 0)
{
$this->id = $id ?: input('id', 0);
$this->news = MediaService::news($this->id);
$this->news = MediaService::instance()->news($this->id);
$this->fetch();
}

View File

@ -35,11 +35,11 @@ class AutoService extends Service
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function register(string $openid)
public function register(string $openid)
{
foreach (WechatAuto::mk()->where(['status' => 1])->order('time asc')->cursor() as $vo) {
[$name, $time] = ["推送客服消息 {$vo['code']}#{$openid}", static::parseTimeString($vo['time'])];
QueueService::register($name, "xadmin:fansmsg {$openid} {$vo['code']}", $time, []);
[$name, $time] = ["推送客服消息 {$vo['code']}#{$openid}", $this->parseTimeString($vo['time'])];
QueueService::instance()->register($name, "xadmin:fansmsg {$openid} {$vo['code']}", $time, []);
}
}
@ -48,7 +48,7 @@ class AutoService extends Service
* @param string $time
* @return int
*/
private static function parseTimeString(string $time): int
private function parseTimeString(string $time): int
{
if (preg_match('|^.*?(\d{2}).*?(\d{2}).*?(\d{2}).*?$|', $time, $vars)) {
return intval($vars[1]) * 3600 * intval($vars[2]) * 60 + intval($vars[3]);

View File

@ -17,7 +17,6 @@
namespace app\wechat\service;
use app\wechat\model\WechatFans;
use think\admin\Library;
use think\admin\Service;
/**
@ -34,7 +33,7 @@ class FansService extends Service
* @param string $appid 微信APPID
* @return boolean
*/
public static function set(array $user, string $appid = ''): bool
public function set(array $user, string $appid = ''): bool
{
if (isset($user['subscribe_time'])) {
$user['subscribe_at'] = date('Y-m-d H:i:s', $user['subscribe_time']);
@ -45,7 +44,7 @@ class FansService extends Service
if ($appid !== '') $user['appid'] = $appid;
unset($user['privilege'], $user['groupid']);
foreach ($user as $k => $v) if ($v === '') unset($user[$k]);
Library::$sapp->event->trigger('WechatFansUpdate', $user);
$this->app->event->trigger('WechatFansUpdate', $user);
return !!WechatFans::mUpdate($user, 'openid');
}
@ -54,7 +53,7 @@ class FansService extends Service
* @param string $openid
* @return array
*/
public static function get(string $openid): array
public function get(string $openid): array
{
return WechatFans::mk()->where(['openid' => $openid])->findOrEmpty()->toArray();
}

View File

@ -39,7 +39,7 @@ class MediaService extends Service
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function news($id, array $map = []): array
public function news($id, array $map = []): array
{
// 文章主体数据
$map1 = ['id' => $id, 'is_deleted' => 0];
@ -68,12 +68,12 @@ class MediaService extends Service
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function upload(string $url, string $type = 'image', array $video = []): string
public function upload(string $url, string $type = 'image', array $video = []): string
{
$map = ['md5' => md5($url), 'appid' => WechatService::getAppid()];
$map = ['md5' => md5($url), 'appid' => WechatService::instance()->getAppid()];
if (($mediaId = WechatMedia::mk()->where($map)->value('media_id'))) return $mediaId;
$result = WechatService::WeChatMedia()->addMaterial(self::buildCurlFile($url), $type, $video);
WechatMedia::mUpdate([
data_save(WechatMedia::class, [
'local_url' => $url, 'md5' => $map['md5'], 'type' => $type, 'appid' => $map['appid'],
'media_url' => $result['url'] ?? '', 'media_id' => $result['media_id'],
], 'type', $map);
@ -86,7 +86,7 @@ class MediaService extends Service
* @return MyCurlFile
* @throws \WeChat\Exceptions\LocalCacheException
*/
private static function buildCurlFile(string $local): MyCurlFile
private function buildCurlFile(string $local): MyCurlFile
{
if (file_exists($local)) {
return new MyCurlFile($local);

View File

@ -18,7 +18,6 @@ namespace app\wechat\service;
use think\admin\Exception;
use think\admin\extend\JsonRpcClient;
use think\admin\Library;
use think\admin\Service;
use think\admin\storage\LocalStorage;
use think\exception\HttpResponseException;
@ -105,7 +104,7 @@ class WechatService extends Service
}
if (sysconf('wechat.type') === 'api' || $type === 'WePay') {
if (class_exists($class)) {
return new $class(static::getConfig());
return new $class(static::instance()->getConfig());
} else {
throw new Exception("抱歉,接口模式无法实例 {$class} 对象!");
}
@ -143,9 +142,9 @@ class WechatService extends Service
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getAppid(): string
public function getAppid(): string
{
if (static::getType() === 'api') {
if ($this->getType() === 'api') {
return sysconf('wechat.appid');
} else {
return sysconf('wechat.thr_appid');
@ -160,7 +159,7 @@ class WechatService extends Service
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getType(): string
public function getType(): string
{
$type = strtolower(sysconf('wechat.type'));
if (in_array($type, ['api', 'thr'])) return $type;
@ -175,16 +174,16 @@ class WechatService extends Service
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getConfig(): array
public function getConfig(): array
{
$options = [
'appid' => static::getAppid(),
'appid' => $this->getAppid(),
'token' => sysconf('wechat.token'),
'appsecret' => sysconf('wechat.appsecret'),
'encodingaeskey' => sysconf('wechat.encodingaeskey'),
'mch_id' => sysconf('wechat.mch_id'),
'mch_key' => sysconf('wechat.mch_key'),
'cache_path' => Library::$sapp->getRuntimePath() . 'wechat',
'cache_path' => $this->app->getRuntimePath() . 'wechat',
];
$local = LocalStorage::instance();
switch (strtolower(sysconf('wechat.mch_ssl_type'))) {
@ -212,16 +211,16 @@ class WechatService extends Service
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getWebOauthInfo(string $source, int $isfull = 0, bool $redirect = true): array
public function getWebOauthInfo(string $source, int $isfull = 0, bool $redirect = true): array
{
$appid = static::getAppid();
$openid = Library::$sapp->session->get("{$appid}_openid");
$userinfo = Library::$sapp->session->get("{$appid}_fansinfo");
$appid = $this->getAppid();
$openid = $this->app->session->get("{$appid}_openid");
$userinfo = $this->app->session->get("{$appid}_fansinfo");
if ((empty($isfull) && !empty($openid)) || (!empty($isfull) && !empty($openid) && !empty($userinfo))) {
empty($userinfo) || FansService::set($userinfo, $appid);
empty($userinfo) || FansService::instance()->set($userinfo, $appid);
return ['openid' => $openid, 'fansinfo' => $userinfo];
}
if (static::getType() === 'api') {
if ($this->getType() === 'api') {
// 解析 GET 参数
parse_str(parse_url($source, PHP_URL_QUERY), $params);
$getVars = [
@ -236,11 +235,11 @@ class WechatService extends Service
$oauthurl = $wechat->getOauthRedirect($location, $appid, $isfull ? 'snsapi_userinfo' : 'snsapi_base');
throw new HttpResponseException($redirect ? redirect($oauthurl, 301) : response("location.href='{$oauthurl}'"));
} elseif (($token = $wechat->getOauthAccessToken($getVars['code'])) && isset($token['openid'])) {
Library::$sapp->session->set("{$appid}_openid", $openid = $token['openid']);
$this->app->session->set("{$appid}_openid", $openid = $token['openid']);
if ($isfull && isset($token['access_token'])) {
$userinfo = $wechat->getUserInfo($token['access_token'], $openid);
Library::$sapp->session->set("{$appid}_fansinfo", $userinfo);
empty($userinfo) || FansService::set($userinfo, $appid);
$this->app->session->set("{$appid}_fansinfo", $userinfo);
empty($userinfo) || FansService::instance()->set($userinfo, $appid);
}
}
if ($getVars['rcode']) {
@ -252,11 +251,11 @@ class WechatService extends Service
throw new Exception('Query params [rcode] not find.');
}
} else {
$result = static::ThinkServiceConfig()->oauth(Library::$sapp->session->getId(), $source, $isfull);
Library::$sapp->session->set("{$appid}_openid", $openid = $result['openid']);
Library::$sapp->session->set("{$appid}_fansinfo", $userinfo = $result['fans']);
$result = static::ThinkServiceConfig()->oauth($this->app->session->getId(), $source, $isfull);
$this->app->session->set("{$appid}_openid", $openid = $result['openid']);
$this->app->session->set("{$appid}_fansinfo", $userinfo = $result['fans']);
if ((empty($isfull) && !empty($openid)) || (!empty($isfull) && !empty($openid) && !empty($userinfo))) {
empty($userinfo) || FansService::set($userinfo, $appid);
empty($userinfo) || FansService::instance()->set($userinfo, $appid);
return ['openid' => $openid, 'fansinfo' => $userinfo];
}
if ($redirect) {
@ -278,10 +277,10 @@ class WechatService extends Service
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getWebJssdkSign(?string $location = null): array
public function getWebJssdkSign(?string $location = null): array
{
$location = $location ?: Library::$sapp->request->url(true);
if (static::getType() === 'api') {
$location = $location ?: $this->app->request->url(true);
if ($this->getType() === 'api') {
return static::WeChatScript()->getJsSign($location);
} else {
return static::ThinkServiceConfig()->jsSign($location);

View File

@ -25,6 +25,6 @@ if (app()->request->isCli()) {
});
} else {
app()->event->listen('WechatFansSubscribe', function ($openid) {
AutoService::register($openid);
AutoService::instance()->register($openid);
});
}

View File

@ -50,39 +50,10 @@ window.jQuery = window.$ = window.jQuery || window.$ || layui.$;
/*! 配置 require 参数 */
require.config({
baseUrl: baseRoot, waitSeconds: 60,
map: {'*': {css: baseRoot + 'plugs/require/css.js'}},
paths: {
'vue': ['plugs/vue/vue.min'],
'md5': ['plugs/jquery/md5.min'],
'json': ['plugs/jquery/json.min'],
'xlsx': ['plugs/jquery/xlsx.min'],
'excel': ['plugs/jquery/excel.xlsx'],
'base64': ['plugs/jquery/base64.min'],
'upload': [tapiRoot + '/api.upload/index?'],
'notify': ['plugs/notify/notify.min'],
'angular': ['plugs/angular/angular.min'],
'cropper': ['plugs/cropper/cropper.min'],
'echarts': ['plugs/echarts/echarts.min'],
'ckeditor4': ['plugs/ckeditor4/ckeditor'],
'ckeditor5': ['plugs/ckeditor5/ckeditor'],
'websocket': ['plugs/socket/websocket'],
'pcasunzips': ['plugs/jquery/pcasunzips'],
'sortablejs': ['plugs/sortable/sortable.min'],
'vue.sortable': ['plugs/sortable/vue.draggable.min'],
'jquery.ztree': ['plugs/ztree/ztree.all.min'],
'jquery.masonry': ['plugs/jquery/masonry.min'],
'jquery.cropper': ['plugs/cropper/cropper.min'],
'jquery.autocompleter': ['plugs/jquery/autocompleter.min'],
baseUrl: baseRoot, waitSeconds: 60, map: {'*': {css: baseRoot + 'plugs/require/css.js'}}, paths: {
'vue': ['plugs/vue/vue.min'], 'md5': ['plugs/jquery/md5.min'], 'json': ['plugs/jquery/json.min'], 'xlsx': ['plugs/jquery/xlsx.min'], 'excel': ['plugs/jquery/excel.xlsx'], 'base64': ['plugs/jquery/base64.min'], 'upload': [tapiRoot + '/api.upload/index?'], 'notify': ['plugs/notify/notify.min'], 'angular': ['plugs/angular/angular.min'], 'cropper': ['plugs/cropper/cropper.min'], 'echarts': ['plugs/echarts/echarts.min'], 'ckeditor4': ['plugs/ckeditor4/ckeditor'], 'ckeditor5': ['plugs/ckeditor5/ckeditor'], 'websocket': ['plugs/socket/websocket'], 'pcasunzips': ['plugs/jquery/pcasunzips'], 'sortablejs': ['plugs/sortable/sortable.min'], 'vue.sortable': ['plugs/sortable/vue.draggable.min'], 'jquery.ztree': ['plugs/ztree/ztree.all.min'], 'jquery.masonry': ['plugs/jquery/masonry.min'], 'jquery.cropper': ['plugs/cropper/cropper.min'], 'jquery.autocompleter': ['plugs/jquery/autocompleter.min'],
}, shim: {
'excel': {deps: [baseRoot + 'plugs/layui_exts/excel.js']},
'notify': {deps: ['css!' + baseRoot + 'plugs/notify/light.css']},
'cropper': {deps: ['css!' + baseRoot + 'plugs/cropper/cropper.min.css']},
'websocket': {deps: [baseRoot + 'plugs/socket/swfobject.min.js']},
'ckeditor5': {deps: ['jquery', 'upload', 'css!' + baseRoot + 'plugs/ckeditor5/ckeditor.css']},
'vue.sortable': {deps: ['vue', 'sortablejs']},
'jquery.ztree': {deps: ['jquery', 'css!' + baseRoot + 'plugs/ztree/zTreeStyle/zTreeStyle.css']},
'jquery.autocompleter': {deps: ['jquery', 'css!' + baseRoot + 'plugs/jquery/autocompleter.css']},
'excel': {deps: [baseRoot + 'plugs/layui_exts/excel.js']}, 'notify': {deps: ['css!' + baseRoot + 'plugs/notify/light.css']}, 'cropper': {deps: ['css!' + baseRoot + 'plugs/cropper/cropper.min.css']}, 'websocket': {deps: [baseRoot + 'plugs/socket/swfobject.min.js']}, 'ckeditor5': {deps: ['jquery', 'upload', 'css!' + baseRoot + 'plugs/ckeditor5/ckeditor.css']}, 'vue.sortable': {deps: ['vue', 'sortablejs']}, 'jquery.ztree': {deps: ['jquery', 'css!' + baseRoot + 'plugs/ztree/zTreeStyle/zTreeStyle.css']}, 'jquery.autocompleter': {deps: ['jquery', 'css!' + baseRoot + 'plugs/jquery/autocompleter.css']},
}
});
@ -575,25 +546,11 @@ $(function () {
});
};
/*! 上传单个视频 */
$.fn.uploadOneVideo = function () {
return this.each(function () {
if ($(this).data('inited')) return true; else $(this).data('inited', true);
var $in = $(this), $bt = $('<a data-file class="uploadimage uploadvideo transition"><span class="layui-icon">&#x1006;</span><span class="layui-icon">&#xe615;</span></a>').data('input', this);
$bt.attr('data-size', $in.data('size') || 0).attr('data-type', $in.data('type') || 'mp4').find('span').on('click', function (event) {
event.stopPropagation();
if ($(this).index() === 0) $bt.attr('style', ''), $in.val(''); else $in.val() && $.previewImage(encodeURI($in.val()));
}), $in.on('change', function () {
if (this.value) $bt.html('<video width="76" height="76" controls><source src="' + encodeURI(this.value) + '" type="video/mp4"></video>');
}).after($bt).trigger('change');
});
};
/*! 上传单张图片 */
$.fn.uploadOneImage = function () {
return this.each(function () {
if ($(this).data('inited')) return true; else $(this).data('inited', true);
var $in = $(this), $bt = $('<a data-file="image" class="uploadimage transition"><span class="layui-icon">&#x1006;</span><span class="layui-icon">&#xe615;</span></a>').data('input', this);
var $in = $(this), $bt = $('<a data-file class="uploadimage transition"><span class="layui-icon">&#x1006;</span><span class="layui-icon">&#xe615;</span></a>').data('input', this);
$bt.attr('data-size', $in.data('size') || 0).attr('data-type', $in.data('type') || 'png,jpg,gif,jpeg').find('span').on('click', function (event) {
event.stopPropagation();
if ($(this).index() === 0) $bt.attr('style', ''), $in.val(''); else $in.val() && $.previewImage(encodeURI($in.val()));
@ -628,6 +585,20 @@ $(function () {
});
};
/*! 上传单个视频 */
$.fn.uploadOneVideo = function () {
return this.each(function () {
if ($(this).data('inited')) return true; else $(this).data('inited', true);
var $in = $(this), $bt = $('<a data-file class="uploadimage uploadvideo transition"><span class="layui-icon">&#x1006;</span><span class="layui-icon">&#xe615;</span></a>').data('input', this);
$bt.attr('data-size', $in.data('size') || 0).attr('data-type', $in.data('type') || 'mp4').find('span').on('click', function (event) {
event.stopPropagation();
if ($(this).index() === 0) $bt.attr('style', ''), $in.val(''); else $in.val() && $.previewImage(encodeURI($in.val()));
}), $in.on('change', function () {
if (this.value) $bt.html('<video width="76" height="76" controls><source src="' + encodeURI(this.value) + '" type="video/mp4"></video>');
}).after($bt).trigger('change');
});
};
/*! 标签输入插件 */
$.fn.initTagInput = function () {
return this.each(function () {
@ -864,22 +835,6 @@ $(function () {
/*! 注册 data-file 事件行为 */
onEvent('click', '[data-file]', function () {
this.id = this.dataset.id = this.id || (function (date) {
return (date + Math.random()).replace('0.', '');
})(layui.util.toDateString(Date.now(), 'yyyyMMddHHmmss-'));
// 上传图片,支持单图或多图选择,分别是 image|images
if (typeof this.dataset.file === 'string' && /^images?$/.test(this.dataset.file)) {
return $.form.modal(tapiRoot + '/api.upload/image', this.dataset, '图片选择器')
}
// 上传视频,支持单视频或多视频选择,分别是 video|videos
if (typeof this.dataset.file === 'string' && /^videos?$/.test(this.dataset.file)) {
return $.form.modal(tapiRoot + '/api.upload/video', this.dataset, '视频选择器')
}
// 上传文档,支持单视频或多视频选择,分别是 document|documents
if (typeof this.dataset.file === 'string' && /^videos?$/.test(this.dataset.file)) {
return $.form.modal(tapiRoot + '/api.upload/document', this.dataset, '文档选择器')
}
// 其他文件上传
if ($(this).data('inited') !== true) (function (that) {
that.uploadFile(undefined, function () {
that.trigger('upload.start');

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-view{display:block;position:relative;margin:10px 0;padding:0;border:1px solid #eee;border-left-width:6px;background-color:#fafafa;color:#333;font-family:Courier New;font-size:13px}.layui-code-h3{position:relative;padding:0 10px;height:40px;line-height:40px;border-bottom:1px solid #eee;font-size:12px}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 10px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view .layui-code-ol li:first-child{padding-top:10px}.layui-code-view .layui-code-ol li:last-child{padding-bottom:10px}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0c0c0c;border-left-color:#3f3f3f;background-color:#0c0c0c;color:#c2be9e}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3f3f3f;border-left:none}.layui-code-demo .layui-code{visibility:visible!important;margin:-15px;border-top:none;border-right:none;border-bottom:none}.layui-code-demo .layui-tab-content{padding:15px;border-top:none}
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-view{display:block;position:relative;margin:10px 0;padding:0;border:1px solid #eee;border-left-width:6px;background-color:#fafafa;color:#333;font-family:Courier New;font-size:12px}.layui-code-h3{position:relative;padding:0 10px;height:40px;line-height:40px;border-bottom:1px solid #eee;font-size:12px}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 10px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view .layui-code-ol li:first-child{padding-top:10px}.layui-code-view .layui-code-ol li:last-child{padding-bottom:10px}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0c0c0c;border-left-color:#3f3f3f;background-color:#0c0c0c;color:#c2be9e}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3f3f3f;border-left:none}.layui-code-demo .layui-code{visibility:visible!important;margin:-15px;border-top:none;border-right:none;border-bottom:none}.layui-code-demo .layui-tab-content{padding:15px;border-top:none}

File diff suppressed because one or more lines are too long

View File

@ -226,10 +226,6 @@ form.layui-form fieldset {
}
.layui-table {
&[lay-even] tr:nth-child(even) {
background-color: #fafafa;
}
td, th {
font-size: 12px;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long