首页新增拖拽装修

This commit is contained in:
Devil
2021-06-22 21:45:29 +08:00
parent ca842448e9
commit 20c867cc48
65 changed files with 9046 additions and 304 deletions

View File

@ -0,0 +1,56 @@
<?php
// +----------------------------------------------------------------------
// | ShopXO 国内领先企业级B2C免费开源电商系统
// +----------------------------------------------------------------------
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://opensource.org/licenses/mit-license.php )
// +----------------------------------------------------------------------
// | Author: Devil
// +----------------------------------------------------------------------
namespace app\admin\controller;
use app\service\LayoutService;
/**
* 布局管理
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-01T21:51:08+0800
*/
class Layout extends Common
{
/**
* 构造方法
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T12:39:08+0800
*/
public function __construct()
{
// 调用父类前置方法
parent::__construct();
// 登录校验
$this->IsLogin();
// 权限校验
$this->IsPower();
}
/**
* 前端首页布局保存
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-06-22
* @desc description
*/
public function LayoutIndexHomeSave()
{
return LayoutService::LayoutConfigSave('home', $this->data_post);
}
}
?>

View File

@ -43,6 +43,9 @@
<option value="{{$k}}" {{if isset($data['home_index_floor_data_type']['value']) and $data['home_index_floor_data_type']['value'] eq $k}}selected{{/if}}>{{$v.name}}</option>
{{/foreach}}
</select>
<div class="am-alert">
拖拽模式需要自行进入首页设计页面<a href="{{:MyUrl('index/index/index', ['is_design'=>1, 'save_url'=>urlencode(base64_encode(MyUrl('admin/layout/layoutindexhomesave')))])}}" target="_blank" class="am-margin-left-sm">去设计页面 >></a>
</div>
</div>
<div class="am-form-group">

View File

@ -417,6 +417,10 @@ class Common extends Controller
$this->assign('home_site_security_record_name', MyC('home_site_security_record_name'));
$this->assign('home_site_security_record_url', MyC('home_site_security_record_url'));
// 布局样式+管理
$this->assign('is_load_layout', 0);
$this->assign('is_load_layout_admin', 0);
// 默认不加载放大镜
$this->assign('is_load_imagezoom', 0);

View File

@ -11,11 +11,16 @@
namespace app\index\controller;
use think\facade\Hook;
use app\layout\service\BaseLayout;
use app\service\SeoService;
use app\service\AdminService;
use app\service\BannerService;
use app\service\GoodsService;
use app\service\ArticleService;
use app\service\OrderService;
use app\service\AppHomeNavService;
use app\service\BrandService;
use app\service\LayoutService;
/**
* 首页
@ -52,25 +57,83 @@ class Index extends Common
$banner = BannerService::Banner();
$this->assign('banner_list', $banner);
// H5导航
$this->assign('navigation', AppHomeNavService::AppHomeNav());
// 数据模式
$floor_data_type = MyC('home_index_floor_data_type', 0, true);
$this->assign('floor_data_type', $floor_data_type);
// 楼层数据
$this->assign('goods_floor_list', GoodsService::HomeFloorList());
// 是否设计模式
$is_design = (!empty($this->data_request['save_url']) && isset($this->data_request['is_design']) && $this->data_request['is_design'] == 1 && $floor_data_type == 2 && AdminService::LoginInfo()) ? 1 : 0;
$this->assign('is_design', $is_design);
if($is_design == 1)
{
// 保存数据地址
$this->assign('layout_save_url', base64_decode(urldecode($this->data_request['save_url'])));
// 文章
$params = [
'where' => ['is_enable'=>1, 'is_home_recommended'=>1],
'field' => 'id,title,title_color,article_category_id',
'm' => 0,
'n' => 9,
];
$article_list = ArticleService::ArticleList($params);
$this->assign('article_list', $article_list['data']);
// 设计配置数据
$layout_data = LayoutService::LayoutConfigAdminData('home');
$this->assign('layout_data', $layout_data['data']);
// 用户订单状态
$user_order_status = OrderService::OrderStatusStepTotal(['user_type'=>'user', 'user'=>$this->user, 'is_comments'=>1]);
$this->assign('user_order_status', $user_order_status['data']);
// 页面列表
$pages_list = BaseLayout::PagesList();
$this->assign('pages_list', $pages_list);
// 商品搜索分类(分类)
$this->assign('layout_goods_category', GoodsService::GoodsCategoryAll());
$this->assign('layout_goods_category_field', 'gci.category_id');
// 品牌
$this->assign('brand_list', BrandService::CategoryBrand());
// 静态数据
$this->assign('border_style_type_list', BaseLayout::$border_style_type_list);
$this->assign('goods_view_list_show_style', BaseLayout::$goods_view_list_show_style);
$this->assign('many_images_view_list_show_style', BaseLayout::$many_images_view_list_show_style);
// 首页商品排序规则
$this->assign('goods_order_by_type_list', lang('goods_order_by_type_list'));
$this->assign('goods_order_by_rule_list', lang('goods_order_by_rule_list'));
// 浏览器名称
$this->assign('home_seo_site_title', SeoService::BrowserSeoTitle('首页设计', 1));
// 编辑器文件存放地址定义
$this->assign('editor_path_type', 'index-design');
// 加载布局样式+管理
$this->assign('is_load_layout', 1);
$this->assign('is_load_layout_admin', 1);
} else {
// 数据模式
if($floor_data_type == 2)
{
// 设计配置数据
$layout_data = LayoutService::LayoutConfigData('home');
$this->assign('layout_data', $layout_data['data']);
// 加载布局样式
$this->assign('is_load_layout', 1);
} else {
// H5导航
$this->assign('navigation', AppHomeNavService::AppHomeNav());
// 楼层数据
$this->assign('goods_floor_list', GoodsService::HomeFloorList());
// 文章
$params = [
'where' => ['is_enable'=>1, 'is_home_recommended'=>1],
'field' => 'id,title,title_color,article_category_id',
'm' => 0,
'n' => 9,
];
$article_list = ArticleService::ArticleList($params);
$this->assign('article_list', $article_list['data']);
// 用户订单状态
$user_order_status = OrderService::OrderStatusStepTotal(['user_type'=>'user', 'user'=>$this->user, 'is_comments'=>1]);
$this->assign('user_order_status', $user_order_status['data']);
}
}
// 加载百度地图api
// 存在地图事件则载入

View File

@ -0,0 +1,87 @@
<?php
// +----------------------------------------------------------------------
// | ShopXO 国内领先企业级B2C免费开源电商系统
// +----------------------------------------------------------------------
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://opensource.org/licenses/mit-license.php )
// +----------------------------------------------------------------------
// | Author: Devil
// +----------------------------------------------------------------------
namespace app\index\controller;
use app\layout\service\BaseLayout;
/**
* 布局自动化
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-01T21:51:08+0800
*/
class Layout extends Common
{
/**
* 构造方法
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-11-30
* @desc description
*/
public function __construct()
{
parent::__construct();
}
/**
* 商品搜索
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2020-10-16
* @desc description
*/
public function GoodsSearch()
{
// 是否ajax请求
if(!IS_AJAX)
{
return $this->error('非法访问');
}
// 获取数据
$params = $this->data_post;
$params['user'] = $this->user;
$ret = BaseLayout::GoodsSearchList($params);
if($ret['code'] == 0)
{
$this->assign('data', $ret['data']['data']);
$ret['data']['data'] = $this->fetch('../../../layout/view/public/common/goodssearch');
}
return $ret;
}
/**
* 商品数据
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2020-10-16
* @desc description
*/
public function GoodsData()
{
// 是否ajax请求
if(!IS_AJAX)
{
return $this->error('非法访问');
}
// 获取数据
$params = $this->data_post;
$params['user'] = $this->user;
return BaseLayout::GoodsDataList($params);
}
}
?>

View File

@ -13,101 +13,104 @@
<!-- header nav -->
{{include file="public/header_nav" /}}
<!-- banner -->
{{include file="public/home_banner" /}}
<!-- goods category -->
{{include file="public/goods_category" /}}
<!-- 轮播上内容 -->
<div class="am-container slideall">
<!-- 轮播-手机导航 -->
{{include file="public/home_nav" /}}
<!-- 数据模式、拖拽默认则不展示轮播和聚合内容 -->
{{if !isset($floor_data_type) or $floor_data_type neq 2}}
<!-- banner -->
{{include file="public/home_banner" /}}
<!-- 轮播-聚合内容 -->
{{if MyC('home_index_banner_right_status', 1) eq 1}}
<div class="banner-mixed">
<div class="mod-vip">
<div class="m-baseinfo">
<a {{if !empty($user)}}href="{{:MyUrl('index/user/index')}}" target="_blank"{{else /}}href="javascript:;"{{/if}}>
<img src="{{if !empty($user['avatar'])}}{{$user.avatar}}{{else /}}{{$attachment_host}}/static/{{$module_name}}/{{$default_theme}}/images/default-user-avatar.jpg{{/if}}" class="user-avatar" />
</a>
<em>
<span class="s-name am-text-truncate">
{{if !empty($user)}}
<em>Hi,</em>
{{if !empty($user['icon'])}}
<img src="{{$user.icon}}" class="common-user-icon" {{if !empty($user['icon_title'])}}title="{{$user.icon_title}}"{{/if}} />
<!-- 轮播内容 -->
<div class="am-container slideall">
<!-- 轮播-手机导航 -->
{{include file="public/home_nav" /}}
<!-- 轮播-聚合内容 -->
{{if MyC('home_index_banner_right_status', 1) eq 1}}
<div class="banner-mixed">
<div class="mod-vip">
<div class="m-baseinfo">
<a {{if !empty($user)}}href="{{:MyUrl('index/user/index')}}" target="_blank"{{else /}}href="javascript:;"{{/if}}>
<img src="{{if !empty($user['avatar'])}}{{$user.avatar}}{{else /}}{{$attachment_host}}/static/{{$module_name}}/{{$default_theme}}/images/default-user-avatar.jpg{{/if}}" class="user-avatar" />
</a>
<em>
<span class="s-name am-text-truncate">
{{if !empty($user)}}
<em>Hi,</em>
{{if !empty($user['icon'])}}
<img src="{{$user.icon}}" class="common-user-icon" {{if !empty($user['icon_title'])}}title="{{$user.icon_title}}"{{/if}} />
{{/if}}
<em>{{$user.user_name_view}}</em>
{{else /}}
<em>您好,欢迎来到</em>
<em>{{:MyC('home_site_name')}}</em>
{{/if}}
<em>{{$user.user_name_view}}</em>
{{else /}}
<em>您好,欢迎来到</em>
<em>{{:MyC('home_site_name')}}</em>
</span>
</em>
{{if !empty($user)}}
<a href="{{:MyUrl('index/user/logout')}}" class="member-logout">退出</a>
{{/if}}
</div>
{{if empty($user) and (!empty($home_user_login_type) or !empty($home_user_reg_type))}}
<div class="member-login">
{{if !empty($home_user_login_type)}}
<a class="am-btn-primary btn am-fl" href="{{:MyUrl('index/user/loginInfo')}}">登录</a>
{{/if}}
</span>
</em>
{{if !empty($home_user_reg_type)}}
<a class="am-btn-primary btn am-fr" href="{{:MyUrl('index/user/regInfo')}}">注册</a>
{{/if}}
</div>
{{/if}}
{{if !empty($user)}}
<a href="{{:MyUrl('index/user/logout')}}" class="member-logout">退出</a>
<div class="member-center">
{{if !empty($user_order_status)}}
{{foreach $user_order_status as $v}}
{{if in_array($v['status'], [1,2,3])}}
<a href="{{:MyUrl('index/order/index', ['is_more'=>1, 'status'=>$v['status']])}}" target="_blank"><strong>{{$v.count}}</strong>{{$v.name}}</a>
{{elseif in_array($v['status'], [100]) /}}
<a href="{{:MyUrl('index/order/index', ['is_more'=>1, 'is_comments'=>0, 'status'=>4])}}" target="_blank"><strong>{{$v.count}}</strong>{{$v.name}}</a>
{{/if}}
{{/foreach}}
{{/if}}
</div>
{{/if}}
</div>
{{if empty($user) and (!empty($home_user_login_type) or !empty($home_user_reg_type))}}
<div class="member-login">
{{if !empty($home_user_login_type)}}
<a class="am-btn-primary btn am-fl" href="{{:MyUrl('index/user/loginInfo')}}">登录</a>
{{/if}}
{{if !empty($home_user_reg_type)}}
<a class="am-btn-primary btn am-fr" href="{{:MyUrl('index/user/regInfo')}}">注册</a>
{{/if}}
{{if !empty($article_list)}}
<div class="banner-news">
<p class="banner-news-title am-text-truncate">新闻头条</p>
<ul>
{{foreach $article_list as $article}}
<li class="am-text-truncate">
<a href="{{$article.url}}" target="_blank">
{{if isset($article['article_category_name'])}}
<span>[</span><p class="news-category-name am-inline-block am-text-truncate">{{$article.article_category_name}}</p><span>]</span>
{{/if}}
<span {{if !empty($article.title_color)}}style="color:{{$article.title_color}};"{{/if}} >{{$article.title}}</span>
</a>
</li>
{{/foreach}}
</ul>
</div>
{{/if}}
{{if !empty($user)}}
<div class="member-center">
{{if !empty($user_order_status)}}
{{foreach $user_order_status as $v}}
{{if in_array($v['status'], [1,2,3])}}
<a href="{{:MyUrl('index/order/index', ['is_more'=>1, 'status'=>$v['status']])}}" target="_blank"><strong>{{$v.count}}</strong>{{$v.name}}</a>
{{elseif in_array($v['status'], [100]) /}}
<a href="{{:MyUrl('index/order/index', ['is_more'=>1, 'is_comments'=>0, 'status'=>4])}}" target="_blank"><strong>{{$v.count}}</strong>{{$v.name}}</a>
{{/if}}
{{/foreach}}
{{/if}}
<!-- 轮播混合数据底部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
<div class="plugins-tag">
<span>plugins_view_home_banner_mixed_bottom</span>
</div>
{{/if}}
{{if !empty($plugins_view_home_banner_mixed_bottom_data) and is_array($plugins_view_home_banner_mixed_bottom_data)}}
{{foreach $plugins_view_home_banner_mixed_bottom_data as $hook}}
{{if is_string($hook) or is_int($hook)}}
{{$hook|raw}}
{{/if}}
{{/foreach}}
{{/if}}
</div>
{{if !empty($article_list)}}
<div class="banner-news">
<p class="banner-news-title am-text-truncate">新闻头条</p>
<ul>
{{foreach $article_list as $article}}
<li class="am-text-truncate">
<a href="{{$article.url}}" target="_blank">
{{if isset($article['article_category_name'])}}
<span>[</span><p class="news-category-name am-inline-block am-text-truncate">{{$article.article_category_name}}</p><span>]</span>
{{/if}}
<span {{if !empty($article.title_color)}}style="color:{{$article.title_color}};"{{/if}} >{{$article.title}}</span>
</a>
</li>
{{/foreach}}
</ul>
</div>
{{/if}}
<!-- 轮播混合数据底部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
<div class="plugins-tag">
<span>plugins_view_home_banner_mixed_bottom</span>
</div>
{{/if}}
{{if !empty($plugins_view_home_banner_mixed_bottom_data) and is_array($plugins_view_home_banner_mixed_bottom_data)}}
{{foreach $plugins_view_home_banner_mixed_bottom_data as $hook}}
{{if is_string($hook) or is_int($hook)}}
{{$hook|raw}}
{{/if}}
{{/foreach}}
{{/if}}
</div>
{{/if}}
</div>
{{/if}}
</div>
{{/if}}
<!-- 楼层数据顶部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
@ -124,98 +127,216 @@
{{/if}}
<!-- 楼层-主内容 -->
<div class="home-floor">
<!-- 楼层 -->
{{if !empty($goods_floor_list) and is_array($goods_floor_list)}}
{{foreach $goods_floor_list as $key=>$floor}}
<!-- 首页楼层顶部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
<div class="plugins-tag">
<span>plugins_view_home_floor_top_{{$key+1}}</span>
{{if isset($floor_data_type) and $floor_data_type eq 2}}
<!-- 是否设计模式 -->
<div class="am-container">
{{if isset($is_design) and $is_design eq 1}}
<div class="am-margin-top-sm">
<div class="layout-operate-container am-fr" data-save-url="{{$layout_save_url}}">
<a href="{{$Think.__MY_URL__}}" class="am-btn am-btn-warning am-radius">取消</a>
<button type="button" class="am-btn am-btn-success am-radius am-margin-left-sm" data-am-loading="{loadingText:'处理中...'}">保存</button>
</div>
{{/if}}
{{php}}
$hook_name = 'plugins_view_home_floor_top_'.($key+1);
$hook_data = Hook::listen($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'floor_id'=>$key+1, 'floor'=>$floor]);
if(!empty($hook_data) && is_array($hook_data))
{
foreach($hook_data as $hook)
{{include file="../../../layout/view/base" /}}
</div>
{{else /}}
{{include file="../../../layout/view/view" /}}
{{/if}}
</div>
{{else /}}
<div class="home-floor">
<!-- 楼层 -->
{{if !empty($goods_floor_list) and is_array($goods_floor_list)}}
{{foreach $goods_floor_list as $key=>$floor}}
<!-- 首页楼层顶部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
<div class="plugins-tag">
<span>plugins_view_home_floor_top_{{$key+1}}</span>
</div>
{{/if}}
{{php}}
$hook_name = 'plugins_view_home_floor_top_'.($key+1);
$hook_data = Hook::listen($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'floor_id'=>$key+1, 'floor'=>$floor]);
if(!empty($hook_data) && is_array($hook_data))
{
if(is_string($hook) || is_int($hook))
foreach($hook_data as $hook)
{
echo htmlspecialchars_decode($hook);
if(is_string($hook) || is_int($hook))
{
echo htmlspecialchars_decode($hook);
}
}
}
}
{{/php}}
{{/php}}
<!-- 楼层数据 -->
<div id="floor{{$key+1}}">
<div class="am-container">
<div class="items-nav-title" {{if !empty($floor['bg_color'])}}style="border-bottom: 2px solid {{$floor.bg_color}};"{{/if}}>
<p class="floor-title">{{$floor.name}}</p>
<p class="floor-desc">{{$floor.vice_name}}</p>
<div class="today-brands ">
{{if !empty($floor['config_keywords']) and is_array($floor['config_keywords'])}}
{{foreach $floor.config_keywords as $wd}}
<a href="{{:MyUrl('index/search/index', ['wd'=>StrToAscii($wd)])}}" target="_blank">{{$wd}}</a>
<!-- 楼层数据 -->
<div id="floor{{$key+1}}">
<div class="am-container">
<div class="items-nav-title" {{if !empty($floor['bg_color'])}}style="border-bottom: 2px solid {{$floor.bg_color}};"{{/if}}>
<p class="floor-title">{{$floor.name}}</p>
<p class="floor-desc">{{$floor.vice_name}}</p>
<div class="today-brands ">
{{if !empty($floor['config_keywords']) and is_array($floor['config_keywords'])}}
{{foreach $floor.config_keywords as $wd}}
<a href="{{:MyUrl('index/search/index', ['wd'=>StrToAscii($wd)])}}" target="_blank">{{$wd}}</a>
{{/foreach}}
{{/if}}
</div>
<span class="more">
<a href="{{:MyUrl('index/search/index', ['category_id'=>$floor['id']])}}" target="_blank">更多 <i class="am-icon-angle-right"></i></a>
</span>
</div>
</div>
<div class="am-g am-g-fixed floor">
<!-- 首页楼层内部顶部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
<div class="plugins-tag">
<span>plugins_view_home_floor_inside_top</span>
</div>
{{/if}}
{{php}}
$hook_name = 'plugins_view_home_floor_inside_top';
$hook_data = Hook::listen($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'floor_id'=>$key+1, 'floor'=>$floor]);
if(!empty($hook_data) && is_array($hook_data))
{
foreach($hook_data as $hook)
{
if(is_string($hook) || is_int($hook))
{
echo htmlspecialchars_decode($hook);
}
}
}
{{/php}}
<div class="am-u-sm-3 aggregation" {{if !empty($floor['bg_color'])}}style="background-color:{{$floor.bg_color}};"{{else /}}style="background-color:#eaeaea;"{{/if}}>
<div class="word">
{{if !empty($floor['items']) and is_array($floor['items'])}}
{{foreach $floor.items as $category_key=>$category}}
<a href="{{:MyUrl('index/search/index', ['category_id'=>$category['id']])}}" class="outer" target="_blank">{{:mb_substr($category['name'], 0, 4, 'utf-8')}}</a>
{{/foreach}}
{{/if}}
</div>
<div class="outer-con">
<div class="describe">{{$floor.describe}}</div>
</div>
{{if !empty($floor['big_images'])}}
<a href="{{:MyUrl('index/search/index', ['category_id'=>$floor['id']])}}" target="_blank">
<img src="{{$floor.big_images}}" />
</a>
{{/if}}
<div class="triangle-topright"></div>
<!-- 首页楼层内部底部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
<div class="plugins-tag">
<span>plugins_view_home_aggregation_inside_bottom</span>
</div>
{{/if}}
{{php}}
$hook_name = 'plugins_view_home_aggregation_inside_bottom';
$hook_data = Hook::listen($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'floor_id'=>$key+1, 'floor'=>$floor]);
if(!empty($hook_data) && is_array($hook_data))
{
foreach($hook_data as $hook)
{
if(is_string($hook) || is_int($hook))
{
echo htmlspecialchars_decode($hook);
}
}
}
{{/php}}
</div>
<div class="goods-list">
{{if !empty($floor['goods']) and is_array($floor['goods'])}}
{{foreach $floor.goods as $goods_key=>$goods}}
<div class="goods-items">
<a href="{{$goods.goods_url}}" target="_blank" class="am-block am-text-center">
<!-- 首页楼层商品内部顶部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
<div class="plugins-tag">
<span>plugins_view_home_goods_inside_top</span>
</div>
{{/if}}
{{php}}
$hook_name = 'plugins_view_home_goods_inside_top';
$hook_data = Hook::listen($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'floor_id'=>$key+1, 'goods_id'=>$goods['id'], 'goods'=>$goods]);
if(!empty($hook_data) && is_array($hook_data))
{
foreach($hook_data as $hook)
{
if(is_string($hook) || is_int($hook))
{
echo htmlspecialchars_decode($hook);
}
}
}
{{/php}}
<img src="{{$goods.images}}" alt="{{$goods.title}}" class="goods-images" />
</a>
<div class="outer-con">
<div class="goods-title am-text-truncate-2 am-margin-bottom-xs">
<a href="{{$goods['goods_url']}}" target="_blank" {{if !empty($goods.title_color)}}style="color:{{$goods.title_color}};"{{/if}}>{{$goods.title}}</a>
</div>
<!-- 首页楼层商品售价顶部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
<div class="plugins-tag">
<span>plugins_view_home_goods_inside_price_top</span>
</div>
{{/if}}
{{php}}
$hook_name = 'plugins_view_home_goods_inside_price_top';
$hook_data = Hook::listen($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'floor_id'=>$key+1, 'goods_id'=>$goods['id'], 'goods'=>$goods]);
if(!empty($hook_data) && is_array($hook_data))
{
foreach($hook_data as $hook)
{
if(is_string($hook) || is_int($hook))
{
echo htmlspecialchars_decode($hook);
}
}
}
{{/php}}
<p class="price am-text-truncate">{{$currency_symbol}}{{$goods.price}}</p>
</div>
<!-- 首页楼层商品内部底部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
<div class="plugins-tag">
<span>plugins_view_home_goods_inside_bottom</span>
</div>
{{/if}}
{{php}}
$hook_name = 'plugins_view_home_goods_inside_bottom';
$hook_data = Hook::listen($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'floor_id'=>$key+1, 'goods_id'=>$goods['id'], 'goods'=>$goods]);
if(!empty($hook_data) && is_array($hook_data))
{
foreach($hook_data as $hook)
{
if(is_string($hook) || is_int($hook))
{
echo htmlspecialchars_decode($hook);
}
}
}
{{/php}}
</div>
{{/foreach}}
{{/if}}
</div>
<span class="more">
<a href="{{:MyUrl('index/search/index', ['category_id'=>$floor['id']])}}" target="_blank">更多 <i class="am-icon-angle-right"></i></a>
</span>
</div>
</div>
<div class="am-g am-g-fixed floor">
<!-- 首页楼层内部顶部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
<div class="plugins-tag">
<span>plugins_view_home_floor_inside_top</span>
</div>
{{/if}}
{{php}}
$hook_name = 'plugins_view_home_floor_inside_top';
$hook_data = Hook::listen($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'floor_id'=>$key+1, 'floor'=>$floor]);
if(!empty($hook_data) && is_array($hook_data))
{
foreach($hook_data as $hook)
{
if(is_string($hook) || is_int($hook))
{
echo htmlspecialchars_decode($hook);
}
}
}
{{/php}}
<div class="am-u-sm-3 aggregation" {{if !empty($floor['bg_color'])}}style="background-color:{{$floor.bg_color}};"{{else /}}style="background-color:#eaeaea;"{{/if}}>
<div class="word">
{{if !empty($floor['items']) and is_array($floor['items'])}}
{{foreach $floor.items as $category_key=>$category}}
<a href="{{:MyUrl('index/search/index', ['category_id'=>$category['id']])}}" class="outer" target="_blank">{{:mb_substr($category['name'], 0, 4, 'utf-8')}}</a>
{{/foreach}}
{{/if}}
</div>
<div class="outer-con">
<div class="describe">{{$floor.describe}}</div>
</div>
{{if !empty($floor['big_images'])}}
<a href="{{:MyUrl('index/search/index', ['category_id'=>$floor['id']])}}" target="_blank">
<img src="{{$floor.big_images}}" />
</a>
{{/if}}
<div class="triangle-topright"></div>
<!-- 首页楼层内部底部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
<div class="plugins-tag">
<span>plugins_view_home_aggregation_inside_bottom</span>
<span>plugins_view_home_floor_inside_bottom</span>
</div>
{{/if}}
{{php}}
$hook_name = 'plugins_view_home_aggregation_inside_bottom';
$hook_name = 'plugins_view_home_floor_inside_bottom';
$hook_data = Hook::listen($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'floor_id'=>$key+1, 'floor'=>$floor]);
if(!empty($hook_data) && is_array($hook_data))
{
@ -229,133 +350,32 @@
}
{{/php}}
</div>
</div>
<div class="goods-list">
{{if !empty($floor['goods']) and is_array($floor['goods'])}}
{{foreach $floor.goods as $goods_key=>$goods}}
<div class="goods-items">
<a href="{{$goods.goods_url}}" target="_blank" class="am-block am-text-center">
<!-- 首页楼层商品内部顶部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
<div class="plugins-tag">
<span>plugins_view_home_goods_inside_top</span>
</div>
{{/if}}
{{php}}
$hook_name = 'plugins_view_home_goods_inside_top';
$hook_data = Hook::listen($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'floor_id'=>$key+1, 'goods_id'=>$goods['id'], 'goods'=>$goods]);
if(!empty($hook_data) && is_array($hook_data))
{
foreach($hook_data as $hook)
{
if(is_string($hook) || is_int($hook))
{
echo htmlspecialchars_decode($hook);
}
}
}
{{/php}}
<img src="{{$goods.images}}" alt="{{$goods.title}}" class="goods-images" />
</a>
<div class="outer-con">
<div class="goods-title am-text-truncate-2 am-margin-bottom-xs">
<a href="{{$goods['goods_url']}}" target="_blank" {{if !empty($goods.title_color)}}style="color:{{$goods.title_color}};"{{/if}}>{{$goods.title}}</a>
</div>
<!-- 首页楼层商品售价顶部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
<div class="plugins-tag">
<span>plugins_view_home_goods_inside_price_top</span>
</div>
{{/if}}
{{php}}
$hook_name = 'plugins_view_home_goods_inside_price_top';
$hook_data = Hook::listen($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'floor_id'=>$key+1, 'goods_id'=>$goods['id'], 'goods'=>$goods]);
if(!empty($hook_data) && is_array($hook_data))
{
foreach($hook_data as $hook)
{
if(is_string($hook) || is_int($hook))
{
echo htmlspecialchars_decode($hook);
}
}
}
{{/php}}
<p class="price am-text-truncate">{{$currency_symbol}}{{$goods.price}}</p>
</div>
<!-- 首页楼层商品内部底部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
<div class="plugins-tag">
<span>plugins_view_home_goods_inside_bottom</span>
</div>
{{/if}}
{{php}}
$hook_name = 'plugins_view_home_goods_inside_bottom';
$hook_data = Hook::listen($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'floor_id'=>$key+1, 'goods_id'=>$goods['id'], 'goods'=>$goods]);
if(!empty($hook_data) && is_array($hook_data))
{
foreach($hook_data as $hook)
{
if(is_string($hook) || is_int($hook))
{
echo htmlspecialchars_decode($hook);
}
}
}
{{/php}}
</div>
{{/foreach}}
{{/if}}
<!-- 首页楼层底部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
<div class="plugins-tag">
<span>plugins_view_home_floor_bottom_{{$key+1}}</span>
</div>
<!-- 首页楼层内部底部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
<div class="plugins-tag">
<span>plugins_view_home_floor_inside_bottom</span>
</div>
{{/if}}
{{php}}
$hook_name = 'plugins_view_home_floor_inside_bottom';
$hook_data = Hook::listen($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'floor_id'=>$key+1, 'floor'=>$floor]);
if(!empty($hook_data) && is_array($hook_data))
{{/if}}
{{php}}
$hook_name = 'plugins_view_home_floor_bottom_'.($key+1);
$hook_data = Hook::listen($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'floor_id'=>$key+1, 'floor'=>$floor]);
if(!empty($hook_data) && is_array($hook_data))
{
foreach($hook_data as $hook)
{
foreach($hook_data as $hook)
if(is_string($hook) || is_int($hook))
{
if(is_string($hook) || is_int($hook))
{
echo htmlspecialchars_decode($hook);
}
echo htmlspecialchars_decode($hook);
}
}
{{/php}}
</div>
</div>
<!-- 首页楼层底部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
<div class="plugins-tag">
<span>plugins_view_home_floor_bottom_{{$key+1}}</span>
</div>
{{/if}}
{{php}}
$hook_name = 'plugins_view_home_floor_bottom_'.($key+1);
$hook_data = Hook::listen($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'floor_id'=>$key+1, 'floor'=>$floor]);
if(!empty($hook_data) && is_array($hook_data))
{
foreach($hook_data as $hook)
{
if(is_string($hook) || is_int($hook))
{
echo htmlspecialchars_decode($hook);
}
}
}
{{/php}}
{{/foreach}}
{{/if}}
</div>
{{/php}}
{{/foreach}}
{{/if}}
</div>
{{/if}}
<!-- 楼层数据底部钩子 -->
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true and (!isset($is_footer) or $is_footer eq 1)}}
@ -371,4 +391,7 @@
{{/foreach}}
{{/if}}
{{include file="public/footer" /}}
{{include file="public/footer" /}}
<!-- layout formback -->
{{include file="../../../layout/view/form_back" /}}

