update niucloud

This commit is contained in:
全栈小学生 2023-09-15 18:47:16 +08:00
parent 55261a17eb
commit 1580d8607a
99 changed files with 2167 additions and 650 deletions

View File

@ -5,5 +5,5 @@
"version": "1.0.1",
"author": "niucloud",
"type": "addon",
"support_app": "niucloud"
"support_app": ""
}

View File

@ -15,6 +15,7 @@ use app\dict\addon\AddonDict;
use app\service\admin\addon\AddonService;
use app\service\core\addon\CoreAddonService;
use core\base\BaseAdminController;
use think\facade\Cache;
use think\Response;
@ -34,17 +35,34 @@ class Addon extends BaseAdminController
*/
public function install($addon)
{
return (new AddonService())->install($addon);
return success((new AddonService())->install($addon));
}
/**
* 执行安装
* 云安装插件
* @param $addon
* @return Response
*/
public function execute($addon)
public function cloudInstall($addon)
{
return (new AddonService())->executeInstall($addon);
return success(data:(new AddonService())->cloudInstall($addon));
}
/**
* 获取安装任务
* @return Response
*/
public function getInstallTask() {
return success(data:(new AddonService())->getInstallTask());
}
/**
* 获取云安装日志
* @param $addon
* @return mixed
*/
public function cloudInstallLog($addon) {
return success(data:(new AddonService())->cloudInstallLog($addon));
}
/**
@ -57,17 +75,6 @@ class Addon extends BaseAdminController
return (new AddonService())->installCheck($addon);
}
/**
* 查询插件安装状态
* @param $addon
* @param $key
* @return Response
*/
public function getInstallState($addon, $key)
{
return success((new AddonService())->getInstallState($addon, $key));
}
/**
* 卸载插件
* @param string $addon
@ -118,7 +125,10 @@ class Addon extends BaseAdminController
* @return Response
*/
public function download($addon){
(new AddonService())->download($addon);
$data = $this->request->params([
['version', '']
]);
(new AddonService())->download($addon, $data['version']);
return success('DOWNLOAD_SUCCESS');
}

View File

@ -0,0 +1,121 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\adminapi\controller\dict;
use core\base\BaseAdminController;
use app\service\admin\dict\DictService;
/**
* 数据字典控制器
* Class Dict
* @package app\adminapi\controller\dict
*/
class Dict extends BaseAdminController
{
/**
* 获取数据字典列表
* @return \think\Response
*/
public function lists(){
$data = $this->request->params([
["name",""],
["key",""]
]);
return success((new DictService())->getPage($data));
}
/**
* 数据字典详情
* @param int $id
* @return \think\Response
*/
public function info(int $id){
return success((new DictService())->getInfo($id));
}
/**
* 添加数据字典
* @return \think\Response
*/
public function add(){
$data = $this->request->params([
["name",""],
["key",""],
["memo",""],
]);
// $this->validate($data, 'app\validate\dict\Dict.add');
$id = (new DictService())->add($data);
return success('ADD_SUCCESS', ['id' => $id]);
}
/**
* 数据字典编辑
* @param $id 数据字典id
* @return \think\Response
*/
public function edit($id){
$data = $this->request->params([
["name",""],
["key",""],
["data",""],
["memo",""],
]);
// $this->validate($data, 'app\validate\dict\Dict.edit');
(new DictService())->edit($id, $data);
return success('EDIT_SUCCESS');
}
/**
* 数据字典删除
* @param $id 数据字典id
* @return \think\Response
*/
public function del(int $id){
(new DictService())->del($id);
return success('DELETE_SUCCESS');
}
/**
* 添加数据字典内容
*/
public function addDictData($id)
{
$data = $this->request->params([
["dictionary",'[]'],
]);
// $this->validate($data, 'app\validate\dict\Dict.add');
$data['dictionary'] = json_encode($data['dictionary'], true);
(new DictService())->edit($id,$data);
return success('ADD_SUCCESS');
}
/**
* 获取全部数据字典
* @return \think\Response
*/
public function getAll(){
return success((new DictService())->getAll());
}
/**
* 数据字典详情
* @param key 数据字典关键字
* @return \think\Response
*/
public function getKeyInfo(string $type){
$res = (new DictService())->getKeyInfo($type);
return success($res);
}
}

View File

@ -36,6 +36,7 @@ class Generator extends BaseController
$data = $this->request->params([
['table_name', ''],
['table_content', ''],
['addon_name','']
]);
return success((new GenerateService())->getPage($data));
}
@ -61,6 +62,7 @@ class Generator extends BaseController
public function preview(int $id)
{
$data = (new GenerateService())->preview(['id' => $id]);
// dd($data);
return success('ADD_SUCCESS', $data);
}
@ -101,6 +103,7 @@ class Generator extends BaseController
['parent_menu',''],
['relations',[]]
], false);
$this->validate($data, 'app\validate\generator\Generator.edit');
(new GenerateService())->edit($id, $data);
return success('MODIFY_SUCCESS');
@ -125,7 +128,7 @@ class Generator extends BaseController
{
$data = $this->request->params([
['id', ''],
['generate_type', '3']
['generate_type', '2']
]);
$data = (new GenerateService())->generate($data);

View File

@ -56,13 +56,10 @@ class Menu extends BaseAdminController
['api_url', ''],
['view_path', ''],
['router_path', ''],
['methods', ''],
['sort', 0],
['status', MenuDict::ON],
['is_show', 0],
['addon', ''],
]);
$this->validate($data, 'app\validate\sys\Menu.add');
@ -94,6 +91,7 @@ class Menu extends BaseAdminController
['addon', ''],
]);
$this->validate($data, 'app\validate\sys\Menu.edit');
(new MenuService())->edit($menu_key, $data);
return success('EDIT_SUCCESS');
}

View File

@ -30,12 +30,14 @@ Route::group(function () {
Route::put('addon/status/:id/:status', 'addon.Addon/setStatus');
//安装插件
Route::post('addon/install/:addon', 'addon.Addon/install');
//云安装插件
Route::post('addon/cloudinstall/:addon', 'addon.Addon/cloudInstall');
// 云编译进度
Route::get('addon/cloudinstall/:addon', 'addon.Addon/cloudInstallLog');
//插件安装检测安装环境
Route::get('addon/install/check/:addon', 'addon.Addon/installCheck');
// 执行安装
Route::post('addon/install/execute/:addon', 'addon.Addon/execute');
//插件安装状态
Route::get('addon/install/:addon/status/:key', 'addon.Addon/getInstallState');
// 获取安装任务
Route::get('addon/installtask', 'addon.Addon/getInstallTask');
//下载插件
Route::post('addon/download/:addon', 'addon.Addon/download');
//插件类型
@ -58,8 +60,6 @@ Route::group(function () {
//编辑插件
Route::put('addon_develop/:key', 'addon.AddonDevelop/edit');
//删除插件
Route::delete('addon_develop/:key', 'addon.AddonDevelop/del');
Route::delete('addon_develop/:key', 'addon.AddonDevelop/del');
//校验是否存在
Route::get('addon_develop/check/:key', 'addon.AddonDevelop/checkKey');

View File

@ -0,0 +1,43 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
use think\facade\Route;
use app\adminapi\middleware\AdminCheckRole;
use app\adminapi\middleware\AdminCheckToken;
use app\adminapi\middleware\AdminLog;
// USER_CODE_BEGIN -- sys_dict
Route::group('dict', function () {
//数据字典列表
Route::get('dict', 'dict.Dict/lists');
//数据字典详情
Route::get('dict/:id', 'dict.Dict/info');
//添加数据字典
Route::post('dict', 'dict.Dict/add');
//编辑数据字典
Route::put('dict/:id', 'dict.Dict/edit');
//删除数据字典
Route::delete('dict/:id', 'dict.Dict/del');
//编辑数据字典
Route::put('dictionary/:id', 'dict.Dict/addDictData');
//全部数据字典
Route::get('all', 'dict.Dict/getAll');
//数据字典关键词
Route::get('dictionary/type/:type', 'dict.Dict/getKeyInfo');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,
AdminLog::class
]);
// USER_CODE_END -- sys_dict

View File

@ -50,9 +50,9 @@ function fail($msg = 'FAIL', ?array $data = [], int $code = 0, int $http_code =
* @param string $str
* @return lang()
*/
function get_lang($str)
function get_lang($str,$vars = [])
{
return Lang::get($str);
return Lang::get($str,$vars);
}
@ -174,8 +174,9 @@ function del_target_dir($path, $delDir)
}
closedir($handle);
if ($delDir) {
return rmdir($path);
@rmdir($path);
}
return true;
} else {
if (file_exists($path)) {
return unlink($path);

View File

@ -25,7 +25,7 @@ class LinkDict
$system_links = [
'SYSTEM_LINK' => [
'key' => '',
'addon_title' => '',
'addon_title' => get_lang('dict_diy.system_title'),
'title' => get_lang('dict_diy.system_link'),
'child_list' => [
[
@ -39,7 +39,7 @@ class LinkDict
],
'MEMBER_LINK' => [
'key' => '',
'addon_title' => '',
'addon_title' => get_lang('dict_diy.system_title'),
'title' => get_lang('dict_diy.member_link'),
'child_list' => [
[

View File

@ -82,14 +82,7 @@ class PagesDict
"componentName" => "AddonList",
"componentTitle" => "应用",
"ignore" => [],
"list" => [
[
"key" => "",
"title" => "",
"url" => "",
"icon" => "",
]
],
"list" => [],
"textColor" => "#303133",
"pageBgColor" => "",
"componentBgColor" => "",

View File

@ -2,17 +2,18 @@
return
[
[
'menu_name' => '首页',
'menu_name' => '应用中心',
'menu_key' => 'overview',
'menu_type' => 0,
'icon' => 'iconfont-icona-shouyediannao',
'api_url' => '',
'router_path' => 'index',
'router_path' => 'apply',
'view_path' => '',
'methods' => '',
'sort' => 100,
'sort' => 60,
'status' => 1,
'is_show' => 1,
'menu_attr' => 'system',
'children' => [
[
'menu_name' => '应用管理',
@ -29,7 +30,7 @@ return
],
[
'menu_name' => '我的星标',
'menu_key' => 'app_index',
'menu_key' => 'app_star',
'menu_type' => 1,
'icon' => 'iconfont-iconwodexingbiao',
'api_url' => '',
@ -38,11 +39,11 @@ return
'methods' => '',
'sort' => 100,
'status' => 1,
'is_show' => 1,
'is_show' => 0,
],
[
'menu_name' => '历史查看',
'menu_key' => 'app_index',
'menu_key' => 'app_record',
'menu_type' => 1,
'icon' => 'iconfont-iconchakanlishi',
'api_url' => '',
@ -51,13 +52,13 @@ return
'methods' => '',
'sort' => 100,
'status' => 1,
'is_show' => 1,
'is_show' => 0,
]
]
],
[
'menu_name' => '网站',
'menu_name' => '网站装修',
'menu_key' => 'website',
'menu_type' => 0,
'icon' => 'iconfont-iconwangzhan1',
@ -68,6 +69,7 @@ return
'sort' => 90,
'status' => 1,
'is_show' => 1,
'menu_attr' => 'common',
'children' => [
[
'menu_name' => '装修管理',
@ -390,7 +392,7 @@ return
]
],
[
'menu_name' => '会员',
'menu_name' => '会员管理',
'menu_key' => 'member',
'menu_type' => 0,
'icon' => 'iconfont-iconhuiyuan2',
@ -401,6 +403,7 @@ return
'sort' => 70,
'status' => 1,
'is_show' => 1,
'menu_attr' => 'system',
'children' => [
[
'menu_name' => '会员列表',
@ -623,7 +626,7 @@ return
],
],
[
'menu_name' => '设置',
'menu_name' => '系统设置',
'menu_key' => 'setting',
'menu_type' => 0,
'icon' => 'iconfont-iconshezhi1',
@ -634,6 +637,7 @@ return
'sort' => 40,
'status' => 1,
'is_show' => 1,
'menu_attr' => 'common',
'children' => [
[
'menu_name' => '基础设置',
@ -1210,7 +1214,7 @@ return
]
],
[
'menu_name' => '市场',
'menu_name' => '应用市场',
'menu_key' => 'app',
'menu_type' => 0,
'icon' => 'iconfont-iconyunshichang',
@ -1221,6 +1225,7 @@ return
'sort' => 10,
'status' => 1,
'is_show' => 1,
'menu_attr' => 'common',
'children' => [
[
'menu_name' => '应用插件',
@ -1275,6 +1280,7 @@ return
'sort' => 10,
'status' => 1,
'is_show' => 1,
'menu_attr' => 'common',
'children' => [
[
'menu_name' => '插件开发',

View File

@ -96,7 +96,7 @@ CREATE TABLE `generate_column` (
`query_type` varchar(100) DEFAULT '=' COMMENT '查询类型',
`view_type` varchar(100) DEFAULT 'input' COMMENT '显示类型',
`dict_type` varchar(255) DEFAULT '' COMMENT '字典类型',
`validate_type` VARCHAR(255) DEFAULT '' COMMENT '验证类型',
`validate_type` varchar(255) DEFAULT '' COMMENT '验证类型',
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间',
PRIMARY KEY (`id`)
@ -115,8 +115,8 @@ CREATE TABLE `generate_table` (
`edit_type` int(11) NOT NULL DEFAULT '1' COMMENT '编辑方式 1-弹框 2-新页面',
`order_type` int NOT NULL DEFAULT 0 COMMENT '排序方式 0-无排序 1-正序 2-倒序',
`parent_menu` varchar(255) NOT NULL DEFAULT '' COMMENT '上级菜单',
`relations` text NOT NULL COMMENT '关联配置',
`synchronous_number` INT(11) NOT NULL DEFAULT 0 COMMENT '同步次数',
`relations` text DEFAULT NULL COMMENT '关联配置',
`synchronous_number` int NOT NULL DEFAULT 0 COMMENT '同步次数',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='代码生成表';
@ -4160,6 +4160,7 @@ CREATE TABLE `sys_config` (
KEY `config_key` (`config_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统配置表';
DROP TABLE IF EXISTS `sys_dict`;
CREATE TABLE `sys_dict` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
@ -4172,6 +4173,7 @@ CREATE TABLE `sys_dict` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据字典表';
DROP TABLE IF EXISTS `sys_menu`;
CREATE TABLE `sys_menu` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '菜单ID',

View File

@ -38,12 +38,6 @@
</div>
<a href="javascript:void(0)" class="other-links-text" >网站后台</a>
</li>
<li class="other-links-item" onclick="window.open('{$root_url}/site/login')">
<div class="other-links-pic">
<img src="INSTALL_IMG/site_web.png" alt="">
</div>
<a href="javascript:void(0)" class="other-links-text" >站点后台</a>
</li>
<li class="other-links-item" onclick="window.open('{$root_url}/web/100000/')">
<div class="other-links-pic">
<img src="INSTALL_IMG/site_web.png" alt="">

View File

@ -38,6 +38,7 @@ return [
'ADDON_INSTALL_NOT_EXIST' => '未找到插件安装任务',
'ADDON_INSTALL_EXECUTED' => '插件安装任务已执行',
'INSTALL_CHECK_NOT_PASS' => '安装校验未通过',
'ADDON_INSTALLING' => '插件正在安装中',
'SITE_INDEX_VIEW_PATH_NOT_EXIST' => '当前首页路径不存在',
'ADMIN_INDEX_VIEW_PATH_NOT_EXIST' => '当前首页路径不存在',
'ADDON_SQL_FAIL' => '插件sql执行失败',
@ -45,6 +46,7 @@ return [
'LAYOUT_NOT_EXIST' => '该布局不存在',
'ZIP_FILE_NOT_FOUND' => '找不到可用的压缩文件',
'DOWNLOAD_SUCCESS' => '下载成功',
'ADDON_INFO_FILE_NOT_EXIST' => '未找到插件info.json配置文件',
//登录注册重置账号....
'LOGIN_SUCCESS' => '登录成功',

View File

@ -201,6 +201,7 @@ return [
'page_diy' => '自定义页面',
'component_type_basic' => '基础组件',
'system_title' => '系统',
'system_link' => '系统页面',
'system_link_index' => '首页',

View File

@ -10,6 +10,17 @@
// +----------------------------------------------------------------------
return [
//公共
'common_validate' => [
'require' => '%s必须填写',
'number' => '%s必须是正整数',
'mobile' => '%s手机号格式错误',
'id_card' => '%s身份证号格式错误',
'email' => '%s邮箱格式错误',
'max' => '%s最大值不能超过%d',
'min' => '%s最小值不能超过%d',
'between' => '%s必须是%d到%d之间'
],
//菜单
'validate_menu' => [
'menu_name_require' => '菜单名称必须填写',

View File

@ -0,0 +1,77 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\model\dict;
use core\base\BaseModel;
use think\model\concern\SoftDelete;
use think\model\relation\HasMany;
use think\model\relation\HasOne;
/**
* 数据字典模型
* Class Dict
* @package app\model\dict
*/
class Dict extends BaseModel
{
/**
* 数据表主键
* @var string
*/
protected $pk = 'id';
/**
* 模型名称
* @var string
*/
protected $name = 'sys_dict';
protected $type = [
'dictionary' => 'json'
];
// 设置json类型字段
protected $json = ['dictionary'];
// 设置JSON数据返回数组
protected $jsonAssoc = true;
/**
* 搜索器:数据字典字典名称
* @param $value
* @param $data
*/
public function searchNameAttr($query, $value, $data)
{
if ($value) {
$query->where("name", $value);
}
}
/**
* 搜索器:数据字典字典关键词
* @param $value
* @param $data
*/
public function searchKeyAttr($query, $value, $data)
{
if ($value) {
$query->where("key", $value);
}
}
}

View File

@ -11,6 +11,7 @@
namespace app\model\generator;
use app\model\addon\Addon;
use app\model\applet\AppletVersion;
use core\base\BaseModel;
@ -62,5 +63,27 @@ class GenerateTable extends BaseModel
}
}
/**
* 插件搜索器
* @param $query
* @param $value
* @param $data
*/
public function searchAddonNameAttr($query, $value, $data)
{
if ($value) {
if($value == 2)
{
$query->where('addon_name','=','');
}else{
$query->where('addon_name', 'like', '%' . $value . '%');
}
}
}
public function addon()
{
return $this->hasOne(Addon::class, 'key', 'addon_name')->joinType('left')->withField('key, title')->bind(['title' => 'title']);
}
}

View File

@ -14,6 +14,7 @@ namespace app\service\admin\addon;
use app\dict\addon\AddonDict;
use app\model\addon\Addon;
use app\service\core\addon\CoreAddonCloudService;
use app\service\core\addon\CoreAddonDownloadService;
use app\service\core\addon\CoreAddonInstallService;
use app\service\core\addon\CoreAddonService;
@ -54,26 +55,33 @@ class AddonService extends BaseAdminService
*/
public function install(string $addon)
{
try {
$data = (new CoreAddonInstallService($addon))->install();
return success('SUCCESS', $data);
} catch ( Exception $e) {
return fail($e->getMessage());
}
return (new CoreAddonInstallService($addon))->install();
}
/**
* 执行安装
* 云安装插件
* @param string $addon
* @return Response
*/
public function executeInstall(string $addon) {
try {
$data = (new CoreAddonInstallService($addon))->executeInstall();
return success('SUCCESS', $data);
} catch ( Exception $e) {
return fail($e->getMessage());
public function cloudInstall(string $addon) {
return (new CoreAddonInstallService($addon))->install('cloud');
}
/**
* 云安装日志
* @param string $addon
* @return null
*/
public function cloudInstallLog(string $addon) {
return (new CoreAddonCloudService())->getBuildLog($addon);
}
/**
* 获取安装任务
* @return mixed
*/
public function getInstallTask() {
return (new CoreAddonInstallService(''))->getInstallTask();
}
/**
@ -86,17 +94,6 @@ class AddonService extends BaseAdminService
return success('SUCCESS', $data);
}
/**
* 获取插件安装状态
* @param string $addon
* @param string $key
* @return mixed
*/
public function getInstallState(string $addon, string $key)
{
return CoreAddonInstallService::instance($addon)->getInstallState($key);
}
/**
* 卸载插件
* @param string $addon
@ -142,8 +139,8 @@ class AddonService extends BaseAdminService
* @param string $app_key
* @return true
*/
public function download(string $app_key){
return (new CoreAddonDownloadService())->download($app_key);
public function download(string $app_key, string $version){
return (new CoreAddonDownloadService())->download($app_key, $version);
}
/**
@ -161,7 +158,7 @@ class AddonService extends BaseAdminService
* @return array
*/
public function getInstallAddonList($where){
$field = 'title, icon, key, desc, status, is_star';
$field = 'title, icon, key, desc, status, is_star, type, support_app';
return $this->model->where([['status', '=', AddonDict::ON]])->withSearch([ 'title' ], $where)->field($field)->append(['status_name'])->order('create_time desc')->select()->toArray();
}
@ -170,7 +167,7 @@ class AddonService extends BaseAdminService
* @return array
*/
public function getInstallStarAddonList($where){
$field = 'title, icon, key, desc, status, is_star';
$field = 'title, icon, key, desc, status, is_star, type, support_app';
return $this->model->where([['status', '=', AddonDict::ON],['is_star', '=', 2]])->withSearch([ 'title' ], $where)->field($field)->append(['status_name'])->order('create_time desc')->select()->toArray();
}
@ -201,7 +198,7 @@ class AddonService extends BaseAdminService
['key', 'in', $keys],
['status', '=', AddonDict::ON]
];
return $this->model->where($data)->withSearch([ 'title' ], $where)->field('title, icon, key, desc, status, cover, is_star')->select()->toArray();
return $this->model->where($data)->withSearch([ 'title' ], $where)->field('title, icon, key, desc, status, cover, is_star, type, support_app')->select()->toArray();
}
@ -232,7 +229,7 @@ class AddonService extends BaseAdminService
['status', '=', AddonDict::ON],
['is_star', '=', 2]
];
return $this->model->where($data)->withSearch([ 'title' ], $where)->field('title, icon, key, desc, status, cover')->select()->toArray();
return $this->model->where($data)->withSearch([ 'title' ], $where)->field('title, icon, key, desc, status, cover, type, support_app')->select()->toArray();
}
/**

View File

@ -0,0 +1,125 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\admin\dict;
use app\model\dict\Dict;
use core\base\BaseAdminService;
/**
* 数据字典服务层
* Class DictService
* @package app\service\admin\dict
*/
class DictService extends BaseAdminService
{
public function __construct()
{
parent::__construct();
$this->model = new Dict();
}
/**
* 获取数据字典列表
* @param array $where
* @return array
*/
public function getPage(array $where = [])
{
$field = 'id,name,key,memo,create_time,update_time';
$order = 'id desc';
$search_model = $this->model->withSearch(["name","key"], $where)->field($field)->order($order);
$list = $this->pageQuery($search_model);
return $list;
}
/**
* 获取数据字典信息
* @param int $id
* @return array
*/
public function getInfo(int $id)
{
$field = 'id,name,key,dictionary,memo,create_time,update_time';
$info = $this->model->field($field)->where([['id', '=', $id]])->findOrEmpty()->toArray();
if($info['dictionary'] == null)
{
$info['dictionary'] = [];
}
return $info;
}
/**
* 添加数据字典
* @param array $data
* @return mixed
*/
public function add(array $data)
{
$res = $this->model->create($data);
return $res->id;
}
/**
* 数据字典编辑
* @param int $id
* @param array $data
* @return bool
*/
public function edit(int $id, array $data)
{
$data['update_time'] = time();
$this->model->where([['id', '=', $id]])->update($data);
return true;
}
/**
* 删除数据字典
* @param int $id
* @return bool
*/
public function del(int $id)
{
$res = $this->model->where([['id', '=', $id]])->delete();
return $res;
}
/**
* 获取全部数据字典
* @param array $where
* @return array
*/
public function getAll()
{
$field = 'id,name,key,dictionary,memo,create_time,update_time';
$list = $this->model->field($field)->select()->toArray();
return $list;
}
public function getKeyInfo($key)
{
$field = 'id,name,key,dictionary,memo,create_time,update_time';
$info = $this->model->field($field)->where([['key', '=', $key]])->findOrEmpty()->toArray();
if($info['dictionary'] == null)
{
$info['dictionary'] = [];
}
return $info;
}
}

View File

@ -383,14 +383,19 @@ class DiyService extends BaseAdminService
/**
* 获取默认页面数据
* @param $type
* @param array $template
* @return array|mixed
*/
public function getFirstPageData($type)
public function getFirstPageData($type, $template = [])
{
$pages = PagesDict::getPages([ 'type' => $type ]);
if (!empty($pages)) {
if (empty($template)) {
$template = array_key_first($pages);
$page = array_shift($pages);
} else {
$page = $pages[ $template ];
}
$page[ 'template' ] = $template;
$page[ 'type' ] = $type;
return $page;
@ -505,6 +510,11 @@ class DiyService extends BaseAdminService
}
}
// 如果没有预览图,并且没有地址,则赋值
if (empty($use_template[ 'cover' ]) && empty($use_template[ 'url' ])) {
$use_template[ 'url' ] = '/' . $v[ 'page' ];
}
$template[ $k ][ 'use_template' ] = $use_template;
}
@ -649,6 +659,10 @@ class DiyService extends BaseAdminService
} else {
$res[ 'page' ] .= '?id=' . $info[ 'id' ];
}
} elseif ($params[ 'name' ]) {
// 表里没有数据,查询默认页面数据
$template = $this->getTemplate([ 'type' => [ $params[ 'name' ] ] ])[ $params[ 'name' ] ];
$res[ 'page' ] = $template[ 'page' ];
}
return $res;

View File

@ -192,11 +192,15 @@ class Generate
public function preview(array $table)
{
$data = [];
// $data = [];
foreach ($this->getGenerator() as $item) {
$generator = app()->make($item);
$generator->init($table);
$data[] = $generator->fileInfo();
$file_info = $generator->fileInfo();
if(!empty($file_info))
{
$data[] = $file_info;
}
}
return $data;
@ -217,8 +221,8 @@ class Generate
WebLangGenerator::class,
WebEditGenerator::class,
WebIndexGenerator::class,
// WebEditPageGenerator::class,
// WebEditLangGenerator::class
WebEditPageGenerator::class,
WebEditLangGenerator::class
];
}

View File

@ -41,9 +41,9 @@ class GenerateService extends BaseAdminService
*/
public function getPage(array $where = [])
{
$field = 'id,table_name,table_content,class_name,edit_type,create_time';
$field = 'id,table_name,table_content,class_name,edit_type,create_time,addon_name';
$order = 'create_time desc';
$search_model = (new GenerateTable())->withSearch(['table_name', 'table_content'], $where)->field($field)->order($order);
$search_model = (new GenerateTable())->withSearch(['table_name', 'table_content','addon_name'], $where)->with('addon')->field($field)->order($order);
return $this->pageQuery($search_model);
}
@ -57,11 +57,12 @@ class GenerateService extends BaseAdminService
*/
public function getInfo(int $id)
{
$field = 'id,table_name,table_content,class_name,module_name,edit_type,addon_name,order_type,parent_menu,relations';
$field = 'id,table_name,table_content,class_name,module_name,edit_type,addon_name,order_type,parent_menu,relations,synchronous_number';
$info = (new GenerateTable())->field($field)->where([['id', '=', $id]])->findOrEmpty()->toArray();
$info['table_column'] = (new GenerateColumn())->where([['table_id', '=', $id]])->select()->toArray();
$column = (new GenerateColumn())->where([['table_id', '=', $id],['is_delete','=',1]])->find();
if($info && $info['order_type'] != 0)
{
@ -88,7 +89,77 @@ class GenerateService extends BaseAdminService
{
$info['relations'] = [];
}else{
if(!empty($info['relations']))
{
$info['relations'] = json_decode($info['relations'],true);
}else{
$info['relations'] = [];
}
}
if($info && !empty($info['table_column']))
{
foreach ($info['table_column'] as &$value)
{
if($value['view_type'] === 'number')
{
if(!empty($value['validate_type']))
{
$num_validate = json_decode($value['validate_type'],true);
if($num_validate[0] == 'between')
{
$value['view_max'] = $num_validate[1][1];
$value['view_min'] = $num_validate[1][0];
} else if($num_validate[0] == 'max')
{
$value['view_max'] = $num_validate[1][0];
} else if($num_validate[0] == 'min')
{
$value['view_min'] = $num_validate[1][0];
}else{
$value['view_max'] = 100;
$value['view_min'] = 0;
}
}else{
$value['view_min'] = 0;
$value['view_max'] = 100;
}
}else{
$value['view_min'] = 0;
$value['view_max'] = 100;
}
if(!empty($value['validate_type']))
{
$validate = json_decode($value['validate_type'],true);
if($validate[0] == 'between')
{
$value['max_number'] = $validate[1][1];
$value['min_number'] = $validate[1][0];
} else if($validate[0] == 'max')
{
$value['max_number'] = $validate[1][0];
} else if($validate[0] == 'min')
{
$value['min_number'] = $validate[1][0];
}else{
$value['max_number'] = 120;
$value['min_number'] = 1;
}
$value['validate_type'] = $validate[0];
}else{
$value['max_number'] = 120;
$value['min_number'] = 1;
}
}
}
return $info;
}
@ -119,7 +190,7 @@ class GenerateService extends BaseAdminService
$add_table_data = [
'table_name' => $table_name,
'table_content' => $table_info['Comment'],
'class_name' => '',
'class_name' => $table_name,
'create_time' => time(),
'module_name' => $table_name
];
@ -218,6 +289,26 @@ class GenerateService extends BaseAdminService
}else{
$item['is_order'] = 0;
}
if(!empty($item['validate_type']) && $item['view_type'] != 'number')
{
if($item['validate_type'] == 'between')
{
$validate_type = [$item['validate_type'],[$item['min_number'],$item['max_number']]];
}else if($item['validate_type'] == 'max'){
$validate_type = [$item['validate_type'],[$item['max_number']]];
}else if($item['validate_type'] == 'min'){
$validate_type = [$item['validate_type'],[$item['min_number']]];
}else{
$validate_type = [$item['validate_type'],[]];
}
$item['validate_type'] = json_encode($validate_type,JSON_UNESCAPED_UNICODE);
}
if($item['view_type'] === 'number')
{
$validate_type = ['between',[$item['view_min'],$item['view_max']]];
$item['validate_type'] = $validate_type;
$item['validate_type'] = json_encode($validate_type,JSON_UNESCAPED_UNICODE);
}
$add_column_data[] = [
'table_id' => $id,
@ -238,6 +329,8 @@ class GenerateService extends BaseAdminService
'update_time' => time(),
'create_time' => time(),
'column_type' => $item['column_type'] ?? 'string',
'validate_type' => $item['validate_type'] ?? '',
'validate_rule' => $params['rule'] ?? []
];
}
(new GenerateColumn())->saveAll($add_column_data);
@ -309,6 +402,8 @@ class GenerateService extends BaseAdminService
$id = $params['id'];
$table_info = (new GenerateTable())->where([ ['id', '=', $id] ])->field('*')->find()->toArray();
$table_info['fields'] = (new GenerateColumn())->where([ ['table_id', '=', $id] ])->field('*')->select()->toArray();
$synchronous_number = $table_info['synchronous_number'] +1;
(new GenerateTable())->where([ ['id', '=', $id] ])->save(['synchronous_number' => $synchronous_number]);
$generator = new Generate();
$generator->delOutFiles();
$flag = array_unique(array_column($table_info, 'table_name'));
@ -456,7 +551,7 @@ class GenerateService extends BaseAdminService
if($data['addon'] == 'system')
{
//获取系统模型
$modulePath = base_path() . '\\model\\';
$modulePath = dirname(root_path()) . '/niucloud/app/model/';
if(!is_dir($modulePath)) {
return [];
}
@ -489,13 +584,13 @@ class GenerateService extends BaseAdminService
}
}else{
//获取插件模型
$path = dirname(root_path())."\\niucloud\\addon\\".$data['addon']."\\app\\model";
$path = dirname(root_path())."/niucloud/addon/".$data['addon']."/app/model";
if(!is_dir($path)) {
return [];
}
$modulefiles = glob($path . '\*');
$modulefiles = glob($path . '/*');
$targetFiles = [];
foreach ($modulefiles as $file) {

View File

@ -38,7 +38,9 @@ class AdminApiRouteGenerator extends BaseGenerator
'{MODULE_NAME}',
'{ROUTE_NAME}',
'{ROUTE_PATH}',
'{ROUTE}'
'{ROUTE}',
'{BEGIN}',
'{END}'
];
$new = [
@ -51,6 +53,8 @@ class AdminApiRouteGenerator extends BaseGenerator
$this->getRouteName(),
$this->getRoutePath(),
$this->getRoute(),
$this->getBegin(),
$this->getEnd()
];
$vmPath = $this->getvmPath('admin_api_route');
@ -88,7 +92,17 @@ class AdminApiRouteGenerator extends BaseGenerator
if(file_exists($file))
{
$route = file_get_contents($file);
$content = file_get_contents($file);
$code_begin = 'USER_CODE_BEGIN -- '.$this->getTableName();
$code_end = 'USER_CODE_END -- '.$this->getTableName();
if(strpos($content,$code_begin) !== false && strpos($content,$code_end) !== false)
{
// 清除相应对应代码块
$pattern = "/\s+\/\/ {$code_begin}[\S\s]+\/\/ {$code_end}(\n,)?/";
$route = preg_replace($pattern, '', $content);
}else{
$route = $content;
}
}else{
$route = "<?php
// +----------------------------------------------------------------------
@ -110,6 +124,19 @@ use app\adminapi\middleware\AdminLog;";
return $route;
}
public function getBegin()
{
$begin = '// USER_CODE_BEGIN -- '.$this->getTableName();
return $begin;
}
public function getEnd()
{
$end = '// USER_CODE_END -- '.$this->getTableName();
return $end;
}
/**
* 获取表主键
* @return mixed|string
@ -232,12 +259,13 @@ use app\adminapi\middleware\AdminLog;";
{
return 'route.php';
}else{
//如果是某个模块下的功能,公用一个路由
if($this->moduleName && ($this->getLCaseTableName() != $this->moduleName)){
return Str::lower($this->moduleName) . '.php';
}else{
return 'route.php';
}
// //如果是某个模块下的功能,公用一个路由
// if($this->moduleName && ($this->getLCaseTableName() != $this->moduleName)){
// return Str::lower($this->moduleName) . '.php';
// }else{
// return 'route.php';
// }
}
}

View File

@ -169,7 +169,11 @@ abstract class BaseGenerator
}
// 写入内容
if($path) file_put_contents($path, $this->text);
if(!empty($this->getFileName()))
{
file_put_contents($path, $this->text);
}
}
@ -179,12 +183,19 @@ abstract class BaseGenerator
*/
public function fileInfo(): array
{
return [
if(!empty($this->getFileName()))
{
return
[
'name' => $this->getFileName(),
'type' => 'php',
'content' => $this->text,
'file_dir' => $this->getFilePath(),
];
}else{
return [];
}
}
/**
@ -415,4 +426,5 @@ abstract class BaseGenerator
return str_replace($old, $new, file_get_contents($template));
}
}

View File

@ -33,8 +33,8 @@ class MenuSqlGenerator extends BaseGenerator
$old = [
'{SQL}',
];
$new = [$this->getMenuSql(),];
$res = $this->getMenuSql();
$new = [$res['sql'],];
if($this->table['generate_type'] == 3)
{
@ -57,9 +57,15 @@ class MenuSqlGenerator extends BaseGenerator
{
$dir = dirname(root_path());
$file = $dir.'\niucloud\addon\\'.$this->addonName.'\\sql\\install.sql';
$addSql = $this->getMenuSql();
$res = $this->getMenuSql();
$key = $res['data'][0]['menu_key'];
$result = (new SysMenu())->where([['menu_key','=',$key]])->find()->toArray();
if(!$result){
$addSql = $res['sql'];
file_put_contents($file,$addSql,FILE_APPEND);
}
}
}
/**
* 获取文件生成到模块的文件夹路径
@ -145,11 +151,18 @@ class MenuSqlGenerator extends BaseGenerator
} else {
$table_content = '';
}
if(!empty($this->className))
{
$name = $this->className;
}else{
$name = $this->table['table_name'];
}
if(!empty($this->addonName))
{
$key = $this->addonName.'_'.$this->table['table_name'].'_'.$this->moduleName.'_'.$this->getUCaseClassName();
$key = $this->addonName.'_'.$this->table['table_name'].'_'.$this->moduleName.'_'.$name;
}else{
$key = $this->table['table_name'].'_'.$this->moduleName.'_'.$this->getUCaseClassName();
$key = $this->table['table_name'].'_'.$this->moduleName.'_'.$name;
}
$data = [
[
@ -177,8 +190,8 @@ class MenuSqlGenerator extends BaseGenerator
'menu_type' => 1,
'icon' => '',
'api_url' => $this->getRouteName(),
'router_path' => $this->className.'_list',
'view_path' => $this->moduleName.'/'.$this->className.'_list',
'router_path' => 'list',
'view_path' => $this->moduleName.'/'.'list',
'methods' => 'get',
'sort' => 90,
'status' => 1,
@ -188,33 +201,33 @@ class MenuSqlGenerator extends BaseGenerator
'addon' => $this->addonName,
'source' => MenuDict::GENERATOR
],
[
'menu_name' => $table_content.'详情',
'menu_key' => $key.'_info',
'parent_key' => $key,
'menu_type' => 1,
'icon' => '',
'api_url' => $this->getRouteName().'/<'.'id>',
'router_path' => $this->moduleName,
'view_path' => $this->moduleName.'/'.$this->className.'_list',
'methods' => 'get',
'sort' => 80,
'status' => 1,
'is_show' => 1,
'create_time' => time(),
'delete_time' => 0,
'addon' => $this->addonName,
'source' => MenuDict::GENERATOR
],
// [
// 'menu_name' => $table_content.'详情',
// 'menu_key' => $key.'_info',
// 'parent_key' => $key,
// 'menu_type' => 1,
// 'icon' => '',
// 'api_url' => $this->getRouteName().'/<'.'id>',
// 'router_path' => $this->moduleName,
// 'view_path' => $this->moduleName.'/'.$this->className.'_list',
// 'methods' => 'get',
// 'sort' => 80,
// 'status' => 1,
// 'is_show' => 1,
// 'create_time' => time(),
// 'delete_time' => 0,
// 'addon' => $this->addonName,
// 'source' => MenuDict::GENERATOR
// ],
[
'menu_name' => $table_content.'添加',
'menu_key' => $key.'_add',
'parent_key' => $key,
'menu_type' => 1,
'menu_type' => 2,
'icon' => '',
'api_url' => $this->getRouteName(),
'router_path' => $this->className.'_edit',
'view_path' => $this->moduleName.'/'.$this->className.'_edit',
'router_path' => 'edit',
'view_path' => $this->moduleName.'/'.'edit',
'methods' => 'post',
'sort' => 70,
'status' => 1,
@ -228,11 +241,13 @@ class MenuSqlGenerator extends BaseGenerator
'menu_name' => $table_content.'编辑',
'menu_key' => $key.'_edit',
'parent_key' => $key,
'menu_type' => 1,
'menu_type' => 2,
'icon' => '',
'api_url' => $this->getRouteName().'/<'.'id>',
'router_path' => $this->className.'_edit',
'view_path' => $this->moduleName.'/'.$this->className.'_edit',
'router_path' => 'edit',
'view_path' => $this->moduleName.'/'.'edit',
// 'router_path' => $this->className.'_edit',
// 'view_path' => $this->moduleName.'/'.$this->className.'_edit',
'methods' => 'put',
'sort' => 60,
'status' => 1,
@ -264,7 +279,11 @@ class MenuSqlGenerator extends BaseGenerator
$sql = Db::name('sys_menu')->fetchSql(true)->insertAll($data);
$sql = str_replace(' (', PHP_EOL.'(', $sql);
return $sql;
$res = [
'data' => $data,
'sql' => $sql
];
return $res;
}
@ -302,11 +321,17 @@ class MenuSqlGenerator extends BaseGenerator
} else {
$table_content = '';
}
if(!empty($this->className))
{
$name = $this->className;
}else{
$name = $this->table['table_name'];
}
if(!empty($this->addonName))
{
$key = $this->addonName.'_'.$this->table['table_name'].'_'.$this->moduleName.'_'.$this->getUCaseClassName();
$key = $this->addonName.'_'.$this->table['table_name'].'_'.$this->moduleName.'_'.$name;
}else{
$key = $this->table['table_name'].'_'.$this->moduleName.'_'.$this->getUCaseClassName();
$key = $this->table['table_name'].'_'.$this->moduleName.'_'.$name;
}
$data = [
[
@ -334,8 +359,8 @@ class MenuSqlGenerator extends BaseGenerator
'menu_type' => 1,
'icon' => '',
'api_url' => $this->getRouteName(),
'router_path' => $this->className.'_list',
'view_path' => $this->moduleName.'/'.$this->className.'_list',
'router_path' => 'list',
'view_path' => $this->moduleName.'/'.'list',
'methods' => 'get',
'sort' => 90,
'status' => 1,
@ -345,33 +370,33 @@ class MenuSqlGenerator extends BaseGenerator
'addon' => $this->addonName,
'source' => MenuDict::GENERATOR
],
[
'menu_name' => $table_content.'详情',
'menu_key' => $key.'_info',
'parent_key' => $key,
'menu_type' => 1,
'icon' => '',
'api_url' => $this->getRouteName().'/<'.'id>',
'router_path' => $this->moduleName,
'view_path' => $this->moduleName.'/'.$this->className.'_list',
'methods' => 'get',
'sort' => 80,
'status' => 1,
'is_show' => 1,
'create_time' => time(),
'delete_time' => 0,
'addon' => $this->addonName,
'source' => MenuDict::GENERATOR
],
// [
// 'menu_name' => $table_content.'详情',
// 'menu_key' => $key.'_info',
// 'parent_key' => $key,
// 'menu_type' => 1,
// 'icon' => '',
// 'api_url' => $this->getRouteName().'/<'.'id>',
// 'router_path' => $this->moduleName,
// 'view_path' => $this->moduleName.'/'.$this->className.'_list',
// 'methods' => 'get',
// 'sort' => 80,
// 'status' => 1,
// 'is_show' => 1,
// 'create_time' => time(),
// 'delete_time' => 0,
// 'addon' => $this->addonName,
// 'source' => MenuDict::GENERATOR
// ],
[
'menu_name' => $table_content.'添加',
'menu_key' => $key.'_add',
'parent_key' => $key,
'menu_type' => 1,
'menu_type' => 2,
'icon' => '',
'api_url' => $this->getRouteName(),
'router_path' => $this->className.'_edit',
'view_path' => $this->moduleName.'/'.$this->className.'_edit',
'router_path' => 'edit',
'view_path' => $this->moduleName.'/'.'edit',
'methods' => 'post',
'sort' => 70,
'status' => 1,
@ -385,11 +410,13 @@ class MenuSqlGenerator extends BaseGenerator
'menu_name' => $table_content.'编辑',
'menu_key' => $key.'_edit',
'parent_key' => $key,
'menu_type' => 1,
'menu_type' => 2,
'icon' => '',
'api_url' => $this->getRouteName().'/<'.'id>',
'router_path' => $this->className.'_edit',
'view_path' => $this->moduleName.'/'.$this->className.'_edit',
'router_path' => 'edit',
'view_path' => $this->moduleName.'/'.'edit',
// 'router_path' => $this->className.'_edit',
// 'view_path' => $this->moduleName.'/'.$this->className.'_edit',
'methods' => 'put',
'sort' => 60,
'status' => 1,
@ -419,9 +446,15 @@ class MenuSqlGenerator extends BaseGenerator
],
];
$menu_model = new SysMenu();
$result = (new SysMenu())->where([['menu_key','=',$key]])->find();
if(empty($result)){
(new $menu_model())->saveAll($data);
$cache_tag_name = 'menu_cache';
Cache::tag($cache_tag_name)->clear();
}
return true;
}
}

View File

@ -294,7 +294,7 @@ class ModelGenerator extends BaseGenerator
$data['deleteColumnValue'] = '';
}else{
$data['softDelete'] = ' use SoftDelete;';
$data['deleteColumn'] = '/**'.PHP_EOL.' * 定义软删除标记字段.'.PHP_EOL.' * @var string'.PHP_EOL.' */'.PHP_EOL.' protected $deleteTime = '."'".$column['column_name']."'";
$data['deleteColumn'] = '/**'.PHP_EOL.' * 定义软删除标记字段.'.PHP_EOL.' * @var string'.PHP_EOL.' */'.PHP_EOL.' protected $deleteTime = '."'".$column['column_name']."';";
$data['deleteColumnValue'] = '/**'.PHP_EOL.' * 定义软删除字段的默认值.'.PHP_EOL.' * @var int'.PHP_EOL.' */'.PHP_EOL.' protected $defaultSoftDelete = 0;';
}
}
@ -307,12 +307,14 @@ class ModelGenerator extends BaseGenerator
public function getRelationModel()
{
$tpl = '';
// $this->table['relations'] = '[{"name":"test","model":"\\app\\common\\model\\Config","type":"has_one","local_key":"id","foreign_key":"id"}]';
if ($this->table['relations'] == '[]') {
return $tpl;
}
// 遍历关联配置
if(!empty($this->table['relations']))
{
$relations = json_decode($this->table['relations'],true);
foreach ($relations as $config) {
@ -338,6 +340,10 @@ class ModelGenerator extends BaseGenerator
$tpl .= $this->replaceFileText($needReplace, $waitReplace, $vmPath). PHP_EOL;
}
return $tpl;
}else{
return '';
}
}
}

View File

@ -65,9 +65,43 @@ class ValidateGenerator extends BaseGenerator
{
$content = "";
foreach ($this->tableColumn as $column) {
if (!$column['is_pk']) {
if($column['is_required'] == 1){
if(!empty($column['validate_type']))
{
$column['validate_type'] = json_decode($column['validate_type'],true);
if($column['validate_type'][0] == 'max')
{
$content .= "'".$column['column_name']."' => 'require|".$column['validate_type'][0].":".$column['validate_type'][1][0]."',". PHP_EOL;
}else if($column['validate_type'][0] == 'min')
{
$content .= "'".$column['column_name']."' => 'require|".$column['validate_type'][0].":".$column['validate_type'][1][0]."',". PHP_EOL;
}else if($column['validate_type'][0] == 'between'){
$content .= "'".$column['column_name']."' => 'require|".$column['validate_type'][0].":".$column['validate_type'][1][0].','.$column['validate_type'][1][1]."',". PHP_EOL;
}else{
$content .= "'".$column['column_name']."' => 'require|".$column['validate_type'][0]."',". PHP_EOL;
}
}else{
$content .= "'".$column['column_name'] . "' => 'require'," . PHP_EOL;
}
}else{
if(!empty($column['validate_type']))
{
$column['validate_type'] = json_decode($column['validate_type'],true);
if($column['validate_type'][0] == 'max')
{
$content .= "'".$column['column_name']."' => '".$column['validate_type'][0].":".$column['validate_type'][1][0]."',". PHP_EOL;
}else if($column['validate_type'][0] == 'min')
{
$content .= "'".$column['column_name']."' => '".$column['validate_type'][0].":".$column['validate_type'][1][0]."',". PHP_EOL;
}else if($column['validate_type'][0] == 'between'){
$content .= "'".$column['column_name']."' => '".$column['validate_type'][0].":".$column['validate_type'][1][0].','.$column['validate_type'][1][1]."',". PHP_EOL;
}else{
$content .= "'".$column['column_name']."' => '".$column['validate_type'][0]."',". PHP_EOL;
}
}
}
}
$content = substr($content, 0, -2);
$content = $this->setBlankSpace($content, " ");
@ -80,7 +114,36 @@ class ValidateGenerator extends BaseGenerator
*/
public function getMessage()
{
return '[]';
$content = "";
foreach ($this->tableColumn as $column) {
if($column['is_required'] == 1)
{
$content .= "'".$column['column_name'].".require"."' => "."['".'common_validate.require'."', ['".$column['column_name']."']]".','. PHP_EOL;
}
if(!empty($column['validate_type']))
{
$column['validate_type'] = json_decode($column['validate_type'],true);
if($column['validate_type'][0] == 'max')
{
$content .= "'".$column['column_name'].".".$column['validate_type'][0]."' => "."['".'common_validate.'.$column['validate_type'][0]."', ['".$column['column_name']."','".$column['validate_type'][1][0]."']]".','. PHP_EOL;
}else if($column['validate_type'][0] == 'min')
{
$content .= "'".$column['column_name'].".".$column['validate_type'][0]."' => "."['".'common_validate.'.$column['validate_type'][0]."', ['".$column['column_name']."','".$column['validate_type'][1][0]."']]".','. PHP_EOL;
}else if($column['validate_type'][0] == 'between'){
$content .= "'".$column['column_name'].".".$column['validate_type'][0]."' => "."['".'common_validate.'.$column['validate_type'][0]."', ['".$column['column_name']."','".$column['validate_type'][1][0]."','".$column['validate_type'][1][1]."']]".','. PHP_EOL;
}else{
$content .= "'".$column['column_name'].".".$column['validate_type'][0]."' => "."['".'common_validate.'.$column['validate_type'][0]."', ['".$column['column_name']."']]".','. PHP_EOL;
}
}
}
$content = substr($content, 0, -2);
$content = $this->setBlankSpace($content, " ");
return '['.PHP_EOL.$content.PHP_EOL.' ]';
}
/**
@ -132,14 +195,21 @@ class ValidateGenerator extends BaseGenerator
*/
public function getClassComment()
{
if (!empty($this->table['table_content'])) {
$tpl = $this->table['table_content'] . '验证器';
} else {
$tpl = $this->getUCaseName() . '验证器';
}
$tpl = $this->getNotes() . '验证器';
return $tpl;
}
public function getNotes()
{
$end_str = substr($this->table['table_content'],-3);
if($end_str == '表')
{
return substr($this->table['table_content'],0,strlen($this->table['table_content'])-3);
}else{
return $this->table['table_content'];
}
}
/**
* 获取包名

View File

@ -40,7 +40,9 @@ class WebApiGenerator extends BaseGenerator
'{UCASE_NAME}',
'{MODULE_NAME}',
'{ROUTE_GROUP_NAME}',
'{IMPORT}'
'{IMPORT}',
'{BEGIN}',
'{END}',
];
$new = [
@ -53,6 +55,8 @@ class WebApiGenerator extends BaseGenerator
$this->moduleName,
$this->getRouteGroupName(),
$this->getImport(),
$this->getBegin(),
$this->getEnd(),
];
$vmPath = $this->getvmPath('web_api');
@ -78,8 +82,14 @@ class WebApiGenerator extends BaseGenerator
* @return string
*/
public function getModuleOutDir()
{
if(!empty($this->addonName))
{
$dir = dirname(app()->getRootPath()) . '/admin/src/api/';
}else{
$dir = dirname(app()->getRootPath()) . '/admin/src/app/api/';
}
$this->checkDir($dir);
return $dir;
}
@ -101,14 +111,40 @@ class WebApiGenerator extends BaseGenerator
if(file_exists($file))
{
$import = file_get_contents($file);
$content = file_get_contents($file);
$code_begin = 'USER_CODE_BEGIN -- '.$this->getTableName();
$code_end = 'USER_CODE_END -- '.$this->getTableName();
if(strpos($content,$code_begin) !== false && strpos($content,$code_end) !== false)
{
// 清除相应对应代码块
$pattern = "/\s+\/\/ {$code_begin}[\S\s]+\/\/ {$code_end}(\n,)?/";
$import = preg_replace($pattern, '', $content);
}else{
$import = "import request from '@//utils//request'";
$import = $content;
}
}else{
$import = "import request from '@/utils/request'";
}
return $import;
}
public function getBegin()
{
$begin = '// USER_CODE_BEGIN -- '.$this->getTableName();
return $begin;
}
public function getEnd()
{
$end = '// USER_CODE_END -- '.$this->getTableName();
return $end;
}
/**
* 获取文件生成到runtime的文件夹路径
* @return string
@ -137,7 +173,7 @@ class WebApiGenerator extends BaseGenerator
{
$dir = $this->rootDir . '/admin/src/'.$this->addonName.'/api/';
}else{
$dir = $this->rootDir . '/admin/src/api/';
$dir = $this->rootDir . '/admin/src/app/api/';
}
$this->checkDir($dir);

View File

@ -44,6 +44,9 @@ class WebEditGenerator extends BaseGenerator
'{PK}',
'{MODULE_NAME}',
'{API_PATH}',
'{DICT_DATA}',
'{DICT_LIST}',
];
$new = [
@ -55,6 +58,8 @@ class WebEditGenerator extends BaseGenerator
$this->getPk(),
$this->moduleName,
$this->getApiPath(),
$this->getDictDataContent(),
$this->getDictList(),
];
$vmPath = $this->getvmPath('web_edit');
@ -88,6 +93,8 @@ class WebEditGenerator extends BaseGenerator
return $this->setBlankSpace($content, ' ');
}
/**
* 获取表单内容
* @return string
@ -104,15 +111,37 @@ class WebEditGenerator extends BaseGenerator
'{COLUMN_NAME}',
'{LCASE_COLUMN_NAME}',
'{PROP}',
'{DICT_TYPE}',
];
if(empty($column['dict_type']))
{
$new = [
$column['column_comment'],
$column['column_name'],
Str::camel($column['column_name']),
$column['is_required'] ? 'prop="'.$column['column_name'].'"' : ''
$column['is_required'] ? 'prop="'.$column['column_name'].'"' : '',
''
];
if($column['view_type'] == 'select' || $column['view_type'] == 'radio' || $column['view_type'] == 'checkbox')
{
$vmName = $column['view_type'].'2';
}else{
$vmName = $column['view_type'];
}
$vmPath = $this->getvmPath('form/' . $column['view_type']);
}else{
$new = [
$column['column_comment'],
$column['column_name'],
Str::camel($column['column_name']),
$column['is_required'] ? 'prop="'.$column['column_name'].'"' : '',
$column['column_name'].'List',
];
$vmName = $column['view_type'];
}
$vmPath = $this->getvmPath('form/' . $vmName);
if (!file_exists($vmPath)) {
continue;
}
@ -127,11 +156,32 @@ class WebEditGenerator extends BaseGenerator
$old[] = '{ITEM_VALUE}';
$new[] = $vmItemValue;
}
// 数字框处理
if ($column['view_type'] == 'number') {
if(!empty($column['validate_type']))
{
$validate = json_decode($column['validate_type'],true);
if($validate[0] == 'min')
{
$rule = ':min = "'.$validate[1][0].'"';
}
if($validate[0] == 'max')
{
$rule = ':max = "'.$validate[1][0].'"';
}
if($validate[0] == 'between')
{
$rule = ':min = "'.$validate[1][0].'"'.' max = "'.$validate[1][1].'"';
}
}else{
$rule = '';
}
$old[] = '{RULE}';
$new[] = $rule;
}
$content .= $this->replaceFileText($old, $new, $vmPath) . PHP_EOL;
}
if (!empty($content)) {
$content = substr($content, 0, -1);
}
@ -139,6 +189,63 @@ class WebEditGenerator extends BaseGenerator
return $this->setBlankSpace($content, ' ');
}
/**
* 获取数据字典内容
* @return string
*/
public function getDictDataContent()
{
$content = '';
$isExist = [];
foreach ($this->tableColumn as $column) {
if (empty($column['dict_type']) || $column['is_pk']) {
continue;
}
if (in_array($column['dict_type'], $isExist)) {
continue;
}
$content .= $column['dict_type'] . ': ' . "[]," . PHP_EOL;
$isExist[] = $column['dict_type'];
}
if (!empty($content)) {
$content = substr($content, 0, -1);
}
return $this->setBlankSpace($content, ' ');
}
/**
* 获取API数据字典内容
* @return string
*/
public function getDictDataApiContent()
{
$content = '';
$isExist = [];
foreach ($this->tableColumn as $column) {
if (empty($column['dict_type']) || $column['is_pk']) {
continue;
}
if (in_array($column['dict_type'], $isExist)) {
continue;
}
$needReplace = [
'{DICT_TYPE}',
];
$waitReplace = [
$column['column_name'].'List',
];
$templatePath = $this->getTemplatePath('/other/dictDataApi');
if (!file_exists($templatePath)) {
continue;
}
$content .= $this->replaceFileData($needReplace, $waitReplace, $templatePath) . '' . PHP_EOL;
$isExist[] = $column['dict_type'];
}
$content = substr($content, 0, -1);
return $content;
}
/**
* 获取表单默认字段内容
@ -182,9 +289,9 @@ class WebEditGenerator extends BaseGenerator
$specDictType = ['input', 'textarea', 'editor'];
foreach ($this->tableColumn as $column) {
if (!$column['is_required'] || $column['is_pk']) {
continue;
}
// if (!$column['is_pk']) {
// continue;
// }
if (!$column['is_insert'] || !$column['is_update'] ) {
continue;
}
@ -197,10 +304,18 @@ class WebEditGenerator extends BaseGenerator
$old = [
'{COLUMN_NAME}',
'{VALIDATE_MSG}',
'{VERIFY}'
];
if(!empty($column['validate_type']))
{
$validate = json_decode($column['validate_type'],true);
}else{
$validate = [];
}
$new = [
$column['column_name'],
$validateMsg,
$this->getVerify($validate)
];
$vmPath = $this->getvmPath('other/formValidate');
if (!file_exists($vmPath)) {
@ -214,6 +329,39 @@ class WebEditGenerator extends BaseGenerator
return substr($content, 0, -2);
}
public function getVerify($validateType)
{
if(!empty($validateType))
{
if(!empty($validateType[1]))
{
if($validateType[0] == 'min')
{
$min = '0,'.$validateType[1][0];
$content = '{ validator: (rule: any, value: string, callback: any) => { '.
' if (value && !/^\d{0,'.$min.'}$/.test(value)) {'.
"callback(new Error(t('".'generateMin'."')))".'} else { callback() }}},';
}
if($validateType[0] == 'max')
{
$max = '0,'.$validateType[1][0];
$content = '{ validator: (rule: any, value: string, callback: any) => { '.
' if (value && !/^\d{0,'.$max.'}$/.test(value)) {'.
" callback(new Error(t('".'generateMax'."')))".' } else { callback() }}},';
}
if($validateType[0] == 'between')
{
$between = $validateType[1][0].','.$validateType[1][1];
$content = '{ validator: (rule: any, value: string, callback: any) => { '.
' if (value && !/^\d{'.$between.'}$/.test(value)) {'. " callback(new Error(t('".'generateBetween'."')))".'} else { callback() }}},';
}
}
}else{
$content = '';
}
return $content;
}
/**
* 获取文件生成到模块的文件夹路径
@ -243,7 +391,7 @@ class WebEditGenerator extends BaseGenerator
{
$dir = $this->outDir . '/addon/'.$this->addonName.'/admin/src/views/' . $this->moduleName . '/';
}else{
$dir = $this->outDir . 'admin/src/views/' . $this->moduleName . '/';
$dir = $this->outDir . 'admin/src/app/views/' . $this->moduleName . '/';
}
$dir .= 'components/';
@ -262,8 +410,7 @@ class WebEditGenerator extends BaseGenerator
{
$dir = $this->rootDir . '/admin/src/'.$this->addonName.'/views/'. $this->moduleName . '/';
}else{
// $dir = '';
$dir = $this->rootDir . '/admin/src/views/'. $this->moduleName . '/';
$dir = $this->rootDir . '/admin/src/app/views/'. $this->moduleName . '/';
}
$dir .= 'components/';
@ -296,10 +443,8 @@ class WebEditGenerator extends BaseGenerator
if($this->table['edit_type'] != 1) {
return '';
}
if($this->className){
return Str::lower($this->className) . '-edit.vue';
}
return str_replace('_', '-', Str::lower($this->getTableName())).'-edit.vue';
return 'edit.vue';
}
/**
@ -312,7 +457,31 @@ class WebEditGenerator extends BaseGenerator
{
return $this->addonName.'/api/'.$this->moduleName;
}else{
return 'api/'.$this->moduleName;
return '/app/api/'.$this->moduleName;
}
}
/**
* 调用字典方法
* @return void
*/
public function getDictList()
{
$content = '';
foreach ($this->tableColumn as $column)
{
if(empty($column['dict_type']))
{
continue;
}
$content.= 'let '.$column['column_name'].'List = ref([])'.PHP_EOL.'const '.$column['column_name'].'DictList = async () => {'.PHP_EOL.$column['column_name'].'List.value = await (await useDictionary(' ."'".$column['dict_type']."'".')).data.dictionary'.PHP_EOL.'}'.PHP_EOL. $column['column_name'].'DictList();'.PHP_EOL;
}
if(!empty($content))
{
$content = substr($content, 0, -1);
}
return $this->setBlankSpace($content, ' ');
}
}

View File

@ -132,7 +132,7 @@ class WebEditLangGenerator extends BaseGenerator
{
$dir = $this->rootDir . '/admin/src/'.$this->addonName.'/lang/zh-cn/';
}else{
$dir = $this->rootDir . '/admin/src/lang/zh-cn/';
$dir = $this->rootDir . '/admin/src/app/lang/zh-cn/';
}
$this->checkDir($dir);

View File

@ -45,6 +45,8 @@ class WebEditPageGenerator extends BaseGenerator
'{LCASE_CLASS_NAME}',
'{MODULE_NAME}',
'{API_PATH}',
'{DICT_DATA}',
'{DICT_LIST}'
];
$new = [
@ -58,6 +60,8 @@ class WebEditPageGenerator extends BaseGenerator
$this->getLCaseClassName(),
$this->moduleName,
$this->getApiPath(),
$this->getDictDataContent(),
$this->getDictList(),
];
$vmPath = $this->getvmPath('web_edit_page');
@ -68,6 +72,54 @@ class WebEditPageGenerator extends BaseGenerator
$this->setText($text);
}
/**
* 获取数据字典内容
* @return string
*/
public function getDictDataContent()
{
$content = '';
$isExist = [];
foreach ($this->tableColumn as $column) {
if (empty($column['dict_type']) || $column['is_pk']) {
continue;
}
if (in_array($column['dict_type'], $isExist)) {
continue;
}
$content .= $column['dict_type'] . ': ' . "[]," . PHP_EOL;
$isExist[] = $column['dict_type'];
}
if (!empty($content)) {
$content = substr($content, 0, -1);
}
return $this->setBlankSpace($content, ' ');
}
/**
* 调用字典方法
* @return void
*/
public function getDictList()
{
$content = '';
foreach ($this->tableColumn as $column)
{
if(empty($column['dict_type']))
{
continue;
}
$content.= 'let '.$column['column_name'].'List = ref([])'.PHP_EOL.'const '.$column['column_name'].'DictList = async () => {'.PHP_EOL.$column['column_name'].'List.value = await (await useDictionary(' ."'".$column['dict_type']."'".')).data.dictionary'.PHP_EOL.'}'.PHP_EOL. $column['column_name'].'DictList();'.PHP_EOL;
}
if(!empty($content))
{
$content = substr($content, 0, -1);
}
return $this->setBlankSpace($content, ' ');
}
/**
* 表单日期处理
* @return string
@ -108,15 +160,36 @@ class WebEditPageGenerator extends BaseGenerator
'{COLUMN_NAME}',
'{LCASE_COLUMN_NAME}',
'{PROP}',
'{DICT_TYPE}',
];
if(empty($column['dict_type']))
{
$new = [
$column['column_comment'],
$column['column_name'],
Str::camel($column['column_name']),
$column['is_required'] ? 'prop="'.$column['column_name'].'"' : ''
$column['is_required'] ? 'prop="'.$column['column_name'].'"' : '',
''
];
if($column['view_type'] == 'select' || $column['view_type'] == 'radio' || $column['view_type'] == 'checkbox')
{
$vmName = $column['view_type'].'2';
}else{
$vmName = $column['view_type'];
}
$vmPath = $this->getvmPath('form/' . $column['view_type']);
}else{
$new = [
$column['column_comment'],
$column['column_name'],
Str::camel($column['column_name']),
$column['is_required'] ? 'prop="'.$column['column_name'].'"' : '',
$column['column_name'].'List',
];
$vmName = $column['view_type'];
}
$vmPath = $this->getvmPath('form/' . $vmName);
if (!file_exists($vmPath)) {
continue;
}
@ -131,7 +204,32 @@ class WebEditPageGenerator extends BaseGenerator
$old[] = '{ITEM_VALUE}';
$new[] = $vmItemValue;
}
// 数字框处理
if ($column['view_type'] == 'number') {
if(!empty($column['validate_type']))
{
$validate = json_decode($column['validate_type'],true);
if($validate[0] == 'min')
{
$rule = ':min = '."'".$validate[1][0]."'";
}
if($validate[0] == 'max')
{
$rule = ':max = '."'".$validate[1][0]."'";
}
if($validate[0] == 'between')
{
$rule = ':min = "'.$validate[1][0].'"'.' :max = "'.$validate[1][1].'"';
}
$old[] = '{RULE}';
$new[] = $rule;
dd($rule);
}else{
$old[] = '{RULE}';
$new[] = '';
}
}
$content .= $this->replaceFileText($old, $new, $vmPath) . PHP_EOL;
}
@ -139,7 +237,6 @@ class WebEditPageGenerator extends BaseGenerator
if (!empty($content)) {
$content = substr($content, 0, -1);
}
return $this->setBlankSpace($content, ' ');
}
@ -188,9 +285,6 @@ class WebEditPageGenerator extends BaseGenerator
$specDictType = ['input', 'textarea', 'editor'];
foreach ($this->tableColumn as $column) {
if (!$column['is_required'] || $column['is_pk']) {
continue;
}
if (!$column['is_insert'] || !$column['is_update'] ) {
continue;
}
@ -203,10 +297,18 @@ class WebEditPageGenerator extends BaseGenerator
$old = [
'{COLUMN_NAME}',
'{VALIDATE_MSG}',
'{VERIFY}'
];
if(!empty($column['validate_type']))
{
$validate = json_decode($column['validate_type'],true);
}else{
$validate = [];
}
$new = [
$column['column_name'],
$validateMsg,
$this->getVerify($validate)
];
$vmPath = $this->getvmPath('other/formValidate');
if (!file_exists($vmPath)) {
@ -220,6 +322,44 @@ class WebEditPageGenerator extends BaseGenerator
return substr($content, 0, -2);
}
/**
* 输入信息验证
* @param $validateType
* @return string
*/
public function getVerify($validateType)
{
if(!empty($validateType))
{
if(!empty($validateType[1]))
{
if($validateType[0] == 'min')
{
$min = '0,'.$validateType[1][0];
$content = '{ validator: (rule: any, value: string, callback: any) => { '.
' if (value && !/^\d{0,'.$min.'}$/.test(value)) {'.
"callback(new Error(t('".'generateMin'."')))".'} else { callback() }}},';
}
if($validateType[0] == 'max')
{
$max = '0,'.$validateType[1][0];
$content = '{ validator: (rule: any, value: string, callback: any) => { '.
' if (value && !/^\d{0,'.$max.'}$/.test(value)) {'.
" callback(new Error(t('".'generateMax'."')))".' } else { callback() }}},';
}
if($validateType[0] == 'between')
{
$between = $validateType[1][0].','.$validateType[1][1];
$content = '{ validator: (rule: any, value: string, callback: any) => { '.
' if (value && !/^\d{'.$between.'}$/.test(value)) {'. " callback(new Error(t('".'generateBetween'."')))".'} else { callback() }}},';
}
}
}else{
$content = '';
}
return $content;
}
/**
* 获取文件生成到模块的文件夹路径
@ -247,13 +387,11 @@ class WebEditPageGenerator extends BaseGenerator
}
if(!empty($this->addonName))
{
$dir = $this->outDir . 'addon/'.$this->addonName.'/admin/src/views/' . $this->moduleName . '/';
$dir = $this->outDir . '/addon/'.$this->addonName.'/admin/src/views/' . $this->moduleName . '/';
}else{
$dir = $this->outDir . 'admin/src/views/' . $this->moduleName . '/';
$dir = $this->outDir . 'admin/src/app/views/' . $this->moduleName . '/';
}
$this->checkDir($dir);
return $dir;
@ -268,11 +406,12 @@ class WebEditPageGenerator extends BaseGenerator
if($this->table['edit_type'] != 2) {
return '';
}
if(!empty($this->addonName))
{
$dir = $this->rootDir . '/admin/src/'.$this->addonName.'/views/'. $this->moduleName . '/';
}else{
$dir = $this->rootDir . '/admin/src/views/' . $this->moduleName . '/';
$dir = $this->rootDir . '/admin/src/app/views/'. $this->moduleName . '/';
}
$this->checkDir($dir);
@ -284,13 +423,14 @@ class WebEditPageGenerator extends BaseGenerator
if($this->table['edit_type'] != 2) {
return '';
}
if(!empty($this->addonName))
{
$dir = 'addon/'.$this->addonName.'/admin/'.$this->addonName.'/views/' . $this->moduleName . '/';
}else{
$dir = 'admin/app/views/' . $this->moduleName . '/';
}
return $dir;
}
@ -303,9 +443,9 @@ class WebEditPageGenerator extends BaseGenerator
if($this->table['edit_type'] != 2) {
return '';
}
if($this->className){
return Str::lower($this->className).'_edit.vue';
}
// if($this->className){
// return Str::lower($this->className).'_edit.vue';
// }
return 'edit.vue';
}
@ -319,7 +459,8 @@ class WebEditPageGenerator extends BaseGenerator
{
return $this->addonName.'/api/'.$this->moduleName;
}else{
return 'api/'.$this->moduleName;
}
return '/app/api/'.$this->moduleName;
}
}
}

View File

@ -49,6 +49,7 @@ class WebIndexGenerator extends BaseGenerator
'{ADD_EVENT}',
'{EDIT_EVENT}',
'{API_PATH}',
'{DICT_LIST}'
];
$new = [
@ -68,6 +69,8 @@ class WebIndexGenerator extends BaseGenerator
$this->getAddEvent(),
$this->getEditEvent(),
$this->getApiPath(),
// $this->getDictDataContent(),
$this->getDictList(),
];
$vmPath = $this->getvmPath('web_index');
@ -101,15 +104,16 @@ class WebIndexGenerator extends BaseGenerator
{
if($this->table['edit_type'] == 2) return "import { useRouter } from 'vue-router'";
$path = 'components/';
$file_name = str_replace('_', '-', Str::lower($this->getTableName())).'-edit.vue';
if($this->className){
$file_name = Str::lower($this->className) . '-edit.vue';
}
// $file_name = str_replace('_', '-', Str::lower($this->getTableName())).'-edit.vue';
$file_name = 'edit.vue';
// if($this->className){
// $file_name = Str::lower($this->className) . '-edit.vue';
// }
if(!empty($this->addonName))
{
return "import ".$this->getUCaseClassName()."Edit from '@/".$this->addonName."/views/".$this->moduleName."/".$path.$file_name."'";
return "import "."Edit from '@/".$this->addonName."/views/".$this->moduleName."/".$path.$file_name."'";
}else{
return "import ".$this->getUCaseClassName()."Edit from '@/views/".$this->moduleName."/".$path.$file_name."'";
return "import "."Edit from '@/app/views/".$this->moduleName."/".$path.$file_name."'";
}
}
@ -120,13 +124,8 @@ class WebIndexGenerator extends BaseGenerator
public function getEditView()
{
if($this->table['edit_type'] == 2) return '';
$file_name = str_replace('_', '-', Str::lower($this->getTableName())).'-edit';
if($this->className){
$file_name = Str::lower($this->className) . '-edit';
}
return '<'.$file_name.' ref="edit'.$this->getUCaseClassName().'Dialog" @complete="load'.$this->getUCaseName().'List" />';
$file_name = 'edit';
return '<'.$file_name.' ref="edit'.$this->getUCaseClassName().'Dialog" @complete="load'.$this->getUCaseClassName().'List" />';
}
/**
@ -148,7 +147,7 @@ class WebIndexGenerator extends BaseGenerator
$class_name = $this->className ? '/'.Str::lower($this->className) : '';
if($this->table['edit_type'] == 2){
//打开新页面
$content = "router.push('/".$this->moduleName.$class_name."/edit')";
$content = "router.push('/".$this->moduleName."/edit')";
}else{
$content = 'edit'.$this->getUCaseClassName().'Dialog.value.setFormData()'.PHP_EOL.'edit'.$this->getUCaseClassName().'Dialog.value.showDialog = true';
}
@ -165,7 +164,7 @@ class WebIndexGenerator extends BaseGenerator
{
$class_name = $this->className ? '/'.Str::lower($this->className) : '';
if($this->table['edit_type'] == 2){
$content = "router.push('/".$this->moduleName.$class_name."/edit?id='+data.".$this->getPk().")";
$content = "router.push('/".$this->moduleName."/edit?id='+data.".$this->getPk().")";
}else{
$content = 'edit'.$this->getUCaseClassName().'Dialog.value.setFormData(data)'.PHP_EOL.'edit'.$this->getUCaseClassName().'Dialog.value.showDialog = true';
}
@ -191,6 +190,8 @@ class WebIndexGenerator extends BaseGenerator
'{LCASE_CLASS_NAME}',
'{LCASE_COLUMN_NAME}',
];
if(empty($column['dict_type']))
{
$new = [
$column['column_comment'],
$column['column_name'],
@ -198,11 +199,31 @@ class WebIndexGenerator extends BaseGenerator
$this->getLCaseClassName(),
Str::camel($column['column_name']),
];
}else{
$new = [
$column['column_comment'],
$column['column_name'],
$column['column_name'].'List',
$this->getLCaseClassName(),
Str::camel($column['column_name']),
];
}
$searchVmType = $column['view_type'];
if ($column['view_type'] == 'radio') {
$searchVmType = 'select';
}
if(empty($column['dict_type']))
{
if ($column['view_type'] == 'radio' || $column['view_type'] == 'select' || $column['view_type'] == 'checkbox' ) {
$searchVmType = 'select2';
}
}else{
if ($column['view_type'] == 'radio') {
$searchVmType = 'select';
}
}
$vmPath = $this->getvmPath('search/' . $searchVmType);
if (!file_exists($vmPath)) {
@ -357,7 +378,7 @@ class WebIndexGenerator extends BaseGenerator
{
$dir = $this->rootDir . '/admin/src/'.$this->addonName.'/views/'. $this->moduleName . '/';
}else{
$dir = $this->rootDir . '/admin/src/views/' . $this->moduleName . '/';
$dir = $this->rootDir . '/admin/src/app/views/' . $this->moduleName . '/';
}
$this->checkDir($dir);
@ -381,7 +402,7 @@ class WebIndexGenerator extends BaseGenerator
*/
public function getFileName()
{
if($this->className) return Str::lower($this->className).'_list.vue';
// if($this->className) return Str::lower($this->className).'_list.vue';
return 'list.vue';
}
@ -393,9 +414,58 @@ class WebIndexGenerator extends BaseGenerator
{
if(!empty($this->addonName))
{
return $this->addonName.'/api/'.$this->moduleName;
return '/'.$this->addonName.'/api/'.$this->moduleName;
}else{
return 'api/'.$this->moduleName;
return '/app/api/'.$this->moduleName;
}
}
public function getDictDataContent()
{
$content = '';
$isExist = [];
foreach ($this->tableColumn as $column) {
if (empty($column['dict_type']) || $column['is_pk']) {
continue;
}
if (in_array($column['dict_type'], $isExist)) {
continue;
}
$content .= $column['dict_type'] . ': ' . "[]," . PHP_EOL;
$isExist[] = $column['dict_type'];
}
if (!empty($content)) {
$content = substr($content, 0, -1);
}
return $this->setBlankSpace($content, ' ');
}
/**
* 调用字典方法
* @return void
*/
public function getDictList()
{
$content = '';
foreach ($this->tableColumn as $column)
{
if(empty($column['dict_type']))
{
continue;
}
if($column['view_type'] == 'select')
{
$content.= 'let '.$column['column_name'].'List = ref([])'.PHP_EOL.'const '.$column['column_name'].'DictList = async () => {'.PHP_EOL.$column['column_name'].'List.value = await (await useDictionary(' ."'".$column['dict_type']."'".')).data.dictionary'.PHP_EOL.'}'.PHP_EOL. $column['column_name'].'DictList();'.PHP_EOL;
}
}
if(!empty($content))
{
$content = substr($content, 0, -1);
}
return $this->setBlankSpace($content, ' ');
}
}

View File

@ -75,7 +75,7 @@ class WebLangGenerator extends BaseGenerator
}
$lang .= '"add'.$this->getUCaseClassName() .'":"添加'.$table_content.'",'.PHP_EOL;
$lang .= '"update'.$this->getUCaseClassName() .'":"编辑'.$table_content.'",'.PHP_EOL;
$lang .= '"'.$this->getLCaseClassName() .'DeleteTips":"确定要删除该'.$table_content.'吗?",'.PHP_EOL;
$lang .= '"'.$this->getLCaseClassName() .'DeleteTips":"确定要删除该数据吗?",'.PHP_EOL;
$lang = trim(trim($lang), ',');
return '{'.PHP_EOL.$this->setBlankSpace($lang, " ").PHP_EOL.'}';
}
@ -120,7 +120,7 @@ class WebLangGenerator extends BaseGenerator
{
$dir = $this->rootDir . '/admin/src/'.$this->addonName.'/lang/zh-cn/';
}else{
$dir = $this->rootDir . '/admin/src/lang/zh-cn/';
$dir = $this->rootDir . '/admin/src/app/lang/zh-cn/';
}
$this->checkDir($dir);
@ -146,7 +146,7 @@ class WebLangGenerator extends BaseGenerator
public function getFileName()
{
if($this->className){
return $this->moduleName.'.'.Str::lower($this->className).'_list.json';
return $this->moduleName.'.'.'list.json';
}
return $this->moduleName.'.list.json';
}

View File

@ -1,9 +1,9 @@
{ROUTE}
{BEGIN}
Route::group('{ROUTE_GROUP_NAME}', function () {
/***************************************************** {NOTES}管理 ****************************************************/
//{NOTES}列表
Route::get('{ROUTE_NAME}', '{ROUTE_PATH}lists');
//{NOTES}详情
@ -20,3 +20,4 @@ Route::group('{ROUTE_GROUP_NAME}', function () {
AdminCheckRole::class,
AdminLog::class
]);
{END}

View File

@ -1,6 +1,11 @@
<el-form-item :label="t('{LCASE_COLUMN_NAME}')" {PROP}>
<el-form-item label="t('{LCASE_COLUMN_NAME}')" {PROP}>
<el-checkbox-group v-model="formData.{COLUMN_NAME}" :placeholder="t('{LCASE_COLUMN_NAME}Placeholder')">
<el-checkbox label="1">选项1</el-checkbox>
<el-checkbox label="2">选项2</el-checkbox>
<el-checkbox
v-for="(item, index) in {DICT_TYPE}"
:key="index"
:label="item.value"
>
{{ item.name }}
</el-checkbox>
</el-checkbox-group>
</el-form-item>

View File

@ -0,0 +1,6 @@
<el-form-item :label="t('{LOWER_COLUMN_NAME}')" {PROP}>
<el-checkbox-group v-model="formData.{COLUMN_NAME}" :placeholder="t('{LOWER_COLUMN_NAME}Placeholder')">
<el-checkbox label="1">选项1</el-checkbox>
<el-checkbox label="2">选项2</el-checkbox>
</el-checkbox-group>
</el-form-item>

View File

@ -1,3 +1,3 @@
<el-form-item :label="t('{COLUMN_NAME}')">
<el-form-item :label="t('{LCASE_COLUMN_NAME}')">
<upload-image v-model="formData.{COLUMN_NAME}" />
</el-form-item>

View File

@ -0,0 +1,3 @@
<el-form-item :label="t('{LCASE_COLUMN_NAME}')" {PROP}>
<el-input-number v-model="formData.{COLUMN_NAME}" clearable :placeholder="t('{LCASE_COLUMN_NAME}Placeholder')" class="input-width" {RULE} />
</el-form-item>

View File

@ -1,10 +1,12 @@
<el-form-item :label="t('{LCASE_COLUMN_NAME}')" {PROP}>
<el-radio-group v-model="formData.{COLUMN_NAME}" :placeholder="t('{LCASE_COLUMN_NAME}Placeholder')">
<el-radio label="1">
选项1
</el-radio>
<el-radio label="2">
选项2
<el-radio
v-for="(item, index) in {DICT_TYPE}"
:key="index"
:label="{ITEM_VALUE}"
>
{{ item.name }}
</el-radio>
</el-radio-group>
</el-form-item>

View File

@ -0,0 +1,10 @@
<el-form-item :label="t('{LOWER_COLUMN_NAME}')" {PROP}>
<el-radio-group v-model="formData.{COLUMN_NAME}" :placeholder="t('{LOWER_COLUMN_NAME}Placeholder')">
<el-radio label="1">
选项1
</el-radio>
<el-radio label="2">
选项2
</el-radio>
</el-radio-group>
</el-form-item>

View File

@ -1,12 +1,10 @@
<el-form-item :label="t('{LCASE_COLUMN_NAME}')" {PROP}>
<el-select v-model="formData.{COLUMN_NAME}" clearable :placeholder="t('{LCASE_COLUMN_NAME}Placeholder')" class="input-width">
<el-select class="input-width" v-model="formData.{COLUMN_NAME}" clearable :placeholder="t('{LCASE_COLUMN_NAME}Placeholder')">
<el-option
label="选项1"
value="1"
/>
<el-option
label="选项2"
value="2"
v-for="(item, index) in {DICT_TYPE}"
:key="index"
:label="item.name"
:value="{ITEM_VALUE}"
/>
</el-select>
</el-form-item>

View File

@ -0,0 +1,12 @@
<el-form-item :label="t('{LOWER_COLUMN_NAME}')" {PROP}>
<el-select v-model="formData.{COLUMN_NAME}" clearable :placeholder="t('{LOWER_COLUMN_NAME}Placeholder')" class="input-width">
<el-option
label="选项1"
value="1"
/>
<el-option
label="选项2"
value="2"
/>
</el-select>
</el-form-item>

View File

@ -12,7 +12,9 @@
{NAMESPACE}
use core\base\BaseModel;
use think\model\concern\SoftDelete;
use think\model\relation\HasMany;
use think\model\relation\HasOne;
/**
* {CLASS_COMMENT}

View File

@ -1,3 +1,4 @@
{COLUMN_NAME}: [
{ required: true, message: t('{VALIDATE_MSG}'), trigger: 'blur' }
{ required: true, message: t('{VALIDATE_MSG}'), trigger: 'blur' },
{VERIFY}
]

View File

@ -1,6 +1,12 @@
<el-form-item :label="t('{LCASE_COLUMN_NAME}')" prop="{COLUMN_NAME}">
<el-select class="" v-model="{LCASE_CLASS_NAME}Table.searchParam.{COLUMN_NAME}" clearable :placeholder="t('{LCASE_COLUMN_NAME}Placeholder')">
<el-option label="全部" value=""></el-option>
<el-form-item :label="t('{LCASE_COLUMN_NAME}')" prop="{COLUMN_NAME}">
<el-select class="w-[280px]" v-model="{LCASE_CLASS_NAME}Table.searchParam.{COLUMN_NAME}" clearable :placeholder="t('{LCASE_COLUMN_NAME}Placeholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in {DICT_TYPE}"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>

View File

@ -0,0 +1,6 @@
<el-form-item :label="t('{LOWER_COLUMN_NAME}')" prop="{COLUMN_NAME}">
<el-select class="" v-model="{LOWER_CLASS_NAME}TableData.searchParam.{COLUMN_NAME}" clearable :placeholder="t('{LOWER_COLUMN_NAME}Placeholder')">
<el-option label="全部" value=""></el-option>
</el-select>
</el-form-item>

View File

@ -88,7 +88,8 @@ class {UCASE_NAME}Service extends BaseAdminService
*/
public function del(int $id)
{
$res = $this->model->where([['{PK}', '=', $id]])->delete();
$model = $this->model->where([['{PK}', '=', $id]])->find();
$res = $model->delete();
return $res;
}

View File

@ -10,13 +10,13 @@
// +----------------------------------------------------------------------
{NAMESPACE}
use core\base\BaseValidate;
/**
* {CLASS_COMMENT}
* Class {UCASE_NAME}
* @package {PACKAGE_NAME}
*/
class {UCASE_NAME} extends \think\Validate
class {UCASE_NAME} extends BaseValidate
{
protected $rule = {RULE};

View File

@ -1,6 +1,7 @@
{IMPORT}
/***************************************************** {NOTES} ****************************************************/
{BEGIN}
/**
* 获取{NOTES}列表
@ -47,4 +48,4 @@ export function edit{UCASE_NAME}(params: Record<string, any>) {
export function delete{UCASE_NAME}({PK}: number) {
return request.delete(`{ROUTE_GROUP_NAME}/{ROUTE_NAME}/${{PK}}`, { showErrorMessage: true, showSuccessMessage: true })
}
{END}

View File

@ -18,8 +18,10 @@
<script lang="ts" setup>
import { ref, reactive, computed } from 'vue'
import { useDictionary } from '@/app/api/dict'
import { t } from '@/lang'
import type { FormInstance } from 'element-plus'
import { add{UCASE_NAME}, edit{UCASE_NAME}, get{UCASE_NAME}Info } from '@/{API_PATH}'
let showDialog = ref(false)
@ -50,7 +52,7 @@ const emit = defineEmits(['complete'])
*/
const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
let save = formData.{PK} ? update{UCASE_NAME} : add{UCASE_NAME}
let save = formData.{PK} ? edit{UCASE_NAME} : add{UCASE_NAME}
await formEl.validate(async (valid) => {
if (valid) {
@ -69,6 +71,9 @@ const confirm = async (formEl: FormInstance | undefined) => {
})
}
// 获取字典数据
{DICT_LIST}
const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData)
loading.value = true
@ -79,9 +84,43 @@ const setFormData = async (row: any = null) => {
})
}
loading.value = false
}
// 验证手机号格式
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
// 验证身份证号
const idCardVerify = (rule: any, value: any, callback: any) => {
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
// 验证邮箱号
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
// 验证请输入整数
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,

View File

@ -25,6 +25,7 @@
<script lang="ts" setup>
import { ref, reactive, computed } from 'vue'
import { t } from '@/lang'
import { useDictionary } from '@/app/api/dict'
import type { FormInstance } from 'element-plus'
import { get{UCASE_NAME}Info,add{UCASE_NAME},edit{UCASE_NAME} } from '@/{API_PATH}';
import { useRoute } from 'vue-router'
@ -53,6 +54,11 @@ const setFormData = async (id:number = 0) => {
if(id) setFormData(id);
const formRef = ref<FormInstance>()
// 选中数据
const selectData = ref<any[]>([])
// 字典数据
{DICT_LIST}
// 表单验证规则
const formRules = computed(() => {
@ -80,6 +86,42 @@ const onSave = async (formEl: FormInstance | undefined) => {
})
}
// 验证手机号格式
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
// 验证身份证号
const idCardVerify = (rule: any, value: any, callback: any) => {
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
// 验证邮箱号
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
// 验证请输入整数
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
const back = () => {
history.back()
}

View File

@ -28,7 +28,7 @@
<el-table-column :label="t('operation')" fixed="right" min-width="120">
<template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
<el-button type="danger" link @click="deleteEvent(row.{PK})">{{ t('delete') }}</el-button>
<el-button type="primary" link @click="deleteEvent(row.{PK})">{{ t('delete') }}</el-button>
</template>
</el-table-column>
@ -48,7 +48,8 @@
<script lang="ts" setup>
import { reactive, ref, watch } from 'vue'
import { t } from '@/lang'
import { get{UCASE_NAME}List, delete{UCASE_NAME} } from '@/{API_PATH}'
import { useDictionary } from '@/app/api/dict'
import { get{UCASE_NAME}List, delete{UCASE_NAME} } from '@{API_PATH}'
import { img } from '@/utils/common'
import { ElMessageBox } from 'element-plus'
{EDIT_PATH}
@ -69,6 +70,11 @@ let {LCASE_CLASS_NAME}Table = reactive({
const searchFormRef = ref<FormInstance>()
// 选中数据
const selectData = ref<any[]>([])
// 字典数据
{DICT_LIST}
/**
* 获取{NOTES}列表
*/

View File

@ -93,7 +93,8 @@ class InstallSystemService extends BaseAdminService
'sort' => $value[ 'sort' ] ?? '',
'status' => 1,
'is_show' => $value[ 'is_show' ] ?? 1,
'source' => MenuDict::SYSTEM
'source' => MenuDict::SYSTEM,
'menu_attr' => $value['menu_attr'] ?? ''
];
$refer = $value;
if (isset($refer[ 'children' ])) {

View File

@ -73,7 +73,7 @@ class WeappVersionService extends BaseAdminService
*/
public function getPage(array $where = [])
{
$field = 'id, version, version_no, desc, create_time, status';
$field = 'id, version, version_no, desc, create_time, status, fail_reason';
$order = 'version_no desc';
$search_model = $this->model->field($field)->order($order)->append(['status_name']);
return $this->pageQuery($search_model);

View File

@ -13,10 +13,224 @@ namespace app\service\core\addon;
use app\model\addon\AddonDevelop;
use app\service\core\niucloud\CoreCloudBaseService;
use core\exception\CommonException;
use core\util\niucloud\CloudService;
use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;
use think\facade\Cache;
/**
*/
class CoreAddonCloudService extends CoreCloudBaseService
{
/**
* 云编译
* @param $addon
* @return void
*/
public function cloudBuild(string $addon) {
// 上传任务key
$task_key = uniqid();
// 此次上传任务临时目录
$temp_dir = runtime_path() . 'backup' . DIRECTORY_SEPARATOR . 'cloud_build' . DIRECTORY_SEPARATOR . $task_key . DIRECTORY_SEPARATOR;
$package_dir = $temp_dir . 'package' . DIRECTORY_SEPARATOR;
dir_mkdir($package_dir);
$compile = (new CoreAddonService())->getAddonConfig($addon)['compile'] ?? [];
$need_build = false;
// 拷贝composer文件
$composer_file = $this->addonPath($addon) . 'package' . DIRECTORY_SEPARATOR . 'composer.json';
if (file_exists($composer_file)) {
file_put_contents($package_dir . 'composer.json', file_get_contents(root_path() . 'composer.json'));
$need_build = true;
}
// 拷贝手机端文件
if (!in_array('wap', $compile)) {
dir_copy($this->root_path . 'uni-app', $package_dir . 'uni-app', exclude_dirs:['node_modules', 'unpackage', 'dist']);
$need_build = true;
}
// 拷贝admin端文件
if (!in_array('admin', $compile)) {
dir_copy($this->root_path . 'admin', $package_dir . 'admin', exclude_dirs:['node_modules', 'dist', '.vscode', '.idea']);
$need_build = true;
}
// 拷贝web端文件
if (!in_array('web', $compile)) {
dir_copy($this->root_path . 'web', $package_dir . 'web', exclude_dirs:['node_modules', '.output', '.nuxt']);
$need_build = true;
}
if ($need_build) {
// 将临时目录下文件生成压缩包
$zip_file = $temp_dir . DIRECTORY_SEPARATOR . 'build.zip';
(new CoreAddonDevelopDownloadService(''))->compressToZip($package_dir, $zip_file);
$install_task = Cache::get('install_task');
$query = [
'authorize_code' => $this->auth_code,
'timestamp' => $install_task['timestamp']
];
(new CloudService())->httpPost('cloud/build?' . http_build_query($query), [
'multipart' => [
[
'name' => 'file',
'contents' => fopen($zip_file, 'r'),
'filename' => 'build.zip'
]
],
]);
// 删除临时文件
del_target_dir($temp_dir, true);
Cache::set('build_success_' . $addon, null);
} else {
(new CoreAddonInstallService($addon))->handleAddonInstall();
}
return true;
}
/**
* 获取编译结果
* @param string $addon
* @return void
*/
public function getBuildLog(string $addon) {
try {
$install_task = Cache::get('install_task');
if (empty($install_task) || !isset($install_task['timestamp'])) return true;
$query = [
'authorize_code' => $this->auth_code,
'timestamp' => $install_task['timestamp']
];
$build_log = (new CloudService())->httpGet('cloud/get_build_logs?' . http_build_query($query));
if (isset($build_log['data']) && isset($build_log['data'][0]) && is_array($build_log['data'][0])) {
$last = end($build_log['data'][0]);
if ($last['code'] == 0) {
(new CoreAddonInstallService($addon))->installExceptionHandle();
throw new CommonException($last['msg']);
}
if ($last['percent'] == 100) {
$build_log['data'][0] = $this->buildSuccess($addon, $build_log['data'][0]);
}
}
return $build_log;
} catch (\Exception $e) {
$install_task = Cache::get('install_task');
$install_task['error'] = $e->getMessage();
Cache::set('install_task', $install_task, 10);
throw new CommonException($e->getMessage());
}
}
/**
* 云编译成功
* @param string $addon
* @return void
*/
public function buildSuccess(string $addon, array $log) {
$query = [
'authorize_code' => $this->auth_code,
];
$chunk_size = 1 * 1024 * 1024;
$cache = Cache::get('build_success_' . $addon);
if (is_null($cache)) {
$response = (new CloudService())->request('HEAD','cloud/build_download?' . http_build_query($query), [
'headers' => ['Range' => 'bytes=0-']
]);
$length = $response->getHeader('Content-range');
$length = (int)explode("/", $length[0])[1];
$step = (int)ceil($length / $chunk_size);
// 下载任务key
$task_key = uniqid();
// 此次下载任务临时目录
$temp_dir = runtime_path() . 'backup' . DIRECTORY_SEPARATOR . 'cloud_build' . DIRECTORY_SEPARATOR . $task_key . DIRECTORY_SEPARATOR;
dir_mkdir($temp_dir);
Cache::set('build_success_' . $addon, ['step' => $step, 'index' => 0, 'length' => $length, 'task_key' => $task_key]);
} else {
$temp_dir = runtime_path() . 'backup' . DIRECTORY_SEPARATOR . 'cloud_build' . DIRECTORY_SEPARATOR . $cache['task_key'] . DIRECTORY_SEPARATOR;
$zip_file = $temp_dir . 'build.zip';
$zip_resource = fopen($zip_file, 'a');
if (($cache['index'] + 1) <= $cache['step']) {
$start = $cache['index'] * $chunk_size;
$end = ($cache['index'] + 1) * $chunk_size;
$end = min($end, $cache['length']);
$response = (new CloudService())->request('GET','cloud/build_download?' . http_build_query($query), [
'headers' => ['Range' => "bytes={$start}-${end}"]
]);
fwrite($zip_resource, $response->getBody());
fclose($zip_resource);
$cache['index'] += 1;
Cache::set('build_success_' . $addon, $cache);
$log[] = ['action' => '编译包下载中,已下载' . round($cache['index'] / $cache['step'] * 100) . '%', 'percent' => '100' ];
} else {
// 解压文件
$zip = new \ZipArchive();
if ($zip->open($zip_file) === true) {
dir_mkdir($temp_dir . 'build');
$zip->extractTo($temp_dir . 'build');
$zip->close();
dir_copy($temp_dir . 'build', root_path());
// 安装插件
(new CoreAddonInstallService($addon))->handleAddonInstall();
// 删除临时文件
@del_target_dir($temp_dir, true);
Cache::set('build_success_' . $addon, null);
} else {
Cache::set('build_success_' . $addon, null);
// 调用插件安装异常处理
(new CoreAddonInstallService($addon))->installExceptionHandle();
throw new CommonException('Zip decompression failed');
}
}
}
return $log;
}
/**
* 下载插件
* @param string $addon
* @param string $version
* @return void
*/
public function downloadAddon(string $addon, string $version) {
$query = [
'authorize_code' => $this->auth_code,
'addon_name' => $addon,
'addon_version' => $version
];
// 获取文件大小
$response = (new CloudService())->request('HEAD','cloud/build_download?' . http_build_query($query), [
'headers' => ['Range' => 'bytes=0-']
]);
$length = $response->getHeader('Content-range');
$temp_dir = runtime_path() . 'backup' . DIRECTORY_SEPARATOR . 'addon_download' . DIRECTORY_SEPARATOR . uniqid() . DIRECTORY_SEPARATOR;
$zip_file = $temp_dir . $addon . '.zip';
$zip_resource = fopen($zip_file, 'W');
$response = (new CloudService())->request('GET','cloud/download?' . http_build_query($query), [
'headers' => ['Range' => "bytes=0-${$length}"]
]);
fwrite($zip_resource, $response->getBody());
fclose($zip_resource);
return $zip_file;
}
}

View File

@ -41,21 +41,20 @@ class CoreAddonDownloadService extends CoreAddonBaseService
* @throws GuzzleException
* @throws GuzzleException
*/
public function download($app_key)
public function download($app_key, $version)
{
$app_path = $this->addon_path . $app_key . DIRECTORY_SEPARATOR;
//先判断当前的应用在本地是否存在
// if(is_dir($app_path)) throw new NiucloudException();
$app_download_path = $this->addon_download_path . $app_key . DIRECTORY_SEPARATOR;
//下载文件到本地
$zip_file = (new CoreModuleService())->downloadModule($app_key, $app_download_path);
$zip_file = (new CoreAddonCloudService())->downloadAddon($app_key, $version);
//解压到应用addon下
//删除旧版本文件
del_target_dir($app_path, true);
//解压文件
$this->unzip($zip_file, $this->addon_path);
//删除压缩包
@unlink($zip_file);
@del_target_dir(dirname($zip_file), true);
return true;
}

View File

@ -76,11 +76,10 @@ class CoreAddonInstallService extends CoreAddonBaseService
private $install_addon_path;
private $state;
// 安装任务
private $task = [];
private $cache_key = '';
private $install_task = null;
public function __construct($addon)
{
parent::__construct();
@ -88,7 +87,8 @@ class CoreAddonInstallService extends CoreAddonBaseService
$this->install_addon_path = $this->addon_path . $addon . DIRECTORY_SEPARATOR;
$this->cache_key = "install_{$addon}";
$this->task = Cache::get($this->cache_key, []);
$this->install_task = Cache::get('install_task');
}
/**
@ -137,10 +137,7 @@ class CoreAddonInstallService extends CoreAddonBaseService
'is_readable' => [],
// 要求可写权限
'is_write' => []
],
// 运行环境检测
'runtime' => [],
'job_normal' => (new SystemService())->checkJob(),
]
];
if (is_dir($from_admin_dir)) $data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', $from_admin_dir), 'status' => is_readable($from_admin_dir)];
@ -155,9 +152,7 @@ class CoreAddonInstallService extends CoreAddonBaseService
$check_res = array_merge(
array_column($data['dir']['is_readable'], 'status'),
array_column($data['dir']['is_write'], 'status'),
array_column($data['runtime'], 'status'),
[$data['job_normal']]
array_column($data['dir']['is_write'], 'status')
);
// 是否通过校验
@ -167,97 +162,85 @@ class CoreAddonInstallService extends CoreAddonBaseService
}
/**
*
* 插件安装
* @return true
*/
public function executeInstall()
public function install(string $mode = 'local')
{
if (empty($this->task)) throw new CommonException('ADDON_INSTALL_NOT_EXIST');
$core_addon_service = new CoreAddonService();
if (!empty($core_addon_service->getInfoByKey($this->addon))) throw new AddonException('REPEAT_INSTALL');
$install_data = $this->getAddonConfig($this->addon);
if (empty($install_data)) throw new AddonException('ADDON_INFO_FILE_NOT_EXIST');
$check_res = Cache::get($this->cache_key . '_install_check');
if (!$check_res) throw new CommonException('INSTALL_CHECK_NOT_PASS');
if ($this->task['installDir']['state'] == AddonDict::INSTALL_UNEXECUTED) AddonInstall::invoke(['addon' => $this->addon, 'task' => 'installDir']);
return true;
}
/**
* 执行任务
* @param string $task
* @return Response
*/
public function executeTask(string $task)
{
if (empty($this->task) || !isset($this->task[$task])) throw new CommonException('ADDON_INSTALL_NOT_EXIST');
if ($this->task[$task]['state'] != AddonDict::INSTALL_UNEXECUTED) throw new CommonException('ADDON_INSTALL_EXECUTED');
$this->setTaskState($task, AddonDict::INPROGRESS);
if ($this->install_task) throw new CommonException('ADDON_INSTALLING');
$this->install_task = [ 'mode' => $mode, 'addon' => $this->addon, 'step' => [], 'timestamp' => time() ];
Cache::set('install_task', $this->install_task);
set_time_limit(0);
$result = Terminal::execute(root_path(), $this->task[$task]['command']);
$install_step = ['installDir','installSql','installMenu','installSchedule','installWap','installDepend'];
// 变更任务状态
if ($result === true) {
if ($task != 'installComplete') {
$this->setTaskState($task, AddonDict::INSTALL_SUCCESS);
$task_key = array_keys($this->task);
AddonInstall::invoke(['addon' => $this->addon, 'task' => $task_key[array_search($task, $task_key) + 1]]);
} else {
// 设置任务缓存30秒后失效
$this->setTaskState($task, AddonDict::INSTALL_SUCCESS, '', 30);
if (!empty($install_data['compile']) || $mode == 'cloud') {
// 备份前端目录
$install_step[] = 'backupFrontend';
}
} else {
if (in_array($task, ['updateComposer', 'updateAdminDependencies', 'updateWapDependencies', 'updateWebDependencies'])) {
$warn = [
'updateComposer' => '在线更新composer依赖执行失败请在项目niucloud目录下执行 composer update命令手动更新依赖',
'updateAdminDependencies' => '在线更新admin端依赖执行失败请在项目admin目录下执行 npm install 命令手动更新依赖',
'updateWapDependencies' => '在线更新wap端依赖执行失败请在项目uni-app目录下执行 npm install 命令手动更新依赖',
'updateWebDependencies' => '在线更新web端依赖执行失败请在项目web目录下执行 npm install 命令手动更新依赖'
];
$this->setTaskState($task, AddonDict::INSTALL_WARN, $warn[$task]);
$task_key = array_keys($this->task);
AddonInstall::invoke(['addon' => $this->addon, 'task' => $task_key[array_search($task, $task_key) + 1]]);
} else {
// 设置任务缓存30秒后失效
$this->setTaskState($task, AddonDict::INSTALL_FAIL, $result, 30);
// 检测插件是否存在编译内容
if (!empty($install_data['compile'])) {
$install_step[] = 'coverCompile';
}
if ($mode == 'cloud') {
$install_step[] = 'cloudInstall';
} else {
$install_step[] = 'handleAddonInstall';
}
try {
foreach ($install_step as $step) {
$this->install_task['step'][] = $step;
$this->$step();
}
if ($mode == 'cloud') Cache::set('install_task', $this->install_task);
return true;
} catch (\Exception $e) {
Cache::set('install_task', null);
throw new CommonException($e->getMessage());
}
return $result;
}
/**
* 设置任务执行状态
* @param string $task
* @param string $state
* @param $error
* @param int|null $ttl
* 安装异常处理
* @return void
*/
public function setTaskState(string $task, string $state, $error = '', $ttl = null)
{
$this->task[$task]['state'] = $state;
if (!empty($error)) $this->task[$task]['error'] = $error;
Cache::set($this->cache_key, $this->task, $ttl);
public function installExceptionHandle() {
$install_task = Cache::get('install_task');
if (in_array('installDir', $install_task['step'])) {
@$this->uninstallDir();
}
if (in_array('installMenu', $install_task['step'])) {
@$this->uninstallMenu();
}
if ($install_task['mode'] == 'cloud') {
$this->revertFrontendBackup();
}
Cache::set('install_task', null);
}
/**
* 获取安装任务
* @return array
* @return mixed
*/
public function getTask()
{
return $this->task;
}
/**
* 获取任务执行状态
* @param string $key
* @return array|mixed
*/
public function getInstallState(string $key)
{
return $this->task[$key] ?? [];
public function getInstallTask() {
return $this->install_task;
}
/**
@ -389,129 +372,11 @@ class CoreAddonInstallService extends CoreAddonBaseService
if (class_exists($class)) {
(new $class())->install();
}
// 清除插件安装中标识
Cache::delete('install_task');
return true;
}
/**
* 插件安装
* @return true
*/
public function install()
{
$core_addon_service = new CoreAddonService();
if (!empty($core_addon_service->getInfoByKey($this->addon))) throw new AddonException('REPEAT_INSTALL');
if (!empty($this->task)) return $this->task;
// 配置文件
$package_path = $this->install_addon_path . 'package' . DIRECTORY_SEPARATOR;
$package_file = [];
search_dir($package_path, $package_file);
$package_file = array_map(function ($file) use ($package_path) {
return str_replace($package_path . DIRECTORY_SEPARATOR, '', $file);
}, $package_file);
$this->task = [
'installDir' => [
'addon' => $this->addon,
'step' => 'installDir',
'command' => "php think addon:install {$this->addon} --step installDir",
'desc' => '复制插件文件',
'state' => AddonDict::INSTALL_UNEXECUTED
],
'installSql' => [
'addon' => $this->addon,
'step' => 'installSql',
'command' => "php think addon:install {$this->addon} --step installSql",
'desc' => '执行插件sql',
'state' => AddonDict::INSTALL_UNEXECUTED
],
'installMenu' => [
'addon' => $this->addon,
'step' => 'installMenu',
'command' => "php think addon:install {$this->addon} --step installMenu",
'desc' => '安装插件菜单',
'state' => AddonDict::INSTALL_UNEXECUTED
],
'installSchedule' => [//安装计划任务
'addon' => $this->addon,
'step' => 'installSchedule',
'command' => "php think addon:install {$this->addon} --step installSchedule",
'desc' => '安装插件计划任务',
'state' => AddonDict::INSTALL_UNEXECUTED
],
'installWap' => [
'addon' => $this->addon,
'step' => 'installWap',
'command' => "php think addon:install {$this->addon} --step installWap",
'desc' => '安装插件手机端',
'state' => AddonDict::INSTALL_UNEXECUTED
],
'handleAddonInstall' => [
'addon' => $this->addon,
'step' => 'handleAddonInstall',
'command' => "php think addon:install {$this->addon} --step handleAddonInstall",
'desc' => '执行插件安装方法',
'state' => AddonDict::INSTALL_UNEXECUTED
],
'installDepend' => [
'addon' => $this->addon,
'step' => 'installDepend',
'command' => "php think addon:install {$this->addon} --step installDepend",
'desc' => '合并依赖文件',
'state' => AddonDict::INSTALL_UNEXECUTED
]
];
if (in_array('composer.json', $package_file)) {
$this->task['updateComposer'] = [
'addon' => $this->addon,
'step' => 'updateComposer',
'command' => "php think addon:install {$this->addon} --step updateComposer",
'desc' => '更新composer依赖',
'state' => AddonDict::INSTALL_UNEXECUTED
];
}
if (in_array('admin-package.json', $package_file)) {
$this->task['updateAdminDependencies'] = [
'addon' => $this->addon,
'step' => 'updateAdminDependencies',
'command' => "php think addon:install {$this->addon} --step updateAdminDependencies",
'desc' => '更新admin端依赖',
'state' => AddonDict::INSTALL_UNEXECUTED
];
}
if (in_array('uni-app-package.json', $package_file)) {
$this->task['updateWapDependencies'] = [
'addon' => $this->addon,
'step' => 'updateWapDependencies',
'command' => "php think addon:install {$this->addon} --step updateWapDependencies",
'desc' => '更新wap端依赖',
'state' => AddonDict::INSTALL_UNEXECUTED
];
}
if (in_array('web-package.json', $package_file)) {
$this->task['updateWebDependencies'] = [
'addon' => $this->addon,
'step' => 'updateWebDependencies',
'command' => "php think addon:install {$this->addon} --step updateWebDependencies",
'desc' => '更新web端依赖',
'state' => AddonDict::INSTALL_UNEXECUTED
];
}
$this->task['installComplete'] = [
'addon' => $this->addon,
'step' => 'installComplete',
'command' => "php think addon:install {$this->addon} --step installComplete",
'desc' => '安装完成',
'state' => AddonDict::INSTALL_UNEXECUTED
];
Cache::set($this->cache_key, $this->task);
return $this->task;
}
/**
* 合并依赖
* @return void
@ -521,6 +386,66 @@ class CoreAddonInstallService extends CoreAddonBaseService
(new CoreDependService())->installDepend($this->addon);
}
/**
* 备份前端页面
* @return void
*/
public function backupFrontend() {
$backup_dir = runtime_path() . 'backup' . DIRECTORY_SEPARATOR . 'frontend' . DIRECTORY_SEPARATOR;
if (is_dir($backup_dir)) del_target_dir($backup_dir, true);
foreach (['admin', 'wap', 'web'] as $port) {
$to_dir = public_path() . $port;
if (is_dir($to_dir)) {
if (is_dir($backup_dir . $port)) del_target_dir($backup_dir . $port, true);
// 备份原目录
dir_copy($to_dir, $backup_dir . $port);
}
}
}
/**
* 还原被覆盖前的文件
* @return void
*/
public function revertFrontendBackup() {
$backup_dir = runtime_path() . 'backup' . DIRECTORY_SEPARATOR . 'frontend' . DIRECTORY_SEPARATOR;
$backup_file = [];
search_dir($backup_dir, $backup_file);
if (!empty($backup_file)) {
dir_copy(public_path(), $backup_dir);
@del_target_dir($backup_dir, true);
}
}
/**
* 插件编译文件覆盖
* @return void
*/
public function coverCompile() {
$compile = $this->getAddonConfig($this->addon)['compile'];
foreach ($compile as $port) {
$to_dir = public_path() . $port;
$from_dir = $this->addon_path . 'compile' . DIRECTORY_SEPARATOR . $port;
if (is_dir($from_dir) && is_dir($to_dir)) {
// 删除后覆盖目录
del_target_dir($to_dir, true);
dir_copy($from_dir, $to_dir . $port);
}
}
}
/**
* 云安装
* @return void
*/
public function cloudInstall() {
(new CoreAddonCloudService())->cloudBuild($this->addon);
}
/**
* 卸载插件
* @return true
@ -533,7 +458,8 @@ class CoreAddonInstallService extends CoreAddonBaseService
(new $class())->uninstall();
}
$core_addon_service = new CoreAddonService();
if (empty($core_addon_service->getInfoByKey($this->addon))) throw new AddonException('NOT_UNINSTALL');
$addon_info = $core_addon_service->getInfoByKey($this->addon);
if (empty($addon_info)) throw new AddonException('NOT_UNINSTALL');
if (!$this->uninstallSql()) throw new AddonException('ADDON_SQL_FAIL');
if (!$this->uninstallDir()) throw new AddonException('ADDON_DIR_FAIL');
@ -546,6 +472,9 @@ class CoreAddonInstallService extends CoreAddonBaseService
// 卸载wap
$this->uninstallWap();
// 还原备份
if (!empty($addon_info['compile'])) (new CoreAddonCompileHandleService())->revertBackup();
$core_addon_service = new CoreAddonService();
$core_addon_service->delByKey($this->addon);
Cache::set("local_install_addons", []);

View File

@ -274,7 +274,12 @@ class CoreAddonService extends CoreAddonBaseService
$data['cover'] = is_file($data['icon']) ? image_to_base64($data['cover']) : '';
$data['type_name'] = empty($data['type']) ? '' : AddonDict::getType()[$data['type']] ?? '';
}
if(isset($data['support_app']) && !empty($data['support_app']))
{
$data['support_type'] = 2;
}else{
$data['support_type'] = 1;
}
return $data;
}
}

View File

@ -373,9 +373,16 @@ trait WapTrait
foreach ($file_arr as $ck => $cv) {
if (str_contains($cv, '.json')) {
$app_json = @file_get_contents($ck);
$json = json_decode($app_json, true);
// 清空当前安装/卸载的插件语言包
foreach ($json as $jk => $jc) {
if (strpos($jk, $addon) !== false) {
unset($json[ $jk ]);
}
}
$locale_data[ $cv ] = [
'path' => $ck,
'json' => json_decode($app_json, true)
'json' => $json
];
}
}

View File

@ -5,6 +5,7 @@
<script setup lang="ts">
import { ref } from 'vue';
import { getHelloWorld } from '@/{key}/api/hello_world';
import { onLoad } from '@dcloudio/uni-app';
let hello_world_text = ref('');
onLoad(() => {
getHelloWorld().then((res) => {

View File

@ -7,15 +7,9 @@ import { ref } from 'vue'
import { getHelloWorld } from '@/{key}/api/hello_world'
const hello_world_text = ref('');
onMounted(() => {
getHelloWorldInfo()
});
const getHelloWorldInfo = () => {
getHelloWorld().then(res => {
hello_world_text.value = res.data;
})
}
</script>
<style lang="scss" scoped></style>

View File

@ -32,11 +32,19 @@ class CoreAuthService extends BaseNiucloudClient
{
$auth_info = $this->httpGet('authinfo', ['code' => $this->code, 'secret' => $this->secret]);
if(!empty($auth_info['data'])){
$auth_info['data']['address_type'] = true;
if($auth_info['data']['site_address'] != $_SERVER['HTTP_HOST']) $auth_info['data']['address_type'] = false;
$auth_info['data']['address_type'] = $this->diffDomain($_SERVER['HTTP_HOST'], $auth_info['data']['site_address']);
}
return $auth_info;
}
public function diffDomain($domain, $child_domain){
$child_domain = str_replace('http://', '', $child_domain);
$child_domain = str_replace('https://', '', $child_domain);
if($domain == $child_domain)
return true;
if( strstr($child_domain, $domain) === false )
return false;
return true;
}
}

View File

@ -63,7 +63,6 @@ class CoreWeappCloudService extends CoreCloudBaseService
(new CoreAddonDevelopDownloadService(''))->compressToZip($package_dir, $zip_file);
$query = [
'action' => 'wechat',
'compile' => $compile_addon->isEmpty() ? 0 : 1,
'authorize_code' => $this->auth_code,
'appid' => $config['app_id'],
@ -71,16 +70,19 @@ class CoreWeappCloudService extends CoreCloudBaseService
'desc' => $data['desc'] ?? '',
'do' => 1
];
(new CloudService())->httpPost('cloud?' . http_build_query($query), [
(new CloudService())->httpPost('cloud/wechat?' . http_build_query($query), [
'multipart' => [
[
'name' => 'weapp',
'name' => 'file',
'contents' => fopen($zip_file, 'r'),
'filename' => 'weapp.zip'
]
],
]);
// 删除临时文件
del_target_dir(runtime_path() . 'backup' . DIRECTORY_SEPARATOR . 'weapp', true);
return ['key' => $task_key];
}
@ -121,9 +123,8 @@ class CoreWeappCloudService extends CoreCloudBaseService
*/
public function getWeappPreviewImage() {
$query = [
'action' => 'get_wechat_preview',
'authorize_code' => $this->auth_code,
];
return (new CloudService())->httpGet('cloud?' . http_build_query($query));
return (new CloudService())->httpGet('cloud/get_wechat_preview?' . http_build_query($query));
}
}

View File

@ -12,12 +12,13 @@
namespace app\validate\addon;
use app\dict\addon\AddonDict;
use core\base\BaseValidate;
use think\Validate;
/**
* 开发插件
*/
class AddonDevelop extends Validate
class AddonDevelop extends BaseValidate
{

View File

@ -11,12 +11,13 @@
namespace app\validate\channel;
use core\base\BaseValidate;
use think\Validate;
/**
* 支付宝小程序配置验证类
*/
class Aliapp extends Validate
class Aliapp extends BaseValidate
{
//用户名或密码的规范可能是从数据库中获取的

View File

@ -11,12 +11,13 @@
namespace app\validate\channel;
use core\base\BaseValidate;
use think\Validate;
/**
* 微信小程序配置验证类
*/
class Weapp extends Validate
class Weapp extends BaseValidate
{
//用户名或密码的规范可能是从数据库中获取的

View File

@ -11,12 +11,13 @@
namespace app\validate\channel;
use core\base\BaseValidate;
use think\Validate;
/**
* 微信配置验证类
*/
class Wechat extends Validate
class Wechat extends BaseValidate
{
//用户名或密码的规范可能是从数据库中获取的

View File

@ -0,0 +1,41 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\validate\dict;
use core\base\BaseValidate;
/**
* 数据字典验证器
* Class Dict
* @package addon\app\validate\dict
*/
class Dict extends BaseValidate
{
protected $rule = [
'name' => 'require',
'key' => 'require',
'data' => 'require',
'memo' => 'require',
];
protected $message = [
'name.require' => ['common_validate.require', ['name']],
'key.require' => ['common_validate.require', ['key']],
'data.require' => ['common_validate.require', ['data']],
'memo.require' => ['common_validate.require', ['memo']],
];
protected $scene = [
"add" => ['name', 'key', 'data', 'memo'],
"edit" => ['name', 'key', 'data', 'memo']
];
}

View File

@ -11,6 +11,7 @@
namespace app\validate\diy;
use core\base\BaseValidate;
use think\Validate;
/**
@ -18,7 +19,7 @@ use think\Validate;
* Class Diy
* @package app\validate\diy
*/
class Diy extends Validate
class Diy extends BaseValidate
{
protected $rule = [

View File

@ -11,6 +11,7 @@
namespace app\validate\diy;
use core\base\BaseValidate;
use think\Validate;
/**
@ -18,7 +19,7 @@ use think\Validate;
* Class DiyRoute
* @package app\validate\diy
*/
class DiyRoute extends Validate
class DiyRoute extends BaseValidate
{
protected $rule = [

View File

@ -12,6 +12,7 @@
namespace app\validate\generator;
use core\base\BaseValidate;
use think\Validate;
/**
@ -19,7 +20,7 @@ use think\Validate;
* Class Generator
* @package app\validate\generator
*/
class Generator extends Validate
class Generator extends BaseValidate
{
protected $rule = [

View File

@ -13,12 +13,13 @@ namespace app\validate\member;
use app\dict\member\MemberAccountTypeDict;
use app\dict\pay\TransferDict;
use core\base\BaseValidate;
use think\Validate;
/**
* 提现验证类
*/
class CashOut extends Validate
class CashOut extends BaseValidate
{
protected $rule = [
'apply_money' => 'min:0.01', // 提现金额

View File

@ -12,12 +12,13 @@
namespace app\validate\member;
use app\dict\pay\TransferDict;
use core\base\BaseValidate;
use think\Validate;
/**
* 提现账号验证类
*/
class CashOutAccount extends Validate
class CashOutAccount extends BaseValidate
{
protected $rule = [
'account_type' => 'checkAccountType',

View File

@ -11,12 +11,13 @@
namespace app\validate\member;
use core\base\BaseValidate;
use think\Validate;
/**
* 提现设置验证类
*/
class CashOutConfig extends Validate
class CashOutConfig extends BaseValidate
{

View File

@ -11,6 +11,7 @@
namespace app\validate\member;
use core\base\BaseValidate;
use think\Validate;
/**
@ -18,7 +19,7 @@ use think\Validate;
* Class LoginConfig
* @package app\validate\member
*/
class LoginConfig extends Validate
class LoginConfig extends BaseValidate
{

View File

@ -13,6 +13,7 @@ namespace app\validate\member;
use app\dict\common\CommonDict;
use app\dict\member\MemberDict;
use core\base\BaseValidate;
use think\facade\Lang;
use think\Validate;
@ -21,7 +22,7 @@ use think\Validate;
* Class Member
* @package app\validate\member
*/
class Member extends Validate
class Member extends BaseValidate
{

View File

@ -11,6 +11,7 @@
namespace app\validate\member;
use core\base\BaseValidate;
use think\facade\Lang;
use think\Validate;
@ -19,7 +20,7 @@ use think\Validate;
* Class LoginConfig
* @package app\validate\member
*/
class MemberConfig extends Validate
class MemberConfig extends BaseValidate
{
protected $rule = [
'length' => 'number|checkLength'

View File

@ -11,6 +11,7 @@
namespace app\validate\member;
use core\base\BaseValidate;
use think\Validate;
/**
@ -18,7 +19,7 @@ use think\Validate;
* Class Member
* @package app\validate\member
*/
class MemberLabel extends Validate
class MemberLabel extends BaseValidate
{

View File

@ -11,12 +11,13 @@
namespace app\validate\niucloud;
use core\base\BaseValidate;
use think\Validate;
/**
* 提现验证类
*/
class Module extends Validate
class Module extends BaseValidate
{
protected $rule = [
'auth_code' => 'require',

View File

@ -12,6 +12,7 @@
namespace app\validate\pay;
use app\dict\pay\PayDict;
use core\base\BaseValidate;
use think\facade\Lang;
use think\Validate;
@ -19,7 +20,7 @@ use think\Validate;
* Class Pay
* @package app\validate\pay
*/
class Pay extends Validate
class Pay extends BaseValidate
{
//用户名或密码的规范可能是从数据库中获取的

View File

@ -12,6 +12,7 @@
namespace app\validate\pay;
use app\dict\pay\PayDict;
use core\base\BaseValidate;
use think\facade\Lang;
use think\Validate;
@ -19,7 +20,7 @@ use think\Validate;
* Class PayTemplate
* @package app\validate\pay
*/
class PayTemplate extends Validate
class PayTemplate extends BaseValidate
{
//用户名或密码的规范可能是从数据库中获取的

View File

@ -11,6 +11,7 @@
namespace app\validate\site;
use core\base\BaseValidate;
use think\Validate;
/**
@ -18,7 +19,7 @@ use think\Validate;
* Class Site
* @package app\validate\site
*/
class Site extends Validate
class Site extends BaseValidate
{

View File

@ -12,6 +12,7 @@
namespace app\validate\sys;
use core\base\BaseValidate;
use think\Validate;
/**
@ -19,7 +20,7 @@ use think\Validate;
* Class Agreement
* @package app\validate\sys
*/
class Agreement extends Validate
class Agreement extends BaseValidate
{
protected $rule = [

View File

@ -12,6 +12,7 @@
namespace app\validate\sys;
use app\dict\sys\FileDict;
use core\base\BaseValidate;
use think\facade\Lang;
use think\Validate;
@ -20,7 +21,7 @@ use think\Validate;
* Class AttachmentCategory
* @package app\validate\sys
*/
class AttachmentCategory extends Validate
class AttachmentCategory extends BaseValidate
{
protected $rule = [

View File

@ -13,6 +13,7 @@ namespace app\validate\sys;
use app\dict\sys\MenuTypeDict;
use app\dict\sys\MethodDict;
use core\base\BaseValidate;
use think\facade\Lang;
use think\Validate;
@ -20,7 +21,7 @@ use think\Validate;
* Class Menu
* @package app\validate\sys
*/
class Menu extends Validate
class Menu extends BaseValidate
{
//用户名或密码的规范可能是从数据库中获取的

View File

@ -11,6 +11,7 @@
namespace app\validate\sys;
use core\base\BaseValidate;
use think\Validate;
/**
@ -18,7 +19,7 @@ use think\Validate;
* Class Page
* @package app\validate\sys
*/
class Page extends Validate
class Page extends BaseValidate
{
protected $rule = [

View File

@ -11,13 +11,14 @@
namespace app\validate\sys;
use core\base\BaseValidate;
use think\Validate;
/**
* Class Role
* @package app\validate\sys
*/
class Role extends Validate
class Role extends BaseValidate
{
//用户名或密码的规范可能是从数据库中获取的

View File

@ -12,13 +12,14 @@
namespace app\validate\sys;
use app\service\core\schedule\CoreScheduleService;
use core\base\BaseValidate;
use think\facade\Lang;
use think\Validate;
/**
* Class Schedule
*/
class Schedule extends Validate
class Schedule extends BaseValidate
{
//用户名或密码的规范可能是从数据库中获取的

View File

@ -11,13 +11,14 @@
namespace app\validate\sys;
use core\base\BaseValidate;
use think\Validate;
/**
* Class User
* @package app\validate\sys
*/
class User extends Validate
class User extends BaseValidate
{
//用户名或密码的规范可能是从数据库中获取的

View File

@ -29,7 +29,7 @@
"topthink/think-image": "v1.0.7",
"topthink/think-queue": "v3.0.7",
"firebase/php-jwt": "v5.5.1",
"overtrue/wechat": "v5.30.0",
"w7corp/easywechat": "v5.30.0",
"spatie/macroable": "v1.0.1",
"dh2y/think-qrcode": "v2.0",
"dragonmantank/cron-expression": "v3.3.1",

View File

@ -0,0 +1,46 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace core\base;
use think\Validate;
/**
* 验证器器基类
* Class BaseValidate
* @package core\base
*/
class BaseValidate extends Validate
{
public function __construct()
{
parent::__construct();
$this->parseMsg();
}
public function parseMsg(){
if(!empty($this->message))
{
foreach ($this->message as $key => $value)
{
if(is_array($value))
{
$this->message[$key] = get_lang($value[0], $value[1]);
}
}
}
}
}

View File

@ -4,6 +4,7 @@ namespace core\util\niucloud;
use core\util\niucloud\http\HasHttpRequests;
use GuzzleHttp\Client;
/**
* niucloud云服务
@ -12,7 +13,7 @@ class CloudService
{
use HasHttpRequests;
private $baseUri = 'http://8.140.96.55:8888/';
private $baseUri = 'http://8.140.96.55:8000/';
public function httpPost(string $url, array $options = []) {
return $this->toRequest($url, 'POST', $options);
@ -21,4 +22,8 @@ class CloudService
public function httpGet(string $url, array $options = []) {
return $this->toRequest($url, 'GET', $options);
}
public function request(string $method, string $url, array $options = []) {
return (new Client(['base_uri' => $this->baseUri ]))->request($method, $url, $options);
}
}

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -12,6 +12,7 @@ use think\facade\Route;
use think\facade\Request;
Route::domain('install.php', ':\app\install\controller');
// 访问首页自动跳转到admin
Route::rule('/', function() {
if (Request::isMobile()) {
@ -20,26 +21,32 @@ Route::rule('/', function () {
return redirect('/web');
}
});
// 管理后台
Route::rule('admin/:any', function() {
return view(app()->getRootPath() . 'public/admin/index.html');
})->pattern([ 'any' => '\w+' ]);
// 站点端
Route::rule('site/:any', function() {
return view(app()->getRootPath() . 'public/admin/index.html');
})->pattern([ 'any' => '\w+' ]);
// 装修端
Route::rule('decorate/:any', function() {
return view(app()->getRootPath() . 'public/admin/index.html');
})->pattern([ 'any' => '\w+' ]);
// 手机端
Route::rule('wap/:any', function() {
return view(app()->getRootPath() . 'public/wap/index.html');
})->pattern([ 'any' => '\w+' ]);
// 电脑端
Route::rule('web/:any', function() {
return view(app()->getRootPath() . 'public/web/index.html');
})->pattern([ 'any' => '\w+' ]);
//用于公众号授权证书
Route::any('MP_verify_<name>.txt', function($name) {
echo $name;