diff --git a/app/admin/controller/Design.php b/app/admin/controller/Design.php index 8ce5f70af..ce80a6fc6 100644 --- a/app/admin/controller/Design.php +++ b/app/admin/controller/Design.php @@ -13,6 +13,7 @@ namespace app\admin\controller; use app\service\DesignService; use app\service\GoodsService; use app\service\BrandService; +use app\service\StoreService; use app\layout\service\BaseLayout; /** @@ -76,6 +77,9 @@ class Design extends Common ]; $ret = DesignService::DesignList($data_params); + // 应用商店 + MyViewAssign('store_design_url', StoreService::StoreDesignUrl()); + // 基础参数赋值 MyViewAssign('params', $this->data_request); MyViewAssign('page_html', $page->GetPageHtml()); @@ -163,6 +167,24 @@ class Design extends Common return MyView(); } + /** + * 下载 + * @author Devil + * @blog http://gong.gg/ + * @version 1.0.0 + * @date 2022-04-17 + * @desc description + */ + public function Download() + { + $ret = DesignService::DesignDownload($this->data_request); + if(isset($ret['code']) && $ret['code'] != 0) + { + MyViewAssign('msg', $ret['msg']); + return MyView('public/tips_error'); + } + } + /** * 保存 * @author Devil @@ -222,5 +244,45 @@ class Design extends Common // 开始操作 return DesignService::DesignDelete($this->data_post); } + + /** + * 同步到首页 + * @author Devil + * @blog http://gong.gg/ + * @version 1.0.0 + * @date 2022-04-19 + * @desc description + */ + public function Sync() + { + // 是否ajax请求 + if(!IS_AJAX) + { + $this->error('非法访问'); + } + + // 开始操作 + return DesignService::DesignSync($this->data_post); + } + + /** + * 导入 + * @author Devil + * @blog http://gong.gg/ + * @version 1.0.0 + * @date 2022-04-19 + * @desc description + */ + public function Upload() + { + // 是否ajax请求 + if(!IS_AJAX) + { + $this->error('非法访问'); + } + + // 开始操作 + return DesignService::DesignUpload($this->data_request); + } } ?> \ No newline at end of file diff --git a/app/admin/form/Design.php b/app/admin/form/Design.php index 79be7c28f..3a9443489 100644 --- a/app/admin/form/Design.php +++ b/app/admin/form/Design.php @@ -44,6 +44,7 @@ class Design 'is_delete' => 1, 'delete_url' => MyUrl('admin/design/delete'), 'delete_key' => 'ids', + 'is_middle' => 0, ], // 表单配置 'form' => [ @@ -55,6 +56,17 @@ class Design 'align' => 'center', 'width' => 80, ], + [ + 'label' => '数据ID', + 'view_type' => 'field', + 'view_key' => 'id', + 'width' => 105, + 'is_sort' => 1, + 'search_config' => [ + 'form_type' => 'input', + 'where_type' => '=', + ], + ], [ 'label' => '基础信息', 'view_type' => 'module', diff --git a/app/admin/form/Payment.php b/app/admin/form/Payment.php index 431113325..d2f770051 100644 --- a/app/admin/form/Payment.php +++ b/app/admin/form/Payment.php @@ -39,6 +39,7 @@ class Payment 'base' => [ 'key_field' => 'payment', 'status_field' => 'is_enable', + 'is_middle' => 0, ], // 表单配置 'form' => [ diff --git a/app/admin/view/default/design/index.html b/app/admin/view/default/design/index.html index 3fedceab3..b975201d1 100644 --- a/app/admin/view/default/design/index.html +++ b/app/admin/view/default/design/index.html @@ -3,7 +3,43 @@ {{block name="form_operate_top"}} + 新增 {__block__} + 更多设计模板下载 +{{/block}} + + +{{block name="form_extend"}} + + + {{/block}} \ No newline at end of file diff --git a/app/admin/view/default/design/module/operate.html b/app/admin/view/default/design/module/operate.html index 8820d0fe1..d7539d7a7 100644 --- a/app/admin/view/default/design/module/operate.html +++ b/app/admin/view/default/design/module/operate.html @@ -4,6 +4,14 @@ 查看 + + + + 下载 + 编辑 diff --git a/app/admin/view/default/payment/index.html b/app/admin/view/default/payment/index.html index b3eb76772..428c3c4d2 100755 --- a/app/admin/view/default/payment/index.html +++ b/app/admin/view/default/payment/index.html @@ -3,7 +3,7 @@ {{block name="form_operate_top"}} - + 更多支付插件下载 {__block__} @@ -21,7 +21,7 @@
-
+

1 类名必须于文件名一致(去除 .php ),如 Alipay.php 则取 Alipay

2 类必须定义的方法

2.1 Config 配置方法

@@ -32,7 +32,7 @@

3 可自定义输出内容方法

3.1 SuccessReturn 支付成功(可选)

3.2 ErrorReturn 支付失败(可选)

-

PS:以上条件不满足则无法查看插件,将插件放入.zip压缩包中上传、支持一个压缩中包含多个支付插件

+

PS:以上条件不满足则无法查看插件,将插件放入.zip压缩包中上传、支持一个压缩中包含多个支付插件

diff --git a/app/index/controller/Design.php b/app/index/controller/Design.php index bdf7ddd35..e2c0ebb47 100644 --- a/app/index/controller/Design.php +++ b/app/index/controller/Design.php @@ -37,7 +37,7 @@ class Design extends Common } /** - * 状态更新 + * 详情 * @author Devil * @blog http://gong.gg/ * @version 1.0.0 @@ -51,7 +51,8 @@ class Design extends Common { $data_params = [ 'where' => [ - 'id' => intval($this->data_request['id']), + ['id', '=', intval($this->data_request['id'])], + ['is_enable', '=', 1], ], 'm' => 0, 'n' => 1, diff --git a/app/layout/service/BaseLayout.php b/app/layout/service/BaseLayout.php index 944965bc0..20496b2eb 100644 --- a/app/layout/service/BaseLayout.php +++ b/app/layout/service/BaseLayout.php @@ -884,7 +884,14 @@ class BaseLayout // 商品分类 case 'category' : - $ret = GoodsService::GoodsDataHandle(Db::name('Goods')->alias('g')->join('goods_category_join gci', 'g.id=gci.goods_id')->field($field)->where($where)->group('g.id')->order($order_by)->limit($m, $n)->select()->toArray()); + $request_params = [ + 'where' => $where, + 'm' => $m, + 'n' => $n, + 'field' => $field, + 'order_by' => $order_by, + ]; + $ret = GoodsService::CategoryGoodsList($request_params); break; } if(!empty($ret) && isset($ret['code']) && $ret['code'] == 0 && !empty($ret['data'])) diff --git a/app/service/ConstService.php b/app/service/ConstService.php index 3bf338f22..ba5e32fd1 100644 --- a/app/service/ConstService.php +++ b/app/service/ConstService.php @@ -92,6 +92,7 @@ class ConstService '2.2.4' => ['value' => '2.2.4', 'name' => 'v2.2.4'], '2.2.5' => ['value' => '2.2.5', 'name' => 'v2.2.5'], '2.2.6' => ['value' => '2.2.6', 'name' => 'v2.2.6'], + '2.2.7' => ['value' => '2.2.7', 'name' => 'v2.2.7'], ], // 用户注册类型列表 diff --git a/app/service/DesignService.php b/app/service/DesignService.php index 978a7654e..516bab536 100644 --- a/app/service/DesignService.php +++ b/app/service/DesignService.php @@ -249,5 +249,400 @@ class DesignService { return 'design-'.$data_id; } + + /** + * 同步到首页 + * @author Devil + * @blog http://gong.gg/ + * @version 1.0.0 + * @date 2022-04-19 + * @desc description + * @param [array] $params [输入参数] + */ + public static function DesignSync($params = []) + { + // 请求参数 + $p = [ + [ + 'checked_type' => 'empty', + 'key_name' => 'id', + 'error_msg' => '操作id有误', + ], + ]; + $ret = ParamsChecked($params, $p); + if($ret !== true) + { + return DataReturn($ret, -1); + } + + // 获取数据 + $data = Db::name('Design')->where(['id'=>intval($params['id'])])->field('config')->find(); + if(empty($data)) + { + return DataReturn('数据不存在', -1); + } + + return LayoutService::LayoutConfigSave('home', $data); + } + + /** + * 下载 + * @author Devil + * @blog http://gong.gg/ + * @version 1.0.0 + * @date 2022-04-17 + * @desc description + * @param [array] $params [输入参数] + */ + public static function DesignDownload($params = []) + { + // 请求参数 + $p = [ + [ + 'checked_type' => 'empty', + 'key_name' => 'id', + 'error_msg' => '操作id有误', + ], + ]; + $ret = ParamsChecked($params, $p); + if($ret !== true) + { + return DataReturn($ret, -1); + } + + // 获取数据 + $data = Db::name('Design')->where(['id'=>intval($params['id'])])->find(); + if(empty($data)) + { + return DataReturn('数据不存在', -1); + } + + // 目录不存在则创建 + $dir = ROOT.'runtime'.DS.'data'.DS.'design'.DS.$data['id']; + \base\FileUtil::CreateDir($dir); + + // 临时数据id + $data_id = GetNumberCode(6).time().GetNumberCode(6); + + // 解析下载数据 + $config = self::ConfigDownloadHandle($data_id, $data['config'], $dir); + + // 基础信息 + $base = [ + 'data_id' => $data_id, + 'name' => $data['name'], + 'logo' => self::FileSave($data_id, $data['logo'], 'images', $dir), + 'is_header' => $data['is_header'], + 'is_footer' => $data['is_footer'], + 'config' => $config, + ]; + if(@file_put_contents($dir.DS.'config.json', JsonFormat($base)) === false) + { + return DataReturn('配置文件生成失败', -1); + } + + // 生成压缩包 + $dir_zip = $dir.'.zip'; + $zip = new \base\ZipFolder(); + if(!$zip->zip($dir_zip, $dir)) + { + return DataReturn('压缩包生成失败', -2); + } + + // 生成成功删除目录 + \base\FileUtil::UnlinkDir($dir); + + // 开始下载 + if(\base\FileUtil::DownloadFile($dir_zip, $data['name'].'_v'.date('YmdHis').'.zip')) + { + // 删除文件 + @unlink($dir_zip); + } else { + return DataReturn('下载失败', -100); + } + return DataReturn('下载成功', 0); + } + + /** + * 配置数据下载处理 + * @author Devil + * @blog http://gong.gg/ + * @version 1.0.0 + * @date 2022-04-17 + * @desc description + * @param [int] $data_id [数据id] + * @param [array] $config [配置数据] + * @param [string] $dir [存储目录] + */ + public static function ConfigDownloadHandle($data_id, $config, $dir) + { + if(!empty($config)) + { + // 非数组则解析 + if(!is_array($config)) + { + $config = json_decode($config, true); + } + + // 开始处理数据 + foreach($config as &$v) + { + if(empty($v['children'])) + { + continue; + } + foreach($v['children'] as &$vs) + { + if(empty($vs['children'])) + { + continue; + } + foreach($vs['children'] as &$vss) + { + if(empty($vss['config'])) + { + continue; + } + switch($vss['value']) + { + // 单图 + case 'images' : + $vss['config']['content_images'] = self::FileSave($data_id, $vss['config']['content_images'], 'images', $dir); + break; + + // 多图 + case 'many-images' : + if(!empty($vss['config']['data_list'])) + { + foreach($vss['config']['data_list'] as &$iv) + { + $iv['images'] = self::FileSave($data_id, $iv['images'], 'images', $dir); + } + } + break; + + // 视频 + case 'video' : + $vss['config']['content_video'] = self::FileSave($data_id, $vss['config']['content_video'], 'video', $dir); + break; + } + } + } + } + } + return $config; + } + + /** + * 文件保存 + * @author Devil + * @blog http://gong.gg/ + * @version 1.0.0 + * @date 2022-04-18 + * @desc description + * @param [int] $data_id [数据id] + * @param [string] $file [文件地址] + * @param [string] $type [类型] + * @param [string] $dir [存储路径] + */ + public static function FileSave($data_id, $file, $type, $dir) + { + if(!empty($file)) + { + $arr = explode('/', $file); + $path = 'static'.DS.'upload'.DS.$type.DS.'design'.DS.$data_id.DS.date('Y/m/d'); + $filename = $path.DS.$arr[count($arr)-1]; + \base\FileUtil::CreateDir($dir.DS.$path); + + $status = false; + if(substr($file, 0, 4) == 'http') + { + $temp = ResourcesService::AttachmentPathHandle($file); + if(substr($temp, 0, 4) == 'http' || !file_exists(ROOT.'public'.$temp)) + { + // 远程下载 + $temp_data = RequestGet($file); + if(!empty($temp_data)) + { + file_put_contents($dir.DS.$filename, $temp_data); + $status = true; + } + } else { + $file = $temp; + } + } + if(!$status) + { + \base\FileUtil::CopyFile(ROOT.'public'.$file, $dir.DS.$filename); + } + + return DS.$filename; + } + return ''; + } + + /** + * 导入 + * @author Devil + * @blog http://gong.gg/ + * @version 1.0.0 + * @date 2022-04-19 + * @desc description + * @param [array] $params [输入参数] + */ + public static function DesignUpload($params = []) + { + // 文件上传校验 + $error = FileUploadError('file'); + if($error !== true) + { + return DataReturn($error, -1); + } + + // 文件格式化校验 + $type = ResourcesService::ZipExtTypeList(); + if(!in_array($_FILES['file']['type'], $type)) + { + return DataReturn('文件格式有误,请上传zip压缩包', -2); + } + + // 上传处理 + return self::DesignUploadHandle($_FILES['file']['tmp_name'], $params); + } + + /** + * 导入处理 + * @author Devil + * @blog http://gong.gg/ + * @version 1.0.0 + * @date 2022-04-19 + * @desc description + * @param [string] $package_file [软件包地址] + * @param [array] $params [输入参数] + */ + public static function DesignUploadHandle($package_file, $params = []) + { + // 应用upload目录权限校验 + $app_upload_dir = ROOT.'public'.DS.'static'.DS.'upload'; + if(!is_writable($app_upload_dir)) + { + return DataReturn('应用upload目录没有操作权限'.'['.$app_upload_dir.']', -3); + } + + // 开始解压文件 + $zip = new \ZipArchive(); + $resource = $zip->open($package_file); + if($resource != true) + { + return DataReturn('压缩包打开失败['.$resource.']', -11); + } + + // 文件处理 + $config = []; + $data_id = 0; + $success = 0; + for($i=0; $i<$zip->numFiles; $i++) + { + // 资源文件 + $file = $zip->getNameIndex($i); + + // 排除临时文件和临时目录 + if(strpos($file, '/.') === false && strpos($file, '__') === false) + { + // 去除第一个目录(为原始数据的id) + $temp_file = substr($file, strpos($file, '/')+1); + if(empty($temp_file) || in_array($temp_file, ['static/', 'static/upload/'])) + { + continue; + } + + // 是否配置文件 + if($temp_file == 'config.json') + { + $stream = $zip->getStream($file); + if($stream === false) + { + $zip->close(); + return DataReturn('配置信息读取失败', -1); + } + + // 获取配置信息并解析 + $file_content = stream_get_contents($stream); + $config = empty($file_content) ? [] : json_decode($file_content, true); + if(empty($config) || empty($config['data_id']) || empty($config['name'])) + { + $zip->close(); + return DataReturn('配置信息为空或有误', -1); + } + + // 数据添加 + $data = [ + 'name' => $config['name'], + 'is_header' => (isset($config['is_header']) && $config['is_header'] == 1) ? 1 : 0, + 'is_footer' => (isset($config['is_footer']) && $config['is_footer'] == 1) ? 1 : 0, + 'add_time' => time(), + ]; + $data_id = Db::name('Design')->insertGetId($data); + if($data_id <= 0) + { + $zip->close(); + return DataReturn('数据添加失败', -1); + } + // 更新配置信息和logo + if(!empty($config['config']) || !empty($config['logo'])) + { + $upd_data = [ + 'logo' => empty($config['logo']) ? '' : str_replace($config['data_id'], $data_id, $config['logo']), + 'config' => empty($config['config']) ? '' : str_replace($config['data_id'], $data_id, json_encode($config['config'], JSON_UNESCAPED_UNICODE)), + 'upd_time' => time(), + ]; + if(!Db::name('Design')->where(['id'=>$data_id])->update($upd_data)) + { + $zip->close(); + return DataReturn('数据更新失败', -1); + } + } + continue; + } + + // 配置信息和新的数据id必须存在 + if(!empty($config) && !empty($data_id)) + { + // 截取文件路径 + $new_file = ROOT.'public'.DS.str_replace($config['data_id'], $data_id, $temp_file); + $file_path = substr($new_file, 0, strrpos($new_file, '/')); + + // 路径不存在则创建 + \base\FileUtil::CreateDir($file_path); + + // 如果不是目录则写入文件 + if(!is_dir($new_file)) + { + // 读取这个文件 + $stream = $zip->getStream($file); + if($stream !== false) + { + $file_content = stream_get_contents($stream); + if($file_content !== false) + { + if(file_put_contents($new_file, $file_content)) + { + $success++; + } + } + fclose($stream); + } + } + } + } + } + // 关闭zip + $zip->close(); + + // 附件同步到数据库 + ResourcesService::AttachmentDiskFilesToDb('design', self::AttachmentPathTypeValue($data_id)); + + return DataReturn('导入成功'); + } } ?> \ No newline at end of file diff --git a/app/service/PackageInstallService.php b/app/service/PackageInstallService.php index 284dc8a41..75e03f4ab 100644 --- a/app/service/PackageInstallService.php +++ b/app/service/PackageInstallService.php @@ -15,6 +15,7 @@ use app\service\PluginsAdminService; use app\service\PaymentService; use app\service\ThemeService; use app\service\AppMiniService; +use app\service\DesignService; /** * 软件安装服务层 @@ -74,6 +75,11 @@ class PackageInstallService $url = MyUrl('admin/app/index'); break; + // 页面设计 + case 'design' : + $url = MyUrl('admin/design/index'); + break; + default : $url = ''; } @@ -172,6 +178,11 @@ class PackageInstallService $ret = AppMiniService::ThemeUploadHandle($res['url'], $params); break; + // 页面设计 + case 'design' : + $ret = DesignService::DesignUploadHandle($res['url'], $params); + break; + // 默认 default : $ret = DataReturn('插件操作类型未定义['.$params['type'].']', -1); diff --git a/app/service/ResourcesService.php b/app/service/ResourcesService.php index f9e9d2c1c..25158dcc5 100755 --- a/app/service/ResourcesService.php +++ b/app/service/ResourcesService.php @@ -464,10 +464,17 @@ class ResourcesService * @version 1.0.0 * @date 2019-08-02 * @desc description - * @param [string] $path_type [附件路径类型] + * @param [string] $dir_path [附件路径类型] + * @param [string] $path_type [附件路径值类型] */ - public static function AttachmentDiskFilesToDb($path_type) + public static function AttachmentDiskFilesToDb($dir_path, $path_type = '') { + // 未指定类型值则使用路径值 + if(empty($path_type)) + { + $path_type = $dir_path; + } + // 处理状态总数 $count = 0; $success = 0; @@ -475,9 +482,9 @@ class ResourcesService // 视频/文件/图片 $path_all = [ - 'video' => __MY_ROOT_PUBLIC__.'static/upload/video/'.$path_type.'/', - 'file' => __MY_ROOT_PUBLIC__.'static/upload/file/'.$path_type.'/', - 'image' => __MY_ROOT_PUBLIC__.'static/upload/images/'.$path_type.'/', + 'video' => __MY_ROOT_PUBLIC__.'static/upload/video/'.$dir_path.'/', + 'file' => __MY_ROOT_PUBLIC__.'static/upload/file/'.$dir_path.'/', + 'image' => __MY_ROOT_PUBLIC__.'static/upload/images/'.$dir_path.'/', ]; foreach($path_all as $type=>$path) { diff --git a/app/service/StoreService.php b/app/service/StoreService.php index 9d2d2e8ed..9f9454784 100644 --- a/app/service/StoreService.php +++ b/app/service/StoreService.php @@ -51,6 +51,20 @@ class StoreService { return MyConfig('shopxo.store_payment_url').self::RequestParamsString($params); } + + /** + * 应用商店页面设计地址 + * @author Devil + * @blog http://gong.gg/ + * @version 1.0.0 + * @date 2021-02-12 + * @desc description + * @param [array] $params [输入参数] + */ + public static function StoreDesignUrl($params = []) + { + return MyConfig('shopxo.store_design_url').self::RequestParamsString($params); + } /** * 应用商店主题地址 diff --git a/config/shopxo.php b/config/shopxo.php index b167e2c7c..4b6350f30 100755 --- a/config/shopxo.php +++ b/config/shopxo.php @@ -117,6 +117,7 @@ return [ 'website_url' => $store_http.'shopxo.net/', 'store_url' => $store_http.'store.shopxo.net/', 'store_payment_url' => $store_http.'store.shopxo.net/', + 'store_design_url' => $store_http.'store.shopxo.net/', 'store_theme_url' => $store_http.'store.shopxo.net/', 'store_regster_url' => $store_http.'store.shopxo.net/regster.html', diff --git a/public/static/admin/default/js/common.js b/public/static/admin/default/js/common.js index 712ae95b5..484702a66 100644 --- a/public/static/admin/default/js/common.js +++ b/public/static/admin/default/js/common.js @@ -86,7 +86,7 @@ function FormTableHeightHandle() * @date 2021-02-22 * @desc description * @param {[string]} url [url地址] - * @param {[string]} type [操作类型(plugins、payment、webtheme、minitheme)] + * @param {[string]} type [操作类型(plugins、payment、webtheme、minitheme、design)] * @param {[string]} value [操作标识值] * @param {[string]} opt [操作类型(url 获取下载地址, download 下载插件包, upgrade 安装插件包)] * @param {[string]} key [操作key(仅download和install需要)]