初始上传
This commit is contained in:
694
app/model/system/Addon.php
Executable file
694
app/model/system/Addon.php
Executable file
@@ -0,0 +1,694 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use app\model\diy\Template;
|
||||
use app\model\diy\Theme;
|
||||
use app\model\system\Config as ConfigModel;
|
||||
use app\model\web\DiyView as DiyViewModel;
|
||||
use app\model\web\DiyViewLink;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Db;
|
||||
|
||||
/**
|
||||
* 插件表
|
||||
*/
|
||||
class Addon extends BaseModel
|
||||
{
|
||||
public $cache_model = 'cache_model_addon';
|
||||
|
||||
/**
|
||||
* 获取单条插件信息
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
*/
|
||||
public function getAddonInfo($condition, $field = '*')
|
||||
{
|
||||
$addon_info = model('addon')->getInfo($condition, $field);
|
||||
return $this->success($addon_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件列表
|
||||
*
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
* @param string $order
|
||||
* @param string $limit
|
||||
*/
|
||||
public function getAddonList($condition = [], $field = '*', $order = '', $limit = null)
|
||||
{
|
||||
$addon_list = model('addon')->getList($condition, $field, $order, '', '', '', $limit);
|
||||
return $this->success($addon_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询插件key数组
|
||||
* @return array
|
||||
*/
|
||||
public function getAddonKeys()
|
||||
{
|
||||
$addon_data = $this->getAddonList([], 'name');
|
||||
$addons = array_column($addon_data[ 'data' ], 'name');
|
||||
return $addons;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件分页列表
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getAddonPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
|
||||
{
|
||||
$list = model('addon')->pageList($condition, $field, $order, $page, $page_size);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有插件
|
||||
* @return array
|
||||
*/
|
||||
public function getAddonAllList()
|
||||
{
|
||||
//获取官网记录的所有数据
|
||||
$upgrade_service = new Upgrade();
|
||||
$data = $upgrade_service->getAuthPlugin();
|
||||
if (isset($data[ 'code' ]) && $data[ 'code' ] >= 0) {
|
||||
$temp_auth_addon_list = $data[ 'data' ];
|
||||
} else {
|
||||
$temp_auth_addon_list = [];
|
||||
}
|
||||
|
||||
//以code为key组装正式数据
|
||||
$auth_addon_list = [];
|
||||
foreach ($temp_auth_addon_list as $key => $val) {
|
||||
$auth_addon_list[ $val[ 'code' ] ] = $val;
|
||||
}
|
||||
//存在的插件
|
||||
$existed_addons = array_map('basename', glob('addon/*', GLOB_ONLYDIR));
|
||||
//已安装的插件
|
||||
$installed_addon_array = model('addon')->getColumn([], 'name');
|
||||
//初始化数据
|
||||
$undownload_addons = [];
|
||||
$uninstall_addons = [];
|
||||
$install_addons = [];
|
||||
//获取未下载插件
|
||||
foreach ($auth_addon_list as $key => $val) {
|
||||
$index = in_array($val['code'], $existed_addons);
|
||||
if ($index === false) {
|
||||
$undownload_addons[] = [
|
||||
'name' => $val[ 'code' ],
|
||||
'title' => $val[ 'goods_name' ],
|
||||
'icon' => $val[ 'logo' ],
|
||||
'description' => $val[ 'introduction' ],
|
||||
'version' => $val[ 'last_online_version_name' ],
|
||||
'download' => 1,
|
||||
'auth' => true,
|
||||
'update' => false
|
||||
];
|
||||
}
|
||||
}
|
||||
//获取已下载插件 区分已安装和为安装 是否需要升级 是否已授权
|
||||
foreach ($existed_addons as $key => $val) {
|
||||
$info_file_path = 'addon/' . $val . '/config/info.php';
|
||||
if (file_exists($info_file_path)) {
|
||||
$info = include_once $info_file_path;
|
||||
$info[ 'icon' ] = 'addon/' . $val . '/icon.png';
|
||||
$info[ 'download' ] = 0;
|
||||
$info[ 'auth' ] = isset($auth_addon_list[ $val ]);
|
||||
$info[ 'update' ] = isset($auth_addon_list[ $val ]) && $auth_addon_list[ $val ][ 'last_online_version_no' ] > $info[ 'version_no' ];
|
||||
$info[ 'last_online_version_no' ] = isset($auth_addon_list[ $val ]) ? $auth_addon_list[ $val ][ 'last_online_version_no' ] : '';
|
||||
if (!in_array($val, $installed_addon_array)) {
|
||||
$uninstall_addons[] = $info;
|
||||
} else {
|
||||
$install_addons[] = $info;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->success([
|
||||
'uninstall' => array_merge($undownload_addons, $uninstall_addons),
|
||||
'install' => $install_addons,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取未安装的插件列表
|
||||
*/
|
||||
public function getUninstallAddonList()
|
||||
{
|
||||
|
||||
$dirs = array_map('basename', glob('addon/*', GLOB_ONLYDIR));
|
||||
$addon_names = model('addon')->getColumn([], 'name');
|
||||
$addons = [];
|
||||
foreach ($dirs as $key => $value) {
|
||||
if (!in_array($value, $addon_names)) {
|
||||
$info_name = 'addon/' . $value . '/config/info.php';
|
||||
if (file_exists($info_name)) {
|
||||
$info = include_once $info_name;
|
||||
$info[ 'icon' ] = 'addon/' . $value . '/icon.png';
|
||||
$addons[] = $info;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->success($addons);
|
||||
}
|
||||
|
||||
/*******************************************************************插件安装方法开始****************************************************/
|
||||
/**
|
||||
* 插件安装
|
||||
*
|
||||
* @param string $addon_name
|
||||
*/
|
||||
public function install($addon_name)
|
||||
{
|
||||
|
||||
Db::startTrans();
|
||||
try {
|
||||
// 插件预安装
|
||||
|
||||
$res2 = $this->preInstall($addon_name);
|
||||
if ($res2[ 'code' ] != 0) {
|
||||
Db::rollback();
|
||||
return $res2;
|
||||
}
|
||||
|
||||
// 安装菜单
|
||||
$res3 = $this->installMenu($addon_name);
|
||||
if ($res3[ 'code' ] != 0) {
|
||||
Db::rollback();
|
||||
return $res3;
|
||||
}
|
||||
|
||||
// 安装自定义模板
|
||||
$res4 = $this->refreshDiyView($addon_name);
|
||||
if ($res4[ 'code' ] != 0) {
|
||||
Db::rollback();
|
||||
return $res4;
|
||||
}
|
||||
|
||||
// 添加插件入表
|
||||
$addons_model = model('addon');
|
||||
$addon_info = require 'addon/' . $addon_name . '/config/info.php';
|
||||
$addon_info[ 'create_time' ] = time();
|
||||
$addon_info[ 'icon' ] = 'addon/' . $addon_name . '/icon.png';
|
||||
|
||||
$data = $addons_model->add($addon_info);
|
||||
|
||||
if (!$data) {
|
||||
Db::rollback();
|
||||
return $this->error($data, 'ADDON_ADD_FAIL');
|
||||
}
|
||||
// 清理缓存
|
||||
Cache::clear();
|
||||
|
||||
Db::commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
// 清理缓存
|
||||
Cache::clear();
|
||||
Db::rollback();
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件预安装
|
||||
*/
|
||||
private function preInstall($addon_name)
|
||||
{
|
||||
$class_name = "addon\\" . $addon_name . "\\event\\Install";
|
||||
$install = new $class_name;
|
||||
$res = $install->handle($addon_name);
|
||||
if ($res[ 'code' ] != 0) {
|
||||
return $res;
|
||||
}
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 安装插件菜单
|
||||
*/
|
||||
private function installMenu($addon)
|
||||
{
|
||||
$menu = new Menu();
|
||||
$menu->refreshMenu('shop', $addon);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 刷新插件自定义页面配置
|
||||
* @param $addon
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function refreshDiyView($addon)
|
||||
{
|
||||
try {
|
||||
if (empty($addon)) {
|
||||
$diy_view_file = 'config/diy_view.php';
|
||||
} else {
|
||||
$diy_view_file = 'addon/' . $addon . '/config/diy_view.php';
|
||||
}
|
||||
|
||||
if (!file_exists($diy_view_file)) {
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
$link_model = new DiyViewLink();
|
||||
$diy_view_model = new DiyViewModel();
|
||||
$diy_template_model = new Template();
|
||||
$diy_theme_model = new Theme();
|
||||
|
||||
// 查询原模板组列表,用于更新自定义页面的所属模板id
|
||||
$diy_template_goods_list_old = $diy_template_model->getTemplateGoodsList([ [ 'addon_name', '=', $addon ] ], 'goods_id,name')[ 'data' ];
|
||||
|
||||
// 清空数据
|
||||
$link_model->deleteLink([ [ 'addon_name', '=', $addon ] ]); // 链接
|
||||
$diy_view_model->deleteUtil([ [ 'addon_name', '=', $addon ] ]); // 组件
|
||||
$diy_template_model->deleteTemplate([ [ 'addon_name', '=', $addon ] ]); // 页面类型
|
||||
$diy_theme_model->deleteTheme([ [ 'addon_name', '=', $addon ] ]); // 主题风格
|
||||
$diy_template_model->deleteTemplateGoods([ [ 'addon_name', '=', $addon ] ]); // 模板组
|
||||
$diy_template_model->deleteTemplateGoodsItem([ [ 'addon_name', '=', $addon ] ]); // 模板页面
|
||||
|
||||
$diy_view = require $diy_view_file;
|
||||
|
||||
// 自定义链接
|
||||
if (isset($diy_view[ 'link' ])) {
|
||||
$diy_view_link_data = $link_model->getViewLinkList($diy_view[ 'link' ], $addon);
|
||||
if ($diy_view_link_data) {
|
||||
model('link')->addList($diy_view_link_data);
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义模板组件
|
||||
if (isset($diy_view[ 'util' ])) {
|
||||
$diy_view_util_data = [];
|
||||
foreach ($diy_view[ 'util' ] as $k => $v) {
|
||||
$util_item = [
|
||||
'name' => $v[ 'name' ], // 组件标识
|
||||
'title' => $v[ 'title' ], // 组件名称
|
||||
'type' => $v[ 'type' ], // 组件类型,SYSTEM:基础组件,PROMOTION:营销组件,EXTEND:扩展组件
|
||||
'value' => $v[ 'value' ], // 组件数据结构json格式
|
||||
'sort' => $v[ 'sort' ],
|
||||
'support_diy_view' => $v[ 'support_diy_view' ] ?? '', // 支持的自定义页面(为空表示公共组件都支持)
|
||||
'addon_name' => $addon,
|
||||
'max_count' => $v[ 'max_count' ] ?? 0, // 限制添加次数,0表示可以无限添加该组件
|
||||
'is_delete' => $v[ 'is_delete' ] ?? 0, // 组件是否可以删除,0 允许,1 禁用
|
||||
'icon' => $v[ 'icon' ] ?? '' // 组件字体图标
|
||||
];
|
||||
$diy_view_util_data[] = $util_item;
|
||||
}
|
||||
if ($diy_view_util_data) {
|
||||
$diy_view_model->addUtilList($diy_view_util_data);
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义模板页面类型
|
||||
if (isset($diy_view[ 'template' ]) && !empty($diy_view[ 'template' ])) {
|
||||
$template_data = [];
|
||||
foreach ($diy_view[ 'template' ] as $k => $v) {
|
||||
// 检测防重复
|
||||
$count = $diy_template_model->getTemplateCount([ [ 'name', '=', $v[ 'name' ] ] ])[ 'data' ];
|
||||
if ($count == 0) {
|
||||
$template_data[] = [
|
||||
'title' => $v[ 'title' ], // 模板名称
|
||||
'name' => $v[ 'name' ], // 模板标识
|
||||
'page' => $v[ 'path' ], // 页面路径
|
||||
'addon_name' => $addon,
|
||||
'value' => $v[ 'value' ] ?? '',
|
||||
'rule' => isset($v[ 'rule' ]) ? json_encode($v[ 'rule' ]) : '',
|
||||
'sort' => $v[ 'sort' ] ?? 0
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($template_data)) {
|
||||
$diy_template_model->addTemplateList($template_data);
|
||||
}
|
||||
}
|
||||
|
||||
// 主题风格配色
|
||||
if (isset($diy_view[ 'theme' ]) && !empty($diy_view[ 'theme' ])) {
|
||||
$theme_data = [];
|
||||
foreach ($diy_view[ 'theme' ] as $k => $v) {
|
||||
// 检测防重复
|
||||
$count = $diy_theme_model->getThemeCount([ [ 'name', '=', $v[ 'name' ] ] ])[ 'data' ];
|
||||
if ($count == 0) {
|
||||
$theme_value = $v;
|
||||
unset($theme_value[ 'title' ], $theme_value[ 'name' ], $theme_value[ 'main_color' ], $theme_value[ 'aux_color' ], $theme_value[ 'preview' ]);
|
||||
$theme_data[] = [
|
||||
'title' => $v[ 'title' ],
|
||||
'name' => $v[ 'name' ],
|
||||
'addon_name' => $addon,
|
||||
'main_color' => $v[ 'main_color' ],
|
||||
'aux_color' => $v[ 'aux_color' ],
|
||||
'preview' => implode(',', $v[ 'preview' ]),
|
||||
'color_img' => $v[ 'color_img' ],
|
||||
'value' => json_encode($theme_value),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
if (!empty($theme_data)) {
|
||||
$diy_theme_model->addThemeList($theme_data);
|
||||
}
|
||||
}
|
||||
|
||||
// 模板信息
|
||||
$diy_goods_id = 0;
|
||||
if (isset($diy_view[ 'info' ]) && !empty($diy_view[ 'info' ])) {
|
||||
$template_goods_data = [
|
||||
'title' => $diy_view[ 'info' ][ 'title' ], // 模板名称
|
||||
'name' => $diy_view[ 'info' ][ 'name' ], // 模板标识
|
||||
'addon_name' => $addon,
|
||||
'cover' => $diy_view[ 'info' ][ 'cover' ], // 模板封面图
|
||||
'preview' => $diy_view[ 'info' ][ 'preview' ], // 模板预览图
|
||||
'desc' => $diy_view[ 'info' ][ 'desc' ], // 模板描述
|
||||
];
|
||||
|
||||
// 检测防重复
|
||||
$count = $diy_template_model->getTemplateGoodsCount([ [ 'name', '=', $template_goods_data[ 'name' ] ] ])[ 'data' ];
|
||||
if ($count == 0) {
|
||||
$diy_goods_id = $diy_template_model->addTemplateGoods($template_goods_data)[ 'data' ];
|
||||
}
|
||||
|
||||
if (!empty($diy_template_goods_list_old)) {
|
||||
foreach ($diy_template_goods_list_old as $k => $v) {
|
||||
// 更新自定义页面的所属模板id
|
||||
// $diy_view_model->editSiteDiyView([
|
||||
// 'template_id' => $diy_goods_id,
|
||||
// ], [
|
||||
// [ 'name', 'like', '%DIY_VIEW_RANDOM_%' ],
|
||||
// [ 'template_id', '=', $v[ 'goods_id' ] ]
|
||||
// ]);
|
||||
|
||||
// 更新店铺关联模板关系id
|
||||
$diy_template_model->editSiteDiyTemplate([
|
||||
'template_goods_id' => $diy_goods_id,
|
||||
], [
|
||||
[ 'addon_name', '=', $addon ],
|
||||
[ 'name', '=', $v[ 'name' ] ],
|
||||
[ 'template_goods_id', '=', $v[ 'goods_id' ] ]
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
// 模板不存在,则清除店铺与模板之间的关系
|
||||
$diy_template_model->deleteSiteDiyTemplate([ [ 'addon_name', '=', $addon ] ]); // 模板页面关联关系
|
||||
}
|
||||
|
||||
// 自定义页面数据
|
||||
if (isset($diy_view[ 'data' ]) && !empty($diy_view[ 'data' ])) {
|
||||
$goods_item_id = 0;
|
||||
foreach ($diy_view[ 'data' ] as $k => $v) {
|
||||
$goods_item_data = [
|
||||
'goods_id' => $diy_goods_id, // 模板组id
|
||||
'title' => $v[ 'title' ], // 名称
|
||||
'addon_name' => $addon,
|
||||
'name' => $v[ 'name' ], // 所属页面(首页、分类,空为微页面)
|
||||
'value' => json_encode($v[ 'value' ]), // 模板数据
|
||||
'create_time' => time()
|
||||
];
|
||||
$item_id = $diy_template_model->addTemplateGoodsItem($goods_item_data)[ 'data' ];
|
||||
|
||||
// 默认装修第一个页面
|
||||
if ($k == 0) {
|
||||
$goods_item_id = $item_id;
|
||||
}
|
||||
}
|
||||
|
||||
$diy_template_model->editTemplateGoods([ 'goods_item_id' => $goods_item_id ], [ [ 'goods_id', '=', $diy_goods_id ] ]);
|
||||
|
||||
// 更新页面的所属模板id
|
||||
$diy_template_goods_item_list = $diy_template_model->getTemplateGoodsItemList([ [ 'addon_name', '=', $addon ] ], 'goods_id,goods_item_id,name')[ 'data' ];
|
||||
if (!empty($diy_template_goods_item_list)) {
|
||||
foreach ($diy_template_goods_item_list as $k => $v) {
|
||||
$diy_view_model->editSiteDiyView([
|
||||
'template_id' => $v[ 'goods_id' ],
|
||||
'template_item_id' => $v[ 'goods_item_id' ]
|
||||
], [
|
||||
[ 'name', '=', $v[ 'name' ] ],
|
||||
[ 'addon_name', '=', $addon ]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************插件安装结束*********************************************************/
|
||||
|
||||
/**************************************************************插件卸载开始*********************************************************/
|
||||
public function uninstall($addon_name)
|
||||
{
|
||||
Db::startTrans();
|
||||
try {
|
||||
$addon_info = model('addon')->getInfo([ [ 'name', '=', $addon_name ] ], '*');
|
||||
// 插件预卸载
|
||||
$res1 = $this->preUninstall($addon_name);
|
||||
if ($res1[ 'code' ] != 0) {
|
||||
Db::rollback();
|
||||
return $res1;
|
||||
}
|
||||
// 卸载菜单
|
||||
$res2 = $this->uninstallMenu($addon_name);
|
||||
if ($res2[ 'code' ] != 0) {
|
||||
Db::rollback();
|
||||
return $res2;
|
||||
}
|
||||
$res3 = $this->uninstallDiyView($addon_name);
|
||||
if ($res3[ 'code' ] != 0) {
|
||||
Db::rollback();
|
||||
return $res3;
|
||||
}
|
||||
$delete_res = model('addon')->delete([
|
||||
[ 'name', '=', $addon_name ]
|
||||
]);
|
||||
if ($delete_res === false) {
|
||||
Db::rollback();
|
||||
return $this->error();
|
||||
}
|
||||
//清理缓存
|
||||
Cache::clear();
|
||||
Db::commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
//清理缓存
|
||||
Cache::clear();
|
||||
Db::rollback();
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件预卸载
|
||||
*/
|
||||
private function preUninstall($addon_name)
|
||||
{
|
||||
$class_name = "addon\\" . $addon_name . "\\event\\UnInstall";
|
||||
$install = new $class_name;
|
||||
$res = $install->handle($addon_name);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 卸载插件菜单
|
||||
*/
|
||||
private function uninstallMenu($addon_name)
|
||||
{
|
||||
$res = model('menu')->delete([
|
||||
[ 'addon', '=', $addon_name ]
|
||||
]);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 卸载自定义数据(清除:自定义链接、组件、主题风格、模板页面类型、模板组、模板组页面、店铺拥有的模板组、店铺自定义模板)
|
||||
* @param $addon_name
|
||||
* @return array
|
||||
*/
|
||||
private function uninstallDiyView($addon_name)
|
||||
{
|
||||
model('link')->delete([ [ 'addon_name', '=', $addon_name ] ]); // 自定义链接
|
||||
model('diy_view_util')->delete([ [ 'addon_name', '=', $addon_name ] ]); // 自定义组件
|
||||
model('diy_theme')->delete([ [ 'addon_name', '=', $addon_name ] ]); // 主题风格
|
||||
model('diy_template')->delete([ [ 'addon_name', '=', $addon_name ] ]); // 模板页面类型
|
||||
model('diy_template_goods')->delete([ [ 'addon_name', '=', $addon_name ] ]); // 模板组
|
||||
model('diy_template_goods_item')->delete([ [ 'addon_name', '=', $addon_name ] ]); // 模板组页面
|
||||
model('site_diy_template')->delete([ [ 'addon_name', '=', $addon_name ] ]); // 店铺拥有的模板组
|
||||
// model('site_diy_view')->delete([ [ 'addon_name', '=', $addon_name ] ]); // 店铺自定义模板
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/***************************************************************插件卸载结束********************************************************/
|
||||
|
||||
/************************************************************* 安装全部插件 start *************************************************************/
|
||||
|
||||
/**
|
||||
* 安装全部插件
|
||||
*/
|
||||
public function installAllAddon()
|
||||
{
|
||||
$addon_list_result = $this->getUninstallAddonList();
|
||||
$addon_list = $addon_list_result['data'];
|
||||
foreach ($addon_list as $k => $v) {
|
||||
$item_result = $this->install($v['name']);
|
||||
if ($item_result['code'] < 0)
|
||||
return $item_result;
|
||||
}
|
||||
return $this->success();
|
||||
}
|
||||
/************************************************************* 安装全部插件 end *************************************************************/
|
||||
|
||||
/**
|
||||
* 刷新应用插件
|
||||
* @return array
|
||||
*/
|
||||
public function cacheAddon()
|
||||
{
|
||||
//刷新插件信息
|
||||
$addon_list = model('addon')->getList();
|
||||
try {
|
||||
foreach ($addon_list as $k => $v) {
|
||||
$data = require 'addon/' . $v[ 'name' ] . '/config/info.php';
|
||||
if (empty($data)) {
|
||||
$data = [];
|
||||
}
|
||||
$data[ 'create_time' ] = time();
|
||||
$data[ 'icon' ] = 'addon/' . $v[ 'name' ] . '/icon.png';
|
||||
model('addon')->update($data, [ 'name' => $v[ 'name' ] ]);
|
||||
}
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新所有插件菜单
|
||||
* @return array
|
||||
*/
|
||||
public function cacheAddonMenu()
|
||||
{
|
||||
$addon_list = model('addon')->getList([], 'name');
|
||||
$menu_model = new Menu();
|
||||
foreach ($addon_list as $k => $v) {
|
||||
$addon_menu_res = $menu_model->refreshMenu('shop', $v[ 'name' ]);
|
||||
// 刷新收银端权限
|
||||
$menu_model->refreshCashierAuth($v[ 'name' ]);
|
||||
}
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件快捷菜单配置
|
||||
* @param $site_id
|
||||
* @param string $app_module
|
||||
* @return array
|
||||
*/
|
||||
public function getAddonQuickMenuConfig($site_id, $app_module = 'shop')
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$res = $config->getConfig([ [ 'site_id', '=', $site_id ], [ 'app_module', '=', $app_module ], [ 'config_key', '=', 'COMMON_ADDON' ] ]);
|
||||
if (!empty($res[ 'data' ][ 'value' ])) {
|
||||
if (!empty($res[ 'data' ][ 'value' ][ 'promotion' ])) {
|
||||
$res[ 'data' ][ 'value' ][ 'promotion' ] = explode(',', $res[ 'data' ][ 'value' ][ 'promotion' ]);
|
||||
foreach ($res[ 'data' ][ 'value' ][ 'promotion' ] as $k => $v) {
|
||||
if (empty($v)) {
|
||||
unset($res[ 'data' ][ 'value' ][ 'promotion' ][ $k ]);
|
||||
} elseif (!empty($v) && addon_is_exit($v) == 0) {
|
||||
unset($res[ 'data' ][ 'value' ][ 'promotion' ][ $k ]);
|
||||
}
|
||||
}
|
||||
$res[ 'data' ][ 'value' ][ 'promotion' ] = array_values($res[ 'data' ][ 'value' ][ 'promotion' ]);
|
||||
} else {
|
||||
$res[ 'data' ][ 'value' ][ 'promotion' ] = [];
|
||||
}
|
||||
|
||||
if (!empty($res[ 'data' ][ 'value' ][ 'tool' ])) {
|
||||
$res[ 'data' ][ 'value' ][ 'tool' ] = explode(',', $res[ 'data' ][ 'value' ][ 'tool' ]);
|
||||
foreach ($res[ 'data' ][ 'value' ][ 'tool' ] as $k => $v) {
|
||||
if (empty($v)) {
|
||||
unset($res[ 'data' ][ 'value' ][ 'tool' ][ $k ]);
|
||||
} elseif (!empty($v) && addon_is_exit($v) == 0) {
|
||||
unset($res[ 'data' ][ 'value' ][ 'tool' ][ $k ]);
|
||||
}
|
||||
}
|
||||
$res[ 'data' ][ 'value' ][ 'tool' ] = array_values($res[ 'data' ][ 'value' ][ 'tool' ]);
|
||||
} else {
|
||||
$res[ 'data' ][ 'value' ][ 'tool' ] = [];
|
||||
}
|
||||
|
||||
} else {
|
||||
$res[ 'data' ][ 'value' ] = [
|
||||
'promotion' => [],
|
||||
'tool' => []
|
||||
];
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置插件快捷菜单配置
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function setAddonQuickMenuConfig($data)
|
||||
{
|
||||
$condition = [
|
||||
[ 'site_id', '=', $data[ 'site_id' ] ],
|
||||
[ 'app_module', '=', $data[ 'app_module' ] ],
|
||||
[ 'config_key', '=', 'COMMON_ADDON' ]
|
||||
];
|
||||
|
||||
$config = new ConfigModel();
|
||||
$value = $config->getConfig($condition)[ 'data' ][ 'value' ];
|
||||
$addon_array = empty($value) ? [] : explode(',', $value[ $data[ 'type' ] ] ?? '');
|
||||
|
||||
if (in_array($data[ 'addon' ], $addon_array)) {
|
||||
$addon_array = array_diff($addon_array, [ $data[ 'addon' ] ]);
|
||||
} else {
|
||||
array_push($addon_array, $data[ 'addon' ]);
|
||||
}
|
||||
$value[ $data[ 'type' ] ] = implode(',', $addon_array);
|
||||
return $config->setConfig($value, '常用功能设置', 1, $condition);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件是否存在
|
||||
* @return array
|
||||
*/
|
||||
public function addonIsExist()
|
||||
{
|
||||
$existed_addons = array_map('basename', glob('addon/*', GLOB_ONLYDIR));
|
||||
$installed_addons = model('addon')->getColumn([], 'name');
|
||||
|
||||
$res = [];
|
||||
foreach($existed_addons as $addon){
|
||||
$res[$addon] = in_array($addon, $installed_addons) ? 1 : 0;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
157
app/model/system/AddonQuick.php
Executable file
157
app/model/system/AddonQuick.php
Executable file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use app\model\system\Upgrade as UpgradeModel;
|
||||
|
||||
|
||||
class AddonQuick extends BaseModel
|
||||
{
|
||||
|
||||
/**
|
||||
* 添加快捷方式
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function addAddonQuickMode($data)
|
||||
{
|
||||
//判断是否已存在该插件
|
||||
$addon_count = model('addon_quick')->getCount([ [ 'name', '=', $data[ 'name' ] ] ]);
|
||||
if ($addon_count > 0) {
|
||||
return $this->error('', '该插件已添加快捷方式,请不要重复添加');
|
||||
}
|
||||
|
||||
$data[ 'create_time' ] = time();
|
||||
$res = model('addon_quick')->add($data);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除快捷方式
|
||||
* @param array $condition
|
||||
* @return array
|
||||
*/
|
||||
public function deleteAddonQuickMode($condition = [])
|
||||
{
|
||||
$res = model('addon_quick')->delete($condition);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取快捷方式信息
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getAddonQuickModeInfo($condition = [], $field = '*')
|
||||
{
|
||||
$info = model('addon_quick')->getInfo($condition, $field);
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取快捷方式类表
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getAddonQuickModeList($condition = [], $order = '', $field = '*')
|
||||
{
|
||||
$list = model('addon_quick')->getList($condition, $field, $order);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断快捷方式插件是否已安装
|
||||
* @param $uninstall
|
||||
* @param $install
|
||||
* @return array
|
||||
*/
|
||||
public function isInstallAddonQuick($uninstall, $install)
|
||||
{
|
||||
//未安装的插件
|
||||
$uninstall_name_arr = array_column($uninstall, 'name');
|
||||
//已安装的插件
|
||||
$install_name_arr = array_column($install, 'name');
|
||||
//获取快捷方式插件
|
||||
$addon_quick_list = $this->getAddonQuickModeList([], '', '*');
|
||||
|
||||
if (empty($addon_quick_list[ 'data' ])) {
|
||||
return [
|
||||
'uninstall' => $uninstall,
|
||||
'install' => $install
|
||||
];
|
||||
} else {
|
||||
|
||||
foreach ($addon_quick_list[ 'data' ] as $k => $v) {
|
||||
|
||||
//判断是否在已安装的插件中
|
||||
if (!in_array($v[ 'name' ], $install_name_arr)) {
|
||||
//判断是否在未安装的插件中
|
||||
if (empty($uninstall_name_arr) || !in_array($v[ 'name' ], $uninstall_name_arr)) {
|
||||
$v[ 'is_quick' ] = 1;
|
||||
$v[ 'download' ] = 1;
|
||||
$uninstall[] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'uninstall' => $uninstall,
|
||||
'install' => $install
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据插件类型获取官网插件
|
||||
* @param $addon_list
|
||||
* @param $type
|
||||
* @return array
|
||||
*/
|
||||
public function getAddonQuickByAddonType($addon_list, $type)
|
||||
{
|
||||
//获取官网所有插件
|
||||
$upgrade_model = new UpgradeModel();
|
||||
$website_addon_list = $upgrade_model->getPluginGoodsList();
|
||||
|
||||
$arr = [];
|
||||
if (empty($website_addon_list)) {
|
||||
return $arr;
|
||||
} else {
|
||||
|
||||
$addon_name_arr = array_column($addon_list, 'name');
|
||||
foreach ($website_addon_list as $k => $v) {
|
||||
|
||||
if ($v[ 'type_mark' ] == $type) {
|
||||
|
||||
if (empty($addon_list)) {
|
||||
$arr[] = $v;
|
||||
} else {
|
||||
//判断是否在插件中
|
||||
if (!in_array($v[ 'addon_goods_key' ], $addon_name_arr)) {
|
||||
$arr[] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
}
|
||||
}
|
||||
426
app/model/system/Address.php
Executable file
426
app/model/system/Address.php
Executable file
@@ -0,0 +1,426 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use extend\api\HttpClient;
|
||||
use think\facade\Cache;
|
||||
use app\model\BaseModel;
|
||||
use think\facade\Db;
|
||||
use think\helper\Str;
|
||||
|
||||
/**
|
||||
* 地区表
|
||||
*/
|
||||
class Address extends BaseModel
|
||||
{
|
||||
/**
|
||||
* 获取地区列表
|
||||
* @param unknown $condition
|
||||
* @param string $field
|
||||
* @param string $order
|
||||
* @param string $limit
|
||||
* @return multitype:string mixed
|
||||
*/
|
||||
public function getAreaList($condition = [], $field = '*', $order = '', $limit = null)
|
||||
{
|
||||
$area_list = model('area')->getList($condition, $field, $order, $limit);
|
||||
return $this->success($area_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地区详情
|
||||
*/
|
||||
public function getAreaInfo($circle)
|
||||
{
|
||||
$info = model('area')->getInfo([['id', '=', $circle]]);
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地区数量
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function getAreaCount($condition)
|
||||
{
|
||||
$count = model('area')->getCount($condition);
|
||||
return $this->success($count);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取省市子项
|
||||
*/
|
||||
public function getAreas($circle = 0)
|
||||
{
|
||||
$list = model('area')->getList([['pid', '=', $circle]]);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取整理后的地址
|
||||
*/
|
||||
public function getAddressTree($level = 4)
|
||||
{
|
||||
$condition = [['level', '<=', $level]];
|
||||
$json_condition = json_encode($condition);
|
||||
$cache = Cache::get('area_getAddressTree' . $json_condition);
|
||||
if (!empty($cache)) {
|
||||
return $this->success($cache);
|
||||
}
|
||||
$area_list = $this->getAreaList($condition, 'id, pid, name, level', 'id asc')['data'];
|
||||
//组装数据
|
||||
$refer_list = [];
|
||||
foreach ($area_list as $key => $val) {
|
||||
$refer_list[$val['level']][$val['pid']]['child_list'][$val['id']] = $area_list[$key];
|
||||
if (isset($refer_list[$val['level']][$val['pid']]['child_num'])) {
|
||||
$refer_list[$val['level']][$val['pid']]['child_num'] += 1;
|
||||
} else {
|
||||
$refer_list[$val['level']][$val['pid']]['child_num'] = 1;
|
||||
}
|
||||
}
|
||||
Cache::tag('area')->set('area_getAddressTree' . $json_condition, $refer_list);
|
||||
return $this->success($refer_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地址树结构
|
||||
* @param $level
|
||||
* @return array
|
||||
*/
|
||||
public function getAddressTreeList($level)
|
||||
{
|
||||
$condition = [['level', '<=', $level]];
|
||||
$json_condition = json_encode($condition);
|
||||
$cache = Cache::get('area_getAddressTreeList' . $json_condition);
|
||||
if (!empty($cache)) {
|
||||
return $this->success($cache);
|
||||
}
|
||||
$area_list = $this->getAreaList($condition, 'id, pid, name', 'id asc')['data'];
|
||||
$tree = $this->toTree($area_list);
|
||||
Cache::tag('area')->set('area_getAddressTreeList' . $json_condition, $tree);
|
||||
return $this->success($tree);
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表转树结构
|
||||
* @param $array
|
||||
* @param int $pid
|
||||
* @return array
|
||||
*/
|
||||
public function toTree($array, $pid = 0)
|
||||
{
|
||||
$tree = array();
|
||||
foreach ($array as $key => $value) {
|
||||
if ($value['pid'] == $pid) {
|
||||
$value['children'] = $this->toTree($array, $value['id']);
|
||||
$tree[] = $value;
|
||||
}
|
||||
}
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地址
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
* @return multitype:number unknown
|
||||
*/
|
||||
public function getAreasInfo(array $condition, string $field = '*')
|
||||
{
|
||||
$info = model('area')->getInfo($condition, $field);
|
||||
if ($info) return $this->success($info);
|
||||
return $this->error();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过地址查询
|
||||
*/
|
||||
public function getAddressByLatlng($post_data)
|
||||
{
|
||||
$qq_map = new \app\model\map\QqMap();
|
||||
$res = $qq_map->locationToDetail([
|
||||
'location' => $post_data['latlng'],
|
||||
]);
|
||||
if ($res['status'] == 0) {
|
||||
$return_array = $res['result']['address_component'] ?? [];
|
||||
$return_data = array(
|
||||
'province' => $return_array['province'] ?? '',
|
||||
'city' => $return_array['city'] ?? '',
|
||||
'district' => $return_array['district'] ?? '',
|
||||
'address' => $return_array['street'] ?? '',
|
||||
'full_address' => $res['result']['address'] ?? '',
|
||||
'town_info' => $res['result']['address_reference']['town'] ?? null,
|
||||
);
|
||||
return $this->success($return_data);
|
||||
} else {
|
||||
return $this->error([], $res['message']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过地址查询
|
||||
*/
|
||||
public function getAddressByName($address)
|
||||
{
|
||||
$qq_map = new \app\model\map\QqMap();
|
||||
$res = $qq_map->addressToDetail([
|
||||
'address' => $address,
|
||||
]);
|
||||
if ($res['status'] == 0) {
|
||||
$return_array = $res['result']['location'] ?? [];
|
||||
$return_data = array(
|
||||
'longitude' => $return_array['lng'] ?? '',
|
||||
'latitude' => $return_array['lat'] ?? '',
|
||||
);
|
||||
return $this->success($return_data);
|
||||
} else {
|
||||
return $this->error([], $res['message']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑地区
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function saveArea($data)
|
||||
{
|
||||
$count = model('area')->getCount([['id', '=', $data['id']]]);
|
||||
if ($count) {
|
||||
$res = model('area')->update($data, [['id', '=', $data['id']]]);
|
||||
} else {
|
||||
$res = model('area')->add($data);
|
||||
}
|
||||
if ($res) {
|
||||
Cache::clear('area');
|
||||
return $this->success($res);
|
||||
}
|
||||
return $this->error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除地区
|
||||
* @param $id
|
||||
* @param $level
|
||||
* @return array
|
||||
*/
|
||||
public function deleteArae($id, $level)
|
||||
{
|
||||
switch ((int)$level) {
|
||||
case 1:
|
||||
$child = model('area')->getColumn([['pid', '=', $id]], 'id');
|
||||
if (empty($child)) {
|
||||
$condition = [['id', '=', $id], ['level', '=', $level]];
|
||||
} else {
|
||||
$child = implode(',', $child);
|
||||
$condition = [['', 'exp', Db::raw("(id = $id AND level = $level) OR (id in ($child) AND level = 2) OR (pid in ($child) AND level = 3)")]];
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
$condition = [['', 'exp', Db::raw("(id = $id AND level = 2) OR (pid = $id AND level = 3)")]];
|
||||
break;
|
||||
case 3:
|
||||
$condition = [['id', '=', $id], ['level', '=', $level]];
|
||||
break;
|
||||
}
|
||||
$res = model('area')->delete($condition);
|
||||
if ($res) {
|
||||
Cache::clear('area');
|
||||
return $this->success($res);
|
||||
}
|
||||
return $this->error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析地址字符串,匹配系统地址库
|
||||
* @param $address
|
||||
* @return array
|
||||
*/
|
||||
public function analysesAddress($address): array
|
||||
{
|
||||
$res = $this->analysesAddressByTaobao($address); //匹配淘宝,京东地址
|
||||
if($res['code'] == 0){
|
||||
$address = $res['data']['address'];
|
||||
}else{
|
||||
$address = $this->addressReplace($address); //去除特定字符
|
||||
$pdd_res = $this->analysesAddressByPdd($address); //匹配拼多多地址
|
||||
$res['data'] = array_merge($pdd_res['data'],$res['data']);
|
||||
if($pdd_res['code'] == 0){
|
||||
$address = $res['data']['address'];
|
||||
}else{
|
||||
$other_res = $this->analysesAddressByThird($address); //无固定格式
|
||||
$res['data'] = array_merge($other_res['data'],$res['data']);
|
||||
if ($other_res['code'] == 0){
|
||||
$address = $res['data']['address'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$mobile = $res['data']['mobile'] ?? '';
|
||||
$name = $res['data']['name'] ?? '';
|
||||
$detail = $res['data']['detail'] ?? '';
|
||||
|
||||
$qq_map = new \app\model\map\QqMap();
|
||||
|
||||
if(!empty($address)){
|
||||
$res = $qq_map->addressToDetail([
|
||||
'address' => $address.$detail,
|
||||
]);
|
||||
|
||||
if ($res['status'] == 0) {
|
||||
$lng = $res['result']['location']['lng'] ?? '';
|
||||
$lat = $res['result']['location']['lat'] ?? '';
|
||||
$return_array = $res['result']['address_components'] ?? [];
|
||||
$province = $return_array['province'] ?? '';
|
||||
$city = $return_array['city'] ?? '';
|
||||
$district = $return_array['district'] ?? '';
|
||||
if (empty($mobile) && empty($name) && empty($province)) {
|
||||
return $this->error([], '解析有误,请检查格式是否正确');
|
||||
}
|
||||
$province_id = model('area')->getValue([['name', 'like', "%" . $province . '%'], ['level', '=', 1]], 'id');
|
||||
if (!empty($province_id) && !empty($city)) {
|
||||
$city_id = model('area')->getValue([['name', 'like', "%" . $city . '%'], ['pid', '=', $province_id], ['level', '=', 2]], 'id');
|
||||
}
|
||||
if (!empty($city_id) && !empty($district)) {
|
||||
$district_id = model('area')->getValue([['name', 'like', "%" . $district . '%'], ['pid', '=', $city_id], ['level', '=', 3]], 'id');
|
||||
}
|
||||
|
||||
if(empty($detail)){
|
||||
$province_temp = str_replace('省','',$province);
|
||||
$city_temp = str_replace('市','',$city);
|
||||
$district_temp = str_replace('区','',$district);
|
||||
$address = $this->removePrefix($address, $province);
|
||||
$address = $this->removePrefix($address, $province_temp);
|
||||
$detail =str_replace([$province, $city,$district], ['','',''], $address);
|
||||
$detail =str_replace([$province_temp, $city_temp,$district_temp], ['','',''], $detail);
|
||||
}
|
||||
}else{
|
||||
if (empty($mobile) && empty($name) ) {
|
||||
return $this->error([], '解析有误,请检查格式是否正确');
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if (empty($mobile) && empty($name) ) {
|
||||
return $this->error([], '解析有误,请检查格式是否正确');
|
||||
}
|
||||
}
|
||||
return $this->success([
|
||||
'name'=>$name,
|
||||
'mobile'=>$mobile,
|
||||
'province_id' => $province_id ?? '',
|
||||
'city_id' => $city_id ?? '',
|
||||
'district_id' => $district_id ?? '',
|
||||
'province_name' => $province ?? '',
|
||||
'city_name' => $city ?? '',
|
||||
'district_name' => $district ?? '',
|
||||
'detail' => $detail,
|
||||
'lng' => $lng ?? '',
|
||||
'lat' => $lat ?? '',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function analysesAddressByTaobao($address_str)
|
||||
{
|
||||
$pattern = [
|
||||
'name' => '/ ^\s*(?:收件人|收货人|姓名)\s*[::]\s*(?<name>.*)\s*/ux',
|
||||
'mobile' => '/ ^\s*手机(?:号码|号)\s*[::]\s* (?<phone>1[3-9]\d{9})\s* /ux',
|
||||
'address' => '/ ^\s*所在地区\s*[::]\s* (?<region>.*)\s* /ux',
|
||||
'detail' => '/ ^\s*详细地址\s*[::]\s* (?<detail>.*)\s* /ux',
|
||||
];
|
||||
|
||||
$address_str_split = preg_split('/\r\n?|\n/', $address_str);
|
||||
$res = [];
|
||||
foreach($address_str_split as $val){
|
||||
if(preg_match($pattern['name'], $val, $matches)){
|
||||
$res['name'] = $matches['name'];
|
||||
}elseif(preg_match($pattern['mobile'], $val, $matches)){
|
||||
$res['mobile'] = $matches['phone'];
|
||||
}elseif(preg_match($pattern['address'], $val, $matches)){
|
||||
$res['address'] = $matches['region'];
|
||||
}elseif(preg_match($pattern['detail'], $val, $matches)){
|
||||
$res['detail'] = $matches['detail'];
|
||||
}
|
||||
}
|
||||
|
||||
if(count($res) < 4){
|
||||
return $this->error($res);
|
||||
}
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
public function analysesAddressByPdd($address_str)
|
||||
{
|
||||
$address_str = preg_replace('/\s+/ux', ' ', $address_str);
|
||||
$address_arr = explode(" ", $address_str);
|
||||
|
||||
if(count($address_arr) < 3){
|
||||
return $this->error([]);
|
||||
}
|
||||
$patterns = [
|
||||
'address' => '/(?<region>.*?(?:省|自治区|直辖市|市).*?(?:市|自治州|地区).*?(?:区|县|旗|市))/u',
|
||||
'mobile' => '/(?<mobile>1[2-9]\d{9})/', // 11位手机号
|
||||
'name' => '/^(?<name>[^\d\s]+)|[^\d\s]+$/u', // 姓名(不含数字和空格)
|
||||
];
|
||||
$result = [];
|
||||
// 分别匹配各个部分
|
||||
foreach ($patterns as $key => $pattern) {
|
||||
foreach ($address_arr as $key1=> $str){
|
||||
if (preg_match($pattern, $str, $matches)) {
|
||||
if($key == 'address' && isset($address_arr[$key1+1])){
|
||||
//如果地址中有详细地址,则保存到detail中
|
||||
$result['detail'] = $address_arr[$key1+1];
|
||||
unset($address_arr[$key1+1]);
|
||||
}
|
||||
unset($address_arr[$key1]);
|
||||
$result[$key] = trim($str);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(isset($result['detail']) && empty($address_arr)){
|
||||
return $this->success($result);
|
||||
}
|
||||
return $this->error($result);
|
||||
}
|
||||
|
||||
|
||||
public function analysesAddressByThird($address_str){
|
||||
$patterns = [
|
||||
'/ ^\s*手机(?:号码|号)\s*[::]\s* (?<phone>1[3-9]\d{9})\s* /ux',
|
||||
// 规则1:姓名 + 电话 + 地址
|
||||
'/^(?<name>[\u4e00-\u9fa5·]+)\s+(?<mobile>\d{11}|0\d{2,3}-?\d{7,9})\s+(?<address>.+)$/u',
|
||||
// 规则2:地址 + 姓名 + 电话
|
||||
'/^(?<address>.+省?.+区)\s+(?<name>[\u4e00-\u9fa5·]+)\s+(?<mobile>\d{11})$/u',
|
||||
'/^(?<name>[^\d]+)(?<mobile>1[3-9]\d{9})(?<address>[^\n]*)(?<detail>.*)$/u',
|
||||
];
|
||||
foreach ($patterns as $pattern) {
|
||||
if (preg_match($pattern, $address_str, $matches)) {
|
||||
$res = [
|
||||
'name' => $matches['name'] ?? '',
|
||||
'mobile' => $matches['mobile'] ?? '',
|
||||
'address' => $matches['address'] ?? '',
|
||||
];
|
||||
return $this->success($res);
|
||||
}
|
||||
}
|
||||
return $this->error([]);
|
||||
}
|
||||
|
||||
public function removePrefix($str, $delimiter = "_") {
|
||||
$pos = strpos($str, $delimiter);
|
||||
return ($pos !== false) ? substr($str, $pos + strlen($delimiter)) : $str;
|
||||
}
|
||||
|
||||
public function addressReplace($address){
|
||||
return str_replace(['所在地区','详细地址',':'],['','',''],trim($address,' '));
|
||||
}
|
||||
}
|
||||
53
app/model/system/Api.php
Executable file
53
app/model/system/Api.php
Executable file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use app\model\system\Config as ConfigModel;
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 接口api配置
|
||||
*/
|
||||
class Api extends BaseModel
|
||||
{
|
||||
|
||||
/***************************************************************接口api 开始********************************************************/
|
||||
/**
|
||||
* 获取api配置
|
||||
* @param int $site_id
|
||||
* @param string $app_module
|
||||
* @return array
|
||||
*/
|
||||
public function getApiConfig($site_id = 1, $app_module = 'shop')
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$res = $config->getConfig([ [ 'site_id', '=', $site_id ], [ 'app_module', '=', $app_module ], [ 'config_key', '=', 'API_CONFIG' ] ]);
|
||||
$res[ 'data' ][ 'value' ][ 'long_time' ] = $res[ 'data' ][ 'value' ][ 'long_time' ] ?? 48;
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置api配置
|
||||
* @param $data
|
||||
* @param $is_use
|
||||
* @param int $site_id
|
||||
* @param string $app_module
|
||||
* @return array
|
||||
*/
|
||||
public function setApiConfig($data, $is_use, $site_id = 1, $app_module = 'shop')
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$res = $config->setConfig($data, 'api配置', $is_use, [ [ 'site_id', '=', $site_id ], [ 'app_module', '=', $app_module ], [ 'config_key', '=', 'API_CONFIG' ] ]);
|
||||
return $res;
|
||||
}
|
||||
/***************************************************************接口api 结束********************************************************/
|
||||
|
||||
}
|
||||
154
app/model/system/Config.php
Executable file
154
app/model/system/Config.php
Executable file
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use think\facade\Cache;
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 系统配置类
|
||||
*/
|
||||
class Config extends BaseModel
|
||||
{
|
||||
|
||||
/**
|
||||
* 配置系统配置项
|
||||
* @param array $value
|
||||
* @param string $config_desc
|
||||
* @param int $is_use
|
||||
* @param array $condition
|
||||
*/
|
||||
public function setConfig($value, $config_desc, $is_use, $condition)
|
||||
{
|
||||
$check_condition = array_column($condition, 2, 0);
|
||||
$site_id = $check_condition['site_id'] ?? '';
|
||||
if ($site_id === '') {
|
||||
return $this->error('', 'REQUEST_SITE_ID');
|
||||
}
|
||||
$app_module = $check_condition['app_module'] ?? '';
|
||||
if ($app_module === '') {
|
||||
return $this->error('', 'REQUEST_APP_MODULE');
|
||||
}
|
||||
$config_key = $check_condition['config_key'] ?? '';
|
||||
if (empty($config_key)) {
|
||||
return $this->error('', 'REQUEST_CONFIG_KEY');
|
||||
}
|
||||
$data = $check_condition;
|
||||
$data[ 'value' ] = json_encode($value);
|
||||
$data[ 'config_desc' ] = $config_desc;
|
||||
$data[ 'is_use' ] = $is_use;
|
||||
$json_condition = json_encode($condition);
|
||||
$config_model = model('config');
|
||||
$info = $config_model->getInfo($condition, 'id');
|
||||
Cache::tag('config')->clear();
|
||||
Cache::tag('config')->set('CONFIG_' . $json_condition, '');
|
||||
if (empty($info)) {
|
||||
$data[ 'create_time' ] = time();
|
||||
$res = $config_model->add($data);
|
||||
} else {
|
||||
$data[ 'modify_time' ] = time();
|
||||
$res = $config_model->update($data, $condition);
|
||||
}
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统配置信息
|
||||
* @param array $condition
|
||||
*/
|
||||
public function getConfig($condition)
|
||||
{
|
||||
$check_condition = array_column($condition, 2, 0);
|
||||
$site_id = $check_condition['site_id'] ?? '';
|
||||
if ($site_id === '') {
|
||||
return $this->error('', 'REQUEST_SITE_ID');
|
||||
}
|
||||
$app_module = $check_condition['app_module'] ?? '';
|
||||
if ($app_module === '') {
|
||||
return $this->error('', 'REQUEST_APP_MODULE');
|
||||
}
|
||||
$config_key = $check_condition['config_key'] ?? '';
|
||||
if (empty($config_key)) {
|
||||
return $this->error('', 'REQUEST_CONFIG_KEY');
|
||||
}
|
||||
|
||||
$info = model('config')->getInfo($condition, 'site_id, app_module, config_key, value, config_desc, is_use, create_time, modify_time');
|
||||
if (!empty($info)) {
|
||||
$info[ 'value' ] = json_decode($info[ 'value' ], true);
|
||||
} else {
|
||||
$info = [
|
||||
'site_id' => $site_id,
|
||||
'app_module' => $app_module,
|
||||
'config_key' => $config_key,
|
||||
'value' => [],
|
||||
'config_desc' => '',
|
||||
'is_use' => 0,
|
||||
'create_time' => 0,
|
||||
'modify_time' => 0
|
||||
];
|
||||
}
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改配置项的使用状态
|
||||
* @param int $is_use
|
||||
* @param array $condition
|
||||
*/
|
||||
public function modifyConfigIsUse($is_use, $condition)
|
||||
{
|
||||
$json_condition = json_encode($condition);
|
||||
$config = model('config')->getInfo($condition);
|
||||
if (!empty($config)) {
|
||||
//配置过
|
||||
$res = model('config')->update([ 'is_use' => $is_use ], $condition);
|
||||
|
||||
Cache::tag('config')->set('CONFIG_' . $json_condition, '');
|
||||
|
||||
return $this->success($res);
|
||||
} else {
|
||||
return $this->error('', 'CONFIG_NOT_EXIST');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统信息
|
||||
*/
|
||||
public function getSystemConfig()
|
||||
{
|
||||
$system_config[ 'os' ] = php_uname(); // 服务器操作系统
|
||||
$system_config[ 'server_software' ] = $_SERVER[ 'SERVER_SOFTWARE' ]; // 服务器环境
|
||||
$system_config[ 'upload_max_filesize' ] = @ini_get('file_uploads') ? ini_get('upload_max_filesize') : 'unknow'; // 文件上传限制
|
||||
$system_config[ 'gd_version' ] = gd_info()[ 'GD Version' ]; // GD(图形处理)版本
|
||||
$system_config[ 'max_execution_time' ] = ini_get('max_execution_time') . '秒'; // 最大执行时间
|
||||
$system_config[ 'port' ] = $_SERVER[ 'SERVER_PORT' ]; // 端口
|
||||
$system_config[ 'dns' ] = $_SERVER[ 'HTTP_HOST' ]; // 服务器域名
|
||||
$system_config[ 'php_version' ] = PHP_VERSION; // php版本
|
||||
$system_config[ 'sockets' ] = extension_loaded('sockets'); //是否支付sockets
|
||||
$system_config[ 'openssl' ] = extension_loaded('openssl'); //是否支付openssl
|
||||
$system_config[ 'curl' ] = function_exists('curl_init'); // 是否支持curl功能
|
||||
$system_config[ 'upload_dir_jurisdiction' ] = check_dir_iswritable(realpath('./upload') . DIRECTORY_SEPARATOR); // upload目录读写权限
|
||||
$system_config[ 'runtime_dir_jurisdiction' ] = check_dir_iswritable(realpath('./runtime') . DIRECTORY_SEPARATOR); // runtime目录读写权限
|
||||
$system_config[ 'fileinfo' ] = extension_loaded('fileinfo'); //是否支付fileinfo
|
||||
|
||||
return $this->success($system_config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除配置
|
||||
* @param $condition
|
||||
*/
|
||||
public function deleteConfig($condition)
|
||||
{
|
||||
$res = model('config')->delete($condition);
|
||||
$this->success($res);
|
||||
}
|
||||
}
|
||||
316
app/model/system/Cron.php
Executable file
316
app/model/system/Cron.php
Executable file
@@ -0,0 +1,316 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use app\dict\system\ScheduleDict;
|
||||
use app\model\BaseModel;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Log;
|
||||
use think\facade\Queue;
|
||||
use think\facade\Db;
|
||||
|
||||
/**
|
||||
* 计划任务管理
|
||||
* @author Administrator
|
||||
*
|
||||
*/
|
||||
class Cron extends BaseModel
|
||||
{
|
||||
//任务类型
|
||||
const TYPE_FIXED = 1;//定时
|
||||
const TYPE_LOOP = 2;//循环
|
||||
|
||||
//最大错误次数
|
||||
protected $max_error_num = 3;
|
||||
|
||||
public $time_diff = 60;//默认半个小时检测一次
|
||||
|
||||
/**
|
||||
* 添加计划任务
|
||||
* @param int $type 任务类型 1.固定任务 2.循环任务
|
||||
* @param int $period 执行周期
|
||||
* @param string $name 任务名称
|
||||
* @param string $event 执行事件
|
||||
* @param int $execute_time 待执行时间
|
||||
* @param int $relate_id 关联id
|
||||
* @param int $period_type 周期类型
|
||||
*/
|
||||
public function addCron($type, $period, $name, $event, $execute_time, $relate_id, $period_type = 0)
|
||||
{
|
||||
$data = [
|
||||
'type' => $type,
|
||||
'period' => $period,
|
||||
'period_type' => $period_type,
|
||||
'name' => $name,
|
||||
'event' => $event,
|
||||
'execute_time' => $execute_time,
|
||||
'relate_id' => $relate_id,
|
||||
'create_time' => time()
|
||||
];
|
||||
$res = model('cron')->add($data);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除计划任务
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function deleteCron($condition)
|
||||
{
|
||||
$res = model('cron')->delete($condition);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行任务
|
||||
*/
|
||||
public function execute($type = 'default')
|
||||
{
|
||||
if(config('cron.default') != $type) return true;
|
||||
Log::write('计划任务方式:'.$type);
|
||||
$this->writeSchedule();//写入计划任务标记运行
|
||||
|
||||
$system_config_model = new SystemConfig();
|
||||
$config = $system_config_model->getSystemConfig()[ 'data' ] ?? [];
|
||||
$is_open_queue = $config[ 'is_open_queue' ] ?? 0;
|
||||
$query_execute_time = $is_open_queue == 1 ? time() + 60 : time();
|
||||
|
||||
$type_fixed = self::TYPE_FIXED;
|
||||
$type_loop = self::TYPE_LOOP;
|
||||
|
||||
$list = model('cron')->getList([
|
||||
['execute_time', '<=', $query_execute_time],
|
||||
['', 'exp', Db::raw("(type = {$type_fixed} and error_num < {$this->max_error_num}) or type = {$type_loop}")],
|
||||
], '*', '', '', [], '', 150);
|
||||
$now_time = time();
|
||||
if (!empty($list)) {
|
||||
foreach ($list as $k => $v) {
|
||||
Log::write('任务信息');
|
||||
Log::write($v);
|
||||
$event_res = checkQueue($v, function($params) {
|
||||
//加入消息队列
|
||||
$job_handler_classname = 'Cronexecute';
|
||||
try {
|
||||
if ($params[ 'execute_time' ] <= time()) {
|
||||
Queue::push($job_handler_classname, $params);
|
||||
} else {
|
||||
Queue::later($params[ 'execute_time' ] - time(), $job_handler_classname, $params);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$res = $this->error($e->getMessage(), $e->getMessage());
|
||||
}
|
||||
return $res ?? $this->success();
|
||||
}, function($params) {
|
||||
try {
|
||||
$res = $this->success();
|
||||
$res_list = event($params[ 'event' ], [ 'relate_id' => $params[ 'relate_id' ] ]);
|
||||
foreach($res_list as $val){
|
||||
if(isset($val['code']) && $val['code'] < 0){
|
||||
$res = $val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$res = $this->error([
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'message' => $e->getMessage(),
|
||||
], '定时任务执行捕获异常');
|
||||
}
|
||||
|
||||
$data_log = [
|
||||
'name' => $params[ 'name' ],
|
||||
'event' => $params[ 'event' ],
|
||||
'relate_id' => $params[ 'relate_id' ],
|
||||
'message' => json_encode($res)
|
||||
];
|
||||
$this->addCronLog($data_log);
|
||||
return $res;
|
||||
});
|
||||
Log::write('任务结果');
|
||||
Log::write($event_res);
|
||||
|
||||
//有错误更新错误次数,下次决定是否继续执行
|
||||
$event_code = $event_res[ 'code' ] ?? 0;
|
||||
if ($event_code < 0) {
|
||||
model('cron')->update([
|
||||
'error_num' => Db::raw("error_num + 1"),
|
||||
], [ [ 'id', '=', $v[ 'id' ] ] ]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($v[ 'type' ] == self::TYPE_LOOP) {
|
||||
//循环任务更新下次执行时间
|
||||
$period = $v[ 'period' ] == 0 ? 1 : $v[ 'period' ];
|
||||
switch ( $v[ 'period_type' ] ) {
|
||||
case 0://分
|
||||
$execute_time = $now_time + $period * 60;
|
||||
break;
|
||||
case 1://天
|
||||
$execute_time = strtotime('+' . $period . 'day', $v[ 'execute_time' ]);
|
||||
break;
|
||||
case 2://周
|
||||
$execute_time = strtotime('+' . $period . 'week', $v[ 'execute_time' ]);
|
||||
break;
|
||||
case 3://月
|
||||
$execute_time = strtotime('+' . $period . 'month', $v[ 'execute_time' ]);
|
||||
break;
|
||||
}
|
||||
if(!empty($execute_time)){
|
||||
model('cron')->update([
|
||||
'execute_time' => $execute_time,
|
||||
], [ [ 'id', '=', $v[ 'id' ] ] ]);
|
||||
}
|
||||
} else {
|
||||
//固定任务删除
|
||||
model('cron')->delete([ [ 'id', '=', $v[ 'id' ] ] ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加自动任务日志
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function addCronLog($data)
|
||||
{
|
||||
// 日常不需要添加,调试使用
|
||||
// $data[ 'execute_time' ] = time();
|
||||
// model('cron_log')->add($data);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检测自动任务标识缓存是否已过期
|
||||
*/
|
||||
public function checkCron()
|
||||
{
|
||||
$diff = $this->time_diff;
|
||||
$now_time = time();
|
||||
$cron_cache = Cache::get('cron_cache');
|
||||
if (empty($cron_cache)) {
|
||||
//todo 不存在缓存标识,并不视为任务停止
|
||||
//创建缓存标识,当前时间填充
|
||||
Cache::set('cron_cache', [ 'time' => $now_time, 'error' => '' ]);
|
||||
} else {
|
||||
$time = $cron_cache[ 'time' ];
|
||||
$error = $cron_cache[ 'error' ] ?? '';
|
||||
$attempts = $cron_cache[ 'attempts' ] ?? 0;//尝试次数
|
||||
if (!empty($error) || ( $now_time - $time ) > $diff) {
|
||||
$message = '自动任务已停止';
|
||||
if (!empty($error)) {
|
||||
$message .= ',停止原因:' . $error;
|
||||
} else {
|
||||
$system_config_model = new \app\model\system\SystemConfig();
|
||||
$config = $system_config_model->getSystemConfig()[ 'data' ] ?? [];
|
||||
$is_open_queue = $config[ 'is_open_queue' ] ?? 0;
|
||||
if (!$is_open_queue) {//如果不是消息队列的话,可以尝试异步调用一下
|
||||
if ($attempts < 1) {
|
||||
Cache::set('cron_cache', [ 'time' => $now_time, 'error' => '', 'attempts' => 1 ]);
|
||||
$url = url('cron/task/execute');
|
||||
http($url, 1);
|
||||
return $this->success();
|
||||
}
|
||||
} else {
|
||||
//消息队列无法启动,应该在前端引导跳转到官方的手册
|
||||
}
|
||||
}
|
||||
//判断任务是 消息队列自动任务,还是默认睡眠sleep自动任务
|
||||
return $this->error([], $message);
|
||||
}
|
||||
|
||||
}
|
||||
return $this->success();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置自动任务
|
||||
* @param array $params
|
||||
* @return array
|
||||
*/
|
||||
public function setCron($params = [])
|
||||
{
|
||||
$cron_cache = Cache::get('cron_cache');
|
||||
if (empty($cron_cache)) {
|
||||
$cron_cache = [];
|
||||
}
|
||||
// $code = $params['code'] ?? 0;
|
||||
// if($code < 0){
|
||||
// $error = $params['message'] ?? '位置的错误';
|
||||
// $cron_cache['error'] = $error;
|
||||
// }
|
||||
|
||||
$cron_cache[ 'time' ] = time();
|
||||
$cron_cache[ 'attempts' ] = 0;
|
||||
Cache::set('cron_cache', $cron_cache);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验计划任务是否正常运行
|
||||
* @return bool
|
||||
*/
|
||||
public function checkSchedule()
|
||||
{
|
||||
$file = root_path('runtime') . '.schedule';
|
||||
if (file_exists($file)) {
|
||||
$time = file_get_contents($file);
|
||||
if (!empty($time) && abs($time - time()) < 90) {
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
$remark = '计划任务已停止!当前启动的任务方式:'.ScheduleDict::getType(config('cron.default')).'。 <a href="https://www.kancloud.cn/niucloud/niushop_b2c_v5/3212243" target="_blank" style="margin-left: 0px">查看文档</a>';
|
||||
$error = self::getError(config('cron.default'));
|
||||
if(!empty($error)){
|
||||
$remark .= $error;
|
||||
}
|
||||
return $this->error([], $remark);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入校验计划任务
|
||||
* @return true
|
||||
*/
|
||||
public function writeSchedule(){
|
||||
$file = root_path('runtime').'.schedule';
|
||||
file_put_contents($file, time());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存自动任务的错误
|
||||
* @param $type
|
||||
* @param $error
|
||||
* @return true
|
||||
*/
|
||||
public static function setError($type, $error = ''){
|
||||
Cache::set('cron_error', [$type => $error]);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取错误
|
||||
* @param $type
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getError($type = ''){
|
||||
$error = Cache::get('cron_error');
|
||||
if(!empty($type))
|
||||
return $error;
|
||||
return $error[$type];
|
||||
}
|
||||
}
|
||||
235
app/model/system/Database.php
Executable file
235
app/model/system/Database.php
Executable file
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use think\facade\Db;
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 数据库操作
|
||||
*/
|
||||
class Database extends BaseModel
|
||||
{
|
||||
|
||||
public $backup_path = __UPLOAD__ . '/dbsql';
|
||||
|
||||
/***********************************************************SQL开始*********************************************************/
|
||||
|
||||
/**
|
||||
* 修复表
|
||||
*/
|
||||
public function repair($tables)
|
||||
{
|
||||
if ($tables) {
|
||||
Db::startTrans();
|
||||
try {
|
||||
if (is_array($tables)) {
|
||||
$tables = implode('`,`', $tables);
|
||||
Db::query("REPAIR TABLE `{$tables}`");
|
||||
} else {
|
||||
Db::query("REPAIR TABLE `{$tables}`");
|
||||
}
|
||||
Db::commit();
|
||||
return $this->success(1);
|
||||
} catch (\Exception $e) {
|
||||
// 回滚事务
|
||||
Db::rollback();
|
||||
return $this->error('', "DABASE_REPAIR_FAIL");
|
||||
}
|
||||
} else {
|
||||
return $this->error('', "DABASE_REPAIR_FAIL");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 优化表
|
||||
*/
|
||||
public function optimize($tables)
|
||||
{
|
||||
if ($tables) {
|
||||
if (is_array($tables)) {
|
||||
$tables = implode('`,`', $tables);
|
||||
$list = Db::query("OPTIMIZE TABLE `{$tables}`");
|
||||
if ($list) {
|
||||
|
||||
return $this->success(1);
|
||||
} else {
|
||||
return $this->error('', "DATABASE_OPTIMIZE_FAIL");
|
||||
}
|
||||
} else {
|
||||
$list = Db::query("OPTIMIZE TABLE `{$tables}`");
|
||||
if ($list) {
|
||||
return $this->success(1);
|
||||
} else {
|
||||
return $this->error('', "DATABASE_OPTIMIZE_FAIL");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return $this->error('', "REQUEST_DATABASE_TABLE");
|
||||
}
|
||||
}
|
||||
|
||||
private function sql_execute($sql, $is_debug)
|
||||
{
|
||||
if (trim($sql) != '') {
|
||||
$sql = str_replace("\r\n", "\n", $sql);
|
||||
$sql = str_replace("\r", "\n", $sql);
|
||||
$sql_array = explode(";\n", $sql);
|
||||
if (!$is_debug) {
|
||||
Db::startTrans();
|
||||
}
|
||||
try {
|
||||
foreach ($sql_array as $item) {
|
||||
if ($is_debug) {
|
||||
Db::startTrans();
|
||||
}
|
||||
$querySql = trim($item);
|
||||
if ($querySql != '') {
|
||||
@Db::execute($querySql . ";");
|
||||
if ($is_debug) {
|
||||
Db::rollback();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$is_debug) {
|
||||
Db::commit();
|
||||
}
|
||||
return $this->success(1);
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
} else {
|
||||
return $this->error('');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行sql
|
||||
*/
|
||||
public function sqlQuery($sql)
|
||||
{
|
||||
$result = $this->sql_execute($sql, false);
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function yujjia($sql)
|
||||
{
|
||||
Db::startTrans();
|
||||
try {
|
||||
Db::query($sql);
|
||||
Db::rollback();
|
||||
return "1";
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有表
|
||||
*/
|
||||
public function getDatabaseList()
|
||||
{
|
||||
$databaseList = Db::query("SHOW TABLE STATUS");
|
||||
return $databaseList;
|
||||
}
|
||||
|
||||
/**备份数据库语句
|
||||
* @return string
|
||||
*/
|
||||
public function backupSql($tables, $id, $start)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function getTableSchemas($table)
|
||||
{
|
||||
$mysql = "DROP TABLE IF EXISTS `$table`;\r\n";
|
||||
$temp_create_table_result = Db::query("show create table `$table`");
|
||||
$create_table = $temp_create_table_result[0]['Create Table'];
|
||||
$mysql .= $create_table . ";\r\n";
|
||||
return $mysql;
|
||||
}
|
||||
|
||||
public function getTableInsertSql($tablename, $start, $size)
|
||||
{
|
||||
$data = '';
|
||||
$tmp = '';
|
||||
$sql = "SELECT * FROM `{$tablename}` LIMIT {$start}, {$size}";
|
||||
$result = Db::query($sql);
|
||||
if (!empty($result)) {
|
||||
foreach ($result as $row) {
|
||||
$tmp .= '(';
|
||||
foreach ($row as $k => $v) {
|
||||
$value = str_replace(array('\\', "\0", "\n", "\r", "'", '"', "\x1a"), array('\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'), $v);
|
||||
$tmp .= "'" . $value . "',";
|
||||
}
|
||||
$tmp = rtrim($tmp, ',');
|
||||
$tmp .= "),\n";
|
||||
}
|
||||
$tmp = rtrim($tmp, ",\n");
|
||||
$data .= "INSERT INTO `{$tablename}` VALUES \n{$tmp};\n";
|
||||
$datas = array(
|
||||
'data' => $data,
|
||||
'result' => $result,
|
||||
);
|
||||
return $datas;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 格式化字节大小
|
||||
*
|
||||
* @param number $size
|
||||
* 字节数
|
||||
* @param string $delimiter
|
||||
* 数字和单位分隔符
|
||||
* @return string 格式化后的带单位的大小
|
||||
* @author
|
||||
*
|
||||
*/
|
||||
public function format_bytes($size, $delimiter = '')
|
||||
{
|
||||
$units = array(
|
||||
'B',
|
||||
'KB',
|
||||
'MB',
|
||||
'GB',
|
||||
'TB',
|
||||
'PB'
|
||||
);
|
||||
for ($i = 0; $size >= 1024 && $i < 5; $i++)
|
||||
$size /= 1024;
|
||||
return round($size, 2) . $delimiter . $units[$i];
|
||||
}
|
||||
|
||||
/**
|
||||
* 多维数组排序
|
||||
*/
|
||||
public function my_array_multisort($data, $sort_order_field, $sort_order = SORT_DESC, $sort_type = SORT_NUMERIC)
|
||||
{
|
||||
foreach ($data as $val) {
|
||||
$key_arrays[] = $val[$sort_order_field];
|
||||
}
|
||||
array_multisort($key_arrays, $sort_order, $sort_type, $data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************SQL结束*********************************************************/
|
||||
|
||||
}
|
||||
24
app/model/system/DiyTemplate.php
Executable file
24
app/model/system/DiyTemplate.php
Executable file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use app\model\BaseModel;
|
||||
|
||||
class DiyTemplate extends BaseModel
|
||||
{
|
||||
/**
|
||||
* 刷新自定义模板
|
||||
*/
|
||||
public function refresh()
|
||||
{
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
98
app/model/system/Document.php
Executable file
98
app/model/system/Document.php
Executable file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use think\facade\Cache;
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 系统文章
|
||||
*/
|
||||
class Document extends BaseModel
|
||||
{
|
||||
|
||||
/**
|
||||
* 设置文章内容
|
||||
* @param $title
|
||||
* @param $content
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function setDocument($title, $content, $condition)
|
||||
{
|
||||
$check_condition = array_column($condition, 2, 0);
|
||||
$site_id = $check_condition['site_id'] ?? '';
|
||||
if ($site_id === '') {
|
||||
return $this->error('', 'REQUEST_SITE_ID');
|
||||
}
|
||||
$app_module = $check_condition['app_module'] ?? '';
|
||||
if ($app_module === '') {
|
||||
return $this->error('', 'REQUEST_APP_MODULE');
|
||||
}
|
||||
$document_key = $check_condition['document_key'] ?? '';
|
||||
if (empty($document_key)) {
|
||||
return $this->error('', 'REQUEST_DOCUMENT_KEY');
|
||||
}
|
||||
$data = $check_condition;
|
||||
$data['title'] = $title;
|
||||
$data['content'] = $content;
|
||||
$json_condition = json_encode($condition);
|
||||
$document_model = model('document');
|
||||
$info = $document_model->getInfo($condition, 'id');
|
||||
Cache::tag("document")->set("document_" . $json_condition, "");
|
||||
if (empty($info)) {
|
||||
$data['create_time'] = time();
|
||||
$res = $document_model->add($data);
|
||||
} else {
|
||||
$data['modify_time'] = time();
|
||||
$res = $document_model->update($data, $condition);
|
||||
}
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统文章
|
||||
* @param array $condition
|
||||
*/
|
||||
public function getDocument($condition)
|
||||
{
|
||||
$check_condition = array_column($condition, 2, 0);
|
||||
$site_id = $check_condition['site_id'] ?? '';
|
||||
if ($site_id === '') {
|
||||
return $this->error('', 'REQUEST_SITE_ID');
|
||||
}
|
||||
$app_module = $check_condition['app_module'] ?? '';
|
||||
if ($app_module === '') {
|
||||
return $this->error('', 'REQUEST_APP_MODULE');
|
||||
}
|
||||
$document_key = $check_condition['document_key'] ?? '';
|
||||
if (empty($document_key)) {
|
||||
return $this->error('', 'REQUEST_DOCUMENT_KEY');
|
||||
}
|
||||
|
||||
$info = model('document')->getInfo($condition, 'site_id, app_module, document_key, title, content, create_time, modify_time');
|
||||
if (empty($info)) {
|
||||
//默认初始值
|
||||
$info = [
|
||||
'site_id' => $site_id,
|
||||
'app_module' => $app_module,
|
||||
'document_key' => $document_key,
|
||||
'title' => '',
|
||||
'content' => '',
|
||||
'create_time' => 0,
|
||||
'modify_time' => 0
|
||||
];
|
||||
}
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
}
|
||||
340
app/model/system/Export.php
Executable file
340
app/model/system/Export.php
Executable file
@@ -0,0 +1,340 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use think\facade\Db;
|
||||
|
||||
class Export extends BaseModel
|
||||
{
|
||||
const STATUS_IN_PROCESS = 0;
|
||||
const STATUS_SUCCESS = 1;
|
||||
const STATUS_FAIL = 2;
|
||||
|
||||
static public function getStatus($key = null)
|
||||
{
|
||||
$arr = [
|
||||
[
|
||||
'id' => self::STATUS_IN_PROCESS,
|
||||
'name' => '导出中',
|
||||
],
|
||||
[
|
||||
'id' => self::STATUS_SUCCESS,
|
||||
'name' => '导出成功',
|
||||
],
|
||||
[
|
||||
'id' => self::STATUS_FAIL,
|
||||
'name' => '导出失败',
|
||||
],
|
||||
];
|
||||
if(isset($arr[0][$key])){
|
||||
$arr = array_column($arr, null, $key);
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
protected $data_num = 0;
|
||||
|
||||
/**
|
||||
* 导出
|
||||
* @param $param
|
||||
* @return array
|
||||
*/
|
||||
public function export($param)
|
||||
{
|
||||
//传参说明
|
||||
/*$param = [
|
||||
'site_id' => $site_id,
|
||||
'store_id' => $export_store_id,
|
||||
'from_type' => 'store_account',
|
||||
'from_type_name' => '门店账户',
|
||||
'condition_desc' => $condition_desc,
|
||||
'export_field' => [
|
||||
['field' => 'store_name', 'name' => '门店名称'],
|
||||
['field' => 'type_name', 'name' => '来源方式'],
|
||||
['field' => 'account_data', 'name' => '记录金额'],
|
||||
['field' => 'create_time', 'name' => '发生时间'],
|
||||
['field' => 'remark', 'name' => '备注'],
|
||||
['field' => 'related_no', 'name' => '关联编号'],
|
||||
],
|
||||
//数据库查询相关参数
|
||||
'query' => [
|
||||
'table' => 'store_account',
|
||||
'alias' => 'sa',
|
||||
'join' => [
|
||||
['store s', 'sa.store_id = s.store_id', 'inner'],
|
||||
],
|
||||
'condition' => $condition,
|
||||
'field' => 'sa.*,s.store_name',
|
||||
'chunk_field' => 'sa.id',
|
||||
'chunk_order' => 'asc',
|
||||
],
|
||||
//数据库查询结果处理 这个其实应该放在query中
|
||||
'handle' => function($item_list){
|
||||
return $item_list;
|
||||
},
|
||||
//直接传递导出的数据
|
||||
'data' => [],
|
||||
];*/
|
||||
|
||||
set_time_limit(0);
|
||||
|
||||
$site_id = $param['site_id'];
|
||||
$store_id = $param['store_id'] ?? 0;
|
||||
$from_type = $param['from_type'];
|
||||
$from_type_name = $param['from_type_name'];
|
||||
$condition_desc= $param['condition_desc'];
|
||||
$export_field = $param['export_field'];
|
||||
$query = $param['query'] ?? null;//table alias join condition field order
|
||||
$handle = $param['handle'] ?? null;//数据处理
|
||||
|
||||
try {
|
||||
//预先创建导出的记录
|
||||
$data = array(
|
||||
'condition' => json_encode($condition_desc, JSON_UNESCAPED_UNICODE),
|
||||
'create_time' => time(),
|
||||
'from_type' => $from_type,
|
||||
'from_type_name' => $from_type_name,
|
||||
'status' => self::STATUS_IN_PROCESS,
|
||||
'site_id' => $site_id,
|
||||
'store_id' => $store_id,
|
||||
);
|
||||
$records_result = $this->addExport($data);
|
||||
$export_id = $records_result['data'];
|
||||
if (empty($export_id)) return $this->error(null, '创建导出记录失败');
|
||||
$this->data_num = 0;
|
||||
|
||||
//创建目录
|
||||
$file_path = 'upload/export/'.$from_type.'/';
|
||||
if (!dir_mkdir($file_path)) return $this->error(null, '导出目录创建失败');
|
||||
|
||||
//创建并打开文件
|
||||
$file_name = $from_type_name.date('YmdHis');//csv文件名
|
||||
$file_path = $file_path . $file_name . '.csv';
|
||||
$fp = fopen($file_path, 'w');
|
||||
fwrite($fp, chr(0xEF) . chr(0xBB) . chr(0xBF));
|
||||
|
||||
//写入第一行表头
|
||||
fwrite($fp, join(',', array_column($export_field, 'name'))."\n");
|
||||
|
||||
//导出数据
|
||||
if(isset($param['query'])){
|
||||
$export_table = Db::name($query['table'])->where($query['condition']);
|
||||
if(!empty($query['alias'])) $export_table = $export_table->alias($query['alias']);
|
||||
if(!empty($query['join'])) $export_table = $this->parseJoin($export_table, $query['join']);
|
||||
if(!empty($query['group'])) $export_table = $export_table->group($query['group']);
|
||||
$export_table->field($query['field'])->chunk(1000, function ($item_list) use ($fp, $export_field, $handle) {
|
||||
$item_list = $item_list->toArray();
|
||||
if(!empty($handle)){
|
||||
$item_list = $handle($item_list);
|
||||
}
|
||||
$this->data_num += count($item_list);
|
||||
$this->itemExport($item_list, $export_field, $fp);
|
||||
unset($item_list);
|
||||
}, $query['chunk_field'], $query['chunk_order']);
|
||||
$export_table->removeOption();
|
||||
}else if(isset($param['data'])){
|
||||
$this->itemExport($param['data'], $export_field, $fp);
|
||||
}else{
|
||||
throw new \Exception('query参数和data参数至少要传一个');
|
||||
}
|
||||
|
||||
fclose($fp); //每生成一个文件关闭
|
||||
unset($export_table);
|
||||
|
||||
//更新导出记录
|
||||
$this->editExport([
|
||||
'path' => $file_path,
|
||||
'status' => self::STATUS_SUCCESS,
|
||||
'data_num' => $this->data_num,
|
||||
], [['export_id', '=', $export_id]]);
|
||||
|
||||
//返回导出信息
|
||||
$export_info = $this->getExportInfo([['export_id', '=', $export_id]])['data'];
|
||||
return $this->success($export_info);
|
||||
} catch (\Exception $e ) {
|
||||
$error = [
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'message' => $e->getMessage(),
|
||||
];
|
||||
if(isset($export_id)){
|
||||
//更新导出记录
|
||||
$this->editExport([
|
||||
'status' => self::STATUS_FAIL,
|
||||
'fail_log' => json_encode($error, JSON_UNESCAPED_UNICODE),
|
||||
], [['export_id', '=', $export_id]]);
|
||||
}
|
||||
return $this->error($error, '导出失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 给csv写入新的数据
|
||||
* @param $item_list
|
||||
* @param $field_key
|
||||
* @param $temp_line
|
||||
* @param $fp
|
||||
*/
|
||||
protected function itemExport($item_list, $export_field, $fp)
|
||||
{
|
||||
if(method_exists($item_list, 'toArray')){
|
||||
$item_list = $item_list->toArray();
|
||||
}
|
||||
foreach ($item_list as $item_info) {
|
||||
$values = [];
|
||||
foreach($export_field as $field_info){
|
||||
if(isset($item_info[$field_info['field']])){
|
||||
$value = $item_info[$field_info['field']];
|
||||
$value = trim($value);
|
||||
$value = str_replace(',', ',', $value . "\t");
|
||||
$value = str_replace("\n", '', $value);
|
||||
$value = str_replace("\r", '', $value);
|
||||
$values[] = $value;
|
||||
}
|
||||
}
|
||||
//写入数据
|
||||
fwrite($fp, join(',', $values)."\n");
|
||||
//销毁变量, 防止内存溢出
|
||||
unset($new_line_value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析关联
|
||||
* @param $db_obj
|
||||
* @param $join
|
||||
* @return mixed
|
||||
*/
|
||||
protected function parseJoin($db_obj, $join)
|
||||
{
|
||||
foreach ($join as $item) {
|
||||
list($table, $on, $type) = $item;
|
||||
$type = strtolower($type);
|
||||
switch ($type) {
|
||||
case 'left':
|
||||
$db_obj = $db_obj->leftJoin($table, $on);
|
||||
break;
|
||||
case 'inner':
|
||||
$db_obj = $db_obj->join($table, $on);
|
||||
break;
|
||||
case 'right':
|
||||
$db_obj = $db_obj->rightjoin($table, $on);
|
||||
break;
|
||||
case 'full':
|
||||
$db_obj = $db_obj->fulljoin($table, $on);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $db_obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加导出记录
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function addExport($data)
|
||||
{
|
||||
$res = model('export')->add($data);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新导出记录
|
||||
* @param $data
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function editExport($data, $condition)
|
||||
{
|
||||
$res = model('export')->update($data, $condition);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除导出记录
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function deleteExport($condition)
|
||||
{
|
||||
//先查询数据
|
||||
$list = model('export')->getList($condition, '*');
|
||||
if (!empty($list)) {
|
||||
foreach ($list as $k => $v) {
|
||||
if (file_exists($v['path'])) {
|
||||
//删除物理文件路径
|
||||
if (!unlink($v['path'])) {
|
||||
//失败
|
||||
} else {
|
||||
//成功
|
||||
}
|
||||
}
|
||||
}
|
||||
$res = model('export')->delete($condition);
|
||||
}
|
||||
return $this->success($res ?? '');
|
||||
}
|
||||
|
||||
public function getExportInfo($condition, $field = '*')
|
||||
{
|
||||
$info = model('export')->getInfo($condition, $field);
|
||||
$info = $this->handleData($info);
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取导出记录
|
||||
* @param $condition
|
||||
* @param string $field
|
||||
* @param string $order
|
||||
* @return array
|
||||
*/
|
||||
public function getExportList($condition, $field = '*', $order = '')
|
||||
{
|
||||
$list = model('export')->getList($condition, $field, $order);
|
||||
foreach($list as &$val){
|
||||
$val = $this->handleData($val);
|
||||
}
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出记录
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getExportPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
|
||||
{
|
||||
$list = model('export')->pageList($condition, $field, $order, $page, $page_size);
|
||||
foreach($list['list'] as &$val){
|
||||
$val = $this->handleData($val);
|
||||
}
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
protected function handleData($data)
|
||||
{
|
||||
if(isset($data['status'])){
|
||||
$status_list = self::getStatus('id');
|
||||
$data['status_name'] = $status_list[$data['status']]['name'] ?? '';
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
246
app/model/system/Group.php
Executable file
246
app/model/system/Group.php
Executable file
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use think\facade\Cache;
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 用户组
|
||||
* @author Administrator
|
||||
*
|
||||
*/
|
||||
class Group extends BaseModel
|
||||
{
|
||||
public $cache_model = "cache_model_group";
|
||||
/*****************************************用户组管理开始******************************************************************************/
|
||||
|
||||
/**
|
||||
* 添加用户组
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function addGroup($data)
|
||||
{
|
||||
$site_id = $data['site_id'] ?? '';
|
||||
if ($site_id === '') {
|
||||
return $this->error('', 'REQUEST_SITE_ID');
|
||||
}
|
||||
$app_module = $data['app_module'] ?? '';
|
||||
if ($app_module === '') {
|
||||
return $this->error('', 'REQUEST_APP_MODULE');
|
||||
}
|
||||
|
||||
//创建者数据
|
||||
if(isset($data['create_uid'])){
|
||||
$user_info = model('user')->getInfo([['uid', '=', $data['create_uid']]], 'uid,username,create_user_data');
|
||||
$create_user_data = json_decode($user_info['create_user_data'], true);
|
||||
$create_user_data[] = ['id' => (string)$user_info['uid'], 'name' => $user_info['username']];
|
||||
$data['create_user_data'] = json_encode($create_user_data, JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
//预留验证
|
||||
$res = model('group')->add($data);
|
||||
Cache::tag($this->cache_model)->clear();
|
||||
if ($res === false) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户组
|
||||
* @param $data
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function editGroup($data, $condition)
|
||||
{
|
||||
$check_condition = array_column($condition, 2, 0);
|
||||
$site_id = $check_condition['site_id'] ?? '';
|
||||
if ($site_id === '') {
|
||||
return $this->error('', 'REQUEST_SITE_ID');
|
||||
}
|
||||
$app_module = $check_condition['app_module'] ?? '';
|
||||
if ($app_module === '') {
|
||||
return $this->error('', 'REQUEST_APP_MODULE');
|
||||
}
|
||||
$condition[] = [ "is_system", "=", 0 ];//只能删除非系统用户组
|
||||
|
||||
$res = model('group')->update($data, $condition);
|
||||
Cache::tag($this->cache_model)->clear();
|
||||
if ($res === false) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
return $this->success($res);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户组(不能批量)
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function deleteGroup($condition)
|
||||
{
|
||||
$check_condition = array_column($condition, 2, 0);
|
||||
$site_id = $check_condition['site_id'] ?? '';
|
||||
if ($site_id === '') {
|
||||
return $this->error('', 'REQUEST_SITE_ID');
|
||||
}
|
||||
$app_module = $check_condition['app_module'] ?? '';
|
||||
if ($app_module === '') {
|
||||
return $this->error('', 'REQUEST_APP_MODULE');
|
||||
}
|
||||
$group_id = $check_condition['group_id'] ?? 0;
|
||||
if (!is_int($group_id) && $group_id <= 0) {
|
||||
return $this->error('', 'USER_GROUP_NOT_ALL_DELETE');
|
||||
}
|
||||
$temp_count = model('user')->getCount([ [ "group_id", "=", $group_id ], [ "app_module", "=", $app_module ], [ "site_id", "=", $site_id ] ], "uid");
|
||||
if ($temp_count > 0)
|
||||
return $this->error('', 'USER_GROUP_USED');
|
||||
|
||||
$condition[] = [ "is_system", "=", 0 ];//只能删除非系统用户组
|
||||
|
||||
$res = model('group')->delete($condition);
|
||||
Cache::tag($this->cache_model)->clear();
|
||||
if ($res === false) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户组状态
|
||||
* @param $group_status
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function modifyGroupStatus($group_status, $condition)
|
||||
{
|
||||
$check_condition = array_column($condition, 2, 0);
|
||||
$site_id = $check_condition['site_id'] ?? '';
|
||||
if ($site_id === '') {
|
||||
return $this->error('', 'REQUEST_SITE_ID');
|
||||
}
|
||||
$app_module = $check_condition['app_module'] ?? '';
|
||||
if ($app_module === '') {
|
||||
return $this->error('', 'REQUEST_APP_MODULE');
|
||||
}
|
||||
$condition[ "is_system" ] = 0;//只能删除非系统用户组
|
||||
$res = model('group')->update([ 'group_status' => $group_status ], $condition);
|
||||
Cache::tag($this->cache_model)->clear();
|
||||
if ($res === false) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取门店分组列信息
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getStoreGroupColumn($condition = [], $field = '')
|
||||
{
|
||||
$res = model('group')->getColumn($condition, $field);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户组详情
|
||||
* @param $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getGroupInfo($condition, $field = '*')
|
||||
{
|
||||
$check_condition = array_column($condition, 2, 0);
|
||||
$app_module = $check_condition['app_module'] ?? '';
|
||||
if ($app_module === '') {
|
||||
return $this->error('', 'REQUEST_APP_MODULE');
|
||||
}
|
||||
$info = model('group')->getInfo($condition, $field);
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过groupid获取相应用户组数据,应用在门店,供应商等不创建站点
|
||||
* @param $group_id
|
||||
* @param $site_id
|
||||
* @param $app_module
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getGroupInfoById($group_id, $site_id, $app_module, $field = '*')
|
||||
{
|
||||
if ($app_module === '') {
|
||||
return $this->error('', 'REQUEST_APP_MODULE');
|
||||
}
|
||||
|
||||
$info = model('group')->getInfo([ [ 'group_id', '=', $group_id ], [ 'app_module', '=', $app_module ] ], $field);
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户组列表
|
||||
* @param array $condition
|
||||
* @param bool $field
|
||||
* @param string $order
|
||||
* @param null $limit
|
||||
* @return array
|
||||
*/
|
||||
public function getGroupList($condition = [], $field = true, $order = 'create_time desc, group_id desc', $limit = null)
|
||||
{
|
||||
$check_condition = array_column($condition, 2, 0);
|
||||
$site_id = $check_condition['site_id'] ?? '';
|
||||
$app_module = $check_condition['app_module'] ?? '';
|
||||
if ($site_id === '') {
|
||||
return $this->error('', 'REQUEST_SITE_ID');
|
||||
}
|
||||
if ($app_module === '') {
|
||||
return $this->error('', 'REQUEST_APP_MODULE');
|
||||
}
|
||||
|
||||
$list = model('group')->getList($condition, $field, $order, '', '', '', $limit);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取管理组分页列表
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getGroupPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'create_time desc, group_id desc', $field = '*')
|
||||
{
|
||||
$check_condition = array_column($condition, 2, 0);
|
||||
$site_id = $check_condition['site_id'] ?? '';
|
||||
$app_module = $check_condition['app_module'] ?? '';
|
||||
if ($site_id === '') {
|
||||
return $this->error('', 'REQUEST_SITE_ID');
|
||||
}
|
||||
if ($app_module === '') {
|
||||
return $this->error('', 'REQUEST_APP_MODULE');
|
||||
}
|
||||
|
||||
$list = model('group')->pageList($condition, $field, $order, $page, $page_size);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/*****************************************用户组管理结束****************************************************************************/
|
||||
|
||||
}
|
||||
159
app/model/system/H5.php
Executable file
159
app/model/system/H5.php
Executable file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use app\model\web\Config;
|
||||
|
||||
class H5 extends BaseModel
|
||||
{
|
||||
private $h5_domain = __ROOT__ . '/h5';
|
||||
|
||||
public function refresh()
|
||||
{
|
||||
try {
|
||||
$h5_template_path = 'public/h5/default'; // h5模板文件目录
|
||||
$h5_path = 'h5'; // h5端生成目录
|
||||
if (!is_dir($h5_template_path) || count(scandir($h5_template_path)) <= 2) {
|
||||
return $this->error('', '未查找到h5模板');
|
||||
}
|
||||
|
||||
if (is_dir($h5_path)) {
|
||||
// 先将之前的文件删除
|
||||
if (count(scandir($h5_path)) > 2) deleteDir($h5_path);
|
||||
} else {
|
||||
// 创建H5目录
|
||||
mkdir($h5_path, intval('0777', 8), true);
|
||||
}
|
||||
$this->copyFile($h5_template_path, $h5_path);
|
||||
file_put_contents($h5_path . '/refresh.log', time());
|
||||
return $this->success();
|
||||
} catch ( \Exception $e ) {
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 独立部署下载
|
||||
* @return array
|
||||
*/
|
||||
function downloadH5Separate($domain_name)
|
||||
{
|
||||
$this->h5_domain = $domain_name;
|
||||
|
||||
$h5_template_path = 'public/h5/separate'; // h5模板文件目录
|
||||
if (!is_dir($h5_template_path) || count(scandir($h5_template_path)) <= 2) {
|
||||
return $this->error('', '未查找到h5模板');
|
||||
}
|
||||
|
||||
$source_file_path = 'upload/temp/h5';
|
||||
if (is_dir($source_file_path)) {
|
||||
// 先将之前的文件删除
|
||||
if (count(scandir($source_file_path)) > 2) deleteDir($source_file_path);
|
||||
} else {
|
||||
// 创建H5目录
|
||||
mkdir($source_file_path, intval('0777', 8), true);
|
||||
}
|
||||
$this->copyFile($h5_template_path, $source_file_path);
|
||||
$file_arr = getFileMap($source_file_path);
|
||||
|
||||
if (!empty($file_arr)) {
|
||||
$zipname = 'h5_' . date('Ymd') . '.zip';
|
||||
|
||||
$zip = new \ZipArchive();
|
||||
$res = $zip->open($zipname, \ZipArchive::CREATE);
|
||||
if ($res === TRUE) {
|
||||
foreach ($file_arr as $file_path => $file_name) {
|
||||
if (is_dir($file_path)) {
|
||||
$file_path = str_replace($source_file_path . '/', '', $file_path);
|
||||
$zip->addEmptyDir($file_path);
|
||||
} else {
|
||||
$zip_path = str_replace($source_file_path . '/', '', $file_path);
|
||||
$zip->addFile($file_path, $zip_path);
|
||||
}
|
||||
}
|
||||
$zip->close();
|
||||
|
||||
header("Content-Type: application/zip");
|
||||
header("Content-Transfer-Encoding: Binary");
|
||||
header("Content-Length: " . filesize($zipname));
|
||||
header("Content-Disposition: attachment; filename=\"" . basename($zipname) . "\"");
|
||||
readfile($zipname);
|
||||
@unlink($zipname);
|
||||
deleteDir($source_file_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function copyFile($source_path, $to_path = '')
|
||||
{
|
||||
$files = scandir($source_path);
|
||||
foreach ($files as $path) {
|
||||
if ($path != '.' && $path != '..') {
|
||||
$temp_path = $source_path . '/' . $path;
|
||||
if (is_dir($temp_path)) {
|
||||
mkdir($to_path . '/' . $path, intval('0777', 8), true);
|
||||
$this->copyFile($temp_path, $to_path . '/' . $path);
|
||||
} else {
|
||||
if (file_exists($temp_path)) {
|
||||
if (preg_match("/(index.)(\w{8})(.js)$/", $temp_path)) {
|
||||
$content = file_get_contents($temp_path);
|
||||
$content = $this->paramReplace($content);
|
||||
file_put_contents($to_path . '/' . $path, $content);
|
||||
} else {
|
||||
copy($temp_path, $to_path . '/' . $path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数替换
|
||||
* @param $site_id
|
||||
* @param $string
|
||||
* @return null|string|string[]
|
||||
*/
|
||||
private function paramReplace($string)
|
||||
{
|
||||
$api_model = new Api();
|
||||
$api_config = $api_model->getApiConfig()['data'];
|
||||
|
||||
$web_config_model = new Config();
|
||||
$web_config = $web_config_model->getMapConfig();
|
||||
$web_config = $web_config['data']['value'];
|
||||
|
||||
$socket_url = (strstr(__ROOT__, 'https://') === false ? str_replace('http', 'ws', __ROOT__) : str_replace('https', 'wss', __ROOT__)) . '/wss';
|
||||
|
||||
$patterns = [
|
||||
'/\{\{\$baseUrl\}\}/',
|
||||
'/\{\{\$imgDomain\}\}/',
|
||||
'/\{\{\$h5Domain\}\}/',
|
||||
'/\{\{\$mpKey\}\}/',
|
||||
'/\{\{\$apiSecurity\}\}/',
|
||||
'/\{\{\$publicKey\}\}/',
|
||||
'/\{\{\$webSocket\}\}/'
|
||||
];
|
||||
$replacements = [
|
||||
__ROOT__,
|
||||
__ROOT__,
|
||||
$this->h5_domain,
|
||||
$web_config['tencent_map_key'] ?? '',
|
||||
$api_config['is_use'] ?? 0,
|
||||
$api_config['value']['public_key'] ?? '',
|
||||
$socket_url
|
||||
];
|
||||
$string = preg_replace($patterns, $replacements, $string);
|
||||
return $string;
|
||||
}
|
||||
|
||||
}
|
||||
375
app/model/system/Menu.php
Executable file
375
app/model/system/Menu.php
Executable file
@@ -0,0 +1,375 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use think\facade\Cache;
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 菜单表
|
||||
* @author Administrator
|
||||
*
|
||||
*/
|
||||
class Menu extends BaseModel
|
||||
{
|
||||
public $list = [];
|
||||
|
||||
/***************************************** 系统菜单开始*****************************************************************************/
|
||||
/**
|
||||
* 获取菜单列表
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
* @param string $order
|
||||
* @param null $limit
|
||||
* @return array
|
||||
*/
|
||||
public function getMenuList($condition = [], $field = 'id, app_module, title, name, parent, level, url, is_show, sort, is_icon, picture, picture_select, is_control, type', $order = '', $limit = null)
|
||||
{
|
||||
$list = model('menu')->getList($condition, $field, $order, '', '', '', $limit);
|
||||
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单数量
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function getMenuCount($condition)
|
||||
{
|
||||
$count = model('menu')->getCount($condition);
|
||||
return $this->success($count);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单树
|
||||
* @param int $level
|
||||
* @return array
|
||||
*/
|
||||
public function menuTree($level = 0)
|
||||
{
|
||||
$condition = [];
|
||||
if ($level > 0) {
|
||||
$condition = [
|
||||
[ 'level', 'elt', $level ]
|
||||
];
|
||||
}
|
||||
$list = $this->getMenuList($condition, 'id, app_module, title, name, parent, level, url, is_show, sort, is_icon, picture, picture_select, is_control, type', 'sort asc');
|
||||
$tree = list_to_tree($list[ 'data' ], 'menu_id', 'parent', 'child_list');
|
||||
return $this->success($tree);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过主键获取菜单信息
|
||||
* @param $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getMenuInfo($condition, $field = 'id, app_module, name, title, parent, level, url, is_show, sort, `desc`, picture, is_icon, picture_select, is_control, addon, type')
|
||||
{
|
||||
$menu_info = model('menu')->getInfo($condition, $field);
|
||||
return $this->success($menu_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取第一个菜单信息
|
||||
* @param $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getFirstMenuInfo($condition, $field = 'id, app_module, name, title, parent, level, url, is_show, sort, `desc`, picture, is_icon, picture_select, is_control, addon, type')
|
||||
{
|
||||
$info = model('menu')->getFirstData($condition, $field, 'sort asc');
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过url和端口查询对应菜单信息
|
||||
* @param $url
|
||||
* @param $app_module
|
||||
* @param string $addon
|
||||
* @return array
|
||||
*/
|
||||
public function getMenuInfoByUrl($url, $app_module, $addon = '')
|
||||
{
|
||||
$info = model('menu')->getFirstData([ [ 'url', "=", $url ], [ 'app_module', "=", $app_module ] ], 'id, app_module, name, title, parent, level, url, is_show, sort, `desc`, picture, is_icon, picture_select, is_control, addon, type', 'level desc');
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新菜单
|
||||
* @param $app_module
|
||||
* @param $addon
|
||||
* @return array
|
||||
*/
|
||||
public function refreshMenu($app_module, $addon)
|
||||
{
|
||||
try {
|
||||
|
||||
if (empty($addon)) {
|
||||
$tree_name = 'config/menu_' . $app_module . '.php';
|
||||
} else {
|
||||
$tree_name = 'addon/' . $addon . '/config/menu_' . $app_module . '.php';
|
||||
}
|
||||
|
||||
model('menu')->delete([ [ 'app_module', "=", $app_module ], [ 'addon', "=", $addon ] ]);
|
||||
|
||||
if(!is_file(root_path().'/'.$tree_name)){
|
||||
return $this->success();
|
||||
}
|
||||
$tree = require $tree_name;
|
||||
|
||||
$list = $this->getAddonMenuList($tree, $app_module, $addon);
|
||||
if (!empty($list)) {
|
||||
$res = model('menu')->addList($list);
|
||||
return $this->success($res);
|
||||
} else {
|
||||
return $this->success();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return $this->error(['file' => $e->getFile(), 'line' => $e->getLine(), 'message' => $e->getMessage()], $e->getMessage());
|
||||
// halt($list);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新收银端权限
|
||||
* @param $addon
|
||||
* @return array
|
||||
*/
|
||||
public function refreshCashierAuth($addon)
|
||||
{
|
||||
$tree_name = 'addon/' . $addon . '/config/cashier_auth.php';
|
||||
if (!file_exists($tree_name)) return $this->error();
|
||||
|
||||
$tree = require $tree_name;
|
||||
if (!$tree) return $this->error();
|
||||
|
||||
model('cashier_auth')->delete([ [ 'addon', '=', $addon ] ]);
|
||||
|
||||
$list = [];
|
||||
$this->getCashierAuthList($tree, $addon, '', $list);
|
||||
$res = model('cashier_auth')->addList($list);
|
||||
|
||||
// 清除缓存
|
||||
Cache::clear('cashier_menu');
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取收银端权限集
|
||||
* @param $tree
|
||||
* @param $addon
|
||||
* @param string $parent
|
||||
* @param array $list
|
||||
*/
|
||||
private function getCashierAuthList($tree, $addon, $parent = '', &$list = [])
|
||||
{
|
||||
foreach ($tree as $item) {
|
||||
$children = $item[ 'children' ] ?? [];
|
||||
if (isset($item[ 'children' ])) unset($item[ 'children' ]);
|
||||
|
||||
$item = array_merge($item, [ 'addon' => $addon, 'parent' => $item[ 'parent' ] ?? $parent ]);
|
||||
ksort($item);
|
||||
array_push($list, $item);
|
||||
|
||||
if (!empty($children)) $this->getCashierAuthList($children, $addon, $item[ 'name' ], $list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新全部菜单
|
||||
*/
|
||||
public function refreshAllMenu()
|
||||
{
|
||||
$res = [];
|
||||
$shop_menu_res = $this->refreshMenu("shop", '');
|
||||
if($shop_menu_res['code'] < 0) $res['shop'] = $shop_menu_res;
|
||||
$addon_model = new Addon();
|
||||
$addon_list = $addon_model->getAddonList([], 'name');
|
||||
$addon_list = $addon_list[ 'data' ];
|
||||
foreach ($addon_list as $k_addon => $v_addon) {
|
||||
$addon_menu_res = $this->refreshMenu('shop', $v_addon[ 'name' ]);
|
||||
if($addon_menu_res['code'] < 0) $res[$v_addon['name']] = $addon_menu_res;
|
||||
}
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新店铺端菜单
|
||||
* @param $addon
|
||||
* @param string $app_module
|
||||
* @return array|int
|
||||
*/
|
||||
public function cacheMenu($addon, $app_module = 'shop')
|
||||
{
|
||||
if (!empty($addon)) {
|
||||
$tree_name = 'addon/' . $addon . '/config/menu_' . $app_module . '.php';
|
||||
} else {
|
||||
$tree_name = $addon . '/config/menu_' . $app_module . '.php';
|
||||
}
|
||||
|
||||
if (file_exists($tree_name)) {
|
||||
model('menu')->delete([ [ 'app_module', "=", $app_module ], [ 'addon', "=", $addon ] ]);
|
||||
$tree = require $tree_name;
|
||||
$list = $this->getAddonMenuList($tree, $app_module, $addon);
|
||||
if (!empty($list)) {
|
||||
$res = model('menu')->addList($list);
|
||||
return $res;
|
||||
} else {
|
||||
return $this->success();
|
||||
}
|
||||
} else {
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单
|
||||
* @param $tree
|
||||
* @param $app_module
|
||||
* @param $addon
|
||||
* @return array|\think\response\Json
|
||||
*/
|
||||
public function getAddonMenuList($tree, $app_module, $addon)
|
||||
{
|
||||
try {
|
||||
$list = [];
|
||||
if (!$tree) {
|
||||
return [];
|
||||
}
|
||||
|
||||
foreach ($tree as $k => $v) {
|
||||
$parent = '';
|
||||
if (isset($v[ 'parent' ])) {
|
||||
if ($v[ 'parent' ] == '') {
|
||||
$parent = '';
|
||||
$level = 1;
|
||||
} else {
|
||||
$parent_menu_info = model('menu')->getInfo([
|
||||
[ 'name', "=", $v[ 'parent' ] ]
|
||||
]);
|
||||
if ($parent_menu_info) {
|
||||
$parent = $parent_menu_info[ 'name' ];
|
||||
$level = $parent_menu_info[ 'level' ] + 1;
|
||||
} else {
|
||||
$level = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$parent = '';
|
||||
$level = 1;
|
||||
}
|
||||
$item = [
|
||||
'app_module' => $app_module,
|
||||
'addon' => $addon,
|
||||
'title' => $v[ 'title' ],
|
||||
'name' => $v[ 'name' ],
|
||||
'parent' => $parent,
|
||||
'level' => $level,
|
||||
'url' => $v[ 'url' ],
|
||||
'is_show' => $v['is_show'] ?? 1,
|
||||
'sort' => $v['sort'] ?? 100,
|
||||
'is_icon' => $v['is_icon'] ?? 0,
|
||||
'picture' => $v['picture'] ?? '',
|
||||
'picture_select' => $v['picture_selected'] ?? '',
|
||||
'is_control' => $v['is_control'] ?? 1,
|
||||
'desc' => $v['desc'] ?? '',
|
||||
'type' => $v['type'] ?? 'page',//页面page 按钮button
|
||||
];
|
||||
|
||||
array_push($list, $item);
|
||||
|
||||
if (isset($v[ 'child_list' ])) {
|
||||
$this->list = [];
|
||||
$this->menuTreeToList($v[ 'child_list' ], $app_module, $addon, $v[ 'name' ], $level + 1);
|
||||
$list = array_merge($list, $this->list);
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return $this->error(-1, $e->getMessage() . ",File:" . $e->getFile() . ",line:" . $e->getLine());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜单树转化为列表
|
||||
* @param $tree
|
||||
* @param $app_module
|
||||
* @param string $addon
|
||||
* @param string $parent
|
||||
* @param int $level
|
||||
*/
|
||||
private function menuTreeToList($tree, $app_module, $addon = '', $parent = '', $level = 1)
|
||||
{
|
||||
if (is_array($tree)) {
|
||||
foreach ($tree as $key => $value) {
|
||||
$item = [
|
||||
'app_module' => $app_module,
|
||||
'addon' => $addon,
|
||||
'title' => $value[ 'title' ],
|
||||
'name' => $value[ 'name' ],
|
||||
'parent' => $parent,
|
||||
'level' => $level,
|
||||
'url' => $value[ 'url' ],
|
||||
'is_show' => $value['is_show'] ?? 1,
|
||||
'sort' => $value['sort'] ?? 100,
|
||||
'is_icon' => $value['is_icon'] ?? 0,
|
||||
'picture' => $value['picture'] ?? '',
|
||||
'picture_select' => $value['picture_selected'] ?? '',
|
||||
'is_control' => $value['is_control'] ?? 1,
|
||||
'desc' => $value['desc'] ?? '',
|
||||
'type' => $value['type'] ?? 'page',
|
||||
];
|
||||
$refer = $value;
|
||||
if (isset($refer[ 'child_list' ])) {
|
||||
unset($refer[ 'child_list' ]);
|
||||
array_push($this->list, $item);
|
||||
$p_name = $refer[ 'name' ];
|
||||
$this->menuTreeToList($value[ 'child_list' ], $app_module, $addon, $p_name, $level + 1);
|
||||
} else {
|
||||
array_push($this->list, $item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空菜单表,防止自增ID越来越大
|
||||
*/
|
||||
public function truncateMenu()
|
||||
{
|
||||
$prefix = config("database")[ "connections" ][ "mysql" ][ "prefix" ];
|
||||
model('menu')->execute("TRUNCATE TABLE {$prefix}menu");
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空收银台菜单表,防止自增ID越来越大
|
||||
*/
|
||||
public function truncateCashierAuth()
|
||||
{
|
||||
$prefix = config("database")[ "connections" ][ "mysql" ][ "prefix" ];
|
||||
model('menu')->execute("TRUNCATE TABLE {$prefix}cashier_auth");
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空组件、链接表,防止自增ID越来越大
|
||||
*/
|
||||
public function truncateDiyView()
|
||||
{
|
||||
$prefix = config("database")[ "connections" ][ "mysql" ][ "prefix" ];
|
||||
model('menu')->execute("TRUNCATE TABLE {$prefix}diy_view_util");
|
||||
model('menu')->execute("TRUNCATE TABLE {$prefix}link");
|
||||
}
|
||||
|
||||
}
|
||||
659
app/model/system/Pay.php
Executable file
659
app/model/system/Pay.php
Executable file
@@ -0,0 +1,659 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use app\model\member\Member;
|
||||
use app\model\order\Config as OrderConfig;
|
||||
use app\model\order\OrderPay;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 系统配置类
|
||||
*/
|
||||
class Pay extends BaseModel
|
||||
{
|
||||
//支付状态
|
||||
const PAY_STATUS_NOT = 0;
|
||||
const PAY_STATUS_IN_PROCESS = 1;
|
||||
const PAY_STATUS_SUCCESS = 2;
|
||||
const PAY_STATUS_CANCEL = -1;
|
||||
const PAY_STATUS_CLOSE = -2;
|
||||
|
||||
public $refund_pay_type = array (
|
||||
'offline_refund_pay' => '线下退款',
|
||||
'online_refund_pay' => '原路退款'
|
||||
);
|
||||
|
||||
static function getPayStatus($key = null)
|
||||
{
|
||||
$arr = [
|
||||
[
|
||||
'id' => self::PAY_STATUS_NOT,
|
||||
'name' => '待支付',
|
||||
],
|
||||
[
|
||||
'id' => self::PAY_STATUS_IN_PROCESS,
|
||||
'name' => '支付中',
|
||||
],
|
||||
[
|
||||
'id' => self::PAY_STATUS_SUCCESS,
|
||||
'name' => '支付成功',
|
||||
],
|
||||
[
|
||||
'id' => self::PAY_STATUS_CANCEL,
|
||||
'name' => '已取消',
|
||||
],
|
||||
[
|
||||
'id' => self::PAY_STATUS_CLOSE,
|
||||
'name' => '已关闭',
|
||||
],
|
||||
];
|
||||
if(isset($arr[0][$key])){
|
||||
$arr = array_column($arr, null, $key);
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/********************************************************************支付**********************************************************/
|
||||
|
||||
/**
|
||||
* 支付
|
||||
* @param string $pay_type 支付方式
|
||||
* @param string $out_trade_no 交易号
|
||||
* @param string $app_type 请求来源类型
|
||||
* @param int $member_id 会员id
|
||||
* @param string $return_url 同步回调地址
|
||||
* @param int $is_balance 是否使用余额
|
||||
* @param int $scene 场景值
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function pay($pay_type, $out_trade_no, $app_type, $member_id, $return_url = null, $is_balance = 0, $scene = 0)
|
||||
{
|
||||
$data = $this->getPayInfo($out_trade_no)[ 'data' ];
|
||||
if (empty($data)) return $this->error('', '未获取到支付信息');
|
||||
if ($data[ 'pay_status' ] == self::PAY_STATUS_SUCCESS) return $this->success(['pay_success' => 1]);
|
||||
if ($data['pay_status'] == self::PAY_STATUS_CLOSE) return $this->error(null, '支付单已关闭');
|
||||
|
||||
$notify_url = addon_url('pay/pay/notify');
|
||||
if (empty($return_url)) {
|
||||
$return_url = addon_url('pay/pay/payreturn');
|
||||
}
|
||||
|
||||
// 是否使用余额
|
||||
if ($is_balance) {
|
||||
$data[ 'member_id' ] = $member_id;
|
||||
$use_res = $this->useBalance($data)[ 'data' ];
|
||||
if (isset($use_res[ 'pay_success' ])) return $this->success($use_res);
|
||||
$data = $this->getPayInfo($out_trade_no)[ 'data' ];
|
||||
}
|
||||
|
||||
$data[ 'app_type' ] = $app_type;
|
||||
$data[ 'notify_url' ] = $notify_url;
|
||||
$data[ 'return_url' ] = $return_url;
|
||||
$data[ 'pay_type' ] = $pay_type;
|
||||
$data[ 'member_id' ] = $member_id;
|
||||
$data[ 'scene' ] = $scene;
|
||||
$res = event('Pay', $data, true);
|
||||
if (empty($res)) return $this->error('', '没有可用的支付方式');
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建支付流水号
|
||||
* @param int $member_id
|
||||
* @return string
|
||||
*/
|
||||
public function createOutTradeNo($member_id = 0)
|
||||
{
|
||||
$cache = Cache::get('pay_out_trade_no' . $member_id . time());
|
||||
if (empty($cache)) {
|
||||
Cache::set('pay_out_trade_no' . $member_id . time(), 1000);
|
||||
$cache = Cache::get('pay_out_trade_no' . $member_id . time());
|
||||
} else {
|
||||
$cache = $cache + 1;
|
||||
Cache::set('pay_out_trade_no' . $member_id . time(), $cache);
|
||||
}
|
||||
$no = time() . rand(1000, 9999) . $member_id . $cache;
|
||||
return $no;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加支付信息
|
||||
* @param int $site_id //站点id 默认平台配置为0
|
||||
* @param string $out_trade_no 交易流水号
|
||||
* @param string $app_type 支付端口类型
|
||||
* @param int $pay_type 支付方式,默认为空
|
||||
* @param string $pay_body 支付主体
|
||||
* @param string $pay_detail 支付细节
|
||||
* @param double $pay_money 支付金额
|
||||
* @param string $pay_no 支付账号
|
||||
* @param string $notify_url 要求的异步回调网址,实际支付后会进行执行或者回调,可以是事件或者域名
|
||||
* @param string $return_url 同步回调网址,知己支付后会进行同步回调
|
||||
*/
|
||||
public function addPay($site_id, $out_trade_no, $pay_type, $pay_body, $pay_detail, $pay_money, $pay_no, $notify_url, $return_url, $relate_id = '', $member_id = 0)
|
||||
{
|
||||
$data = array (
|
||||
'site_id' => $site_id,
|
||||
'out_trade_no' => $out_trade_no,
|
||||
'pay_body' => $pay_body,
|
||||
'pay_detail' => $pay_detail,
|
||||
'pay_money' => $pay_money,
|
||||
'pay_no' => $pay_no,
|
||||
'event' => $notify_url,
|
||||
'return_url' => $return_url,
|
||||
'pay_status' => 0,
|
||||
'create_time' => time(),
|
||||
'relate_id' => $relate_id,
|
||||
'member_id' => $member_id,
|
||||
);
|
||||
model('pay')->add($data);
|
||||
$result = $this->success();
|
||||
if ($pay_money == 0) {
|
||||
$result = $this->onlinePay($out_trade_no, $pay_type, '', '');
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在线支付
|
||||
* @param $out_trade_no
|
||||
* @param $pay_type
|
||||
* @param $trade_no
|
||||
* @param $pay_addon
|
||||
* @param array $log_data
|
||||
* @return array|mixed|void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function onlinePay($out_trade_no, $pay_type, $trade_no, $pay_addon, $log_data = [])
|
||||
{
|
||||
Log::write("在线支付_onlinePay_" . $out_trade_no);
|
||||
$pay_type = empty($pay_type) ? 'ONLINE_PAY' : $pay_type;
|
||||
$pay_info = $this->getPayInfo($out_trade_no)['data'];
|
||||
if(empty($pay_info)) return $this->error(null, '支付信息缺失');
|
||||
|
||||
//根据不同的状态执行不同的业务
|
||||
switch($pay_info[ 'pay_status' ]){
|
||||
case self::PAY_STATUS_NOT:
|
||||
case self::PAY_STATUS_IN_PROCESS:
|
||||
case self::PAY_STATUS_CANCEL:
|
||||
$data = array (
|
||||
'trade_no' => $trade_no,
|
||||
'pay_type' => $pay_type,
|
||||
'pay_addon' => $pay_addon,
|
||||
'pay_time' => time(),
|
||||
'pay_status' => self::PAY_STATUS_SUCCESS
|
||||
);
|
||||
$res = model('pay')->update($data, [['out_trade_no', '=', $out_trade_no]]);
|
||||
if(!$res){
|
||||
Log::write("在线支付更新pay失败_" . $out_trade_no);
|
||||
return $this->error(null, '支付单据更新失败');
|
||||
}
|
||||
|
||||
return $this->onlinePayEvent($pay_info['id'], $log_data, 1);
|
||||
break;
|
||||
case self::PAY_STATUS_SUCCESS:
|
||||
return $this->success();
|
||||
break;
|
||||
case self::PAY_STATUS_CLOSE:
|
||||
//退款
|
||||
$refund_no = $this->createRefundNo();
|
||||
return $this->refund($refund_no, $pay_info['pay_money'], $pay_info['out_trade_no'], '重复支付退款', $pay_info['pay_money'], $pay_info['site_id'], 1, 0, 0);
|
||||
break;
|
||||
default:
|
||||
return $this->error(null, '支付状态有误');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param array $log_data
|
||||
* @return array|mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function onlinePayEvent($id, $log_data = [], $execute_num = 1)
|
||||
{
|
||||
$pay_info = model('pay')->getInfo([['id', '=', $id]]);
|
||||
$return_data = [
|
||||
'out_trade_no' => $pay_info['out_trade_no'],
|
||||
'trade_no' => $pay_info['trade_no'],
|
||||
'pay_type' => $pay_info['pay_type'],
|
||||
'log_data' => $log_data,
|
||||
];
|
||||
|
||||
$res = $this->success();
|
||||
if (strpos($pay_info[ 'event' ], 'http://') !== 0 || strpos($pay_info[ 'event' ], 'https://') !== 0) {
|
||||
$event_res_arr = event($pay_info[ 'event' ], $return_data);
|
||||
foreach($event_res_arr as $event_res){
|
||||
if(isset($event_res['code']) && $event_res['code'] < 0){
|
||||
$pay_json = json_encode($pay_info['pay_json'], true);
|
||||
if(!is_array($pay_json)) $pay_json = [];
|
||||
$pay_json['event_res'] = $event_res;
|
||||
model('pay')->update(['pay_json' => json_encode($pay_json, JSON_UNESCAPED_UNICODE)], [['out_trade_no', '=', $pay_info['out_trade_no']]]);
|
||||
Log::write("支付回调event失败");
|
||||
Log::write(['pay_info' => $pay_info, 'return_data' => $return_data, 'event_res' => $event_res]);
|
||||
$res = $event_res;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
http($pay_info[ 'event' ], 1);
|
||||
}
|
||||
if(in_array($pay_info['pay_type'], ['wechatpay','alipay']) && $res['code'] < 0){
|
||||
if($execute_num < 3){
|
||||
sleep(3);
|
||||
return $this->onlinePayEvent($pay_info, $return_data, $execute_num+1);
|
||||
}else if($execute_num == 3){
|
||||
//如果执行3次以后还是失败,那就定时任务1分钟后再执行,如果依然失败就不再继续
|
||||
(new Cron())->addCron(1, 0, "支付回调", "OnlinePayEvent", time() + 60, $id);
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭支付
|
||||
* @param $out_trade_no
|
||||
* @return array|mixed
|
||||
* @throws \think\db\exception\DbException
|
||||
*/
|
||||
public function closePay($out_trade_no)
|
||||
{
|
||||
$pay_info = $this->getPayInfo($out_trade_no)['data'];
|
||||
if(empty($pay_info)) return $this->error(null, '支付信息不存在');
|
||||
if($pay_info['pay_status'] == self::PAY_STATUS_CLOSE) return $this->success();
|
||||
if($pay_info['pay_status'] == self::PAY_STATUS_SUCCESS) return $this->error(null, '已支付单据不可关闭');
|
||||
|
||||
$event_res = event('PayClose', $pay_info);
|
||||
foreach ($event_res as $v) {
|
||||
if (isset($v[ 'code' ]) && $v[ 'code' ] < 0) {
|
||||
return $v;
|
||||
}
|
||||
}
|
||||
|
||||
model('pay')->startTrans();
|
||||
try{
|
||||
// 冻结中的余额返还
|
||||
if ($pay_info[ 'member_id' ]) {
|
||||
if ($pay_info[ 'balance' ]) model('member')->setDec([['site_id', '=', $pay_info[ 'site_id' ]], ['member_id', '=', $pay_info[ 'member_id' ]]], 'balance_lock', $pay_info[ 'balance' ]);
|
||||
if ($pay_info[ 'balance_money' ]) model('member')->setDec([['site_id', '=', $pay_info[ 'site_id' ]], ['member_id', '=', $pay_info[ 'member_id' ]]], 'balance_money_lock', $pay_info[ 'balance_money' ]);
|
||||
}
|
||||
$res = model('pay')->update(['pay_status' => self::PAY_STATUS_CLOSE], [['out_trade_no', '=', $out_trade_no]]);
|
||||
if ($res === false) {
|
||||
model('pay')->rollback();
|
||||
return $this->error(null, '数据修改失败');
|
||||
}
|
||||
|
||||
model('pay')->commit();
|
||||
return $this->success();
|
||||
}catch(\Exception $e){
|
||||
model('pay')->rollback();
|
||||
return $this->error(null, $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新生成新的pay支付记录
|
||||
* @param $out_trade_no
|
||||
* @param $pay_money
|
||||
* @return array|mixed|void
|
||||
*/
|
||||
public function rewritePay($out_trade_no, $pay_money)
|
||||
{
|
||||
$pay_info_result = $this->getPayInfo($out_trade_no);
|
||||
$pay_info = $pay_info_result[ 'data' ];
|
||||
//支付状态 (未支付 未取消)
|
||||
if ($pay_info[ 'pay_status' ] == self::PAY_STATUS_NOT) {
|
||||
// if (!empty($pay_info[ 'pay_type' ])) {
|
||||
$close_result = event('payClose', $pay_info, true);
|
||||
if (!empty($close_result[ 'code' ]) && $close_result[ 'code' ] < 0) {
|
||||
return $close_result;
|
||||
}
|
||||
// }
|
||||
$new_out_trade_no = $this->createOutTradeNo();
|
||||
$data = array (
|
||||
'out_trade_no' => $new_out_trade_no,
|
||||
'pay_money' => $pay_money
|
||||
);
|
||||
$res = model('pay')->update($data, [['out_trade_no', '=', $out_trade_no]]);
|
||||
if ($res === false) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
} else {
|
||||
|
||||
return $this->success($new_out_trade_no);
|
||||
}
|
||||
} else if ($pay_info[ 'pay_status' ] == self::PAY_STATUS_CANCEL) {
|
||||
$new_out_trade_no = $this->createOutTradeNo();
|
||||
$data = array (
|
||||
'out_trade_no' => $new_out_trade_no,
|
||||
'pay_money' => $pay_money,
|
||||
'pay_status' => self::PAY_STATUS_NOT
|
||||
);
|
||||
$res = model('pay')->update($data, [['out_trade_no', '=', $out_trade_no]]);
|
||||
return $this->success($new_out_trade_no);
|
||||
} else {
|
||||
return $this->error([], '当前支付已完成');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付绑定商户信息
|
||||
* @param $out_trade_no
|
||||
* @param $json_data
|
||||
*/
|
||||
public function clearMchPay($out_trade_no, $curr_pay_type)
|
||||
{
|
||||
//如果当前方式与之前发起的支付方式不同则要关闭旧的支付,防止一个支付单不同的支付方式都支付成功
|
||||
$pay_info = $this->getPayInfo($out_trade_no)['data'];
|
||||
$mch_info = json_decode($pay_info['mch_info'], true);
|
||||
$bind_pay_type = $mch_info['pay_type'] ?? '';
|
||||
if(!empty($bind_pay_type) && $bind_pay_type != $curr_pay_type){
|
||||
$event_res = event('PayClose', $pay_info);
|
||||
foreach ($event_res as $v) {
|
||||
if (isset($v[ 'code' ]) && $v[ 'code' ] < 0) {
|
||||
return $this->error($v, '有其他方式正在支付中,请稍后再试');
|
||||
}
|
||||
}
|
||||
}
|
||||
model('pay')->update(['mch_info' => ''], [['out_trade_no', '=', $out_trade_no]]);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付绑定商户信息
|
||||
* @param $out_trade_no
|
||||
* @param $json_data
|
||||
*/
|
||||
public function bindMchPay($out_trade_no, $json_data)
|
||||
{
|
||||
$res = model('pay')->update([
|
||||
'mch_info' => json_encode($json_data, JSON_UNESCAPED_UNICODE),
|
||||
], [['out_trade_no', '=', $out_trade_no]]);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支付方式
|
||||
* @param array $params 'pay_scene' => ['wap', 'wechat', 'app', 'pc', 'wechat_applet']
|
||||
* @return array
|
||||
*/
|
||||
public function getPayType($params = [])
|
||||
{
|
||||
$res = event('PayType', $params);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支付信息详情
|
||||
* @param $out_trade_no
|
||||
* @return array
|
||||
*/
|
||||
public function getPayInfo($out_trade_no)
|
||||
{
|
||||
$condition = [['out_trade_no', '=', $out_trade_no]];
|
||||
return $this->getInfo($condition, '*');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支付信息
|
||||
* @param $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getInfo($condition, $field = '*')
|
||||
{
|
||||
$info = model('pay')->setIsCache(0)->getInfo($condition, $field);
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付记录
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getPayPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
|
||||
{
|
||||
$list = model('pay')->pageList($condition, $field, $order, $page, $page_size);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付统计
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function getPayStatistics($condition)
|
||||
{
|
||||
$statistics_array = array (
|
||||
'count' => model('pay')->getCount($condition),
|
||||
'sum_money' => model('pay')->getSum($condition, 'pay_money')
|
||||
);
|
||||
return $statistics_array;
|
||||
}
|
||||
|
||||
/****************************************************************退款**************************************************************/
|
||||
|
||||
/**
|
||||
* 创建退款流水号
|
||||
*/
|
||||
public function createRefundNo()
|
||||
{
|
||||
$cache = Cache::get('pay_refund_out_trade_no' . time());
|
||||
if (empty($cache)) {
|
||||
Cache::set('niutk' . time(), 1000);
|
||||
$cache = Cache::get('pay_refund_out_trade_no' . time());
|
||||
} else {
|
||||
$cache = $cache + 1;
|
||||
Cache::set('pay_refund_out_trade_no' . time(), $cache);
|
||||
}
|
||||
$no = date('Ymdhis', time()) . rand(1000, 9999) . $cache;
|
||||
return $no;
|
||||
}
|
||||
|
||||
/**
|
||||
* 原路退款
|
||||
* @param $refund_no
|
||||
* @param $refund_fee
|
||||
* @param $out_trade_no
|
||||
* @param $refund_desc
|
||||
* @param number $total_fee 实际支付金额
|
||||
* @param $site_id
|
||||
* @param int $refund_type 退款方式 1 原路退款 2 线下支付
|
||||
* @param int $order_goods_id
|
||||
* @param int $is_video_number
|
||||
* @return array|mixed|void
|
||||
*/
|
||||
public function refund($refund_no, $refund_fee, $out_trade_no, $refund_desc, $total_fee, $site_id, $refund_type, $order_goods_id = 0, $is_video_number = 0)
|
||||
{
|
||||
//是否是原理退款方式退款
|
||||
if ($refund_type == 1) {
|
||||
$pay_info_result = $this->getPayInfo($out_trade_no);
|
||||
$pay_info = $pay_info_result[ 'data' ];
|
||||
if (empty($pay_info))
|
||||
return $this->error('', '付款记录不存在!');
|
||||
|
||||
$data = array (
|
||||
'refund_no' => $refund_no,
|
||||
'refund_fee' => $refund_fee,
|
||||
'refund_desc' => $refund_desc,
|
||||
'pay_info' => $pay_info,
|
||||
'total_fee' => $total_fee,
|
||||
'site_id' => $site_id,
|
||||
'order_goods_id' => $order_goods_id,
|
||||
'is_video_number' => $is_video_number,
|
||||
'out_aftersale_id' => 0
|
||||
);
|
||||
|
||||
if (!empty($order_goods_id)) {
|
||||
$order_goods_info = model('order_goods')->getInfo([['order_goods_id', '=', $order_goods_id]]);
|
||||
if (!empty($order_goods_info)) {
|
||||
$data[ 'out_aftersale_id' ] = $order_goods_info[ 'out_aftersale_id' ];
|
||||
}
|
||||
}
|
||||
//退款金额许大于0
|
||||
if ($refund_fee > 0 && !in_array($pay_info[ 'pay_type' ], ['offlinepay', 'BALANCE', 'ONLINE_PAY'])) {
|
||||
$result = event('PayRefund', $data, true);
|
||||
if (empty($result))
|
||||
return $this->error('', '找不到可用的退款方式!');
|
||||
|
||||
if ($result[ 'code' ] < 0)
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
$refund_data = array (
|
||||
'refund_no' => $refund_no,
|
||||
'refund_fee' => $refund_fee,
|
||||
'total_money' => $total_fee,
|
||||
'refund_type' => $refund_type,
|
||||
'site_id' => $site_id,
|
||||
'out_trade_no' => $out_trade_no,
|
||||
);
|
||||
$this->addRefundPay($refund_data);
|
||||
return $this->success();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加退款记录
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function addRefundPay($data)
|
||||
{
|
||||
$data[ 'create_time' ] = time();
|
||||
$data[ 'refund_detail' ] = '支付交易号:' . $data[ 'out_trade_no' ] . ',退款金额:' . $data[ 'refund_fee' ] . '元';
|
||||
$res = model('pay_refund')->add($data);
|
||||
if ($res == false) {
|
||||
return $this->error($res);
|
||||
}
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询转账方式
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function getTransferType($site_id)
|
||||
{
|
||||
$data = array (
|
||||
'bank' => '银行卡'
|
||||
);
|
||||
$temp_array = event('TransferType', ['site_id' => $site_id]);
|
||||
|
||||
if (!empty($temp_array)) {
|
||||
foreach ($temp_array as $k => $v) {
|
||||
$data[ $v[ 'type' ] ] = $v[ 'type_name' ];
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用余额
|
||||
* @param $pay_info
|
||||
* @return array|mixed|void
|
||||
*/
|
||||
public function useBalance($pay_info)
|
||||
{
|
||||
// 查询是否可使用余额
|
||||
$balance_config = (new OrderConfig())->getBalanceConfig($pay_info[ 'site_id' ])[ 'data' ][ 'value' ];
|
||||
if (!$balance_config[ 'balance_show' ]) return $this->success();
|
||||
|
||||
// 查询会员当前可用余额
|
||||
$balance_data = (new Member())->getMemberUsableBalance($pay_info[ 'site_id' ], $pay_info[ 'member_id' ]);
|
||||
if ($balance_data[ 'code' ] != 0) return $balance_data;
|
||||
$balance_data = $balance_data[ 'data' ];
|
||||
if ($balance_data[ 'usable_balance' ] <= 0) return $this->success();
|
||||
|
||||
$data = [
|
||||
'pay_money' => $pay_info[ 'pay_money' ],
|
||||
'member_id' => $pay_info[ 'member_id' ]
|
||||
];
|
||||
|
||||
if ($balance_data[ 'balance' ] > 0) {
|
||||
$data[ 'balance' ] = bccomp($balance_data[ 'balance' ], $data[ 'pay_money' ], 2) == 1 ? $data[ 'pay_money' ] : $balance_data[ 'balance' ];
|
||||
$data[ 'pay_money' ] -= $data[ 'balance' ];
|
||||
}
|
||||
if ($balance_data[ 'balance_money' ] > 0 && $data[ 'pay_money' ] > 0) {
|
||||
$data[ 'balance_money' ] = bccomp($balance_data[ 'balance_money' ], $data[ 'pay_money' ], 2) == 1 ? $data[ 'pay_money' ] : $balance_data[ 'balance_money' ];
|
||||
$data[ 'pay_money' ] -= $data[ 'balance_money' ];
|
||||
}
|
||||
|
||||
model('pay')->startTrans();
|
||||
try {
|
||||
model('pay')->update($data, [['out_trade_no', '=', $pay_info[ 'out_trade_no' ]]]);
|
||||
if (isset($data[ 'balance' ]) && $data[ 'balance' ] > 0) model('member')->setInc([['site_id', '=', $pay_info[ 'site_id' ]], ['member_id', '=', $pay_info[ 'member_id' ]]], 'balance_lock', $data[ 'balance' ]);
|
||||
if (isset($data[ 'balance_money' ]) && $data[ 'balance_money' ] > 0) model('member')->setInc([['site_id', '=', $pay_info[ 'site_id' ]], ['member_id', '=', $pay_info[ 'member_id' ]]], 'balance_money_lock', $data[ 'balance_money' ]);
|
||||
|
||||
if ($data[ 'pay_money' ] == 0) {
|
||||
$res = $this->onlinePay($pay_info[ 'out_trade_no' ], 'BALANCE', '', '');
|
||||
if ($res[ 'code' ] != 0) {
|
||||
model('pay')->rollback();
|
||||
return $res;
|
||||
}
|
||||
model('pay')->commit();
|
||||
return $this->success(['pay_success' => 1]);
|
||||
}
|
||||
model('pay')->commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
model('pay')->rollback();
|
||||
return $this->error('', '支付冻结余额错误');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置支付
|
||||
* @param $params
|
||||
* @return array|mixed|void
|
||||
*/
|
||||
public function resetPay($params)
|
||||
{
|
||||
$out_trade_no = $params[ 'out_trade_no' ];
|
||||
$pay_info = $this->getPayInfo($out_trade_no)[ 'data' ] ?? [];
|
||||
if (empty($pay_info))
|
||||
return $this->error();
|
||||
$result = event('PayReset', $pay_info, true);//各种插件自己实现
|
||||
if (empty($result)) {
|
||||
switch ($pay_info[ 'event' ]) {
|
||||
case 'OrderPayNotify':
|
||||
$order_pay_model = new OrderPay();
|
||||
$result = $order_pay_model->resetOrderTradeNo(['out_trade_no' => $out_trade_no]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($result[ 'code' ] < 0)
|
||||
return $result;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付编辑(切勿调用,收银业务专用)
|
||||
* @param $data
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function edit($data, $condition)
|
||||
{
|
||||
model('pay')->update($data, $condition);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
}
|
||||
179
app/model/system/PayBalance.php
Executable file
179
app/model/system/PayBalance.php
Executable file
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use addon\cashier\model\order\CashierOrderPay;
|
||||
use app\model\BaseModel;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 会员付款码
|
||||
* Class PayBalance
|
||||
* @package app\model\system
|
||||
*/
|
||||
class PayBalance extends BaseModel
|
||||
{
|
||||
/**
|
||||
* 创建会员码生成记录
|
||||
* @param $param
|
||||
* @return array
|
||||
*/
|
||||
public function create($param)
|
||||
{
|
||||
model('pay_balance')->startTrans();
|
||||
try {
|
||||
$data = [
|
||||
'auth_code' => $this->createAuthCode($param[ 'member_id' ]),
|
||||
'site_id' => $param[ 'site_id' ],
|
||||
'member_id' => $param[ 'member_id' ],
|
||||
'create_time' => time(),
|
||||
'expire_time' => time() + 120,
|
||||
'dynamic_code' => rand(1000, 9999)
|
||||
];
|
||||
// 生成前将其他的失效
|
||||
model('pay_balance')->delete([ [ 'site_id', '=', $param[ 'site_id' ] ], [ 'member_id', '=', $param[ 'member_id' ] ] ]);
|
||||
$res = model('pay_balance')->add($data);
|
||||
// 提交事务
|
||||
model('pay_balance')->commit();
|
||||
|
||||
$barcode = getBarcode($data[ 'auth_code' ], '', 3);
|
||||
$qrcode = qrcode($data[ 'auth_code' ], 'upload/qrcode/pay/', $data[ 'auth_code' ], 16);
|
||||
|
||||
$return = [
|
||||
'auth_code' => $data[ 'auth_code' ],
|
||||
'barcode' => 'data:image/png;base64,' . base64_encode(file_get_contents($barcode)),
|
||||
'qrcode' => 'data:image/png;base64,' . base64_encode(file_get_contents($qrcode)),
|
||||
'expire_time' => $data[ 'expire_time' ],
|
||||
'dynamic_code' => $data[ 'dynamic_code' ]
|
||||
];
|
||||
// 删除
|
||||
@unlink($barcode);
|
||||
@unlink($qrcode);
|
||||
return $this->success($return);
|
||||
} catch (\Exception $e) {
|
||||
model('pay_balance')->rollback();
|
||||
Log::write('付款码生成失败:' . $e->getMessage() . $e->getFile() . $e->getLine());
|
||||
return $this->error('', '付款码生成失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 付款码支付
|
||||
* @param $auth_code
|
||||
* @param $out_trade_no
|
||||
* @return array
|
||||
*/
|
||||
public function pay($auth_code, $out_trade_no)
|
||||
{
|
||||
$pay_info = model('pay')->getInfo([ [ 'out_trade_no', '=', $out_trade_no ] ]);
|
||||
|
||||
if (empty($pay_info)) return $this->error('', '未获取到支付单据');
|
||||
if ($pay_info[ 'pay_status' ] != 0) return $this->error('', '支付单据状态异常');
|
||||
$pay_info[ 'pay_json' ] = !empty($pay_info[ 'pay_json' ]) ? json_decode($pay_info[ 'pay_json' ], true) : [];
|
||||
|
||||
$member_id = $pay_info[ 'pay_json' ][ 'member_id' ] ?? 0;
|
||||
$site_id = $pay_info[ 'site_id' ];
|
||||
|
||||
$code_info = model('pay_balance')->getInfo([ [ 'auth_code', '=', $auth_code ] ]);
|
||||
|
||||
if (empty($code_info)) return $this->error('', '付款码已失效');
|
||||
if ($code_info[ 'member_id' ] != $member_id) return $this->error('', '不是当前会员的付款码');
|
||||
if ($code_info[ 'status' ] != 0) return $this->error('', '付款码状态异常');
|
||||
if ($code_info[ 'expire_time' ] < time()) return $this->error('', '付款码已失效');
|
||||
|
||||
$member_info = model('member')->getInfo([ [ 'member_id', '=', $member_id ], [ 'site_id', '=', $site_id ], [ 'is_delete', '=', 0 ] ], 'balance,balance_money');
|
||||
if (empty($member_info)) return $this->error('', '未查找到会员信息');
|
||||
|
||||
if (bccomp($pay_info[ 'pay_money' ], ( $member_info[ 'balance' ] + $member_info[ 'balance_money' ] ), 2) == 1) return $this->error('', '余额不足');
|
||||
|
||||
model('pay_balance')->startTrans();
|
||||
|
||||
try {
|
||||
$cashier_order_pay = new CashierOrderPay();
|
||||
$cache = $cashier_order_pay->getCache($out_trade_no)[ 'data' ];
|
||||
$promotion = $cache[ 'promotion' ] ?? [];
|
||||
$promotion[ 'is_use_balance' ] = 1;
|
||||
$cache[ 'promotion' ] = $promotion;
|
||||
$cashier_order_pay->setCache($out_trade_no, $cache);
|
||||
$pay_data = [
|
||||
'site_id' => $site_id,//站点id
|
||||
'out_trade_no' => $out_trade_no,
|
||||
'store_id' => 0,
|
||||
'online_type' => 'online',
|
||||
'pay_type' => 'BALANCE',
|
||||
'member_id' => $member_id,
|
||||
];
|
||||
$res = ( new CashierOrderPay() )->doPay($pay_data);
|
||||
if ($res[ 'code' ] != 0) {
|
||||
model('pay_balance')->rollback();
|
||||
return $res;
|
||||
}
|
||||
model('pay_balance')->update([ 'status' => 1, 'out_trade_no' => $pay_info[ 'out_trade_no' ], 'pay_time' => time() ], [ [ 'auth_code', '=', $auth_code ] ]);
|
||||
model('pay_balance')->commit();
|
||||
return $this->success([ 'out_trade_no' => $out_trade_no ]);
|
||||
} catch (\Exception $e) {
|
||||
model('pay_balance')->rollback();
|
||||
Log::write('付款码支付扣款失败:' . $e->getMessage() . $e->getFile() . $e->getLine());
|
||||
return $this->error('', '付款码支付扣款失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询信息
|
||||
* @param $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getInfo($condition, $field = '*')
|
||||
{
|
||||
$data = model('pay_balance')->getInfo($condition, $field);
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建会员支付码
|
||||
*/
|
||||
private function createAuthCode($member_id)
|
||||
{
|
||||
$code = [
|
||||
rand(1000, 9999),
|
||||
$member_id,
|
||||
(int) date('dis')
|
||||
];
|
||||
$tmp = implode('', $code);
|
||||
for ($i = 0; $i < ( 18 - strlen($tmp) ); $i++) {
|
||||
$code[] = rand(0, 9);
|
||||
}
|
||||
shuffle($code);
|
||||
return implode('', $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检验付款码
|
||||
* @param $code
|
||||
* @param $member_id
|
||||
* @return array
|
||||
*/
|
||||
public function checkPaymentCode($code, $member_id)
|
||||
{
|
||||
$condition = [
|
||||
[ 'auth_code|dynamic_code', '=', $code ]
|
||||
];
|
||||
if (!empty($member_id)) {
|
||||
$condition[] = [ 'member_id', '=', $member_id ];
|
||||
}
|
||||
$info = model('pay_balance')->getInfo($condition, 'id,member_id,expire_time');
|
||||
if (empty($info)) return $this->error('', '无效付款码');
|
||||
if ($info['expire_time'] < time()) return $this->error('', '付款码已失效');
|
||||
model('pay_balance')->delete([ ['id', '=', $info['id'] ] ]);
|
||||
return $this->success($info);
|
||||
}
|
||||
}
|
||||
174
app/model/system/PayTransfer.php
Executable file
174
app/model/system/PayTransfer.php
Executable file
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use think\facade\Cache;
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 系统转账业务
|
||||
*/
|
||||
class PayTransfer extends BaseModel
|
||||
{
|
||||
const STATUS_WAIT = 0;
|
||||
const STATUS_IN_PROCESS = 1;
|
||||
const STATUS_SUCCESS = 2;
|
||||
const STATUS_FAIL = 3;
|
||||
|
||||
/**
|
||||
* 添加
|
||||
* @param $param
|
||||
* @return array|mixed|string|void
|
||||
*/
|
||||
public function add($param)
|
||||
{
|
||||
$data = [
|
||||
'out_trade_no' => $this->createOutTradeNo(),
|
||||
'real_name' => $param[ 'real_name' ],
|
||||
'amount' => $param[ 'amount' ],
|
||||
'desc' => $param['desc'],
|
||||
'transfer_type' => $param['transfer_type'],
|
||||
'account_number' => $param['account_number'],
|
||||
'site_id' => $param['site_id'],
|
||||
'is_weapp' => $param['is_weapp'],
|
||||
'member_id' => $param['member_id'],
|
||||
'from_type' => $param['from_type'],
|
||||
'status' => self::STATUS_WAIT,
|
||||
'create_time' => time(),
|
||||
'relate_tag' => $param['relate_tag'] ?? ''
|
||||
];
|
||||
$id = model('pay_transfer')->add($data);
|
||||
return $this->success($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起转账
|
||||
* @param $from_type
|
||||
* @param $relate_tag
|
||||
* @return array|mixed|string|void
|
||||
*/
|
||||
public function transfer($from_type, $relate_tag,$transfer_check=false)
|
||||
{
|
||||
$info = model('pay_transfer')->getInfo([['from_type', '=', $from_type], ['relate_tag', '=', $relate_tag]]);
|
||||
if(empty($info)){
|
||||
return $this->error($info, '转账记录不存在');
|
||||
}
|
||||
|
||||
//各自业务检测
|
||||
if($transfer_check){
|
||||
$check_res = event('PayTransferCheck', $info, true);
|
||||
if(isset($check_res['code']) && $check_res['code'] < 0){
|
||||
return $check_res;
|
||||
}
|
||||
}
|
||||
|
||||
$result = event('PayTransfer', $info, true);
|
||||
if($result['code'] < 0){
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result = $this->updateStatus($result['data'], $info['id']);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新状态
|
||||
* @param $result
|
||||
* @param $id
|
||||
* @return array|mixed|string|void
|
||||
*/
|
||||
public function updateStatus($data, $id)
|
||||
{
|
||||
$status = $data['status'] ?? self::STATUS_SUCCESS;
|
||||
model('pay_transfer')->update([
|
||||
'status' => $status,
|
||||
'resp_data' => json_encode($data, JSON_UNESCAPED_UNICODE),
|
||||
'update_time' => time(),
|
||||
], [['id', '=', $id],['status', 'in', [self::STATUS_WAIT, self::STATUS_IN_PROCESS]]]);
|
||||
|
||||
if($status == self::STATUS_WAIT){
|
||||
return $this->success($data);
|
||||
}
|
||||
if($status == self::STATUS_IN_PROCESS){
|
||||
(new Cron())->addCron(1, 0, "查询转账结果", "CronPayTransferResult", time() + 10, $id);
|
||||
}
|
||||
$info = model('pay_transfer')->getInfo([['id', '=', $id]]);
|
||||
$res = event('PayTransferNotify', $info, true);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建支付流水号
|
||||
*/
|
||||
public function createOutTradeNo($member_id = 0)
|
||||
{
|
||||
$cache = Cache::get('pay_transfer_out_trade_no' . $member_id . time());
|
||||
if (empty($cache)) {
|
||||
Cache::set('pay_transfer_out_trade_no' . $member_id . time(), 1000);
|
||||
$cache = Cache::get('pay_transfer_out_trade_no' . $member_id . time());
|
||||
} else {
|
||||
$cache = $cache + 1;
|
||||
Cache::set('pay_transfer_out_trade_no' . $member_id . time(), $cache);
|
||||
}
|
||||
$no = time() . rand(1000, 9999) . $member_id . $cache;
|
||||
return $no;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询支付结果
|
||||
* @param $id
|
||||
* @return array|mixed|string|void
|
||||
*/
|
||||
public function result($id)
|
||||
{
|
||||
$info = model('pay_transfer')->getInfo([['id', '=', $id]]);
|
||||
if(empty($info)){
|
||||
return $this->error($info, '转账信息有误');
|
||||
}
|
||||
|
||||
if($info['status'] != self::STATUS_IN_PROCESS){
|
||||
return $this->error($info, '非转账中单据无需处理');
|
||||
}
|
||||
|
||||
$result = event('PayTransferResult', $info, true);
|
||||
if(!isset($result['code']) || $result['code'] < 0){
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $this->updateStatus($result['data'], $id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改
|
||||
* @param $data
|
||||
* @param $where
|
||||
* @return array
|
||||
*/
|
||||
public function editTransfer($data,$where)
|
||||
{
|
||||
$result = model("pay_transfer")->update($data,$where);
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取单条结果集
|
||||
* @param $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getTransferInfo($condition,$field="*")
|
||||
{
|
||||
$result = model("pay_transfer")->getInfo($condition,$field);
|
||||
return $this->success($result);
|
||||
}
|
||||
}
|
||||
594
app/model/system/Poster.php
Executable file
594
app/model/system/Poster.php
Executable file
@@ -0,0 +1,594 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use addon\postertemplate\model\PosterTemplate as PosterTemplateModel;
|
||||
use addon\store\model\Config as StoreConfig;
|
||||
use app\model\BaseModel;
|
||||
use app\model\upload\Upload;
|
||||
use app\model\web\Config;
|
||||
use extend\multitype;
|
||||
use extend\Poster as PosterExtend;
|
||||
|
||||
/**
|
||||
* 海报生成类
|
||||
*/
|
||||
class Poster extends BaseModel
|
||||
{
|
||||
/**
|
||||
* 商品海报
|
||||
*/
|
||||
public function goods($app_type, $page, $qrcode_param, $promotion_type, $site_id, $store_id = 0)
|
||||
{
|
||||
try {
|
||||
|
||||
$goods_info = $this->getGoodsInfo($qrcode_param[ 'goods_id' ], $site_id, $store_id);
|
||||
if (empty($goods_info)) return $this->error('未获取到商品信息');
|
||||
|
||||
$qrcode_info = $this->getGoodsQrcode($app_type, $page, $qrcode_param, $promotion_type, $site_id);
|
||||
|
||||
if ($qrcode_info[ 'code' ] < 0) return $qrcode_info;
|
||||
//判断海报是否存在或停用
|
||||
$template_info = $this->getTemplateInfo($goods_info[ 'template_id' ]);
|
||||
|
||||
$site_model = new Site();
|
||||
$condition = array (
|
||||
[ "site_id", "=", $site_id ]
|
||||
);
|
||||
$site_info = $site_model->getSiteInfo($condition);
|
||||
|
||||
if (!empty($qrcode_param[ 'source_member' ])) {
|
||||
$member_info = $this->getMemberInfo($qrcode_param[ 'source_member' ]);
|
||||
}
|
||||
$upload_config_model = new Config();
|
||||
$upload_config_result = $upload_config_model->getDefaultImg($site_id);
|
||||
|
||||
if (empty($goods_info[ 'template_id' ]) || empty($template_info) || $template_info[ 'template_status' ] == 0) {
|
||||
$poster_width = 720;
|
||||
$poster_height = 1150;
|
||||
|
||||
$poster = new PosterExtend($poster_width, $poster_height);
|
||||
|
||||
$option = [
|
||||
[
|
||||
'action' => 'setBackground', // 设背景色
|
||||
'data' => [ 255, 255, 255 ]
|
||||
],
|
||||
[
|
||||
'action' => 'imageCopy', // 写入商品图
|
||||
'data' => [
|
||||
img($goods_info['sku_image'], 'big'),
|
||||
50,
|
||||
165,
|
||||
620,
|
||||
620,
|
||||
'square',
|
||||
true,
|
||||
1
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageText', // 写入商品名称
|
||||
'data' => [
|
||||
$goods_info[ 'goods_name' ],
|
||||
22,
|
||||
[ 35, 35, 35 ],
|
||||
50,
|
||||
915,
|
||||
360,
|
||||
2,
|
||||
true,
|
||||
1
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageCopy', // 写入商品二维码
|
||||
'data' => [
|
||||
$qrcode_info[ 'data' ][ 'path' ],
|
||||
435,
|
||||
825,
|
||||
240,
|
||||
240,
|
||||
'square',
|
||||
0,
|
||||
1
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageText', // 写入提示
|
||||
'data' => [
|
||||
'长按识别二维码',
|
||||
19,
|
||||
[ 102, 102, 102 ],
|
||||
465,
|
||||
1110,
|
||||
490,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageText', // 写入商品价格单位
|
||||
'data' => [
|
||||
'¥',
|
||||
27,
|
||||
[ 255, 0, 0 ],
|
||||
50,
|
||||
860,
|
||||
490,
|
||||
2,
|
||||
true,
|
||||
1
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageText', // 写入商品价格
|
||||
'data' => [
|
||||
$goods_info[ 'discount_price' ],
|
||||
30,
|
||||
[ 255, 0, 0 ],
|
||||
78,
|
||||
862,
|
||||
490,
|
||||
2,
|
||||
true,
|
||||
1
|
||||
]
|
||||
],
|
||||
];
|
||||
if (!empty($member_info)) {
|
||||
$member_option = [
|
||||
[
|
||||
'action' => 'imageCircularCopy', // 写入用户头像
|
||||
'data' => [
|
||||
!empty($member_info[ 'headimg' ]) ? $member_info[ 'headimg' ] : $upload_config_result[ 'data' ][ 'value' ][ 'head' ],
|
||||
50,
|
||||
30,
|
||||
100,
|
||||
100
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageText', // 写入分享人昵称
|
||||
'data' => [
|
||||
$member_info[ 'nickname' ],
|
||||
22,
|
||||
[ 10, 10, 10 ],
|
||||
170,
|
||||
80,
|
||||
580,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageText', // 写入分享人昵称
|
||||
'data' => [
|
||||
'分享给你一个商品',
|
||||
18,
|
||||
[ 102, 102, 102 ],
|
||||
170,
|
||||
115,
|
||||
580,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
]
|
||||
]
|
||||
];
|
||||
$option = array_merge($option, $member_option);
|
||||
}
|
||||
|
||||
} else {
|
||||
$condition = [
|
||||
[ 'template_id', '=', $goods_info[ 'template_id' ] ],
|
||||
[ 'site_id', '=', $site_id ]
|
||||
];
|
||||
$poster_template_model = new PosterTemplateModel();
|
||||
$poster_data = $poster_template_model->getPosterTemplateInfo($condition);
|
||||
$poster_data[ 'data' ][ 'template_json' ] = json_decode($poster_data[ 'data' ][ 'template_json' ], true);
|
||||
$poster_width = 720;
|
||||
$poster_height = 1280;
|
||||
$poster = new PosterExtend($poster_width, $poster_height);
|
||||
$fontRate = 0.725; // 20px 等于 14.5磅,换算比率 1px = 0.725磅
|
||||
if ($goods_info[ 'price' ] == 0) {
|
||||
$line = '一一一';
|
||||
} else {
|
||||
$line = '一一一一';
|
||||
}
|
||||
if (!empty($poster_data[ 'data' ][ 'background' ])) {
|
||||
$background = str_replace(" ", "", img($poster_data[ 'data' ][ 'background' ]));
|
||||
list($width, $height, $type, $attr) = getimagesize($background);
|
||||
|
||||
$height = 720 * $height / $width;
|
||||
$back_ground = [
|
||||
'action' => 'imageCopy', // 写入背景图
|
||||
'data' => [
|
||||
img($poster_data[ 'data' ][ 'background' ]),
|
||||
0,
|
||||
0,
|
||||
$poster_width,
|
||||
$poster_height,
|
||||
'square',
|
||||
true,
|
||||
1
|
||||
]
|
||||
];
|
||||
} else {
|
||||
$back_ground = [
|
||||
'action' => 'setBackground', // 设背景色
|
||||
'data' => [ 255, 255, 255 ]
|
||||
];
|
||||
}
|
||||
$ground = [ [
|
||||
'action' => 'setBackground', // 设背景色
|
||||
'data' => [ 255, 255, 255 ]
|
||||
] ];
|
||||
$option = [
|
||||
$back_ground,
|
||||
[
|
||||
'action' => 'imageText', // 写入店铺名称
|
||||
'data' => [
|
||||
$site_info[ 'data' ][ 'site_name' ],
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'store_name_font_size' ] * $fontRate * 2,
|
||||
hex2rgb($poster_data[ 'data' ][ 'template_json' ][ 'store_name_color' ]),
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'store_name_left' ] * 2,
|
||||
( $poster_data[ 'data' ][ 'template_json' ][ 'store_name_top' ] + $poster_data[ 'data' ][ 'template_json' ][ 'store_name_font_size' ] ) * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'store_name_width' ] * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'store_name_height' ] * 2,
|
||||
true,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'store_name_is_show' ]
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageCopy', // 店铺logo
|
||||
'data' => [
|
||||
!empty($site_info[ 'data' ][ 'logo_square' ]) ? $site_info[ 'data' ][ 'logo_square' ] : getUrl() . '/app/shop/view/public/img/shop_logo.png',
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'store_logo_left' ] * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'store_logo_top' ] * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'store_logo_width' ] * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'store_logo_height' ] * 2,
|
||||
'square',
|
||||
true,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'store_logo_is_show' ]
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageCopy', // 写入商品图
|
||||
'data' => [
|
||||
img($goods_info[ 'sku_image' ], 'big'),
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_img_left' ] * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_img_top' ] * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_img_width' ] * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_img_height' ] * 2,
|
||||
!empty($poster_data[ 'data' ][ 'template_json' ][ 'goods_img_shape' ]) ? $poster_data[ 'data' ][ 'template_json' ][ 'goods_img_shape' ] : 'square',
|
||||
0,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_img_is_show' ]
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageText', // 写入商品名称
|
||||
'data' => [
|
||||
$goods_info[ 'goods_name' ],
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_name_font_size' ] * $fontRate * 2,
|
||||
hex2rgb($poster_data[ 'data' ][ 'template_json' ][ 'goods_name_color' ]),
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_name_left' ] * 2,
|
||||
( $poster_data[ 'data' ][ 'template_json' ][ 'goods_name_top' ] + $poster_data[ 'data' ][ 'template_json' ][ 'goods_name_font_size' ] ) * 2 + 10,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_name_width' ] * 2,
|
||||
1,//文本行数 $poster_data['data']['template_json']['goods_name_height']*2,
|
||||
true,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_name_is_show' ]
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageCopy', // 写入商品二维码
|
||||
'data' => [
|
||||
$qrcode_info[ 'data' ][ 'path' ],
|
||||
$poster_data[ 'data' ][ 'qrcode_left' ] * 2,
|
||||
$poster_data[ 'data' ][ 'qrcode_top' ] * 2,
|
||||
$poster_data[ 'data' ][ 'qrcode_width' ] * 2,
|
||||
$poster_data[ 'data' ][ 'qrcode_height' ] * 2,
|
||||
'square',
|
||||
0,
|
||||
1
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageText', // 写入商品价格
|
||||
'data' => [
|
||||
'¥' . $goods_info[ 'discount_price' ],
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_price_font_size' ] * $fontRate * 2,
|
||||
hex2rgb($poster_data[ 'data' ][ 'template_json' ][ 'goods_price_color' ]),
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_price_left' ] * 2,
|
||||
( $poster_data[ 'data' ][ 'template_json' ][ 'goods_price_top' ] + $poster_data[ 'data' ][ 'template_json' ][ 'goods_price_font_size' ] ) * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_price_width' ] * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_price_height' ] * 2,
|
||||
true,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_price_is_show' ]
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
if ($goods_info[ 'market_price' ] > 0) {
|
||||
$market_price = [
|
||||
[
|
||||
'action' => 'imageText', // 写入商品划线价格
|
||||
'data' => [
|
||||
'¥' . $goods_info[ 'market_price' ],
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_font_size' ] * $fontRate * 2,
|
||||
hex2rgb($poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_color' ]),
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_left' ] * 2,
|
||||
( $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_top' ] + $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_font_size' ] ) * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_width' ] * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_height' ] * 2,
|
||||
true,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_is_show' ]
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageText', // 写入线
|
||||
'data' => [
|
||||
$line,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_font_size' ] * $fontRate * 2,
|
||||
hex2rgb($poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_color' ]),
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_left' ] * 2 - 5,
|
||||
( $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_top' ] + $poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_font_size' ] ) * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_width' ] * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_height' ] * 2,
|
||||
true,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'goods_market_price_is_show' ]
|
||||
]
|
||||
],
|
||||
];
|
||||
$option = array_merge($option, $market_price);
|
||||
}
|
||||
|
||||
if (!empty($member_info)) {
|
||||
$member_option = [
|
||||
[
|
||||
'action' => 'imageCopy', // 写入用户头像
|
||||
'data' => [
|
||||
!empty($member_info[ 'headimg' ]) ? $member_info[ 'headimg' ] : $upload_config_result[ 'data' ][ 'value' ][ 'head' ],
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'headimg_left' ] * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'headimg_top' ] * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'headimg_width' ] * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'headimg_height' ] * 2,
|
||||
!empty($poster_data[ 'data' ][ 'template_json' ][ 'headimg_shape' ]) ? $poster_data[ 'data' ][ 'template_json' ][ 'headimg_shape' ] : 'square',
|
||||
0,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'headimg_is_show' ]
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageText', // 写入分享人昵称
|
||||
'data' => [
|
||||
$member_info[ 'nickname' ],
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'nickname_font_size' ] * $fontRate * 2,
|
||||
hex2rgb($poster_data[ 'data' ][ 'template_json' ][ 'nickname_color' ]),
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'nickname_left' ] * 2,
|
||||
( $poster_data[ 'data' ][ 'template_json' ][ 'nickname_top' ] + $poster_data[ 'data' ][ 'template_json' ][ 'nickname_font_size' ] ) * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'nickname_width' ] * 2,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'nickname_height' ] * 2,
|
||||
0,
|
||||
$poster_data[ 'data' ][ 'template_json' ][ 'nickname_is_show' ]
|
||||
]
|
||||
],
|
||||
];
|
||||
$option = array_merge($ground, $option, $member_option);
|
||||
}
|
||||
}
|
||||
$option_res = $poster->create($option);
|
||||
if (is_array($option_res)) return $option_res;
|
||||
|
||||
$res = $option_res->jpeg('upload/poster/goods', 'goods_' . $promotion_type . '_' . $qrcode_param[ 'goods_id' ] . '_' . $qrcode_param[ 'source_member' ] . '_' . time() . '_' . $app_type);
|
||||
if ($res[ 'code' ] == 0) {
|
||||
$upload = new Upload($site_id);
|
||||
$cloud_res = $upload->fileCloud($res[ 'data' ][ 'path' ]);
|
||||
if ($cloud_res[ 'code' ] >= 0) {
|
||||
return $this->success([ "path" => $cloud_res[ 'data' ] ]);
|
||||
} else {
|
||||
return $this->error();
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
} catch (\Exception $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @param unknown $member_id
|
||||
*/
|
||||
private function getMemberInfo($member_id)
|
||||
{
|
||||
$info = model('member')->getInfo([ 'member_id' => $member_id ], 'nickname,headimg');
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品信息
|
||||
* @param $goods_id
|
||||
* @param $site_id
|
||||
* @param $store_id
|
||||
* @return mixed
|
||||
*/
|
||||
private function getGoodsInfo($goods_id, $site_id, $store_id)
|
||||
{
|
||||
$field = 'g.goods_id,g.goods_name,g.introduction,gs.price,gs.discount_price,g.goods_image,g.sku_id,gs.collect_num,g.template_id,g.market_price,gs.sku_image';
|
||||
$join = [
|
||||
[ 'goods_sku gs', 'gs.sku_id=g.sku_id', 'left' ]
|
||||
];
|
||||
if (!empty($store_id)) {
|
||||
$store_config = ( new StoreConfig() )->getStoreBusinessConfig($site_id)[ 'data' ][ 'value' ];
|
||||
if ($store_config[ 'store_business' ] == 'store') {
|
||||
$join[] = [ 'store_goods_sku sgs', 'gs.sku_id = sgs.sku_id and sgs.store_id=' . $store_id, 'left' ];
|
||||
$field = str_replace('gs.price', 'IFNULL(IF(g.is_unify_price = 1,gs.price,sgs.price), gs.price) as price', $field);
|
||||
$field = str_replace('gs.discount_price', 'IFNULL(IF(g.is_unify_price = 1,gs.discount_price,sgs.price), gs.discount_price) as discount_price', $field);
|
||||
}
|
||||
}
|
||||
$info = model('goods')->getInfo([ 'g.goods_id' => $goods_id ], $field, 'g', $join);
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品二维码
|
||||
* @param unknown $app_type 请求类型
|
||||
* @param unknown $page uniapp页面路径
|
||||
* @param unknown $qrcode_param 二维码携带参数
|
||||
* @param string $promotion_type 活动类型 null为无活动
|
||||
*/
|
||||
private function getGoodsQrcode($app_type, $page, $qrcode_param, $promotion_type, $site_id)
|
||||
{
|
||||
$res = event('Qrcode', [
|
||||
'site_id' => $site_id,
|
||||
'app_type' => $app_type,
|
||||
'type' => 'create',
|
||||
'data' => $qrcode_param,
|
||||
'page' => $page,
|
||||
'qrcode_path' => 'upload/qrcode/goods',
|
||||
'qrcode_name' => 'goods_' . $promotion_type . '_' . $qrcode_param[ 'goods_id' ] . '_' . $qrcode_param[ 'source_member' ] . '_' . $site_id,
|
||||
], true);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取海报信息
|
||||
* @param unknown $template_id
|
||||
*/
|
||||
private function getTemplateInfo($template_id)
|
||||
{
|
||||
$info = model('poster_template')->getInfo([ 'template_id' => $template_id ], 'template_id,template_status');
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享图片
|
||||
* @param $page
|
||||
* @param $qrcode_param
|
||||
* @param $site_id
|
||||
* @param int $store_id
|
||||
* @return array|multitype|PosterExtend|string|string[]
|
||||
*/
|
||||
public function shareImg($page, $qrcode_param, $site_id, $store_id = 0)
|
||||
{
|
||||
try {
|
||||
$goods_info = $this->getGoodsInfo($qrcode_param[ 'goods_id' ], $site_id, $store_id);
|
||||
if (empty($goods_info)) return $this->error('未获取到商品信息');
|
||||
|
||||
// $file_path = 'upload/share_img/goods_'.$goods_info['goods_id'] .'/sku_'.$goods_info['sku_id'] .'.jpg';
|
||||
// if (file_exists($file_path)) return $this->success(['path' => $file_path]);
|
||||
|
||||
$poster_width = 600;
|
||||
$poster_height = 480;
|
||||
|
||||
$poster = new PosterExtend($poster_width, $poster_height);
|
||||
$option = [
|
||||
[
|
||||
'action' => 'setBackground', // 设背景色
|
||||
'data' => [ 255, 255, 255 ]
|
||||
],
|
||||
[
|
||||
'action' => 'imageCopy', // 商品图
|
||||
'data' => [
|
||||
img($goods_info[ 'sku_image' ], 'big'),
|
||||
30,
|
||||
50,
|
||||
200,
|
||||
200,
|
||||
'square',
|
||||
50,
|
||||
1
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageText', // 写入商品名称
|
||||
'data' => [
|
||||
$goods_info[ 'goods_name' ],
|
||||
25,
|
||||
[ 51, 51, 51 ],
|
||||
250,
|
||||
100,
|
||||
330,
|
||||
2,
|
||||
false,
|
||||
1
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageText', // 写入商品价格
|
||||
'data' => [
|
||||
'¥',
|
||||
15,
|
||||
[ 255, 0, 0 ],
|
||||
250,
|
||||
230,
|
||||
300,
|
||||
2,
|
||||
false,
|
||||
1,
|
||||
PUBLIC_PATH . 'static/font/custom.ttf'
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageText', // 写入商品价格
|
||||
'data' => [
|
||||
$goods_info[ 'discount_price' ],
|
||||
32,
|
||||
[ 255, 0, 0 ],
|
||||
265,
|
||||
230,
|
||||
300,
|
||||
2,
|
||||
false,
|
||||
1,
|
||||
PUBLIC_PATH . 'static/font/custom.ttf'
|
||||
]
|
||||
],
|
||||
[
|
||||
'action' => 'imageCopy', // 背景图
|
||||
'data' => [
|
||||
'upload/share_img/bg/goods_1.png',
|
||||
0,
|
||||
0,
|
||||
600,
|
||||
480,
|
||||
'square',
|
||||
0,
|
||||
1
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
$option_res = $poster->create($option);
|
||||
if (is_array($option_res)) {
|
||||
return $option_res;
|
||||
}
|
||||
|
||||
$res = $option_res->jpeg('upload/share_img/goods_' . $goods_info[ 'goods_id' ],
|
||||
'sku_' . $goods_info[ 'sku_id' ]);
|
||||
return $res;
|
||||
} catch (\Exception $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除分享图片
|
||||
* @param int $goods_id
|
||||
*/
|
||||
public function clearShareImg(int $goods_id)
|
||||
{
|
||||
$dir = 'upload/share_img/goods_' . $goods_id;
|
||||
@deleteDir($dir);
|
||||
}
|
||||
}
|
||||
298
app/model/system/Promotion.php
Executable file
298
app/model/system/Promotion.php
Executable file
@@ -0,0 +1,298 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use app\model\order\Order;
|
||||
use app\model\system\Config as ConfigModel;
|
||||
|
||||
/**
|
||||
* 活动整体管理
|
||||
*/
|
||||
class Promotion extends BaseModel
|
||||
{
|
||||
/**
|
||||
* 获取营销活动展示
|
||||
*/
|
||||
public function getPromotions($addons = [])
|
||||
{
|
||||
$show = event("ShowPromotion", []);
|
||||
$shop_promotion = [];
|
||||
foreach ($show as $k => $v) {
|
||||
if (!empty($v[ 'shop' ])) {
|
||||
if(empty($addons) || in_array($v['shop'][0]['name'], $addons)){
|
||||
$shop_promotion = array_merge($shop_promotion, $v[ 'shop' ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return [
|
||||
'shop' => $shop_promotion
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取站点营销活动展示
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function getSitePromotions($site_id, $addons = [])
|
||||
{
|
||||
$show = event("ShowPromotion", []);
|
||||
$promotion = [];
|
||||
foreach ($show as $k => $v) {
|
||||
if (!empty($v[ 'shop' ])) {
|
||||
if(empty($addons) || in_array($v['shop'][0]['name'], $addons)){
|
||||
$promotion = array_merge($promotion, $v[ 'shop' ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $promotion;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取营销类型
|
||||
*/
|
||||
public function getPromotionType()
|
||||
{
|
||||
$promotion_type = event("PromotionType");
|
||||
$promotion_type[] = [ "type" => "empty", "name" => "无营销活动" ];
|
||||
return $promotion_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取营销活动总数
|
||||
*/
|
||||
public function getPromotionCount($site_id)
|
||||
{
|
||||
$show = event("ShowPromotion", [ 'count' => 1, 'site_id' => $site_id ]);
|
||||
$count = 0;
|
||||
foreach ($show as $k => $v) {
|
||||
if (!empty($v[ 'shop' ])) {
|
||||
$summary = $v[ 'shop' ][ 'summary' ] ?? [];
|
||||
if (!empty($summary)) {
|
||||
$count += $summary[ 'count' ];
|
||||
}
|
||||
}
|
||||
if (!empty($v[ 'member' ])) {
|
||||
$summary = $v[ 'member' ][ 'summary' ] ?? [];
|
||||
if (!empty($summary)) {
|
||||
$count += $summary[ 'count' ];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 输入时间查看活动营销概况
|
||||
* @param $start_time
|
||||
* @param $end_time
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function getPromotionSummary($start_time, $end_time, $site_id, $addons = [])
|
||||
{
|
||||
$summary = event("ShowPromotion", [ 'summary' => 1, 'start_time' => $start_time, 'end_time' => $end_time, 'site_id' => $site_id, 'promotion_tyye' => 'time_limit' ]);
|
||||
$promotion = [
|
||||
'time_limit' => [], // 限时类活动
|
||||
];
|
||||
foreach ($summary as $k => $v) {
|
||||
$shop = $v[ 'shop' ][ 0 ] ?? [];
|
||||
if (empty($shop)) continue;
|
||||
if(empty($addons) || in_array($shop['name'], $addons)) {
|
||||
$summary_v = $shop['summary'] ?? [];
|
||||
if (isset($summary_v['time_limit'])) {
|
||||
unset($shop['summary']);
|
||||
array_push($promotion['time_limit'], array_merge($shop, $summary_v['time_limit']));
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->success($promotion);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置活动专区页面配置
|
||||
* @param $data
|
||||
* @param $site_id
|
||||
* @param $app_module
|
||||
* @return array
|
||||
*/
|
||||
public function setPromotionZoneConfig($data, $site_id, $app_module = 'shop')
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$config_key = strtoupper($data[ 'name' ]) . '_ZONE_CONFIG';
|
||||
$res = $config->setConfig($data, $data[ 'title' ] . '活动专区页面配置', 1, [ [ 'site_id', '=', $site_id ], [ 'app_module', '=', $app_module ], [ 'config_key', '=', $config_key ] ]);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取活动专区页面配置
|
||||
* @param $name
|
||||
* @param $config_key
|
||||
* @param $site_id
|
||||
* @param $app_module
|
||||
* @return array
|
||||
*/
|
||||
public function getPromotionZoneConfig($name, $site_id, $app_module = 'shop')
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$config_key = strtoupper($name) . '_ZONE_CONFIG';
|
||||
$res = $config->getConfig([ [ 'site_id', '=', $site_id ], [ 'app_module', '=', $app_module ], [ 'config_key', '=', $config_key ] ]);
|
||||
if (empty($res[ 'data' ][ 'value' ])) {
|
||||
$promotion_zone_config = event('PromotionZoneConfig', [ 'name' => $name ], true);
|
||||
$res[ 'data' ][ 'value' ] = $promotion_zone_config[ 'value' ] ?? '';
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取营销配置
|
||||
* @param $start_time
|
||||
* @param $end_time
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function getPromotionConfig($start_time, $end_time, $site_id, $addons = [])
|
||||
{
|
||||
$promotion = event("ShowPromotion", [
|
||||
'summary' => 1,
|
||||
'start_time' => $start_time,
|
||||
'end_time' => $end_time,
|
||||
'site_id' => $site_id,
|
||||
'promotion_type' => 'unlimited_time'
|
||||
]);
|
||||
|
||||
$promotion_data = [];
|
||||
foreach ($promotion as $key => $val){
|
||||
if(!empty($val[ 'shop' ][ 0 ])){
|
||||
if(empty($addons) || in_array($val['shop'][0]['name'], $addons)){
|
||||
$shop = $val[ 'shop' ][0] ?? [];
|
||||
if(empty($shop['summary'])){
|
||||
unset($promotion[$key]);
|
||||
}else{
|
||||
array_push($promotion_data, array_merge($shop, $shop['summary']['unlimited_time']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->success($promotion_data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取营销数据统计
|
||||
* @param $start_time
|
||||
* @param $end_time
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function getPromotionStat($start_time, $end_time, $site_id)
|
||||
{
|
||||
$promotion = event("ShowPromotion", [
|
||||
'summary' => 1,
|
||||
'start_time' => $start_time,
|
||||
'end_time' => $end_time,
|
||||
'site_id' => $site_id
|
||||
]);
|
||||
|
||||
$promotion_data = [
|
||||
'promotion_num' => 0, // 活动数量
|
||||
'in_progress_num' => 0, // 进行中活动数量,
|
||||
'order_num' => 0
|
||||
];
|
||||
|
||||
foreach ($promotion as $k => $v) {
|
||||
$shop = $v[ 'shop' ][ 0 ] ?? [];
|
||||
if (empty($shop)) continue;
|
||||
$promotion_data[ 'promotion_num' ] += 1;
|
||||
|
||||
$summary_v = $shop[ 'summary' ] ?? [];
|
||||
if (isset($summary_v[ 'time_limit' ])) {
|
||||
$promotion_data[ 'in_progress_num' ] += $summary_v[ 'time_limit' ][ 'count' ];
|
||||
}
|
||||
}
|
||||
|
||||
$promotion_data['order_num'] = ( new Order() )->getOrderCount([ [ 'site_id', '=', $site_id ], [ 'promotion_type', '<>', '' ], [ 'pay_status', '=', 1 ] ], 'order_id')[ 'data' ];
|
||||
|
||||
return $this->success($promotion_data);
|
||||
}
|
||||
|
||||
public function getUnlimitedTimePromotion()
|
||||
{
|
||||
// 不限时类的活动
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取推广二维码
|
||||
* @param $param
|
||||
* @return array
|
||||
*/
|
||||
public function getPromotionQrcode($param)
|
||||
{
|
||||
try{
|
||||
$page_name = $param['page_name'];
|
||||
$option = $param['option'];
|
||||
$app_type = $param['app_type'];
|
||||
$site_id = $param['site_id'];
|
||||
|
||||
//找到页面配置
|
||||
$event_res = event('PromotionPage');
|
||||
$page_info = null;
|
||||
foreach($event_res as $list){
|
||||
foreach ($list as $info){
|
||||
if($page_name == $info['name']){
|
||||
$page_info = $info;
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(empty($page_info)){
|
||||
return $this->error(null, '页数数据有误');
|
||||
}
|
||||
|
||||
//二维码名称
|
||||
$qrcode_name_arr = [];
|
||||
foreach ($option as $key=>$val){
|
||||
$qrcode_name_arr[] = $key.'_'.$val;
|
||||
}
|
||||
$qrcode_name = join('_', $qrcode_name_arr);
|
||||
|
||||
//路径数据
|
||||
$wap_url = $page_info['wap_url'];
|
||||
$url_data = parse_url($wap_url);
|
||||
parse_str($url_data['query'], $query_data);
|
||||
foreach ($query_data as $key=>$val){
|
||||
if(!isset($option[$key])) return $this->error(null, 'option缺少'.$key.'参数');
|
||||
$query_data[$key] = $option[$key];
|
||||
}
|
||||
|
||||
$params = [
|
||||
'site_id' => $site_id,
|
||||
'data' => $query_data,
|
||||
'page' => $url_data['path'],
|
||||
'app_type' => $app_type,
|
||||
'qrcode_path' => 'upload/qrcode/'.strtolower($page_name),
|
||||
'qrcode_name' => $qrcode_name,
|
||||
];
|
||||
|
||||
$res = event('PromotionQrcode', $params, true);
|
||||
return $this->success($res);
|
||||
}catch(\Exception $e){
|
||||
return $this->error([
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'message' => $e->getMessage(),
|
||||
], '生成二维码失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
84
app/model/system/Qrcode.php
Executable file
84
app/model/system/Qrcode.php
Executable file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use app\model\web\Config as ConfigModel;
|
||||
use extend\QRcode as QRcodeExtend;
|
||||
|
||||
/**
|
||||
* 二维码生成类
|
||||
*/
|
||||
class Qrcode extends BaseModel
|
||||
{
|
||||
public function createQrcode(array $param)
|
||||
{
|
||||
try {
|
||||
$checkpath_result = $this->checkPath($param[ 'qrcode_path' ]);
|
||||
if ($checkpath_result[ "code" ] != 0) return $checkpath_result;
|
||||
|
||||
$urlParam = '';
|
||||
if (!empty($param[ 'data' ])) {
|
||||
foreach ($param[ 'data' ] as $key => $value) {
|
||||
if ($urlParam == '') $urlParam .= '?' . $key . '=' . $value;
|
||||
else $urlParam .= '&' . $key . '=' . $value;
|
||||
}
|
||||
}
|
||||
|
||||
$domain = getH5Domain();
|
||||
if ($param[ 'app_type' ] == 'pc') {
|
||||
$config_model = new ConfigModel();
|
||||
$domain = $config_model->getPcDomainName()[ 'data' ][ 'value' ][ 'domain_name_pc' ];
|
||||
}
|
||||
|
||||
$url = $domain . $param[ 'page' ] . $urlParam;
|
||||
|
||||
$filename = $param[ 'qrcode_path' ] . '/' . $param[ 'qrcode_name' ] . '_' . $param[ 'app_type' ] . '.png';
|
||||
|
||||
if ($param[ 'type' ] == 'create') {
|
||||
delFile($filename);
|
||||
}
|
||||
|
||||
QRcodeExtend::png($url, $filename, 'L', $param[ 'qrcode_size' ] ?? 16, 1);
|
||||
return $this->success([ 'type' => 'h5', 'path' => $filename, 'url' => $url ]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验目录是否可写
|
||||
* @param unknown $path
|
||||
* @return multitype:number unknown |multitype:unknown
|
||||
*/
|
||||
private function checkPath($path)
|
||||
{
|
||||
if (is_dir($path) || mkdir($path, intval('0755', 8), true)) {
|
||||
return $this->success();
|
||||
}
|
||||
return $this->error('', "directory {$path} creation failed");
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成base64格式二维码
|
||||
* @param $text
|
||||
* @return array
|
||||
*/
|
||||
public function createBase64Qrcode($text)
|
||||
{
|
||||
ob_start();
|
||||
QRcodeExtend::png($text, false, 'L', 4, 1);
|
||||
$image_string = base64_encode(ob_get_contents());
|
||||
ob_end_clean();
|
||||
$base_64 = "data:image/png;base64,".$image_string;
|
||||
return $this->success($base_64);
|
||||
}
|
||||
}
|
||||
63
app/model/system/Servicer.php
Executable file
63
app/model/system/Servicer.php
Executable file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 山西牛酷信息科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
|
||||
use app\model\BaseModel;
|
||||
use app\model\system\Config as ConfigModel;
|
||||
|
||||
/**
|
||||
* 客服配置
|
||||
*/
|
||||
class Servicer extends BaseModel
|
||||
{
|
||||
/**
|
||||
* 设置客服配置
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function setServicerConfig($data)
|
||||
{
|
||||
$config_model = new ConfigModel();
|
||||
$res = $config_model->setConfig($data, '客服配置', 1, [ [ 'site_id', '=', 1 ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'SRRVICER_ROOT_CONFIG' ] ]);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客服配置
|
||||
*/
|
||||
public function getServicerConfig()
|
||||
{
|
||||
$config_model = new ConfigModel();
|
||||
$res = $config_model->getConfig([ [ 'site_id', '=', 1 ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'SRRVICER_ROOT_CONFIG' ] ]);
|
||||
if (empty($res[ 'data' ][ 'value' ])) {
|
||||
$res[ 'data' ][ 'value' ] = [
|
||||
'h5' => [
|
||||
'type' => 'none'
|
||||
],
|
||||
'weapp' => [
|
||||
'type' => 'none'
|
||||
],
|
||||
'pc' => [
|
||||
'type' => 'none'
|
||||
],
|
||||
'aliapp' => [
|
||||
'type' => 'none'
|
||||
],
|
||||
];
|
||||
}
|
||||
$res[ 'data' ][ 'value' ][ 'h5' ][ 'type' ] = $res[ 'data' ][ 'value' ][ 'h5' ][ 'type' ] ?? 'none';
|
||||
$res[ 'data' ][ 'value' ][ 'weapp' ][ 'type' ] = $res[ 'data' ][ 'value' ][ 'weapp' ][ 'type' ] ?? 'none';
|
||||
$res[ 'data' ][ 'value' ][ 'pc' ][ 'type' ] = $res[ 'data' ][ 'value' ][ 'pc' ][ 'type' ] ?? 'none';
|
||||
$res[ 'data' ][ 'value' ][ 'aliapp' ][ 'type' ] = $res[ 'data' ][ 'value' ][ 'aliapp' ][ 'type' ] ?? 'none';
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
78
app/model/system/Site.php
Executable file
78
app/model/system/Site.php
Executable file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use app\model\upload\Upload;
|
||||
use think\facade\Cache;
|
||||
|
||||
/**
|
||||
* 站点管理
|
||||
* @author Administrator
|
||||
*
|
||||
*/
|
||||
class Site extends BaseModel
|
||||
{
|
||||
public $cache_model = 'cache_model_site';
|
||||
|
||||
/**
|
||||
* 添加站点
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function addSite($data)
|
||||
{
|
||||
$res = model('site')->add($data);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* getSiteInfo 获取站点详情
|
||||
* @param $condition
|
||||
* @param string $fields
|
||||
* @return array
|
||||
*/
|
||||
public function getSiteInfo($condition, $fields = '*')
|
||||
{
|
||||
$res = model('site')->getInfo($condition, $fields);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改商城站点信息
|
||||
* @param $site_data
|
||||
* @param $condition
|
||||
* @return int
|
||||
*/
|
||||
public function editSite($site_data, $condition)
|
||||
{
|
||||
$site_info = $this->getSiteInfo($condition);
|
||||
if($site_info['data'] && $site_data['logo'] && $site_info['data']['logo'] != $site_data['logo']){
|
||||
$upload_model = new Upload();
|
||||
$upload_model->deletePic($site_info['data']['logo'], $site_info['data']['site_id']);
|
||||
}
|
||||
if($site_info['data'] && !empty($site_data['logo_square']) && $site_info['data']['logo_square'] != $site_data['logo_square']){
|
||||
$upload_model = new Upload();
|
||||
$upload_model->deletePic($site_info['data']['logo_square'], $site_info['data']['site_id']);
|
||||
}
|
||||
$res = model('site')->update($site_data, $condition);
|
||||
if($res && $site_data['logo']){
|
||||
if(file_exists($site_data['logo']))
|
||||
{
|
||||
copy($site_data['logo'],"public/static/img/default_img/login.png");
|
||||
}
|
||||
|
||||
}
|
||||
Cache::tag($this->cache_model )->clear();
|
||||
return $this->success($res);
|
||||
}
|
||||
}
|
||||
60
app/model/system/SplitWord.php
Executable file
60
app/model/system/SplitWord.php
Executable file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace app\model\system;
|
||||
use app\model\BaseModel;
|
||||
use extend\BaiDuApi;
|
||||
use think\facade\Log;
|
||||
|
||||
class SplitWord extends BaseModel
|
||||
{
|
||||
protected $table = 'split_word';
|
||||
|
||||
/**
|
||||
* 获取拆词
|
||||
* @param $keyword
|
||||
* @return array
|
||||
*/
|
||||
public function getSplitWord($keyword): array
|
||||
{
|
||||
$result = $this->getInfo([['keyword','=',$keyword]]);
|
||||
if($result['code'] == 0 && !empty($result['data']['result'])){
|
||||
return $this->success(json_decode($result['data']['result']));
|
||||
}
|
||||
|
||||
$config_model = new \app\model\web\Config();
|
||||
$config = $config_model->getSplitWordConfig()['data']['value'];
|
||||
if($config['is_open'] == 0){
|
||||
return $this->success([$keyword]);
|
||||
}
|
||||
$result = (new BaiduApi($config))->splitWords($keyword);
|
||||
if (!empty($result)){
|
||||
$this->addSplitWord($keyword,$result);
|
||||
return $this->success($result);
|
||||
}
|
||||
return $this->success([$keyword]);
|
||||
}
|
||||
|
||||
|
||||
public function getInfo($condition,$field = '*'): array
|
||||
{
|
||||
$result = model($this->table)->getInfo($condition,$field);
|
||||
if(empty($result)){
|
||||
return $this->error('暂无数据');
|
||||
}
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
public function addSplitWord($keyword,$result): array
|
||||
{
|
||||
$result = model($this->table)->add([
|
||||
'keyword' => $keyword,
|
||||
'result' => json_encode($result,JSON_UNESCAPED_UNICODE),
|
||||
'add_time'=>date('Y-m-d H:i:s')
|
||||
]);
|
||||
if(empty($result)){
|
||||
return $this->error('添加失败');
|
||||
}
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
}
|
||||
537
app/model/system/Stat.php
Executable file
537
app/model/system/Stat.php
Executable file
@@ -0,0 +1,537 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use app\dict\order_refund\OrderRefundDict;
|
||||
use app\model\BaseModel;
|
||||
use app\model\order\OrderCommon;
|
||||
use app\model\order\OrderRefund;
|
||||
use app\model\stat\GoodsCartStat;
|
||||
use app\model\stat\GoodsStat;
|
||||
use app\model\stat\MemberStat;
|
||||
use app\model\stat\MemberWithdrawStat;
|
||||
use app\model\stat\OrderStat;
|
||||
use app\model\stat\RechargeStat;
|
||||
use app\model\stat\StatShop;
|
||||
use app\model\stat\VisitStat;
|
||||
use Carbon\Carbon;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Db;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 统计
|
||||
* @author Administrator
|
||||
*
|
||||
*/
|
||||
class Stat extends BaseModel
|
||||
{
|
||||
/**
|
||||
* 添加店铺统计(按照天统计)
|
||||
* @param array $data
|
||||
*/
|
||||
public function addShopStat($data)
|
||||
{
|
||||
$data = $this->getStatData($data);
|
||||
return (new StatShop())->addShopStat($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加当日的时统计记录
|
||||
* @param $data
|
||||
* @param $carbon
|
||||
* @return array
|
||||
* @throws DbException
|
||||
*/
|
||||
public function addShopHourStat($data, $carbon)
|
||||
{
|
||||
$site_id = $data[ 'site_id' ];
|
||||
// $carbon = Carbon::now();
|
||||
$condition = [
|
||||
'site_id' => $site_id,
|
||||
'year' => $carbon->year,
|
||||
'month' => $carbon->month,
|
||||
'day' => $carbon->day,
|
||||
'hour' => $carbon->hour
|
||||
];
|
||||
$info = model('stat_shop_hour')->getInfo($condition, 'id');
|
||||
|
||||
//在这里会整体处理总支出 总收入 总预计收入
|
||||
|
||||
$stat_data = $this->getStatData($data);
|
||||
|
||||
if (empty($info)) {
|
||||
$insert_data = [
|
||||
'site_id' => $site_id,
|
||||
'year' => $carbon->year,
|
||||
'month' => $carbon->month,
|
||||
'day' => $carbon->day,
|
||||
'day_time' => time(),
|
||||
'create_time' => time(),
|
||||
'hour' => $carbon->hour
|
||||
];
|
||||
$insert_data = array_merge($insert_data, $stat_data);
|
||||
$res = model('stat_shop_hour')->add(
|
||||
$insert_data
|
||||
);
|
||||
|
||||
} else {
|
||||
$update_data = array ();
|
||||
if (!empty($stat_data)) {
|
||||
foreach ($stat_data as $k => $v) {
|
||||
if ($v > 0) {
|
||||
$update_data[ $k ] = Db::raw($k . '+' . $v);
|
||||
} else if ($v < 0) {
|
||||
$update_data[ $k ] = Db::raw($k . '-' . abs($v));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($update_data)) {
|
||||
$res = Db::name('stat_shop_hour')->where($condition)
|
||||
->update($update_data);
|
||||
Cache::tag("cache_table" . "stat_shop_hour")->clear();
|
||||
}
|
||||
|
||||
}
|
||||
return $this->success($res ?? 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 整理数据
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function getStatData($data)
|
||||
{
|
||||
unset($data[ 'site_id' ]);
|
||||
$order_pay_money = $data[ 'order_pay_money' ] ?? 0;//订单总额
|
||||
$member_recharge_total_money = $data[ 'member_recharge_total_money' ] ?? 0;//会员充值总额
|
||||
$member_level_total_money = $data[ 'member_level_total_money' ] ?? 0;//超级会员卡销售额
|
||||
$member_giftcard_total_money = $data[ 'member_giftcard_total_money' ] ?? 0;//礼品卡订单总额
|
||||
$earnings_total_money = $order_pay_money + $member_recharge_total_money + $member_level_total_money + $member_giftcard_total_money;//预计总收入
|
||||
|
||||
$order_refund_total_money = $data[ 'refund_total' ] ?? 0;//订单退款总额
|
||||
$member_withdraw_total_money = $data[ 'member_withdraw_total_money' ] ?? 0;//会员提现总额
|
||||
$expenditure_total_money = $order_refund_total_money + $member_withdraw_total_money;//总支出
|
||||
$expected_earnings_total_money = $earnings_total_money - $expenditure_total_money;
|
||||
|
||||
Log::write('getStatData' . json_encode([ $earnings_total_money, $expenditure_total_money, $expected_earnings_total_money ]));
|
||||
|
||||
$data[ 'earnings_total_money' ] = $earnings_total_money;
|
||||
$data[ 'expenditure_total_money' ] = $expenditure_total_money;
|
||||
$data[ 'expected_earnings_total_money' ] = $expected_earnings_total_money;
|
||||
$data = array_filter($data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取店铺统计(按照天查询)
|
||||
* @param unknown $site_id 0表示平台
|
||||
* @param unknown $year
|
||||
* @param unknown $month
|
||||
* @param unknown $day
|
||||
*/
|
||||
public function getStatShop($site_id, $year, $month, $day)
|
||||
{
|
||||
$condition = [
|
||||
'site_id' => $site_id,
|
||||
'year' => $year,
|
||||
'month' => $month,
|
||||
'day' => $day
|
||||
];
|
||||
$info = model('stat_shop')->setIsCache(0)->getInfo($condition, '*');
|
||||
if (empty($info)) {
|
||||
$condition[ 'day_time' ] = strtotime(date("{$year}-{$month}-{$day}"));
|
||||
model('stat_shop')->add($condition);
|
||||
$info = model('stat_shop')->getInfo($condition, '*');
|
||||
}
|
||||
$info[ 'goods_order_count' ] = numberFormat($info[ 'goods_order_count' ]);
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取店铺统计信息
|
||||
* @param $site_id
|
||||
* @param int $start_time
|
||||
* @param int $end_time
|
||||
* @return array
|
||||
*/
|
||||
public function getShopStatSum($site_id, $start_time = 0, $end_time = 0)
|
||||
{
|
||||
$condition = [
|
||||
[ 'site_id', '=', $site_id ]
|
||||
];
|
||||
if (!empty($start_time)) {
|
||||
$condition[] = [ 'day_time', '>=', $start_time ];
|
||||
}
|
||||
if (!empty($end_time)) {
|
||||
$condition[] = [ 'day_time', '<=', $end_time ];
|
||||
}
|
||||
$field = array_map(function($field) {
|
||||
switch ( $field ) {
|
||||
case 'earnings_total_money':
|
||||
return "sum(earnings_total_money) + sum(cashier_billing_money) + sum(cashier_buycard_money) as earnings_total_money";
|
||||
break;
|
||||
case 'expenditure_total_money':
|
||||
return "sum(expenditure_total_money) as expenditure_total_money";
|
||||
break;
|
||||
case 'cashier_billing_money':
|
||||
return "sum(cashier_billing_money) + sum(cashier_buycard_money) as cashier_order_pay_money";
|
||||
break;
|
||||
case 'refund_total':
|
||||
return "sum(refund_total) as refund_total";
|
||||
break;
|
||||
case 'expected_earnings_total_money':
|
||||
return "sum(expected_earnings_total_money) + sum(cashier_billing_money) + sum(cashier_buycard_money) as expected_earnings_total_money";
|
||||
break;
|
||||
case 'order_pay_count':
|
||||
return "sum(order_pay_count) + sum(cashier_billing_count) + sum(cashier_buycard_count) as order_pay_count";
|
||||
break;
|
||||
default:
|
||||
return "sum($field) as $field";
|
||||
}
|
||||
}, $this->getStatField());
|
||||
$info = model('stat_shop')->getInfo($condition, $field);
|
||||
if (isset($info[ 'goods_order_count' ])) {
|
||||
$info[ 'goods_order_count' ] = numberFormat($info[ 'goods_order_count' ]);
|
||||
}
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取店铺统计列表
|
||||
* @param unknown $site_id
|
||||
* @param unknown $start_time
|
||||
*/
|
||||
public function getShopStatList($site_id, $start_time, $end_time)
|
||||
{
|
||||
$condition = [
|
||||
[ 'site_id', '=', $site_id ],
|
||||
[ 'day_time', '>=', $start_time ],
|
||||
[ 'day_time', '<=', $end_time ],
|
||||
];
|
||||
$list = model('stat_shop')->getList($condition, $this->handleStatField());
|
||||
foreach ($list as $k => $v) {
|
||||
$list[ $k ][ 'goods_order_count' ] = numberFormat($list[ $k ][ 'goods_order_count' ]);
|
||||
}
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理查询字段
|
||||
*/
|
||||
private function handleStatField()
|
||||
{
|
||||
$fields = Db::name('stat_shop')->getTableFields('');
|
||||
foreach ($fields as $k => $field) {
|
||||
switch ( $field ) {
|
||||
case 'earnings_total_money':
|
||||
$fields[ $k ] = "earnings_total_money + cashier_billing_money + cashier_buycard_money as earnings_total_money";
|
||||
break;
|
||||
case 'expenditure_total_money':
|
||||
$fields[ $k ] = "expenditure_total_money + cashier_refund_money as expenditure_total_money";
|
||||
break;
|
||||
case 'cashier_billing_money':
|
||||
$fields[ $k ] = "cashier_billing_money + cashier_buycard_money as cashier_order_pay_money";
|
||||
break;
|
||||
case 'expected_earnings_total_money':
|
||||
$fields[ $k ] = "expected_earnings_total_money + cashier_billing_money + cashier_buycard_money - cashier_refund_money as expected_earnings_total_money";
|
||||
break;
|
||||
case 'order_pay_count':
|
||||
$fields[ $k ] = "order_pay_count + cashier_billing_count + cashier_buycard_count as order_pay_count";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return implode(',', $fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小时统计数据
|
||||
* @param $site_id
|
||||
* @param $year
|
||||
* @param $month
|
||||
* @param $day
|
||||
* @return array
|
||||
*/
|
||||
public function getShopStatHourList($site_id, $year, $month, $day)
|
||||
{
|
||||
$condition = [
|
||||
[ 'site_id', '=', $site_id ],
|
||||
[ 'year', '=', $year ],
|
||||
[ 'month', '=', $month ],
|
||||
[ 'day', '=', $day ],
|
||||
];
|
||||
$list = model('stat_shop_hour')->getList($condition, $this->handleStatHourField(), 'id desc');
|
||||
foreach ($list as $k => $v) {
|
||||
$list[ $k ][ 'goods_order_count' ] = numberFormat($list[ $k ][ 'goods_order_count' ]);
|
||||
}
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理查询字段
|
||||
*/
|
||||
private function handleStatHourField()
|
||||
{
|
||||
$fields = Db::name('stat_shop_hour')->getTableFields('');
|
||||
foreach ($fields as $k => $field) {
|
||||
switch ( $field ) {
|
||||
case 'earnings_total_money':
|
||||
$fields[ $k ] = "earnings_total_money + cashier_billing_money + cashier_buycard_money as earnings_total_money";
|
||||
break;
|
||||
case 'expenditure_total_money':
|
||||
// $fields[ $k ] = "expenditure_total_money + cashier_refund_money as expenditure_total_money";
|
||||
break;
|
||||
case 'expected_earnings_total_money':
|
||||
$fields[ $k ] = "expected_earnings_total_money + cashier_billing_money + cashier_buycard_money - cashier_refund_money as expected_earnings_total_money";
|
||||
break;
|
||||
case 'order_pay_count':
|
||||
$fields[ $k ] = "order_pay_count + cashier_billing_count + cashier_buycard_count as order_pay_count";
|
||||
break;
|
||||
}
|
||||
}
|
||||
$fields[] = 'cashier_billing_money + cashier_buycard_money as cashier_order_pay_money';
|
||||
return implode(',', $fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取天统计表统计字段
|
||||
* @return array
|
||||
*/
|
||||
public function getStatField()
|
||||
{
|
||||
$fields = Db::name('stat_shop')->getTableFields('');
|
||||
$fields = array_values(array_diff($fields, [ 'id', 'site_id', 'year', 'month', 'day', 'day_time' ]));
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取时统计表统计字段
|
||||
* @return array
|
||||
*/
|
||||
public function getStatHourField()
|
||||
{
|
||||
$fields = Db::name('stat_shop_hour')->getTableFields('');
|
||||
$fields = array_values(array_diff($fields, [ 'id', 'site_id', 'year', 'month', 'day', 'hour', 'day_time' ]));
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品销量排行榜
|
||||
* @param $site_id
|
||||
* @param string $start_time
|
||||
* @param string $end_time
|
||||
* @param $page_index
|
||||
* @param $page_size
|
||||
* @return array
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function getGoodsSaleNumRankingList($site_id, $start_time, $end_time, $page_index, $page_size)
|
||||
{
|
||||
$condition = [
|
||||
[ 'o.site_id', '=', $site_id ],
|
||||
[ 'o.pay_status', '=', 1 ],
|
||||
[ 'g.is_delete', '=', 0 ],
|
||||
[ 'o.order_status', '<>', OrderCommon::ORDER_CLOSE ],
|
||||
[ 'og.refund_status', '<>', OrderRefundDict::REFUND_COMPLETE ]
|
||||
];
|
||||
if (!empty($start_time) && empty($end_time)) {
|
||||
$condition[] = [ 'o.create_time', '>=', date_to_time($start_time) ];
|
||||
} elseif (empty($start_time) && !empty($end_time)) {
|
||||
$condition[] = [ 'o.create_time', '<=', date_to_time($end_time) ];
|
||||
} elseif (!empty($start_time) && !empty($end_time)) {
|
||||
$condition[] = [ 'o.create_time', 'between', [ date_to_time($start_time), date_to_time($end_time) ] ];
|
||||
}
|
||||
$join = [
|
||||
[ 'order o', 'og.order_id = o.order_id', 'left' ],
|
||||
[ 'goods g', 'og.goods_id = g.goods_id', 'right' ]
|
||||
];
|
||||
$list = model('order_goods')->pageList($condition, 'og.goods_id,g.goods_name,g.goods_state,SUM(og.num) AS sale_num', 'sale_num desc', $page_index, $page_size, 'og', $join, 'og.goods_id');
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品销量排行榜
|
||||
* @param $site_id
|
||||
* @param string $start_time
|
||||
* @param string $end_time
|
||||
* @param $page_index
|
||||
* @param $page_size
|
||||
* @return array
|
||||
*/
|
||||
public function getGoodsSaleMoneyRankingList($site_id, $start_time, $end_time, $page_index, $page_size)
|
||||
{
|
||||
$condition = [
|
||||
[ 'o.site_id', '=', $site_id ],
|
||||
[ 'o.pay_status', '=', 1 ],
|
||||
[ 'g.is_delete', '=', 0 ],
|
||||
[ 'o.order_status', '<>', OrderCommon::ORDER_CLOSE ],
|
||||
[ 'og.refund_status', '<>', OrderRefundDict::REFUND_COMPLETE ]
|
||||
];
|
||||
if (!empty($start_time) && empty($end_time)) {
|
||||
$condition[] = [ 'o.create_time', '>=', date_to_time($start_time) ];
|
||||
} elseif (empty($start_time) && !empty($end_time)) {
|
||||
$condition[] = [ 'o.create_time', '<=', date_to_time($end_time) ];
|
||||
} elseif (!empty($start_time) && !empty($end_time)) {
|
||||
$condition[] = [ 'o.create_time', 'between', [ date_to_time($start_time), date_to_time($end_time) ] ];
|
||||
}
|
||||
$join = [
|
||||
[ 'order o', 'og.order_id = o.order_id', 'left' ],
|
||||
[ 'goods g', 'og.goods_id = g.goods_id', 'right' ]
|
||||
];
|
||||
$list = model('order_goods')->pageList($condition, 'og.goods_id,g.goods_name,g.goods_state,SUM(o.order_money) AS order_money', 'order_money desc', $page_index, $page_size, 'og', $join, 'og.goods_id');
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
public function switchStat($params)
|
||||
{
|
||||
$async = $params['async'] ?? true;//是否异步处理,默认异步
|
||||
$type = $params[ 'type' ];
|
||||
$temp_params = $params[ 'data' ];
|
||||
if($async){
|
||||
$stat_shop_cron_id = model('stat_shop_cron')->add(['type'=>$type,'data'=>json_encode($temp_params),'create_time'=>date('Y-m-d H:i:s')]);
|
||||
$cron_model = new Cron();
|
||||
return $cron_model->addCron(1, 0, '统计任务处理', 'CronStatCron', time()+60, $stat_shop_cron_id);
|
||||
}
|
||||
|
||||
$result = event('AddStat', $params, true);
|
||||
if (empty($result)) {
|
||||
switch ( $type ) {
|
||||
case 'order_create'://订单创建
|
||||
$order_stat_model = new OrderStat();
|
||||
$result = $order_stat_model->addOrderCreateStat($temp_params);
|
||||
break;
|
||||
case 'order_pay'://订单支付
|
||||
$order_stat_model = new OrderStat();
|
||||
$result = $order_stat_model->addOrderPayStat($temp_params);
|
||||
break;
|
||||
case 'order_refund'://退款
|
||||
$order_stat_model = new OrderStat();
|
||||
$result = $order_stat_model->addOrderRefundStat($temp_params);
|
||||
break;
|
||||
case 'add_goods'://添加商品
|
||||
$goods_stat_model = new GoodsStat();
|
||||
$result = $goods_stat_model->addGoodsStat($temp_params);
|
||||
break;
|
||||
case 'collect_goods':
|
||||
$goods_stat_model = new GoodsStat();
|
||||
$result = $goods_stat_model->addGoodsCollectStat($temp_params);
|
||||
break;
|
||||
case 'recharge':
|
||||
$recharge_model = new RechargeStat();
|
||||
$result = $recharge_model->addRechargeStat($temp_params);
|
||||
break;
|
||||
case 'visit':
|
||||
$visit_model = new VisitStat();
|
||||
$result = $visit_model->addVisitStat($temp_params);
|
||||
break;
|
||||
case 'member_withdraw':
|
||||
$withdraw_model = new MemberWithdrawStat();
|
||||
$result = $withdraw_model->addMemberWithdrawStat($temp_params);
|
||||
break;
|
||||
case 'add_member':
|
||||
$member_model = new MemberStat();
|
||||
$result = $member_model->addMemberStat($temp_params);
|
||||
break;
|
||||
case 'goods_cart'://购物车加购
|
||||
$goods_cart_stat_model = new GoodsCartStat();
|
||||
$result = $goods_cart_stat_model->addGoodsCartStat($temp_params);
|
||||
break;
|
||||
case 'goods_visit':
|
||||
$goods_stat_model = new GoodsStat();
|
||||
$result = $goods_stat_model->addGoodsVisit($temp_params);
|
||||
break;
|
||||
case 'goods_on'://上下架
|
||||
$goods_stat_model = new GoodsStat();
|
||||
$result = $goods_stat_model->addGoodsOnStat($temp_params);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计入库(按天)
|
||||
* @param $data
|
||||
*/
|
||||
public function addStatShopModel($data)
|
||||
{
|
||||
$condition = [
|
||||
'site_id' => $data['site_id'],
|
||||
'year' => $data['year'],
|
||||
'month' => $data['month'],
|
||||
'day' => $data['day']
|
||||
];
|
||||
$info = model('stat_shop')->getInfo($condition, 'id');
|
||||
if(empty($info)){
|
||||
model('stat_shop')->add($data);
|
||||
}else{
|
||||
$update_data = [];
|
||||
|
||||
if(isset($data['site_id'])) unset($data['site_id']);
|
||||
if(isset($data['year'])) unset($data['year']);
|
||||
if(isset($data['month'])) unset($data['month']);
|
||||
if(isset($data['day'])) unset($data['day']);
|
||||
if(isset($data['day_time'])) unset($data['day_time']);
|
||||
|
||||
foreach ($data as $k => $v) {
|
||||
if ($v > 0) {
|
||||
$update_data[ $k ] = Db::raw($k . '+' . $v);
|
||||
} else if ($v < 0) {
|
||||
$update_data[ $k ] = Db::raw($k . '-' . abs($v));
|
||||
}
|
||||
}
|
||||
model('stat_shop')->update($update_data, $condition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计入库(按时)
|
||||
* @param $data
|
||||
*/
|
||||
public function addStatShopHourModel($data)
|
||||
{
|
||||
$condition = [
|
||||
'site_id' => $data['site_id'],
|
||||
'year' => $data['year'],
|
||||
'month' => $data['month'],
|
||||
'day' => $data['day'],
|
||||
'hour' => $data['hour']
|
||||
];
|
||||
$info = model('stat_shop_hour')->getInfo($condition, 'id');
|
||||
if(empty($info)){
|
||||
model('stat_shop_hour')->add($data);
|
||||
}else{
|
||||
$update_data = [];
|
||||
|
||||
if(isset($data['site_id'])) unset($data['site_id']);
|
||||
if(isset($data['year'])) unset($data['year']);
|
||||
if(isset($data['month'])) unset($data['month']);
|
||||
if(isset($data['day'])) unset($data['day']);
|
||||
if(isset($data['hour'])) unset($data['hour']);
|
||||
if(isset($data['day_time'])) unset($data['day_time']);
|
||||
|
||||
foreach ($data as $k => $v) {
|
||||
if ($v > 0) {
|
||||
$update_data[ $k ] = Db::raw($k . '+' . $v);
|
||||
} else if ($v < 0) {
|
||||
$update_data[ $k ] = Db::raw($k . '-' . abs($v));
|
||||
}
|
||||
}
|
||||
model('stat_shop_hour')->update($update_data, $condition);
|
||||
}
|
||||
}
|
||||
}
|
||||
58
app/model/system/SystemConfig.php
Executable file
58
app/model/system/SystemConfig.php
Executable file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use think\facade\Queue;
|
||||
|
||||
/**
|
||||
* 系统配置
|
||||
*/
|
||||
class SystemConfig extends BaseModel
|
||||
{
|
||||
|
||||
/**
|
||||
* 系统配置
|
||||
* @param int $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function getSystemConfig($site_id = 0)
|
||||
{
|
||||
return $this->success([ 'is_open_queue' => 0 ]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验消息队列是否正常运行
|
||||
* @return bool
|
||||
*/
|
||||
public function checkJob()
|
||||
{
|
||||
$queue_default = config('queue.default');
|
||||
if($queue_default != 'sync'){
|
||||
$secret = uniqid('', true);
|
||||
$file = root_path('runtime') . $secret . '.job';
|
||||
try {
|
||||
Queue::push('app\job\system\CheckJob', [ 'file' => $file ]);
|
||||
} catch ( \Exception $e) {
|
||||
return false;
|
||||
}
|
||||
sleep(3);
|
||||
if (file_exists($file)) {
|
||||
@unlink($file);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
496
app/model/system/Upgrade.php
Executable file
496
app/model/system/Upgrade.php
Executable file
@@ -0,0 +1,496 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use extend\api\HttpClient;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Db;
|
||||
|
||||
class Upgrade extends BaseModel
|
||||
{
|
||||
private $url;
|
||||
private $code = '';
|
||||
private $cert = '';
|
||||
|
||||
public function __construct($code = '')
|
||||
{
|
||||
$this->code = defined('NIUSHOP_AUTH_CODE') ? NIUSHOP_AUTH_CODE : '';
|
||||
$this->cert = file_exists('cert.key') ? file_get_contents('cert.key') : '';
|
||||
$this->url = 'https://api.niushop.com';
|
||||
}
|
||||
|
||||
/**
|
||||
* post 服务器请求
|
||||
*/
|
||||
private function doPost($post_url, $post_data)
|
||||
{
|
||||
$post_data[ 'code' ] = $this->code;
|
||||
$post_data[ 'cert' ] = $this->cert;
|
||||
$httpClient = new HttpClient();
|
||||
$res = $httpClient->post($this->url . $post_url . "?url=" . request()->domain(), $post_data);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在线下载文件
|
||||
* @return bool|string
|
||||
*/
|
||||
public function test()
|
||||
{
|
||||
$result = $this->doPost('/upgrade/upgrade/test', []);//授权
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取可升级的版本信息
|
||||
*/
|
||||
public function getSystemUpgradeInfo()
|
||||
{
|
||||
$app_info = config('info');
|
||||
$addon_array = array_map('basename', glob('addon/*', GLOB_ONLYDIR));
|
||||
$plugin_info = [];
|
||||
foreach ($addon_array as $addon) {
|
||||
$addon_info_path = "addon/{$addon}/config/info.php";
|
||||
if (file_exists($addon_info_path)) {
|
||||
$info = include_once $addon_info_path;
|
||||
$plugin_info[] = [
|
||||
'code' => $info[ 'name' ],
|
||||
'version_no' => $info[ 'version_no' ],
|
||||
'version_name' => $info[ 'version' ],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$post_data = [
|
||||
'app_info' => [
|
||||
'code' => $app_info[ 'name' ],
|
||||
'version_no' => $app_info[ 'version_no' ],
|
||||
'version_name' => $app_info[ 'version' ],
|
||||
],
|
||||
'plugin_info' => $plugin_info
|
||||
];
|
||||
|
||||
$res = $this->doPost('/upgrade/upgrade/updateinfo', $post_data);
|
||||
$res = json_decode($res, true);
|
||||
|
||||
//处理返回数据
|
||||
if (!empty($res) && $res[ 'code' ] == 0) {
|
||||
//整合系统和插件数据
|
||||
$app_data = $res[ 'data' ][ 'app_data' ];
|
||||
$client_data = $res[ 'data' ][ 'client_data' ];
|
||||
$plugin_data = $res[ 'data' ][ 'plugin_data' ];
|
||||
$install_data = $res[ 'data' ][ 'install_data' ];
|
||||
$data = [];
|
||||
if ($app_data[ 'code' ] == 0) {
|
||||
$app_data[ 'data' ][ 'action' ] = 'upgrade';
|
||||
$app_data[ 'data' ][ 'action_name' ] = '升级';
|
||||
$app_data[ 'data' ][ 'type' ] = 'system';
|
||||
$app_data[ 'data' ][ 'type_name' ] = '系统';
|
||||
$data[] = $app_data[ 'data' ];
|
||||
}
|
||||
foreach ($client_data as $key => $val) {
|
||||
if ($val[ 'code' ] == 0) {
|
||||
$val[ 'data' ][ 'action' ] = 'download';
|
||||
$val[ 'data' ][ 'action_name' ] = '下载';
|
||||
$val[ 'data' ][ 'type' ] = 'client';
|
||||
$val[ 'data' ][ 'type_name' ] = '客户端';
|
||||
$data[] = $val[ 'data' ];
|
||||
}
|
||||
}
|
||||
foreach ($plugin_data as $key => $val) {
|
||||
if ($val[ 'code' ] == 0) {
|
||||
$val[ 'data' ][ 'action' ] = 'upgrade';
|
||||
$val[ 'data' ][ 'action_name' ] = '升级';
|
||||
$val[ 'data' ][ 'type' ] = 'addon';
|
||||
$val[ 'data' ][ 'type_name' ] = '插件';
|
||||
$data[] = $val[ 'data' ];
|
||||
}
|
||||
}
|
||||
foreach ($install_data as $key => $val) {
|
||||
if ($val[ 'code' ] == 0) {
|
||||
$val[ 'data' ][ 'action' ] = 'install';
|
||||
$val[ 'data' ][ 'action_name' ] = '安装';
|
||||
$val[ 'data' ][ 'type' ] = 'addon';
|
||||
$val[ 'data' ][ 'type_name' ] = '插件';
|
||||
$data[] = $val[ 'data' ];
|
||||
}
|
||||
}
|
||||
|
||||
//处理更新说明的换行
|
||||
foreach ($data as $key => $val) {
|
||||
foreach ($val[ 'scripts' ] as $k => $v) {
|
||||
$val[ 'scripts' ][ $k ][ 'description' ] = str_replace("\n", '<br/>', $v[ 'description' ]);
|
||||
}
|
||||
$data[ $key ] = $val;
|
||||
}
|
||||
$res[ 'data' ] = $data;
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在线下载文件
|
||||
* @param $param
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function download($param)
|
||||
{
|
||||
$data = array (
|
||||
"file_token" => $param[ "token" ]
|
||||
);
|
||||
$result = $this->doPost('/upgrade/upgrade/download', $data);//授权
|
||||
if (empty($result)) {
|
||||
return $this->error();
|
||||
}
|
||||
|
||||
$result = json_decode($result, true);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取授权信息
|
||||
* @return bool|mixed|string
|
||||
*/
|
||||
public function authInfo()
|
||||
{
|
||||
$app_info = config('info');
|
||||
$data = array (
|
||||
"product_key" => $app_info[ 'name' ],
|
||||
);
|
||||
$re = $this->doPost('/upgrade/auth/info', $data);
|
||||
$re = json_decode($re, true);
|
||||
return $re;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有插件
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function getAuthPlugin()
|
||||
{
|
||||
$result = $this->doPost('/upgrade/auth/plugin', []);//授权
|
||||
if (empty($result))
|
||||
return $this->error();
|
||||
|
||||
|
||||
$result = json_decode($result, true);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有表
|
||||
*/
|
||||
public function getDatabaseList()
|
||||
{
|
||||
$databaseList = Db::query("SHOW TABLE STATUS");
|
||||
return $databaseList;
|
||||
}
|
||||
|
||||
/******************************* 升级日志相关 start *****************************/
|
||||
|
||||
/**
|
||||
* 添加升级日志
|
||||
* @param $data
|
||||
* upgrade_time 升级时间
|
||||
* version_info 升级的版本信息
|
||||
* backup_root 备份文件和sql的根目录
|
||||
* download_root 下载文件和sql的根目录
|
||||
* @return array
|
||||
*/
|
||||
public function addUpgradeLog($data)
|
||||
{
|
||||
$res = model('sys_upgrade_log')->add($data);
|
||||
if ($res == false) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
} else {
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改日志
|
||||
* @return array
|
||||
*/
|
||||
public function editUpgradeLog($data, $condition)
|
||||
{
|
||||
$res = model('sys_upgrade_log')->update($data, $condition);
|
||||
if ($res == false) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
} else {
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取升级日志信息
|
||||
* @param $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getUpgradeLogInfo($condition, $field = '*')
|
||||
{
|
||||
$info = model('sys_upgrade_log')->getInfo($condition, $field);
|
||||
if (!empty($info)) {
|
||||
$info[ 'version_info' ] = json_decode($info[ 'version_info' ], true);
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取升级分页列表
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getUpgradeLogPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
|
||||
{
|
||||
$list = model('sys_upgrade_log')->pageList($condition, $field, $order, $page, $page_size);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取升级日志列表
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
* @param string $order
|
||||
* @param null $limit
|
||||
* @return array
|
||||
*/
|
||||
public function getUpgradeLogList($condition = [], $field = '*', $order = '', $limit = null)
|
||||
{
|
||||
$list = model('sys_upgrade_log')->getList($condition, $field, $order, '', '', '', $limit);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除升级日志
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function deleteUpgradeLog($condition)
|
||||
{
|
||||
$log_list = model('sys_upgrade_log')->getList($condition, '*', 'upgrade_time asc');
|
||||
try {
|
||||
foreach ($log_list as $log) {
|
||||
$backup_root = $log[ 'backup_root' ];
|
||||
if (is_dir($backup_root)) {
|
||||
unlink($backup_root);
|
||||
}
|
||||
}
|
||||
model('sys_upgrade_log')->delete($condition);
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/******************************* 升级日志相关 end *****************************/
|
||||
|
||||
public function getVersionLog($page, $page_size)
|
||||
{
|
||||
$app_info = config('info');
|
||||
$post_data = [
|
||||
'page_index' => $page,
|
||||
'page_size' => $page_size,
|
||||
'product_key' => $app_info[ 'name' ]
|
||||
];
|
||||
$re = $this->doPost('/upgrade/upgrade/versionPage', $post_data);
|
||||
$re = json_decode($re, true);
|
||||
if (!empty($re[ 'data' ])) {
|
||||
|
||||
//处理返回数据
|
||||
$return_data = [];
|
||||
foreach ($re[ 'data' ][ 'list' ] as $key => $val) {
|
||||
$val[ 'version_desc' ] = str_replace("\n", '<br/>', $val[ 'version_desc' ]);
|
||||
$day = date('Y-m-d', $val[ 'create_time' ]);
|
||||
$day_time = strtotime($day);
|
||||
$return_data[ $day_time ][] = $val;
|
||||
}
|
||||
|
||||
$temp_arr = [];
|
||||
foreach ($return_data as $key => $value) {
|
||||
$temp_arr[] = [ 'list' => $value, 'time' => $key, 'format_time' => date('Y-m-d', $key) ];
|
||||
}
|
||||
|
||||
$re[ 'data' ][ 'list' ] = $temp_arr;
|
||||
} else {
|
||||
$re[ 'data' ][ 'list' ] = [];
|
||||
}
|
||||
return $re;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有插件
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function getPluginGoodsList()
|
||||
{
|
||||
$addon_list = Cache::get('website_addon_list');
|
||||
if (empty($addon_list)) {
|
||||
$app_info = config('info');
|
||||
$data = array (
|
||||
"product_key" => $app_info[ 'name' ],
|
||||
);
|
||||
$result = $this->doPost('/upgrade/auth/allplugin', $data);//授权
|
||||
if (empty($result))
|
||||
return $this->error();
|
||||
|
||||
$result = json_decode($result, true);
|
||||
Cache::set('website_addon_list', $result[ 'data' ], 3 * 24 * 60 * 60);
|
||||
return $result[ 'data' ];
|
||||
} else {
|
||||
return $addon_list;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载uniapp
|
||||
* @param $version
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function downloadUniapp($version)
|
||||
{
|
||||
$data = array (
|
||||
"version" => $version
|
||||
);
|
||||
$result = $this->doPost('/upgrade/upgrade/downloaduniapp', $data);//授权
|
||||
|
||||
if (empty($result))
|
||||
return $this->error();
|
||||
|
||||
$result = json_decode($result, true);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取应用更新日志
|
||||
* @return mixed
|
||||
*/
|
||||
public function getUpdateLog()
|
||||
{
|
||||
$app_info = config('info');
|
||||
$post_data = [
|
||||
'product_key' => $app_info[ 'name' ]
|
||||
];
|
||||
$re = $this->doPost('/upgrade/upgrade/updateLog', $post_data);
|
||||
$re = json_decode($re, true);
|
||||
return $re;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取补丁列表
|
||||
* @param array $param
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPatchLists($param = [])
|
||||
{
|
||||
$app_info = config('info');
|
||||
$existed_addons = array_map('basename', glob('addon/*', GLOB_ONLYDIR));
|
||||
$post_data = [
|
||||
'product_key' => $app_info[ 'name' ],
|
||||
'version_name' => $app_info[ 'version' ],
|
||||
'page' => $param[ 'page' ] ?? 1,
|
||||
'page_size' => $param[ 'page_size' ] ?? PAGE_LIST_ROWS,
|
||||
'addons' => join(',',$existed_addons),
|
||||
];
|
||||
$re = $this->doPost('/upgrade/upgrade/patchLists', $post_data);
|
||||
$re = json_decode($re, true);
|
||||
|
||||
if(!empty($re['data']['list'])){
|
||||
$patch_ids = array_column($re['data']['list'], 'id');
|
||||
$patch_list = model('sys_patch')->getList([['patch_id', 'in', $patch_ids]]);
|
||||
$patch_list = array_column($patch_list, null, 'patch_id');
|
||||
foreach($re['data']['list'] as &$val){
|
||||
$val['patch_res'] = $patch_list[$val['id']] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
return $re;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理补丁结果
|
||||
* @param $patch_id
|
||||
* @param $patch_res
|
||||
* @return array
|
||||
*/
|
||||
public function dealPatchRes($patch_id, $patch_res)
|
||||
{
|
||||
$info = model('sys_patch')->getInfo([['patch_id', '=', $patch_id]]);
|
||||
if(!empty($info)){
|
||||
model('sys_patch')->update([
|
||||
'patch_res' => $patch_res,
|
||||
'patch_time' => time(),
|
||||
], [['patch_id', '=', $patch_id]]);
|
||||
}else{
|
||||
model('sys_patch')->add([
|
||||
'patch_id' => $patch_id,
|
||||
'patch_res' => $patch_res,
|
||||
'patch_time' => time(),
|
||||
]);
|
||||
}
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载补丁
|
||||
* @param $patch_id
|
||||
* @param $patch_link
|
||||
* @return array
|
||||
*/
|
||||
public function downloadPatch($patch_id, $patch_link)
|
||||
{
|
||||
try{
|
||||
$info = model('sys_patch')->getInfo([['patch_id', '=', $patch_id]]);
|
||||
if(!empty($info['patch_link'])){
|
||||
@unlink($info['patch_link']);
|
||||
}
|
||||
|
||||
$temp_dir = "upload/version/patch/";
|
||||
if (!is_dir($temp_dir)) mkdir($temp_dir, 0777, true);
|
||||
$arrContextOptions = array(
|
||||
"ssl" => array(
|
||||
"verify_peer" => false,
|
||||
"verify_peer_name" => false,
|
||||
"allow_self_signed" => true,
|
||||
),
|
||||
);
|
||||
$fileContent = file_get_contents($patch_link, false, stream_context_create($arrContextOptions));
|
||||
$temp_file = $temp_dir . uniqid() . ".zip";
|
||||
file_put_contents($temp_file, $fileContent);
|
||||
|
||||
if(!empty($info)){
|
||||
model('sys_patch')->update([
|
||||
'patch_link' => $temp_file,
|
||||
], [['patch_id', '=', $patch_id]]);
|
||||
}else{
|
||||
model('sys_patch')->add([
|
||||
'patch_id' => $patch_id,
|
||||
'patch_link' => $temp_file,
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->success([
|
||||
'patch_link' => $temp_file,
|
||||
]);
|
||||
}catch(\Exception $e){
|
||||
return $this->error(null, '下载错误');
|
||||
}
|
||||
}
|
||||
}
|
||||
824
app/model/system/User.php
Executable file
824
app/model/system/User.php
Executable file
@@ -0,0 +1,824 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use app\model\store\Store;
|
||||
use think\facade\Session;
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 管理员模型
|
||||
*/
|
||||
class User extends BaseModel
|
||||
{
|
||||
/*******************************************************************用户 编辑查询 start*****************************************************/
|
||||
|
||||
/**
|
||||
* 添加用户
|
||||
* @param $data
|
||||
* @param int $store_id
|
||||
* @param string $source_type register 注册 add 添加
|
||||
* @return array
|
||||
*/
|
||||
public function addUser($data, $store_id = 0, $source_type = 'register')
|
||||
{
|
||||
$site_id = $data[ 'site_id' ] ?? '';
|
||||
$app_module = $data[ 'app_module' ] ?? '';
|
||||
$member_id = $data[ 'member_id' ] ?? 0;
|
||||
|
||||
if ($site_id === '') return $this->error('', 'REQUEST_SITE_ID');
|
||||
if ($app_module === '') return $this->error('', 'REQUEST_APP_MODULE');
|
||||
if (empty($data[ "username" ])) return $this->error('', '用户名不能为空');
|
||||
if (empty($data[ "password" ])) return $this->error('', '密码不能为空');
|
||||
|
||||
//判断 用户名 是否存在
|
||||
$user_info = model('user')->getInfo(
|
||||
[
|
||||
[ 'username', "=", $data[ "username" ] ],
|
||||
[ 'site_id', '=', $site_id ],
|
||||
[ 'app_module', '=', $app_module ]
|
||||
]
|
||||
);
|
||||
|
||||
if ($source_type == 'add') {
|
||||
if (!empty($user_info)) {
|
||||
return $this->error('', '账号已存在');
|
||||
}
|
||||
} else {
|
||||
if (!empty($user_info)) {
|
||||
if (data_md5($data[ "password" ]) == $user_info[ 'password' ]) {
|
||||
return $this->success(2);
|
||||
} else {
|
||||
return $this->error('', '账号已存在');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($member_id > 0) {
|
||||
$temp_condition = array (
|
||||
"app_module" => $data[ "app_module" ],
|
||||
"member_id" => $member_id
|
||||
);
|
||||
$temp_count = model('user')->getCount($temp_condition, 'uid');
|
||||
if ($temp_count > 0) {
|
||||
return $this->error('', 'USERNAME_EXISTED');
|
||||
}
|
||||
}
|
||||
|
||||
$group_id = $data[ 'group_id' ] ?? 0;
|
||||
$data[ "group_name" ] = '';
|
||||
if ($group_id > 0) {
|
||||
$group_model = new Group();
|
||||
$group_info = $group_model->getGroupInfo([ [ "group_id", "=", $group_id ], [ "site_id", "=", $site_id ], [ "app_module", "=", $app_module ] ], "group_name")[ 'data' ];
|
||||
$data[ "group_name" ] = $group_info[ "group_name" ] ?? '';
|
||||
}
|
||||
|
||||
$data[ "password" ] = data_md5($data[ "password" ]);
|
||||
$data[ "create_time" ] = time();
|
||||
|
||||
//记录创建用户信息
|
||||
if($source_type == 'add' && isset($data['create_uid'])){
|
||||
$user_info = model('user')->getInfo([['uid', '=', $data['create_uid']]], 'uid,username,create_user_data');
|
||||
$create_user_data = json_decode($user_info['create_user_data'], true);
|
||||
$create_user_data[] = ['id' => (string)$user_info['uid'], 'name' => $user_info['username']];
|
||||
$data['create_user_data'] = json_encode($create_user_data, JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
model("user")->startTrans();
|
||||
try {
|
||||
$uid = model("user")->add($data);
|
||||
if ($uid === false) {
|
||||
model("user")->rollback();
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
if (isset($data[ 'store' ]) && !empty($data[ 'store' ])) {
|
||||
$store_user_list = [];
|
||||
foreach ($data[ 'store' ] as $item) {
|
||||
if (empty($item[ 'store_id' ])) {
|
||||
model("user")->rollback();
|
||||
return $this->error('', '门店id不能为空');
|
||||
}
|
||||
if (empty($item[ 'group_id' ])) {
|
||||
model("user")->rollback();
|
||||
return $this->error('', '门店角色不能为空');
|
||||
}
|
||||
array_push($store_user_list, [
|
||||
'uid' => $uid,
|
||||
'site_id' => $data[ 'site_id' ],
|
||||
'store_id' => $item[ 'store_id' ],
|
||||
'group_id' => $item[ 'group_id' ],
|
||||
'create_time' => time(),
|
||||
'app_module' => 'store'
|
||||
]);
|
||||
}
|
||||
model('user_group')->addList($store_user_list);
|
||||
}
|
||||
model("user")->commit();
|
||||
return $this->success($uid);
|
||||
} catch (\Exception $e) {
|
||||
model("user")->rollback();
|
||||
return $this->error('', '用户添加失败');
|
||||
}
|
||||
}
|
||||
|
||||
public function getUserColumn($condition = [], $field = '')
|
||||
{
|
||||
$res = model('user')->getColumn($condition, $field);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑用户
|
||||
* @param $data
|
||||
* @param $condition
|
||||
* @param int $store_id
|
||||
* @return array
|
||||
*/
|
||||
public function editUser($data, $condition, $store_id = 0)
|
||||
{
|
||||
$check_condition = array_column($condition, 2, 0);
|
||||
$site_id = $check_condition[ 'site_id' ] ?? '';
|
||||
$app_module = $check_condition[ 'app_module' ] ?? '';
|
||||
$uid = $check_condition[ 'uid' ] ?? '';
|
||||
if ($uid === '') {
|
||||
return $this->error('', '缺少必须参数UID');
|
||||
}
|
||||
if ($site_id === '') {
|
||||
return $this->error('', 'REQUEST_SITE_ID');
|
||||
}
|
||||
if ($app_module === '') {
|
||||
return $this->error('', 'REQUEST_APP_MODULE');
|
||||
}
|
||||
$group_id = $data[ 'group_id' ] ?? 0;
|
||||
$data[ "group_name" ] = '';
|
||||
if ($group_id > 0) {
|
||||
$group_model = new Group();
|
||||
$group_info = $group_model->getGroupInfo([ [ "group_id", "=", $group_id ], [ "site_id", "=", $site_id ], [ 'app_module', '=', $app_module ] ], "group_name")[ 'data' ];
|
||||
$data[ "group_name" ] = $group_info[ "group_name" ] ?? '';
|
||||
}
|
||||
model('user')->startTrans();
|
||||
try {
|
||||
$res = model("user")->update($data, $condition);
|
||||
if ($res === false) {
|
||||
model('user')->rollback();
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
|
||||
model('user_group')->delete([ [ 'site_id', '=', $site_id ], [ 'uid', '=', $uid ], [ 'app_module', '=', 'store' ] ]);
|
||||
if (isset($data[ 'store' ]) && !empty($data[ 'store' ])) {
|
||||
$store_user_list = [];
|
||||
foreach ($data[ 'store' ] as $item) {
|
||||
if (empty($item[ 'store_id' ])) {
|
||||
model("user")->rollback();
|
||||
return $this->error('', '门店id不能为空');
|
||||
}
|
||||
if (empty($item[ 'group_id' ])) {
|
||||
model("user")->rollback();
|
||||
return $this->error('', '门店角色不能为空');
|
||||
}
|
||||
array_push($store_user_list, [
|
||||
'uid' => $uid,
|
||||
'site_id' => $site_id,
|
||||
'store_id' => $item[ 'store_id' ],
|
||||
'group_id' => $item[ 'group_id' ],
|
||||
'create_time' => time(),
|
||||
'app_module' => 'store'
|
||||
]);
|
||||
}
|
||||
model('user_group')->addList($store_user_list);
|
||||
}
|
||||
|
||||
model("user")->commit();
|
||||
return $this->success($res);
|
||||
} catch (\Exception $e) {
|
||||
model("user")->rollback();
|
||||
return $this->error('', '用户编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑用户状态
|
||||
* @param $status
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function modifyUserStatus($status, $condition)
|
||||
{
|
||||
$check_condition = array_column($condition, 2, 0);
|
||||
$site_id = $check_condition[ 'site_id' ] ?? '';
|
||||
if ($site_id === '') {
|
||||
return $this->error('', 'REQUEST_SITE_ID');
|
||||
}
|
||||
$data = array (
|
||||
"status" => $status,
|
||||
"update_time" => time()
|
||||
);
|
||||
$res = model('user')->update($data, $condition);
|
||||
if ($res === false) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
* @param $password
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function modifyUserPassword($password, $condition)
|
||||
{
|
||||
$res = model('user')->update([ 'password' => data_md5($password) ], $condition);
|
||||
if ($res === false) {
|
||||
return $this->error('', 'RESULT_ERROR');
|
||||
}
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统用户修改密码
|
||||
* @param $condition
|
||||
* @param $new_password
|
||||
* @return array
|
||||
*/
|
||||
public function modifyAdminUserPassword($condition, $new_password)
|
||||
{
|
||||
if (addon_is_exit("demo")) {
|
||||
return $this->error('', '权限不足,请联系客服');
|
||||
}
|
||||
$res = model('user')->getInfo($condition, "uid,password");
|
||||
if (!empty($res)) {
|
||||
$data = array (
|
||||
'password' => data_md5($new_password)
|
||||
);
|
||||
$res = model('user')->update($data, $condition);
|
||||
return $this->success($res, 'SUCCESS');
|
||||
} else {
|
||||
return $this->error('', 'PASSWORD_ERROR');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function deleteUser($condition)
|
||||
{
|
||||
$check_condition = array_column($condition, 2, 0);
|
||||
$app_module = $check_condition[ 'app_module' ] ?? '';
|
||||
$uid = $check_condition[ 'uid' ] ?? '';
|
||||
if ($uid === '') {
|
||||
return $this->error('', '缺少必须参数UID');
|
||||
}
|
||||
if ($app_module === '') {
|
||||
return $this->error('', 'REQUEST_APP_MODULE');
|
||||
}
|
||||
|
||||
//自己和下属都删除
|
||||
$uid_arr = model('user')->getColumn([['create_user_data', 'like', '%"'.$uid.'"%']], 'uid');
|
||||
$uid_arr[] = $uid;
|
||||
|
||||
$res = model('user')->delete([['uid', 'in', $uid_arr]]);
|
||||
if ($res === false) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
|
||||
//用户组也删除
|
||||
model('user_group')->delete([ [ 'uid', 'in', $uid_arr ] ]);
|
||||
model('group')->delete([['create_uid', 'in', $uid_arr]]);
|
||||
if(addon_is_exit('cashier')){
|
||||
model('cashier_auth_group')->delete([['create_uid', 'in', $uid_arr]]);
|
||||
}
|
||||
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除后台所有用户的登录信息
|
||||
* @param $app_module
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function deleteUserLoginInfo($app_module, $site_id)
|
||||
{
|
||||
$dir = './runtime/session';
|
||||
$this->deldir($dir);
|
||||
Session::delete($app_module . "_" . $site_id . ".uid");
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $dir
|
||||
*/
|
||||
public function deldir($dir)
|
||||
{
|
||||
//先删除目录下的文件:
|
||||
$dh = opendir($dir);
|
||||
while ($file = readdir($dh)) {
|
||||
if ($file != "." && $file != "..") {
|
||||
$fullpath = $dir . "/" . $file;
|
||||
if (!is_dir($fullpath)) {
|
||||
unlink($fullpath);
|
||||
} else {
|
||||
$this->deldir($fullpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @param $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getUserInfo($condition, $field = "uid, app_module, site_id, group_id, group_name, username, member_id, create_time, update_time, status, login_time, login_ip, is_admin")
|
||||
{
|
||||
$info = model('user')->getInfo($condition, $field);
|
||||
if (!empty($info)) {
|
||||
if (isset($info[ 'uid' ])) {
|
||||
if(isset($info['is_admin']) && isset($info['site_id']) && $info['is_admin'] == 1 && addon_is_exit('cashier', $info['site_id'])){
|
||||
//如果是超级管理员,默认有所有门店的管理员角色
|
||||
$join = [
|
||||
[ 'cashier_auth_group g', "g.keyword = 'admin'", 'inner' ],
|
||||
];
|
||||
$info[ 'user_group_list' ] = model('store')->getList([ [ 's.site_id', '=', $info[ 'site_id' ] ],['s.is_frozen', '=', 0] ], 's.store_id,s.store_name,g.group_id,g.menu_array', 's.is_default desc,store_id desc', 's', $join);
|
||||
}else{
|
||||
$join = [
|
||||
[ 'store s', 's.store_id = ug.store_id', 'inner' ],
|
||||
[ 'cashier_auth_group g', 'g.group_id = ug.group_id', 'inner' ]
|
||||
];
|
||||
$info[ 'user_group_list' ] = model('user_group')->getList([ [ 'ug.uid', '=', $info[ 'uid' ] ],['s.is_frozen', '=', 0] ], 's.store_id,s.store_name,g.group_id,g.menu_array', 's.is_default desc,store_id desc', 'ug', $join);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户列表
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
* @param string $order
|
||||
* @param null $limit
|
||||
* @return array
|
||||
*/
|
||||
public function getUserList($condition = [], $field = 'uid, app_module, site_id, group_id, username, member_id, create_time, update_time, status, login_time, login_ip, is_admin, group_name', $order = '', $limit = null)
|
||||
{
|
||||
$list = model('user')->getList($condition, $field, $order, '', '', '', $limit);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会员分页列表
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getUserPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = 'uid, app_module, site_id, group_id, username, member_id, create_time, update_time, status, login_time, login_ip, is_admin, group_name, login_time')
|
||||
{
|
||||
$list = model('user')->pageList($condition, $field, $order, $page, $page_size);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取站点用户分页列表
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @return array
|
||||
*/
|
||||
public function getSiteUserPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '')
|
||||
{
|
||||
$field = ' nu.uid, nu.app_module, nu.app_group,
|
||||
nu.is_admin, nu.site_id, nu.group_id, nu.group_name, nu.username, nu.member_id, nu.create_time,
|
||||
nu.update_time, nu.status, nu.login_time, nu.login_ip, ns.site_name,';
|
||||
$alias = 'nu';
|
||||
$join = [
|
||||
[
|
||||
'shop ns',
|
||||
'nu.site_id = ns.site_id',
|
||||
'left'
|
||||
],
|
||||
];
|
||||
$list = model("user")->pageList($condition, $field, $order, $page, $page_size, $alias, $join);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测权限,success:通过,error:拒绝
|
||||
* @param $url
|
||||
* @param $app_module
|
||||
* @param $group_info
|
||||
* @param string $addon
|
||||
* @return array
|
||||
*/
|
||||
public function checkAuth($url, $app_module, $group_info, $addon = '')
|
||||
{
|
||||
$auth_control = event("AuthControl", [ 'url' => $url, 'app_module' => $app_module ], 1);
|
||||
if (!empty($auth_control)) {
|
||||
if ($auth_control[ 'code' ] < 0) {
|
||||
return $this->error();
|
||||
}
|
||||
}
|
||||
|
||||
// 权限组
|
||||
if (empty($group_info)) {
|
||||
return $this->error();
|
||||
}
|
||||
|
||||
if ($group_info[ 'is_system' ] == 1) {
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
$menu_model = new Menu();
|
||||
$menu_info = $menu_model->getMenuInfoByUrl($url, $app_module, $addon)[ 'data' ];
|
||||
|
||||
if (!empty($menu_info)) {
|
||||
if ($menu_info[ 'is_control' ] == 0) {
|
||||
return $this->success();
|
||||
}
|
||||
if (strpos(',' . $group_info[ 'menu_array' ] . ',', ',' . $menu_info[ 'name' ] . ',') !== false) {
|
||||
return $this->success();
|
||||
} else {
|
||||
return $this->error($menu_info);
|
||||
}
|
||||
} else {
|
||||
$count = $menu_model->getMenuCount([ [ 'url', '=', $url ] ])['data'];
|
||||
if ($count > 0) {
|
||||
return $this->error();
|
||||
}
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测和获取重定向信息
|
||||
* @param $url_param
|
||||
* @param $group_info
|
||||
* @return array
|
||||
*/
|
||||
public function checkAndGetRedirectUrl($url_param, $group_info)
|
||||
{
|
||||
//静态处理不用重复查询
|
||||
static $menu_tree_data = null;
|
||||
static $menu_tree_md5 = '';
|
||||
|
||||
$res = [
|
||||
'is_auth' => false,
|
||||
'redirect_url' => '',
|
||||
];
|
||||
|
||||
$menu_model = new Menu();
|
||||
|
||||
//链接对应的菜单
|
||||
$menu_info = $menu_model->getMenuList([
|
||||
['url', '=', $url_param['url']],
|
||||
['app_module', '=', $url_param['app_module']],
|
||||
], '*', 'level desc')[ 'data' ][0] ?? null;
|
||||
|
||||
//1、菜单不存在默认可以访问
|
||||
if(empty($menu_info)){
|
||||
$res['is_auth'] = true;
|
||||
return $res;
|
||||
}
|
||||
//2、菜单不控制权限可以访问
|
||||
if($menu_info['is_control'] == 0){
|
||||
$res['is_auth'] = true;
|
||||
return $res;
|
||||
}
|
||||
|
||||
//菜单路径
|
||||
$crumbs = [$menu_info];
|
||||
while ($menu_info['parent']){
|
||||
$menu_info = $menu_model->getMenuInfo([
|
||||
['name', '=', $menu_info['parent']],
|
||||
['app_module', '=', $url_param['app_module']],
|
||||
])[ 'data' ];
|
||||
array_unshift($crumbs, $menu_info);
|
||||
}
|
||||
|
||||
//权限树
|
||||
if(is_null($menu_tree_data) || md5($group_info[ 'menu_array' ]) != $menu_tree_md5){
|
||||
$menu_tree_md5 = md5($group_info[ 'menu_array' ]);
|
||||
$menu_array = "'".str_replace(',',"','", $group_info[ 'menu_array' ])."'";
|
||||
$menu_list = $menu_model->getMenuList([
|
||||
[ 'app_module', '=', $url_param['app_module'] ],
|
||||
['', 'exp', \think\facade\Db::raw("name in ({$menu_array}) or is_control = 0")]
|
||||
], '*', 'level asc,sort asc,id asc')['data'];
|
||||
$menu_tree_data = list_to_tree($menu_list, 'name', 'parent', 'child_list', '');
|
||||
}
|
||||
$menu_tree = $menu_tree_data;
|
||||
|
||||
//菜单路径和权限树进行比对,如果比对到最后则说明有权限,没有比对到最后要看产生分歧的分支的首个有权限菜单
|
||||
$is_to_last = true;
|
||||
foreach($crumbs as $menu_info){
|
||||
if(isset($menu_tree[$menu_info['name']])){
|
||||
$menu_tree = $menu_tree[$menu_info['name']]['child_list'];
|
||||
}else{
|
||||
$is_to_last = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//3、在权限集中可以访问
|
||||
if($is_to_last){
|
||||
$res['is_auth'] = true;
|
||||
return $res;
|
||||
}
|
||||
|
||||
//4、查找重定向链接,重定向访问
|
||||
$is_continue = true;
|
||||
while ($is_continue){
|
||||
$is_continue = false;
|
||||
foreach($menu_tree as $menu_info){
|
||||
if($menu_info['type'] == 'page'){
|
||||
$real_menu_info = $menu_info;
|
||||
$menu_tree = $menu_info['child_list'];
|
||||
$is_continue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!empty($real_menu_info)){
|
||||
if(strtolower($real_menu_info['url']) != strtolower($url_param['url'])){
|
||||
$res['redirect_url'] = $real_menu_info['url'];
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/*******************************************************************用户 编辑查询 end*****************************************************/
|
||||
|
||||
/*******************************************************************用户注册登录 start*****************************************************/
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
* @param $username
|
||||
* @param $password
|
||||
* @param string $app_module
|
||||
* @param int $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function login($username, $password, $app_module = 'shop', $site_id = 0)
|
||||
{
|
||||
$user_condition = [
|
||||
[ 'username', '=', $username ],
|
||||
[ 'app_module', '=', $app_module ],
|
||||
[ 'site_id', '=', $site_id ]
|
||||
];
|
||||
// if ($app_module == 'shop') $user_condition[] = [ 'group_id', '>', 0 ];
|
||||
$user_info = model('user')->getInfo($user_condition);
|
||||
if (empty($user_info)) {
|
||||
return $this->error('', 'USER_LOGIN_ERROR');
|
||||
}
|
||||
if ($user_info[ 'password' ] != data_md5($password)) {
|
||||
return $this->error('', 'USER_LOGIN_ERROR');
|
||||
}
|
||||
if ($user_info[ 'status' ] !== 1) {
|
||||
return $this->error([], 'USER_IS_LOCKED');
|
||||
}
|
||||
// 检查是否有权限登录
|
||||
if ($app_module == 'shop' && $user_info[ 'group_id' ] == 0) {
|
||||
return $this->error('', 'PERMISSION_DENIED');
|
||||
}
|
||||
$this->initLogin($user_info);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化登录
|
||||
* @param $user_info
|
||||
*/
|
||||
private function initLogin($user_info)
|
||||
{
|
||||
$time = time();
|
||||
//初始化登录信息
|
||||
$auth = array (
|
||||
'uid' => $user_info[ 'uid' ],
|
||||
'username' => $user_info[ 'username' ],
|
||||
'create_time' => $user_info[ 'create_time' ],
|
||||
'status' => $user_info[ 'status' ],
|
||||
'group_id' => $user_info[ "group_id" ],
|
||||
'site_id' => $user_info[ "site_id" ],
|
||||
'app_group' => $user_info[ "app_group" ],
|
||||
'is_admin' => $user_info[ 'is_admin' ],
|
||||
'login_time' => $time,
|
||||
'login_ip' => request()->ip(),
|
||||
'sys_uid' => $user_info[ 'sys_uid' ],
|
||||
'password' => $user_info[ 'password' ],
|
||||
'app_module' => $user_info[ 'app_module' ]
|
||||
);
|
||||
|
||||
//更新登录记录
|
||||
$data = [
|
||||
'login_time' => time(),
|
||||
'login_ip' => request()->ip(),
|
||||
];
|
||||
model('user')->update($data, [ [ 'uid', "=", $user_info[ 'uid' ] ] ]);
|
||||
Session::set($user_info[ 'app_module' ] . "_" . $user_info[ 'site_id' ] . ".uid", $user_info[ 'uid' ]);
|
||||
Session::set($user_info[ 'app_module' ] . "_" . $user_info[ 'site_id' ] . ".user_info", $auth);
|
||||
Session::set('app_module' . "_" . $user_info[ 'site_id' ] . ".login_module", $user_info[ 'app_module' ]);
|
||||
$this->addUserLog($user_info[ 'uid' ], $user_info[ 'username' ], $user_info[ 'site_id' ], "用户登录", []);//添加日志
|
||||
}
|
||||
|
||||
/**
|
||||
* uni-app端用户登录
|
||||
* @param $username
|
||||
* @param $password
|
||||
* @param $app_module
|
||||
* @return array
|
||||
*/
|
||||
public function uniAppLogin($username, $password, $app_module)
|
||||
{
|
||||
$time = time();
|
||||
// 验证参数 预留
|
||||
$user_info = $this->getUserInfo([ [ 'username', "=", $username ] ], 'uid,app_module,site_id,group_id,group_name,username,status,is_admin,password')[ 'data' ];
|
||||
if (empty($user_info)) {
|
||||
return $this->error('', 'USER_LOGIN_ERROR');
|
||||
} else if (data_md5($password) !== $user_info[ 'password' ]) {
|
||||
return $this->error([], 'PASSWORD_ERROR');
|
||||
} else if ($user_info[ 'status' ] !== 1) {
|
||||
return $this->error([], 'USER_IS_LOCKED');
|
||||
}
|
||||
|
||||
// 检查是否有权限登录
|
||||
if ($app_module == 'shop' && $user_info[ 'group_id' ] == 0) {
|
||||
return $this->error('', 'PERMISSION_DENIED');
|
||||
}
|
||||
|
||||
//更新登录记录
|
||||
$data = [
|
||||
'login_time' => $time,
|
||||
'login_ip' => request()->ip(),
|
||||
];
|
||||
model('user')->update($data, [ [ 'uid', "=", $user_info[ 'uid' ] ] ]);
|
||||
|
||||
$this->addUserLog($user_info[ 'uid' ], $user_info[ 'username' ], $user_info[ 'site_id' ], "用户登录", []); //添加日志
|
||||
|
||||
unset($user_info[ 'password' ]);
|
||||
return $this->success($user_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录uid
|
||||
* @param $app_module
|
||||
* @param int $site_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function uid($app_module, $site_id = 0)
|
||||
{
|
||||
return Session::get($app_module . "_" . $site_id . ".uid");
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录模块
|
||||
* @param $site_id
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function loginModule($site_id)
|
||||
{
|
||||
$login_module = Session::get('app_module' . "_" . $site_id . ".login_module");
|
||||
if (empty($login_module) || !strstr($_SERVER[ "REQUEST_URI" ], 'store/store')) {
|
||||
return 'shop';
|
||||
} else {
|
||||
return $login_module;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录管理员信息
|
||||
* @param $app_module
|
||||
* @param int $site_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function userInfo($app_module, $site_id = 0)
|
||||
{
|
||||
return Session::get($app_module . "_" . $site_id . ".user_info");
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前登录管理员信息
|
||||
* @param $user_info
|
||||
*/
|
||||
public function setUserInfo($user_info)
|
||||
{
|
||||
Session::set($user_info[ 'app_module' ] . "_" . $user_info[ 'site_id' ] . ".user_info", $user_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测当前登录管理员密码是否正确
|
||||
* @param $user_info
|
||||
* @param $app_module
|
||||
* @param int $site_id
|
||||
* @return int|mixed
|
||||
*/
|
||||
public function checkPassword($user_info, $app_module, $site_id = 0)
|
||||
{
|
||||
// 兼容v5.2.0版本,下个版本可以移除
|
||||
if (empty($user_info[ 'password' ])) {
|
||||
return 1;
|
||||
}
|
||||
$count = model('user')->getCount([
|
||||
[ 'site_id', '=', $site_id ],
|
||||
[ 'app_module', '=', $app_module ],
|
||||
[ 'uid', '=', $user_info[ 'uid' ] ],
|
||||
[ 'username', '=', $user_info[ 'username' ] ],
|
||||
[ 'password', '=', $user_info[ 'password' ] ]
|
||||
]);
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除登录信息
|
||||
*/
|
||||
public function clearLogin($app_module, $site_id = 0)
|
||||
{
|
||||
Session::delete($app_module . "_" . $site_id);
|
||||
}
|
||||
/*******************************************************************用户注册登录 end*****************************************************/
|
||||
|
||||
/*******************************************************************用户日志 start*****************************************************/
|
||||
|
||||
/**
|
||||
* 添加用户日志
|
||||
* @param $uid
|
||||
* @param $username
|
||||
* @param $site_id
|
||||
* @param $action_name
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function addUserLog($uid, $username, $site_id, $action_name, $data = [])
|
||||
{
|
||||
$url = request()->parseUrl();
|
||||
$ip = request()->ip();
|
||||
$log = array (
|
||||
"uid" => $uid,
|
||||
"username" => $username,
|
||||
"site_id" => $site_id,
|
||||
"url" => $url,
|
||||
"ip" => $ip,
|
||||
"data" => json_encode($data),
|
||||
"action_name" => $action_name,
|
||||
"create_time" => time(),
|
||||
);
|
||||
$res = model("user_log")->add($log);
|
||||
if ($res === false) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户日志
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function deleteUserLog($condition)
|
||||
{
|
||||
$check_condition = array_column($condition, 2, 0);
|
||||
$site_id = $check_condition[ 'site_id' ] ?? '';
|
||||
if ($site_id === '') {
|
||||
return $this->error('', 'REQUEST_SITE_ID');
|
||||
}
|
||||
|
||||
$res = model("user_log")->delete($condition);
|
||||
if ($res === false) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获用户员日志分页列表
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getUserLogPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = 'username, site_id, url, id, uid, data, ip, action_name, create_time')
|
||||
{
|
||||
$list = model('user_log')->pageList($condition, $field, $order, $page, $page_size);
|
||||
return $this->success($list);
|
||||
}
|
||||
/*******************************************************************用户日志 end*****************************************************/
|
||||
}
|
||||
70
app/model/system/UserGroup.php
Executable file
70
app/model/system/UserGroup.php
Executable file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 查询用户信息以user_group为主表
|
||||
* @author Administrator
|
||||
*/
|
||||
class UserGroup extends BaseModel
|
||||
{
|
||||
/**
|
||||
* @param array $condition
|
||||
* @param number $page
|
||||
* @param string $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return multitype:string mixed
|
||||
*/
|
||||
public function getUserPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'group_id desc', $field = '*', $alias = 'a', $join = [])
|
||||
{
|
||||
$list = model('user_group')->pageList($condition, $field, $order, $page, $page_size, $alias, $join);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
* @param string $alias
|
||||
* @param array $join
|
||||
* @return array
|
||||
*/
|
||||
public function getUserInfo($condition = [], $field = '*', $alias = 'a', $join = []){
|
||||
$list = model('user_group')->getInfo($condition, $field, $alias, $join);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
* @param string $alias
|
||||
* @param array $join
|
||||
* @return array
|
||||
*/
|
||||
public function getUserList($condition = [], $field = '*', $order = '', $alias = 'a', $join = []){
|
||||
$list = model('user_group')->getList($condition, $field, $order, $alias, $join);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function deleteUser($condition){
|
||||
$res = model('user_group')->delete($condition);
|
||||
if ($res) return $this->success();
|
||||
return $this->error();
|
||||
}
|
||||
}
|
||||
452
app/model/system/Visit.php
Executable file
452
app/model/system/Visit.php
Executable file
@@ -0,0 +1,452 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use think\facade\Cache;
|
||||
use think\Session;
|
||||
use think\facade\Db;
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 访问统计
|
||||
*/
|
||||
class Visit extends BaseModel
|
||||
{
|
||||
|
||||
/**
|
||||
* 获取访问信息(以日为基本单位)
|
||||
* @param $condition
|
||||
* @return \multitype
|
||||
*/
|
||||
public function getVisitInfo($condition)
|
||||
{
|
||||
$visit_model = model("nc_visit");//访问统计记录表
|
||||
$info = $visit_model->getInfo($condition);
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取访问ip信息(以日为基本单位)
|
||||
* @param $condition
|
||||
* @return \multitype
|
||||
*/
|
||||
public function getVisitIpInfo($condition)
|
||||
{
|
||||
$visit_ip_model = model("nc_visit_ip");//访问统计记录表
|
||||
$info = $visit_ip_model->getInfo($condition);
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户访问记录
|
||||
* @param $condition
|
||||
* @return \multitype
|
||||
*/
|
||||
public function getVisitUserInfo($condition)
|
||||
{
|
||||
$visit_user_model = model("nc_visit_user");//用户访问记录表
|
||||
$info = $visit_user_model->getInfo($condition);
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当日的访问数据写入
|
||||
* @param array $param
|
||||
*/
|
||||
public function todayVisit($param = [])
|
||||
{
|
||||
//加入防止写入过多无效访问
|
||||
$now_time = time();
|
||||
$today_date = date("Ymd");
|
||||
$expire_time = 1800;//过期的周期时长
|
||||
$visit_session_name = "visit_" . $param["site_id"] . "_" . $param["type"] . "_" . $param["module"] . "_" . $param["addon"] . "_" . $today_date;
|
||||
if (!empty(Session::get($visit_session_name)) && (Session::get($visit_session_name) + $expire_time) > $now_time) {
|
||||
return $this->success();
|
||||
}
|
||||
Session::set($visit_session_name, $now_time);//设置访问记录,存入时间
|
||||
$yesterday = date("Ymd", strtotime('-1 days'));
|
||||
Cache::clear("visit_info" . $yesterday);//清理昨天的缓存
|
||||
Cache::clear("visit_ip_info" . $yesterday);//清理昨天的缓存
|
||||
|
||||
$visit_model = model("nc_visit");//访问统计记录表
|
||||
$visit_ip_model = model("nc_visit_ip");//ip访问记录表
|
||||
$visit_user_model = model("nc_visit_user");//用户模块访问记录表
|
||||
// 启动事务
|
||||
|
||||
$ip_count = 0;
|
||||
//ip访问记录
|
||||
$ip = ip2long(getip());
|
||||
$vivit_ip_condition = array(
|
||||
"date" => $today_date,
|
||||
"site_id" => $param["site_id"],
|
||||
"type" => $param["type"],
|
||||
"module" => $param["module"],
|
||||
"ip" => $ip,
|
||||
"addon" => $param["addon"]
|
||||
);
|
||||
$visit_ip_result = $this->getVisitIpInfo($vivit_ip_condition);
|
||||
$visit_ip_info = $visit_ip_result["data"];
|
||||
$ip_data = array(
|
||||
"date" => $today_date,
|
||||
"site_id" => $param["site_id"],
|
||||
"type" => $param["type"],
|
||||
"module" => $param["module"],
|
||||
"ip" => $ip,
|
||||
"addon" => $param["addon"]
|
||||
);
|
||||
if (empty($visit_ip_info)) {
|
||||
$ip_count += 1;
|
||||
$ip_data["ip_count"] = 1;
|
||||
$visit_ip_res = $visit_ip_model->add($ip_data);
|
||||
} else {
|
||||
$ip_data["ip_count"] = $visit_ip_info["ip_count"] + 1;
|
||||
$visit_ip_res = $visit_ip_model->update($ip_data, $vivit_ip_condition);
|
||||
}
|
||||
Cache::tag("visit_ip_info" . $today_date)->set("visit_ip_info_" . $param["site_id"] . "_" . $param["type"] . "_" . $param["module"] . "_" . $param["addon"] . "_" . $ip["ip"] . "_" . $today_date, $ip_data);
|
||||
|
||||
//用户模块访问记录
|
||||
if ($param["uid"] > 0) {
|
||||
$visit_user_condition = array(
|
||||
"uid" => $param["uid"],
|
||||
"site_id" => $param["site_id"],
|
||||
"module" => $param["module"],
|
||||
"addon" => $param["addon"]
|
||||
);
|
||||
|
||||
$visit_user_result = $this->getVisitUserInfo($visit_user_condition);
|
||||
$visit_user_info = $visit_user_result["data"];
|
||||
$visit_user_data = array(
|
||||
"uid" => $param["uid"],
|
||||
"site_id" => $param["site_id"],
|
||||
"module" => $param["module"],
|
||||
"addon" => $param["addon"]
|
||||
);
|
||||
if (empty($visit_user_info)) {
|
||||
$visit_user_data["create_time"] = time();
|
||||
$visit_user_result = $visit_user_model->add($visit_user_data);
|
||||
} else {
|
||||
$visit_user_data["update_time"] = time();
|
||||
|
||||
$visit_user_result = $visit_user_model->update($visit_user_data, $visit_user_condition);
|
||||
}
|
||||
Cache::tag("visit_user_info" . $param["site_id"])->set("visit_user_info_" . $param["site_id"] . "_" . $param["uid"] . "_" . $param["module"] . "_" . $param["addon"], $visit_user_data);
|
||||
}
|
||||
|
||||
//访问记录
|
||||
$vivit_condition = array(
|
||||
"date" => $today_date,
|
||||
"site_id" => $param["site_id"],
|
||||
"type" => $param["type"],
|
||||
"module" => $param["module"],
|
||||
"addon" => $param["addon"]
|
||||
);
|
||||
|
||||
$visit_result = $this->getVisitInfo($vivit_condition);
|
||||
$visit_info = $visit_result["data"];
|
||||
//如果当前日不存在访问统计数据,则需要创建
|
||||
$data = array(
|
||||
"date" => $today_date,
|
||||
"site_id" => $param["site_id"],
|
||||
"type" => $param["type"],
|
||||
"module" => $param["module"],
|
||||
"addon" => $param["addon"]
|
||||
);
|
||||
if (empty($visit_info)) {
|
||||
$data["count"] = 1;
|
||||
$data["ip_count"] = $ip_count;
|
||||
$res = $visit_model->add($data);
|
||||
} else {
|
||||
$data["count"] = $visit_info["count"] + 1;
|
||||
$data["ip_count"] = $visit_info["ip_count"] + $ip_count;
|
||||
$res = $visit_model->update($data, $vivit_condition);
|
||||
}
|
||||
Cache::tag("visit_info" . $today_date)->set("visit_info_" . $param["site_id"] . "_" . $param["type"] . "_" . $param["module"] . "_" . $param["addon"] . "_" . $today_date, $data);
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询统计 访问数据
|
||||
* @param array $param
|
||||
*/
|
||||
public function getVisitStatisticsData($param = [])
|
||||
{
|
||||
$visit_model = model("nc_visit");//访问统计记录表
|
||||
$date_range = $param["date_range"] ?? [];//时间范围
|
||||
$date_type = $param["date_type"];//日期类型 用于查询方式
|
||||
$type = $param["type"];//访问类型查询
|
||||
if (empty($type) && !in_array($type, array('HOME', 'APP', 'API', 'ALL'))) {
|
||||
$type = "ALL";
|
||||
}
|
||||
$condition = array();
|
||||
|
||||
switch ($type) {
|
||||
case "HOME":
|
||||
$condition["type"] = ["in", ["admin", "sitehome"]];
|
||||
break;
|
||||
case "APP":
|
||||
$condition["type"] = ["in", ["wap", "web"]];
|
||||
break;
|
||||
case "API":
|
||||
$condition["type"] = ["in", ["api"]];
|
||||
break;
|
||||
}
|
||||
|
||||
//站点id
|
||||
if (!empty($param["site_id"])) {
|
||||
$condition["site_id"] = $param["site_id"];
|
||||
}
|
||||
$today_date = date('Ymd');//当前日日期
|
||||
$today_time = strtotime($today_date);
|
||||
switch ($date_type) {
|
||||
case 'today':
|
||||
$date_condition = $today_date;
|
||||
$date_x = periodGroup($today_time, $today_time);
|
||||
break;
|
||||
case 'yesterday':
|
||||
$yesterday = strtotime(date("Ymd", strtotime('-1 days')));
|
||||
$date_condition = date('Ymd', $yesterday);
|
||||
$date_x = periodGroup($yesterday, $yesterday);
|
||||
break;
|
||||
case 'week':
|
||||
$week = strtotime(date("Ymd", strtotime('-6 days')));
|
||||
$date_condition = ["between", [date('Ymd', $week), $today_date]];
|
||||
$date_x = periodGroup($week, $today_date);
|
||||
break;
|
||||
case 'month':
|
||||
$month = strtotime(date("Ymd", strtotime('-29 days')));
|
||||
$date_condition = ["between", [date('Ymd', $month), $today_date]];
|
||||
$date_x = periodGroup($month, $today_time);
|
||||
break;
|
||||
case 'daterange':
|
||||
$start_time = strtotime($date_range['start_date']);
|
||||
$end_time = strtotime($date_range['end_date']);
|
||||
$start_date = date('Ymd', $start_time);//开始日期
|
||||
$end_date = date('Ymd', $end_time);//结束日期
|
||||
$date_x = periodGroup($start_time, $end_time);
|
||||
$date_condition = ["between", [$start_date, $end_date]];
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (!empty($date_condition)) {
|
||||
$condition["date"] = $date_condition;
|
||||
}
|
||||
|
||||
$data1 = $visit_model->getList($condition, "*,sum(count) as visit_count", '', '', '', "date");
|
||||
|
||||
$visit_ip_model = model("nc_visit_ip");//访问统计记录表
|
||||
$data2 = $visit_ip_model->getList($condition, "*,count( DISTINCT ip ) as visit_ip_count", '', '', '', "date");
|
||||
$visit_data = [];
|
||||
$ip_visit_data = [];
|
||||
foreach ($date_x as $k => $v) {
|
||||
$visit_count = 0;
|
||||
$visit_ip_count = 0;
|
||||
foreach ($data1 as $data1_k => $data1_v) {
|
||||
if ($data1_v["date"] == $v) {
|
||||
$visit_count = $data1_v["visit_count"];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
foreach ($data2 as $data2_k => $data2_v) {
|
||||
if ($data2_v["date"] == $v) {
|
||||
$visit_ip_count = $data2_v["visit_ip_count"];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$visit_data[] = $visit_count;
|
||||
$ip_visit_data[] = $visit_ip_count;
|
||||
|
||||
}
|
||||
$data = array(
|
||||
"date" => $date_x,
|
||||
"data" => array(
|
||||
"count_data" => $visit_data,
|
||||
"ip_count_data" => $ip_visit_data,
|
||||
)
|
||||
);
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计一段时间内的总访问量
|
||||
* @param $param
|
||||
* @return \multitype
|
||||
*/
|
||||
public function getVisitCountData($param)
|
||||
{
|
||||
$visit_model = Db::table("nc_visit");//访问统计记录表
|
||||
$date_range = $param["date_range"] ?? [];//时间范围
|
||||
$date_type = $param["date_type"];//日期类型 用于查询方式
|
||||
$type = $param["type"] ?? '';//访问类型查询
|
||||
if (empty($type) && !in_array($type, array('HOME', 'APP', 'API', 'ALL'))) {
|
||||
$type = "ALL";
|
||||
}
|
||||
$condition = array();
|
||||
if ($type != "ALL") {
|
||||
$condition["type"] = $type;
|
||||
$visit_model = $visit_model->where("type", $type);
|
||||
}
|
||||
//站点id
|
||||
if (!empty($param["site_id"])) {
|
||||
$condition["site_id"] = $param["site_id"];
|
||||
$visit_model = $visit_model->where("site_id", $param["site_id"]);
|
||||
}
|
||||
$today_date = date('Ymd');//当前日日期
|
||||
switch ($date_type) {
|
||||
case 'today':
|
||||
$visit_model = $visit_model->where("date", $today_date);
|
||||
break;
|
||||
case 'yesterday':
|
||||
$visit_model = $visit_model->where("date", strtotime('-1 days'));
|
||||
break;
|
||||
case 'week':
|
||||
$visit_model = $visit_model->whereBetween("date", date('Ymd', strtotime('-6 days')), $today_date);
|
||||
break;
|
||||
case 'month':
|
||||
$visit_model = $visit_model->whereBetween("date", date('Ymd', strtotime('-29 days')), $today_date);
|
||||
break;
|
||||
case 'daterange':
|
||||
$start_date = date('Ymd', strtotime($date_range['start_date']));//开始日期
|
||||
$end_date = date('Ymd', strtotime($date_range['end_date']));//结束日期
|
||||
$visit_model = $visit_model->whereBetween("date", $start_date, $end_date);
|
||||
break;
|
||||
}
|
||||
|
||||
$visit_count = $visit_model->count();
|
||||
$visit_ip_model = model("nc_visit_ip");//访问统计记录表
|
||||
$visit_ip_result = $visit_ip_model->getInfo($condition, "count( DISTINCT ip ) as ip_count");
|
||||
$visit_ip_count = $visit_ip_result["ip_count"];
|
||||
$data = array(
|
||||
"visit_count" => $visit_count,
|
||||
"visit_ip_count" => $visit_ip_count
|
||||
);
|
||||
return $this->success($data);
|
||||
|
||||
}
|
||||
|
||||
public function test()
|
||||
{
|
||||
$arr = array('HOME', 'APP', 'API');
|
||||
for ($i = 0; $i <= 100; $i++) {
|
||||
$param["type"] = $arr[array_rand($arr)];
|
||||
$param["site_id"] = rand(11111, 12000);
|
||||
$param["module"] = "";
|
||||
$num = sprintf("%02d", rand(1, 30));
|
||||
$today_date = date("Ym" . $num);
|
||||
$visit_model = model("nc_visit");//访问统计记录表
|
||||
$visit_ip_model = model("nc_visit_ip");//ip访问记录表
|
||||
// 启动事务
|
||||
|
||||
$ip_count = 0;
|
||||
//ip访问记录
|
||||
|
||||
$ip = ip2long($this->get_rand_ip());
|
||||
$vivit_ip_condition = array(
|
||||
"date" => $today_date,
|
||||
"site_id" => $param["site_id"],
|
||||
"type" => $param["type"],
|
||||
"module" => $param["module"],
|
||||
"ip" => $ip
|
||||
);
|
||||
$visit_ip_info = $visit_ip_model->getInfo($vivit_ip_condition);
|
||||
if (empty($visit_ip_info)) {
|
||||
$ip_count += 1;
|
||||
$ip_data = array(
|
||||
"date" => $today_date,
|
||||
"site_id" => $param["site_id"],
|
||||
"type" => $param["type"],
|
||||
"module" => $param["module"],
|
||||
"ip" => $ip,
|
||||
"ip_count" => 1
|
||||
);
|
||||
$visit_ip_res = $visit_ip_model->add($ip_data);
|
||||
} else {
|
||||
$ip_data = array(
|
||||
"ip_count" => $visit_ip_info["ip_count"] + 1
|
||||
);
|
||||
$visit_ip_res = $visit_ip_model->update($ip_data, $vivit_ip_condition);
|
||||
}
|
||||
|
||||
//访问记录
|
||||
$vivit_condition = array(
|
||||
"date" => $today_date,
|
||||
"site_id" => $param["site_id"],
|
||||
"type" => $param["type"],
|
||||
"module" => $param["module"]
|
||||
);
|
||||
$visit_info = $visit_model->getInfo($vivit_condition);
|
||||
//如果当前日不存在访问统计数据,则需要创建
|
||||
if (empty($visit_info)) {
|
||||
$data = array(
|
||||
"date" => $today_date,
|
||||
"site_id" => $param["site_id"],
|
||||
"type" => $param["type"],
|
||||
"module" => $param["module"],
|
||||
"count" => 1,
|
||||
"ip_count" => $ip_count
|
||||
);
|
||||
$res = $visit_model->add($data);
|
||||
} else {
|
||||
$data = array(
|
||||
"count" => $visit_info["count"] + 1,
|
||||
"ip_count" => $visit_info["ip_count"] + $ip_count
|
||||
);
|
||||
$visit_model->update($data, $vivit_condition);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function get_rand_ip()
|
||||
{
|
||||
$arr_1 = array("218", "218", "66", "66", "218", "218", "60", "60", "202", "204", "66", "66", "66", "59", "61", "60", "222", "221", "66", "59", "60", "60", "66", "218", "218", "62", "63", "64", "66", "66", "122", "211");
|
||||
$randarr = mt_rand(0, count($arr_1));
|
||||
// $ip1id = $arr_1[$randarr];
|
||||
$ip1id = "218";
|
||||
$ip2id = 600000 / 10000;
|
||||
$ip3id = 2550000 / 10000;
|
||||
$ip4id = 2550000 / 10000 - rand(0, 10);
|
||||
return $ip1id . "." . $ip2id . "." . $ip3id . "." . $ip4id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取时间段内分组
|
||||
*/
|
||||
public function periodGroup($srart_time, $end_time)
|
||||
{
|
||||
$type_time = 3600 * 24;
|
||||
$format = 'Ymd';
|
||||
$data = [];
|
||||
for ($i = $srart_time; $i <= $end_time; $i += $type_time) {
|
||||
$data[] = date($format, $i);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除站点
|
||||
* @param unknown $site_id
|
||||
*/
|
||||
public function deleteSite($site_id)
|
||||
{
|
||||
$visit_model = model("nc_visit");//访问统计记录表
|
||||
$visit_ip_model = model("nc_visit_ip");//ip访问记录表
|
||||
$visit_user_model = model("nc_visit_user");//用户模块访问记录表
|
||||
$visit_model->delete(['site_id' => $site_id]);
|
||||
$visit_ip_model->delete(['site_id' => $site_id]);
|
||||
$visit_user_model->delete(['site_id' => $site_id]);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
}
|
||||
67
app/model/system/Web.php
Executable file
67
app/model/system/Web.php
Executable file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\system;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use think\facade\Cache;
|
||||
|
||||
class Web extends BaseModel
|
||||
{
|
||||
private $url = "https://www.niushop.com/api/%s";
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 官网资讯
|
||||
*/
|
||||
public function news()
|
||||
{
|
||||
$cache = Cache::get("new_day");
|
||||
if (!empty($cache)) {
|
||||
return $cache;
|
||||
}
|
||||
$url = sprintf($this->url, 'news/news');
|
||||
$post_data = [
|
||||
|
||||
];
|
||||
$result = $this->doPost($url, $post_data);
|
||||
$res = json_decode($result, true);
|
||||
if ($res["code"] >= 0) {
|
||||
Cache::set("new_day", $res, 86400);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* post 服务器请求
|
||||
*/
|
||||
private function doPost($post_url, $post_data)
|
||||
{
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $post_url);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
|
||||
|
||||
if ($post_data != '' && !empty($post_data)) {
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
$result = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user