Commit 7b9173db authored by wangtao's avatar wangtao

第一次

parents
Pipeline #884 canceled with stages

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

APP_DEBUG = true
APP_TRACE = false
[APP]
DEFAULT_TIMEZONE = Asia/Shanghai
[DATABASE]
TYPE = mysql
HOSTNAME = 127.0.0.1
DATABASE = veitooldata
USERNAME = root
PASSWORD = root
HOSTPORT = 3306
PREFIX = fj_
CHARSET = utf8
DEBUG = true
[CACHE]
DRIVER = file
[REDIS]
HOSTNAME = 127.0.0.1
HOSTPORT = 6379
PASSWORD =
SELECT = 0
[LANG]
default_lang = zh-cn
\ No newline at end of file
*.yml linguist-language=php
*.html linguist-language=php
*.js linguist-language=php
*.xml linguist-language=php
\ No newline at end of file
/.idea
/.vscode
/nbproject
*.log
\ No newline at end of file
sudo: false
language: php
branches:
only:
- stable
cache:
directories:
- $HOME/.composer/cache
before_install:
- composer self-update
install:
- composer install --no-dev --no-interaction --ignore-platform-reqs
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip .
- composer require --update-no-dev --no-interaction "topthink/think-image:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0"
- composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0"
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip .
script:
- php think unit
deploy:
provider: releases
api_key:
secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw=
file:
- ThinkPHP_Core.zip
- ThinkPHP_Full.zip
skip_cleanup: true
on:
tags: true
# Veitool 《免责声明》
> 任何用户在使用由 Veitool 技术开发团队(以下简称「本团队」)研发的 Veitool 开源后台框架系统(以下简称「Veitool 开源框架」)前,请您仔细阅读并透彻理解本声明。您可以选择不使用 Veitool 开源框架,若您一旦使用 Veitool 开源框架,您的使用行为即被视为对本声明全部内容的认可和接受。
1. Veitool 是一款基于 ThinkPHP 框架扩展的 PHP 基础程序平台,主要用于更便捷的后台应用程序开发,除系统基础功能以外,本身不具备业务模块功能。
2. 您承诺秉着合法、合理的原则使用 Veitool 开源框架,不利用 Veitool 开源框架进行任何违法、侵害他人合法利益等恶意的行为,亦不将 Veitool 开源框架运用于任何违反我国法律法规的 Web 平台。
3. 任何单位或个人因下载使用 Veitool 开源框架而产生的任何意外、疏忽、合约毁坏、诽谤、版权或知识产权侵犯及其造成的损失 (包括但不限于直接、间接、附带或衍生的损失等),本团队不承担任何法律责任。
4. 用户明确并同意本声明条款列举的全部内容,对使用 Veitool 开源框架可能存在的风险和相关后果将完全由用户自行承担,本团队不承担任何法律责任。
5. 任何单位或个人在阅读本免责声明后,应在《Apache-2.0 开源许可证》所允许的范围内进行合法的发布、传播和使用 Veitool 开源框架等行为,若违反本免责声明条款或违反法律法规所造成的法律责任(包括但不限于民事赔偿和刑事责任),由违约者自行承担。
6. 本团队对 Veitool 开源框架拥有知识产权(包括但不限于商标权、专利权、著作权、商业秘密等),上述产品均受到相关法律法规的保护。
7. 任何单位或个人不得在未经本团队书面授权的情况下对 Veitool 开源框架本身申请相关的知识产权。
8. 如果本声明的任何部分被认为无效或不可执行,则该部分将被解释为反映本团队的初衷,其余部分仍具有完全效力。不可执行的部分声明,并不构成我们放弃执行该声明的权利。
9. 本团队有权随时对本声明条款及附件内容进行单方面的变更,并以消息推送、网页公告等方式予以公布,公布后立即自动生效,无需另行单独通知;若您在本声明内容公告变更后继续使用的,表示您已充分阅读、理解并接受修改后的声明内容。
\ No newline at end of file
This diff is collapsed.
![](https://www.veitool.com/file/demo/logo.png)
Veitool V2.2.3 正式版
===============
Veitool 是一款PHP开发的框架系统,基于ThinkPHP8.x + Layui2.9.x架构,拥有完善的菜单、角色、权限管理机制,集成了常用的管理构建模块,用户可快速便捷的在此基础上进行二次开发、配置、扩展功能,以及可通过安装插件快捷实现系统功能。
## 官方网址
https://www.veitool.com
## 官方社区
https://www.veitool.com/ask
## 演示地址
https://demo.veitool.com/admin
## 反馈邮箱
veitoolphp@gmail.com
## 系统要求
运行环境支持Nginx、Apache、IIS,要求PHP>=8.1。
## 系统特点
#### 安全高效
严谨的验证安全机制,秉承高效的设计理念,我们采用了尽可能代码复用的设计,异步防重载局部解析运行,以及视图模板解析尽量终端处理以提高请求呈现高效稳定。跨平台可运行在Linux、Windows、MacOSX等多种平台上。
#### 应用灵活
模块化设计,我们尽可能的实现代码逻辑最优化处理,降低冗余代码注重细节以求更完美的结合。完善的菜单、角色、权限管理机制,服务端程序逻辑清晰、低冗余、模块化设计,应用构建灵活,界面简约美观,前后端均无需编译低运维成本,利于全栈开发。
#### 快捷构建
内置常用基础应用模块,方便初步接触者参考快速入手,在线窗口化快速生成相关模块以及配置相关参数、亦可安装拖拽插件实现可视化布局。丰富的在线插件安装满足多方应用需求。组件化接口便于二次开发,迭代分享更快捷、丰富。
#### 请作者喝咖啡☕️
<img src="https://www.veitool.com/file/pay/wepay.jpg" width="200"/>
<img src="https://www.veitool.com/file/pay/alipay.jpg" width="200"/>
<p>如果您觉得 Veitool 框架对您有所帮助,欢迎捐赠。<b><a href="https://www.veitool.com/donate">【捐赠列表】</a></b></p>
## 版权信息
Veitool 采用 [Apache2.0](https://opensource.org/license/apache-2-0/) 开源协议发布,并免费提供使用《[免责声明](https://gitee.com/veitool/veitool/blob/master/DISCLAIMER.md)》。
版权所有Copyright © 2025 by https://www.veitool.com All rights reserved。
\ No newline at end of file
deny from all
\ No newline at end of file
<?php
/**
* ===========================================================================
* Veitool 快捷开发框架系统
* Author: Niaho 26843818@qq.com
* Copyright (c)2020-2022 www.veitool.com All rights reserved.
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace addons\build;
use veitool\addons\Base;
use tool\Menus;
use think\facade\Db;
/**
* 构建器
*/
class Build extends Base
{
/**
* 插件名称
* @var string
*/
private $name = 'build';
/**
* 插件安装方法 必须要实现的
* @return bool
*/
public function install()
{
$file = str_replace('\\', '/', dirname(__FILE__)) . '/data/menus.php';
if(is_file($file)){
$data = include_once $file;
Menus::create($data,1,$this->name);
}
//追加插件应用路由
$this->setAddons([$this->name]);
return true;
}
/**
* 插件卸载方法 必须要实现的
* @return bool
*/
public function uninstall()
{
//删除相关菜单项
Menus::delete($this->name);
//剔除系统应用路由
$this->setAddons([$this->name], false);
return true;
}
/**
* 插件升级方法、变动的数据、配置处理逻辑
* @return bool
*/
public function upgrade()
{
return true;
}
/**
* 插件启用方法
* @return bool
*/
public function enable()
{
Menus::enable($this->name);
//追加插件应用路由
$this->setAddons([$this->name]);
return true;
}
/**
* 插件禁用方法
* @return bool
*/
public function disable()
{
Menus::disable($this->name);
//剔除系统应用路由
$this->setAddons([$this->name], false);
return true;
}
}
\ No newline at end of file
<?php
/**
* ===========================================================================
* Veitool 快捷开发框架系统
* Author: Niaho 26843818@qq.com
* Copyright (c)2020-2022 www.veitool.com All rights reserved.
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace addons\build\controller;
use addons\build\tool\Build;
use think\facade\Db;
use think\Exception;
use app\admin\controller\AdminBase;
/**
* 构建工控制器
*/
class Index extends AdminBase
{
/**
* 构建类型
* @var array
*/
private $Types = ['controller'=>"控制器类",'model'=>"模型类",'command'=>"指令类",'validate'=>"验证器类",'middleware'=>"中间件类",'event'=>"事件类",'listener'=>"监听器类",'subscribe'=>"订阅者类",'service'=>"系统服务类"];
/**
* 构建记录
* @param string $do 异步数据
* @return mixed
*/
public function index(string $do = '')
{
if($do=='json'){
$where = [];
$d = $this->request->get('','','strip_sql');
$kw = $d['kw'] ?? '';
$fds = ['note','username','ip'];
$field = isset($d['fields']) && isset($fds[$d['fields']]) ? $d['fields'] : -1;
$sotime = $d['sotime'] ?? '';
$type = $d['type'] ?? '';
$state = $d['state'] ?? '';
$limit = isset($d['limit']) ? intval($d['limit']) : 10;
if($kw!=''){
if($field>-1){
$where[] = $field>1 ? [$fds[$field],'LIKE', '%'.$kw.'%'] : [$fds[$field],'=',$kw];
}else{
$where[] = [implode('|',$fds),'LIKE', '%'.$kw.'%'];
}
}
if(strpos($sotime,' - ')!==false){
$t = explode(' - ',$sotime);
$where[] = ['logtime','>=',strtotime($t[0]." 00:00:00")];
$where[] = ['logtime','<=',strtotime($t[1]." 23:59:59")];
}
if($type) $where[] = ['type','=',$type];
if(is_numeric($state)) $where[] = ['state','=',$state];
return $this->returnMsg(Db::name("build_local")->where($where)->order(['id'=>'desc'])->field("*")->paginate($limit));
}
$this->assign([
'limit'=>10,
'Types'=> json_encode($this->Types)
]);
return $this->fetch();
}
/**
* 在线构建 php think make:controller admin@Veitool --admin
* @return mixed
*/
public function add()
{
$d = $this->request->post();
$content = $d['content'] ?? '';
if(!$content) return $this->returnMsg("请选择构建命令");
$cou = [0,0];
//$make = new \think\Console($this->app);
try{
$darr = explode("\n", $content);
foreach($darr as $str){
// 多空格替换为1个空格
$str = preg_replace("/\s+/",' ',$str);
$rs = explode(' ', $str);
$type = substr($rs[2],5);
$arr = [];
$arr[0] = $rs[3] ?? '';
if(isset($rs[4]) && $rs[4]){$arr[1] = $rs[4];}
if(in_array($type,['controller','model'])){$arr['remarks'] = $d['note'] ?? '';}
// 开始构建
//$info = $make->call($rs[2], $arr)->fetch();
$info = $this->app->console->call($rs[2], $arr)->fetch();
$state = strstr($info,'<error>')===false ? 1 : 0;
$cou[$state] ++;
// 创建日志
Db::name('build_local')->insert([
"username" => $this->manUser['username'],
"type" => $type,
"note" => $info,
"state" => $state,
"ip" => $this->request->ip(),
"logtime" => time()
]);
}
}catch(Exception $e){
return $this->returnMsg($e->getMessage());
}
return $this->returnMsg('构建完成(成功:'.$cou[1].' 失败:'.$cou[0].')',1);
}
/**
* 删除记录
* @return mixed
*/
public function del(){
$id = $this->request->post('id/a','','intval');
if(!$id) return $this->returnMsg('参数错误');
if(Db::name('build_local')->delete($id)){
return $this->returnMsg("删除成功!", 1);
}else{
return $this->returnMsg("删除失败!");
}
}
/**
* 微库构建记录
* @param string $do 异步数据
* @return mixed
*/
public function veitool(string $do = '')
{
if($do == 'json'){
$where = [];
$d = $this->request->get('','','strip_sql');
$kw = $d['kw'] ?? '';
$fds = ['note','username','ip'];
$field = isset($d['fields']) && isset($fds[$d['fields']]) ? $d['fields'] : -1;
$sotime = $d['sotime'] ?? '';
$type = $d['type'] ?? '';
$state = $d['state'] ?? '';
$limit = isset($d['limit']) ? intval($d['limit']) : 10;
if($kw!=''){
if($field>-1){
$where[] = $field>1 ? [$fds[$field],'LIKE', '%'.$kw.'%'] : [$fds[$field],'=',$kw];
}else{
$where[] = [implode('|',$fds),'LIKE', '%'.$kw.'%'];
}
}
if(strpos($sotime,' - ')!==false){
$t = explode(' - ',$sotime);
$where[] = ['logtime','>=',strtotime($t[0]." 00:00:00")];
$where[] = ['logtime','<=',strtotime($t[1]." 23:59:59")];
}
if($type) $where[] = ['type','=',$type];
if(is_numeric($state)) $where[] = ['state','=',$state];
return $this->returnMsg(Db::name("build_veitool")->where($where)->order(['id'=>'desc'])->field("*")->paginate($limit));
}
$this->assign([
'limit' => 10
]);
return $this->fetch();
}
/**
* 微库构建
*/
public function build(){
$d = $this->only(['type/s','uid/d','repeat/d','reback/d','name/*/{2,20}/标识名称/1,2/','token','title/h','db_table/*/{2,20}/数据表名/1,2/_','app_dir','sub_dir','parent_id/d']);
if(Db::name('build_veitool')->where("name = '$d[name]'")->find()) return $this->returnMsg('构建标识名称已经存在,请更换为其他标识!');
try{
$d['version'] = VT_VERSION;
//获取模板后缀
$d['suffix'] = config('view.view_suffix');
Build::build($d['name'], $d);
Db::name('build_veitool')->insert([
'name' => $d['name'],
"type" => $d['type'],
"db_table" => $d['db_table'],
"app_dir" => $d['app_dir'],
"sub_dir" => $d['sub_dir'],
"ip" => $this->request->ip(),
"logtime" => time(),
"username" => $this->manUser['username']
]);
return $this->returnMsg('构建成功', 1);
}catch(Exception $e){
return $this->returnMsg($e->getMessage(),$e->getCode());
}
}
/**
* 卸载构建
* @return json
*/
public function uninstall()
{
$d = $this->only(['@token'=>'','name/*/a']);
try{
Build::uninstall($d['name']);
Db::name('build_veitool')->where("name = '$d[name]'")->delete();
return $this->returnMsg('卸载成功', 1);
}catch(Exception $e){
return $this->returnMsg($e->getMessage(),$e->getCode());
}
}
/**
* 删除记录
* @return mixed
*/
public function vdel(){
$id = $this->only(['@token'=>'','id'])['id'];
$id = is_array($id) ? implode(',',$id) : $id;
if(!$id) return $this->returnMsg('参数错误');
$rs = Db::name('build_veitool')->where("id IN($id)")->column('name');
if(Db::name('build_veitool')->where("id IN($id)")->delete()){
foreach ($rs as $v){
@rmdirs(ADDON_PATH . '/build/data/' . $v);
}
return $this->returnMsg("删除成功!", 1);
}else{
return $this->returnMsg("删除失败!");
}
}
}
\ No newline at end of file
{"license":"623","licensekey":"84f74899c71628c75fd3c8a8fa3972de"}
\ No newline at end of file
DROP TABLE IF EXISTS `__PREFIX__build_local`;
CREATE TABLE `__PREFIX__build_local` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(30) NOT NULL DEFAULT '' COMMENT '用户',
`type` varchar(30) NOT NULL DEFAULT '' COMMENT '类型',
`note` varchar(200) NOT NULL DEFAULT '' COMMENT '说明',
`ip` varchar(50) NOT NULL DEFAULT '' COMMENT 'IP',
`logtime` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
`state` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态:0失败,1成功',
PRIMARY KEY (`id`),
KEY `username` (`username`),
KEY `type` (`type`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='简捷构建日志';
DROP TABLE IF EXISTS `__PREFIX__build_veitool`;
CREATE TABLE `__PREFIX__build_veitool` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL DEFAULT '' COMMENT '构建标识名称',
`username` varchar(30) NOT NULL DEFAULT '' COMMENT '用户',
`type` varchar(30) NOT NULL DEFAULT '' COMMENT '类型',
`title` varchar(50) NOT NULL DEFAULT '' COMMENT '标题',
`db_table` varchar(30) NOT NULL DEFAULT '' COMMENT '数据表名',
`app_dir` varchar(30) NOT NULL DEFAULT '' COMMENT '应用目录',
`sub_dir` varchar(30) NOT NULL DEFAULT '' COMMENT '子级目录',
`ip` varchar(50) NOT NULL DEFAULT '' COMMENT 'IP',
`logtime` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
`state` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态:0失败,1成功',
PRIMARY KEY (`id`),
KEY `username` (`username`),
KEY `type` (`type`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='微库构建日志';
\ No newline at end of file
<?php
return [
0 => [
'catid' => 1,
'name' => 'build',
'menu_name' => '在线构建',
'role_name' => '在线构建',
'role_url' => '',
'listorder' => 100,
'ismenu' => 1,
'state' => 1,
'type' => 1,
'sublist' => [
0 => [
'catid' => 1,
'name' => 'build',
'menu_name' => '简捷构建',
'role_name' => '简捷构建',
'link_url' => '@',
'menu_url' => 'build/index/index',
'role_url' => '',
'listorder' => 10,
'ismenu' => 1,
'state' => 1,
'type' => 1,
'sublist' => [
0 => [
'catid' => 1,
'name' => 'build',
'menu_name' => '构建记录',
'role_name' => '构建记录',
'role_url' => 'build/index/index',
'listorder' => 10,
'ismenu' => 0,
'state' => 0,
'type' => 1,
],
1 => [
'catid' => 1,
'name' => 'build',
'menu_name' => '构建添加',
'role_name' => '构建添加',
'role_url' => 'build/index/add',
'listorder' => 10,
'ismenu' => 0,
'state' => 0,
'type' => 1,
],
2 => [
'catid' => 1,
'name' => 'build',
'menu_name' => '构建删除',
'role_name' => '构建删除',
'role_url' => 'build/index/del',
'listorder' => 10,
'ismenu' => 0,
'state' => 0,
'type' => 1,
],
],
],
1 => [
'catid' => 1,
'name' => 'build',
'menu_name' => '微库构建',
'role_name' => '微库构建',
'link_url' => '@',
'menu_url' => 'build/index/veitool',
'role_url' => '',
'listorder' => 10,
'ismenu' => 1,
'state' => 1,
'type' => 1,
'sublist' => [
0 => [
'catid' => 1,
'name' => 'build',
'menu_name' => '构建记录',
'role_name' => '构建记录',
'role_url' => 'build/index/veitool',
'listorder' => 10,
'ismenu' => 0,
'state' => 0,
'type' => 1,
],
1 => [
'catid' => 1,
'name' => 'build',
'menu_name' => '微库构建',
'role_name' => '微库构建',
'role_url' => 'build/index/build',
'listorder' => 10,
'ismenu' => 0,
'state' => 0,
'type' => 1,
],
2 => [
'catid' => 1,
'name' => 'build',
'menu_name' => '构建编辑',
'role_name' => '构建编辑',
'role_url' => 'build/index/vedit',
'listorder' => 10,
'ismenu' => 0,
'state' => 0,
'type' => 1,
],
3 => [
'catid' => 1,
'name' => 'build',
'menu_name' => '构建删除',
'role_name' => '构建删除',
'role_url' => 'build/index/vdel',
'listorder' => 10,
'ismenu' => 0,
'state' => 0,
'type' => 1,
],
],
],
],
]
];
\ No newline at end of file
name = build
title = Veitool框架命令构建器
intro = 基于Veitool快捷开发框架的命令构建器
author = veitool
website = https://www.veitool.com
version = 1.0.1
state = 1
home = 0
license = 623
\ No newline at end of file
This diff is collapsed.
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header">
<form class="layui-form" lay-filter="build-form-search">
<div class="layui-form-item">
<div class="layui-inline" style="width:72px;"><select name="fields"><option value="">属性</option><option value="0">说明</option><option value="1">用户</option><option value="2">IP</option></select></div>
<div class="layui-inline" style="width:120px;"><input type="text" name="kw" placeholder="关键词" autocomplete="off" class="layui-input"></div>
<div class="layui-inline" style="margin-right:0;">
<div class="layui-input-inline" style="width:172px;"><input type="text" name="sotime" id="build-search-time" placeholder="构建时间" autocomplete="off" class="layui-input"></div>
</div>
<div class="layui-inline" style="width:110px;"><select name="type" id="build_top_select"></select></div>
<div class="layui-inline" style="width:72px;"><select name="state"><option value="">状态</option><option value="0">失败</option><option value="1">成功</option></select></div>
<div class="layui-inline">
<div class="layui-btn-group">
<button class="layui-btn" lay-submit lay-filter="top-build-search"><i class="layui-icon layui-icon-search layuiadmin-button-btn"></i> 搜索</button>
<button class="layui-btn" lay-submit lay-filter="top-build-all"><i class="layui-icon layui-icon-light"></i>全部</button>
</div>
</div>
</div>
</form>
</div>
<div class="layui-card-body">
<div class="layui-card-box">
<div class="layui-btn-group">
<button class="layui-btn" id="top-build-add"><i class="layui-icon layui-icon-add-circle"></i> 构建</button>
<button class="layui-btn" id="top-build-del"><i class="layui-icon layui-icon-delete"></i> 删除</button>
</div>
</div>
<table lay-filter="build" id="build"></table>
</div>
</div>
</div>
<!--JS部分-->
<script type="text/javascript">
layui.use(['buildItems'], function(){
var map_root = 'build/', app_root = map_root + 'index/';
var $=layui.$,table=layui.table,form=layui.form,laydate=layui.laydate,admin=layui.admin,dropdown=layui.dropdown;
var Types = {$Types|raw};
var type_select = ''; $.each(Types,function(k,v){type_select += '<option value="'+ k +'">'+ v +'</option>';});
//顶部搜索类型
$('#build_top_select').html('<option value="">构建类型</option>' + type_select);
//渲染搜索元素
form.render(null,'build-form-search');
laydate.render({elem:'#build-search-time',range:true,format:'yyyy/MM/dd'});
/*渲染数据*/
table.render({
elem: '#build',
url: app_root + "index?do=json",
cols: [[
{type:'checkbox',fixed:'left'},
{field:"id",fixed:"left",width:50,align:'center',title:"ID",sort:!0},
{field:"type",width:120,align:'center',templet:function(d){return Types[d.type];},title:"类型"},
{field:"note",title:"反馈"},
{field:"username",width:130,align:'center',title: "帐号"},
{field:"ip",align:'center',width:160,toolbar:'<div><a style="cursor:pointer;" lay-event="showip">{{d.ip}}</a></div>',title:"IP"},
{field:"logtime",width:160,align:'center',templet:function(d){return layui.util.toDateString(d.logtime*1000);},title:"时间",sort:!0},
{field:"state",width:80,align:'center',templet:function(d){return d.state==1 ? '<font color=green>成功</font>' : '<font color=red>失败</font>';},title:"状态"}
]],
page: true,
limit:{$limit}
});/**/
/*监听搜索*/
form.on('submit(top-build-search)',function(data){
var field = data.field;
table.reload('build',{where:field,page:{curr:1}});
return false;
});/**/
/*监听全部按钮*/
form.on('submit(top-build-all)',function(){
table.reload('build',{where:'',page:{curr:1}});
return false;
});/**/
/*顶部添加按钮*/
$('#top-build-add').on('click',function(){buildOpen();});
/*顶部删除按钮*/
$('#top-build-del').on('click', function(){
var checkRows = table.checkStatus('build').data;
if(checkRows.length === 0){return layer.msg('请选择需删除的记录');}
var ids = checkRows.map(function(d){return d.id;});
del(ids);
});/**/
/*删除*/
function del(ids){
layer.confirm('确定要删除所选记录吗?', function(index){
layer.close(index);
admin.req(app_root+"del",{id:ids},function(res){
layer.msg(res.msg,{shade:[0.4,'#000'],time:1500},function(){
if(res.code==1) table.reloadData('build');
});
},'post');
});
}/**/
/*构建弹窗*/
function buildOpen(){
admin.open({
type: 1,
bid: 'build_items',
btn: ['开始构建', '取消'],
area: ['720px', '700px'],
title: '简捷构建器',
success: function(l,index){
layui.buildItems.build({
bid: 'build_items',
data: [
{name:"name",title:"构建类名",type:"text",value:'',id:'buildname',placeholder:"请输入构建类名"},
{name:"content",title:"构建命令",type:"textarea",value:'',verify:'required',id:'buildcode',placeholder:"php think make:controller admin/dir@folder/Veitool --admin",style:'height:200px',must:true},
{name:"note",title:"类名备注",type:"text",value:'',placeholder:"请输入类名备注"}
]
});
dropdown.render({
elem: '#buildcode',
data: [
{id:'php think make:controller admin@Veitool --admin',title:'后台控制器:php think make:controller admin@Veitool --admin'},
{id:'php think make:controller index@Veitool --index',title:'前台控制器:php think make:controller index@Veitool --index'},
{id:'php think make:controller api@Veitool --api',title:'API控制器:php think make:controller api@Veitool --api'},
{id:'php think make:model Veitool',title:'数据模型类:php think make:model Veitool'},
{id:'php think make:validate Veitool',title:'验证器类:php think make:validate Veitool'},
{id:'php think make:middleware Veitool',title:'中间件类:php think make:middleware Veitool'},
{id:'php think make:listener Veitool',title:'监听器类:php think make:listener Veitool'},
{id:'php think make:subscribe Veitool',title:'订阅者类:php think make:subscribe Veitool'},
{id:'php think make:service Veitool',title:'系统服务类:php think make:service Veitool'},
{id:'php think make:event Veitool',title:'事件类:php think make:event Veitool'},
{id:'php think make:command Veitool',title:'指令类:php think make:command Veitool'}
],
click: function(d){
var str = d.id, cont = $('#buildcode').val(), name = $('#buildname').val();
str = name ? str.replace(/Veitool/,name.charAt(0).toUpperCase() + name.slice(1)) : str;
if(cont.indexOf(str) === -1){
$('#buildcode').val(cont ? cont+'\n'+str : str);
}
return false;
},
style: 'width:580px;height:300px;overflow-y:auto;overflow-x:hidden'
});
form.on('submit(build_items)',function(data){
var btn = $(this);
if(btn.attr('stop')){return false}else{btn.attr('stop',1)}
admin.req(app_root+'add',data.field,function(res){
res.msg = res.code==1 ? '构建成功:'+ res.msg : '构建失败:'+ res.msg;
layer.msg(res.msg,{shade:[0.4,'#000'],time:2000},function(){
if(res.code==1){
table.reload('build');
}
btn.removeAttr('stop');
});
},'post');
return false;
});
}
});
}/**/
});
</script>
\ No newline at end of file
This diff is collapsed.
<?php
/**
* ===========================================================================
* Veitool 快捷开发框架系统
* Author: Niaho 26843818@qq.com
* Copyright (c)2020-2022 www.veitool.com All rights reserved.
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace addons\vtool;
use veitool\addons\Base;
use tool\Menus;
use think\facade\Db;
/**
* Vtool插件
*/
class Vtool extends Base
{
/**
* 插件名称
* @var string
*/
private $name = 'vtool';
/**
* 插件安装方法 必须要实现的
* @return bool
*/
public function install()
{
//引入菜单数据并导入
$file = str_replace('\\', '/', dirname(__FILE__)) . '/data/menus.php';
if(is_file($file)){
$data = include_once $file;
Menus::create($data,1,$this->name);
}
//追加插件应用路由
$this->setAddons([$this->name]);
return true;
}
/**
* 插件卸载方法 必须要实现的
* @return bool
*/
public function uninstall()
{
//删除相关菜单项
Menus::delete($this->name);
/* 删除安装的相关数据表 【如果表名中含有 "pre_插件标识符_" 的前缀 则不需要这一步】 */
if(config('veitool.ddata',1)){
$prefix = config('database.connections.'.config('database.default').'.prefix');
Db::execute("DROP TABLE IF EXISTS `{$prefix}build_module`");
}/**/
//剔除系统应用路由
$this->setAddons([$this->name], false);
return true;
}
/**
* 插件升级方法、变动的数据、配置处理逻辑
* @return bool
*/
public function upgrade()
{
$pre = config('database.connections.'.config('database.default').'.prefix');
Db::query("ALTER TABLE {$pre}build_module ADD COLUMN `state` tinyint(1) unsigned NOT NULL DEFAULT 1 COMMENT '状态:0停用1启用' AFTER note;");
return true;
}
/**
* 插件启用方法
* @return bool
*/
public function enable()
{
Menus::enable($this->name);
//追加插件应用路由
$this->setAddons([$this->name]);
return true;
}
/**
* 插件禁用方法
* @return bool
*/
public function disable()
{
Menus::disable($this->name);
//剔除系统应用路由
$this->setAddons([$this->name], false);
return true;
}
}
<?php
/**
* ===========================================================================
* Veitool 快捷开发框架系统
* Author: Niaho 26843818@qq.com
* Copyright (c)2020-2024 www.veitool.com All rights reserved.
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace addons\vtool\controller;
use think\facade\Db;
use think\Exception;
use app\admin\controller\AdminBase;
use addons\vtool\tool\Build;
use addons\vtool\model\BuildModule as MD;
/**
* 插件内的主控制器
*/
class Index extends AdminBase
{
/**
* 构建记录
* @param string $do 异步数据
* @return mixed
*/
public function index(string $do='')
{
if($do == 'json'){
$where = [];
$d = $this->request->get('','','strip_sql');
$kw = $d['kw'] ?? '';
$fds = ['title','name','controller'];
$field = isset($d['fields']) && isset($fds[$d['fields']]) ? $d['fields'] : -1;
$sotime = $d['sotime'] ?? '';
$type = $d['type'] ?? '';
$state = $d['state'] ?? '';
$limit = isset($d['limit']) ? intval($d['limit']) : 10;
if($kw!=''){
if($field>-1){
$where[] = $field>1 ? [$fds[$field],'LIKE', '%'.$kw.'%'] : [$fds[$field],'=',$kw];
}else{
$where[] = [implode('|',$fds),'LIKE', '%'.$kw.'%'];
}
}
if(strpos($sotime,' - ')!==false){
$t = explode(' - ',$sotime);
$where[] = ['addtime','>=',strtotime($t[0]." 00:00:00")];
$where[] = ['addtime','<=',strtotime($t[1]." 23:59:59")];
}
if($type) $where[] = ['type','=',$type];
if(is_numeric($state)) $where[] = ['state','=',$state];
return $this->returnMsg(MD::where($where)->order(['id'=>'desc'])->field('*')->paginate($limit)); // ->withoutField('table_fields')
}elseif($do == 'table'){
return $this->fetch($do);
}elseif($do == 'tableInfo'){
$db = new \tool\MysqlBackup;
$rs = $db->dataList();
$data = [];
foreach ($rs as $v){
$data[] = ['name'=>$v['name'], 'value'=>$v['name']];
}
return $this->returnMsg($data);
}elseif($do == 'tableSQL'){
$table = $this->request->get('table');
$rs = array_map('array_change_key_case', Db::query("SHOW CREATE TABLE `$table`"));
return $this->returnMsg($rs[0]['create table'] ?? '');
}
$this->assign([
'limit'=>10
]);
return $this->fetch();
}
/**
* 模块添加
* @return json
*/
public function add()
{
$d = $this->only(['@token'=>'','name/*/{2,30}/模块标识/1,2,3/','title/h/请输入模块名称','controller/*/{2,30}/请输入控制器名称/1,2/','table/?/{2,30}/数据表名/1,2/_','appdir/*/{2,30}/应用目录/1,2,3/@_','subdir/?/{2,30}/子目录/1,2,3/_','table_engine','table_charset','table_size/d','form_type/d','excelout/d','excelup/d','type/d','do_build/d','menu_pid/d','dict_load/d','open_size/*/{5,30}/弹窗尺寸/1,2/,%','table_fields']);
//检查模块
if($rs = MD::where("name = '$d[name]' OR `table` = '$d[table]' OR (controller = '$d[controller]' AND appdir = '$d[appdir]' AND subdir = '$d[subdir]')")->find()){
if($rs['name'] == $d['name']) return $this->returnMsg('模块标识已经存在');
if($rs['table'] == $d['table']) return $this->returnMsg('数据表已经存在');
return $this->returnMsg('控制器路由已经存在');
}
//创建信息
$d['note'] = '';
$d["addtime"] = time();
$d['add'] = $this->manUser['username'];
if(MD::insert($d)){
return $this->returnMsg("添加成功", 1);
}else{
return $this->returnMsg('添加失败');
}
}
/**
* 模块编辑
* @param string $do 快编操作
* @return json
*/
public function edit(string $do='')
{
$d = $this->only($do ? ['@token'=>'','id/d/参数错误222','av','af'] : ['@token'=>'','id/d/参数错误212','name/*/{2,30}/模块标识/1,2,3/','title/h/请输入模块名称','controller/*/{2,30}/请输入控制器名称/1,2/','table/?/{2,30}/数据表名/1,2/_','appdir/*/{2,30}/应用目录/1,2,3/@_','subdir/?/{2,30}/子目录/1,2,3/_','table_engine','table_charset','table_size/d','form_type/d','excelout/d','excelup/d','type/d','do_build/d','menu_pid/d','dict_load/d','open_size/*/{5,30}/弹窗尺寸/1,2/,%','action']);
$id = $d['id'];
$Myobj = MD::one("id = $id");
if(!$Myobj) return $this->returnMsg("数据不存在");
if($do=='up'){
$value = $d['av'];
$field = $d['af'];
if(!in_array($field,['table_fields','state'])) return $this->returnMsg("参数错误32132");
return $this->returnMsg($Myobj->save(['edit'=>$this->manUser['username'], 'edittime'=>time(), $field=>$value]) ? "设置成功" : '设置失败', 1);
}else{
//检查模块
if($rs = MD::where("id <> '$id' AND (name = '$d[name]' OR `table` = '$d[table]' OR (controller = '$d[controller]' AND appdir = '$d[appdir]' AND subdir = '$d[subdir]'))")->find()){
if($rs['name'] == $d['name']) return $this->returnMsg('模块标识已经存在');
if($rs['table'] == $d['table']) return $this->returnMsg('数据表已经存在');
return $this->returnMsg('控制器路由已经存在');
}
$d["edittime"] = time();
$d['edit'] = $this->manUser['username'];
$action = $d['action']; unset($d['action']);
if($Myobj->save($d)){
if($action == 'build'){ //生成代码
if(!$Myobj->state) return $this->returnMsg('模块已被停用,数据已保存,构建未执行');
$rs = $Myobj->toArray();
if(!$rs['table_fields'] || $rs['table_fields'] == '[]') return $this->returnMsg('请先配置好数据表字段');
unset($rs['addtime'],$rs['edittime'],$rs['runtime'],$rs['times'],$rs['add'],$rs['edit'],$rs['run'],$rs['note']);
$d = $this->only(['uid/d','token','repeat/d','reback/d']);
$d = array_merge($rs,$d);
try{
$d['version'] = VT_VERSION;
//删除相关菜单
if($d['do_build'] > 1) \tool\Menus::delete($d['name']);
//获取模板后缀
$d['suffix'] = config('view.view_suffix');
//开始远程构建
Build::build(strtolower($d['name']), $d);
//记录操作
$Myobj->times ++;
$Myobj->runtime = time();
$Myobj->run = $this->manUser['username'];
$note = '标识:'.$d['name'].' 控制器:'.$d['controller'].' 目录:'.$d['appdir'].($d['subdir'] ? ' / '.$d['subdir'] : '').(in_array($d['do_build'],[1,3]) ? ' 创建表:'.$d['table'].'/'.$d['table_engine'].'/'.$d['table_charset'] : '').(in_array($d['do_build'],[2,3]) ? ' 建菜单' : '').' 用户:'.$this->manUser['username'];
$Myobj->note = $Myobj->note . '<li><a>'.date('Y-m-d H:i:s', time()).' #</a> <a>'.$note.' 执行生成</a></li>';
$Myobj->save();
}catch(Exception $e){
return $this->returnMsg($e->getMessage(),$e->getCode());
}
return $this->returnMsg('生成成功',1);
}
return $this->returnMsg("编辑成功", 1);
}else{
return $this->returnMsg("编辑失败");
}
}
}
/**
* 模块删除
* @return json
*/
public function del()
{
$id = $this->only(['@token'=>'','id'])['id'];
$id = is_array($id) ? implode(',',$id) : $id;
if(!$id) return $this->returnMsg('参数错误');
$rs = MD::where("id IN($id)")->column('name');
if(MD::del("id IN($id)")){
/* 删除记录文件 */
foreach ($rs as $v){
@rmdirs(ADDON_PATH . '/vtool/data/' . $v);
}/**/
return $this->returnMsg("删除成功", 1);
}else{
return $this->returnMsg("删除失败");
}
}
/**
* 模块卸载
* @return json
*/
public function uninstall()
{
$d = $this->only(['@token'=>'','name/*/{2,30}/模块标识/1,2,3/']);
try{
$Myobj = MD::one("name = '".$d['name']."'");
if(!$Myobj) return $this->returnMsg("数据不存在");
if(!$Myobj->state) return $this->returnMsg('模块已被停用,不能执行卸载');
//执行卸载
Build::uninstall(strtolower($d['name']));
//记录操作
$Myobj->note = $Myobj->note . '<li><a>'.date('Y-m-d H:i:s', time()).' #</a> <a>'.$this->manUser['username'].' 执行卸载</a></li>';
$Myobj->save();
return $this->returnMsg('卸载成功', 1);
}catch(Exception $e){
return $this->returnMsg($e->getMessage(),$e->getCode());
}
}
}
\ No newline at end of file
{"license":"623","licensekey":"f9b8e26637b5d1b2dbebbd6633b1159b"}
\ No newline at end of file
This diff is collapsed.
<?php
return [
0 => [
'catid' => 1,
'name' => 'vtool',
'menu_name' => '在线构建',
'role_name' => '在线构建',
'link_url' => '@',
'menu_url' => 'vtool/index/index',
'role_url' => '',
'listorder' => 10,
'ismenu' => 1,
'state' => 1,
'type' => 1,
'sublist' => [
0 => [
'catid' => 1,
'name' => 'vtool',
'menu_name' => '模块列表',
'role_name' => '模块列表',
'role_url' => 'vtool/index/index',
'listorder' => 10,
'ismenu' => 0,
'state' => 0,
'type' => 1,
],
1 => [
'catid' => 1,
'name' => 'vtool',
'menu_name' => '模块添加',
'role_name' => '模块添加',
'role_url' => 'vtool/index/add',
'listorder' => 10,
'ismenu' => 0,
'state' => 0,
'type' => 1,
],
2 => [
'catid' => 1,
'name' => 'vtool',
'menu_name' => '模块编辑',
'role_name' => '模块编辑',
'role_url' => 'vtool/index/edit',
'listorder' => 10,
'ismenu' => 0,
'state' => 0,
'type' => 1,
],
3 => [
'catid' => 1,
'name' => 'vtool',
'menu_name' => '模块删除',
'role_name' => '模块删除',
'role_url' => 'vtool/index/del',
'listorder' => 10,
'ismenu' => 0,
'state' => 0,
'type' => 1,
],
4 => [
'catid' => 1,
'name' => 'vtool',
'menu_name' => '模块卸载',
'role_name' => '模块卸载',
'role_url' => 'vtool/index/uninstall',
'listorder' => 10,
'ismenu' => 0,
'state' => 0,
'type' => 1,
],
],
],
];
name = vtool
title = Veitool模块在线快速构建器
intro = 在线自由配置数据表、数据表格、详细弹窗、表单添加编辑弹窗,快速生成控制器、模型、视图代码
author = veitool
website = https://www.veitool.com
version = 1.0.4
state = 1
home = 0
license = 623
\ No newline at end of file
<?php
/**
* ===========================================================================
* Veitool 快捷开发框架系统
* Author: Niaho 26843818@qq.com
* Copyright (c)2019-2023 www.veitool.com All rights reserved.
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace addons\vtool\model;
use app\model\Base;
/**
*【模型构建模型】
*/
class BuildModule extends Base
{
/**
* 定义主键
* @var string
*/
protected $pk = 'id';
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
deny from all
\ No newline at end of file
<?php
declare(strict_types=1);
namespace app;
use Closure;
use think\Request;
use think\Response;
use think\facade\Route;
/**
* App初始化
*/
class AppInit
{
/**
* 前置中间件
* @param Request $request
* @param Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next): Response
{
$App = app();
/* 路由处理 旧模式不兼容nginx:$url = request()->pathinfo(); */
$url = VT_DIR ? str_replace([".".config('route.url_html_suffix'),VT_DIR.'/'], '', $App->request->url()) : str_replace(".".config('route.url_html_suffix'), '', ltrim($App->request->url(), '/'));
$url = strpos($url, '?') ? strstr($url, '?', true) : $url;
$arr = explode('/', $url);
$addon = $arr[0];
$module = '';
/* 插件应用处理 */
if(in_array($addon,config('veitool.addons'))){
$App->config->set(['app_express'=>false], 'app');
$module = $addon ?: 'index';
$contr = isset($arr[1]) && $arr[1] ? $arr[1] : 'index';
$method = isset($arr[2]) && $arr[2] ? $arr[2] : 'index';
$App->setNamespace("addons\\" . $module);
$App->setAppPath($App->getRootPath() . 'addons' . VT_DS . $module . VT_DS);
is_file($file = ADDON_PATH . $addon . VT_DS . 'data' . VT_DS . 'route.php') && require_once($file);
Route::rule($url, $contr . '/' . $method);
$module .= '/';
}/**/
/* 插件应用名 用于 AdminBase.php 中兼容插件权限 */
$request->ADDON_APP = $module;
return $next($request);
}
}
\ No newline at end of file
This diff is collapsed.
<?php
namespace app;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\Response;
use Throwable;
/**
* 应用异常处理类
*/
class ExceptionHandle extends Handle
{
/**
* 不需要记录信息(日志)的异常类列表
* @var array
*/
protected $ignoreReport = [
HttpException::class,
HttpResponseException::class,
ModelNotFoundException::class,
DataNotFoundException::class,
ValidateException::class,
];
/**
* 记录异常信息(包括日志或者其它方式记录)
* @access public
* @param Throwable $exception
* @return void
*/
public function report(Throwable $exception): void
{
// 使用内置的方式记录异常日志
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
* @access public
* @param \think\Request $request
* @param Throwable $e
* @return Response
*/
public function render($request, Throwable $e): Response
{
// 添加自定义异常处理机制
// 其他错误交给系统处理
return parent::render($request, $e);
}
}
\ No newline at end of file
<?php
namespace app;
// 应用请求对象类
class Request extends \think\Request
{
}
\ No newline at end of file
<?php
/**
* ===========================================================================
* Veitool 快捷开发框架系统
* Author: Niaho 26843818@qq.com
* Copyright (c)2019-2025 www.veitool.com All rights reserved.
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace app\admin\controller;
use think\facade\Db;
use think\Exception;
use veitool\addons\Service;
use veitool\addons\AddonException;
use app\model\system\SystemSetting as S;
/**
* 插件管理控制器
*/
class Addon extends AdminBase
{
/**
* 插件列表
* @return mixed
*/
public function index()
{
$this->assign([
'limit' => 10,
'addons' => json_encode(Service::hasAddon())
]);
return $this->fetch();
}
/**
* 本地已装插件
* @return json
*/
public function exist()
{
$d = $this->only(['kw','uid/d','catid/d','version'=>'0','all'=>'list'],'get');
$kw = $d['kw'];
$catid = $d['catid'];
$d['catid'] = -1;
$addonsOn = Service::onAddon($d);
$addons = Service::hasAddon();
$data = [];
foreach($addons as $k=>$v){
if($kw && stripos($k,$kw)===false && stripos($v['title'],$kw)===false && stripos($v['intro'],$kw)===false) continue;
if(isset($addonsOn[$k])){
$v = array_merge($v,$addonsOn[$k]);
}else{
$v['catid'] = 0;
$v['down'] = '-';
$v['price'] = '-';
$v['require'] = '';
$v['releaselist'] = [];
}
if($catid > -1 && $catid != $v['catid']) continue;
$data[] = $v;
}
return $this->returnMsg($data);
}
/**
* 插件安装
* @return json
*/
public function install()
{
$d = $this->only(['name/*/a','uid/d','token','version'=>'1.0.0']);
try{
$d['vversion'] = VT_VERSION;
Service::install($d['name'], config('veitool.force',1), $d);
}catch(AddonException $e){
return $this->returnMsg($e->getMessage().'_01',$e->getCode(),$e->getData());
}catch(Exception $e){
return $this->returnMsg($e->getMessage().'_02',$e->getCode());
}
return $this->returnMsg('安装成功', 1, ['addons' => Service::hasAddon()]);
}
/**
* 本地上传
* @return json
*/
public function local()
{
$d = $this->only(['uid/d','token']);
if(!$d["uid"] || !$d["token"]) return $this->returnMsg('请先登录Veitool会员后再进行离线安装!',2);
try{
$d["vversion"] = VT_VERSION;
Service::local($this->request->file('file'), config('veitool.force',1), $d);
}catch(AddonException $e){
return $this->returnMsg($e->getMessage().'_01',$e->getCode(),$e->getData());
}catch(Exception $e){
return $this->returnMsg($e->getMessage().'_02');
}
return $this->returnMsg('安装成功', 1, ['addons' => Service::hasAddon()]);
}
/**
* 卸载插件
* @return json
*/
public function uninstall()
{
$d = $this->only(['@token'=>'','name/*/a']);
try{
//只有开启调试且为超级管理员方可删除相关 数据表 和 配置项
$tables = config('veitool.ddata',1) && env('app_debug') && $this->manUser['userid']==1 ? Service::getAddonTables($d['name']) : [];
Service::uninstall($d['name'], config('veitool.force',1));
if($tables){
$prefix = config('database.connections.'.config('database.default').'.prefix');
foreach($tables as $index => $table){
if(!preg_match("/^{$prefix}{$d['name']}/", $table)) continue;
Db::execute("DROP TABLE IF EXISTS `{$table}`");
}
Db::name('system_setting')->where('addon',$d['name'])->delete();
}
}catch(AddonException $e){
return $this->returnMsg($e->getMessage(),$e->getCode(),$e->getData());
}catch(Exception $e){
return $this->returnMsg($e->getMessage(),$e->getCode());
}
return $this->returnMsg('卸载成功', 1, ['addons' => Service::hasAddon()]);
}
/**
* 禁用启用插件
* @return json
*/
public function state()
{
$d = $this->only(['name/*/a','state/d']);
try{
$action = $d['state'] ? 'enable' : 'disable';
Service::$action($d['name'], config('veitool.force',1));
}catch(AddonException $e){
return $this->returnMsg($e->getMessage(),$e->getCode(),$e->getData());
}catch(Exception $e){
return $this->returnMsg($e->getMessage());
}
return $this->returnMsg('设置成功', 1, ['addons' => Service::hasAddon()]);
}
/**
* 更新升级
* @return json
*/
public function upgrade()
{
$d = $this->only(['name/*/a','uid/d','token','version'=>'1.0.0']);
try{
$d["vversion"] = VT_VERSION;
Service::upgrade($d['name'], $d);
}catch(AddonException $e){
return $this->returnMsg($e->getMessage().'_01',$e->getCode(),$e->getData());
}catch(Exception $e){
return $this->returnMsg($e->getMessage().'_02',$e->getCode());
}
return $this->returnMsg('升级成功', 1, ['addons' => Service::hasAddon()]);
}
/**
* 插件配置管理
* @param string $do 操作参数
* @param string $addon 插件名称
* @param string $group 配置分组
* @return mixed
*/
public function setting(string $do = '', string $addon = '', string $group = '')
{
$groups = (array) vconfig('@'.$addon.'.'.'group',[]); reset($groups);
if($do=='json'){
$group = $group ? $group : key($groups);
$where = [];
$where[] = ['state','=',1];
$where[] = ['addon','=',$addon];
if($group) $where[] = ['group','=',$group];
$rs = (new S())->listArray($where,'name,title,value,type,options,private,relation,tips');
foreach($rs as &$v){
if($v['type'] == 'images'){
$v['value'] = $v['value'] ? json_decode($v['value']) : [];
}elseif(in_array($v['type'],['year','month','date','time','datetime'])){
$v['range'] = $v['options'];
}elseif($v['private']){
$v['value'] = half_replace($v['value']);
}
$v['placeholder'] = $v['tips'];
if($v['options']) $v['options'] = parse_attr($v['options']);
}
return $this->returnMsg($rs,1);
}
$this->assign([
'addon' => $addon,
'groups' => json_encode($groups)
]);
return $this->fetch();
}
/**
* 插件配置更新
* @return json
*/
public function setup()
{
$this->only(['@token'=>'']);
$d = $this->request->post();
$group = $d['__g'] ?? '';
$addon = $d['__a'] ?? '';
if(!$addon) return $this->returnMsg("参数错误");
$where = [];
$where[] = ['state','=',1];
$where[] = ['addon','=',$addon];
if($group) $where[] = ['group','=',$group];
$rs = (new S())->listArray($where,'name,type,private');
if($rs){
unset($d['__g'],$d['__a']);
foreach ($rs as $v){
$name = $v['name'];
if(in_array($name, ['sys_group','sys_type'])) continue; // 系统关键配置项不可修改 开发时请注释该行
if($v['type'] == 'checkbox'){
$data['value'] = isset($d[$name]) && is_array($d[$name]) ? implode(',', $d[$name]) : '';
}elseif($v['type'] == 'image'){
$data['value'] = $d[$name] ?? '';
}elseif($v['type'] == 'images'){
$data['value'] = isset($d[$name]) && is_array($d[$name]) ? json_encode($d[$name]) : '';
}else{
$data['value'] = $d[$name] ?? 0;
if($v['private'] && strpos($data['value'], '***') !== false) continue; // 隐私项含星号不可更新
}
S::where("name='$name'")->update($data);
}
S::cache(1);
return $this->returnMsg("设置成功", 1);
}else{
return $this->returnMsg('参数错误或未找到相关记录');
}
}
}
\ No newline at end of file
<?php
/**
* ===========================================================================
* Veitool 快捷开发框架系统
* Author: Niaho 26843818@qq.com
* Copyright (c)2019-2025 www.veitool.com All rights reserved.
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace app\admin\controller;
use app\BaseController;
use app\model\system\SystemRoles as Roles;
use app\model\system\SystemManager as Manager;
/**
*【后台控制器抽象基类】
*/
abstract class AdminBase extends BaseController
{
/**
* 后台管理员信息
* @var array
*/
protected $manUser = [];
/**
* 映射路径
* @var string
*/
protected $appMap = '';
/**
* 当前路由uri
* @var string
*/
protected $routeUri = '';
/**
* Token 名
* @var string
*/
protected $tokenName = '__admin__';
/**
* 覆盖无需业务
*/
protected function __home(){}
/**
* 后台控制器验证初始化
*/
protected final function __auth()
{
//映射路径
$this->appMap = VT_DIR . '/' . (array_search("admin", config('app.app_map')) ?: 'admin');
//验证登录
$this->isLogin();
//载入权限菜单
$this->loadMenusRoles();
//构组路由: 控制器 + 方法 + (参数action的传值)
$this->routeUri = strtolower($this->request->ADDON_APP.$this->request->controller()."/".$this->request->action().(($action = $this->request->get('action')) ? '/'.$action : ''));
//验证权限
$this->isPower();
}
/**
* 登录判断
*/
private function isLogin()
{
if(is_null($this->manUser = session(VT_MANAGER))){
$url = $this->appMap.'/login/index';
if($this->request->isAjax()){
$this->exitMsg('您还未登录或已过期,请先登录!',401,['url'=>$url]);
}else{
$this->redirect($url);
}
}
}
/**
* 载入管理员角色权限菜单
*/
private function loadMenusRoles()
{
$us = Manager::one("username = '{$this->manUser['username']}' AND state > 0");
if($us && $this->manUser['password'] == $us['password'] && $this->manUser['passsalt'] == $us['passsalt']){
//禁止同帐号同时异地登录处理
if(in_array(vconfig('ip_login',0),[2,3]) && $us['loginip'] != $this->request->ip()){
session(null);
$url = $this->appMap.'/login/index';
$this->exitMsg('您的帐号已在其他终端登录!',$this->request->isAjax() ? 401 : 303,['url'=>$url]);
}
$us = $us->toArray();
$us['role_menuid'] = '';
$us['role_name'] = '超级管理员';
$us['uid'] = $this->manUser['uid'];
//非超级管理员载入角色权限['roleid'=>角色ID,'role_name'=>+角色名,'role_menuid'=>+拥有的菜单ID串'actions'=>+权限记录集]
$this->manUser = $us['userid']>1 ? array_merge($us, Roles::cache($us['roleid'])) : $us;
}else{
session(null);
$url = $this->appMap.'/login/index';
$this->exitMsg('您还未登录或已过期,请先登录!',$this->request->isAjax() ? 401 : 303,['url'=>$url]);
}
}
/**
* 权限判断
*/
private function isPower()
{
if($this->manUser['userid']>1 && !in_array($this->routeUri,$this->manUser['actions'])){
$this->exitMsg('抱歉,您没有该项权限请联系管理员!',$this->request->isAjax() ? 401 : 400);
}
}
/**
* 日志/在线处理
* @access protected
* @param sting $tip 提示
*/
protected function logon(string $tip = '')
{
//操作日志
if(vconfig('admin_log',0)){
\app\model\system\SystemManagerLog::add(['url'=>$this->routeUri.($tip ? ' '.$tip : ''),'username'=>$this->manUser['username'],'ip'=>$this->request->ip()]);
}
//在线统计 【online_on = 0:关闭全部 1:开启后台 2:开启会员 3:开启全部】
if(in_array(vconfig('online_on',0),[1,3])){
\app\model\system\SystemOnline::recod($this->manUser, $this->routeUri, 0);
}
}
/**
* 获取权限扩展标识【不存在默认返回为:0】用于控制器内调用
* 优先级:addon/* > addon/controller/* > addon/controller/action
* @access protected
* @return string|int
*/
protected function getRoleExt()
{
if($this->manUser['userid'] == 1) return 0;
$d = explode('/', $this->routeUri);
if(isset($this->manUser['role_ext'][$d[0].'/*'])){
return $this->manUser['role_ext'][$d[0].'/*'];
}elseif(isset($d[1]) && isset($this->manUser['role_ext'][$d[0].'/'.$d[1].'/*'])){
return $this->manUser['role_ext'][$d[0].'/'.$d[1].'/*'];
}elseif(isset($d[1]) && isset($d[2]) && isset($this->manUser['role_ext'][$d[0].'/'.$d[1].'/'.$d[2].'/*'])){
return $this->manUser['role_ext'][$d[0].'/'.$d[1].'/'.$d[2].'/*'];
}else{
return $this->manUser['role_ext'][$this->routeUri] ?? 0;
}
}
}
\ No newline at end of file
<?php
/**
* ===========================================================================
* Veitool 快捷开发框架系统
* Author: Niaho 26843818@qq.com
* Copyright (c)2019-2025 www.veitool.com All rights reserved.
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace app\admin\controller;
use app\model\system\SystemDict as Dict;
use app\model\system\SystemMenus as Menus;
use app\model\system\SystemCategory as Category;
/**
* 后台主控制器
*/
class Index extends AdminBase
{
/**
* 后台首页
* @return mixed
*/
public function index()
{
$this->assign([
"appMap" => $this->appMap,
"tokenName" => $this->tokenName
]);
return $this->fetch('','',false);
}
/**
* 后台主面板
* @return mixed
*/
public function main()
{
if($this->request->isPost()){
return $this->returnMsg('登录成功!',1);
}
$data['type'] = 'imagewt';
$data['name'] = 'headimgwt';
$this->assign('data',$data);
$data2['type'] = 'imagewt';
$data2['name'] = 'headimgwt2';
$data2['value'] = '';
$this->assign('data2',$data2);
$data3['type'] = 'imageswt';
$data3['name'] = 'headimgwts2';
$data3['value'] = '';
$this->assign('data3',$data3);
$data4['type'] = 'upfilewt';
$data4['name'] = 'filename';
$data4['value'] = '';
$this->assign('data4',$data4);
return $this->fetch();
}
/**
* 获取左侧菜单和用户信息
* @param int $do 是否更新字典缓存0否1是
* @return json
*/
public function json(int $do = 0)
{
$arr = [];
$cat = Category::catList([['state','=',1],['type','=','01']],0,'title,icon,catid'); // 获取菜单分类
$data = Menus::getMenus(array_intersect_key($this->manUser, ['userid'=>"",'role_menuid'=>""])); // 获取拥有的菜单数据
$rs =[
'menus' => $cat ? ['cat'=>$cat,'menus'=>$data['menus']]: $data['menus'],
'user' => $this->manUser + ['roles' => $data['roles']] + ['rolem' => \app\model\system\SystemRoles::where("state = 1 AND roleid IN(".$this->manUser['roleids'].")")->column("roleid id,role_name name")] + ['dict' => Dict::cache((int)$do)]
];
unset($rs['user']['password'],$rs['user']['passsalt']);
return json($rs);
}
/**
* 清空缓存
* @return json
*/
public function clear(){
\think\facade\Cache::clear();
return $this->returnMsg("清理缓存成功!");
}
/**
* 查询IP所在地区
* @return mixed
*/
public function ip()
{
$url = 'https://whois.pconline.com.cn/ipJson.jsp?callback='.input('callback').'&ip='.input('ip');
$cont = trim(file_get_contents($url));
$cont = iconv("gb2312","utf-8//IGNORE",$cont);
return $cont;
}
}
\ No newline at end of file
<?php
/**
* ===========================================================================
* Veitool 快捷开发框架系统
* Author: Niaho 26843818@qq.com
* Copyright (c)2019-2025 www.veitool.com All rights reserved.
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace app\admin\controller;
use app\BaseController;
use app\model\system\SystemManager as Manager;
use app\model\system\SystemLoginLog as LoginLog;
use app\model\system\SystemOnline as Online;
use tool\Lock;
/**
* 后台登录
*/
class Login extends BaseController
{
/**
* 映射路径
* @var string
*/
protected $appMap = '';
/**
* 覆盖无需业务 & 初始映射路径
*/
protected function __home(){
$this->appMap = VT_DIR . '/' . (array_search("admin", config('app.app_map')) ?: 'admin');
}
/**
* 登录首页
*/
public function index()
{
if(!empty(session(VT_MANAGER))) return $this->redirect($this->appMap);
$this->assign([
"appMap" => $this->appMap
]);
return $this->fetch();
}
/**
* 退出系统
*/
public function logout()
{
if($User = session(VT_MANAGER)) Online::del(['uid'=>$User['uid'],'userid'=>$User['userid']]); //删除在线数据
session(null);
return $this->redirect($this->appMap);
}
/**
* 解锁屏处理
* @return json
*/
public function unlock()
{
if(is_null($us=session(VT_MANAGER))) return $this->returnMsg('还未登录');
$password = $this->request->post('password','');
if($us['password'] === set_password($password,$us['passsalt'])){
return $this->returnMsg('success',1);
}else{
return $this->returnMsg('解锁密码错误');
}
}
/**
* 登录验证
* @return json
*/
public function check()
{
//多次尝试验证
$ip = $this->request->ip();
if(Lock::check(['key'=>'LOGIN_'.$ip])) return $this->returnMsg(Lock::msg());
$d = $this->only(['username/*/u/管理帐号','password/*/p/登录密码','captcha']);
if(vconfig('admin_captcha',1) && !captcha_check($d['captcha'])) return $this->returnMsg('验证码错误!');
$username = $d['username'];
$password = $d['password'];
//查询用户数据
$rs = Manager::one(compact('username'));
if(empty($rs)){
LoginLog::add($username, $password, '', '账号错误');
Lock::add();
return $this->returnMsg('帐号或密码错误!');
}
if($rs->state == 0) return $this->returnMsg('帐号已被停用!');
if($rs['password'] === set_password($password,$rs['passsalt'])){
$rs->logintime = time();
$rs->loginip = $ip;
$rs->logins ++;
$rs->save();
$rs = $rs->toArray();
$rs['uid'] = 'AM-'.uniqid(); //设置编号
LoginLog::add($username, $password, $rs['passsalt']);
session(VT_MANAGER,$rs);
Lock::del();
return $this->returnMsg('登录成功!',1,['url'=>($this->appMap ?: '/')]);
}
LoginLog::add($username, $password, $rs['passsalt'], '密码错误');
Lock::add();
return $this->returnMsg('帐号或密码错误!');
}
}
\ No newline at end of file
<?php
/**
* ===========================================================================
* Veitool 快捷开发框架系统
* Author: Niaho 26843818@qq.com
* Copyright (c)2019-2025 www.veitool.com All rights reserved.
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace app\admin\controller\system;
use app\admin\controller\AdminBase;
use app\model\system\SystemArea as A;
/**
* 后台地区控制器
*/
class Area extends AdminBase
{
/**
* 地区列表
* @param string $pid 上级ID
* @return mixed
*/
public function index(?string $pid = null)
{
$rs = A::all("parentid=".(int)$pid, '*', ['listorder'=>'asc']);
if(is_null($pid)){
$this->assign('list', json_encode($rs));
return $this->fetch();
}else{
if(isset($rs[0])){
$r = A::where('areaid','in',$rs[0]['arrparentid'])->column('areaid,areaname');
$rs[0]['arrparentid'] = '0|顶级';
foreach ($r as $v){
$rs[0]['arrparentid'] .= ','.$v['areaid'].'|'.$v['areaname'];
}
}
A::where('areaid',$pid)->update(['childs'=>count($rs->toArray())]);
return $this->returnMsg($rs);
}
}
/**
* 地区添加
* @return json
*/
public function add()
{
$d = $this->only(['@token'=>'','parentid/d','listorder/d','areaname/*/{2,30}/地区名称']);
$parentid = $d['parentid'];
$listorder = $d['listorder'];
$arrparentid = 0;
if($parentid>0){
$rs = A::one(['areaid'=>$parentid]);
if(is_null($rs)) return $this->returnMsg("上级地区ID不存在");
$arrparentid = $rs['arrparentid'] ? $rs['arrparentid'].','.$rs['areaid'] : $rs['areaid'];
}
$data = [];
$area = explode("\n",$d['areaname']);
foreach($area as $v){
$v = strip_html($v);
if(!$v) continue;
$data[] = ['areaname'=>$v,'parentid'=>$parentid,'listorder'=>$listorder,'arrparentid'=>$arrparentid];
$listorder ++;
}
if(A::insertAll($data)){
A::cache(1);
return $this->returnMsg("添加地区成功", 1);
}else{
return $this->returnMsg('添加地区失败');
}
}
/**
* 地区编辑
* @return json
*/
public function edit()
{
$d = $this->only(['@token'=>'','areaid/d/参数错误','av','af']);
$value = $d['av'];
$field = $d['af'];
if(!in_array($field,['areaname','listorder'])) return $this->returnMsg("参数错误2");
if($field=='areaname'){
$this->only(['av/*/{2,30}/地区名称']);
}else{
$value = intval($value);
}
if(A::update([$field=>$value,'areaid'=>$d['areaid']])){
A::cache(1);
return $this->returnMsg("设置成功", 1);
}else{
return $this->returnMsg("设置失败");
}
}
/**
* 数据导入
* @return json
*/
public function import()
{
if(A::count() > 0){
return $this->returnMsg("地区表非空,不可导入");
}else{
@set_time_limit(0);
$file = VT_PUBLIC . 'install/data/area_data.sql';
$prefix = config('database.connections.'.config('database.default').'.prefix');
if(is_file($file)){
$sql = explode("\n", trim(str_replace(["\r\n", "\r", "vt_"], ["\n", "\n", $prefix], file_get_contents($file))));
foreach($sql as $v){
\think\facade\Db::execute($v);
}
A::cache(1);
return $this->returnMsg("导入成功",1);
}else{
return $this->returnMsg("安装目录下无 data/area_data.sql 内置数据文件");
}
}
}
/**
* 地区删除
* @return json
*/
public function del()
{
$areaid = $this->only(['@token'=>'','areaid'])['areaid'];
$areaid = is_array($areaid) ? implode(',',$areaid) : $areaid;
$rs = A::one("parentid IN ($areaid)");
if($rs) return $this->returnMsg("该地区存在子地区不能删除!");
if(A::del("areaid IN ($areaid)")){
A::cache(1);
return $this->returnMsg("删除成功", 1);
}else{
return $this->returnMsg("删除失败");
}
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
<?php
/**
* ===========================================================================
* Veitool 快捷开发框架系统
* Author: Niaho 26843818@qq.com
* Copyright (c)2019-2025 www.veitool.com All rights reserved.
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace app\admin\controller\system;
use app\admin\controller\AdminBase;
use app\model\system\SystemUploadFile as UploadFile;
use app\model\system\SystemUploadGroup as UploadGroup;
/**
* 文件管理控制器
*/
class Filemanage extends AdminBase
{
/**
* 文件列表
* @param string $do 异步数据
* @return mixed
*/
public function index(string $do = '')
{
if($do=='json'){
$d = $this->only(['kw','fields','sotime','groupid','isdel','limit'=>'10/d'],'get');
$kw = $d['kw'];
$fds = ['filename','username'];
$field = isset($fds[$d['fields']]) ? $d['fields'] : -1;
$sotime = $d['sotime'];
$groupid = $d['groupid'];
$isdel = $d['isdel'];
$limit = $d['limit'];
$where = [];
if($kw!=''){
if($field>-1){
$where[] = $field>0 ? [$fds[$field],'=',$kw] : [$fds[$field],'LIKE', '%'.$kw.'%'];
}else{
$where[] = [implode('|',$fds),'LIKE', '%'.$kw.'%'];
}
}
if(strpos($sotime,' - ')!==false){
$t = explode(' - ',$sotime);
$where[] = ['u.addtime','>=',strtotime($t[0]." 00:00:00")];
$where[] = ['u.addtime','<=',strtotime($t[1]." 23:59:59")];
}
if(is_numeric($groupid)) $where[] = ['u.groupid','=',$groupid];
if(is_numeric($isdel)) $where[] = ['u.isdel','=',$isdel];
return $this->returnMsg(UploadFile::alias('u')->leftJoin('system_upload_group g','u.groupid=g.groupid')->where($where)->order(['fileid'=>'desc'])->field('u.*,g.groupname')->paginate($limit));
}
$this->assign([
'limit' => 10,
'group' => json_encode(UploadGroup::where("isdel = 0")->column('groupname','groupid'))
]);
return $this->fetch();
}
/**
* 编辑文件
* @return json
*/
public function edit()
{
$d = $this->only(['@token'=>'','fileid/d/参数错误','av','af']);
$fileid = $d['fileid'];
$Myobj = UploadFile::one("fileid = $fileid");
if(!$Myobj) return $this->returnMsg("数据不存在");
$value = $d['av'];
$field = $d['af'];
if(!in_array($field,['filename'])) return $this->returnMsg("参数错误");
if($field=='filename'){
$this->only(['av/*/{2,100}/文件标题/0/.']);
}
$rs = $Myobj->save([$field=>$value]);
return $this->returnMsg($rs ? "设置成功" : '设置失败', 1);
}
/**
* 删除文件
* @return json
*/
public function del()
{
$fileid = $this->only(['@token'=>'','fileid'])['fileid'];
$fileid = is_array($fileid) ? implode(',',$fileid) : $fileid;
if(!$fileid) return $this->returnMsg('参数错误');
$rs = UploadFile::where("fileid IN ($fileid)")->update(['isdel'=>1]);
if($rs){
return $this->returnMsg("删除成功1!", 1);
}else{
return $this->returnMsg("删除失败!");
}
}
/**
* 恢复文件
* @return json
*/
public function reset()
{
$fileid = $this->only(['@token'=>'','fileid'])['fileid'];
$fileid = is_array($fileid) ? implode(',',$fileid) : intval($fileid);
if(!$fileid) return $this->returnMsg('参数错误');
$rs = UploadFile::where("fileid IN ($fileid)")->update(['isdel'=>0]);
if($rs){
return $this->returnMsg("恢复成功!", 1);
}else{
return $this->returnMsg("恢复失败!");
}
}
/**
* 清理文件
* @return json
*/
public function clear()
{
$this->only(['@token'=>'']);
$rs = (new UploadFile())->listQuery('isdel=1')->toArray();
if($rs['data']){
$fileid = [];
$path = ROOT_PATH . 'public';
foreach ($rs['data'] as $v){
if($v['storage']=='local'){
$file = $path.$v['fileurl'];
if(is_file($file)){
if(@unlink($file)){
$fileid[] = $v['fileid'];
}
}else{
$fileid[] = $v['fileid'];
}
}else{
$fileid[] = $v['fileid'];
}
}
if($fileid){
UploadFile::del("fileid IN (". implode(',', $fileid) .")");
}
return $this->returnMsg("文件清理完毕!",1);
}else{
return $this->returnMsg("没有满足条件的文件可清理!");
}
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<?php
use app\ExceptionHandle;
use app\Request;
// 容器Provider定义文件
return [
'think\Request' => Request::class,
'think\exception\Handle' => ExceptionHandle::class,
];
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment