应用商店帐号绑定、更新检查

This commit is contained in:
Devil 2021-04-20 18:38:23 +08:00
parent a67724048c
commit 75ee4acae7
17 changed files with 957 additions and 96 deletions

View File

@ -188,7 +188,7 @@ class Goods extends Common
// 商品分类 // 商品分类
$this->assign('goods_category_list', GoodsService::GoodsCategoryAll()); $this->assign('goods_category_list', GoodsService::GoodsCategoryAll());
// 品牌分类 // 品牌
$this->assign('brand_list', BrandService::CategoryBrand()); $this->assign('brand_list', BrandService::CategoryBrand());
// 规格扩展数据 // 规格扩展数据

View File

@ -11,6 +11,8 @@
namespace app\admin\controller; namespace app\admin\controller;
use app\service\StatisticalService; use app\service\StatisticalService;
use app\service\StoreService;
use app\service\ConfigService;
/** /**
* 首页 * 首页
@ -112,7 +114,69 @@ class Index extends Common
$goods_hot_sale = StatisticalService::GoodsHotSaleSevenTodayTotal(); $goods_hot_sale = StatisticalService::GoodsHotSaleSevenTodayTotal();
$this->assign('goods_hot_sale', $goods_hot_sale['data']); $this->assign('goods_hot_sale', $goods_hot_sale['data']);
// 配置信息
$config = ConfigService::ConfigList();
$this->assign('config_data', $config);
// 站点商店信息
$site_store_info = StoreService::SiteStoreInfo();
if(empty($site_store_info))
{
$site_params = [
'common_store_accounts' => MyC('common_store_accounts'),
'common_store_password' => MyC('common_store_password'),
];
$res = StoreService::SiteStoreAccountsBind($site_params);
if($res['code'] == 0)
{
$site_store_info = StoreService::SiteStoreInfo();
}
}
$this->assign('site_store_info', $site_store_info);
return $this->fetch(); return $this->fetch();
} }
/**
* 应用商店帐号绑定
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-16
* @desc description
*/
public function StoreAccountsBind()
{
// 是否ajax请求
if(!IS_AJAX)
{
return $this->error('非法访问');
}
// 开始处理
$params = $this->data_request;
return StoreService::SiteStoreAccountsBind($params);
}
/**
* 检查更新
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-16
* @desc description
*/
public function InspectUpgrade()
{
// 是否ajax请求
if(!IS_AJAX)
{
return $this->error('非法访问');
}
// 开始处理
$params = $this->data_request;
return StoreService::SiteInspectUpgrade($params);
}
} }
?> ?>

View File