View File

@ -85,6 +85,9 @@
<!-- 项目公共 -->
<script type='text/javascript' src="{{$public_host}}static/common/js/common.js?v={{:MyC('home_static_cache_version')}}"></script>
<script type='text/javascript' src="{{$public_host}}static/index/{{$default_theme}}/js/common.js?v={{:MyC('home_static_cache_version')}}"></script>
{{if isset($is_load_layout_admin) and $is_load_layout_admin eq 1}}
<script type='text/javascript' src="{{$public_host}}static/common/js/layout.admin.js?v={{:MyC('home_static_cache_version')}}"></script>
{{/if}}
<!-- 应用插件公共js -->
{{if !empty($plugins_js)}}

View File

@ -24,9 +24,15 @@
<link rel="stylesheet" type="text/css" href="{{$public_host}}static/common/lib/amazeui-tagsinput/amazeui.tagsinput.css?v={{:MyC('home_static_cache_version')}}" />
<link rel="stylesheet" type="text/css" href="{{$public_host}}static/common/css/common.css?v={{:MyC('home_static_cache_version')}}" />
<link rel="stylesheet" type="text/css" href="{{$public_host}}static/index/{{$default_theme}}/css/common.css?v={{:MyC('home_static_cache_version')}}" />
<link rel="stylesheet" type="text/css" href="{{$public_host}}static/index/{{$default_theme}}/css/common.css?v={{:MyC('home_static_cache_version')}}" />
{{if !empty($plugins_css)}}
<link rel="stylesheet" type="text/css" href="{{$public_host}}static/{{$plugins_css}}?v={{:MyC('home_static_cache_version')}}" />
{{/if}}
{{if isset($is_load_layout) and $is_load_layout eq 1}}
<link rel="stylesheet" type="text/css" href="{{$public_host}}static/common/css/layout.css?v={{:MyC('home_static_cache_version')}}" />
{{/if}}
{{if isset($is_load_layout_admin) and $is_load_layout_admin eq 1}}
<link rel="stylesheet" type="text/css" href="{{$public_host}}static/common/css/layout.admin.css?v={{:MyC('home_static_cache_version')}}" />
{{/if}}
{{if !empty($module_css)}}
<link rel="stylesheet" type="text/css" href="{{$public_host}}static/{{$module_css}}?v={{:MyC('home_static_cache_version')}}" />

View File

@ -362,6 +362,7 @@ return [
'common_site_floor_data_type_list' => [
0 => ['value' => 0, 'name' => '自动模式', 'checked' => true],
1 => ['value' => 1, 'name' => '手动模式'],
2 => ['value' => 2, 'name' => '拖拽模式'],
],
// 色彩值

View File

@ -0,0 +1,769 @@
<?php
// +----------------------------------------------------------------------
// | ShopXO 国内领先企业级B2C免费开源电商系统
// +----------------------------------------------------------------------
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://opensource.org/licenses/mit-license.php )
// +----------------------------------------------------------------------
// | Author: Devil
// +----------------------------------------------------------------------
namespace app\layout\service;
use think\Db;
use think\facade\Hook;
use app\service\ResourcesService;
use app\service\GoodsService;
/**
* 布局自动化服务层
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2020-05-25
* @desc description
*/
class BaseLayout
{
// 边线样式类型
public static $border_style_type_list = [
'solid' => '实线',
'dashed' => '虚线',
'dotted' => '点状',
'double' => '双线',
];
// 商品样式类型
public static $goods_view_list_show_style = [
'routine' => '常规模式',
'rolling' => '滚动模式',
];
// 多图样式类型
public static $many_images_view_list_show_style = [
'routine' => '轮播模式',
'rolling' => '滚动模式',
'list' => '列表模式',
];
/**
* 配置处理-管理
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-06-17
* @desc description
* @param [array] $config [配置信息]
* @param [array] $params [输入参数]
*/
public static function ConfigAdminHandle($config, $params = [])
{
if(!empty($config))
{
// 是否数组
if(!is_array($config))
{
$config = json_decode($config, true);
}
if(!empty($config))
{
foreach($config as &$v)
{
// 配置信息处理
if(!empty($v['config']))
{
$v['config']['frontend_config'] = empty($v['config']['frontend_config']) ? '' : self::FrontendConfigHandle($v['config']['frontend_config']);
}
// 布局类型
$v['value_arr'] = explode(':', $v['value']);
// 布局
if(!empty($v['children']) && is_array($v['children']))
{
foreach($v['children'] as &$vs)
{
// 配置信息处理
if(!empty($vs['config']))
{
$vs['config']['frontend_config'] = empty($vs['config']['frontend_config']) ? '' : self::FrontendConfigHandle($vs['config']['frontend_config']);
}
// 容器
if(!empty($vs['children']) && is_array($vs['children']))
{
// 模块
foreach($vs['children'] as &$vss)
{
if(!empty($vss['value']) && !empty($vss['config']))
{
// 前端配置信息处理
$vss['config']['frontend_config'] = empty($vss['config']['frontend_config']) ? '' : self::FrontendConfigHandle($vss['config']['frontend_config']);
// 滚动配置
if(array_key_exists('view_list_show_style_value', $vss['config']))
{
$vss['config']['view_list_show_style_value_arr'] = empty($vss['config']['view_list_show_style_value']) ? '' : json_decode(urldecode($vss['config']['view_list_show_style_value']), true);
}
// 根据模块类型处理
switch($vss['value'])
{
// 视频 video
case 'video' :
$vss['config']['content_video'] = ResourcesService::AttachmentPathViewHandle($vss['config']['content_video']);
break;
// 单图 images
case 'images' :
$vss['config']['content_images'] = ResourcesService::AttachmentPathViewHandle($vss['config']['content_images']);
break;
// 多图 many-images
case 'many-images' :
foreach($vss['config']['data_list'] as &$mil)
{
$mil['images'] = ResourcesService::AttachmentPathViewHandle($mil['images']);
}
$key = 'content_images_';
foreach($vss['config'] as $mik=>$miv)
{
if(substr($mik, 0, strlen($key)) == $key)
{
$vss['config'][$mik] = ResourcesService::AttachmentPathViewHandle($miv);
}
}
break;
// 商品
case 'goods' :
$p = [
'data_type' => $vss['config']['goods_data_type'],
];
switch($vss['config']['goods_data_type'])
{
// 指定商品
case 'goods' :
$p['goods_ids'] = $vss['config']['goods_ids'];
break;
// 商品分类
case 'category' :
$category = json_decode(urldecode($vss['config']['goods_category_value']), true);
$p['category_id'] = $category[count($category)-1]['id'];
$p['order_limit_number'] = empty($vss['config']['goods_order_limit_number']) ? 0 : $vss['config']['goods_order_limit_number'];
break;
}
$res = self::GoodsDataList($p);
$vss['config']['data_list'] = $res['data'];
break;
}
}
}
}
}
}
}
}
}
//print_r($config);die;
return $config;
}
/**
* 配置处理-展示使用
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-06-17
* @desc description
* @param [array] $config [配置信息]
* @param [array] $params [输入参数]
*/
public static function ConfigHandle($config, $params = [])
{
if(!empty($config))
{
// 是否数组
if(!is_array($config))
{
$config = json_decode($config, true);
}
if(!empty($config))
{
foreach($config as &$v)
{
// 配置信息处理
if(!empty($v['config']))
{
// 配置信息处理
$v['config'] = self::ConfigViewFieldHandle($v['config']);
}
// 布局类型
$v['value_arr'] = explode(':', $v['value']);
// 布局
if(!empty($v['children']) && is_array($v['children']))
{
foreach($v['children'] as &$vs)
{
// 配置信息处理
if(!empty($vs['config']))
{
// 配置信息处理
$vs['config'] = self::ConfigViewFieldHandle($vs['config']);
}
// 容器
if(!empty($vs['children']) && is_array($vs['children']))
{
// 模块
foreach($vs['children'] as &$vss)
{
if(!empty($vss['value']) && !empty($vss['config']))
{
// 配置信息处理
$vss['config'] = self::ConfigViewFieldHandle($vss['config']);
// 根据模块类型处理
switch($vss['value'])
{
// 视频 video
case 'video' :
$vss['config']['video'] = ResourcesService::AttachmentPathViewHandle($vss['config']['content_video']);
unset($vss['config']['content_video']);
break;
// 单图 images
case 'images' :
// 配置重新组合
$vss['config'] = [
'frontend_config' => $vss['config']['frontend_config'],
'images' => ResourcesService::AttachmentPathViewHandle($vss['config']['content_images']),
'url' => self::LayoutUrlValueHandle($vss['config']['content_to_type'], $vss['config']['content_to_value']),
];
break;
// 多图 many-images
case 'many-images' :
foreach($vss['config']['data_list'] as &$mil)
{
$mil = [
'images' => ResourcesService::AttachmentPathViewHandle($mil['images']),
'url' => self::LayoutUrlValueHandle($mil['type'], $mil['value']),
];
}
break;
// 商品
case 'goods' :
$p = [
'data_type' => $vss['config']['goods_data_type'],
];
switch($vss['config']['goods_data_type'])
{
// 指定商品
case 'goods' :
$p['goods_ids'] = $vss['config']['goods_ids'];
break;
// 商品分类
case 'category' :
$category = json_decode(urldecode($vss['config']['goods_category_value']), true);
$p['category_id'] = $category[count($category)-1]['id'];
$p['order_limit_number'] = empty($vss['config']['goods_order_limit_number']) ? 0 : $vss['config']['goods_order_limit_number'];
break;
}
$res = self::GoodsDataList($p);
$vss['config']['data_list'] = $res['data'];
break;
// 标题
case 'title' :
// 关键字
$keywords_list = [];
if(!empty($vss['config']['keywords_list']))
{
foreach($vss['config']['keywords_list'] as $wd)
{
$keywords_list[] = [
'keywords' => $wd['content_keywords'],
'color' => empty($wd['style_keywords_color']) ? '' : $wd['style_keywords_color'],
'url' => self::LayoutUrlValueHandle($wd['content_to_type'], $wd['content_to_value']),
];
}
}
// 配置重新组合
$vss['config'] = [
'frontend_config' => $vss['config']['frontend_config'],
'title' => $vss['config']['content_title'],
'title_vice' => $vss['config']['content_title_vice'],
'title_more' => $vss['config']['content_title_more'],
'title_more_url' => self::LayoutUrlValueHandle($vss['config']['content_to_type'], $vss['config']['content_to_value']),
'keywords_list' => $keywords_list,
];
break;
}
}
}
}
}
}
}
}
}
//print_r($config);die;
return $config;
}
/**
* 配置信息字段处理
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-06-22
* @desc description
* @param [array] $config [配置信息]
*/
public static function ConfigViewFieldHandle($config)
{
if(!empty($config) && is_array($config))
{
// 配置信息多余字段移除
$arr = [
'style_',
'content_item_keywords_',
'content_images_',
'content_to_type_',
'content_to_name_',
'content_to_value_',
'view_list_number_',
];
foreach($config as $k=>$v)
{
foreach($arr as $f)
{
$length = strlen($f);
if(substr($k, 0, $length) == $f)
{
unset($config[$k]);
}
}
}
// 前端配置处理
$config['frontend_config'] = empty($config['frontend_config']) ? '' : self::FrontendConfigHandle($config['frontend_config']);
// 滚动配置
if(array_key_exists('view_list_show_style_value', $config))
{
$config['view_list_show_style_value_arr'] = empty($config['view_list_show_style_value']) ? '' : json_decode(urldecode($config['view_list_show_style_value']), true);
unset($config['view_list_show_style_value']);
}
}
return $config;
}
/**
* 链接地址处理
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-06-22
* @desc description
* @param [string] $type [类型]
* @param [string] $value [特殊地址配置值]
*/
public static function LayoutUrlValueHandle($type, $value)
{
// 当前客户端类型
$client_type = ApplicationClientType();
// url地址、默认空字符串
$url = '';
// 静态地址定义-web端
$static_url_web_arr = [
'home' => __MY_URL__,
'goods_category' => MyUrl('index/category/index'),
'cart' => MyUrl('index/cart/index'),
'user_center' => MyUrl('index/user/index'),
'user_order_list' => MyUrl('index/order/index'),
'user_order_aftersale_list' => MyUrl('index/orderaftersale/index'),
'user_goods_favor_list' => MyUrl('index/usergoodsfavor/index'),
'user_address_list' => MyUrl('index/useraddress/index'),
'user_goods_browse_list' => MyUrl('index/usergoodsbrowse/index'),
'user_integral_list' => MyUrl('index/userintegral/index'),
'user_answer_list' => MyUrl('index/answer/index'),
'user_message_list' => MyUrl('index/message/index'),
];
// 静态地址定义-手机端
$static_url_app_arr = [
'home' => '/pages/index/index',
'goods_category' => '/pages/goods-category/goods-category',
'cart' => '/pages/cart/cart',
'user_center' => '/pages/user/user',
'user_order_list' => '/pages/user-order/user-order',
'user_order_aftersale_list' => '/pages/user-orderaftersale/user-orderaftersale',
'user_goods_favor_list' => '/pages/user-faovr/user-faovr',
'user_address_list' => '/pages/user-address/user-address',
'user_goods_browse_list' => '/pages/user-goods-browse/user-goods-browse',
'user_integral_list' => '/pages/user-integral/user-integral',
'user_answer_list' => '/pages/user-answer-list/user-answer-list',
'user_message_list' => '/pages/message/message',
];
// 静态地址
$static_url_arr = ($client_type == 'pc') ? $static_url_web_arr : $static_url_app_arr;
if(array_key_exists($type, $static_url_arr))
{
$url = $static_url_arr[$type];
} else {
switch($type)
{
// 商品
case 'goods' :
if(!empty($value) && $value['id'])
{
$url = MyUrl('index/goods/index', ['id'=>$value['id']]);
}
break;
// 商品分类
case 'goods_search' :
$url = 'goods_search';
break;
}
}
return $url;
}
/**
* 前端配置处理
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-06-18
* @desc description
* @param [array] $data [配偶者数据]
*/
public static function FrontendConfigHandle($data)
{
if(!empty($data) && is_array($data))
{
foreach($data as &$v)
{
if(is_array($v))
{
foreach($v as &$vs)
{
$vs = empty($vs) ? '' : urldecode($vs);
}
} else {
$v = empty($v) ? '' : urldecode($v);
}
}
}
return $data;
}
/**
* 商品搜索
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2020-07-13
* @desc description
* @param [array] $params [输入参数]
*/
public static function GoodsSearchList($params = [])
{
// 返回数据
$result = [
'page_total' => 0,
'page_size' => 20,
'page' => max(1, isset($params['page']) ? intval($params['page']) : 1),
'total' => 0,
'data' => [],
];
// 条件
$where = [
['g.is_delete_time', '=', 0],
['g.is_shelves', '=', 1],
];
// 关键字
if(!empty($params['keywords']))
{
$where[] = ['g.title', 'like', '%'.$params['keywords'].'%'];
}
// 数据分类id
if(!empty($params['category_id']))
{
// 默认系统商品分类,并读取分类子级
$category_field = empty($params['category_field']) ? 'gci.category_id' : $params['category_field'];
if($category_field == 'gci.category_id')
{
$category_id = GoodsService::GoodsCategoryItemsIds([intval($params['category_id'])]);
} else {
$category_id = [intval($params['category_id'])];
}
$where[] = [$category_field, 'in', $category_id];
}
// 获取商品总数
$result['total'] = GoodsService::CategoryGoodsTotal($where);
// 获取商品列表
if($result['total'] > 0)
{
// 基础参数
$field = 'g.id,g.title,g.images';
$order_by = 'g.id desc';
// 分页计算
$m = intval(($result['page']-1)*$result['page_size']);
$ret = GoodsService::CategoryGoodsList(['where'=>$where, 'm'=>$m, 'n'=>$result['page_size'], 'field'=>$field, 'order_by'=>$order_by]);
$result['data'] = $ret['data'];
$result['page_total'] = ceil($result['total']/$result['page_size']);
// 数据处理
if(!empty($result['data']) && is_array($result['data']) && !empty($params['goods_ids']))
{
$goods_ids = is_array($params['goods_ids']) ? $params['goods_ids'] : explode(',', $params['goods_ids']);
foreach($result['data'] as &$v)
{
// 是否已添加
$v['is_exist'] = in_array($v['id'], $goods_ids) ? 1 : 0;
}
}
}
return DataReturn('处理成功', 0, $result);
}
/**
* 商品数据
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2020-07-13
* @desc description
* @param [array] $params [输入参数]
*/
public static function GoodsDataList($params = [])
{
// 数据类型、默认商品
$data_type = empty($params['data_type']) ? 'goods' : $params['data_type'];
switch($data_type)
{
// 商品
case 'goods' :
// 参数处理
if(empty($params['goods_ids']))
{
return DataReturn('商品id为空', -1);
}
if(!is_array($params['goods_ids']))
{
$params['goods_ids'] = explode(',', $params['goods_ids']);
}
// 读取数量
$m = 0;
$n = 50;
// 获取商品
$order_by = 'id desc';
$field = 'id,title,images,price,original_price,min_price,max_price,min_original_price,max_original_price,inventory,inventory_unit';
$where = [
['is_delete_time', '=', 0],
['is_shelves', '=', 1],
['id', 'in', $params['goods_ids']],
];
break;
// 商品分类
case 'category' :
// 参数处理
if(empty($params['category_id']))
{
return DataReturn('商品分类id为空', -1);
}
// 排序处理
$order_by_type_list = lang('goods_order_by_type_list');
$order_by_rule_list = lang('goods_order_by_rule_list');
// 排序类型
$order_by_type = empty($params['order_by_type']) ? $order_by_type_list[0]['value'] : (array_key_exists($params['order_by_type'], $order_by_type_list) ? $order_by_type_list[$params['order_by_type']]['value'] : $order_by_type_list[0]['value']);
// 排序规则
$order_by_rule = empty($params['order_by_rule']) ? $order_by_rule_list[0]['value'] : (array_key_exists($params['order_by_rule'], $order_by_rule_list) ? $order_by_rule_list[$params['order_by_rule']]['value'] : $order_by_rule_list[0]['value']);
// 读取数量
$m = 0;
$n = min(empty($params['order_limit_number']) ? 50 : intval($params['order_limit_number']), 50);
// 获取商品
$order_by = $order_by_type.' '.$order_by_rule;
$field = 'g.id,g.title,g.images,g.price,g.original_price,g.min_price,g.max_price,g.min_original_price,g.max_original_price,g.inventory,g.inventory_unit';
$where = [
['gci.category_id', 'in', GoodsService::GoodsCategoryItemsIds([intval($params['category_id'])])],
['g.is_delete_time', '=', 0],
['g.is_shelves', '=', 1],
];
break;
default :
return DataReturn('数据类型未处理['.$params['data_type'].']', -1);
}
// 商品搜索列表读取钩子
$hook_name = 'plugins_layout_service_search_goods_begin';
Hook::listen($hook_name, [
'hook_name' => $hook_name,
'is_backend' => true,
'params' => $params,
'data_type' => $data_type,
'where' => &$where,
'field' => &$field,
'm' => &$m,
'n' => &$n,
'order_by' => &$order_by,
]);
// 根据请求类型处理数据读取
switch($data_type)
{
// 商品
case 'goods' :
$request_params = [
'where' => $where,
'm' => $m,
'n' => $n,
'field' => $field,
'order_by' => $order_by,
];
$ret = GoodsService::GoodsList($request_params);
break;
// 商品分类
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());
break;
}
if(!empty($ret) && isset($ret['code']) && $ret['code'] == 0 && !empty($ret['data']))
{
return $ret;
}
return DataReturn('无商品信息', -1);
}
/**
* 页面数据
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-05-14
* @desc description
* @param [array] $params [输入参数]
*/
public static function PagesList($params = [])
{
return [
// 公共
'common' => [
'name' => '系统页面',
'data' => [
[
'value' => 'home',
'name' => '商城首页',
],
[
'value' => 'goods_category',
'name' => '全部商品分类',
],
[
'value' => 'goods_search',
'name' => '商品搜索',
'tips' => '可带参数关键字、商品分类id、品牌id',
],
[
'value' => 'goods',
'name' => '单一商品',
],
[
'value' => 'cart',
'name' => '购物车',
],
[
'value' => 'user_center',
'name' => '用户中心',
],
[
'value' => 'user_order_list',
'name' => '我的订单',
],
[
'value' => 'user_order_aftersale_list',
'name' => '订单售后',
],
[
'value' => 'user_goods_favor_list',
'name' => '商品收藏',
],
[
'value' => 'user_address_list',
'name' => '我的地址',
],
[
'value' => 'user_goods_browse_list',
'name' => '我的足迹',
],
[
'value' => 'user_integral_list',
'name' => '我的积分',
],
[
'value' => 'user_message_list',
'name' => '我的消息',
],
[
'value' => 'user_answer_list',
'name' => '问答/留言',
],
],
],
// 插件
'plugins' => [
'name' => '扩展模块',
'data' => [
[
'name' => '多商户',
'value' => 'shop',
'tips' => '暂时不支持小程序',
'data' => [
[
'value' => 'home',
'name' => '店铺首页',
],
[
'value' => 'goods_category',
'name' => '商品分类',
],
],
],
],
],
];
}
}
?>

View File

@ -0,0 +1,119 @@
<!-- 布局/模块导航-->
<div class="am-tabs renovation-tabs">
<ul class="am-tabs-nav am-nav am-nav-tabs">
<li class="am-active" data-value="structure"><a href="#renovation-tabs-structure">布局</a></li>
<li data-value="module"><a href="#renovation-tabs-module">模块</a></li>
</ul>
<div class="am-tabs-bd am-padding-sm">
<!-- 布局 -->
<div class="renovation-panel am-active" id="renovation-tabs-structure">
<div class="am-alert" data-am-alert>
<button type="button" class="am-close">&times;</button>
<p>1. 手机模式下每一块布局全部自动100%展示、从左往右依次往下排版</p>
<p>2. 布局宽度以100%分为12块、每一块占比8.33%</p>
<p>3. 小屏640px及以下、中屏641px及以上、大屏1025px及以上</p>
</div>
<div class="structure-drag scrollspy-nav" data-am-tabs="{noSwipe: 1}" data-am-sticky>
<button type="button" draggable="true" class="am-btn am-btn-default am-radius am-btn-xs am-margin-xs" data-value="100">100%</button>
<button type="button" draggable="true" class="am-btn am-btn-default am-radius am-btn-xs am-margin-xs" data-value="6:6">6 : 6</button>
<button type="button" draggable="true" class="am-btn am-btn-default am-radius am-btn-xs am-margin-xs" data-value="9:3">9 : 3</button>
<button type="button" draggable="true" class="am-btn am-btn-default am-radius am-btn-xs am-margin-xs" data-value="3:9">3 : 9</button>
<button type="button" draggable="true" class="am-btn am-btn-default am-radius am-btn-xs am-margin-xs" data-value="6:3:3">6 : 3 : 3</button>
<button type="button" draggable="true" class="am-btn am-btn-default am-radius am-btn-xs am-margin-xs" data-value="3:6:3">3 : 6 : 3</button>
<button type="button" draggable="true" class="am-btn am-btn-default am-radius am-btn-xs am-margin-xs" data-value="3:3:6">3 : 3 : 6</button>
<button type="button" draggable="true" class="am-btn am-btn-default am-radius am-btn-xs am-margin-xs" data-value="4:4:4">x 3</button>
<button type="button" draggable="true" class="am-btn am-btn-default am-radius am-btn-xs am-margin-xs" data-value="3:3:3:3">x 4</button>
<button type="button" draggable="true" class="am-btn am-btn-default am-radius am-btn-xs am-margin-xs" data-value="2:2:2:2:2:2">x 6</button>
</div>
</div>
<!-- 模块 -->
<div class="renovation-panel am-hide" id="renovation-tabs-module">
<div class="renovation-drag scrollspy-nav" data-am-tabs="{noSwipe: 1}" data-am-sticky>
<button type="button" draggable="true" class="am-btn am-btn-default am-radius am-btn-xs am-margin-xs" data-value="images">单图</button>
<button type="button" draggable="true" class="am-btn am-btn-default am-radius am-btn-xs am-margin-xs" data-value="many-images">多图</button>
<button type="button" draggable="true" class="am-btn am-btn-default am-radius am-btn-xs am-margin-xs" data-value="video">视频</button>
<button type="button" draggable="true" class="am-btn am-btn-default am-radius am-btn-xs am-margin-xs" data-value="goods">商品</button>
<button type="button" draggable="true" class="am-btn am-btn-default am-radius am-btn-xs am-margin-xs" data-value="title">标题</button>
<button type="button" draggable="true" class="am-btn am-btn-default am-radius am-btn-xs am-margin-xs" data-value="border">辅助线</button>
<button type="button" draggable="true" class="am-btn am-btn-default am-radius am-btn-xs am-margin-xs" data-value="height">辅助空白</button>
</div>
</div>
</div>
</div>
<!-- 拖拽容器-->
<div class="layout-container am-padding-sm am-margin-top-sm">
{{if !empty($layout_data) and is_array($layout_data)}}
{{foreach $layout_data as $k=>$v}}
{{if !empty($v['value']) and !empty($v['children']) and is_array($v['children']) and !empty($v['value_arr']) and count($v['children']) eq count($v['value_arr'])}}
<div class="layout-view {{if $v['status'] eq 0}}layout-view-hidden{{/if}}" data-value="{{$v.value}}">
<i class="layout-view-dragenter-icon am-icon-sort-asc am-icon-lg am-hide"></i>
<div class="layout-content-submit drag-submit">
<input type="checkbox" class="switch-checkbox" data-size="xs" data-on-color="success" data-off-color="warning" data-off-text="关闭" data-on-text="开启" {{if isset($v['status']) and $v['status'] eq 1}}checked="true"{{/if}} />
<button type="button" class="am-btn am-btn-secondary am-radius am-btn-xs am-icon-square-o layout-submit layout-submit-set"> 布局设置</button>
<button type="button" class="am-btn am-btn-danger am-radius am-btn-xs am-icon-trash-o layout-submit layout-submit-del"> 布局移除</button>
</div>
<div class="layout-content-children {{if !empty($v['config']) and !empty($v['config']['frontend_config'])}}{{$v.config.frontend_config.ent}}{{/if}}" data-json="{{if !empty($v['config'])}}{{:urlencode(json_encode($v['config']))}}{{/if}}" style="{{if !empty($v['config']) and !empty($v['config']['frontend_config'])}}{{$v.config.frontend_config.style}}{{/if}}">
{{foreach $v.children as $ks=>$vs}}
{{if count($v['value_arr']) eq 1}}
{{include file="../../../layout/view/public/common/module_admin" /}}
{{else /}}
<div class="am-u-md-{{$v['value_arr'][$ks]}}">
{{include file="../../../layout/view/public/common/module_admin" /}}
</div>
{{/if}}
{{/foreach}}
</div>
</div>
{{/if}}
{{/foreach}}
{{else /}}
<div class="layout-container-tips">布局拖放到该区域松开鼠标即可</div>
{{/if}}
</div>
<!-- 侧边栏 - 布局 - 容器设置 -->
{{include file="../../../layout/view/public/offcanvas/offcanvas_layout_config" /}}
<!-- 侧边栏 - 模块配置 - 单图 -->
{{include file="../../../layout/view/public/offcanvas/offcanvas_module_config_images" /}}
<!-- 侧边栏 - 模块配置 - 多图 -->
{{include file="../../../layout/view/public/offcanvas/offcanvas_module_config_many_images" /}}
<!-- 侧边栏 - 模块配置 - 视频 -->
{{include file="../../../layout/view/public/offcanvas/offcanvas_module_config_video" /}}
<!-- 侧边栏 - 模块配置 - 商品 -->
{{include file="../../../layout/view/public/offcanvas/offcanvas_module_config_goods" /}}
<!-- 侧边栏 - 模块配置 - 标题 -->
{{include file="../../../layout/view/public/offcanvas/offcanvas_module_config_title" /}}
<!-- 侧边栏 - 模块配置 - 辅助线 -->
{{include file="../../../layout/view/public/offcanvas/offcanvas_module_config_border" /}}
<!-- 侧边栏 - 模块配置 - 辅助空白 -->
{{include file="../../../layout/view/public/offcanvas/offcanvas_module_config_height" /}}
<!-- 滚动设置 -->
{{include file="../../../layout/view/public/modal/modal_module_rolling_config" /}}
<!-- 列表设置 -->
{{include file="../../../layout/view/public/modal/modal_module_list_config" /}}
<!-- 关键字设置 -->
{{include file="../../../layout/view/public/modal/modal_module_title_keywords" /}}
<!-- 页面选择 -->
{{include file="../../../layout/view/public/modal/modal_module_pages_select" /}}
<!-- 商品选择 -->
{{include file="../../../layout/view/public/popup/popup_module_goods_select" /}}
<!-- 商品搜索 -->
{{include file="../../../layout/view/public/popup/popup_module_goods_search" /}}
<!-- 商品分类选择 -->
{{include file="../../../layout/view/public/popup/popup_module_goods_category" /}}

View File

@ -0,0 +1,74 @@
<script type="text/javascript">
// 容器设置回调处理
function FormBackLayoutConfig(e)
{
FormBackLayoutConfigHandle(e);
}
// 单图选择回调处理
function FormBackModuleConfigImages(e)
{
FormBackModuleConfigImagesHandle(e);
}
// 多图选择回调处理
function FormBackModuleConfigManyImages(e)
{
FormBackModuleConfigManyImagesHandle(e);
}
// 视频选择回调处理
function FormBackModuleConfigVideo(e)
{
FormBackModuleConfigVideoHandle(e);
}
// 商品选择回调处理
function FormBackModuleConfigGoods(e)
{
FormBackModuleConfigGoodsHandle(e);
}
// 标题选择回调处理
function FormBackModuleConfigTitle(e)
{
FormBackModuleConfigTitleHandle(e);
}
// 辅助线选择回调处理
function FormBackModuleConfigBorder(e)
{
FormBackModuleConfigBorderHandle(e);
}
// 辅助空白选择回调处理
function FormBackModuleConfigHeight(e)
{
FormBackModuleConfigHeightHandle(e);
}
// 滚动配置回调处理
function FormBackModuleModalRollingConfig(e)
{
FormBackModuleModalRollingConfigHandle(e);
}
// 列表配置回调处理
function FormBackModuleModalListConfig(e)
{
FormBackModuleModalListConfigHandle(e);
}
// 标题关键字回调处理
function FormBackModuleModalTitleKeywords(e)
{
FormBackModuleModalTitleKeywordsHandle(e);
}
// 弹窗搜索选择回调处理
function FormBackModulePopupGoodsSearch(e)
{
FormBackModulePopupGoodsSearchHandle(e);
}
</script>

View File

@ -0,0 +1,24 @@
{{if !empty($goods_category_list)}}
<div class="goods-category-choice-content am-nbfc am-padding-lg">
<ul class="goods-category-select-1 am-scrollable-vertical am-list am-list-border am-fl" data-level="1">
{{foreach $goods_category_list as $k=>$v}}
<li>
<a href="javascript:;" data-json="{{:urlencode(json_encode($v['items']))}}" data-index="{{$k}}" data-value="{{$v.id}}">
<span>{{$v.name}}</span>
{{if !empty($v['items'])}}
<i class="am-icon-angle-double-right am-fr"></i>
{{/if}}
</a>
</li>
{{/foreach}}
</ul>
<ul class="goods-category-select-2 am-scrollable-vertical am-list am-list-border am-fl am-margin-left-lg am-hide" data-level="2"></ul>
<ul class="goods-category-select-3 am-scrollable-vertical am-list am-list-border am-fl am-margin-left-lg am-hide" data-level="3"></ul>
</div>
<p class="already-select-tips am-margin-top-lg am-hide">
<span>您当前选择的商品类别是:</span>
<strong></strong>
</p>
{{else /}}
<div class="table-no"><i class="am-icon-warning"></i> 无商品分类</div>
{{/if}}

View File

@ -0,0 +1,21 @@
{{if !empty($data)}}
{{foreach $data as $v}}
<li data-gid="{{$v.id}}" data-url="{{$v.goods_url}}" data-title="{{$v.title}}" data-img="{{$v.images}}" data-add-html='<a href="javascript:;" class="am-icon-btn am-icon-check am-success goods-add-submit" data-type="add"></a>' data-del-html='<a href="javascript:;" class="am-icon-btn am-icon-remove am-danger goods-del-submit" data-type="del"></a>'>
<div class="am-gallery-item am-radius">
<a href="{{$v.goods_url}}" target="_blank" title="{{$v.title}}">
<img src="{{$v.images}}" alt="{{$v.title}}" />
</a>
<h3 class="am-gallery-title">{{$v.title}}</h3>
<div class="icon-submit-container">
{{if isset($v['is_exist']) and $v['is_exist'] eq 1}}
<a href="javascript:;" class="am-icon-btn am-icon-remove am-danger goods-del-submit" data-type="del"></a>
{{else /}}
<a href="javascript:;" class="am-icon-btn am-icon-check am-success goods-add-submit" data-type="add"></a>
{{/if}}
</div>
</div>
</li>
{{/foreach}}
{{else /}}
<div class="table-no"><i class="am-icon-warning"></i> 没有相关商品</div>
{{/if}}

View File

@ -0,0 +1,148 @@
<div class="layout-content-container {{if !empty($vs['config']) and !empty($vs['config']['frontend_config'])}}{{$vs.config.frontend_config.ent}}{{/if}}" data-json="{{if !empty($vs['config'])}}{{:urlencode(json_encode($vs['config']))}}{{/if}}" style="{{if !empty($vs['config']) and !empty($vs['config']['frontend_config'])}}{{$vs.config.frontend_config.style}}{{/if}}">
<div class="layout-content-submit-container">
<button type="button" class="am-btn am-btn-secondary am-radius am-btn-xs am-icon-gear layout-submit layout-content-submit-set"></button>
</div>
<div class="layout-content">
{{if !empty($vs['children']) and is_array($vs['children'])}}
{{foreach $vs.children as $kss=>$vss}}
<div class="module-view">
<div class="module-view-submit-container" data-value="{{$vss.value}}" data-index="{{$k}}{{$ks}}{{$kss}}" data-doc=".module-content-index-{{$vss.value}}-{{$k}}{{$ks}}{{$kss}}">
<button type="button" class="am-btn am-btn-secondary am-radius am-btn-xs am-icon-reorder layout-submit module-view-submit-drag"></button>
<button type="button" class="am-btn am-btn-secondary am-radius am-btn-xs am-icon-folder-open-o layout-submit module-view-submit-set"></button>
<button type="button" class="am-btn am-btn-danger am-radius am-btn-xs am-icon-trash-o layout-submit module-view-submit-del"></button>
</div>
<div class="module-content module-content-type-{{$vss.value}} module-content-index-{{$vss.value}}-{{$k}}{{$ks}}{{$kss}}" data-json="{{if !empty($vss['config'])}}{{:urlencode(json_encode($vss['config']))}}{{/if}}">
{{if !empty($vss['config'])}}
<div class="module-{{$vss.value}}-container" style="{{if isset($vss['config']['frontend_config']['style'])}}{{$vss.config.frontend_config.style}}{{/if}}">
{{switch vss.value}}
{{case images}}
<a href="javascript:ModuleToPrompt('{{$vss.config.content_to_name}}');" class="{{$vss.config.frontend_config.media_fixed.media_container_ent}}" style="{{$vss.config.frontend_config.media_fixed.media_container_style}}">
<img src="{{$vss.config.content_images}}" class="{{$vss.config.frontend_config.media_fixed.media_ent}}" />
</a>
{{/case}}
{{case many-images}}
{{switch vss.config.view_list_show_style}}
{{case rolling}}
<div class="am-slider am-slider-default am-slider-carousel {{$vss.config.frontend_config.nav_dot_ent}}" data-am-flexslider="{itemWidth: {{if empty($vss['config']['view_list_show_style_value_arr']) or empty($vss['config']['view_list_show_style_value_arr']['item_width'])}}200{{else /}}{{$vss.config.view_list_show_style_value_arr.item_width}}{{/if}}, itemMargin: {{if empty($vss['config']['view_list_show_style_value_arr']) or empty($vss['config']['view_list_show_style_value_arr']['item_margin'])}}0{{else /}}{{$vss.config.view_list_show_style_value_arr.item_margin}}{{/if}}, slideshow: {{if empty($vss['config']['view_list_show_style_value_arr']) or !isset($vss['config']['view_list_show_style_value_arr']['is_auto_play']) or $vss['config']['view_list_show_style_value_arr']['is_auto_play'] eq 0}}false{{else /}}true{{/if}}, controlNav: {{if empty($vss['config']['view_list_show_style_value_arr']) or !isset($vss['config']['view_list_show_style_value_arr']['is_nav_dot']) or $vss['config']['view_list_show_style_value_arr']['is_nav_dot'] eq 0}}false{{else /}}true{{/if}}}">
<ul class="am-slides">
{{foreach $vss.config.data_list as $i}}
<li>
<a href="javascript:ModuleToPrompt('{{$i.name}}');" class="{{$vss.config.frontend_config.media_fixed.media_container_ent}}" style="{{$vss.config.frontend_config.media_fixed.media_container_style}}">
<img src="{{$i.images}}" class="{{$vss.config.frontend_config.media_fixed.media_ent}}" />
</a>
</li>
{{/foreach}}
</ul>
</div>
{{/case}}
{{case list}}
<ul class="module-list-content {{$vss.config.frontend_config.list_ent}}">
{{foreach $vss.config.data_list as $i}}
<li>
<div class="module-item" style="{{$vss.config.frontend_config.item_style}}">
<a href="javascript:ModuleToPrompt('{{$i.name}}');" class="{{$vss.config.frontend_config.media_fixed.media_container_ent}}" style="{{$vss.config.frontend_config.media_fixed.media_container_style}}">
<img src="{{$i.images}}" class="{{$vss.config.frontend_config.media_fixed.media_ent}}" />
</a>
</div>
</li>
{{/foreach}}
</ul>
{{/case}}
{{default /}}
<div data-am-widget="slider" class="am-slider am-slider-a1" data-am-slider='{"directionNav":false}'>
<ul class="am-slides">
{{foreach $vss.config.data_list as $i}}
<li>
<a href="javascript:ModuleToPrompt('{{$i.name}}');" class="{{$vss.config.frontend_config.media_fixed.media_container_ent}}" style="{{$vss.config.frontend_config.media_fixed.media_container_style}}">
<img src="{{$i.images}}" class="{{$vss.config.frontend_config.media_fixed.media_ent}}" />
</a>
</li>
{{/foreach}}
</ul>
</div>
{{/switch}}
{{/case}}
{{case video}}
<div class="module-video-content" class="{{$vss.config.frontend_config.media_fixed.media_container_ent}}" style="{{$vss.config.frontend_config.media_fixed.media_container_style}}">
<video src="{{$vss.config.content_video}}" poster="{{if !empty($vss['config']['content_images'])}}{{$vss.config.content_images}}{{/if}}" controls class="{{$vss.config.frontend_config.media_fixed.media_ent}}">your browser does not support the video tag</video>
</div>
{{/case}}
{{case goods}}
{{switch vss.config.view_list_show_style}}
{{case rolling}}
<div class="am-slider am-slider-default am-slider-carousel {{$vss.config.frontend_config.nav_dot_ent}}" data-am-flexslider="{itemWidth: {{if empty($vss['config']['view_list_show_style_value_arr']) or empty($vss['config']['view_list_show_style_value_arr']['item_width'])}}200{{else /}}{{$vss.config.view_list_show_style_value_arr.item_width}}{{/if}}, itemMargin: {{if empty($vss['config']['view_list_show_style_value_arr']) or empty($vss['config']['view_list_show_style_value_arr']['item_margin'])}}0{{else /}}{{$vss.config.view_list_show_style_value_arr.item_margin}}{{/if}}, slideshow: {{if empty($vss['config']['view_list_show_style_value_arr']) or !isset($vss['config']['view_list_show_style_value_arr']['is_auto_play']) or $vss['config']['view_list_show_style_value_arr']['is_auto_play'] eq 0}}false{{else /}}true{{/if}}, controlNav: {{if empty($vss['config']['view_list_show_style_value_arr']) or !isset($vss['config']['view_list_show_style_value_arr']['is_nav_dot']) or $vss['config']['view_list_show_style_value_arr']['is_nav_dot'] eq 0}}false{{else /}}true{{/if}}}">
<div class="am-viewport">
<ul class="am-slides module-list-content">
{{foreach $vss.config.data_list as $g}}
<li>
<div class="module-item" style="{{$vss.config.frontend_config.item_style}}">
<a href="{{$g.goods_url}}" target="_blank" class="{{$vss.config.frontend_config.media_fixed.media_container_ent}}" style="{{$vss.config.frontend_config.media_fixed.media_container_style}}">
<img src="{{$g.images}}" alt="{{$g.title}}" class="{{$vss.config.frontend_config.media_fixed.media_ent}}" />
</a>
<div class="item-bottom">
<div class="module-title">
<a href="{{$g.goods_url}}" target="_blank">{{$g.title}}</a></div>
<p class="module-price">{{$currency_symbol}}{{$g.price}}</p>
</div>
</div>
</li>
{{/foreach}}
</ul>
</div>
</div>
{{/case}}
{{default /}}
<ul class="module-list-content {{$vss.config.frontend_config.list_ent}}">
{{foreach $vss.config.data_list as $g}}
<li>
<div class="module-item" style="{{$vss.config.frontend_config.item_style}}">
<a href="{{$g.goods_url}}" target="_blank" class="{{$vss.config.frontend_config.media_fixed.media_container_ent}}" style="{{$vss.config.frontend_config.media_fixed.media_container_style}}">
<img src="{{$g.images}}" alt="{{$g.title}}" class="{{$vss.config.frontend_config.media_fixed.media_ent}}" />
</a>
<div class="item-bottom">
<div class="module-title">
<a href="{{$g.goods_url}}" target="_blank">{{$g.title}}</a></div>
<p class="module-price">{{$currency_symbol}}{{$g.price}}</p>
</div>
</div>
</li>
{{/foreach}}
</ul>
{{/switch}}
{{/case}}
{{case title}}
<div class="module-title-content">
<span class="title-main" style="{{$vss.config.frontend_config.style_title_main}}">{{$vss.config.content_title}}</span>
{{if !empty($vss['config']['content_title_vice'])}}
<span class="title-vice" style="{{$vss.config.frontend_config.style_title_vice}}">{{$vss.config.content_title_vice}}</span>
{{/if}}
{{if !empty($vss['config']['keywords_list'])}}
<div class="keywords-content">
{{foreach $vss.config.keywords_list as $wd}}
<a href="javascript:ModuleToPrompt('{{$wd.content_to_name}}');" {{if !empty($wd['style_keywords_color'])}}style="color:{{$wd.style_keywords_color}};"{{/if}}>{{$wd.content_keywords}}</a>
{{/foreach}}
</div>
{{/if}}
{{if !empty($vss['config']['content_title_more'])}}
<div class="more-content">
<a href="javascript:ModuleToPrompt('{{$vss.config.content_to_name}}');" style="{{$vss.config.frontend_config.style_title_more}}">
<span>{{$vss.config.content_title_more}}</span>
<i class="am-icon-angle-right"></i>
</a>
</div>
{{/if}}
</div>
{{/case}}
{{/switch}}
</div>
{{else /}}
<div class="am-text-center am-padding-vertical-sm am-text-primary">{{$vss.name}}</div>
{{/if}}
</div>
</div>
{{/foreach}}
{{else /}}
<div class="layout-content-tips">模块内容区域</div>
{{/if}}
</div>
</div>

View File

@ -0,0 +1,138 @@
<div class="layout-content-container {{if !empty($vs['config']) and !empty($vs['config']['frontend_config'])}}{{$vs.config.frontend_config.ent}}{{/if}}" style="{{if !empty($vs['config']) and !empty($vs['config']['frontend_config'])}}{{$vs.config.frontend_config.style}}{{/if}}">
<div class="layout-content">
{{if !empty($vs['children']) and is_array($vs['children'])}}
{{foreach $vs.children as $kss=>$vss}}
<div class="module-view">
<div class="module-content">
{{if !empty($vss['config'])}}
<div class="module-{{$vss.value}}-container" style="{{if isset($vss['config']['frontend_config']['style'])}}{{$vss.config.frontend_config.style}}{{/if}}">
{{switch vss.value}}
{{case images}}
<a {{if empty($vss['config']['url'])}}href="javascript:;"{{else /}}href="{{$vss.config.url}}" target="_blank"{{/if}} class="{{$vss.config.frontend_config.media_fixed.media_container_ent}}" style="{{$vss.config.frontend_config.media_fixed.media_container_style}}">
<img src="{{$vss.config.images}}" class="{{$vss.config.frontend_config.media_fixed.media_ent}}" />
</a>
{{/case}}
{{case many-images}}
{{switch vss.config.view_list_show_style}}
{{case rolling}}
<div class="am-slider am-slider-default am-slider-carousel {{$vss.config.frontend_config.nav_dot_ent}}" data-am-flexslider="{itemWidth: {{if empty($vss['config']['view_list_show_style_value_arr']) or empty($vss['config']['view_list_show_style_value_arr']['item_width'])}}200{{else /}}{{$vss.config.view_list_show_style_value_arr.item_width}}{{/if}}, itemMargin: {{if empty($vss['config']['view_list_show_style_value_arr']) or empty($vss['config']['view_list_show_style_value_arr']['item_margin'])}}0{{else /}}{{$vss.config.view_list_show_style_value_arr.item_margin}}{{/if}}, slideshow: {{if empty($vss['config']['view_list_show_style_value_arr']) or !isset($vss['config']['view_list_show_style_value_arr']['is_auto_play']) or $vss['config']['view_list_show_style_value_arr']['is_auto_play'] eq 0}}false{{else /}}true{{/if}}, controlNav: {{if empty($vss['config']['view_list_show_style_value_arr']) or !isset($vss['config']['view_list_show_style_value_arr']['is_nav_dot']) or $vss['config']['view_list_show_style_value_arr']['is_nav_dot'] eq 0}}false{{else /}}true{{/if}}}">
<ul class="am-slides">
{{foreach $vss.config.data_list as $i}}
<li>
<a {{if empty($i['url'])}}href="javascript:;"{{else /}}href="{{$i.url}}" target="_blank"{{/if}} class="{{$vss.config.frontend_config.media_fixed.media_container_ent}}" style="{{$vss.config.frontend_config.media_fixed.media_container_style}}">
<img src="{{$i.images}}" class="{{$vss.config.frontend_config.media_fixed.media_ent}}" />
</a>
</li>
{{/foreach}}
</ul>
</div>
{{/case}}
{{case list}}
<ul class="module-list-content {{$vss.config.frontend_config.list_ent}}">
{{foreach $vss.config.data_list as $i}}
<li>
<div class="module-item" style="{{$vss.config.frontend_config.item_style}}">
<a {{if empty($i['url'])}}href="javascript:;"{{else /}}href="{{$i.url}}" target="_blank"{{/if}} class="{{$vss.config.frontend_config.media_fixed.media_container_ent}}" style="{{$vss.config.frontend_config.media_fixed.media_container_style}}">
<img src="{{$i.images}}" class="{{$vss.config.frontend_config.media_fixed.media_ent}}" />
</a>
</div>
</li>
{{/foreach}}
</ul>
{{/case}}
{{default /}}
<div data-am-widget="slider" class="am-slider am-slider-a1" data-am-slider='{"directionNav":false}'>
<ul class="am-slides">
{{foreach $vss.config.data_list as $i}}
<li>
<a {{if empty($i['url'])}}href="javascript:;"{{else /}}href="{{$i.url}}" target="_blank"{{/if}} class="{{$vss.config.frontend_config.media_fixed.media_container_ent}}" style="{{$vss.config.frontend_config.media_fixed.media_container_style}}">
<img src="{{$i.images}}" class="{{$vss.config.frontend_config.media_fixed.media_ent}}" />
</a>
</li>
{{/foreach}}
</ul>
</div>
{{/switch}}
{{/case}}
{{case video}}
<div class="module-video-content" class="{{$vss.config.frontend_config.media_fixed.media_container_ent}}" style="{{$vss.config.frontend_config.media_fixed.media_container_style}}">
<video src="{{$vss.config.video}}" poster="{{if !empty($vss['config']['content_images'])}}{{$vss.config.content_images}}{{/if}}" controls class="{{$vss.config.frontend_config.media_fixed.media_ent}}">your browser does not support the video tag</video>
</div>
{{/case}}
{{case goods}}
{{switch vss.config.view_list_show_style}}
{{case rolling}}
<div class="am-slider am-slider-default am-slider-carousel {{$vss.config.frontend_config.nav_dot_ent}}" data-am-flexslider="{itemWidth: {{if empty($vss['config']['view_list_show_style_value_arr']) or empty($vss['config']['view_list_show_style_value_arr']['item_width'])}}200{{else /}}{{$vss.config.view_list_show_style_value_arr.item_width}}{{/if}}, itemMargin: {{if empty($vss['config']['view_list_show_style_value_arr']) or empty($vss['config']['view_list_show_style_value_arr']['item_margin'])}}0{{else /}}{{$vss.config.view_list_show_style_value_arr.item_margin}}{{/if}}, slideshow: {{if empty($vss['config']['view_list_show_style_value_arr']) or !isset($vss['config']['view_list_show_style_value_arr']['is_auto_play']) or $vss['config']['view_list_show_style_value_arr']['is_auto_play'] eq 0}}false{{else /}}true{{/if}}, controlNav: {{if empty($vss['config']['view_list_show_style_value_arr']) or !isset($vss['config']['view_list_show_style_value_arr']['is_nav_dot']) or $vss['config']['view_list_show_style_value_arr']['is_nav_dot'] eq 0}}false{{else /}}true{{/if}}}">
<div class="am-viewport">
<ul class="am-slides module-list-content">
{{foreach $vss.config.data_list as $g}}
<li>
<div class="module-item" style="{{$vss.config.frontend_config.item_style}}">
<a href="{{$g.goods_url}}" target="_blank" class="{{$vss.config.frontend_config.media_fixed.media_container_ent}}" style="{{$vss.config.frontend_config.media_fixed.media_container_style}}">
<img src="{{$g.images}}" alt="{{$g.title}}" class="{{$vss.config.frontend_config.media_fixed.media_ent}}" />
</a>
<div class="item-bottom">
<div class="module-title">
<a href="{{$g.goods_url}}" target="_blank">{{$g.title}}</a></div>
<p class="module-price">{{$currency_symbol}}{{$g.price}}</p>
</div>
</div>
</li>
{{/foreach}}
</ul>
</div>
</div>
{{/case}}
{{default /}}
<ul class="module-list-content {{$vss.config.frontend_config.list_ent}}">
{{foreach $vss.config.data_list as $g}}
<li>
<div class="module-item" style="{{$vss.config.frontend_config.item_style}}">
<a href="{{$g.goods_url}}" target="_blank" class="{{$vss.config.frontend_config.media_fixed.media_container_ent}}" style="{{$vss.config.frontend_config.media_fixed.media_container_style}}">
<img src="{{$g.images}}" alt="{{$g.title}}" class="{{$vss.config.frontend_config.media_fixed.media_ent}}" />
</a>
<div class="item-bottom">
<div class="module-title">
<a href="{{$g.goods_url}}" target="_blank">{{$g.title}}</a></div>
<p class="module-price">{{$currency_symbol}}{{$g.price}}</p>
</div>
</div>
</li>
{{/foreach}}
</ul>
{{/switch}}
{{/case}}
{{case title}}
<div class="module-title-content">
<span class="title-main" style="{{$vss.config.frontend_config.style_title_main}}">{{$vss.config.title}}</span>
{{if !empty($vss['config']['title_vice'])}}
<span class="title-vice" style="{{$vss.config.frontend_config.style_title_vice}}">{{$vss.config.title_vice}}</span>
{{/if}}
{{if !empty($vss['config']['keywords_list'])}}
<div class="keywords-content">
{{foreach $vss.config.keywords_list as $wd}}
<a {{if empty($wd['url'])}}href="javascript:;"{{else /}}href="{{$wd.url}}" target="_blank"{{/if}} {{if !empty($wd['color'])}}style="color:{{$wd.color}};"{{/if}}>{{$wd.keywords}}</a>
{{/foreach}}
</div>
{{/if}}
{{if !empty($vss['config']['title_more'])}}
<div class="more-content">
<a {{if empty($vss['config']['title_more_url'])}}href="javascript:;"{{else /}}href="{{$vss.config.title_more_url}}" target="_blank"{{/if}} style="{{$vss.config.frontend_config.style_title_more}}">
<span>{{$vss.config.title_more}}</span>
<i class="am-icon-angle-right"></i>
</a>
</div>
{{/if}}
</div>
{{/case}}
{{/switch}}
</div>
{{else /}}
<div class="am-text-center am-padding-vertical-sm am-text-primary">{{$vss.name}}</div>
{{/if}}
</div>
</div>
{{/foreach}}
{{/if}}
</div>
</div>

View File

@ -0,0 +1,11 @@
<div class="am-form-group am-form-group-refreshing">
<label>展示模式</label>
<div class="config-view-show-style">
{{foreach $goods_view_list_show_style as $k=>$v}}
<label class="am-radio-inline">
<input type="radio" name="view_list_show_style" value="{{$k}}" data-am-ucheck {{if $k eq 'routine'}}checked{{/if}} /> {{$v}}
</label>
{{/foreach}}
<input type="hidden" name="view_list_show_style_value" value="" />
</div>
</div>

View File

@ -0,0 +1,11 @@
<div class="am-form-group am-form-group-refreshing">
<label>展示模式</label>
<div class="config-view-show-style">
{{foreach $many_images_view_list_show_style as $k=>$v}}
<label class="am-radio-inline">
<input type="radio" name="view_list_show_style" value="{{$k}}" data-am-ucheck {{if $k eq 'routine'}}checked{{/if}} /> {{$v}}
</label>
{{/foreach}}
<input type="hidden" name="view_list_show_style_value" value="" />
</div>
</div>

View File

@ -0,0 +1,26 @@
<!-- 高度 -->
{{include file="../../../layout/view/public/style/height" key="[key]" required="[required]" height="800" name="[name]" /}}
<!-- 是否高度100% -->
<div class="am-form-group am-form-group-refreshing">
<label class="block">是否宽度100%</label>
<input name="style[key]_is_width" value="1" type="checkbox" data-off-text="否" data-on-text="是" data-size="xs" data-on-color="success" data-off-color="default" data-handle-width="50" data-am-switch />
</div>
<!-- 是否高度100% -->
<div class="am-form-group am-form-group-refreshing">
<label class="block">是否高度100%</label>
<input name="style[key]_is_height" value="1" type="checkbox" data-off-text="否" data-on-text="是" data-size="xs" data-on-color="success" data-off-color="default" data-handle-width="50" data-am-switch />
</div>
<!-- 是否居中 -->
<div class="am-form-group am-form-group-refreshing">
<label class="block">是否居中</label>
<input name="style[key]_is_auto" value="1" type="checkbox" data-off-text="否" data-on-text="是" data-size="xs" data-on-color="success" data-off-color="default" data-handle-width="50" data-am-switch />
</div>
<!-- 是否铺满容器 -->
<div class="am-form-group am-form-group-refreshing">
<label class="block">是否铺满容器</label>
<input name="style[key]_is_cover" value="1" type="checkbox" data-off-text="否" data-on-text="是" data-size="xs" data-on-color="success" data-off-color="default" data-handle-width="50" data-am-switch />
</div>

View File

@ -0,0 +1,9 @@
<div class="am-form-group am-form-group-refreshing">
<label>行展示数量</label>
<div class="am-input-group am-input-group-sm group-list-number-width">
<input type="number" placeholder="小屏" name="view_list_number_sm" min="0" max="12" data-validation-message="小屏最大12" value="2" class="am-form-field" />
<input type="number" placeholder="中屏" name="view_list_number_md" min="0" max="12" data-validation-message="中屏最大12" value="5" class="am-form-field" />
<input type="number" placeholder="大屏" name="view_list_number_lg" min="0" max="12" data-validation-message="大屏最大12" value="5" class="am-form-field" />
<span class="am-input-group-label"></span>
</div>
</div>

View File

@ -0,0 +1,16 @@
<!-- 列表配置 -->
<div class="am-modal am-modal-no-btn modal-dialog-not-title" tabindex="-1" id="modal-module-list-config">
<div class="am-modal-dialog">
<span data-am-modal-close class="am-close am-close-alt am-icon-times"></span>
<form class="am-form am-padding-sm am-text-left form-validation-module-modal-list-config" request-type="sync" request-value="FormBackModuleModalListConfig">
<!-- 行展示数量 -->
{{include file="../../../layout/view/public/content/view_list_number" /}}
<!-- 外边距 -->
{{include file="../../../layout/view/public/style/margin" key="" required="" /}}
<div class="am-margin-top-sm">
<button type="submit" class="am-btn am-btn-primary am-btn-block">确认</button>
</div>
</form>
</div>
</div>

View File

@ -0,0 +1,60 @@
<!-- 页面选择 -->
<div class="am-modal am-modal-no-btn modal-dialog-not-title" tabindex="-1" id="modal-module-pages-select">
<div class="am-modal-dialog">
<span data-am-modal-close class="am-close am-close-alt am-icon-times"></span>
{{if !empty($pages_list)}}
<form class="am-form" action="false">
<div data-am-widget="tabs" class="am-tabs am-tabs-d2">
<ul class="am-tabs-nav am-cf">
<li class="am-active"><a href="[data-tab-panel-0]">系统页面</a></li>
<li><a href="[data-tab-panel-1]">扩展模块</a></li>
</ul>
<div class="am-tabs-bd">
<div data-tab-panel-0 class="am-tab-panel am-active">
<ul class="am-scrollable-vertical am-list am-list-border am-text-left">
{{foreach $pages_list.common.data as $ks=>$vs}}
<li class="page-{{$vs.value}}">
<a href="javascript:;" class="am-text-truncate" data-value="{{$vs.value}}" data-name="{{$vs.name}}">
<span>{{$vs.name}}</span>
<i class="am-icon-check am-fr am-hide"></i>
</a>
</li>
{{/foreach}}
</ul>
</div>
<div data-tab-panel-1 class="am-tab-panel">
<div class="am-scrollable-vertical">
{{foreach $pages_list.plugins.data as $k=>$v}}
<section data-am-widget="accordion" class="am-accordion am-accordion-default" data-am-accordion='{ "multiple": true }'>
<dl class="am-accordion-item am-active">
<dt class="am-accordion-title">{{$v.name}}</dt>
<dd class="am-accordion-bd am-collapse am-in">
<div class="am-accordion-content am-padding-0">
<ul class="am-list am-list-border am-text-left am-margin-bottom-0">
{{foreach $v.data as $ks=>$vs}}
<li class="page-plugins-{{$v.value}}-{{$vs.value}}">
<a href="javascript:;" class="am-text-truncate" data-value="plugins-{{$v.value}}-{{$vs.value}}" data-name="{{$v.name}}-{{$vs.name}}">
<span>{{$vs.name}}</span>
<i class="am-icon-check am-fr am-hide"></i>
</a>
</li>
{{/foreach}}
</ul>
</div>
</dd>
</dl>
</section>
{{/foreach}}
</div>
</div>
</div>
</div>
<div class="am-padding-sm">
<button type="button" class="am-btn am-btn-primary am-btn-block pages-confirm-submit">确认</button>
</div>
</form>
{{else /}}
{{include file="public/not_data" /}}
{{/if}}
</div>
</div>

View File

@ -0,0 +1,33 @@
<!-- 滚动配置 -->
<div class="am-modal am-modal-no-btn modal-dialog-not-title" tabindex="-1" id="modal-module-rolling-config">
<div class="am-modal-dialog">
<span data-am-modal-close class="am-close am-close-alt am-icon-times"></span>
<form class="am-form am-padding-sm am-text-left form-validation-module-modal-rolling-config" request-type="sync" request-value="FormBackModuleModalRollingConfig">
<div class="am-form-group am-form-group-refreshing">
<label>数据项宽度<span class="am-form-group-label-tips">默认200</span></label>
<div class="am-input-group am-input-group-sm">
<input type="number" placeholder="数据项宽度" name="item_width" min="0" max="600" data-validation-message="数据项宽度最大600" value="200" class="am-form-field" />
<span class="am-input-group-label">px</span>
</div>
</div>
<div class="am-form-group am-form-group-refreshing">
<label>数据项间距</label>
<div class="am-input-group am-input-group-sm">
<input type="number" placeholder="数据项间距" name="item_margin" min="0" max="100" data-validation-message="数据项间距最大100" value="" class="am-form-field" />
<span class="am-input-group-label">px</span>
</div>
</div>
<div class="am-form-group am-form-group-refreshing">
<label class="block">是否自动播放</label>
<input name="is_auto_play" value="1" type="checkbox" data-off-text="否" data-on-text="是" data-size="xs" data-on-color="success" data-off-color="default" data-handle-width="50" data-am-switch />
</div>
<div class="am-form-group am-form-group-refreshing">
<label class="block">展示导航点</label>
<input name="is_nav_dot" value="1" type="checkbox" data-off-text="否" data-on-text="是" data-size="xs" data-on-color="success" data-off-color="default" data-handle-width="50" data-am-switch />
</div>
<div class="am-margin-top-sm">
<button type="submit" class="am-btn am-btn-primary am-btn-block">确认</button>
</div>
</form>
</div>
</div>

View File

@ -0,0 +1,26 @@
<!-- 标题关键字配置 -->
<div class="am-modal am-modal-no-btn modal-dialog-not-title" tabindex="-1" id="modal-module-title-keywords">
<div class="am-modal-dialog">
<span data-am-modal-close class="am-close am-close-alt am-icon-times"></span>
<form class="am-form am-padding-sm am-text-left form-validation-module-modal-title-keywords" request-type="sync" request-value="FormBackModuleModalTitleKeywords">
<!-- 关键字 -->
{{include file="../../../layout/view/public/style/input_color" key="_keywords" title="关键字" placeholder="关键字" minlength="1" maxlength="8" message="关键字最多1~8个字符" value="" required="required" color_value="" tips-must="-must" tips-msg="必填" /}}
<!-- 关键字链接 -->
<div class="am-form-group am-form-group-refreshing">
<label>链接地址</label>
<div class="form-view-choice-container am-margin-top-xs">
<input type="hidden" name="content_to_type" value="" />
<input type="hidden" name="content_to_name" value="" />
<input type="hidden" name="content_to_value" value="" />
<div class="form-view-choice-container-content">
<a href="javascript:;" class="form-view-choice-container-submit">请选择跳转链接</a>
</div>
</div>
</div>
<div class="am-margin-top-sm">
<button type="submit" class="am-btn am-btn-primary am-btn-block">确认</button>
</div>
</form>
</div>
</div>

View File

@ -0,0 +1,87 @@
<!-- 侧边栏 - 布局 - 容器设置 -->
<div id="offcanvas-layout-config" class="am-offcanvas module-offcanvas-container">
<div class="am-offcanvas-bar">
<div class="am-offcanvas-content am-padding-0">
<form class="am-form form-validation-layout-config" request-type="sync" request-value="FormBackLayoutConfig">
<!-- 基础样式 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">基础样式</div>
<div class="am-panel-bd">
<!-- 背景色 -->
{{include file="../../../layout/view/public/style/background_color" key="" required="" /}}
<!-- 边线颜色 -->
{{include file="../../../layout/view/public/style/color" key="_border" required="" name="边线颜色" /}}
</div>
</div>
<!-- 中屏样式 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">中屏样式</div>
<div class="am-panel-bd">
<!-- 圆角 -->
{{include file="../../../layout/view/public/style/border_radius" key="_md" required="" /}}
<!-- 边线类型 -->
{{include file="../../../layout/view/public/style/border_style_4" key="_md" /}}
<!-- 边线大小 -->
{{include file="../../../layout/view/public/style/border_width_4" key="_md" /}}
<!-- 外边距 -->
{{include file="../../../layout/view/public/style/margin_4" key="_md" /}}
<!-- 内边距 -->
{{include file="../../../layout/view/public/style/padding_4" key="_md" /}}
</div>
</div>
<!-- 小屏样式 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">小屏样式</div>
<div class="am-panel-bd">
<!-- 圆角 -->
{{include file="../../../layout/view/public/style/border_radius" key="_sm" required="" /}}
<!-- 边线类型 -->
{{include file="../../../layout/view/public/style/border_style_4" key="_sm" /}}
<!-- 边线大小 -->
{{include file="../../../layout/view/public/style/border_width_4" key="_sm" /}}
<!-- 外边距 -->
{{include file="../../../layout/view/public/style/margin_4" key="_sm" /}}
<!-- 内边距 -->
{{include file="../../../layout/view/public/style/padding_4" key="_sm" /}}
</div>
</div>
<!-- 大屏样式 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">大屏样式</div>
<div class="am-panel-bd">
<!-- 圆角 -->
{{include file="../../../layout/view/public/style/border_radius" key="_lg" required="" /}}
<!-- 边线类型 -->
{{include file="../../../layout/view/public/style/border_style_4" key="_lg" /}}
<!-- 边线大小 -->
{{include file="../../../layout/view/public/style/border_width_4" key="_lg" /}}
<!-- 外边距 -->
{{include file="../../../layout/view/public/style/margin_4" key="_lg" /}}
<!-- 内边距 -->
{{include file="../../../layout/view/public/style/padding_4" key="_lg" /}}
</div>
</div>
<div class="form-submit-container">
<button type="submit" class="am-btn am-btn-primary am-radius am-btn-xs am-btn-block" data-am-loading="{loadingText: '处理中...'}">确认</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,27 @@
<!-- 侧边栏 - 模块配置 - 辅助线 -->
<div id="offcanvas-module-config-border" class="am-offcanvas module-offcanvas-container">
<div class="am-offcanvas-bar">
<div class="am-offcanvas-content am-padding-0">
<form class="am-form form-validation-module-offcanvas-border" request-type="sync" request-value="FormBackModuleConfigBorder">
<!-- 样式设置 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">样式设置</div>
<div class="am-panel-bd">
<!-- 边线类型 -->
{{include file="../../../layout/view/public/style/border_style" key="" required="required" /}}
<!-- 边线大小 -->
{{include file="../../../layout/view/public/style/border_width_color" key="" required="required" /}}
<!-- 外边距 -->
{{include file="../../../layout/view/public/style/margin_4" key="" /}}
</div>
</div>
<div class="form-submit-container">
<button type="submit" class="am-btn am-btn-primary am-radius am-btn-xs am-btn-block" data-am-loading="{loadingText: '处理中...'}">确认</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,127 @@
<!-- 侧边栏 - 模块配置 - 商品 -->
<div id="offcanvas-module-config-goods" class="am-offcanvas module-offcanvas-container" data-data-url="{{:MyUrl('index/layout/goodsdata')}}">
<div class="am-offcanvas-bar">
<div class="am-offcanvas-content am-padding-0">
<form class="am-form form-validation-module-offcanvas-goods" request-type="sync" request-value="FormBackModuleConfigGoods">
<input type="hidden" name="goods_data_type" value="goods" />
<div data-am-widget="tabs" class="am-tabs am-tabs-d2 am-margin-bottom-lg" data-am-tabs="{noSwipe: 1}">
<ul class="am-tabs-nav am-cf">
<li class="am-active"><a href="[data-tab-panel-0]" data-value="goods">选择商品</a></li>
<li><a href="[data-tab-panel-1]" data-value="category">选择分类</a></li>
</ul>
<div class="am-tabs-bd am-padding-sm">
<div data-tab-panel-0 class="am-tab-panel am-active">
<input type="hidden" name="goods_ids" value="" />
<div class="form-view-choice-container" data-value="goods">
<div class="form-view-choice-container-content">
<a href="javascript:;" class="form-view-choice-container-submit">请选择商品</a>
<span class="am-form-group-label-tips-must">必选</span>
<span class="text-tips am-margin-left-sm">最多添加50件商品</span>
</div>
</div>
<ul class="config-goods-list am-cf am-margin-top-sm"></ul>
</div>
<div data-tab-panel-1 class="am-tab-panel">
<div class="am-form-group am-form-group-refreshing">
<label>商品分类<span class="am-form-group-label-tips-must">必选</span></label>
<div class="form-view-choice-container am-margin-top-xs offcanvas-config-goods-category-container" data-value="category">
<input type="hidden" name="goods_category_value" value="" />
<div class="form-view-choice-container-content">
<a href="javascript:;" class="form-view-choice-container-submit">请选择商品分类</a>
</div>
</div>
</div>
<div class="am-form-group am-form-group-refreshing">
<label>排序类型<span class="am-form-group-label-tips">默认综合</span></label>
<select name="goods_order_by_type" class="am-radius chosen-select" data-placeholder="请选择..." data-validation-message="请选择商品排序类型">
{{foreach $goods_order_by_type_list as $k=>$v}}
<option value="{{$k}}" {{if $k eq 0}}selected{{/if}}>{{$v.name}}</option>
{{/foreach}}
</select>
<div class="am-alert am-alert-warning" data-am-alert>
<button type="button" class="am-close">&times;</button>
<p>综合为:热度->销量->最新 进行 降序(desc)排序</p>
</div>
</div>
<div class="am-form-group am-form-group-refreshing">
<label>排序规则<span class="am-form-group-label-tips">默认降序(desc)</span></label>
<select name="goods_order_by_rule" class="am-radius chosen-select" data-placeholder="请选择..." data-validation-message="请选择排序规则">
{{foreach $goods_order_by_rule_list as $k=>$v}}
<option value="{{$k}}" {{if $k eq 0}}selected{{/if}}>{{$v.name}}</option>
{{/foreach}}
</select>
</div>
<div class="am-form-group am-form-group-refreshing">
<label>数量</label>
<input type="number" placeholder="数量" name="goods_order_limit_number" min="0" max="50" data-validation-message="数量最大50" value="10" class="am-form-field" />
</div>
</div>
</div>
</div>
<!-- 内容样式 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">内容样式</div>
<div class="am-panel-bd">
<!-- 行展示数量 -->
{{include file="../../../layout/view/public/content/view_list_number" /}}
<!-- 背景色 -->
{{include file="../../../layout/view/public/style/background_color" key="_module" required="" /}}
<!-- 圆角 -->
{{include file="../../../layout/view/public/style/border_radius" key="_module" required="" /}}
<!-- 边线类型 -->
{{include file="../../../layout/view/public/style/border_style_4" key="_module" /}}
<!-- 边线大小 -->
{{include file="../../../layout/view/public/style/border_width_color_4" key="_module" /}}
<!-- 外边距 -->
{{include file="../../../layout/view/public/style/margin_4" key="_module" /}}
<!-- 内边距 -->
{{include file="../../../layout/view/public/style/padding_4" key="_module" /}}
<!-- 展示模式 -->
{{include file="../../../layout/view/public/content/goods_show_style" /}}
</div>
</div>
<!-- 商品样式 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">商品样式</div>
<div class="am-panel-bd">
<!-- 圆角 -->
{{include file="../../../layout/view/public/style/border_radius" key="" required="" /}}
<!-- 边线类型 -->
{{include file="../../../layout/view/public/style/border_style" key="" required="" /}}
<!-- 边线大小 -->
{{include file="../../../layout/view/public/style/border_width_color" key="" required="" /}}
<!-- 外边距 -->
{{include file="../../../layout/view/public/style/margin" key="" required="" /}}
<!-- 内边距 -->
{{include file="../../../layout/view/public/style/padding" key="" required="" /}}
</div>
</div>
<!-- 图片固定 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">图片固定</div>
<div class="am-panel-bd">
{{include file="../../../layout/view/public/content/media_fixed" key="_media_fixed" required="" name="图片容器高度" /}}
</div>
</div>
<div class="form-submit-container">
<button type="submit" class="am-btn am-btn-primary am-radius am-btn-xs am-btn-block" data-am-loading="{loadingText: '处理中...'}">确认</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,27 @@
<!-- 侧边栏 - 模块配置 - 辅助空白 -->
<div id="offcanvas-module-config-height" class="am-offcanvas module-offcanvas-container">
<div class="am-offcanvas-bar">
<div class="am-offcanvas-content am-padding-0">
<form class="am-form form-validation-module-offcanvas-height" request-type="sync" request-value="FormBackModuleConfigHeight">
<!-- 样式设置 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">样式设置</div>
<div class="am-panel-bd">
<!-- 背景色 -->
{{include file="../../../layout/view/public/style/background_color" key="" required="" /}}
<!-- 高度 -->
{{include file="../../../layout/view/public/style/height" key="" required="required" height="100" name="高度" /}}
<!-- 外边距 -->
{{include file="../../../layout/view/public/style/margin_4" key="" /}}
</div>
</div>
<div class="form-submit-container">
<button type="submit" class="am-btn am-btn-primary am-radius am-btn-xs am-btn-block" data-am-loading="{loadingText: '处理中...'}">确认</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,68 @@
<!-- 侧边栏 - 模块配置 - 图片 -->
<div id="offcanvas-module-config-images" class="am-offcanvas module-offcanvas-container" data-default-images="{{$attachment_host}}/static/plugins/images/shop/renovation/module-default-images.png">
<div class="am-offcanvas-bar">
<div class="am-offcanvas-content am-padding-0">
<form class="am-form form-validation-module-offcanvas-images" request-type="sync" request-value="FormBackModuleConfigImages">
<div class="am-panel am-panel-default">
<div class="am-panel-hd">内容设置</div>
<div class="am-panel-bd">
<div class="am-form-group am-form-file am-form-group-refreshing">
<label class="block">图片<span class="am-form-group-label-tips-must">必传</span></label>
<ul class="plug-file-upload-view module-images-type-images-view" data-form-name="content_images" data-max-number="1" data-delete="0" data-dialog-type="images">
<li>
<input type="text" name="content_images" data-validation-message="请上传图片" value="" required />
<img src="{{$attachment_host}}/static/plugins/images/shop/renovation/module-default-images.png" />
</li>
</ul>
<div class="plug-file-upload-submit" data-view-tag="ul.module-images-type-images-view">+上传图片</div>
</div>
<div class="am-form-group am-form-group-refreshing">
<label>链接地址</label>
<div class="form-view-choice-container am-margin-top-xs">
<input type="hidden" name="content_to_type" value="" />
<input type="hidden" name="content_to_name" value="" />
<input type="hidden" name="content_to_value" value="" />
<div class="form-view-choice-container-content">
<a href="javascript:;" class="form-view-choice-container-submit">请选择跳转链接</a>
</div>
</div>
</div>
</div>
</div>
<!-- 样式设置 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">样式设置</div>
<div class="am-panel-bd">
<!-- 圆角 -->
{{include file="../../../layout/view/public/style/border_radius" key="" required="" /}}
<!-- 边线类型 -->
{{include file="../../../layout/view/public/style/border_style_4" key="" /}}
<!-- 边线大小 -->
{{include file="../../../layout/view/public/style/border_width_color_4" key="" /}}
<!-- 外边距 -->
{{include file="../../../layout/view/public/style/margin_4" key="" /}}
<!-- 内边距 -->
{{include file="../../../layout/view/public/style/padding_4" key="" /}}
</div>
</div>
<!-- 图片固定 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">图片固定</div>
<div class="am-panel-bd">
{{include file="../../../layout/view/public/content/media_fixed" key="_media_fixed" required="" name="图片容器高度" /}}
</div>
</div>
<div class="form-submit-container">
<button type="submit" class="am-btn am-btn-primary am-radius am-btn-xs am-btn-block" data-am-loading="{loadingText: '处理中...'}">确认</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,58 @@
<!-- 侧边栏 - 模块配置 - 多图 -->
<div id="offcanvas-module-config-many-images" class="am-offcanvas module-offcanvas-container" data-default-images="{{$attachment_host}}/static/plugins/images/shop/renovation/module-default-images.png">
<div class="am-offcanvas-bar">
<div class="am-offcanvas-content am-padding-0">
<form class="am-form form-validation-module-offcanvas-many-images" request-type="sync" request-value="FormBackModuleConfigManyImages">
<div class="am-panel am-panel-default">
<div class="am-panel-hd">内容设置<span class="am-form-group-label-tips-must">必传</span></div>
<div class="am-panel-bd">
<div class="config-many-images-container"></div>
<div class="business-operations-submit am-text-center am-block config-many-images-item-add">+添加图片</div>
</div>
</div>
<!-- 内容样式 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">内容样式</div>
<div class="am-panel-bd">
<!-- 展示模式 -->
{{include file="../../../layout/view/public/content/many_images_show_style" /}}
</div>
</div>
<!-- 样式设置 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">样式设置</div>
<div class="am-panel-bd">
<!-- 圆角 -->
{{include file="../../../layout/view/public/style/border_radius" key="" required="" /}}
<!-- 边线类型 -->
{{include file="../../../layout/view/public/style/border_style_4" key="" /}}
<!-- 边线大小 -->
{{include file="../../../layout/view/public/style/border_width_color_4" key="" /}}
<!-- 外边距 -->
{{include file="../../../layout/view/public/style/margin_4" key="" /}}
<!-- 内边距 -->
{{include file="../../../layout/view/public/style/padding_4" key="" /}}
</div>
</div>
<!-- 图片固定 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">图片固定</div>
<div class="am-panel-bd">
{{include file="../../../layout/view/public/content/media_fixed" key="_media_fixed" required="" name="图片容器高度" /}}
</div>
</div>
<div class="form-submit-container">
<button type="submit" class="am-btn am-btn-primary am-radius am-btn-xs am-btn-block" data-am-loading="{loadingText: '处理中...'}">确认</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,79 @@
<!-- 侧边栏 - 模块配置 - 标题 -->
<div id="offcanvas-module-config-title" class="am-offcanvas module-offcanvas-container">
<div class="am-offcanvas-bar">
<div class="am-offcanvas-content am-padding-0">
<form class="am-form form-validation-module-offcanvas-title" request-type="sync" request-value="FormBackModuleConfigTitle">
<!-- 主内容 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">主内容</div>
<div class="am-panel-bd">
<!-- 主标题 -->
{{include file="../../../layout/view/public/style/input_color" key="_title" title="主标题" placeholder="主标题" minlength="1" maxlength="8" message="主标题最多1~8个字符" value="" required="required" color_value="" tips-must="-must" tips-msg="必填" /}}
<!-- 副标题 -->
{{include file="../../../layout/view/public/style/input_color" key="_title_vice" title="副标题" placeholder="副标题" minlength="0" maxlength="16" message="副标题最多16个字符" value="" required="" color_value="" tips-must="" tips-msg="空则不显示" /}}
</div>
</div>
<!-- 右侧按钮 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">右侧按钮<span class="am-form-group-label-tips">空则不显示</span></div>
<div class="am-panel-bd">
<!-- 右侧按钮名称 -->
{{include file="../../../layout/view/public/style/input_color" key="_title_more" title="右侧按钮名称" placeholder="右侧按钮名称" minlength="0" maxlength="4" message="右侧按钮名称最多4个字符" value="" required="" color_value="" tips-must="" tips-msg="" /}}
<!-- 右侧按钮链接 -->
<div class="am-form-group am-form-group-refreshing">
<label>右侧按钮链接地址</label>
<div class="form-view-choice-container am-margin-top-xs">
<input type="hidden" name="content_to_type" value="" />
<input type="hidden" name="content_to_name" value="" />
<input type="hidden" name="content_to_value" value="" />
<div class="form-view-choice-container-content">
<a href="javascript:;" class="form-view-choice-container-submit">请选择跳转链接</a>
</div>
</div>
</div>
</div>
</div>
<!-- 关键字 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">关键字<span class="am-form-group-label-tips">小屏下不显示</span></div>
<div class="am-panel-bd">
<ul class="am-list am-list-static am-list-border config-title-container"></ul>
<div class="business-operations-submit am-text-center am-block config-title-item-add">+添加关键字</div>
</div>
</div>
<!-- 样式设置 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">样式设置</div>
<div class="am-panel-bd">
<!-- 背景色 -->
{{include file="../../../layout/view/public/style/background_color" key="" required="" /}}
<!-- 圆角 -->
{{include file="../../../layout/view/public/style/border_radius" key="" required="" /}}
<!-- 边线类型 -->
{{include file="../../../layout/view/public/style/border_style_4" key="" /}}
<!-- 边线大小 -->
{{include file="../../../layout/view/public/style/border_width_color_4" key="" /}}
<!-- 外边距 -->
{{include file="../../../layout/view/public/style/margin_4" key="" /}}
<!-- 内边距 -->
{{include file="../../../layout/view/public/style/padding_4" key="" /}}
</div>
</div>
<div class="form-submit-container">
<button type="submit" class="am-btn am-btn-primary am-radius am-btn-xs am-btn-block" data-am-loading="{loadingText: '处理中...'}">确认</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,63 @@
<!-- 侧边栏 - 模块配置 - 视频 -->
<div id="offcanvas-module-config-video" class="am-offcanvas module-offcanvas-container" data-default-images="{{$attachment_host}}/static/plugins/images/shop/renovation/module-default-images.png">
<div class="am-offcanvas-bar">
<div class="am-offcanvas-content am-padding-0">
<form class="am-form form-validation-module-offcanvas-video" request-type="sync" request-value="FormBackModuleConfigVideo">
<div class="am-panel am-panel-default">
<div class="am-panel-hd">内容设置</div>
<div class="am-panel-bd">
<div class="am-form-group am-form-file am-form-group-refreshing">
<label class="block">视频<span class="am-form-group-label-tips-must">必传</span></label>
<ul class="plug-file-upload-view plug-file-upload-view-video module-video-type-view-video" data-form-name="content_video" data-max-number="1" data-dialog-type="video" data-delete="0">
<li>
<input type="text" name="content_video" data-validation-message="请上传视频" value="" required />
<video src="" controls>your browser does not support the video tag</video>
</li>
</ul>
<div class="plug-file-upload-submit" data-view-tag="ul.module-video-type-view-video">+上传视频</div>
</div>
<div class="am-form-group am-form-file am-form-group-refreshing">
<label class="block">封面图片</label>
<ul class="plug-file-upload-view module-video-type-view-images" data-form-name="content_images" data-max-number="1" data-dialog-type="images"></ul>
<div class="plug-file-upload-submit" data-view-tag="ul.module-video-type-view-images">+上传图片</div>
</div>
</div>
</div>
<!-- 样式设置 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">样式设置</div>
<div class="am-panel-bd">
<!-- 圆角 -->
{{include file="../../../layout/view/public/style/border_radius" key="" required="" /}}
<!-- 边线类型 -->
{{include file="../../../layout/view/public/style/border_style_4" key="" /}}
<!-- 边线大小 -->
{{include file="../../../layout/view/public/style/border_width_color_4" key="" /}}
<!-- 外边距 -->
{{include file="../../../layout/view/public/style/margin_4" key="" /}}
<!-- 内边距 -->
{{include file="../../../layout/view/public/style/padding_4" key="" /}}
</div>
</div>
<!-- 视频固定 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">视频固定</div>
<div class="am-panel-bd">
{{include file="../../../layout/view/public/content/media_fixed" key="_media_fixed" required="" name="视频容器高度" /}}
</div>
</div>
<div class="form-submit-container">
<button type="submit" class="am-btn am-btn-primary am-radius am-btn-xs am-btn-block" data-am-loading="{loadingText: '处理中...'}">确认</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,21 @@
<!-- 商品分类 -->
<div class="am-popup popup-not-title" id="popup-module-goods-category">
<div class="am-popup-inner">
<span data-am-modal-close class="am-close am-close-alt am-icon-times"></span>
<div class="am-popup-bd am-padding-0">
<form class="am-form">
<div class="layout-category-choice">
<div class="goods-category-choice am-padding-sm form-container-category">
{{include file="../../../layout/view/public/common/goods_category_choice" /}}
</div>
</div>
<!-- 操作 -->
<div class="am-text-center am-padding-sm goods-bottom-operate-container">
<button type="button" class="am-btn am-btn-warning am-radius am-btn-xs am-margin-right-sm" data-am-modal-close>取消</button>
<button type="button" class="am-btn am-btn-primary am-radius am-btn-xs am-margin-left-sm confirm-submit" data-am-loading="{loadingText: '处理中...'}">确认</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,59 @@
<!-- 商品搜索 -->
<div class="am-popup popup-not-title" id="popup-module-goods-search">
<div class="am-popup-inner">
<span data-am-modal-close class="am-close am-close-alt am-icon-times"></span>
<div class="am-popup-bd am-padding-0">
<form class="am-form form-validation-module-popup-goods-search" request-type="sync" request-value="FormBackModulePopupGoodsSearch">
<div data-am-widget="tabs" class="am-tabs am-tabs-d2">
<ul class="am-tabs-nav am-cf">
<li class="am-active"><a href="[data-tab-panel-0]" data-value="category">商品分类</a></li>
<li><a href="[data-tab-panel-1]" data-value="brand">品牌</a></li>
<li><a href="[data-tab-panel-2]" data-value="keywords">关键字</a></li>
</ul>
<div class="am-tabs-bd">
<div data-tab-panel-0 class="am-tab-panel am-active">
<div class="layout-category-choice">
<div class="goods-category-choice am-padding-sm form-container-category">
{{include file="../../../layout/view/public/common/goods_category_choice" /}}
</div>
</div>
</div>
<div data-tab-panel-1 class="am-tab-panel">
<div class="layout-category-choice">
<div class="goods-category-choice am-padding-sm form-container-brand">
<div class="goods-category-choice-content am-nbfc">
<ul class="am-scrollable-vertical am-list am-list-border" data-level="1">
{{foreach $brand_list as $k=>$v}}
<li>
<a href="javascript:;" data-index="{{$k}}" data-value="{{$v.id}}">
<span>{{$v.name}}</span>
</a>
</li>
{{/foreach}}
</ul>
</div>
</div>
</div>
</div>
<div data-tab-panel-2 class="am-tab-panel">
<div class="am-form-group am-form-group-refreshing">
<div class="am-padding-sm form-container-keywords">
<p class="am-margin-top-sm am-text-warning am-text-center">搜索关键字格式1~30个字符</p>
<div class="am-margin-top-sm">
<input type="text" name="goods_search_keywords" placeholder="关键字" maxlength="30" data-validation-message="关键字格式1~30个字符" class="am-radius" />
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 操作 -->
<div class="am-text-center am-padding-sm goods-bottom-operate-container">
<button type="button" class="am-btn am-btn-warning am-radius am-btn-xs am-margin-right-sm" data-am-modal-close>取消</button>
<button type="submit" class="am-btn am-btn-primary am-radius am-btn-xs am-margin-left-sm" data-am-loading="{loadingText: '处理中...'}">确认</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,56 @@
<!-- 商品选择 -->
<div class="am-popup popup-not-title" id="popup-module-goods-select">
<div class="am-popup-inner">
<span data-am-modal-close class="am-close am-close-alt am-icon-times"></span>
<div class="am-popup-bd am-padding-0">
<form class="am-form layout-forth-selection-container" action="false">
<!-- 搜索 -->
<div class="forth-selection-container am-padding-sm" data-search-url="{{:MyUrl('index/layout/goodssearch')}}" data-data-url="{{:MyUrl('index/layout/goodsdata')}}">
<input type="hidden" name="category_field" value="{{if empty($layout_goods_category_field)}}gci.category_id{{else /}}{{$layout_goods_category_field}}{{/if}}">
<select class="am-radius chosen-select forth-selection-form-category" data-placeholder="分类..." data-validation-message="请选择分类">
<option value="">分类...</option>
{{if !empty($layout_goods_category)}}
{{if empty($layout_goods_category_field) or $layout_goods_category_field eq 'gci.category_id'}}
{{foreach $layout_goods_category as $v}}
<option value="{{$v.id}}" {{if !empty($data['category_ids']) and in_array($v['id'], $data['category_ids'])}}selected{{/if}}>一级 - {{$v.name}}</option>
{{if !empty($v['items'])}}
{{foreach $v.items as $vs}}
<option style="padding-left: 30px;" value="{{$vs.id}}" {{if !empty($data['category_ids']) and in_array($vs['id'], $data['category_ids'])}}selected{{/if}}>二级-{{$vs.name}}</option>
{{if !empty($vs['items'])}}
{{foreach $vs.items as $vss}}
<option style="padding-left: 60px;" value="{{$vss.id}}" {{if !empty($data['category_ids']) and in_array($vss['id'], $data['category_ids'])}}selected{{/if}}>三级-{{$vss.name}}</option>
{{/foreach}}
{{/if}}
{{/foreach}}
{{/if}}
{{/foreach}}
{{else /}}
{{foreach $layout_goods_category as $v}}
<option value="{{$v.id}}">{{$v.name}}</option>
{{/foreach}}
{{/if}}
{{/if}}
</select>
<input type="text" placeholder="商品名称" class="am-radius forth-selection-form-keywords" />
<button type="button" class="am-btn am-btn-secondary am-radius am-btn-sm am-icon-search search-submit" data-am-loading="{loadingText: ' 搜索中...'}"> 搜索</button>
</div>
<!-- 商品列表 -->
<div class="am-scrollable-vertical am-margin-horizontal-sm goods-list-container" data-loading-msg="搜索中...">
<ul class="am-gallery am-avg-sm-3 am-avg-md-4 am-avg-lg-5 am-gallery-bordered">
<div class="table-no"><i class="am-icon-warning"></i> 请搜索商品</div>
</ul>
</div>
<!-- 分页 -->
<div class="am-margin-top-sm am-text-center goods-page-container"></div>
<!-- 操作 -->
<div class="am-text-center am-padding-sm goods-bottom-operate-container">
<button type="button" class="am-btn am-btn-warning am-radius am-btn-xs am-margin-right-sm" data-am-modal-close>取消</button>
<button type="button" class="am-btn am-btn-primary am-radius am-btn-xs am-margin-left-sm confirm-submit" data-am-loading="{loadingText: '处理中...'}">确认</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,7 @@
<div class="am-form-group am-form-group-refreshing">
<label>背景色</label>
<input type="hidden" name="style[key]_background_color" data-validation-message="请选择背景色" value="" [required] />
<button type="button" class="am-btn am-btn-default am-btn-xs colorpicker-submit module-style-background-color[key] am-btn-block" data-position="fixed" data-input-tag="button.module-style-background-color[key]" data-color-tag="input[name='style[key]_background_color']" data-color-style="background-color">
<img src="{{$attachment_host}}/static/common/images/colorpicker.png" />
</button>
</div>

View File

@ -0,0 +1,7 @@
<div class="am-form-group am-form-group-refreshing">
<label>圆角</label>
<div class="am-input-group am-input-group-sm">
<input type="number" placeholder="圆角" name="style[key]_border_radius" min="0" max="30" data-validation-message="请输入圆角、最大30的数字" value="" class="am-form-field" [required] />
<span class="am-input-group-label">px</span>
</div>
</div>

View File

@ -0,0 +1,11 @@
<div class="am-form-group am-form-group-refreshing">
<label>边线类型</label>
{{if !empty($border_style_type_list)}}
<select name="style[key]_border_style" class="am-radius chosen-select" data-placeholder="请选择" data-validation-message="请选择边线类型" [required]>
<option value="">请选择</option>
{{foreach $border_style_type_list as $k=>$v}}
<option value="{{$k}}">{{$v}}</option>
{{/foreach}}
</select>
{{/if}}
</div>

View File

@ -0,0 +1,31 @@
<div class="am-form-group am-form-group-refreshing">
<label>边线类型<span class="am-form-group-label-tips">上 -> 右 -> 下 -> 左</span></label>
<div class="am-input-group am-input-group-sm group-border-style">
{{if !empty($border_style_type_list)}}
<select name="style[key]_border_style_top" class="am-radius chosen-select" data-placeholder="上" data-validation-message="请选择边线类型">
<option value=""></option>
{{foreach $border_style_type_list as $k=>$v}}
<option value="{{$k}}">{{$v}}</option>
{{/foreach}}
</select>
<select name="style[key]_border_style_right" class="am-radius chosen-select" data-placeholder="右" data-validation-message="请选择边线类型">
<option value=""></option>
{{foreach $border_style_type_list as $k=>$v}}
<option value="{{$k}}">{{$v}}</option>
{{/foreach}}
</select>
<select name="style[key]_border_style_bottom" class="am-radius chosen-select" data-placeholder="下" data-validation-message="请选择边线类型">
<option value=""></option>
{{foreach $border_style_type_list as $k=>$v}}
<option value="{{$k}}">{{$v}}</option>
{{/foreach}}
</select>
<select name="style[key]_border_style_left" class="am-radius chosen-select" data-placeholder="左" data-validation-message="请选择边线类型">
<option value=""></option>
{{foreach $border_style_type_list as $k=>$v}}
<option value="{{$k}}">{{$v}}</option>
{{/foreach}}
</select>
{{/if}}
</div>
</div>

View File

@ -0,0 +1,10 @@
<div class="am-form-group am-form-group-refreshing">
<label>边线大小<span class="am-form-group-label-tips">上 -> 右 -> 下 -> 左</span></label>
<div class="am-input-group am-input-group-sm group-border-width group-border-radius-color">
<input type="number" placeholder="上" name="style[key]_border_width_top" min="0" max="10" data-validation-message="边线上最大10" value="" class="am-form-field" />
<input type="number" placeholder="右" name="style[key]_border_width_right" min="0" max="10" data-validation-message="边线右最大10" value="" class="am-form-field" />
<input type="number" placeholder="下" name="style[key]_border_width_bottom" min="0" max="10" data-validation-message="边线下最大10" value="" class="am-form-field" />
<input type="number" placeholder="左" name="style[key]_border_width_left" min="0" max="10" data-validation-message="边线左最大10" value="" class="am-form-field" />
<span class="am-input-group-label">px</span>
</div>
</div>

View File

@ -0,0 +1,11 @@
<div class="am-form-group am-form-group-refreshing">
<label>边线/颜色</label>
<div class="am-input-group am-input-group-sm group-border-radius-color">
<input type="number" placeholder="边线" name="style[key]_border_width" min="0" max="10" data-validation-message="请输入边线、最大10的数字" value="" class="am-form-field" [required] />
<span class="am-input-group-label">px</span>
<input type="hidden" name="style[key]_border_color" value="" />
<a href="javascript:;" class="am-input-group-label colorpicker-submit module-style-border-color[key]" data-position="fixed" data-input-tag=".module-offcanvas-container .module-style-border-color[key]" data-color-tag=".module-offcanvas-container input[name='style[key]_border_color']" data-color-style="background-color|border-color">
<img src="{{$attachment_host}}/static/common/images/colorpicker.png" />
</a>
</div>
</div>

View File

@ -0,0 +1,14 @@
<div class="am-form-group am-form-group-refreshing">
<label>边线大小<span class="am-form-group-label-tips">上 -> 右 -> 下 -> 左 -> 颜色</span></label>
<div class="am-input-group am-input-group-sm group-border-width group-border-radius-color">
<input type="number" placeholder="上" name="style[key]_border_width_top" min="0" max="10" data-validation-message="边线上最大10" value="" class="am-form-field" />
<input type="number" placeholder="右" name="style[key]_border_width_right" min="0" max="10" data-validation-message="边线右最大10" value="" class="am-form-field" />
<input type="number" placeholder="下" name="style[key]_border_width_bottom" min="0" max="10" data-validation-message="边线下最大10" value="" class="am-form-field" />
<input type="number" placeholder="左" name="style[key]_border_width_left" min="0" max="10" data-validation-message="边线左最大10" value="" class="am-form-field" />
<span class="am-input-group-label">px</span>
<input type="hidden" name="style[key]_border_color" value="" />
<a href="javascript:;" class="am-input-group-label colorpicker-submit module-style-border-color[key]" data-position="fixed" data-input-tag=".module-offcanvas-container .module-style-border-color[key]" data-color-tag=".module-offcanvas-container input[name='style[key]_border_color']" data-color-style="background-color|border-color">
<img src="{{$attachment_host}}/static/common/images/colorpicker.png" />
</a>
</div>
</div>

View File

@ -0,0 +1,7 @@
<div class="am-form-group am-form-group-refreshing">
<label>[name]</label>
<input type="hidden" name="style[key]_color" data-validation-message="请选择[name]" value="" [required] />
<button type="button" class="am-btn am-btn-default am-btn-xs colorpicker-submit module-style-color[key] am-btn-block" data-position="fixed" data-input-tag="button.module-style-color[key]" data-color-tag="input[name='style[key]_color']" data-color-style="background-color">
<img src="{{$attachment_host}}/static/common/images/colorpicker.png" />
</button>
</div>

View File

@ -0,0 +1,7 @@
<div class="am-form-group am-form-group-refreshing">
<label>[name]</label>
<div class="am-input-group am-input-group-sm">
<input type="number" placeholder="[name]" name="style[key]_height" min="0" max="[height]" data-validation-message="请输入[name]、最大[height]的数字" value="" class="am-form-field" [required] />
<span class="am-input-group-label">px</span>
</div>
</div>

View File

@ -0,0 +1,10 @@
<div class="am-form-group am-form-group-refreshing">
<label>[title]<span class="am-form-group-label-tips[tips-must]">[tips-msg]</span></label>
<div class="am-input-group am-input-group-sm">
<input type="text" placeholder="[placeholder]" name="content[key]" minlength="[minlength]" maxlength="[maxlength]" data-validation-message="[message]" value="[value]" class="am-form-field" [required] />
<input type="hidden" name="style[key]_color" value="[color_value]" />
<a href="javascript:;" class="am-input-group-label colorpicker-submit module-style-color[key]" data-position="fixed" data-input-tag=".module-style-color[key]" data-color-tag="input[name='style[key]_color']" data-color-style="background-color|border-color">
<img src="{{$attachment_host}}/static/common/images/colorpicker.png" />
</a>
</div>
</div>

View File

@ -0,0 +1,7 @@
<div class="am-form-group am-form-group-refreshing">
<label>外边距</label>
<div class="am-input-group am-input-group-sm">
<input type="number" placeholder="外边距" name="style[key]_margin" min="0" max="30" data-validation-message="请输入外边距、最大30的数字" value="" class="am-form-field" [required] />
<span class="am-input-group-label">px</span>
</div>
</div>

View File

@ -0,0 +1,10 @@
<div class="am-form-group am-form-group-refreshing">
<label>外边距<span class="am-form-group-label-tips">上 -> 右 -> 下 -> 左</span></label>
<div class="am-input-group am-input-group-sm group-border-width">
<input type="number" placeholder="上" name="style[key]_margin_top" min="0" max="60" data-validation-message="外边距上最大60" value="" class="am-form-field" />
<input type="number" placeholder="右" name="style[key]_margin_right" min="0" max="60" data-validation-message="外边距右最大60" value="" class="am-form-field" />
<input type="number" placeholder="下" name="style[key]_margin_bottom" min="0" max="60" data-validation-message="外边距下最大60" value="" class="am-form-field" />
<input type="number" placeholder="左" name="style[key]_margin_left" min="0" max="60" data-validation-message="外边距左最大60" value="" class="am-form-field" />
<span class="am-input-group-label">px</span>
</div>
</div>

View File

@ -0,0 +1,7 @@
<div class="am-form-group am-form-group-refreshing">
<label>内边距</label>
<div class="am-input-group am-input-group-sm">
<input type="number" placeholder="内边距" name="style[key]_padding" min="0" max="30" data-validation-message="请输入内边距、最大30的数字" value="" class="am-form-field" [required] />
<span class="am-input-group-label">px</span>
</div>
</div>

View File

@ -0,0 +1,10 @@
<div class="am-form-group am-form-group-refreshing">
<label>内边距<span class="am-form-group-label-tips">上 -> 右 -> 下 -> 左</span></label>
<div class="am-input-group am-input-group-sm group-border-width">
<input type="number" placeholder="上" name="style[key]_padding_top" min="0" max="60" data-validation-message="内边距上最大60" value="" class="am-form-field" />
<input type="number" placeholder="右" name="style[key]_padding_right" min="0" max="60" data-validation-message="内边距右最大60" value="" class="am-form-field" />
<input type="number" placeholder="下" name="style[key]_padding_bottom" min="0" max="60" data-validation-message="内边距下最大60" value="" class="am-form-field" />
<input type="number" placeholder="左" name="style[key]_padding_left" min="0" max="60" data-validation-message="内边距左最大60" value="" class="am-form-field" />
<span class="am-input-group-label">px</span>
</div>
</div>

View File

@ -0,0 +1,7 @@
<div class="am-form-group am-form-group-refreshing">
<label>[name]</label>
<div class="am-input-group am-input-group-sm">
<input type="number" placeholder="[name]" name="style[key]_width" min="0" max="[width]" data-validation-message="请输入[name]、最大[width]的数字" value="" class="am-form-field" [required] />
<span class="am-input-group-label">px</span>
</div>
</div>

View File

@ -0,0 +1,21 @@
<div class="layout-container">
{{if !empty($layout_data) and is_array($layout_data)}}
{{foreach $layout_data as $k=>$v}}
{{if !empty($v['value']) and !empty($v['children']) and is_array($v['children']) and !empty($v['value_arr']) and count($v['children']) eq count($v['value_arr']) and $v['status'] eq 1}}
<div class="layout-view">
<div class="layout-content-children {{if !empty($v['config']) and !empty($v['config']['frontend_config'])}}{{$v.config.frontend_config.ent}}{{/if}}" style="{{if !empty($v['config']) and !empty($v['config']['frontend_config'])}}{{$v.config.frontend_config.style}}{{/if}}">
{{foreach $v.children as $ks=>$vs}}
{{if count($v['value_arr']) eq 1}}
{{include file="../../../layout/view/public/common/module_view" /}}
{{else /}}
<div class="am-u-md-{{$v['value_arr'][$ks]}}">
{{include file="../../../layout/view/public/common/module_view" /}}
</div>
{{/if}}
{{/foreach}}
</div>
</div>
{{/if}}
{{/foreach}}
{{/if}}
</div>

View File

@ -40,6 +40,7 @@ class ConfigService
'admin_email_login_template',
'home_email_login_template',
'home_site_security_record_url',
'layout_index_home_data',
];
// 附件字段列表

View File

@ -241,6 +241,7 @@ class GoodsService
// 数据模式
// 0 自动模式
// 1 手动模式
// 2 拖拽模式
$floor_data_type = MyC('home_index_floor_data_type', 0, true);
// 数据处理

View File

@ -0,0 +1,103 @@
<?php
// +----------------------------------------------------------------------
// | ShopXO 国内领先企业级B2C免费开源电商系统
// +----------------------------------------------------------------------
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://opensource.org/licenses/mit-license.php )
// +----------------------------------------------------------------------
// | Author: Devil
// +----------------------------------------------------------------------
namespace app\service;
use app\service\ConfigService;
use app\layout\service\BaseLayout;
/**
* 布局服务层
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-06-22
* @desc description
*/
class LayoutService
{
// 布局key
public static $layout_key = [
'home' => 'layout_index_home_data',
];
/**
* 布局配置保存
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-06-22
* @desc description
* @param [string] $key [数据key值]
* @param [array] $params [输入参数]
*/
public static function LayoutConfigSave($key, $params)
{
// key 值是否存在
if(!array_key_exists($key, self::$layout_key))
{
return DataReturn('布局key值有', -1);
}
// 保存数据
$config = empty($params['config']) ? '' : (is_array($params['config']) ? json_encode($params['config'], JSON_UNESCAPED_UNICODE) : htmlspecialchars_decode($params['config'])) ;
$ret = ConfigService::ConfigSave([self::$layout_key[$key]=>$config]);
if($ret['code'] == 0)
{
$ret['msg'] = '操作成功';
}
return $ret;
}
/**
* 布局配置获取-管理
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-06-22
* @desc description
* @param [string] $key [数据key值]
*/
public static function LayoutConfigAdminData($key)
{
// key 值是否存在
if(!array_key_exists($key, self::$layout_key))
{
return DataReturn('布局key值有', -1);
}
// 配置数据
$config = BaseLayout::ConfigAdminHandle(MyC(self::$layout_key[$key]));
return DataReturn('success', 0, $config);
}
/**
* 布局配置获取-展示使用
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-06-22
* @desc description
* @param [string] $key [数据key值]
*/
public static function LayoutConfigData($key)
{
// key 值是否存在
if(!array_key_exists($key, self::$layout_key))
{
return DataReturn('布局key值有', -1);
}
// 配置数据
$config = BaseLayout::ConfigHandle(MyC(self::$layout_key[$key]));
return DataReturn('success', 0, $config);
}
}
?>

View File

@ -32,5 +32,168 @@ return array (
'log_write' =>
array (
),
'plugins_admin_css' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_css' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\salerecords\\Hook',
2 => 'app\\plugins\\points\\Hook',
),
'plugins_js' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\salerecords\\Hook',
2 => 'app\\plugins\\points\\Hook',
),
'plugins_service_navigation_header_handle' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\points\\Hook',
),
'plugins_service_users_center_left_menu_handle' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\usercdkey\\Hook',
),
'plugins_service_header_navigation_top_right_handle' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\usercdkey\\Hook',
),
'plugins_service_goods_save_handle' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_service_editor_path_type_admin_goods_saveinfo' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_view_goods_detail_right_content_bottom' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_view_goods_detail_base_bottom' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\salerecords\\Hook',
),
'plugins_view_goods_detail_base_buy_nav_min_inside_begin' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_service_warehouse_handle_end' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_service_buy_handle' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_service_buy_order_insert_begin' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_service_buy_order_insert_end' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\points\\Hook',
),
'plugins_service_order_status_change_history_success_handle' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\points\\Hook',
),
'plugins_service_order_aftersale_audit_handle_end' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_view_admin_goods_save' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_service_goods_handle_end' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\points\\Hook',
),
'plugins_module_form_admin_goods_index' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_module_form_admin_goods_detail' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_service_goods_buy_nav_button_handle' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_layout_service_search_goods_begin' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_view_home_floor_bottom' =>
array (
0 => 'app\\plugins\\salerecords\\Hook',
),
'plugins_service_base_data_return_api_index_index' =>
array (
0 => 'app\\plugins\\salerecords\\Hook',
),
'plugins_service_base_data_return_api_goods_detail' =>
array (
0 => 'app\\plugins\\salerecords\\Hook',
),
'plugins_service_quick_navigation_pc' =>
array (
0 => 'app\\plugins\\points\\Hook',
),
'plugins_service_quick_navigation_h5' =>
array (
0 => 'app\\plugins\\points\\Hook',
),
'plugins_service_quick_navigation_weixin' =>
array (
0 => 'app\\plugins\\points\\Hook',
),
'plugins_service_quick_navigation_alipay' =>
array (
0 => 'app\\plugins\\points\\Hook',
),
'plugins_service_quick_navigation_baidu' =>
array (
0 => 'app\\plugins\\points\\Hook',
),
'plugins_service_quick_navigation_qq' =>
array (
0 => 'app\\plugins\\points\\Hook',
),
'plugins_service_quick_navigation_toutiao' =>
array (
0 => 'app\\plugins\\points\\Hook',
),
'plugins_view_buy_form_inside' =>
array (
0 => 'app\\plugins\\points\\Hook',
),
'plugins_view_buy_base_confirm_top' =>
array (
0 => 'app\\plugins\\points\\Hook',
),
'plugins_service_buy_group_goods_handle' =>
array (
0 => 'app\\plugins\\points\\Hook',
),
'plugins_service_base_data_return_api_buy_index' =>
array (
0 => 'app\\plugins\\points\\Hook',
),
'plugins_service_user_register_end' =>
array (
0 => 'app\\plugins\\points\\Hook',
),
);
?>

View File

@ -1,3 +1,16 @@
+=========================================================+
ShopXO --- http://shopxo.net
+=========================================================+
全局
1.
web端
1. 商品详情小导航优化
插件
1. 新增销售记录插件(首页展示最新销售商品、商品详情浮窗提示)
+=========================================================+
ShopXO 2.0.3 Release 20210527 http://shopxo.net
+=========================================================+

View File

@ -19,7 +19,7 @@ return [
// 应用地址
'app_host' => '',
// 应用调试模式
'app_debug' => false,
'app_debug' => true,
// 应用Trace
'app_trace' => false,
// 是否支持多模块

View File

@ -0,0 +1,353 @@
<?php
// +----------------------------------------------------------------------
// | ShopXO 国内领先企业级B2C免费开源电商系统
// +----------------------------------------------------------------------
// | Copyright (c) 2011~2019 http://shopxo.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: Devil
// +----------------------------------------------------------------------
namespace payment;
/**
* 星链-微信
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-09-19
* @desc description
*/
class SliWeixin
{
// 插件配置参数
private $config;
//支付方式1=wechat、2=alipay、4=个人银行)
private $pay_type = 4;
/**
* 构造方法
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-09-17
* @desc description
* @param [array] $params [输入参数(支付配置参数)]
*/
public function __construct($params = [])
{
$this->config = $params;
}
/**
* 配置信息
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-09-19
* @desc description
*/
public function Config()
{
// 基础信息
$base = [
'name' => '星链-微信', // 插件名称
'version' => '1.0.0', // 插件版本
'apply_version' => '不限', // 适用系统版本描述
'apply_terminal'=> ['pc','h5'], // 适用终端 默认全部 ['pc', 'h5', 'ios', 'android', 'alipay', 'weixin', 'baidu']
'desc' => '适用PC+H5即时到帐支付方式跨境支付。 <a href="https://www.sli.money/" target="_blank">立即申请</a>', // 插件描述支持html
'author' => 'Devil', // 开发者
'author_url' => 'http://shopxo.net/', // 开发者主页
];
// 配置信息
$element = [
[
'element' => 'input',
'type' => 'text',
'default' => '',
'name' => 'accounts',
'placeholder' => '登录帐号',
'title' => '登录帐号',
'is_required' => 0,
'message' => '请填写登录帐号',
],
[
'element' => 'input',
'type' => 'text',
'default' => '',
'name' => 'secret',
'placeholder' => '密钥',
'title' => '密钥',
'is_required' => 0,
'message' => '请填写密钥',
],
[
'element' => 'input',
'type' => 'text',
'default' => 'CNY',
'name' => 'currency',
'placeholder' => '货币',
'title' => '货币',
'is_required' => 0,
'message' => '请填写货币',
],
];
return [
'base' => $base,
'element' => $element,
];
}
/**
* 支付入口
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-09-19
* @desc description
* @param [array] $params [输入参数]
*/
public function Pay($params = [])
{
// 参数
if(empty($params))
{
return DataReturn('参数不能为空', -1);
}
// 配置信息
if(empty($this->config))
{
return DataReturn('支付缺少配置', -1);
}
// 处理支付
$parameter = [
'login' => $this->config['accounts'],
'orderno' => $params['order_no'],
'paymode' => $this->pay_type,
'currency' => $this->config['currency'],
'amount' => (int) (($params['total_price']*1000)/10),
'product' => $params['name'],
'ip' => GetClientIP(),
'notifyurl' => $params['notify_url'],
'callbackurl' => $params['redirect_url'],
'rejecturl' => $params['call_back_url'],
];
// 签名
$parameter['md5check'] = $this->GetParamSign($parameter);
$url = 'https://www.sli.money/api/main/v1/payment/request';
$ret = $this->HttpRequest($url, $parameter);
if($ret['code'] == 0)
{
return DataReturn('success', 0, $ret['data']['payurl']);
}
return $ret;
}
/**
* 签名生成
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-09-19
* @desc description
* @param [array] $params [输入参数]
* @param [boolean] $is_ksort [是否需要排序]
* @param [string] $key_field [密钥字段key]
*/
private function GetParamSign($params = [], $is_ksort = false, $key_field = 'secret')
{
$string = '';
if($is_ksort)
{
ksort($params);
}
foreach($params AS $key=>$val)
{
if(!in_array($key, ['sign']))
{
$string .= $key.'='.$val.'&';
}
}
return md5($string.$key_field.'='.$this->config['secret']);
}
/**
* 支付回调处理
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-09-19
* @desc description
* @param [array] $params [输入参数]
*/
public function Respond($params = [])
{
if(empty($this->config))
{
return DataReturn('配置有误', -1);
}
if(empty($params['refno']))
{
return DataReturn('支付失败', -1);
}
if(empty($params['sign']))
{
return DataReturn('签名为空', -1);
}
// 签名验证
$sign = $this->GetParamSign($params, true, 'key');
if($sign != $params['sign'])
{
return DataReturn('签名错误', -1);
}
// 支付状态
if(isset($params['errcode']))
{
switch($params['errcode'])
{
// 收款方报故障单
case 9040 :
$ret = DataReturn('收款平台故障', -10);
break;
// 交易取消
case 9099 :
$ret = DataReturn('交易取消', -20);
break;
// 成功
case 9000 :
case 9044 :
case 9046 :
$ret = DataReturn('支付成功', 0, $this->ReturnData($params));
break;
// 默认
default :
$ret = DataReturn('支付错误['.$params['errmsg'].']', -100);
}
} else {
$ret = DataReturn('支付异常错误', -1000);
}
return $ret;
}
/**
* [ReturnData 返回数据统一格式]
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @datetime 2018-10-06T16:54:24+0800
* @param [array] $data [返回数据]
*/
private function ReturnData($data)
{
// 返回数据固定基础参数
$data['trade_no'] = isset($data['refno']) ? $data['refno'] : ''; // 支付平台 - 订单号
$data['buyer_user'] = ''; // 支付平台 - 用户
$data['out_trade_no'] = $data['orderno']; // 本系统发起支付的 - 订单号
$data['subject'] = ''; // 本系统发起支付的 - 商品名称
$data['pay_price'] = $data['amount']/100; // 本系统发起支付的 - 总价
return $data;
}
/**
* 网络请求
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @datetime 2017-09-25T09:10:46+0800
* @param [string] $url [请求url]
* @param [array] $data [发送数据]
* @param [int] $second [超时]
* @return [mixed] [请求返回数据]
*/
private function HttpRequest($url, $data, $second = 30)
{
$ch = curl_init();
$header = ['Content-Type: application/json;charset=utf-8'];
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => $header,
CURLOPT_POST => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_TIMEOUT => $second,
));
$result = curl_exec($ch);
//返回结果
if($result)
{
curl_close($ch);
$res = json_decode($result, true);
if(empty($res) || empty($res['data']) || empty($res['data']['errcode']))
{
return DataReturn('请求失败['.$result.']', -1);
}
if($res['data']['errcode'] != 200)
{
return DataReturn($this->ErrorCodeToMsg($res['data']['errcode'], $res['data']['errmsg']), -1);
}
return DataReturn('success', 0, $res['data']);
} else {
$error = curl_errno($ch);
curl_close($ch);
return DataReturn('curl出错错误码['.$error.']', -1);
}
}
/**
* 错误处理
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-06-08
* @desc description
* @param [string] $code [错误码]
* @param [string] $msg [错误信息]
*/
public function ErrorCodeToMsg($code, $msg)
{
$data = [
'4001' => '第三方登录信息不能为空',
'4002' => '第三方登录信息不存在',
'4003' => '第三方订单号信息不能为空',
'4004' => '第三方订单号不能重复',
'4005' => '第三方订单支付方式不能为空',
'4006' => '第三方订单支付方式应该为1-5 ',
'4007' => '第三方订单支付金额不能为空',
'4008' => '第三方订单支付金额应该大于等于0 第三方订单币种汇率不能为空',
'4010' => '第三方订单md5check不能为空',
'4011' => '第三方订单callbackurl不能为空',
'4012' => '第三方订单notifyurl不能为空',
'4013' => '第三方订单rejecturl不能为空',
'4014' => '第三方登录帐号已经关闭',
'4015' => '没有该订单号',
'4016' => '第三方订单号不能大於30位文字',
'4020' => '支付金额大于流量,请先买流量',
'4021' => '支付金额大于最大限额,请把支付金额调小',
'4021' => '请把支付金额调小',
'4023' => '不能用这种支付方式请找客服确认无效IP地址',
'4030' => '你没有当前货币的权限,请找客服确认',
'4040' => 'md5check错误',
'4041' => '不允许HTTPGET方法',
'4133' => '账户余额不足',
];
return (array_key_exists($code, $data) ? $data[$code] : $msg).'['.$code.']';
}
}
?>

View File

@ -562,7 +562,6 @@ button.colorpicker-submit img {
position: relative;
}
.am-table-scrollable-horizontal .am-table {
border-collapse: collapse;
border: 0;
margin: 0;
}

View File

@ -0,0 +1,582 @@
/**
* 选项卡切换
*/
.renovation-tabs .am-nav-tabs > li.am-active > a {
border-color: #eee #eee transparent #eee;
}
.renovation-tabs .am-nav-tabs {
background: none;
border-bottom: 1px solid #eee;
}
.renovation-tabs .am-active {
border-bottom: 2px solid transparent !important;
background: #fff;
}
.renovation-tabs .am-tabs-bd {
border-color: #eee;
z-index: 1;
position: static;
}
.renovation-tabs li {
margin-bottom: -3px !important;
}
.renovation-tabs li a {
margin-right: 0;
}
.renovation-tabs li:not(.am-active) a:hover {
border-color: transparent !important;
}
.renovation-tabs .renovation-panel .scrollspy-nav.am-sticky {
background: #fff;
border: 1px solid #eee;
border-top: 0;
-webkit-box-shadow: 0 3px 5px rgb(0 0 0 / 5%);
box-shadow: 0 3px 5px rgb(0 0 0 / 5%);
padding: 5px;
}
/**
* 拖放模块
*/
.structure-drag button {
cursor: move !important;
}
/**
* 布局容器-提示
*/
.layout-container {
border: 1px solid #eee;
}
.layout-container .layout-container-tips {
border: 1px dashed #ccc;
color: #999;
padding: 20px;
text-align: center;
}
.layout-container .layout-container-tips:hover,
.layout-container .layout-container-tips.layout-view-dragenter {
border: 1px dashed #2196f3;
color: #2196f3;
}
/**
* 布局-基础
*/
.layout-content-submit .am-switch,
.layout-content-submit .am-btn:not(:last-child),
.module-view-submit-container .am-btn:not(:last-child) {
margin-right: 2px !important;
}
/**
* 布局容器-内容
*/
.layout-view {
background: #fff;
}
.layout-view .drag-submit {
background: #e6e6e6;
cursor: move !important;
text-align: right;
padding: 3px;
left: 0;
top: -28px;
width: 100%;
-webkit-box-shadow: 0 -5px 10px rgb(0 0 0 / 60%);
box-shadow: 0 -5px 10px rgb(0 0 0 / 60%);
}
.layout-view .layout-submit {
padding: 2px 5px;
}
.layout-view .drag-submit .am-switch-handle-on,
.layout-view .drag-submit .am-switch-handle-off,
.layout-view .drag-submit .am-switch-label {
padding: 3px 5px;
}
.layout-content {
border: 1px dashed rgb(244 244 244 / 50%);
}
.layout-content:hover {
border-color: #666;
}
.layout-content-tips {
color: #ccc;
text-align: center;
padding: 10px;
}
.layout-content-tips:hover,
.layout-content-dragenter .layout-content-tips {
color: #666;
}
.layout-view,
.layout-content-container,
.layout-content-children,
.module-view {
position: sticky;
}
.layout-content-children > [class^="am-u-md"] {
padding: 0;
}
.layout-view .drag-submit,
.layout-content-submit-container,
.module-view-submit-container {
position: absolute;
z-index: 1;
display: none;
}
.layout-content-submit-container .am-btn,
.module-view-submit-container .am-btn {
-webkit-box-shadow: 0 3px 5px rgb(0 0 0 / 30%);
box-shadow: 0 3px 5px rgb(0 0 0 / 30%);
}
.layout-content-submit-container {
top: 0;
right: 1px;
}
.layout-view:hover .drag-submit,
.layout-content-children:hover .layout-content-submit-container,
.module-view:hover .module-view-submit-container {
display: block;
}
.module-view:hover {
background: rgb(222 243 255 / 15%);
}
.layout-container .layout-view:first-child {
margin-top: 0;
}
.layout-container .layout-view:last-child {
margin-bottom: 0;
}
.layout-container .drag-sort-dotted {
border-width: 2px !important;
}
.layout-view-hidden .layout-content-submit {
background: #ffdddd !important;
}
.layout-view-hidden .layout-content {
border-color: #f00 !important;
}
/**
* 布局新添加的样式
*/
.layout-view-new {
border: 1px solid #4caf50;
-webkit-box-shadow: 0 0px 4px #4caf50;
box-shadow: 0 0px 4px #4caf50;
}
/**
* 布局拖拽过程中经过的元素样式
*/
.layout-view-dragenter {
border: 2px solid #2196f3;
}
.layout-view-dragenter .layout-view-dragenter-icon {
color: #2296f3;
display: block !important;
visibility: inherit !important;
position: absolute;
left: calc(50% - 8px);
top: -13px;
}
/**
* 模块
*/
.module-view-submit-container {
top: -1px;
left: 0;
}
/**
* 模块拖拽过程中经过的元素样式
*/
.layout-content-dragenter {
border: 1px dashed #2196f3;
-webkit-box-shadow: 0 0px 4px #2196f3;
box-shadow: 0 0px 4px #2196f3;
}
/**
* 颜色组件
*/
.colorpicker-submit {
background-color: #fff;
}
/**
* 模块设置侧边栏
*/
.module-offcanvas-container .am-offcanvas-bar {
background: #fff;
width: 330px;
}
.module-offcanvas-container .am-offcanvas-bar,
.module-offcanvas-container .goods-search-container {
padding-bottom: 51px;
}
.am-offcanvas.am-active .am-offcanvas-bar.am-offcanvas-bar-active {
-webkit-transform: none;
-ms-transform: none;
transform: none;
}
.module-offcanvas-container .am-offcanvas-content {
color: #666;
}
.module-offcanvas-container .am-offcanvas-bar:after {
background: #ccc;
}
.module-offcanvas-container .am-form-group-refreshing {
padding: 0 0 15px 0 !important;
}
.module-offcanvas-container .module-images-type-images-view,
.module-offcanvas-container .module-slider-type-images-view {
padding: 0;
}
.module-offcanvas-container .am-offcanvas-content .am-panel {
-webkit-box-shadow: none;
box-shadow: none;
}
.module-offcanvas-container .module-images-type-images-view li,
.module-offcanvas-container .module-slider-type-images-view li {
width: 100%;
height: auto;
margin: 0;
}
.module-offcanvas-container .form-submit-container {
position: fixed;
bottom: 0;
left: 0;
width: 329px;
padding: 10px;
border-top: 1px solid #dfdfdf;
background: #f5f5f5;
z-index: 2;
}
.module-offcanvas-container .text-tips {
color: #ccc;
}
.module-offcanvas-container .am-tabs-d2 {
margin-bottom: 20px;
}
.module-offcanvas-container .am-tabs-d2 .am-tabs-bd {
border: 1px solid #ddd;
overflow: inherit;
}
.module-offcanvas-container .am-panel .am-panel-bd .am-form-group:last-child {
padding-bottom: 5px !important;
}
@media only screen and (max-width: 640px) {
.module-offcanvas-container .am-offcanvas-bar {
width: 280px;
}
.module-offcanvas-container .form-submit-container {
width: 279px;
}
}
/**
* 表单小组合组件
*/
.group-border-width input,
.group-list-number-width input {
display: -webkit-inline-box;
text-align: center;
}
.group-border-width input {
width: 25% !important;
}
.group-list-number-width input {
width: 33.33% !important;
}
.group-list-number-width {
background: #ccc;
}
.group-list-number-width input:nth-child(3) {
border-right-width: 0px;
}
.group-border-width input:not(:first-child),
.group-list-number-width input:not(:first-child),
.group-border-radius-color .am-input-group-label {
border-left: 0;
}
.group-border-radius-color .colorpicker-submit img {
width: 14px;
height: 14px;
}
.group-border-style .chosen-container {
width: 72px !important;
}
.group-border-style .chosen-container:not(:last-child) {
margin-right: 5px;
}
@media only screen and (max-width: 640px) {
.group-border-style .chosen-container {
width: 59px !important;
}
}
/**
* 链接地址选择
*/
.form-view-choice-container-active {
padding: 6px;
border: 1px solid #ccc;
cursor: pointer;
}
.form-view-choice-container-active .am-text-truncate {
max-width: 70%;
display: inline-block;
vertical-align: bottom;
}
.form-view-choice-container-active i:hover {
color: #f00;
}
.form-view-choice-container a {
color: #3bb4f2;
text-decoration: none;
}
.form-view-choice-container a:hover {
color: #2196f3;
}
/**
* 模块设置侧边栏 - 商品
*/
#offcanvas-module-config-goods .config-goods-list {
}
#offcanvas-module-config-goods .config-goods-list li {
float: left;
border: 1px solid #eee;
position: relative;
}
#offcanvas-module-config-goods .config-goods-list li:hover {
border: 1px solid #ccc;
}
#offcanvas-module-config-goods .config-goods-list li:not(:last-child) {
margin: 0 15px 15px 0;
}
#offcanvas-module-config-goods .config-goods-list li img {
width: 33px;
height: 33px;
}
#offcanvas-module-config-goods .config-goods-list li .am-close,
#offcanvas-module-config-many-images .config-many-images-container .am-panel .am-close {
position: absolute;
top: -8px;
right: -8px;
width: 18px;
font-size: 12px;
line-height: 18px;
opacity: 1;
}
/**
* 模块设置侧边栏 - 视频
*/
#offcanvas-module-config-video ul.plug-file-upload-view-video li,
#offcanvas-module-config-video ul.plug-file-upload-view li {
width: 100%;
height: auto;
}
/**
* 模块设置侧边栏 - 多图
*/
#offcanvas-module-config-many-images .config-many-images-container .am-panel {
position: relative;
}
#offcanvas-module-config-many-images .config-many-images-container .am-panel .am-form-group:last-child {
padding-bottom: 5px !important;
}
/**
* 模块设置侧边栏 - 标题
*/
#offcanvas-module-config-title .config-title-container li {
position: relative;
}
#offcanvas-module-config-title .config-title-container li span {
width: calc(100% - 55px);
}
#offcanvas-module-config-title .config-title-container li a.am-icon-edit,
#offcanvas-module-config-title .config-title-container li a.am-icon-remove {
position: absolute;
top: 0;
right: 0;
padding: 10px;
}
#offcanvas-module-config-title .config-title-container li a.am-icon-edit {
right: 30px;
}
/**
* 页面选择
*/
#modal-module-pages-select .am-scrollable-vertical {
border-bottom: 1px solid #dedede;
margin-bottom: 0;
}
#modal-module-pages-select .am-scrollable-vertical a {
text-decoration: none;
padding-right: 30px;
}
#modal-module-pages-select .am-accordion-default {
margin: 0 0 15px 0;
}
#modal-module-pages-select .am-accordion-default .am-accordion-title {
background: #f0f8ff;
}
#modal-module-pages-select .am-accordion-default:last-child {
margin-bottom: 0;
}
#modal-module-pages-select .am-tabs-bd ul li {
border-width: 1px 0;
}
#modal-module-pages-select .am-tabs-bd ul li:last-child {
border-bottom: 0;
}
#modal-module-pages-select .am-tabs-bd ul.am-scrollable-vertical > li:first-child {
border-top: 0;
}
#modal-module-pages-select .am-tabs-bd ul li.active a {
background: #d2354c;
color: #fff;
}
#modal-module-pages-select .am-tabs-bd ul li.active a i {
display: block !important;
visibility: initial !important;
position: absolute;
top: 10px;
right: 10px;
}
/**
* 商品添加-搜索列表
*/
.layout-forth-selection-container {
height: 100%;
}
.layout-forth-selection-container .forth-selection-container select.forth-selection-form-category {
display: -webkit-inline-box;
}
.layout-forth-selection-container .forth-selection-container .forth-selection-form-category, .forth-selection-container .chosen-container, .forth-selection-container .forth-selection-form-keywords {
width: calc(50% - 48px) !important;
}
.layout-forth-selection-container .forth-selection-container .chosen-container, .forth-selection-container .forth-selection-form-keywords {
display: -webkit-inline-box !important;
}
.layout-forth-selection-container .forth-selection-container .chosen-single {
width: 100%;
}
.layout-forth-selection-container .forth-selection-container .search-submit {
width: 87px;
}
.layout-forth-selection-container .goods-list-container {
height: calc(100% - 157px);
border: 1px solid #eee;
}
.layout-forth-selection-container .goods-list-container .am-gallery-bordered .am-gallery-title {
margin-top: 5px;
}
.layout-forth-selection-container .goods-list-container ul li {
position: relative;
cursor: pointer;
}
.layout-forth-selection-container .goods-list-container ul li:hover .am-gallery-item {
-webkit-box-shadow: 0 0 6px #3cb4f1;
box-shadow: 0 0 6px #3cb4f1;
}
.layout-forth-selection-container .goods-list-container .icon-submit-container {
position: absolute;
right: 15px;
bottom: 47px;
}
.layout-forth-selection-container .goods-list-container .icon-submit-container .am-icon-btn {
width: 36px;
height: 36px;
line-height: 36px;
font-size: 20px;
-webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
}
.layout-forth-selection-container .goods-list-container .am-icon-btn.am-success:hover {
background: #4CAF50;
}
.layout-forth-selection-container .goods-list-container .am-icon-btn.am-danger:hover {
background: #F44336;
}
.layout-forth-selection-container .goods-page-container {
height: 40px;
}
.layout-forth-selection-container .goods-bottom-operate-container {
background: #f5f5f5;
border-top: 1px solid #dedede;
position: fixed;
left: 0;
bottom: 25px;
width: calc(100% - 50px);
margin: 0 25px;
}
/**
* 商品分类选择
*/
.layout-category-choice .goods-category-choice-content {
background: #f8f8f8;
border: 1px solid #eee;
}
.layout-category-choice .goods-category-choice-content ul {
width: calc(33% - 15px);
margin-bottom: 0;
height: 380px;
background: #fff;
border: 1px solid #dedede;
}
.layout-category-choice .goods-category-choice-content ul li {
border-width: 1px 0;
border-top: 0;
margin-bottom: 0;
}
.layout-category-choice .goods-category-choice-content ul li:not(:nth-child(-n+7)):last-child {
border-bottom: 0;
}
.layout-category-choice .goods-category-choice-content ul li:first-child {
border-bottom: 1px solid #dedede;
}
.layout-category-choice .goods-category-choice-content ul li a {
text-decoration: none;
}
.layout-category-choice .goods-category-choice-content ul li.active a {
background: #d2354c;
color: #fff;
}
.layout-category-choice .goods-category-choice .already-select-tips {
padding: 10px 15px;
border: 1px solid #ed7f5a;
margin-top: 10px;
margin-bottom: 10px;
background-color: #fff4f0;
color: #ed7f5a;
}
.layout-category-choice .form-container-category .goods-category-choice-content {
padding: 15px;
background: #fcfcfc;
}
.layout-category-choice .form-container-brand .goods-category-choice-content {
border: 0px;
}
.layout-category-choice .form-container-brand ul {
width: 100%;
height: 465px;
}
@media only screen and (max-width: 640px) {
.layout-category-choice .form-container-category .goods-category-choice-content ul.am-margin-left-lg {
margin-left: 20px;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -557,10 +557,9 @@ function FormDataFill(json, tag)
$form.find('input[type="hidden"][name="'+i+'"], input[type="text"][name="'+i+'"], input[type="password"][name="'+i+'"], input[type="email"][name="'+i+'"], input[type="number"][name="'+i+'"], input[type="date"][name="'+i+'"], textarea[name="'+i+'"], select[name="'+i+'"], input[type="url"][name="'+i+'"]').val(json[i]);
// input radio
$form.find('input[type="radio"][name="'+i+'"]').each(function(temp_value, temp_tag)
$form.find('input[type="radio"][name="'+i+'"]').each(function(k, v)
{
var state = (json[i] == temp_value);
this.checked = state;
this.checked = (json[i] == $(this).val());
});
}
@ -574,6 +573,14 @@ function FormDataFill(json, tag)
}
}
// switch切换插件
$form.find('.am-switch').each(function(k, v)
{
var name = $(this).find('input').attr('name') || null;
var state = (name == null || (json[name] || 0) == 0) ? false : true;
$(this).find('input').bootstrapSwitch('state', state);
});
// 多选插件事件更新
if($('.chosen-select').length > 0)
{

File diff suppressed because it is too large Load Diff

View File

@ -183,4 +183,16 @@ text-align: center;float:none}
.floor .goods-list .goods-items { width: 50%; float: left; padding: 10px; border-bottom: 1px solid #eee; }
.floor .goods-list .goods-items:nth-of-type(2n + 1) { border-right: 1px solid #eee; }
.floor .goods-list .goods-items:nth-of-type(2n) { border-left: 1px solid transparent; }
}
/**
* 布局保存
*/
.layout-operate-container .am-btn {
padding: 4px 10px;
}
@media only screen and (max-width: 1025px) {
.layout-operate-container {
margin-right: 10px;
}
}

View File

@ -8,6 +8,11 @@ function FloorResizeHandle()
});
}
$(window).load(function()
{
FloorResizeHandle();
});
$(function()
{
// 新闻轮播
@ -35,9 +40,37 @@ $(function()
FloorResizeHandle();
});
});
// 布局保存
$('.layout-operate-container button').on('click', function()
{
var $this = $(this);
$this.button('loading');
$.ajax({
url: $('.layout-operate-container').data('save-url'),
type: 'post',
data: {"config": JSON.stringify(LayoutViewConfig())},
dataType: 'json',
success:function(res)
{
if(res['code'] == 0)
{
Prompt(res.msg, 'success');
setTimeout(function()
{
window.location.href = __my_url__;
}, 1500);
} else {
$this.button('reset');
Prompt(res.msg);
}
},
error:function(res)
{
$this.button('reset');
var msg = HtmlToString(xhr.responseText) || '异常错误';
Prompt(msg, null, 30);
}
});
});
$(window).load(function()
{
FloorResizeHandle();
});