@ -3,8 +3,39 @@
<!-- right content start --> <!-- right content start -->
<div class="content-right"> <div class="content-right">
<div class="content"> <div class="content">
<!-- 顶部基础信息 -->
<div class="block-container base-content-top am-nbfc">
<div class="am-fl am-nbfc left-content">
<!-- 帐号信息 -->
{{if !empty($site_store_info) and !empty($site_store_info['user'])}}
<i class="am-icon-user"></i>
<span>{{$site_store_info.user.user_name_view}}</span>
<a href="javascript:;" class="am-margin-left-xs" data-am-modal="{target: '#store-accounts-popup'}">修改</a>
{{else /}}
<a href="javascript:;" class="am-margin-left-xs" data-am-modal="{target: '#store-accounts-popup'}">绑定ShopXO商店账户</a>
{{/if}}
<!-- 广告 -->
{{if !empty($site_store_info) and !empty($site_store_info['adverts']) and !empty($site_store_info['adverts']['name'])}}
<a class="am-margin-left-sm am-text-danger ad-content {{if !empty($site_store_info['adverts']['icon'])}}{{$site_store_info.adverts.icon}}{{/if}}" {{if empty($site_store_info['adverts']['url'])}}href="javascript:;"{{else /}}href="{{$site_store_info.adverts.url}}" target="_blank"{{/if}}> {{$site_store_info.adverts.name}}</a>
{{/if}}
</div>
<div class="am-fr am-nbfc right-content">
<!-- VIP授权信息 -->
{{if !empty($site_store_info) and !empty($site_store_info['vip']) and !empty($site_store_info['vip']['auth_view'])}}
<a class="am-icon-diamond vip {{if isset($site_store_info['vip']['status']) and $site_store_info['vip']['status'] eq 1}}vip-active{{/if}}" {{if empty($site_store_info['vip']['go_url'])}}href="javascript:;"{{else /}}href="{{$site_store_info.vip.go_url}}" target="_blank"{{/if}} {{if !empty($site_store_info['vip']['auth_person'])}}data-am-popover="{content: '授权主体:{{$site_store_info.vip.auth_person}}', trigger: 'hover focus', theme: 'sm'}"{{/if}}> {{$site_store_info.vip.auth_view}}</a>
{{/if}}
<!-- 右侧版本信息及更新检查 -->
<span class="right-base">
<a href="https://ask.shopxo.net/article/148" target="_blank" class="am-margin-left-xs">{{$Think.APPLICATION_VERSION}}</a>
<a href="javascript:;" class="am-margin-left-sm inspect-upgrade-submit" data-url="{{:MyUrl('admin/index/inspectupgrade')}}">检查更新{{if !empty($site_store_info) and !empty($site_store_info['upgrade']) and !empty($site_store_info['upgrade']['version_old']) and $site_store_info['upgrade']['version_old'] eq $Think.APPLICATION_VERSION}}<i></i>{{/if}}</a>
</span>
</div>
</div>
<!-- 基础统计 --> <!-- 基础统计 -->
<div class="echarts-container shopxo-base"> <div class="block-container shopxo-base">
<div class="echarts-title"> <div class="echarts-title">
<span class="icon"></span> <span class="icon"></span>
<span class="title">商城统计</span> <span class="title">商城统计</span>
@ -106,7 +137,7 @@
</div> </div>
<!-- 近30日订单成交金额走势 --> <!-- 近30日订单成交金额走势 -->
<div class="echarts-container"> <div class="block-container">
<div class="echarts-title"> <div class="echarts-title">
<span class="icon"></span> <span class="icon"></span>
<span class="title">近30日订单成交金额走势</span> <span class="title">近30日订单成交金额走势</span>
@ -115,7 +146,7 @@
</div> </div>
<!-- 近30日订单交易走势 --> <!-- 近30日订单交易走势 -->
<div class="echarts-container"> <div class="block-container">
<div class="echarts-title"> <div class="echarts-title">
<span class="icon"></span> <span class="icon"></span>
<span class="title">近30日订单交易走势</span> <span class="title">近30日订单交易走势</span>
@ -124,7 +155,7 @@
</div> </div>
<!-- 组合 --> <!-- 组合 -->
<ul class="am-avg-sm-1 am-avg-sm-2 am-avg-lg-2 echarts-combination-container-2"> <ul class="am-avg-sm-1 am-avg-sm-2 am-avg-lg-2 block-combination-container-2">
<li> <li>
<!-- 近30日热销商品 --> <!-- 近30日热销商品 -->
<div class="echarts-title"> <div class="echarts-title">
@ -145,7 +176,7 @@
</ul> </ul>
<!-- 系统信息 --> <!-- 系统信息 -->
<ul class="am-avg-sm-1 am-avg-sm-2 am-avg-lg-2 echarts-combination-container-2"> <ul class="am-avg-sm-1 am-avg-sm-2 am-avg-lg-2 block-combination-container-2 am-padding-bottom-sm">
<li> <li>
<div class="echarts-title"> <div class="echarts-title">
<span class="icon"></span> <span class="icon"></span>
@ -214,6 +245,51 @@
</div> </div>
<!-- right content end --> <!-- right content end -->
<!-- 应用商店账户绑定 -->
<div class="am-popup popup-not-title" id="store-accounts-popup">
<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">
<!-- form start -->
<form class="am-form form-validation view-save" action="{{:MyUrl('admin/index/storeaccountsbind')}}" method="POST" request-type="ajax-reload">
<div class="am-form-group am-form-group-refreshing business-form-block am-margin-top-xs">
<label>账号<span class="am-form-group-label-tips-must">必填</span></label>
<input type="text" name="common_store_accounts" placeholder="用户名/手机/邮箱" data-validation-message="账号格式1~30个字符" class="am-radius" value="{{if !empty($config_data) and !empty($config_data['common_store_accounts'])}}{{$config_data.common_store_accounts.value}}{{/if}}" required />
</div>
<div class="am-form-group am-form-group-refreshing business-form-block am-margin-top-xs">
<label>密码<span class="am-form-group-label-tips-must">必填</span></label>
<input type="password" name="common_store_password" placeholder="登录密码" data-validation-message="登录密码格式6~30个字符" class="am-radius" value="{{if !empty($config_data) and !empty($config_data['common_store_password'])}}{{$config_data.common_store_password.value}}{{/if}}" required />
</div>
<div class="am-form-group am-form-group-refreshing am-margin-top-sm">
<button type="submit" class="am-btn am-btn-primary am-radius btn-loading-example am-btn-sm am-btn-block" data-am-loading="{loadingText:'绑定中...'}">绑定</button>
</div>
<div class="am-margin-top-xr am-text-right am-padding-right-xs">
<a href="https://store.shopxo.net/regster.html" target="_blank">未有账号,去注册</a>
</div>
<p class="am-text-warning am-text-center am-margin-top-sm">一个账号支持绑定多台ShopXO商城</p>
</form>
<!-- form end -->
</div>
</div>
</div>
<!-- 检查更新显示信息 -->
<div class="am-popup popup-not-title" id="inspect-upgrade-popup">
<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">
<div class="upgrade-content"></div>
<div class="upgrade-bottom am-text-right">
<div class="upgrade-bottom-content">
<button type="button" class="am-btn am-btn-default am-radius am-btn-xs" data-am-modal-close>取消</button>
<button type="button" class="am-btn am-btn-success am-radius am-btn-xs am-margin-left-sm am-hide inspect-upgrade-confirm">立即更新</button>
</div>
</div>
</div>
</div>
</div>
<!-- footer start --> <!-- footer start -->
{{include file="public/footer" /}} {{include file="public/footer" /}}
<!-- footer end --> <!-- footer end -->

View File

@ -20,7 +20,7 @@
</li> </li>
<li> <li>
<button type="button" class="am-btn am-btn-link am-btn-xs am-btn-block am-text-left am-padding-horizontal-sm am-icon-plus submit-add" data-am-modal="{target: '#nav-customview-save-win'}" data-tag="nav-customview-save-win"> 自定义页面</button> <button type="button" class="am-btn am-btn-link am-btn-xs am-btn-block am-text-left am-padding-horizontal-sm am-icon-plus submit-add" data-am-modal="{target: '#nav-customview-save-win'}" data-tag="nav-customview-save-win"> 自定义页面</button>
</li> </li>
<li> <li>
<button type="button" class="am-btn am-btn-link am-btn-xs am-btn-block am-text-left am-padding-horizontal-sm am-icon-plus submit-add" data-am-modal="{target: '#nav-goods_category-save-win'}" data-tag="nav-goods_category-save-win"> 商品分类</button> <button type="button" class="am-btn am-btn-link am-btn-xs am-btn-block am-text-left am-padding-horizontal-sm am-icon-plus submit-add" data-am-modal="{target: '#nav-goods_category-save-win'}" data-tag="nav-goods_category-save-win"> 商品分类</button>
</li> </li>

View File

@ -2,9 +2,11 @@
<li {{if $view_type eq 'home'}}class="am-active"{{/if}}> <li {{if $view_type eq 'home'}}class="am-active"{{/if}}>
<a href="{{:MyUrl('admin/pluginsadmin/index', ['view_type'=>'home'])}}">应用管理</a> <a href="{{:MyUrl('admin/pluginsadmin/index', ['view_type'=>'home'])}}">应用管理</a>
</li> </li>
<li {{if $view_type eq 'upload'}}class="am-active"{{/if}}> {{if isset($shopxo_is_develop) and $shopxo_is_develop eq true}}
<a href="{{:MyUrl('admin/pluginsadmin/index', ['view_type'=>'upload'])}}">上传应用</a> <li {{if $view_type eq 'upload'}}class="am-active"{{/if}}>
</li> <a href="{{:MyUrl('admin/pluginsadmin/index', ['view_type'=>'upload'])}}">上传应用</a>
</li>
{{/if}}
<li class="fr"> <li class="fr">
<a class="am-margin-left-sm" href="{{$store_url}}" target="_blank">更多插件下载 <i class="am-icon-external-link"></i></a> <a class="am-margin-left-sm" href="{{$store_url}}" target="_blank">更多插件下载 <i class="am-icon-external-link"></i></a>
</li> </li>

View File

@ -7,7 +7,7 @@
<div class="am-scrollable-vertical form-table-fields-list-container"> <div class="am-scrollable-vertical form-table-fields-list-container">
{{if !empty($form_user_fields)}} {{if !empty($form_user_fields)}}
<div class="am-alert am-margin-bottom-0"> <div class="am-alert am-margin-bottom-0">
<p>可点击拖拽调整显示顺序</p> <p>可点击拖拽调整显示顺序、如需恢复点击重置即可</p>
</div> </div>
<ul class="am-list am-list-static am-list-striped am-margin-bottom-0 form-table-fields-content-container"> <ul class="am-list am-list-static am-list-striped am-margin-bottom-0 form-table-fields-content-container">
{{foreach $form_user_fields as $v}} {{foreach $form_user_fields as $v}}

View File

@ -76,7 +76,11 @@ function GetUrlHost($url)
{ {
// 地址解析 // 地址解析
$arr = parse_url(strtolower($url)); $arr = parse_url(strtolower($url));
$host = (count($arr) == 1) ? $arr['path'] : $arr['host']; $host = (count($arr) == 1) ? $arr['path'] : (empty($arr['host']) ? '' : $arr['host']);
if(empty($host))
{
return $url;
}
// 是否存在斜杠 // 是否存在斜杠
if(stripos($host, '/') !== false) if(stripos($host, '/') !== false)

View File

@ -7,7 +7,7 @@
<div class="am-scrollable-vertical form-table-fields-list-container"> <div class="am-scrollable-vertical form-table-fields-list-container">
{{if !empty($form_user_fields)}} {{if !empty($form_user_fields)}}
<div class="am-alert am-margin-bottom-0"> <div class="am-alert am-margin-bottom-0">
<p>可点击拖拽调整显示顺序</p> <p>可点击拖拽调整显示顺序、如需恢复点击重置即可</p>
</div> </div>
<ul class="am-list am-list-static am-list-striped am-margin-bottom-0 form-table-fields-content-container"> <ul class="am-list am-list-static am-list-striped am-margin-bottom-0 form-table-fields-content-container">
{{foreach $form_user_fields as $v}} {{foreach $form_user_fields as $v}}

View File

@ -37,6 +37,7 @@ class ConfigService
'home_index_floor_manual_mode_goods', 'home_index_floor_manual_mode_goods',
'home_index_floor_left_top_category', 'home_index_floor_left_top_category',
'admin_email_login_template', 'admin_email_login_template',
'home_email_login_template',
]; ];
// 附件字段列表 // 附件字段列表
@ -63,6 +64,43 @@ class ConfigService
'home_search_params_type', 'home_search_params_type',
]; ];
// 需要文件缓存的key
public static $file_cache_keys = [
// 伪静态后缀
'home_seo_url_html_suffix',
// 前端默认主题
'common_default_theme',
// 时区
'common_timezone',
// 是否开启redis缓存
'common_data_is_use_cache',
'common_cache_data_redis_host',
'common_cache_data_redis_port',
'common_cache_data_redis_password',
'common_cache_data_redis_expire',
'common_cache_data_redis_prefix',
// session是否开启redis缓存
'common_session_is_use_cache',
'common_cache_session_redis_host',
'common_cache_session_redis_port',
'common_cache_session_redis_password',
'common_cache_session_redis_expire',
'common_cache_session_redis_prefix',
// cdn地址
'common_cdn_attachment_host',
'common_cdn_public_host',
// 编辑器配置信息
'home_max_limit_image',
'home_max_limit_video',
'home_max_limit_file',
];
/** /**
* 配置列表唯一标记作为key * 配置列表唯一标记作为key
* @author Devil * @author Devil
@ -238,7 +276,10 @@ class ConfigService
cache($k, $v); cache($k, $v);
// 数据文件缓存 // 数据文件缓存
MyFileConfig($k, $v); if(array_key_exists($k, self::$file_cache_keys))
{
MyFileConfig($k, $v);
}
} }
// 所有配置缓存集合 // 所有配置缓存集合

View File

@ -215,7 +215,7 @@ class PluginsAdminService
* @desc description * @desc description
* @param [string] $plugins [插件名称] * @param [string] $plugins [插件名称]
*/ */
private static function GetPluginsConfig($plugins) public static function GetPluginsConfig($plugins)
{ {
$config = []; $config = [];
$file = APP_PATH.'plugins'.DS.$plugins.DS.'config.json'; $file = APP_PATH.'plugins'.DS.$plugins.DS.'config.json';

View File

@ -13,6 +13,7 @@ namespace app\service;
use think\Db; use think\Db;
use app\service\ResourcesService; use app\service\ResourcesService;
use app\service\PluginsAdminService; use app\service\PluginsAdminService;
use app\service\StoreService;
/** /**
* 应用服务层 * 应用服务层
@ -295,15 +296,15 @@ class PluginsService
// 应用控制器 // 应用控制器
$control = ucfirst($control); $control = ucfirst($control);
$plugins = '\app\plugins\\'.$plugins.'\\'.$group.'\\'.$control; $plugins_class = '\app\plugins\\'.$plugins.'\\'.$group.'\\'.$control;
if(!class_exists($plugins)) if(!class_exists($plugins_class))
{ {
return DataReturn('应用控制器未定义['.$control.']', -1); return DataReturn('应用控制器未定义['.$control.']', -1);
} }
// 调用方法 // 调用方法
$action = ucfirst($action); $action = ucfirst($action);
$obj = new $plugins($params); $obj = new $plugins_class($params);
if(!method_exists($obj, $action)) if(!method_exists($obj, $action))
{ {
return DataReturn('应用方法未定义['.$action.']', -1); return DataReturn('应用方法未定义['.$action.']', -1);
@ -314,6 +315,35 @@ class PluginsService
{ {
$params = $params['data_request']; $params = $params['data_request'];
} }
// 安全判断
if(config('shopxo.is_develop') === false)
{
$key = 'plugins_legal_check_'.$plugins;
$status = cache($key);
if(empty($status))
{
$config = PluginsAdminService::GetPluginsConfig($plugins);
if(!empty($config) && is_array($config))
{
unset($config['hook']);
} else {
$config = [];
}
$check_params = [
'config' => $config,
'plugins' => $plugins,
];
$ret = StoreService::PluginsLegalCheck($check_params);
if($ret['code'] != 0)
{
return $ret;
}
cache($key, 1, 600);
}
}
// 调用对应插件
return DataReturn('调用成功', 0, $obj->$action($params)); return DataReturn('调用成功', 0, $obj->$action($params));
} }

View File

@ -10,6 +10,8 @@
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
namespace app\service; namespace app\service;
use app\service\ConfigService;
/** /**
* 应用商店服务层 * 应用商店服务层
* @author Devil * @author Devil
@ -19,6 +21,18 @@ namespace app\service;
*/ */
class StoreService class StoreService
{ {
// 远程信息接口
public static $store_site_info_url = 'https://store.shopxo.net/index.php?s=/api/plugins/index&pluginsname=store&pluginscontrol=index&pluginsaction=siteinfo';
// 远程检查更新接口
public static $store_inspect_upgrade_url = 'https://store.shopxo.net/index.php?s=/api/plugins/index&pluginsname=store&pluginscontrol=index&pluginsaction=inspectupgrade';
// 远程插件安全合法校验接口
public static $store_plugins_legal_check_url = 'https://store.shopxo.net/index.php?s=/api/plugins/index&pluginsname=store&pluginscontrol=index&pluginsaction=pluginslegalcheck';
// 站点商店数据缓存key
public static $site_store_info_key = 'admin_site_store_info_data';
/** /**
* 应用商店地址 * 应用商店地址
* @author Devil * @author Devil
@ -78,5 +92,183 @@ class StoreService
// 拼接商店请求参数地址 // 拼接商店请求参数地址
return '?name='.urldecode(base64_encode(MyC('home_site_name'))).'&ver='.urldecode(base64_encode(APPLICATION_VERSION)).'&url='.urlencode(base64_encode(__MY_URL__)).'&host='.urlencode(base64_encode(__MY_HOST__)).'&ip='.urlencode(base64_encode(__MY_ADDR__)).'&admin_url='.urlencode(base64_encode($admin_url[0])); return '?name='.urldecode(base64_encode(MyC('home_site_name'))).'&ver='.urldecode(base64_encode(APPLICATION_VERSION)).'&url='.urlencode(base64_encode(__MY_URL__)).'&host='.urlencode(base64_encode(__MY_HOST__)).'&ip='.urlencode(base64_encode(__MY_ADDR__)).'&admin_url='.urlencode(base64_encode($admin_url[0]));
} }
/**
* 获取站点商店信息
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-16
* @desc description
*/
public static function SiteStoreInfo()
{
$res = cache(self::$site_store_info_key);
return empty($res) ? [] : $res;
}
/**
* 站点应用商店帐号绑定
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-16
* @desc description
* @param [array] $params [输入参数]
*/
public static function SiteStoreAccountsBind($params = [])
{
// 请求类型
$p = [
[
'checked_type' => 'length',
'key_name' => 'common_store_accounts',
'checked_data' => '1,30',
'error_msg' => '账号格式1~30个字符',
],
[
'checked_type' => 'length',
'key_name' => 'common_store_password',
'checked_data' => '6,30',
'error_msg' => '登录密码格式6~30个字符',
],
];
$ret = ParamsChecked($params, $p);
if($ret !== true)
{
return DataReturn($ret, -1);
}
// 保存商店帐号信息
$ret = ConfigService::ConfigSave($params);
if($ret['code'] != 0)
{
return $ret;
}
// 获取信息
$res = self::RemoteStoreData($params['common_store_accounts'], $params['common_store_password'], self::$store_site_info_url);
if($res['code'] == 0)
{
// 存储缓存、取远程给的时间未拿到时间则默认30分钟
$cache_time = (empty($res['data']['base']) || empty($res['data']['base']['cache_time'])) ? 1800 : intval($res['data']['base']['cache_time']);
cache(self::$site_store_info_key, $res['data'], $cache_time);
return DataReturn('绑定成功', 0);
}
return $res;
}
/**
* 检查更新
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-18
* @desc description
* @param [array] $params [输入参数]
*/
public static function SiteInspectUpgrade($params = [])
{
// 帐号信息
$accounts = MyC('common_store_accounts');
$password = MyC('common_store_password');
// 获取信息
return self::RemoteStoreData($accounts, $password, self::$store_inspect_upgrade_url);
}
/**
* 插件安全合法校验
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-19
* @desc description
* @param [array] $params [输入参数]
*/
public static function PluginsLegalCheck($params)
{
// 帐号信息
$accounts = MyC('common_store_accounts');
$password = MyC('common_store_password');
// 获取信息
$request_params = [
'plugins_type' => 0,
'plugins_value' => $params['plugins'],
'plugins_config' => empty($params['config']) ? [] : $params['config'],
];
return self::RemoteStoreData($accounts, $password, self::$store_plugins_legal_check_url, $request_params);
}
/**
* 远程获取数据
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-13
* @desc description
* @param [string] $accounts [帐号]
* @param [string] $password [密码]
* @param [string] $url [请求地址]
* @param [array] $params [额外参数]
*/
public static function RemoteStoreData($accounts, $password, $url, $params = [])
{
// 帐号信息
if(empty($accounts) || empty($password))
{
return DataReturn('请先绑定应用商店帐号', -1);
}
// 基础数据获取
$bo = new \base\Behavior();
// 请求校验
$data = [
'accounts' => $accounts,
'password' => $password,
'host' => __MY_HOST__,
'url' => __MY_URL__,
'ver' => APPLICATION_VERSION,
'server_port' => $bo->GetServerPort(),
'server_ip' => $bo->GetServerIP(),
'client_ip' => $bo->GetClientIP(),
'os' => $bo->GetOs(),
'browser' => $bo->GetBrowser(),
'scheme' => $bo->GetScheme(),
'version' => $bo->GetHttpVersion(),
'client' => $bo->GetClinet(),
'php_os' => PHP_OS,
'php_version' => PHP_VERSION,
'php_sapi_name' => php_sapi_name(),
'client_date' => date('Y-m-d H:i:s'),
];
$res = CurlPost($url, array_merge($data, $params));
$result = json_decode($res, true);
if(empty($result))
{
return DataReturn('接口请求失败'.(empty($res) ? '' : '['.$res.']'), -1);
}
// 是否非数组
if(is_string($result))
{
return DataReturn($result, -1);
}
// 请求成功
if(isset($result['code']) && $result['code'] == 0)
{
if(empty($result['data']))
{
return DataReturn('无对应数据、请稍后再试!', -1);
}
return $result;
}
return DataReturn(empty($result['msg']) ? '异常错误失败、请稍后再试!' : $result['msg'], -1);
}
} }
?> ?>

View File

@ -1826,19 +1826,13 @@ class UserService
// 基础处理 // 基础处理
if(isset($user['id'])) if(isset($user['id']))
{ {
// token生成并存储缓存 // 非token数据库校验则重新生成token更新到数据库
if($user['is_mandatory_bind_mobile'] == 0 || ($user['is_mandatory_bind_mobile'] == 1 && !empty($user['mobile']))) if($where_field != 'token')
{ {
// token生成并存储缓存
$user['token'] = self::CreatedUserToken($user['id']); $user['token'] = self::CreatedUserToken($user['id']);
Db::name('User')->where(['id'=>$user['id']])->update(['token'=>$user['token'], 'upd_time'=>time()]);
cache(config('shopxo.cache_user_info').$user['token'], $user); cache(config('shopxo.cache_user_info').$user['token'], $user);
// 非token数据库校验则重新生成token更新到数据库
if($where_field != 'token')
{
Db::name('User')->where(['id'=>$user['id']])->update(['token'=>$user['token'], 'upd_time'=>time()]);
}
} else {
$user['token'] = '';
} }
// 用户登录纪录处理 // 用户登录纪录处理
@ -2033,73 +2027,110 @@ class UserService
return DataReturn('验证码错误', -11); return DataReturn('验证码错误', -11);
} }
// 用户信息 // 用户更新数据
$accounts_field = APPLICATION_CLIENT_TYPE.'_openid'; $data = [
if(empty($params[$accounts_field])) 'mobile' => $params['mobile'],
{ ];
return DataReturn('用户openid不能为空', -20);
}
// 用户数据 // 是否小程序请求
$data = array( $is_appmini = array_key_exists(APPLICATION_CLIENT_TYPE, lang('common_appmini_type'));
$accounts_field => $params[$accounts_field],
'mobile' => $params['mobile'],
);
// 获取用户信息 // 手机号码获取用户信息
$mobile_user = Db::name('User')->where([ $mobile_user = Db::name('User')->where([
['mobile', '=', $data['mobile']], ['mobile', '=', $data['mobile']],
['is_delete_time', '=', 0], ['is_delete_time', '=', 0],
])->find(); ])->find();
$open_user = Db::name('User')->where([
[$accounts_field, '=', $params[$accounts_field]],
['is_delete_time', '=', 0],
])->find();
// 如果手机号码存在并且openid也已存在则更新掉之前的openid
if(!empty($mobile_user))
{
if(!empty($open_user))
{
Db::name('User')->where(['id'=>$open_user['id']])->update([$accounts_field=>'', 'upd_time'=>time()]);
}
} else {
$mobile_user = $open_user;
}
// 如果用户不存在则新增用户状态字段
if(empty($mobile_user) && empty($open_user))
{
// 是否需要审核
$common_register_is_enable_audit = MyC('common_register_is_enable_audit', 0);
$data['status'] = ($common_register_is_enable_audit == 1) ? 3 : 0;
}
// 额外信息 // 额外信息
if(empty($mobile_user['nickname']) && !empty($params['nickname'])) if(empty($mobile_user))
{ {
$data['nickname'] = $params['nickname']; if(empty($mobile_user['nickname']) && !empty($params['nickname']))
{
$data['nickname'] = $params['nickname'];
}
if(empty($mobile_user['avatar']) && !empty($params['avatar']))
{
$data['avatar'] = $params['avatar'];
}
if(empty($mobile_user['province']) && !empty($params['province']))
{
$data['province'] = $params['province'];
}
if(empty($mobile_user['city']) && !empty($params['city']))
{
$data['city'] = $params['city'];
}
if(empty($mobile_user) && isset($params['gender']))
{
$data['gender'] = intval($params['gender']);
}
} }
if(empty($mobile_user['avatar']) && !empty($params['avatar']))
// 小程序请求处理
if($is_appmini)
{ {
$data['avatar'] = $params['avatar']; // openid必须存在
} $accounts_field = APPLICATION_CLIENT_TYPE.'_openid';
if(empty($mobile_user['province']) && !empty($params['province'])) if(empty($params[$accounts_field]))
{ {
$data['province'] = $params['province']; return DataReturn('用户openid不能为空', -20);
} }
if(empty($mobile_user['city']) && !empty($params['city']))
{ // openid数据
$data['city'] = $params['city']; $data[$accounts_field] = $params[$accounts_field];
}
if(empty($mobile_user) && isset($params['gender'])) // 小程序请求获取用户信息
{ $open_user = Db::name('User')->where([
$data['gender'] = intval($params['gender']); [$accounts_field, '=', $params[$accounts_field]],
['is_delete_time', '=', 0],
])->find();
// 如果手机号码存在并且openid也已存在则更新掉之前的openid
if(!empty($mobile_user))
{
if(!empty($open_user))
{
Db::name('User')->where(['id'=>$open_user['id']])->update([$accounts_field=>'', 'upd_time'=>time()]);
}
} else {
$mobile_user = $open_user;
}
} else {
// 获取当前登录用户
// 如果手机号码已经存在帐号、当前用户已登录
$user = self::LoginUserInfo();
if(!empty($user))
{
// 手机帐号信息是否存在
if(!empty($mobile_user))
{
// id不一致则提示错误
if($user['id'] != $mobile_user['id'])
{
return DataReturn('手机已绑定、请换手机号重试', -50);
}
// 是否与当前帐号的手机号码一致
if(!empty($user['mobile']) && $user['mobile'] == $mobile_user['mobile'])
{
return DataReturn('请使用新的手机号', -51);
}
}
// 当前用户赋值手机帐号信息
$mobile_user = $user;
}
} }
// 不存在添加/则更新 // 不存在添加/则更新
if(empty($mobile_user)) if(empty($mobile_user))
{ {
// 如果用户不存在则新增用户状态字段
// 是否需要审核
$common_register_is_enable_audit = MyC('common_register_is_enable_audit', 0);
$data['status'] = ($common_register_is_enable_audit == 1) ? 3 : 0;
// 新增用户
$user_ret = self::UserInsert($data, $params); $user_ret = self::UserInsert($data, $params);
if($user_ret['code'] == 0) if($user_ret['code'] == 0)
{ {
@ -2108,17 +2139,22 @@ class UserService
return $user_ret; return $user_ret;
} }
} else { } else {
// 用户unionid // 小程序请求处理
$unionid = self::UserUnionidHandle($params); if($is_appmini)
if(!empty($unionid['field']) && !empty($unionid['value']))
{ {
if(empty($mobile_user[$unionid['field']])) // 用户unionid
$unionid = self::UserUnionidHandle($params);
if(!empty($unionid['field']) && !empty($unionid['value']))
{ {
// unionid放入用户data中 if(empty($mobile_user[$unionid['field']]))
$data[$unionid['field']] = $unionid['value']; {
// unionid放入用户data中
$data[$unionid['field']] = $unionid['value'];
}
} }
} }
// 帐号信息更新
$data['upd_time'] = time(); $data['upd_time'] = time();
if(Db::name('User')->where(['id'=>$mobile_user['id']])->update($data)) if(Db::name('User')->where(['id'=>$mobile_user['id']])->update($data))
{ {

View File

@ -32,5 +32,228 @@ return array (
'log_write' => 'log_write' =>
array ( array (
), ),
'plugins_css' =>
array (
0 => 'app\\plugins\\points\\Hook',
1 => 'app\\plugins\\shop\\Hook',
2 => 'app\\plugins\\multilingual\\Hook',
3 => 'app\\plugins\\commonrightnavigation\\Hook',
4 => 'app\\plugins\\store\\Hook',
),
'plugins_js' =>
array (
0 => 'app\\plugins\\points\\Hook',
1 => 'app\\plugins\\shop\\Hook',
2 => 'app\\plugins\\multilingual\\Hook',
3 => 'app\\plugins\\commonrightnavigation\\Hook',
4 => 'app\\plugins\\store\\Hook',
),
'plugins_service_navigation_header_handle' =>
array (
0 => 'app\\plugins\\points\\Hook',
1 => 'app\\plugins\\shop\\Hook',
2 => 'app\\plugins\\store\\Hook',
),
'plugins_service_quick_navigation_pc' =>
array (
0 => 'app\\plugins\\points\\Hook',
1 => 'app\\plugins\\multilingual\\Hook',
),
'plugins_service_quick_navigation_h5' =>
array (
0 => 'app\\plugins\\points\\Hook',
1 => 'app\\plugins\\multilingual\\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_service_goods_handle_end' =>
array (
0 => 'app\\plugins\\points\\Hook',
1 => 'app\\plugins\\shop\\Hook',
),
'plugins_view_buy_form_inside' =>
array (
0 => 'app\\plugins\\points\\Hook',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_view_buy_base_confirm_top' =>
array (
0 => 'app\\plugins\\points\\Hook',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_service_buy_group_goods_handle' =>
array (
0 => 'app\\plugins\\points\\Hook',
1 => 'app\\plugins\\newuserreduction\\Hook',
),
'plugins_service_buy_order_insert_end' =>
array (
0 => 'app\\plugins\\points\\Hook',
1 => 'app\\plugins\\shop\\Hook',
2 => 'app\\plugins\\store\\Hook',
),
'plugins_service_order_status_change_history_success_handle' =>
array (
0 => 'app\\plugins\\points\\Hook',
1 => 'app\\plugins\\shop\\Hook',
2 => 'app\\plugins\\store\\Hook',
),
'plugins_service_base_data_return_api_buy_index' =>
array (
0 => 'app\\plugins\\points\\Hook',
),
'plugins_admin_css' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\orderpricerevision\\Hook',
2 => 'app\\plugins\\store\\Hook',
),
'plugins_service_users_center_left_menu_handle' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_service_header_navigation_top_right_handle' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\multilingual\\Hook',
2 => 'app\\plugins\\store\\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',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_view_goods_detail_right_content_bottom' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_view_goods_detail_base_bottom' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_view_goods_detail_base_buy_nav_min_inside_begin' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_service_warehouse_handle_end' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_service_buy_handle' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_service_buy_order_insert_begin' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_service_order_aftersale_audit_handle_end' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_view_admin_goods_save' =>
array (
0 => 'app\\plugins\\shop\\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',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_common_page_bottom' =>
array (
0 => 'app\\plugins\\multilingual\\Hook',
),
'plugins_view_common_top' =>
array (
0 => 'app\\plugins\\multilingual\\Hook',
),
'plugins_view_common_bottom' =>
array (
0 => 'app\\plugins\\multilingual\\Hook',
1 => 'app\\plugins\\commonrightnavigation\\Hook',
),
'plugins_service_search_goods_list_where' =>
array (
0 => 'app\\plugins\\multilingual\\Hook',
),
'plugins_admin_js' =>
array (
0 => 'app\\plugins\\orderpricerevision\\Hook',
),
'plugins_admin_view_common_bottom' =>
array (
0 => 'app\\plugins\\orderpricerevision\\Hook',
),
'plugins_view_admin_order_list_operate' =>
array (
0 => 'app\\plugins\\orderpricerevision\\Hook',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_service_warehouse_goods_inventory_deduct' =>
array (
0 => 'app\\plugins\\store\\Hook',
),
'plugins_service_warehouse_goods_inventory_rollback' =>
array (
0 => 'app\\plugins\\store\\Hook',
),
'plugins_service_warehouse_goods_inventory_sync' =>
array (
0 => 'app\\plugins\\store\\Hook',
),
'plugins_service_goods_field_status_update' =>
array (
0 => 'app\\plugins\\store\\Hook',
),
'plugins_service_goods_delete' =>
array (
0 => 'app\\plugins\\store\\Hook',
),
'plugins_service_goods_save_end' =>
array (
0 => 'app\\plugins\\store\\Hook',
),
'plugins_service_system_begin' =>
array (
0 => 'app\\plugins\\store\\Hook',
),
); );
?> ?>

View File

@ -5,7 +5,7 @@
html, body { html, body {
background: #f5f5f5; background: #f5f5f5;
} }
.echarts-container, .echarts-combination-container-2 li { .block-container, .block-combination-container-2 li {
width: 100%; width: 100%;
background: #fff !important; background: #fff !important;
padding: 10px; padding: 10px;
@ -13,17 +13,17 @@ html, body {
border-radius: 3px; border-radius: 3px;
overflow: hidden;; overflow: hidden;;
} }
.echarts-container, .echarts-combination-container-2 li { .block-container, .block-combination-container-2 li {
position: relative; position: relative;
} }
.echarts-container { .block-container {
margin-bottom: 20px; margin-bottom: 20px;
} }
.echarts-container .echarts-title, .echarts-combination-container-2 li .echarts-title { .block-container .echarts-title, .block-combination-container-2 li .echarts-title {
margin-left: 10px; margin-left: 10px;
} }
.echarts-container .echarts-title .icon, .echarts-combination-container-2 li .echarts-title .icon { .block-container .echarts-title .icon, .block-combination-container-2 li .echarts-title .icon {
background: #3f82fe; background: #3f82fe;
display: block; display: block;
width: 5px; width: 5px;
@ -32,31 +32,31 @@ html, body {
left: 10px; left: 10px;
top: 13px; top: 13px;
} }
.echarts-container .echarts-title .title, .echarts-combination-container-2 li .echarts-title .title { .block-container .echarts-title .title, .block-combination-container-2 li .echarts-title .title {
color: #666; color: #666;
font-size: 14px; font-size: 14px;
margin-left: 5px; margin-left: 5px;
} }
@media only screen and (min-width: 641px) { @media only screen and (min-width: 641px) {
.echarts-combination-container-2 { .block-combination-container-2 {
margin-bottom: 20px; margin-bottom: 20px;
} }
.echarts-combination-container-2 li { .block-combination-container-2 li {
width: calc(50% - 10px); width: calc(50% - 10px);
} }
.echarts-combination-container-2 li:nth-child(1) { .block-combination-container-2 li:nth-child(1) {
float: left; float: left;
top: 0; top: 0;
left: 0; left: 0;
} }
.echarts-combination-container-2 li:nth-child(2) { .block-combination-container-2 li:nth-child(2) {
float: right; float: right;
top: 0; top: 0;
right: 0; right: 0;
} }
} }
@media only screen and (max-width: 641px) { @media only screen and (max-width: 641px) {
.echarts-combination-container-2 li { .block-combination-container-2 li {
margin-bottom: 20px; margin-bottom: 20px;
} }
} }
@ -167,4 +167,103 @@ html, body {
} }
.dl-content dd:last-child { .dl-content dd:last-child {
border-bottom: 0; border-bottom: 0;
}
/**
* 顶部基础
*/
.base-content-top {
margin-bottom: 10px;
}
.base-content-top .vip {
border-radius: 2px;
padding: 0 6px;
background: #e1e1e1;
color: #666;
}
.base-content-top .vip-active {
background: #ffe500;
color: #c97e10;
}
.base-content-top .ad-content:hover {
color: #f44336;
}
.inspect-upgrade-submit i {
background: #f00;
display: inline-block;
padding: 3px;
vertical-align: super;
margin-left: 2px;
border-radius: 15px;
}
@media only screen and (max-width: 641px) {
.base-content-top .left-content,
.base-content-top .right-content {
width: 100%;
}
.base-content-top .right-content {
margin-top: 10px;
border-top: 1px dashed #eee;
padding-top: 10px;
}
.base-content-top .left-content .ad-content,
.base-content-top .right-content .right-base {
float: right;
}
}
/**
* 商店帐号信息
*/
#store-accounts-popup {
width: 360px;
height: 350px;
left: 50%;
top: 50%;
}
@media (min-width: 630px) {
#store-accounts-popup {
margin-left: -180px;
margin-top: -175px;
}
}
@media only screen and (max-width: 641px) {
#store-accounts-popup {
left: calc(50% - 180px);
top: calc(50% - 175px);
}
}
/**
* 更新信息展示
*/
#inspect-upgrade-popup .am-popup-bd {
padding-bottom: 50px;
overflow: auto;
}
#inspect-upgrade-popup .upgrade-title span {
font-weight: bold;
font-size: 16px;
line-height: 16px;
}
#inspect-upgrade-popup .upgrade-title * {
vertical-align: middle;
}
#inspect-upgrade-popup .upgrade-content-item ul li {
line-height: 26px;
min-height: 26px;
}
#inspect-upgrade-popup .upgrade-bottom {
position: fixed;
left: 0;
bottom: 0px;
width: 100%;
height: 70px;
padding: 0 25px;
}
#inspect-upgrade-popup .upgrade-bottom-content {
background: #fff;
padding: 10px 20px 0 0;
height: 50px;
border-top: 1px solid #ececec;
} }

View File

@ -178,4 +178,89 @@ $(function()
} }
}); });
// 检查更新
$('.inspect-upgrade-submit').on('click', function()
{
// 基础信息
var $inspect_upgrade_popup = $('#inspect-upgrade-popup');
AMUI.dialog.loading({title: '正在获取最新内容、请稍候...'});
// ajax请求
$.ajax({
url: $(this).data('url'),
type: 'POST',
dataType: 'json',
timeout: 30000,
data: {},
success: function(result)
{
AMUI.dialog.loading('close');
if(result.code == 0)
{
// html内容处理
// 基础信息
var html = '<p class="upgrade-title">';
html += '<i class="am-icon-info-circle am-icon-md am-text-warning"></i>';
html += '<span class="am-margin-left-xs">'+result.data.title+'</span>';
html += '</p>';
html += '<div class="am-alert upgrade-base">';
html += '<span class="upgrade-ver">更新版本:'+result.data.version_new+'</span>';
html += '<span class="upgrade-date am-margin-left-sm">更新日期:'+result.data.add_time+'</span>';
// 是否带指定链接和链接名称
if((result.data.go_title || null) != null && (result.data.go_url || null) != null)
{
html += '<a href="'+result.data.go_url+'" class="upgrade-go-detail am-margin-left-lg" target="_blank">'+result.data.go_title+'</a>';
}
html += '</div>';
// 提示信息
if((result.data.tips || null) != null)
{
html += '<div class="am-alert am-alert-danger">';
html += '<p class="am-text-danger">'+result.data.tips+'</p>';
html += '</div>';
}
// 更新内容介绍
if((result.data.content || null) != null && result.data.content.length > 0)
{
html += '<div class="am-alert am-alert-secondary upgrade-content-item">';
html += '<ul>';
for(var i in result.data.content)
{
html += '<li>'+result.data.content[i]+'</li>';
}
html += '</ul>';
html += '</div>';
}
$inspect_upgrade_popup.find('.upgrade-content').html(html);
// 是否支持在线自动更新
if((result.data.is_auto || 0) == 1)
{
$inspect_upgrade_popup.find('.inspect-upgrade-confirm').removeClass('am-hide');
} else {
$inspect_upgrade_popup.find('.inspect-upgrade-confirm').addClass('am-hide');
}
// 打开弹窗
$inspect_upgrade_popup.modal('open');
} else {
Prompt(result.msg);
}
},
error: function(xhr, type)
{
AMUI.dialog.loading('close');
Prompt(HtmlToString(xhr.responseText) || '异常错误', null, 30);
}
});
});
// 系统更新确认
$('.inspect-upgrade-confirm').on('click', function()
{
Prompt('开发中...');
});
}); });

View File

@ -145,6 +145,15 @@ form.am-form .am-form-group-refreshing, .plug-file-upload-view { border-bottom:
.am-modal-dialog .am-modal-bd { .am-modal-dialog .am-modal-bd {
background: #fff; background: #fff;
} }
.am-modal-dialog {
width: auto;
}
.am-modal-dialog .am-modal-bd {
padding: 10px 30px;
}
.am-modal-dialog .am-modal-bd span {
vertical-align: middle;
}
/** /**
* iframe * iframe