This commit is contained in:
全栈小学生 2026-03-20 15:59:18 +08:00
parent 1bc4217bef
commit 504b4c96a8
90 changed files with 1390 additions and 687 deletions

View File

@ -72,7 +72,8 @@ class Addon extends BaseAdminController
* @description 获取安装任务 * @description 获取安装任务
* @return Response * @return Response
*/ */
public function getInstallTask() { public function getInstallTask()
{
return success(data: ( new AddonService() )->getInstallTask()); return success(data: ( new AddonService() )->getInstallTask());
} }
@ -82,7 +83,8 @@ class Addon extends BaseAdminController
* @param $addon * @param $addon
* @return mixed * @return mixed
*/ */
public function cloudInstallLog($addon) { public function cloudInstallLog($addon)
{
return success(data: ( new AddonService() )->cloudInstallLog($addon)); return success(data: ( new AddonService() )->cloudInstallLog($addon));
} }
@ -173,7 +175,8 @@ class Addon extends BaseAdminController
* @param $addon * @param $addon
* @return Response * @return Response
*/ */
public function download($addon){ public function download($addon)
{
$data = $this->request->params([ $data = $this->request->params([
[ 'version', '' ] [ 'version', '' ]
]); ]);
@ -186,7 +189,8 @@ class Addon extends BaseAdminController
* @description 查询已安装插件 * @description 查询已安装插件
* @return Response * @return Response
*/ */
public function getInstallList(){ public function getInstallList()
{
return success(data: ( new AddonService() )->getInstallList()); return success(data: ( new AddonService() )->getInstallList());
} }
@ -204,7 +208,8 @@ class Addon extends BaseAdminController
* @description 插件类型 * @description 插件类型
* @return Response * @return Response
*/ */
public function getType(){ public function getType()
{
return success(AddonDict::getType()); return success(AddonDict::getType());
} }
@ -214,21 +219,11 @@ class Addon extends BaseAdminController
* @param $addon * @param $addon
* @return Response * @return Response
*/ */
public function upgrade($addon = ''){ public function upgrade($addon = '')
{
return success('DOWNLOAD_SUCCESS', ( new AddonService() )->upgrade($addon)); return success('DOWNLOAD_SUCCESS', ( new AddonService() )->upgrade($addon));
} }
public function showApp()
{
return success(data:(new AddonService())->getShowAppTools());
}
public function showMarketing()
{
return success(( new AddonService() )->getShowMarketingTools());
}
/** /**
* 统一展示 安装的插件 应用 营销工具等。。 * 统一展示 安装的插件 应用 营销工具等。。
* @return Response * @return Response
@ -237,6 +232,7 @@ class Addon extends BaseAdminController
{ {
return success(( new AddonService() )->showCustomer()); return success(( new AddonService() )->showCustomer());
} }
public function getSpecialMenuList() public function getSpecialMenuList()
{ {
return success('SUCCESS', ( new AddonService() )->getSpecialMenuList()); return success('SUCCESS', ( new AddonService() )->getSpecialMenuList());

View File

@ -208,23 +208,6 @@ class NiuSms extends BaseAdminController
return success($data); return success($data);
} }
/**
* 忘记密码
* @description 忘记密码
* @param $username
* @return Response
*/
public function forgetPassword($username)
{
$params = $this->request->params([
['mobile', ''],
['code', ''],
['key', ''],
]);
$data = (new NiuSmsService())->forgetPassword($username, $params);
return success($data);
}
/** /**
* 签名列表 * 签名列表
* @description 签名列表 * @description 签名列表
@ -281,6 +264,15 @@ class NiuSms extends BaseAdminController
['signType', ""], ['signType', ""],
['imgUrl', ""], ['imgUrl', ""],
['defaultSign', 0], ['defaultSign', 0],
//新增字段
['bizLicenseUrl', ''],
['qccUrl', ''],
['tmnetUrl', ''],
['mobileIcpUrl', ''],
['telecomAppstoreUrl', ''],
['idcardFrontUrl', ''],
['idcardBackUrl', ''],
]); ]);
(new NiuSmsService())->signCreate($username, $params); (new NiuSmsService())->signCreate($username, $params);
return success("SUCCESS"); return success("SUCCESS");

View File

@ -58,9 +58,9 @@ class Config extends BaseAdminController
[ "front_end_logo", "" ], [ "front_end_logo", "" ],
[ "front_end_icon", "" ], [ "front_end_icon", "" ],
[ "icon", "" ], [ "icon", "" ],
[ "meta_title", "" ], [ "meta_title", "" ], // Meta 标题
[ "meta_desc", "" ], [ "meta_desc", "" ], // Meta 描述
[ "meta_keyword", "" ], [ "meta_keyword", "" ], // Meta 关键字
]); ]);
( new ConfigService() )->setWebSite($data); ( new ConfigService() )->setWebSite($data);

View File

@ -128,7 +128,6 @@ class Ueditor extends BaseAdminController
'title' => $upload_res['url'], 'title' => $upload_res['url'],
'original' => $upload_res['url'], 'original' => $upload_res['url'],
], 'json', 200); ], 'json', 200);
break;
case 'video': case 'video':
$upload_res = $upload_service->video($data['file']); $upload_res = $upload_service->video($data['file']);
return Response::create([ return Response::create([
@ -137,7 +136,6 @@ class Ueditor extends BaseAdminController
'title' => $upload_res['url'], 'title' => $upload_res['url'],
'original' => $upload_res['url'], 'original' => $upload_res['url'],
], 'json', 200); ], 'json', 200);
break;
} }
} }
} }

View File

@ -36,6 +36,8 @@ class User extends BaseAdminController
['realname', ''], ['realname', ''],
['role', ''], ['role', ''],
['create_time', []], ['create_time', []],
['real_name', ''],
['last_time', []]
]); ]);
$list = (new UserService())->getPage($data); $list = (new UserService())->getPage($data);
@ -129,6 +131,7 @@ class User extends BaseAdminController
['mobile', ''], ['mobile', ''],
['real_name', ''], ['real_name', ''],
['head_img', ''], ['head_img', ''],
['role_ids', []],
]); ]);
(new UserService())->edit($uid, $data); (new UserService())->edit($uid, $data);
return success(); return success();
@ -144,67 +147,4 @@ class User extends BaseAdminController
(new UserService())->del($uid); (new UserService())->del($uid);
return success("DELETE_SUCCESS"); return success("DELETE_SUCCESS");
} }
/**
* 获取用户站点创建限制
* @description 获取用户站点创建限制
* @param $uid
* @return Response
*/
public function getUserCreateSiteLimit($uid){
return success(data:(new UserService())->getUserCreateSiteLimit($uid));
}
/**
* 获取用户站点创建限制
* @description 获取用户站点创建限制
* @param $id
* @return Response
*/
public function getUserCreateSiteLimitInfo($id){
return success(data:(new UserService())->getUserCreateSiteLimitInfo($id));
}
/**
* 添加用户站点创建限制
* @description 添加用户站点创建限制
* @param $uid
* @return Response
*/
public function addUserCreateSiteLimit($uid){
$data = $this->request->params([
['uid', 0],
['group_id', 0],
['num', 1],
['month', 1],
]);
(new UserService())->addUserCreateSiteLimit($data);
return success('SUCCESS');
}
/**
* 编辑用户站点创建限制
* @description 编辑用户站点创建限制
* @param $id
* @return Response
*/
public function editUserCreateSiteLimit($id){
$data = $this->request->params([
['num', 1],
['month', 1],
]);
(new UserService())->editUserCreateSiteLimit($id, $data);
return success('SUCCESS');
}
/**
* 删除用户站点创建限制
* @description 删除用户站点创建限制
* @param $id
* @return Response
*/
public function delUserCreateSiteLimit($id){
(new UserService())->delUserCreateSiteLimit($id);
return success('SUCCESS');
}
} }

View File

@ -92,7 +92,5 @@ Route::group(function () {
Route::group(function () { Route::group(function () {
//获取已安装插件列表 //获取已安装插件列表
Route::get('addon/list/install', 'addon.Addon/getInstallList'); Route::get('addon/list/install', 'addon.Addon/getInstallList');
Route::get('addon/list/showApp', 'addon.Addon/showApp');
Route::get('showMarketing', 'addon.Addon/showMarketing');
}); });

View File

@ -58,7 +58,6 @@ Route::group('notice', function () {
Route::post('login', 'notice.NiuSms/loginAccount'); Route::post('login', 'notice.NiuSms/loginAccount');
Route::post('edit/:username', 'notice.NiuSms/editAccount'); Route::post('edit/:username', 'notice.NiuSms/editAccount');
Route::post('reset/password/:username', 'notice.NiuSms/resetPassword'); Route::post('reset/password/:username', 'notice.NiuSms/resetPassword');
Route::post('forget/password/:username', 'notice.NiuSms/forgetPassword');
Route::get('send_list/:username', 'notice.NiuSms/accountSendList'); Route::get('send_list/:username', 'notice.NiuSms/accountSendList');
Route::get('info/:username', 'notice.NiuSms/accountInfo'); Route::get('info/:username', 'notice.NiuSms/accountInfo');
}); });

View File

@ -82,8 +82,6 @@ Route::group('sys', function() {
//地图设置 //地图设置
Route::put('config/map', 'sys.Config/setMap'); Route::put('config/map', 'sys.Config/setMap');
//地图设置
Route::get('config/map', 'sys.Config/getMap');
//登录注册设置 //登录注册设置
Route::get('config/login', 'login.Config/getConfig'); Route::get('config/login', 'login.Config/getConfig');
@ -343,6 +341,15 @@ Route::group('sys', function() {
AdminLog::class AdminLog::class
]); ]);
//系统环境(不效验登录状态)
Route::group('sys', function() {
//地图设置
Route::get('config/map', 'sys.Config/getMap');
})->middleware([
AdminCheckToken::class,
AdminLog::class
]);
//系统环境(不效验登录状态) //系统环境(不效验登录状态)
Route::group('sys', function() { Route::group('sys', function() {
Route::get('web/website', 'sys.Config/getWebsite'); Route::get('web/website', 'sys.Config/getWebsite');

View File

@ -1,28 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\controller;
use core\base\BaseController;
use think\facade\App;
class Index extends BaseController
{
public function index()
{
return '<style type="text/css">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px;} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }</style><div style="padding: 24px 48px;"> <h1>:) </h1><p> ThinkPHP V' . App::version() . '<br/><span style="font-size:30px;">16载初心不改 - 你值得信赖的PHP框架</span></p><span style="font-size:25px;">[ V6.0 版本由 <a href="https://www.yisu.com/" target="yisu">亿速云</a> 独家赞助发布 ]</span></div><script type="text/javascript" src="https://e.topthink.com/Public/static/client.js"></script><think id="ee9b1aa918103c4fc"></think>';
}
public function hello($name = 'ThinkPHP6')
{
return 'hello,' . $name;
}
}

View File

@ -68,4 +68,38 @@ class Upload extends BaseApiController
$base64_service = new Base64Service(); $base64_service = new Base64Service();
return success($base64_service->image($data['content'])); return success($base64_service->image($data['content']));
} }
public function config()
{
return success([
'upload_max_filesize' => [
'unit' => 'KB',
'num'=>$this->convertPhpSizeToBytes(ini_get('upload_max_filesize'))/1024
],
]);
}
private function convertPhpSizeToBytes($size_str) {
// 去除字符串两端的空格,统一转为大写(方便判断单位)
$size_str = trim(strtoupper($size_str));
// 如果是空值或纯数字(无单位),默认单位为字节
if (!preg_match('/^(\d+(\.\d+)?)([BKMGTP]B?)?$/', $size_str, $matches)) {
return (int)$size_str;
}
// 提取数值和单位
$size = (float)$matches[1];
$unit = isset($matches[3]) ? $matches[3] : 'B'; // 默认单位为B
// 根据单位转换为字节
switch ($unit) {
case 'TB': case 'T': $size *= 1024;
case 'GB': case 'G': $size *= 1024;
case 'MB': case 'M': $size *= 1024;
case 'KB': case 'K': $size *= 1024;
case 'B': default: break; // 字节无需转换
}
return (int)$size;
}
} }

View File

@ -46,7 +46,7 @@ class ApiCheckToken
if (!empty($token_info)) { if (!empty($token_info)) {
$request->memberId($token_info[ 'member_id' ]); $request->memberId($token_info[ 'member_id' ]);
} }
//校验会员和站点 //校验会员
( new AuthService() )->checkMember($request); ( new AuthService() )->checkMember($request);
} catch (AuthException $e) { } catch (AuthException $e) {
//是否将登录错误抛出 //是否将登录错误抛出

View File

@ -32,6 +32,7 @@ Route::group('file', function() {
*/ */
Route::group('file', function() { Route::group('file', function() {
//上传图片 //上传图片
Route::get('config', 'upload.Upload/config');
Route::post('image', 'upload.Upload/image'); Route::post('image', 'upload.Upload/image');
//上传视频 //上传视频
Route::post('video', 'upload.Upload/video'); Route::post('video', 'upload.Upload/video');

View File

@ -17,7 +17,6 @@ use think\facade\Route;
//支付异步回调 //支付异步回调
Route::any('pay/notify/:channel/:type/:action', 'pay.Pay/notify') Route::any('pay/notify/:channel/:type/:action', 'pay.Pay/notify')
->middleware(ApiChannel::class) ->middleware(ApiChannel::class)
->middleware(ApiCheckToken::class)
->middleware(ApiLog::class); ->middleware(ApiLog::class);
/** /**
* 路由 * 路由

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace app\command\Addon; namespace app\command\addon;
use app\service\core\addon\CoreAddonInstallService; use app\service\core\addon\CoreAddonInstallService;
use Exception; use Exception;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace app\command\Addon; namespace app\command\addon;
use think\console\Command; use think\console\Command;
use think\console\Input; use think\console\Input;

View File

@ -9,7 +9,7 @@ use think\console\Command;
use think\console\Input; use think\console\Input;
use think\console\Output; use think\console\Output;
class refreshAreaCommand extends Command class RefreshAreaCommand extends Command
{ {
protected function configure() protected function configure()
{ {

View File

@ -1,6 +1,9 @@
<?php <?php
use Location\Coordinate;
use Location\Distance\Vincenty;
use think\Container; use think\Container;
use think\exception\InvalidArgumentException;
use think\Response; use think\Response;
use think\facade\Lang; use think\facade\Lang;
use think\facade\Queue; use think\facade\Queue;
@ -756,7 +759,11 @@ function cache_remember(string $name = null, $value = '', $tag = null, $options
if (is_null($tag)) { if (is_null($tag)) {
Cache::set($name, $value, $options['expire'] ?? null); Cache::set($name, $value, $options['expire'] ?? null);
} else { } else {
try {
Cache::tag($tag)->set($name, $value, $options['expire'] ?? null); Cache::tag($tag)->set($name, $value, $options['expire'] ?? null);
} catch (InvalidArgumentException $e) {
Cache::tag($tag)->set($name, $value, $options['expire'] ?? null);
}
} }
return $value; return $value;
@ -1151,3 +1158,18 @@ function downloadImage($img_url, $file_name)
fclose($fp); fclose($fp);
return true; return true;
} }
/**
* 获取地图两坐标点之间距离
* @param $lat1
* @param $lng1
* @param $lat2
* @param $lng2
* @return float
*/
function get_map_distance($lat1, $lng1, $lat2, $lng2)
{
$location = new Coordinate($lat1, $lng1);
$distance = ( new Vincenty() )->getDistance($location, new Coordinate((float) $lat2, (float) $lng2));
return round($distance/1000, 3);
}

View File

@ -37,52 +37,67 @@ class CommonActiveDict
self::IMPULSE_BUY => [ self::IMPULSE_BUY => [
'name' => get_lang('common_active_short.impulse_buy_short'), 'name' => get_lang('common_active_short.impulse_buy_short'),
'active_name' => get_lang('common_active_short.impulse_buy_name'), 'active_name' => get_lang('common_active_short.impulse_buy_name'),
'bg_color' => "#FF7700" 'bg_color' => "#FF7700",
'jump_url'=>'/admin/shop_impulse_buy/list',/////
'is_need_params'=>1
], ],
self::GIFTCARD => [ self::GIFTCARD => [
'name' => get_lang('common_active_short.gift_card_short'), 'name' => get_lang('common_active_short.gift_card_short'),
'active_name' => get_lang('common_active_short.gift_card_name'), 'active_name' => get_lang('common_active_short.gift_card_name'),
'bg_color' => '#F00000' 'bg_color' => '#F00000',
'jump_url'=>'/admin/shop_giftcard/giftcard/list',/////
'is_need_params'=>1
], ],
self::DISCOUNT => [ self::DISCOUNT => [
'name' => get_lang('common_active_short.discount_short'), 'name' => get_lang('common_active_short.discount_short'),
'active_name' => get_lang('common_active_short.discount_name'), 'active_name' => get_lang('common_active_short.discount_name'),
'bg_color' => '#FFA322' 'bg_color' => '#FFA322',
'jump_url'=>'/admin/shop/marketing/discount/list',/////
'is_need_params'=>1
], ],
self::EXCHANGE => [ self::EXCHANGE => [
'name' => get_lang('common_active_short.exchange_short'), 'name' => get_lang('common_active_short.exchange_short'),
'active_name' => get_lang('common_active_short.exchange_name'), 'active_name' => get_lang('common_active_short.exchange_name'),
'bg_color' => '#00C441' 'bg_color' => '#00C441',
'jump_url'=>'/admin/shop/marketing/exchange/goods_list',/////
'is_need_params'=>1
], ],
self::MANJIANSONG => [ self::MANJIANSONG => [
'name' => get_lang('common_active_short.manjiansong_short'), 'name' => get_lang('common_active_short.manjiansong_short'),
'active_name' => get_lang('common_active_short.manjiansong_name'), 'active_name' => get_lang('common_active_short.manjiansong_name'),
'bg_color' => '#249DE9' 'bg_color' => '#249DE9',
'jump_url'=>'/admin/shop/marketing/manjian/list',/////
'is_need_params'=>1
], ],
self::NEWCOMER_DISCOUNT => [ self::NEWCOMER_DISCOUNT => [
'name' => get_lang('common_active_short.newcomer_discount_short'), 'name' => get_lang('common_active_short.newcomer_discount_short'),
'active_name' => get_lang('common_active_short.newcomer_discount_name'), 'active_name' => get_lang('common_active_short.newcomer_discount_name'),
'bg_color' => '#BB27FF' 'bg_color' => '#BB27FF',
'jump_url'=>'/admin/shop/marketing/newcomer/config'
], ],
self::SECKILL => [ self::SECKILL => [
'name' => get_lang('common_active_short.seckill_short'), 'name' => get_lang('common_active_short.seckill_short'),
'active_name' => get_lang('common_active_short.seckill_name'), 'active_name' => get_lang('common_active_short.seckill_name'),
'bg_color' => '#F606CA' 'bg_color' => '#F606CA',
'jump_url'=>'/admin/seckill/active/list'
], ],
self::PINTUAN => [ self::PINTUAN => [
'name' => get_lang('common_active_short.pintuan_short'), 'name' => get_lang('common_active_short.pintuan_short'),
'active_name' => get_lang('common_active_short.pintuan_name'), 'active_name' => get_lang('common_active_short.pintuan_name'),
'bg_color' => '#FF1C77' 'bg_color' => '#FF1C77',
'jump_url'=>'/admin/pintuan/active/list'
], ],
self::RELAY => [ self::RELAY => [
'name' => get_lang('common_active_short.relay_short'), 'name' => get_lang('common_active_short.relay_short'),
'active_name' => get_lang('common_active_short.relay_name'), 'active_name' => get_lang('common_active_short.relay_name'),
'bg_color' => '#0EB108' 'bg_color' => '#0EB108',
'jump_url'=>'/admin/relay/active/list'
], ],
self::FRIEND_HELP => [ self::FRIEND_HELP => [
'name' => get_lang('common_active_short.friend_help_short'), 'name' => get_lang('common_active_short.friend_help_short'),
'active_name' => get_lang('common_active_short.friend_help_name'), 'active_name' => get_lang('common_active_short.friend_help_name'),
'bg_color' => '#F20C8A' 'bg_color' => '#F20C8A',
'jump_url'=>'/admin/friend_help/active/list'
], ],
]; ];
return !empty($active) ? $data[$active] ?? [] : $data; return !empty($active) ? $data[$active] ?? [] : $data;

View File

@ -189,5 +189,17 @@ return [
//是否累增 //是否累增
'is_change_get' => 0, 'is_change_get' => 0,
], ],
],
MemberAccountTypeDict::GROWTH => [
//调整
'member_register' => [
//名称
'name' => get_lang('dict_member.account_point_member_register'),
//是否增加
'inc' => 1,
//是否减少
'dec' => 0,
],
] ]
]; ];

View File

@ -1042,7 +1042,7 @@ return [
'children' => [ 'children' => [
[ [
'menu_name' => '转账', 'menu_name' => '转账',
'menu_key' => 'cash_out_transfer', 'menu_key' => 'member_refund_transfer',
'menu_short_name' => '转账', 'menu_short_name' => '转账',
'menu_type' => '2', 'menu_type' => '2',
'icon' => '', 'icon' => '',
@ -1115,7 +1115,7 @@ return [
'router_path' => 'marketing/verify/index', 'router_path' => 'marketing/verify/index',
'view_path' => '', 'view_path' => '',
'methods' => 'get', 'methods' => 'get',
'sort' => '48', 'sort' => '30',
'status' => '1', 'status' => '1',
'is_show' => '1', 'is_show' => '1',
'children' => [ 'children' => [
@ -1232,7 +1232,7 @@ return [
'router_path' => 'marketing/sign/config', 'router_path' => 'marketing/sign/config',
'view_path' => '', 'view_path' => '',
'methods' => 'get', 'methods' => 'get',
'sort' => '30', 'sort' => '91',
'status' => '1', 'status' => '1',
'is_show' => '1', 'is_show' => '1',
'children' => [ 'children' => [
@ -2812,7 +2812,7 @@ return [
'router_path' => '', 'router_path' => '',
'view_path' => '', 'view_path' => '',
'methods' => '', 'methods' => '',
'sort' => '0', 'sort' => '29',
'status' => '1', 'status' => '1',
'is_show' => '1', 'is_show' => '1',
'menu_attr' => 'diy_form', 'menu_attr' => 'diy_form',
@ -2862,7 +2862,7 @@ return [
'router_path' => '', 'router_path' => '',
'view_path' => '', 'view_path' => '',
'methods' => '', 'methods' => '',
'sort' => '0', 'sort' => '27',
'status' => '1', 'status' => '1',
'is_show' => '1', 'is_show' => '1',
'menu_attr' => 'setting_export', 'menu_attr' => 'setting_export',
@ -2912,7 +2912,7 @@ return [
'router_path' => '', 'router_path' => '',
'view_path' => '', 'view_path' => '',
'methods' => '', 'methods' => '',
'sort' => '0', 'sort' => '28',
'status' => '1', 'status' => '1',
'is_show' => '1', 'is_show' => '1',
'menu_attr' => 'printer_management', 'menu_attr' => 'printer_management',

View File

@ -141,12 +141,12 @@ class NoticeTypeDict
} }
const PARAMS_TYPE_VALID_CODE = 'valid_code'; const PARAMS_TYPE_VALID_CODE = 'valid_code';
const PARAMS_TYPE_MOBILE_NUMBER = 'mobile_number';
const PARAMS_TYPE_OTHER_NUMBER = 'other_number'; const PARAMS_TYPE_OTHER_NUMBER = 'other_number';
const PARAMS_TYPE_AMOUNT = 'amount'; const PARAMS_TYPE_AMOUNT = 'amount';
const PARAMS_TYPE_DATE = 'date'; const PARAMS_TYPE_DATE = 'date';
const PARAMS_TYPE_CHINESE = 'chinese'; const PARAMS_TYPE_CHINESE = 'chinese';
const PARAMS_TYPE_OTHERS = 'others'; const PARAMS_TYPE_OTHERS = 'others';
const PARAMS_TYPE_INT_NUMBER = 'int_number';
public static function getApiParamsType() public static function getApiParamsType()
{ {
return [ return [
@ -159,20 +159,12 @@ class NoticeTypeDict
'max'=>6 'max'=>6
], ],
[ [
'name' => '手机号', 'name' => '其他号码(手机号)',
'type' => self::PARAMS_TYPE_MOBILE_NUMBER,
'desc' => '1-15位纯数字',
'rule' => '/^\d$/',
'min'=>1,
'max'=>15
],
[
'name' => '其他号码',
'type' => self::PARAMS_TYPE_OTHER_NUMBER, 'type' => self::PARAMS_TYPE_OTHER_NUMBER,
'desc' => '1-32位字母+数字组合', 'desc' => '1-20位字母+数字组合',
'rule'=>'/^[a-zA-Z0-9]$/', 'rule'=>'/^[a-zA-Z0-9]$/',
'min'=>1, 'min'=>1,
'max'=>32 'max'=>20
], ],
[ [
'name' => '金额', 'name' => '金额',
@ -189,18 +181,26 @@ class NoticeTypeDict
[ [
'name' => '中文', 'name' => '中文',
'type' => self::PARAMS_TYPE_CHINESE, 'type' => self::PARAMS_TYPE_CHINESE,
'desc' => '1-32中文支持中文园括号()', 'desc' => '1-15中文支持中文圆括号()',
'rule' => '/^[\p{Han}()]$/u', 'rule' => '/^[\p{Han}]+$/u',
'min'=>1, 'min'=>1,
'max'=>32 'max'=>15
],
[
'name' => '纯数字',
'type' => self::PARAMS_TYPE_INT_NUMBER,
'desc' => ' 1-10个数字',
'rule' => '/^\d$/',
'min'=>1,
'max'=>10
], ],
[ [
'name' => '其他', 'name' => '其他',
'type' => self::PARAMS_TYPE_OTHERS, 'type' => self::PARAMS_TYPE_OTHERS,
'desc' => ' 1-35个中文数字字母组合支持中文符号和空格', 'desc' => ' 1-30个中文数字字母组合,支持中文符号。',
'rule' => '/^[\p{Han}\p{N}\p{L}\p{P}\p{S}\s]$/u', 'rule' => '/^[\p{Han}\p{N}\p{L}\p{P}\p{S}\s]$/u',
'min'=>1, 'min'=>1,
'max'=>35 'max'=>30
], ],
]; ];
} }

View File

@ -39,6 +39,10 @@ class PayChannelDict
'key' => $k, 'key' => $k,
'pay_type' => $pay_type 'pay_type' => $pay_type
]; ];
if (in_array($k,[ChannelDict::WEAPP,ChannelDict::WECHAT])){
unset($temp_pay_type[ PayDict::ALIPAY ]);
$list[ $k ][ 'pay_type' ] = $temp_pay_type;
}
// PC端暂不支持 帮付 // PC端暂不支持 帮付
if ($k == ChannelDict::PC) { if ($k == ChannelDict::PC) {
unset($temp_pay_type[ PayDict::FRIENDSPAY ]); unset($temp_pay_type[ PayDict::FRIENDSPAY ]);

View File

@ -13,9 +13,10 @@ return [
], ],
'class' => 'app\job\schedule\AutoClearScheduleLog', 'class' => 'app\job\schedule\AutoClearScheduleLog',
'function' => '' 'function' => ''
], [ ],
[
'key' => 'auto_clear_poster_qrcode', 'key' => 'auto_clear_poster_qrcode',
'name' => '定时清理海报及二维码数据', 'name' => '定时清理一周前的海报及二维码数据',
'desc' => '', 'desc' => '',
'time' => [ 'time' => [
'type' => 'day', 'type' => 'day',
@ -26,6 +27,19 @@ return [
'class' => 'app\job\schedule\AutoClearPosterAndQrcode', 'class' => 'app\job\schedule\AutoClearPosterAndQrcode',
'function' => '' 'function' => ''
], ],
[
'key' => 'auto_clear_system_log',
'name' => '定时清理一周前的业务日志',
'desc' => '',
'time' => [
'type' => 'day',
'day' => 1,
'hour' => 1,
'min' => 1
],
'class' => 'app\job\schedule\AutoClearLogFiles',
'function' => ''
],
[ [
'key' => 'transfer_check_finish', 'key' => 'transfer_check_finish',
'name' => '检验在线转账是否处理完毕', 'name' => '检验在线转账是否处理完毕',
@ -61,5 +75,5 @@ return [
], ],
'class' => 'app\job\sys\ClearUserLog', 'class' => 'app\job\sys\ClearUserLog',
'function' => '' 'function' => ''
] ],
]; ];

View File

@ -103,7 +103,7 @@ class Index extends BaseInstall
$this->assign("name", $name); $this->assign("name", $name);
$this->assign("verison", $verison); $this->assign("verison", $verison);
$this->assign("dirs_list", $dirs_list); $this->assign("dirs_list", $dirs_list);
if ($verison && $pdo && $curl && $openssl && $gd && $fileinfo && $is_dir) { if ($verison && $pdo && $curl && $openssl && $gd && $fileinfo && $is_dir && $imagick) {
$continue = true; $continue = true;
} else { } else {
$continue = false; $continue = false;
@ -170,6 +170,15 @@ class Index extends BaseInstall
$conn = @mysqli_connect($dbhost, $dbuser, $dbpwd); $conn = @mysqli_connect($dbhost, $dbuser, $dbpwd);
if ($conn) { if ($conn) {
$sql_mode_result = mysqli_query($conn, "SELECT @@global.sql_mode");
$sql_mode = strtolower($sql_mode_result->fetch_array()[0] ?? '');
if (strpos($sql_mode, 'only_full_group_by') !== false) {
return fail([
"status" => -2,
"message" => "请将mysql配置sql_mode字段中的值“ONLY_FULL_GROUP_BY”去掉"
]);
}
if (empty($dbname)) { if (empty($dbname)) {
$result = [ $result = [
"status" => 1, "status" => 1,
@ -390,6 +399,7 @@ class Index extends BaseInstall
$this->setSuccessLog([ '初始化', 'success' ]); $this->setSuccessLog([ '初始化', 'success' ]);
Cache::set('install_status', 2);//成功 Cache::set('install_status', 2);//成功
// Cache::tag(MenuService::$cache_tag_name)->clear();
return success(); return success();
} catch (Exception $e) { } catch (Exception $e) {
$this->setSuccessLog([ '安装失败' . $e->getMessage(), 'error' ]); $this->setSuccessLog([ '安装失败' . $e->getMessage(), 'error' ]);

View File

@ -23,6 +23,7 @@ CREATE TABLE `activity_exchange_code`
`activity_id` INT(11) NOT NULL DEFAULT 0 COMMENT '活动ID', `activity_id` INT(11) NOT NULL DEFAULT 0 COMMENT '活动ID',
`type` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '类型 例seckill_goods-秒杀商品', `type` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '类型 例seckill_goods-秒杀商品',
`type_id` INT(11) NOT NULL DEFAULT 0 COMMENT '类型对应id 秒杀商品id', `type_id` INT(11) NOT NULL DEFAULT 0 COMMENT '类型对应id 秒杀商品id',
`type_item_id` int NOT NULL DEFAULT 0 COMMENT '规格id',
`expire_time` INT(11) NOT NULL DEFAULT 0 COMMENT '过期时间 0-不过期', `expire_time` INT(11) NOT NULL DEFAULT 0 COMMENT '过期时间 0-不过期',
`member_id` INT(11) NOT NULL DEFAULT 0 COMMENT '领取会员', `member_id` INT(11) NOT NULL DEFAULT 0 COMMENT '领取会员',
`received_time` INT(11) NOT NULL DEFAULT 0 COMMENT '领取时间', `received_time` INT(11) NOT NULL DEFAULT 0 COMMENT '领取时间',
@ -366,6 +367,7 @@ CREATE TABLE `member`
`member_label` varchar(255) NOT NULL DEFAULT '' COMMENT '会员标签', `member_label` varchar(255) NOT NULL DEFAULT '' COMMENT '会员标签',
`wx_openid` varchar(255) NOT NULL DEFAULT '' COMMENT '微信用户openid', `wx_openid` varchar(255) NOT NULL DEFAULT '' COMMENT '微信用户openid',
`weapp_openid` varchar(255) NOT NULL DEFAULT '' COMMENT '微信小程序openid', `weapp_openid` varchar(255) NOT NULL DEFAULT '' COMMENT '微信小程序openid',
`wxapp_openid` varchar(255) NOT NULL DEFAULT '' COMMENT '微信移动应用openid',
`wx_unionid` varchar(255) NOT NULL DEFAULT '' COMMENT '微信unionid', `wx_unionid` varchar(255) NOT NULL DEFAULT '' COMMENT '微信unionid',
`ali_openid` varchar(255) NOT NULL DEFAULT '' COMMENT '支付宝账户id', `ali_openid` varchar(255) NOT NULL DEFAULT '' COMMENT '支付宝账户id',
`douyin_openid` varchar(255) NOT NULL DEFAULT '' COMMENT '抖音小程序openid', `douyin_openid` varchar(255) NOT NULL DEFAULT '' COMMENT '抖音小程序openid',
@ -4957,7 +4959,6 @@ DROP TABLE IF EXISTS `app_version`;
CREATE TABLE `app_version` CREATE TABLE `app_version`
( (
`id` INT(11) NOT NULL AUTO_INCREMENT, `id` INT(11) NOT NULL AUTO_INCREMENT,
`site_id` INT(11) NOT NULL DEFAULT 0 COMMENT '站点id',
`version_code` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '版本号', `version_code` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '版本号',
`version_name` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '版本名称', `version_name` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '版本名称',
`version_desc` VARCHAR(1500) NOT NULL DEFAULT '' COMMENT '版本描述', `version_desc` VARCHAR(1500) NOT NULL DEFAULT '' COMMENT '版本描述',
@ -4974,15 +4975,3 @@ CREATE TABLE `app_version`
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'app版本管理' ROW_FORMAT = Dynamic; ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'app版本管理' ROW_FORMAT = Dynamic;
ALTER TABLE activity_exchange_code
CHANGE COLUMN activity_type activity_type VARCHAR(20) NOT NULL DEFAULT '' COMMENT '例seckill-秒杀活动';
ALTER TABLE activity_exchange_code
ADD COLUMN type_item_id INT(11) NOT NULL DEFAULT 0 COMMENT '规格id';
ALTER TABLE member
ADD COLUMN wxapp_openid VARCHAR(255) NOT NULL DEFAULT '' COMMENT '微信移动应用openid';
ALTER TABLE member
MODIFY wxapp_openid VARCHAR(255) NOT NULL DEFAULT '' COMMENT '微信移动应用openid' AFTER weapp_openid;

View File

@ -56,6 +56,12 @@
<div style='float:left' class="mysql-message" id='dbpwdsta'></div> <div style='float:left' class="mysql-message" id='dbpwdsta'></div>
</td> </td>
</tr> </tr>
<tr class="sql-mode-error" style="display: none">
<td></td>
<td>
<div class="message" style="color: red;">请将mysql配置sql_mode字段中的值“ONLY_FULL_GROUP_BY”去掉</div>
</td>
</tr>
<tr> <tr>
<td class="onetd"><span class="required">*</span>数据库名称:</td> <td class="onetd"><span class="required">*</span>数据库名称:</td>
<td> <td>
@ -224,7 +230,14 @@
type: "post", type: "post",
dataType: 'json', dataType: 'json',
success: function(data){ success: function(data){
if (data.data.status == -2) {
inputBoxPointer('dbpwdsta').innerHTML = '数据库连接成功'
$('.sql-mode-error .message').text(data.data.message)
$('.sql-mode-error').show()
} else {
$('.sql-mode-error').hide()
inputBoxPointer('dbpwdsta').innerHTML = data.data.message; inputBoxPointer('dbpwdsta').innerHTML = data.data.message;
}
is_existdb = data.data.status; is_existdb = data.data.status;
message = data.data.message; message = data.data.message;
} }

View File

@ -0,0 +1,163 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\job\schedule;
use core\base\BaseJob;
use think\facade\Log;
/**
* 队列异步调用定时任务 - 清理日志文件
*/
class AutoClearLogFiles extends BaseJob
{
public function doJob()
{
Log::write('AutoClearLogFiles 定时清理日志文件开始 ' . date('Y-m-d H:i:s'));
try {
// 定义需要清理的日志目录数组
$log_dirs = [
'log',
'adminapi/log',
'api/log'
];
// 遍历每个日志目录进行清理
foreach ($log_dirs as $dir) {
$abs_dir = runtime_path($dir);
// runtime_path补充根目录拼接方式
if (!is_dir($abs_dir)) {
$abs_dir = root_path() . $dir;
}
$this->clearDirectory($abs_dir);
}
Log::write('AutoClearLogFiles 定时清理日志文件完成 ' . date('Y-m-d H:i:s'));
return true;
} catch (\Exception $e) {
Log::write('AutoClearLogFiles 定时清除异常: ' . $e->getMessage() . ' 位置: ' . $e->getFile() . ':' . $e->getLine() . $e->getTraceAsString());
return false;
}
}
/**
* 清空指定目录下一周前的日志文件和空的子目录
*
* @param string $directory 目录路径
* @param bool $preserveDirectory 是否保留根目录(默认保留)
* @return bool 是否成功执行
*/
function clearDirectory(string $directory, bool $preserveDirectory = true): bool
{
// 规范化目录路径统一使用DIRECTORY_SEPARATOR
$directory = rtrim(realpath($directory), DIRECTORY_SEPARATOR);
Log::write('AutoClearLogFiles开始清理目录: ' . $directory);
// 检查目录是否存在
if (!is_dir($directory)) {
Log::write('AutoClearLogFiles目录不存在或不是有效目录: ' . $directory);
return false;
}
// 计算一周前的时间戳7天 = 7*24*60*60 = 604800秒
$one_week_ago = time() - 604800;
// 打开目录
$handle = opendir($directory);
if (!$handle) {
Log::write('AutoClearLogFiles无法打开目录: ' . $directory);
return false;
}
// 遍历目录内容
while (($entry = readdir($handle)) !== false) {
// 跳过当前目录和上级目录
if ($entry === '.' || $entry === '..') {
continue;
}
// 使用DIRECTORY_SEPARATOR确保路径分隔符正确
$path = $directory . DIRECTORY_SEPARATOR . $entry;
// 递归处理子目录
if (is_dir($path)) {
// 递归清理子目录(只删一周前文件,保留子目录本身)
if (!$this->clearDirectory($path, true)) {
Log::write('AutoClearLogFiles递归清理子目录失败: ' . $path);
closedir($handle);
return false;
}
// 检查子目录是否为空,若为空则删除
$isEmpty = true;
$sub_handle = opendir($path);
while (($sub_entry = readdir($sub_handle)) !== false) {
if ($sub_entry !== '.' && $sub_entry !== '..') {
$isEmpty = false;
break;
}
}
closedir($sub_handle);
if ($isEmpty && !$preserveDirectory) {
if (!rmdir($path)) {
Log::write('AutoClearLogFiles删除空目录失败: ' . $path);
} else {
Log::write('AutoClearLogFiles已删除空目录: ' . $path);
}
}
} else {
// 过滤日志文件(可选:只清理.log后缀的文件避免误删其他类型文件
$file_ext = pathinfo($path, PATHINFO_EXTENSION);
if ($file_ext !== 'log') {
Log::write('AutoClearLogFiles跳过非日志文件: ' . $path);
continue;
}
// 获取文件的最后修改时间
$file_time = filemtime($path);
// 校验:文件时间有效 且 早于/等于一周前
if ($file_time !== false && $file_time <= $one_week_ago) {
// 删除一周前的日志文件
if (!unlink($path)) {
Log::write('AutoClearLogFiles删除日志文件失败: ' . $path);
closedir($handle);
return false;
}
Log::write('AutoClearLogFiles已删除一周前的日志文件: ' . $path);
} else {
// 跳过近期日志文件
Log::write('AutoClearLogFiles跳过近期日志文件: ' . $path);
}
}
}
// 关闭目录句柄
closedir($handle);
// 根目录是否删除(默认保留,避免目录丢失)
if (!$preserveDirectory) {
Log::write('AutoClearLogFiles准备删除根目录: ' . $directory);
if (!rmdir($directory)) {
Log::write('AutoClearLogFiles删除根目录失败: ' . $directory);
return false;
}
Log::write('AutoClearLogFiles成功删除根目录: ' . $directory);
} else {
Log::write('AutoClearLogFiles保留根目录: ' . $directory);
}
return true;
}
}

View File

@ -24,16 +24,14 @@ class AutoClearPosterAndQrcode extends BaseJob
{ {
Log::write('AutoClearPosterAndQrcode 定时清除 二维码及海报数据开始' . date('Y-m-d H:i:s')); Log::write('AutoClearPosterAndQrcode 定时清除 二维码及海报数据开始' . date('Y-m-d H:i:s'));
try { try {
// 清理海报目录 $dirs = [
$dir = 'upload/poster'; 'upload/poster',
'upload/qrcode',
];
foreach ($dirs as $dir) {
$dir = public_path($dir); $dir = public_path($dir);
$res = $this->clearDirectory($dir); $res = $this->clearDirectory($dir);
}
// 清理二维码目录
$qrcode_dir = 'upload/qrcode';
$qrcode_dir = public_path($qrcode_dir);
$res = $this->clearDirectory($qrcode_dir);
return true; return true;
} catch (\Exception $e) { } catch (\Exception $e) {
Log::write('AutoClearPosterAndQrcode 定时清除异常: ' . $e->getMessage() . ' 位置: ' . $e->getFile() . ':' . $e->getLine() . $e->getTraceAsString()); Log::write('AutoClearPosterAndQrcode 定时清除异常: ' . $e->getMessage() . ' 位置: ' . $e->getFile() . ':' . $e->getLine() . $e->getTraceAsString());
@ -42,7 +40,7 @@ class AutoClearPosterAndQrcode extends BaseJob
} }
/** /**
* 清空指定目录下所有文件和子目录 * 清空指定目录下一周前的文件和空的子目录
* *
* @param string $directory 目录路径 * @param string $directory 目录路径
* @param bool $preserveDirectory 是否保留根目录(默认保留) * @param bool $preserveDirectory 是否保留根目录(默认保留)
@ -61,6 +59,9 @@ class AutoClearPosterAndQrcode extends BaseJob
return false; return false;
} }
// 计算一周前的时间戳7天 = 7*24*60*60 = 604800秒
$one_week_ago = time() - 604800;
// 打开目录 // 打开目录
$handle = opendir($directory); $handle = opendir($directory);
if (!$handle) { if (!$handle) {
@ -80,28 +81,55 @@ class AutoClearPosterAndQrcode extends BaseJob
// 递归处理子目录 // 递归处理子目录
if (is_dir($path)) { if (is_dir($path)) {
// 递归清空子目录 // 递归清理子目录(只删一周前文件,保留子目录本身)
if (!$this->clearDirectory($path, false)) { if (!$this->clearDirectory($path, true)) {
Log::write('AutoClearPosterAndQrcode递归清理子目录失败: ' . $path); Log::write('AutoClearPosterAndQrcode递归清理子目录失败: ' . $path);
closedir($handle); closedir($handle);
return false; return false;
} }
Log::write('AutoClearPosterAndQrcode已递归删除子目录: ' . $path);
// 子目录已经在递归调用中被删除,不需要再次删除 // 检查子目录是否为空,若为空则删除(可选逻辑,根据需求调整)
$isEmpty = true;
$sub_handle = opendir($path);
while (($sub_entry = readdir($sub_handle)) !== false) {
if ($sub_entry !== '.' && $sub_entry !== '..') {
$isEmpty = false;
break;
}
}
closedir($sub_handle);
if ($isEmpty && !$preserveDirectory) {
if (!rmdir($path)) {
Log::write('AutoClearPosterAndQrcode删除空目录失败: ' . $path);
} else { } else {
// 删除文件 Log::write('AutoClearPosterAndQrcode已删除空目录: ' . $path);
}
}
} else {
// 获取文件的创建/修改时间优先用修改时间filemtime更贴合业务
$file_time = filemtime($path);
// 校验:文件时间有效 且 早于一周前
if ($file_time !== false && $file_time <= $one_week_ago) {
// 删除一周前的文件
if (!unlink($path)) { if (!unlink($path)) {
Log::write('AutoClearPosterAndQrcode删除文件失败: ' . $path); Log::write('AutoClearPosterAndQrcode删除文件失败: ' . $path);
closedir($handle); closedir($handle);
return false; return false;
} }
Log::write('AutoClearPosterAndQrcode已删除一周前的文件: ' . $path);
} else {
// 跳过近期文件,记录日志(可选)
Log::write('AutoClearPosterAndQrcode跳过近期文件: ' . $path);
}
} }
} }
// 关闭目录句柄 // 关闭目录句柄
closedir($handle); closedir($handle);
// 是否删除根目录本身 // 根目录是否删除(默认保留,避免目录丢失)
if (!$preserveDirectory) { if (!$preserveDirectory) {
Log::write('AutoClearPosterAndQrcode准备删除根目录: ' . $directory); Log::write('AutoClearPosterAndQrcode准备删除根目录: ' . $directory);
if (!rmdir($directory)) { if (!rmdir($directory)) {
@ -115,6 +143,4 @@ class AutoClearPosterAndQrcode extends BaseJob
return true; return true;
} }
} }

View File

@ -1,34 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\job\wxoplatform;
use app\service\admin\wxoplatform\WeappVersionService;
use core\base\BaseJob;
/**
* 队列异步调用支付定时未支付恢复
*/
class GetVersionUploadResult extends BaseJob
{
/**
* 消费
* @param $data
* @return true
*/
protected function doJob($task_key, $is_all)
{
WeappVersionService::getVersionUploadResult($task_key, $is_all);
return true;
}
}

View File

@ -1,34 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\job\wxoplatform;
use app\service\admin\wxoplatform\WeappVersionService;
use core\base\BaseJob;
/**
* 队列异步调用支付定时未支付恢复
*/
class VersionUploadSuccess extends BaseJob
{
/**
* 消费
* @param $data
* @return true
*/
protected function doJob($task_key, $is_all)
{
WeappVersionService::uploadSuccess($task_key, $is_all);
return true;
}
}

View File

@ -72,7 +72,7 @@ return [
'ATTACHMENT_GROUP_HAS_IMAGE' => '附件组中存在图片不允许删除', 'ATTACHMENT_GROUP_HAS_IMAGE' => '附件组中存在图片不允许删除',
'OSS_TYPE_NOT_EXIST' => '云存储类型不存在', 'OSS_TYPE_NOT_EXIST' => '云存储类型不存在',
'URL_FILE_NOT_EXIST' => '获取不到网址指向的文件', 'URL_FILE_NOT_EXIST' => '获取不到网址指向的文件',
'PLEACE_SELECT_IMAGE' => '请选择要删除的图片', 'PLEASE_SELECT_IMAGE' => '请选择要删除的图片',
'UPLOAD_TYPE_ERROR' => '不是有效的上传类型', 'UPLOAD_TYPE_ERROR' => '不是有效的上传类型',

View File

@ -67,6 +67,7 @@ return [
'CLOUD_BUILD_AUTH_CODE_NOT_FOUND' => '请先填写授权码', 'CLOUD_BUILD_AUTH_CODE_NOT_FOUND' => '请先填写授权码',
'TASK_CYCLE_ERROR' => '任务周期填写错误', 'TASK_CYCLE_ERROR' => '任务周期填写错误',
'UPGRADE_TASK_EXIST' => '有正在执行的升级任务,可以展开正在升级的任务,也可以在开发>更新缓存中清除缓存重新开始升级', 'UPGRADE_TASK_EXIST' => '有正在执行的升级任务,可以展开正在升级的任务,也可以在开发>更新缓存中清除缓存重新开始升级',
'ZIP_ARCHIVE_NOT_EXIST' => '请先安装或启用zip扩展',
//登录注册重置账号.... //登录注册重置账号....
'LOGIN_SUCCESS' => '登录成功', 'LOGIN_SUCCESS' => '登录成功',
@ -79,7 +80,6 @@ return [
'OLD_PASSWORD_ERROR' => '原始密码不正确', 'OLD_PASSWORD_ERROR' => '原始密码不正确',
'MOBILE_LOGIN_UNOPENED' => '手机号登录注册未开启', 'MOBILE_LOGIN_UNOPENED' => '手机号登录注册未开启',
'APP_TYPE_NOT_EXIST' => '无效的登录端口', 'APP_TYPE_NOT_EXIST' => '无效的登录端口',
"USER_NOT_ALLOW_DEL" => "该用户是一些站点的管理员不允许删除",
"SUPER_ADMIN_NOT_ALLOW_DEL" => "超级管理员不允许删除", "SUPER_ADMIN_NOT_ALLOW_DEL" => "超级管理员不允许删除",
//用户组权限 //用户组权限
@ -112,7 +112,7 @@ return [
'ATTACHMENT_GROUP_HAS_IMAGE' => '附件组中存在图片不允许删除', 'ATTACHMENT_GROUP_HAS_IMAGE' => '附件组中存在图片不允许删除',
'OSS_TYPE_NOT_EXIST' => '云存储类型不存在', 'OSS_TYPE_NOT_EXIST' => '云存储类型不存在',
'URL_FILE_NOT_EXIST' => '获取不到网址指向的文件', 'URL_FILE_NOT_EXIST' => '获取不到网址指向的文件',
'PLEACE_SELECT_IMAGE' => '请选择要删除的图片', 'PLEASE_SELECT_IMAGE' => '请选择要删除的图片',
'UPLOAD_TYPE_ERROR' => '不是有效的上传类型', 'UPLOAD_TYPE_ERROR' => '不是有效的上传类型',
'OSS_FILE_URL_NOT_EXIST' => '远程资源文件地址不能为空', 'OSS_FILE_URL_NOT_EXIST' => '远程资源文件地址不能为空',
'BASE_IMAGE_FILE_NOT_EXIST' => 'base图片资源不能为空', 'BASE_IMAGE_FILE_NOT_EXIST' => 'base图片资源不能为空',
@ -218,6 +218,7 @@ return [
'WEAPP_NOT_EXIST' => '微信小程序未配置完善', 'WEAPP_NOT_EXIST' => '微信小程序未配置完善',
'WEAPP_EMPOWER_NOT_EXIST' => '微信小程序授信信息不存在', 'WEAPP_EMPOWER_NOT_EXIST' => '微信小程序授信信息不存在',
'WEAPP_EMPOWER_TEL_NOT_EXIST' => '微信小程序授信手机号不存在', 'WEAPP_EMPOWER_TEL_NOT_EXIST' => '微信小程序授信手机号不存在',
'CURR_SITE_IS_NOT_OPEN_SSL' => '微信小程序请求地址只支持https请先配置ssl',
'WECHAT_MINI_PROGRAM_CODE_GENERATION_FAILED' => '微信小程序码生成失败', 'WECHAT_MINI_PROGRAM_CODE_GENERATION_FAILED' => '微信小程序码生成失败',
@ -329,8 +330,6 @@ return [
/********************************************************* 微信开放平台 **************************************/ /********************************************************* 微信开放平台 **************************************/
'WECHAT_OPLATFORM_NOT_EXIST' => '未配置微信开放平台', 'WECHAT_OPLATFORM_NOT_EXIST' => '未配置微信开放平台',
'WEAPP_EXIST' => '该小程序已经授权给其他站点',
'WECHAT_EXIST' => '该公众号已经授权给其他站点',
'NOT_YET_PRESENT_TEMPLATE_LIBRARY' => '平台尚未上传小程序到模板库', 'NOT_YET_PRESENT_TEMPLATE_LIBRARY' => '平台尚未上传小程序到模板库',
'WEAPP_VERSION_NOT_EXIST' => '未获取到小程序版本提交记录', 'WEAPP_VERSION_NOT_EXIST' => '未获取到小程序版本提交记录',
'NOT_ALLOWED_CANCEL_AUDIT' => '只有审核中的才可以撤回', 'NOT_ALLOWED_CANCEL_AUDIT' => '只有审核中的才可以撤回',

View File

@ -26,7 +26,6 @@ class MemberLoginListener
{ {
// 新人专享活动 // 新人专享活动
event("MemberLoginAfter", ['member_id' => $member['member_id']]); event("MemberLoginAfter", ['member_id' => $member['member_id']]);
return;
} }
} }

View File

@ -20,6 +20,5 @@ class PayNotifyListener
{ {
public function handle($member) public function handle($member)
{ {
return;
} }
} }

View File

@ -221,60 +221,6 @@ class AddonService extends BaseAdminService
return $this->model->where([ [ 'key', '=', $key ] ])->field('title, icon, key, desc, status, cover')->findOrEmpty()->toArray(); return $this->model->where([ [ 'key', '=', $key ] ])->field('title, icon, key, desc, status, cover')->findOrEmpty()->toArray();
} }
/**
* 查询应用列表todo 完善
* @return array
*/
public function getShowAppTools()
{
$list = [
'tool' => $this->getAllAddonAndTool()[ 'tool' ],
];
return $list;
}
/**
* 查询营销列表
* @return array
*/
public function getShowMarketingTools()
{
$all = $this->getAllAddonAndTool();
$list = [
'marketing' => $all[ 'marketing' ],
'addon' => $all[ 'addon' ],
];
return $list;
}
private function getMarketing()
{
$list = [
'marketing' => [
'title' => '营销活动',
'list' => []
]
];
$apps = event('ShowMarketing');
$keys = [];
foreach ($apps as $v) {
foreach ($v as $ck => $cv) {
if (!empty($cv)) {
foreach ($cv as $addon_k => $addon_v) {
if (in_array($addon_v[ 'key' ], $keys)) {
continue;
}
$list[ $ck ][ 'list' ][] = $addon_v;
$keys[] = $addon_v[ 'key' ];
}
}
}
}
return $list;
}
/** /**
* @return array[] * @return array[]
*/ */
@ -303,7 +249,7 @@ class AddonService extends BaseAdminService
$keys[] = $value[ 'key' ]; $keys[] = $value[ 'key' ];
} }
} }
$addon_list = $this->getAddonList([]); $addon_list = $this->getAddonList();
$menu_model = ( new SysMenu() ); $menu_model = ( new SysMenu() );
$addon_urls = $menu_model $addon_urls = $menu_model
->where([ [ 'addon', 'in', array_column($addon_list, 'key') ], [ 'addon', 'not in', $keys ], [ 'is_show', '=', 1 ], [ 'menu_type', '=', 1 ] ]) ->where([ [ 'addon', 'in', array_column($addon_list, 'key') ], [ 'addon', 'not in', $keys ], [ 'is_show', '=', 1 ], [ 'menu_type', '=', 1 ] ])
@ -334,6 +280,7 @@ class AddonService extends BaseAdminService
} }
return $return; return $return;
} }
//生成菜单数据 //生成菜单数据
public function getSpecialMenuList() public function getSpecialMenuList()
{ {
@ -362,11 +309,13 @@ class AddonService extends BaseAdminService
'is_show' => '1', 'is_show' => '1',
]; ];
$children = []; $children = [];
if (!empty($auth_menu_list)) {
foreach ($auth_menu_list as $datum_item) { foreach ($auth_menu_list as $datum_item) {
if (in_array($datum_item[ 'menu_key' ], $menu_key_list)) { if (in_array($datum_item[ 'menu_key' ], $menu_key_list)) {
$children[] = $datum_item; $children[] = $datum_item;
} }
} }
}
$temp_menu[ 'children' ] = $children; $temp_menu[ 'children' ] = $children;
$menu_list[] = $temp_menu; $menu_list[] = $temp_menu;
} }
@ -381,82 +330,4 @@ class AddonService extends BaseAdminService
]; ];
} }
private function getAllAddonAndTool()
{
$markting_list = $this->getMarketing() ?? [];
$markting = $markting_list[ 'marketing' ];
$marking_addon = $markting_list[ 'tool' ][ 'list' ] ?? [];
$list = [
'marketing' => $markting,
'addon' => [
'title' => '营销工具',
'list' => $marking_addon
],
'tool' => [
'title' => '系统工具',
'list' => []
]
];
$apps = event('ShowApp');
$keys = [];
foreach ($apps as $v) {
foreach ($v as $ck => $cv) {
if (!empty($cv)) {
foreach ($cv as $addon_k => $addon_v) {
if (in_array($addon_v[ 'key' ], $keys)) {
continue;
}
$list[ $ck ][ 'list' ][] = $addon_v;
$keys[] = $addon_v[ 'key' ];
}
}
}
}
$menu_model = ( new SysMenu() );
$site_addons = $this->getAddonList();
if (!empty($site_addons)) {
foreach ($site_addons as $k => $v) {
if ($v[ 'type' ] == 'app') {
unset($site_addons[ $k ]);
}
}
$addon_urls = $menu_model
->where([ [ 'addon', 'in', array_column($site_addons, 'key') ], [ 'is_show', '=', 1 ], [ 'menu_type', '=', 1 ] ])
->order('id asc')
->group('addon')
->column('router_path', 'addon');
foreach ($site_addons as $k => $v) {
$continue = true;
if (!empty($markting[ 'list' ])) {
foreach ($markting[ 'list' ] as $key => $val) {
if ($v[ 'key' ] == $val[ 'key' ]) {
unset($site_addons[ $k ]);
$continue = false;
}
}
}
if ($continue && !in_array($v[ 'key' ], $keys)) {
$url = $addon_urls[ $v[ 'key' ] ] ?? '';
$list[ 'addon' ][ 'list' ][] = [
'title' => $v[ 'title' ],
'desc' => $v[ 'desc' ],
'icon' => $v[ 'icon' ],
'key' => $v[ 'key' ],
'url' => $url ? '/' . $url : ''
];
}
}
}
return $list;
}
} }

View File

@ -15,8 +15,10 @@ use app\Request;
use app\service\admin\sys\MenuService; use app\service\admin\sys\MenuService;
use app\service\admin\sys\RoleService; use app\service\admin\sys\RoleService;
use app\service\admin\user\UserService; use app\service\admin\user\UserService;
use app\service\core\niucloud\CoreAuthService;
use core\base\BaseAdminService; use core\base\BaseAdminService;
use core\exception\AuthException; use core\exception\AuthException;
use core\exception\CommonException;
use Exception; use Exception;
/** /**
@ -35,10 +37,15 @@ class AuthService extends BaseAdminService
*/ */
public function checkRole(Request $request) public function checkRole(Request $request)
{ {
$this->checkAuthinfo($request);
$rule = strtolower(trim($request->rule()->getRule())); $rule = strtolower(trim($request->rule()->getRule()));
$method = strtolower(trim($request->method())); $method = strtolower(trim($request->method()));
if($method != 'get'){
// throw new AuthException('演示站禁止操作');
}
$menu_service = new MenuService(); $menu_service = new MenuService();
$all_menu_list = $menu_service->getAllApiList(); $all_menu_list = $menu_service->getAllApiList();
//先判断当前访问的接口是否收到权限的限制 //先判断当前访问的接口是否收到权限的限制
@ -54,6 +61,33 @@ class AuthService extends BaseAdminService
} }
public function checkAuthinfo(Request $request) {
$rule = strtolower(trim($request->rule()->getRule()));
$method = strtolower(trim($request->method()));
if ($method == 'get') return;
$ignore = ['niucloud/authinfo', 'upgrade', 'niucloud/build', 'sys/cache/clear'];
foreach ($ignore as $item) {
if (strpos($rule, $item) !== false) return;
}
$authinfo = (new CoreAuthService())->getAuthInfo()['data'] ?? [];;
if (empty($authinfo)) return;
if (!$this->isCheckDomain()) return;
$site_address = $authinfo['site_address'] ?? '';
$domain = request()->domain();
if (!empty($site_address) && strpos($domain, $site_address) !== false) return;
throw new CommonException("授权域名校验失败!请确保当前访问域名与授权码绑定的域名一致");
}
private function isCheckDomain() {
return !(request()->ip() == '127.0.0.1' || request()->host() == 'localhost');
}
/** /**
* 当前授权用户接口权限 * 当前授权用户接口权限
* @return array * @return array

View File

@ -20,7 +20,6 @@ use app\service\core\sys\CoreConfigService;
use core\base\BaseAdminService; use core\base\BaseAdminService;
use core\exception\AuthException; use core\exception\AuthException;
use core\util\TokenAuth; use core\util\TokenAuth;
use Exception;
use Throwable; use Throwable;
/** /**
@ -41,7 +40,6 @@ class LoginService extends BaseAdminService
* 用户登录 * 用户登录
* @param string $username * @param string $username
* @param string $password * @param string $password
* @param string $app_type
* @return array|bool * @return array|bool
*/ */
public function login(string $username, string $password) public function login(string $username, string $password)
@ -127,7 +125,6 @@ class LoginService extends BaseAdminService
/** /**
* 清理token * 清理token
* @param int $uid * @param int $uid
* @param string|null $type
* @param string|null $token * @param string|null $token
*/ */
public static function clearToken(int $uid, ?string $token = '') public static function clearToken(int $uid, ?string $token = '')
@ -151,7 +148,6 @@ class LoginService extends BaseAdminService
$token_info = TokenAuth::parseToken($token, AppTypeDict::ADMIN); $token_info = TokenAuth::parseToken($token, AppTypeDict::ADMIN);
} catch (Throwable $e) { } catch (Throwable $e) {
throw new AuthException('LOGIN_EXPIRE', 401); throw new AuthException('LOGIN_EXPIRE', 401);
} }
if (!$token_info) { if (!$token_info) {
throw new AuthException('MUST_LOGIN', 401); throw new AuthException('MUST_LOGIN', 401);

View File

@ -60,22 +60,39 @@ class DiyService extends BaseAdminService
/** /**
* 获取自定义页面分页列表,轮播搜索组件用 * 获取自定义页面分页列表,轮播搜索组件用
* 查询微页面,数据排除存在轮播搜索组件的 * 查询微页面,数据排除存在轮播搜索组件的
* @param array $where
* @return array * @return array
* @throws DbException
*/ */
public function getPageByCarouselSearch() public function getPageByCarouselSearch()
{ {
$field = 'id,title,page_title,name,template,type,mode,is_default,share,visit_count,create_time,update_time,value'; $field = 'id,title,page_title,name,type,create_time,value';
$order = "update_time desc"; $order = "update_time desc";
$search_model = $this->model->whereOr([ $search_model = $this->model
->whereOr([
[ [
[ 'type', '=', 'DIY_PAGE' ], [ 'type', '=', 'DIY_PAGE' ],
[ 'value', 'not in', [ 'top_fixed', 'right_fixed', 'bottom_fixed', 'left_fixed', 'fixed' ] ] [ 'value', 'not like',
[
'%"position":"top_fixed"%',
'%"position":"right_fixed"%',
'%"position":"bottom_fixed"%',
'%"position":"left_fixed"%',
'%"position":"fixed"%'
]
]
], ],
[ [
[ 'type', '<>', 'DIY_PAGE' ], [ 'type', '<>', 'DIY_PAGE' ],
[ 'is_default', '=', 0 ], [ 'is_default', '=', 0 ],
[ 'value', 'not in', [ 'top_fixed', 'right_fixed', 'bottom_fixed', 'left_fixed', 'fixed' ] ] [ 'value', 'not like',
[
'%"position":"top_fixed"%',
'%"position":"right_fixed"%',
'%"position":"bottom_fixed"%',
'%"position":"left_fixed"%',
'%"position":"fixed"%'
]
]
] ]
])->field($field)->order($order)->append([ 'type_name', 'type_page', 'addon_name' ]); ])->field($field)->order($order)->append([ 'type_name', 'type_page', 'addon_name' ]);
return $this->pageQuery($search_model); return $this->pageQuery($search_model);

View File

@ -205,7 +205,7 @@ class GenerateService extends BaseAdminService
$table_id = $res->id; $table_id = $res->id;
$add_column_data = []; $add_column_data = [];
$default_column = ['id', 'create_time', 'update_time']; $default_column = ['id', 'create_time', 'update_time', 'delete_time'];
foreach ($fields as $k => $v){ foreach ($fields as $k => $v){
$required = 0; $required = 0;
if ($v['notnull'] && !$v['primary'] && !in_array($v['name'], $default_column)) { if ($v['notnull'] && !$v['primary'] && !in_array($v['name'], $default_column)) {

View File

@ -212,7 +212,7 @@ use app\adminapi\middleware\AdminLog;";
{ {
if(!empty($this->addonName)) if(!empty($this->addonName))
{ {
$dir = $this->outDir . DIRECTORY_SEPARATOR.'addon'.DIRECTORY_SEPARATOR.'.$this->addonName.'.DIRECTORY_SEPARATOR.'app'.DIRECTORY_SEPARATOR.'adminapi'.DIRECTORY_SEPARATOR.'route'.DIRECTORY_SEPARATOR; $dir = $this->outDir . DIRECTORY_SEPARATOR.'addon'.DIRECTORY_SEPARATOR.$this->addonName.DIRECTORY_SEPARATOR.'app'.DIRECTORY_SEPARATOR.'adminapi'.DIRECTORY_SEPARATOR.'route'.DIRECTORY_SEPARATOR;
}else{ }else{
$dir = $this->outDir . 'niucloud'.DIRECTORY_SEPARATOR.'app'.DIRECTORY_SEPARATOR.'adminapi'.DIRECTORY_SEPARATOR.'route'.DIRECTORY_SEPARATOR; $dir = $this->outDir . 'niucloud'.DIRECTORY_SEPARATOR.'app'.DIRECTORY_SEPARATOR.'adminapi'.DIRECTORY_SEPARATOR.'route'.DIRECTORY_SEPARATOR;
} }

View File

@ -106,7 +106,7 @@ class WebEditGenerator extends BaseGenerator
{ {
$content = ''; $content = '';
foreach ($this->tableColumn as $column) { foreach ($this->tableColumn as $column) {
if (!$column['is_insert'] || !$column['is_update'] || $column['is_pk']) { if (!$column['is_insert'] || !$column['is_update'] || $column['is_pk'] || $column['is_delete']) {
continue; continue;
} }
@ -435,7 +435,7 @@ class WebEditGenerator extends BaseGenerator
/** /**
* 获取文件生成到插件中 * 获取文件生成到插件中
* @return void * @return string
*/ */
public function getAddonObjectOutDir() { public function getAddonObjectOutDir() {
$dir = $this->rootDir . DIRECTORY_SEPARATOR.'niucloud'.DIRECTORY_SEPARATOR.'addon'.DIRECTORY_SEPARATOR.$this->addonName.DIRECTORY_SEPARATOR.'admin'.DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR. $this->moduleName . DIRECTORY_SEPARATOR.'components'.DIRECTORY_SEPARATOR; $dir = $this->rootDir . DIRECTORY_SEPARATOR.'niucloud'.DIRECTORY_SEPARATOR.'addon'.DIRECTORY_SEPARATOR.$this->addonName.DIRECTORY_SEPARATOR.'admin'.DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR. $this->moduleName . DIRECTORY_SEPARATOR.'components'.DIRECTORY_SEPARATOR;
@ -492,7 +492,7 @@ class WebEditGenerator extends BaseGenerator
/** /**
* 调用字典方法 * 调用字典方法
* @return void * @return string
*/ */
public function getDictList() public function getDictList()
{ {
@ -518,7 +518,7 @@ class WebEditGenerator extends BaseGenerator
/** /**
* 调用远程下拉方法 * 调用远程下拉方法
* @return void * @return string
*/ */
public function getModelData() public function getModelData()
{ {
@ -542,7 +542,7 @@ class WebEditGenerator extends BaseGenerator
/** /**
* 编辑远程下拉方法 * 编辑远程下拉方法
* @return void * @return string
*/ */
public function getEditWithApiPath() public function getEditWithApiPath()
{ {
@ -559,7 +559,7 @@ class WebEditGenerator extends BaseGenerator
/** /**
* 增加关联方法 * 增加关联方法
* @return void * @return string
*/ */
public function getWithApiPath() public function getWithApiPath()
{ {

View File

@ -156,7 +156,7 @@ class WebEditPageGenerator extends BaseGenerator
{ {
$content = ''; $content = '';
foreach ($this->tableColumn as $column) { foreach ($this->tableColumn as $column) {
if (!$column['is_insert'] || !$column['is_update'] || $column['is_pk']) { if (!$column['is_insert'] || !$column['is_update'] || $column['is_pk'] || $column['is_delete']) {
continue; continue;
} }
@ -505,7 +505,7 @@ class WebEditPageGenerator extends BaseGenerator
/** /**
* 调用远程下拉方法 * 调用远程下拉方法
* @return void * @return string
*/ */
public function getModelData() public function getModelData()
{ {
@ -528,7 +528,7 @@ class WebEditPageGenerator extends BaseGenerator
/** /**
* 编辑远程下拉方法 * 编辑远程下拉方法
* @return void * @return string
*/ */
public function getEditWithApiPath() public function getEditWithApiPath()
{ {

View File

@ -539,7 +539,7 @@ class WebIndexGenerator extends BaseGenerator
/** /**
* 增加关联方法 * 增加关联方法
* @return void * @return string
*/ */
public function getWithApiPath() public function getWithApiPath()
{ {
@ -556,7 +556,7 @@ class WebIndexGenerator extends BaseGenerator
/** /**
* 调用远程下拉方法 * 调用远程下拉方法
* @return void * @return string
*/ */
public function getModelData() public function getModelData()
{ {

View File

@ -15,7 +15,6 @@ use app\model\member\MemberAddress;
use app\service\admin\sys\AreaService; use app\service\admin\sys\AreaService;
use app\service\core\member\CoreMemberAddressService; use app\service\core\member\CoreMemberAddressService;
use core\base\BaseAdminService; use core\base\BaseAdminService;
use core\exception\AdminException;
/** /**

View File

@ -22,6 +22,7 @@ use core\exception\AdminException;
use think\db\exception\DataNotFoundException; use think\db\exception\DataNotFoundException;
use think\db\exception\DbException; use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException; use think\db\exception\ModelNotFoundException;
use think\facade\Db;
/** /**
* 会员服务层 * 会员服务层
@ -80,7 +81,11 @@ class MemberService extends BaseAdminService
public function getInfo(int $member_id) public function getInfo(int $member_id)
{ {
$field = 'member_id,member_no, id_card,remark,username, mobile, password, register_channel, register_type, nickname, headimg, member_level, member_label, wx_openid, weapp_openid, wx_unionid, ali_openid, douyin_openid, login_ip, login_type, login_channel, login_count, login_time, create_time, last_visit_time, last_consum_time, sex, status, birthday, point, point_get, balance, balance_get, growth, growth_get, is_member, member_time, is_del, province_id, city_id, district_id, address, location, delete_time, money, money_get, commission, commission_get, commission_cash_outing'; $field = 'member_id,member_no, id_card,remark,username, mobile, password, register_channel, register_type, nickname, headimg, member_level, member_label, wx_openid, weapp_openid, wx_unionid, ali_openid, douyin_openid, login_ip, login_type, login_channel, login_count, login_time, create_time, last_visit_time, last_consum_time, sex, status, birthday, point, point_get, balance, balance_get, growth, growth_get, is_member, member_time, is_del, province_id, city_id, district_id, address, location, delete_time, money, money_get, commission, commission_get, commission_cash_outing';
return $this->makeUp($this->model->where([ [ 'member_id', '=', $member_id ] ])->field($field)->with('member_level_name_bind')->append([ 'register_channel_name', 'register_type_name', 'sex_name', 'login_channel_name', 'login_type_name', 'status_name' ])->findOrEmpty()->toArray()); $info = $this->makeUp($this->model->where([ [ 'member_id', '=', $member_id ] ])->field($field)->with('member_level_name_bind')->append([ 'register_channel_name', 'register_type_name', 'sex_name', 'login_channel_name', 'login_type_name', 'status_name' ])->findOrEmpty()->toArray());
if (empty($info[ 'member_level' ])) {
$info[ 'member_level' ] = '';
}
return $info;
} }
/** /**
@ -149,6 +154,7 @@ class MemberService extends BaseAdminService
* @param int $member_id * @param int $member_id
* @param string $field * @param string $field
* @param $data * @param $data
* @return Member
*/ */
public function modify(int $member_id, string $field, $data) public function modify(int $member_id, string $field, $data)
{ {
@ -168,6 +174,10 @@ class MemberService extends BaseAdminService
/** /**
* 组合整理数据 * 组合整理数据
* @param $data * @param $data
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/ */
public function makeUp($data) public function makeUp($data)
{ {
@ -223,7 +233,16 @@ class MemberService extends BaseAdminService
*/ */
public function getMemberNo() public function getMemberNo()
{ {
return ( new CoreMemberService() )->createMemberNo(); //开启事务,解决创建会员编码重复
try {
Db::startTrans();
$member_no = ( new CoreMemberService() )->createMemberNo();
Db::commit();
return $member_no;
} catch (AdminException $e) {
Db::rollback();
throw new AdminException("MEMBER_NO_CREATE_ERROR");
}
} }
/** /**
@ -256,7 +275,7 @@ class MemberService extends BaseAdminService
/** /**
* 获取会员权益字典 * 获取会员权益字典
* @return mixed * @return array|null
*/ */
public function getMemberBenefitsDict() public function getMemberBenefitsDict()
{ {
@ -302,7 +321,7 @@ class MemberService extends BaseAdminService
/** /**
* 获取会员礼包内容 * 获取会员礼包内容
* @param array $benefits * @param array $gifts
* @return array|null * @return array|null
*/ */
public function getMemberGiftsContent(array $gifts) public function getMemberGiftsContent(array $gifts)

View File

@ -50,6 +50,7 @@ class MemberSignService extends BaseAdminService
/** /**
* 组合整理数据 * 组合整理数据
* @param $data * @param $data
* @return mixed
*/ */
public function makeUp($data) public function makeUp($data)
{ {
@ -84,14 +85,14 @@ class MemberSignService extends BaseAdminService
*/ */
public function setSign(array $value) public function setSign(array $value)
{ {
if (empty($value[ 'sign_period' ])) throw new AdminException('SIGN_PERIOD_CANNOT_EMPTY'); // if (empty($value[ 'sign_period' ])) throw new AdminException('SIGN_PERIOD_CANNOT_EMPTY');
if ($value[ 'sign_period' ] < 2 || $value[ 'sign_period' ] > 365) throw new AdminException('SIGN_PERIOD_BETWEEN_2_365_DAYS'); // if ($value[ 'sign_period' ] < 2 || $value[ 'sign_period' ] > 365) throw new AdminException('SIGN_PERIOD_BETWEEN_2_365_DAYS');
if (!empty($value[ 'continue_award' ])) { // if (!empty($value[ 'continue_award' ])) {
foreach ($value[ 'continue_award' ] as $v) { // foreach ($value[ 'continue_award' ] as $v) {
if ($v[ 'continue_sign' ] < 2 || $v[ 'continue_sign' ] > 365) throw new AdminException('CONTINUE_SIGN_BETWEEN_2_365_DAYS'); // if ($v[ 'continue_sign' ] < 2 || $v[ 'continue_sign' ] > 365) throw new AdminException('CONTINUE_SIGN_BETWEEN_2_365_DAYS');
if ($v[ 'continue_sign' ] > $value[ 'sign_period' ]) throw new AdminException('CONTINUE_SIGN_CANNOT_GREATER_THAN_SIGN_PERIOD'); // if ($v[ 'continue_sign' ] > $value[ 'sign_period' ]) throw new AdminException('CONTINUE_SIGN_CANNOT_GREATER_THAN_SIGN_PERIOD');
} // }
} // }
$data = [ $data = [
'is_use' => $value[ 'is_use' ], //是否开启 'is_use' => $value[ 'is_use' ], //是否开启
'sign_period' => $value[ 'sign_period' ], // 签到周期 'sign_period' => $value[ 'sign_period' ], // 签到周期

View File

@ -17,6 +17,7 @@ use app\service\core\niucloud\CoreModuleService;
use app\service\core\sys\CoreConfigService; use app\service\core\sys\CoreConfigService;
use core\base\BaseAdminService; use core\base\BaseAdminService;
use core\exception\CommonException; use core\exception\CommonException;
use think\facade\Cache;
/** /**
* 消息管理服务层 * 消息管理服务层
@ -47,6 +48,7 @@ class NiucloudService extends BaseAdminService
$auth_info = $service->getAuthInfo()['data'] ?? []; $auth_info = $service->getAuthInfo()['data'] ?? [];
if (empty($auth_info)) throw new CommonException('AUTH_NOT_EXISTS'); if (empty($auth_info)) throw new CommonException('AUTH_NOT_EXISTS');
$service->clearAccessToken(); $service->clearAccessToken();
Cache::set("authinfo", null);
return $this->core_config_service->setConfig(ConfigKeyDict::NIUCLOUD_CONFIG, $data); return $this->core_config_service->setConfig(ConfigKeyDict::NIUCLOUD_CONFIG, $data);
} }

View File

@ -233,10 +233,34 @@ class NiuSmsService extends BaseAdminService
*/ */
public function signCreate($username, $params) public function signCreate($username, $params)
{ {
if (!empty($params['imgUrl']) && strstr($params['imgUrl'], 'http') === false) { $params['imgUrl'] = $this->formatImageUrl($params['imgUrl']);
$params['imgUrl'] = request()->domain() . '/' . $params['imgUrl']; $params['bizLicenseUrl'] = $this->formatImageUrl($params['bizLicenseUrl']);
} else { $params['qccUrl'] = $this->formatImageUrl($params['qccUrl']);
$params['imgUrl'] = $params['imgUrl'] ?? ''; $params['tmnetUrl'] = $this->formatImageUrl($params['tmnetUrl']);
$params['mobileIcpUrl'] = $this->formatImageUrl($params['mobileIcpUrl']);
$params['telecomAppstoreUrl'] = $this->formatImageUrl($params['telecomAppstoreUrl']);
$params['idcardFrontUrl'] = $this->formatImageUrl($params['idcardFrontUrl']);
$params['idcardBackUrl'] = $this->formatImageUrl($params['idcardBackUrl']);
if (empty($params['idcardFrontUrl'])) {
throw new ApiException('身份证正面不能为空');
}
if (empty($params['idcardBackUrl'])) {
throw new ApiException('身份证反面不能为空');
}
if (empty($params['bizLicenseUrl'])) {
throw new ApiException('营业执照');
}
if (in_array($params['signSource'], [4, 5]) && empty($params['telecomAppstoreUrl'])) {
throw new ApiException('应用商店/小程序页面开发者截图不能为空');
}
if (in_array($params['signSource'], [4, 5]) && empty($params['mobileIcpUrl'])) {
throw new ApiException('移动ICP截图不能为空');
}
if (in_array($params['signSource'], [3]) && empty($params['tmnetUrl'])) {
throw new ApiException('中国商标网截图不能为空');
}
if (in_array($params['signSource'], [1, 2]) && $params['signType'] == 1 && empty($params['qccUrl'])) {
throw new ApiException('企查查唯一性截图不能为空');
} }
$res = $this->niu_service->signCreate($username, $params); $res = $this->niu_service->signCreate($username, $params);
if (!empty($res['failList'])) { if (!empty($res['failList'])) {
@ -244,6 +268,21 @@ class NiuSmsService extends BaseAdminService
} }
} }
/**
* 格式化图片地址
* @param $url
* @return string
*/
private function formatImageUrl($url)
{
if (!empty($url) && strstr($url, 'http') === false) {
$url = request()->domain() . '/' . $url;
} else {
$url = $url ?? '';
}
return $url;
}
/** /**
* 签名创建 * 签名创建
* @param $username * @param $username

View File

@ -31,11 +31,15 @@ class RefundService extends BaseAdminService
/** /**
* 退款账户记录 * 退款账户记录
* @param array $where * @param array $where
* @return mixed * @return array
*/ */
public function getPage(array $where){ public function getPage(array $where){
$field = 'id,refund_no,out_trade_no,type,channel,money,reason,status,create_time,refund_time,close_time,fail_reason,voucher,trade_type,trade_id,refund_type,main_type,main_id'; $field = 'id,refund_no,out_trade_no,type,channel,money,reason,status,create_time,refund_time,close_time,fail_reason,voucher,trade_type,trade_id,refund_type,main_type,main_id';
$search_model = $this->model->where([ [ 'id', '>', 0 ] ])->withSearch([ 'create_time', 'out_trade_no', 'refund_no', 'status' ], $where)->field($field)->append([ 'type_name', 'status_name' ])->order('create_time desc'); $search_model = $this->model->where([ [ 'id', '>', 0 ] ])
->withSearch([ 'create_time', 'out_trade_no', 'refund_no', 'status' ], $where)
->field($field)
->append([ 'type_name', 'status_name','trade_type_name' ])
->order('create_time desc');
return $this->pageQuery($search_model); return $this->pageQuery($search_model);
} }

View File

@ -87,6 +87,9 @@ class ConfigService extends BaseAdminService
'front_end_logo' => '', 'front_end_logo' => '',
'front_end_icon' => '', 'front_end_icon' => '',
'icon' => '', 'icon' => '',
'meta_title' => '',
'meta_desc' => '',
'meta_keyword' => '',
]; ];
} }
return $info[ 'value' ]; return $info[ 'value' ];
@ -137,7 +140,6 @@ class ConfigService extends BaseAdminService
"enterprise_wechat" => $value[ 'enterprise_wechat' ], "enterprise_wechat" => $value[ 'enterprise_wechat' ],
"tel" => $value[ 'tel' ] "tel" => $value[ 'tel' ]
]; ];
return $this->core_config_service->setConfig('SERVICE_INFO', $data); return $this->core_config_service->setConfig('SERVICE_INFO', $data);
} }

View File

@ -54,7 +54,7 @@ class PosterService extends BaseAdminService
* 获取自定义海报列表 * 获取自定义海报列表
* @param array $where * @param array $where
* @param string $field * @param string $field
* @return mixed * @return array
*/ */
public function getList(array $where = [], $field = 'id, name, type, channel, value, status,is_default, create_time, update_time, addon') public function getList(array $where = [], $field = 'id, name, type, channel, value, status,is_default, create_time, update_time, addon')
{ {
@ -66,7 +66,7 @@ class PosterService extends BaseAdminService
* 获取自定义海报信息 * 获取自定义海报信息
* @param int $id * @param int $id
* @param string $field * @param string $field
* @return mixed * @return array
*/ */
public function getInfo(int $id, $field = 'id, name, type, channel, value, status,is_default, create_time, update_time, addon') public function getInfo(int $id, $field = 'id, name, type, channel, value, status,is_default, create_time, update_time, addon')
{ {
@ -109,7 +109,7 @@ class PosterService extends BaseAdminService
/** /**
* 修改自定义海报启用状态 * 修改自定义海报启用状态
* @param $data * @param $data
* @return mixed * @return Poster
*/ */
public function modifyStatus($data) public function modifyStatus($data)
{ {
@ -126,7 +126,7 @@ class PosterService extends BaseAdminService
/** /**
* 将自定义海报修改为默认海报 * 将自定义海报修改为默认海报
* @param $data * @param $data
* @return mixed * @return bool
*/ */
public function modifyDefault($data) public function modifyDefault($data)
{ {
@ -137,7 +137,7 @@ class PosterService extends BaseAdminService
} }
Db::startTrans(); Db::startTrans();
$this->model->where([ [ 'type', '=', $info[ 'type' ] ] ])->update([ 'is_default' => 0 ]); $this->model->where([ [ 'type', '=', $info[ 'type' ] ] ])->update([ 'is_default' => 0 ]);
$this->model->where([ [ 'id', '=', $data[ 'id' ] ] ])->update([ 'is_default' => 1, 'update_time' => time() ]); $this->model->where([ [ 'id', '=', $data[ 'id' ] ] ])->update([ 'is_default' => 1, 'status' => 1, 'update_time' => time() ]);
Db::commit(); Db::commit();
return true; return true;
} catch (Exception $e) { } catch (Exception $e) {

View File

@ -249,8 +249,10 @@ class RoleService extends BaseAdminService
/** /**
* 角色状态修改 * 角色状态修改
*/ */
public function modifyStatus(int $id, int $status) public function modifyStatus($data)
{ {
$id = $data[ 'role_id' ];
$status = $data[ 'status' ];
$this->model->where([ [ 'role_id', '=', $id ] ])->update([ 'status' => $status ]); $this->model->where([ [ 'role_id', '=', $id ] ])->update([ 'status' => $status ]);
return true; return true;
} }

View File

@ -127,24 +127,26 @@ class UpgradeService extends BaseAdminService
// 检测全部目录及文件是否可读可写,忽略指定目录 // 检测全部目录及文件是否可读可写,忽略指定目录
// 忽略指定目录admin // 忽略指定目录admin
$exclude_admin_dir = [ 'dist', 'node_modules', '.git' ]; $exclude_admin_dir = [ 'dist', 'node_modules', '.git', '.user.ini' ];
$check_res = checkDirPermissions(project_path() . 'admin', [], $exclude_admin_dir); $check_res = checkDirPermissions(project_path() . 'admin', [], $exclude_admin_dir);
// 忽略指定目录uni-app // 忽略指定目录uni-app
$exclude_uniapp_dir = [ 'dist', 'node_modules', '.git' ]; $exclude_uniapp_dir = [ 'dist', 'node_modules', '.git', '.user.ini' ];
$check_res = array_merge2($check_res, checkDirPermissions(project_path() . 'uni-app', [], $exclude_uniapp_dir)); $check_res = array_merge2($check_res, checkDirPermissions(project_path() . 'uni-app', [], $exclude_uniapp_dir));
// 忽略指定目录web // 忽略指定目录web
$exclude_web_dir = [ '.nuxt', '.output', 'dist', 'node_modules', '.git' ]; $exclude_web_dir = [ '.nuxt', '.output', 'dist', 'node_modules', '.git', '.user.ini' ];
$check_res = array_merge2($check_res, checkDirPermissions(project_path() . 'web', [], $exclude_web_dir)); $check_res = array_merge2($check_res, checkDirPermissions(project_path() . 'web', [], $exclude_web_dir));
// 忽略指定目录niucloud // 忽略指定目录niucloud
$exclude_niucloud_dir = [ $exclude_niucloud_dir = [
'public' . DIRECTORY_SEPARATOR . 'admin', 'public' . DIRECTORY_SEPARATOR . 'admin',
'public' . DIRECTORY_SEPARATOR . 'admin' . DIRECTORY_SEPARATOR .'niucloud.ico',
'public' . DIRECTORY_SEPARATOR . 'wap', 'public' . DIRECTORY_SEPARATOR . 'wap',
'public' . DIRECTORY_SEPARATOR . 'web', 'public' . DIRECTORY_SEPARATOR . 'web',
'public' . DIRECTORY_SEPARATOR . 'upload', 'public' . DIRECTORY_SEPARATOR . 'upload',
'public' . DIRECTORY_SEPARATOR . 'file', 'public' . DIRECTORY_SEPARATOR . 'file',
'public' . DIRECTORY_SEPARATOR . 'favicon.ico',
'runtime', 'runtime',
'vendor', 'vendor',
'.user.ini', '.user.ini',
@ -313,8 +315,6 @@ class UpgradeService extends BaseAdminService
} }
if (!in_array($step, [ 'upgradeComplete', 'restoreComplete' ])) { if (!in_array($step, [ 'upgradeComplete', 'restoreComplete' ])) {
Cache::set($this->cache_key, $this->upgrade_task); Cache::set($this->cache_key, $this->upgrade_task);
} else {
$this->clearUpgradeTask(2);
} }
} catch (CloudBuildException $e) { } catch (CloudBuildException $e) {
if (strpos($e->getMessage(), '队列') !== false) { if (strpos($e->getMessage(), '队列') !== false) {
@ -466,7 +466,7 @@ class UpgradeService extends BaseAdminService
// 覆盖文件 // 覆盖文件
if (is_dir($code_dir . $version_no)) { if (is_dir($code_dir . $version_no)) {
// 忽略环境变量文件 // 忽略环境变量文件
$exclude_files = [ '.env.development', '.env.production', '.env', '.env.dev', '.env.product' ]; $exclude_files = [ '.env.development', '.env.production', '.env', '.env.dev', '.env.product', 'favicon.ico', 'niucloud.ico' ];
dir_copy($code_dir . $version_no, $to_dir, exclude_files: $exclude_files); dir_copy($code_dir . $version_no, $to_dir, exclude_files: $exclude_files);
if ($addon != AddonDict::FRAMEWORK_KEY) { if ($addon != AddonDict::FRAMEWORK_KEY) {
( new CoreAddonInstallService($addon) )->installDir(); ( new CoreAddonInstallService($addon) )->installDir();
@ -629,15 +629,57 @@ class UpgradeService extends BaseAdminService
$sql_data = array_filter($this->getSqlQuery($sql_content)); $sql_data = array_filter($this->getSqlQuery($sql_content));
if (!empty($sql_data)) { if (!empty($sql_data)) {
try {
$default_collation = Db::query("SHOW VARIABLES LIKE 'collation_database'")[0]['Value'] ?? 'utf8mb4_general_ci';
} catch (\Exception $e) {
$default_collation = 'utf8mb4_general_ci';
}
foreach ($sql_data as $sql) { foreach ($sql_data as $sql) {
$sql = $prefix ? $this->handleSqlPrefix($sql, $prefix) : $sql; $sql = $prefix ? $this->handleSqlPrefix($sql, $prefix) : $sql;
// 处理成默认排序规则
$sql = preg_replace_callback(
'/\bCOLLATE\s*(=)?\s*[`"\']?([a-zA-Z0-9_]+)[`"\']?/i',
function ($matches) use ($default_collation) {
return "COLLATE " . $default_collation;
},
$sql
);
// 判断是否是新增字段
$pattern = '/^ALTER\s+TABLE\s+(`?)(\w+)\1\s+ADD(?:\s+COLUMN)?\s+(`?)(\w+)\3\s+/i';
if (preg_match($pattern, $sql, $matches)) {
if (!$this->columnExists($matches[2], $matches[4])) {
Db::query($sql);
}
}else{
Db::query($sql); Db::query($sql);
} }
} }
} }
}
return true; return true;
} }
/**
* 判断数据表中某个字段是否存在
*
* @param string $table 表名(不带前缀)
* @param string $column 字段名
* @param string|null $database 指定数据库名(可选,默认当前连接的数据库)
* @return bool
*/
private function columnExists(string $table, string $column, ?string $database = null): bool
{
$db = env('database.database', '');
$count = Db::query(
"SELECT COUNT(*) AS cnt FROM information_schema.COLUMNS
WHERE table_schema = ? AND table_name = ? AND column_name = ?",
[$db, $table, $column]
);
return (int)$count[0]['cnt'] > 0;
}
/** /**
* 刷新菜单 * 刷新菜单
* @return array|true * @return array|true
@ -703,20 +745,10 @@ class UpgradeService extends BaseAdminService
foreach ($log[ 'data' ][ 0 ] as $item) { foreach ($log[ 'data' ][ 0 ] as $item) {
if ($item[ 'code' ] == 0) { if ($item[ 'code' ] == 0) {
$this->upgrade_task[ 'step' ] = 'gteCloudBuildLog'; $this->upgrade_task[ 'step' ] = 'gteCloudBuildLog';
$this->upgrade_task[ 'error' ][] = $item[ 'msg' ]; // $this->upgrade_task[ 'error' ][] = $item[ 'msg' ];
$this->upgrade_task[ 'cloud_build_error' ] = $item[ 'msg' ];
Cache::set($this->cache_key, $this->upgrade_task); Cache::set($this->cache_key, $this->upgrade_task);
$fail_reason = [
'Message' => '失败原因 云编译错误:' . $item[ 'msg' ],
'File' => '',
'Line' => '',
'Trace' => ''
];
( new CoreCloudBuildService() )->clearTask(); ( new CoreCloudBuildService() )->clearTask();
$this->upgradeErrorHandle($fail_reason);
return true; return true;
} }
if (!in_array($item[ 'action' ], $this->upgrade_task[ 'log' ])) { if (!in_array($item[ 'action' ], $this->upgrade_task[ 'log' ])) {
@ -745,7 +777,13 @@ class UpgradeService extends BaseAdminService
} }
// 执行完成,更新升级记录状态,备份记录状态 // 执行完成,更新升级记录状态,备份记录状态
( new UpgradeRecordsService() )->complete($this->upgrade_task[ 'key' ]); ( new UpgradeRecordsService() )->complete($this->upgrade_task[ 'key' ]);
if (!isset($this->upgrade_task['cloud_build_error'])) {
$this->upgrade_task['step'] = 'upgradeComplete';
$this->clearUpgradeTask(2); $this->clearUpgradeTask(2);
} else {
$this->upgrade_task['step'] = 'upgradeComplete';
Cache::set($this->cache_key, $this->upgrade_task);
}
return true; return true;
} }
@ -779,7 +817,7 @@ class UpgradeService extends BaseAdminService
if (!isset($this->upgrade_task['is_need_backup']) || $this->upgrade_task['is_need_backup']) { if (!isset($this->upgrade_task['is_need_backup']) || $this->upgrade_task['is_need_backup']) {
$backup_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'code' . DIRECTORY_SEPARATOR; $backup_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'code' . DIRECTORY_SEPARATOR;
} else { } else {
$backup_dir = $this->upgrade_dir . $this->upgrade_task['upgrade_content']['last_backup'][ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'code' . DIRECTORY_SEPARATOR; $backup_dir = $this->upgrade_dir . $this->upgrade_task['upgrade_content']['last_backup'][ 'backup_key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'code' . DIRECTORY_SEPARATOR;
} }
try { try {
if (is_dir($backup_dir)) { if (is_dir($backup_dir)) {
@ -802,7 +840,7 @@ class UpgradeService extends BaseAdminService
if (!isset($this->upgrade_task['is_need_backup']) || $this->upgrade_task['is_need_backup']) { if (!isset($this->upgrade_task['is_need_backup']) || $this->upgrade_task['is_need_backup']) {
$backup_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR; $backup_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR;
} else { } else {
$backup_dir = $this->upgrade_dir . $this->upgrade_task['upgrade_content']['last_backup'][ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR; $backup_dir = $this->upgrade_dir . $this->upgrade_task['upgrade_content']['last_backup'][ 'backup_key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR;
} }
try { try {
if (is_dir($backup_dir)) { if (is_dir($backup_dir)) {
@ -826,7 +864,11 @@ class UpgradeService extends BaseAdminService
public function restoreComplete() public function restoreComplete()
{ {
( new UpgradeRecordsService() )->failed($this->upgrade_task[ 'key' ], $this->upgrade_task['error']); $error = $this->upgrade_task['error'] ?? [];
if (isset($this->upgrade_task['cloud_build_error'])) $error[] = $this->upgrade_task['cloud_build_error'];
( new UpgradeRecordsService() )->failed($this->upgrade_task[ 'key' ], $error);
$this->upgrade_task['step'] = 'restoreComplete';
Cache::set($this->cache_key, $this->upgrade_task);
$this->clearUpgradeTask(2); $this->clearUpgradeTask(2);
return true; return true;
} }
@ -951,6 +993,15 @@ class UpgradeService extends BaseAdminService
]; ];
$this->upgradeErrorHandle($fail_reason); $this->upgradeErrorHandle($fail_reason);
break; break;
case 'cloud_build_error_rollback':
$fail_reason = [
'Message' => '失败原因:云编译失败,错误原因:' . $this->upgrade_task['cloud_build_error'],
'File' => '',
'Line' => '',
'Trace' => ''
];
$this->upgradeErrorHandle($fail_reason);
break;
} }
} }
} }

View File

@ -12,9 +12,7 @@
namespace app\service\admin\weapp; namespace app\service\admin\weapp;
use app\dict\sys\CloudDict; use app\dict\sys\CloudDict;
use app\service\core\site\CoreSiteService;
use app\service\core\weapp\CoreWeappCloudService; use app\service\core\weapp\CoreWeappCloudService;
use app\service\core\weapp\CoreWeappConfigService;
use app\service\core\weapp\CoreWeappService; use app\service\core\weapp\CoreWeappService;
use core\base\BaseAdminService; use core\base\BaseAdminService;
use app\model\weapp\WeappVersion; use app\model\weapp\WeappVersion;

View File

@ -65,7 +65,7 @@ class WechatTemplateService extends BaseAdminService
//删除原来的消息模板 //删除原来的消息模板
// (new CoreWechatTemplateService())->deletePrivateTemplate($wechat_template_id); // (new CoreWechatTemplateService())->deletePrivateTemplate($wechat_template_id);
$template_loader = new TemplateLoader('wechat'); $template_loader = new TemplateLoader('wechat');
$template_loader->delete([ 'templateId' => $wechat_template_id ]); $del_res = $template_loader->delete([ 'templateId' => $wechat_template_id ]);
//新的消息模板 //新的消息模板
// $res = (new CoreWechatTemplateService())->addTemplate($temp_key, $keyword_name_list); // $res = (new CoreWechatTemplateService())->addTemplate($temp_key, $keyword_name_list);
$res = $template_loader->addTemplate([ 'shortId' => $temp_key, 'keyword_name_list' => $keyword_name_list ]); $res = $template_loader->addTemplate([ 'shortId' => $temp_key, 'keyword_name_list' => $keyword_name_list ]);
@ -74,6 +74,9 @@ class WechatTemplateService extends BaseAdminService
//修改 //修改
$notice_service->modify($key, 'wechat_template_id', $res[ 'template_id' ]); $notice_service->modify($key, 'wechat_template_id', $res[ 'template_id' ]);
} else { } else {
if (isset($res[ 'errcode' ]) && $res[ 'errcode' ] == 45026) {
throw new NoticeException('模板数量超出限制');
}
throw new NoticeException($res[ 'errmsg' ]); throw new NoticeException($res[ 'errmsg' ]);
} }
return true; return true;

View File

@ -167,9 +167,9 @@ class DiyService extends BaseApiService
]; ];
$data = []; $data = [];
foreach ($addon_list as $key => $value) { foreach ($addon_list as $key => $value) {
if (isset($value[ 'support_app' ]) && empty($value[ 'support_app' ]) && $value[ 'type' ] == 'addon') { // if (isset($value[ 'support_app' ]) && empty($value[ 'support_app' ]) && $value[ 'type' ] == 'addon') {
continue; // continue;
} // }
$addon_theme = array_values(array_filter(event('ThemeColor', [ 'key' => $value[ 'key' ] ])))[ 0 ] ?? []; $addon_theme = array_values(array_filter(event('ThemeColor', [ 'key' => $value[ 'key' ] ])))[ 0 ] ?? [];
if (!empty($addon_theme) && !empty($addon_theme[ 'theme_color' ])) { if (!empty($addon_theme) && !empty($addon_theme[ 'theme_color' ])) {
$data[ $value[ 'key' ] ][ 'title' ] = $theme_data[ $value[ 'key' ] ][ 'title' ] ?? $addon_theme[ 'theme_color' ][ 0 ][ 'title' ]; $data[ $value[ 'key' ] ][ 'title' ] = $theme_data[ $value[ 'key' ] ][ 'title' ] ?? $addon_theme[ 'theme_color' ][ 0 ][ 'title' ];

View File

@ -124,10 +124,10 @@ class AuthService extends BaseApiService
$mobile = $phone_info[ 'purePhoneNumber' ]; $mobile = $phone_info[ 'purePhoneNumber' ];
if (empty($mobile)) throw new ApiException('WECHAT_EMPOWER_NOT_EXIST'); if (empty($mobile)) throw new ApiException('WECHAT_EMPOWER_NOT_EXIST');
$member_service = new MemberService(); // $member_service = new MemberService();
$mobile_member = $member_service->findMemberInfo([ 'mobile' => $mobile ]); // $mobile_member = $member_service->findMemberInfo([ 'mobile' => $mobile ]);
if (!$mobile_member->isEmpty()) throw new AuthException('MOBILE_IS_EXIST'); // if (!$mobile_member->isEmpty()) throw new AuthException('MOBILE_IS_EXIST');
return [ return [
'mobile' => $mobile 'mobile' => $mobile

View File

@ -46,7 +46,8 @@ class ConfigService extends BaseApiService
* 获取前端域名 * 获取前端域名
* @return array|string[] * @return array|string[]
*/ */
public function getSceneDomain(){ public function getSceneDomain()
{
return ( new CoreSysConfigService() )->getSceneDomain(); return ( new CoreSysConfigService() )->getSceneDomain();
} }
@ -80,17 +81,22 @@ class ConfigService extends BaseApiService
'front_end_name' => '', 'front_end_name' => '',
'front_end_logo' => '', 'front_end_logo' => '',
'icon' => '', 'icon' => '',
'meta_title' => '',
'meta_desc' => '',
'meta_keyword' => '',
]; ];
} }
$info[ 'site_addons' ] = ( new CoreAddonService() )->getInstallAddonList(); $info[ 'site_addons' ] = ( new CoreAddonService() )->getInstallAddonList();
return $info; return $info;
} }
public function getMap(){ public function getMap()
{
return ( new CoreSysConfigService() )->getMap(); return ( new CoreSysConfigService() )->getMap();
} }
public function getAppConfig() { public function getAppConfig()
{
$config = ( new CoreAppService() )->getConfig(); $config = ( new CoreAppService() )->getConfig();
if (!empty($config) && isset($config[ 'wechat_app_secret' ])) unset($config[ 'wechat_app_secret' ]); if (!empty($config) && isset($config[ 'wechat_app_secret' ])) unset($config[ 'wechat_app_secret' ]);
$weapp_config = ( new CoreWeappConfigService() )->getWeappConfig(); $weapp_config = ( new CoreWeappConfigService() )->getWeappConfig();

View File

@ -175,6 +175,7 @@ class WeappAuthService extends BaseApiService
// } // }
} }
} }
if (empty($member_info->wx_unionid) && !empty($unionid)) $member_info->wx_unionid = $unionid;
return $login_service->login($member_info, MemberLoginTypeDict::WEAPP); return $login_service->login($member_info, MemberLoginTypeDict::WEAPP);
} }
} }

View File

@ -136,11 +136,14 @@ class WechatAuthService extends BaseApiService
return [ 'avatar' => $avatar, 'nickname' => $nickname, 'openid' => $openid, 'unionid' => $unionid ]; return [ 'avatar' => $avatar, 'nickname' => $nickname, 'openid' => $openid, 'unionid' => $unionid ];
} else if ($is_force_access_user_info) { } else if ($is_force_access_user_info) {
// 开启强制获取会员信息时,必须获取到昵称和头像才能进行注册 // 开启强制获取会员信息时,必须获取到昵称和头像才能进行注册
if (!empty($nickname) && !empty($avatar)) { // if (!empty($nickname) && !empty($avatar)) {
return $this->register($openid, '', $nickname, $avatar, $unionid); // 获取到昵称和头像,然后进行注册 if (empty($nickname)){
} else { $nickname = unique_random();
return [ 'avatar' => $avatar, 'nickname' => $nickname, 'openid' => $openid, 'unionid' => $unionid ];
} }
return $this->register($openid, '', $nickname, $avatar, $unionid); // 获取到昵称和头像,然后进行注册
// } else {
// return [ 'avatar' => $avatar, 'nickname' => $nickname, 'openid' => $openid, 'unionid' => $unionid ];
// }
} else if ($is_bind_mobile) { } else if ($is_bind_mobile) {
// 开启强制绑定手机号,必须获取手机号才能进行注册,由于公众号无法主动获取,所以不能注册 // 开启强制绑定手机号,必须获取手机号才能进行注册,由于公众号无法主动获取,所以不能注册
return [ 'openid' => $openid, 'unionid' => $unionid ]; return [ 'openid' => $openid, 'unionid' => $unionid ];

View File

@ -173,7 +173,7 @@ class CoreAddonInstallService extends CoreAddonBaseService
} }
if (!isset($install_data['support_version']) || empty($install_data['support_version'])) { if (!isset($install_data['support_version']) || empty($install_data['support_version'])) {
$data['addon_check'][] = [ $data['addon_check'][] = [
'msg' => $install_data['title'] . '插件的info.json文件中未检测到匹配框架当前版本['. $framework_version_arr[0].'.'.$framework_version_arr[1] .'.*]的信息无法安装,<a style="text-decoration: underline;" href="https://www.kancloud.cn/niucloud/niucloud-admin-develop/3244512" target="blank">点击查看相关手册</a>', 'msg' => $install_data['title'] . '插件的info.json文件中未检测到匹配框架当前版本['. $framework_version_arr[0].'.'.$framework_version_arr[1] .'.*]的信息无法安装,<a style="text-decoration: underline;" href="https://doc.press.niucloud.com/php/saas-framework/use/installFAQ/pluginNotCompatible.html" target="blank">点击查看相关手册</a>',
'status' => false 'status' => false
]; ];
continue; continue;
@ -182,7 +182,7 @@ class CoreAddonInstallService extends CoreAddonBaseService
if ($framework_version_arr[0].$framework_version_arr[1] != $support_framework_arr[0].$support_framework_arr[1]) { if ($framework_version_arr[0].$framework_version_arr[1] != $support_framework_arr[0].$support_framework_arr[1]) {
if ((float) "$support_framework_arr[0].$support_framework_arr[1]" < (float) "$framework_version_arr[0].$framework_version_arr[1]") { if ((float) "$support_framework_arr[0].$support_framework_arr[1]" < (float) "$framework_version_arr[0].$framework_version_arr[1]") {
$data['addon_check'][] = [ $data['addon_check'][] = [
'msg' => $install_data['title'] . '插件的info.json文件中检测到支持的框架版本['. $install_data['support_version'] .']低于当前框架版本['. $framework_version_arr[0].'.'.$framework_version_arr[1] .'.*]无法安装,<a style="text-decoration: underline;" href="https://www.kancloud.cn/niucloud/niucloud-admin-develop/3244512" target="blank">点击查看相关手册</a>', 'msg' => $install_data['title'] . '插件的info.json文件中检测到支持的框架版本['. $install_data['support_version'] .']低于当前框架版本['. $framework_version_arr[0].'.'.$framework_version_arr[1] .'.*]无法安装,<a style="text-decoration: underline;" href="https://doc.press.niucloud.com/php/saas-framework/use/installFAQ/pluginNotCompatible.html" target="blank">点击查看相关手册</a>',
'status' => false 'status' => false
]; ];
} }

View File

@ -46,17 +46,20 @@ class CoreAddonService extends CoreAddonBaseService
public function getLocalAddonList() public function getLocalAddonList()
{ {
$list = []; $list = [];
$online_app_list = []; $online_app_list = $online_apps = [];
$install_addon_list = $this->model->append(['status_name'])->column('title, icon, key, desc, status, author, version, install_time, update_time, cover', 'key'); $install_addon_list = $this->model->append(['status_name'])->column('title, icon, key, desc, status, author, version, install_time, update_time, cover', 'key');
try { try {
$niucloud_module_list = (new CoreModuleService())->getModuleList()['data'] ?? []; $niucloud_module_list = (new CoreModuleService())->getModuleList()['data'] ?? [];
foreach ($niucloud_module_list as $v) { foreach ($niucloud_module_list as $v) {
$data = array( $data = array(
'app_id' => $v['app']['app_id'],
'title' => $v['app']['app_name'], 'title' => $v['app']['app_name'],
'desc' => $v['app']['app_desc'], 'desc' => $v['app']['app_desc'],
'key' => $v['app']['app_key'] ?? '', 'key' => $v['app']['app_key'] ?? '',
'version' => $v['version'] ?? '', 'version' => $v['version'] ?? '',
'author' => $v['app']['app_name'], 'author' => $v['site_name'],
'author_phone' => $v['site_phone'],
'expire_time' => $v['expire_time'],
'type' => $v['app']['app_type'], 'type' => $v['app']['app_type'],
'support_app' => $v['app']['support_channel'] ?? [], 'support_app' => $v['app']['support_channel'] ?? [],
'is_download' => false, 'is_download' => false,
@ -65,9 +68,15 @@ class CoreAddonService extends CoreAddonBaseService
'cover' => $v['app']['window_logo'][0], 'cover' => $v['app']['window_logo'][0],
); );
$data['install_info'] = $install_addon_list[$v['app']['app_key']] ?? []; $data['install_info'] = $install_addon_list[$v['app']['app_key']] ?? [];
//给安装的插件中为授权插件或应用的数据赋值过期时间
if (isset($install_addon_list[$v['app']['app_key']])) {
$install_addon_list[$v['app']['app_key']]['expire_time'] = $v['expire_time'];
}
$list[$v['app']['app_key']] = $data; $list[$v['app']['app_key']] = $data;
} }
$online_app_list = array_column($list, 'key'); $online_app_list = array_column($list, 'key');
$online_apps = array_column($list, 'app_id', 'key');
} catch (Throwable $e) { } catch (Throwable $e) {
$error = $e->getMessage(); $error = $e->getMessage();
} }
@ -81,8 +90,11 @@ class CoreAddonService extends CoreAddonBaseService
$key = $data['key']; $key = $data['key'];
$data['install_info'] = $install_addon_list[$key] ?? []; $data['install_info'] = $install_addon_list[$key] ?? [];
$data['is_download'] = true; $data['is_download'] = true;
$data['is_local'] = in_array($data['key'], $online_app_list) ? false : true; $data['is_local'] = !in_array($data['key'], $online_app_list);
$data['version'] = isset($list[$data['key']]) ? $list[$data['key']]['version'] : $data['version']; $data['version'] = isset($list[$data['key']]) ? $list[$data['key']]['version'] : $data['version'];
$data['app_id'] = in_array($data['key'], $online_app_list) ? $online_apps[$data['key']] : 0;
$data['author_phone'] = '';
$data['expire_time'] = !isset($install_addon_list[$data['key']]) ? '长期有效' : ($install_addon_list[$data['key']]['expire_time'] ?? '');
$list[$key] = $data; $list[$key] = $data;
} }
} }

View File

@ -126,12 +126,12 @@ trait WapTrait
$content .= " </view>\n"; $content .= " </view>\n";
$content .= " </view>\n"; $content .= " </view>\n";
$content .= " </template>\n"; $content .= " </template>\n";
$content .= " <template v-if=\"diyStore.mode == '' && data.global && diyGroup.showCopyright.value && data.global.copyright && data.global.copyright.isShow\">\n"; $content .= " <template v-if=\"data.global && diyGroup.showCopyright.value && data.global.copyright && data.global.copyright.isShow\">\n";
$content .= " <copy-right :textColor=\"data.global.copyright.textColor\" />\n"; $content .= " <copy-right :textColor=\"data.global.copyright.textColor\" />\n";
$content .= " </template>\n\n"; $content .= " </template>\n\n";
$content .= " <template v-if=\"diyStore.mode == '' && data.global && data.global.bottomTabBar && data.global.bottomTabBar.isShow\">\n"; $content .= " <template v-if=\"diyStore.mode == '' && data.global && data.global.bottomTabBar && data.global.bottomTabBar.isShow\">\n";
$content .= " <view class=\"pt-[20rpx]\"></view>\n"; $content .= " <view class=\"pt-[20rpx]\"></view>\n";
$content .= " <tabbar :addon=\"data.global.bottomTabBar.designNav.key\" />\n"; $content .= " <tabbar :addon=\"data.global.bottomTabBar.designNav?.key\" />\n";
$content .= " </template>\n"; $content .= " </template>\n";
$content .= " </view>\n"; $content .= " </view>\n";
$content .= "</template>\n"; $content .= "</template>\n";
@ -191,13 +191,21 @@ trait WapTrait
*/ */
public function installPageCode($compile_path, $addon = '') public function installPageCode($compile_path, $addon = '')
{ {
if (is_array($addon)){
foreach ($addon as $item_addon){
if (!file_exists($this->geAddonPackagePath($item_addon) . 'uni-app-pages.php')) {
continue;
}
$uniapp_pages = require $this->geAddonPackagePath($item_addon) . 'uni-app-pages.php';
}
}else{
if (!file_exists($this->geAddonPackagePath($this->addon) . 'uni-app-pages.php')) return; if (!file_exists($this->geAddonPackagePath($this->addon) . 'uni-app-pages.php')) return;
$uniapp_pages = require $this->geAddonPackagePath($this->addon) . 'uni-app-pages.php'; $uniapp_pages = require $this->geAddonPackagePath($this->addon) . 'uni-app-pages.php';
if (empty($uniapp_pages[ 'pages' ])) { if (empty($uniapp_pages[ 'pages' ])) {
return; return;
} }
}
$pages = []; $pages = [];

View File

@ -55,27 +55,6 @@ class CoreAppService extends BaseCoreService
public function setConfig($data) public function setConfig($data)
{ {
$info = (new CoreConfigService())->setConfig(ConfigKeyDict::APP, $data); $info = (new CoreConfigService())->setConfig(ConfigKeyDict::APP, $data);
$this->appConfigChange($data);
return $info; return $info;
} }
/**
* 地图key改变后变更 manifest.json
* @param string $map_key
* @return void
*/
public function appConfigChange($data) {
// $compile_path = project_path(). 'uni-app' . DIRECTORY_SEPARATOR;
// $this->mergeManifestJson($compile_path, [
// "h5" => [
// "sdkConfigs" => [
// "maps" => [
// "qqmap" => [
// "key" => $map_key
// ]
// ]
// ]
// ]
// ]);
}
} }

View File

@ -64,7 +64,7 @@ class CoreDiyService extends BaseCoreService
$addon_theme = array_values(array_filter(event('ThemeColor', [ 'key' => $value[ 'key' ] ])))[ 0 ] ?? []; $addon_theme = array_values(array_filter(event('ThemeColor', [ 'key' => $value[ 'key' ] ])))[ 0 ] ?? [];
if (empty($addon_theme)) continue; if (empty($addon_theme)) continue;
foreach ($addon_theme[ 'theme_color' ] as $k => $v) { foreach ($addon_theme[ 'theme_color' ] ?? [] as $k => $v) {
$data[] = [ $data[] = [
'type' => 'app', 'type' => 'app',
'addon' => $value[ 'key' ], 'addon' => $value[ 'key' ],

View File

@ -0,0 +1,99 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\core\map;
use app\service\core\sys\CoreConfigService;
use core\base\BaseCoreService;
use core\exception\CommonException;
/**
* 地图服务层
* Class CoreMapService
* @package app\service\core\map
*/
class CoreMapService extends BaseCoreService
{
//系统配置文件
public $core_config_service;
public function __construct()
{
parent::__construct();
$this->core_config_service = new CoreConfigService();
}
/**
* 获取规划路线
* @param $params
* @return array
*/
public function getPolyline($params)
{
$url = 'https://apis.map.qq.com/ws/direction/v1/driving/';
$map = $this->getMapConfig();
$get_data = [
'key' => $map[ 'key' ],
'from' => $params[ 'from' ],
'to' => $params[ 'to' ], // 是否返回周边POI列表1.返回0不返回(默认)
];
$url = $url . '?' . http_build_query($get_data);
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_TIMEOUT, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
$res = curl_exec($curl);
$res = json_decode($res, true);
if ($res) {
curl_close($curl);
if ($res[ 'status' ] == 0) {
return $res['result'];
} else {
throw new CommonException('请检查地图配置:'.$res[ 'message' ]);
}
} else {
$error = curl_errno($curl);
curl_close($curl);
throw new CommonException($error);
}
}
/**
* 获取地图配置
* @return array|mixed
*/
public function getMapConfig()
{
$info = ( new CoreConfigService() )->getConfig('MAPKEY');
if (empty($info)) {
$info = [];
$info[ 'value' ] = [
'key' => 'IZQBZ-3UHEU-WTCVD-2464U-I5N4V-ZFFU3',
'is_open' => 1, // 是否开启定位
'valid_time' => 5 // 定位有效期/分钟过期后将重新获取定位信息0为不过期
];
}
$info[ 'value' ][ 'is_open' ] = $info[ 'value' ][ 'is_open' ] ?? 1;
$info[ 'value' ][ 'valid_time' ] = $info[ 'value' ][ 'valid_time' ] ?? 5;
return $info[ 'value' ];
}
}

View File

@ -37,10 +37,14 @@ class CoreMemberAccountService extends BaseCoreService
$member_info = $member_model->where([ $member_info = $member_model->where([
[ 'member_id', '=', $member_id ], [ 'member_id', '=', $member_id ],
])->field($account_type . ',' . $account_type . "_get" . ', username, mobile, nickname')->lock(true)->find(); ])->field($account_type . ',' . $account_type . "_get" . ', username, mobile, nickname')->lock(true)->find();
if (empty($member_info)) throw new CommonException('MEMBER_NOT_EXIST'); if (empty($member_info)) {
Db::rollback();
throw new CommonException('MEMBER_NOT_EXIST');
}
$account_new_data = round((float) $member_info[ $account_type ] + (float) $account_data, 2); $account_new_data = round((float) $member_info[ $account_type ] + (float) $account_data, 2);
if ($account_new_data < 0) { if ($account_new_data < 0) {
Db::rollback();
throw new CommonException('ACCOUNT_INSUFFICIENT'); throw new CommonException('ACCOUNT_INSUFFICIENT');
} }

View File

@ -15,6 +15,7 @@ use core\util\niucloud\BaseNiucloudClient;
use core\util\niucloud\http\Response; use core\util\niucloud\http\Response;
use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use think\facade\Cache;
/** /**
* 官网授权管理服务层 * 官网授权管理服务层
@ -28,10 +29,14 @@ class CoreAuthService extends BaseNiucloudClient
*/ */
public function getAuthInfo() public function getAuthInfo()
{ {
$cache = Cache::get("authinfo");
if (!empty($cache)) return $cache;
$auth_info = $this->httpGet('authinfo', ['code' => $this->code, 'secret' => $this->secret, 'product_key' => self::PRODUCT ]); $auth_info = $this->httpGet('authinfo', ['code' => $this->code, 'secret' => $this->secret, 'product_key' => self::PRODUCT ]);
if(!empty($auth_info['data'])){ if(!empty($auth_info['data'])){
$auth_info['data']['address_type'] = true; $auth_info['data']['address_type'] = true;
if($auth_info['data']['site_address'] != $_SERVER['HTTP_HOST']) $auth_info['data']['address_type'] = false; if($auth_info['data']['site_address'] != $_SERVER['HTTP_HOST']) $auth_info['data']['address_type'] = false;
Cache::set("authinfo", $auth_info, 7200);
} }
return $auth_info; return $auth_info;
} }

View File

@ -136,18 +136,18 @@ class CoreCloudBuildService extends BaseCoreService
// 拷贝手机端文件 // 拷贝手机端文件
$wap_is_compile = ( new Addon() )->where([ [ 'compile', 'like', '%wap%' ] ])->field('id')->findOrEmpty(); $wap_is_compile = ( new Addon() )->where([ [ 'compile', 'like', '%wap%' ] ])->field('id')->findOrEmpty();
if ($wap_is_compile->isEmpty()) { if ($wap_is_compile->isEmpty()) {
dir_copy($this->root_path . 'uni-app', $package_dir . 'uni-app', exclude_dirs: [ 'node_modules', 'unpackage', 'dist' ]); dir_copy($this->root_path . 'uni-app', $package_dir . 'uni-app', exclude_dirs: [ 'node_modules', 'unpackage', 'dist', '.git' ]);
$this->handleUniapp($package_dir . 'uni-app'); $this->handleUniapp($package_dir . 'uni-app');
} }
// 拷贝admin端文件 // 拷贝admin端文件
$admin_is_compile = ( new Addon() )->where([ [ 'compile', 'like', '%admin%' ] ])->field('id')->findOrEmpty(); $admin_is_compile = ( new Addon() )->where([ [ 'compile', 'like', '%admin%' ] ])->field('id')->findOrEmpty();
if ($admin_is_compile->isEmpty()) { if ($admin_is_compile->isEmpty()) {
dir_copy($this->root_path . 'admin', $package_dir . 'admin', exclude_dirs: [ 'node_modules', 'dist', '.vscode', '.idea' ]); dir_copy($this->root_path . 'admin', $package_dir . 'admin', exclude_dirs: [ 'node_modules', 'dist', '.vscode', '.idea', '.git' ]);
} }
// 拷贝web端文件 // 拷贝web端文件
$web_is_compile = ( new Addon() )->where([ [ 'compile', 'like', '%web%' ] ])->field('id')->findOrEmpty(); $web_is_compile = ( new Addon() )->where([ [ 'compile', 'like', '%web%' ] ])->field('id')->findOrEmpty();
if ($web_is_compile->isEmpty()) { if ($web_is_compile->isEmpty()) {
dir_copy($this->root_path . 'web', $package_dir . 'web', exclude_dirs: [ 'node_modules', '.output', '.nuxt' ]); dir_copy($this->root_path . 'web', $package_dir . 'web', exclude_dirs: [ 'node_modules', '.output', '.nuxt', '.git' ]);
} }
$this->handleCustomPort($package_dir); $this->handleCustomPort($package_dir);

View File

@ -15,6 +15,8 @@ namespace app\service\core\notice;
use app\job\notice\Notice; use app\job\notice\Notice;
use app\model\sys\SysNotice; use app\model\sys\SysNotice;
use core\base\BaseCoreService; use core\base\BaseCoreService;
use core\exception\NoticeException;
use think\facade\Log;
/** /**
@ -36,16 +38,19 @@ class NoticeService extends BaseCoreService
* @return false|mixed * @return false|mixed
* @throws \Exception * @throws \Exception
*/ */
public static function send($key, $data){ public static function send($key, $data)
{
try { try {
$template = (new CoreNoticeService())->getInfo($key); $template = (new CoreNoticeService())->getInfo($key);
Log::write("消息发送");
Log::write($template);
if (empty($template)) return false; if (empty($template)) return false;
return Notice::dispatch(['key' => $key, 'data' => $data, 'template' => $template], is_async: $template['async']); return Notice::dispatch(['key' => $key, 'data' => $data, 'template' => $template], is_async: $template['async']);
} catch (\Exception $e) { } catch (\Exception $e) {
throw new \Exception($e->getMessage()); throw new NoticeException($e->getMessage());
} }
} }
} }

View File

@ -150,6 +150,7 @@ class CorePayService extends BaseCoreService
* @param string $trade_type * @param string $trade_type
* @param string $trade_id * @param string $trade_id
* @param string $channel * @param string $channel
* @param string $scene
* @return array * @return array
* @throws DataNotFoundException * @throws DataNotFoundException
* @throws DbException * @throws DbException
@ -203,6 +204,8 @@ class CorePayService extends BaseCoreService
* @param string $return_url * @param string $return_url
* @param string $quit_url * @param string $quit_url
* @param string $buyer_id * @param string $buyer_id
* @param string $voucher
* @param int $member_id
* @return mixed * @return mixed
* @throws DataNotFoundException * @throws DataNotFoundException
* @throws DbException * @throws DbException
@ -263,7 +266,7 @@ class CorePayService extends BaseCoreService
] ]
); );
if (env('queue.state', true)) { if (env('queue.state', true)) {
PayReturnTo::dispatch([ 'out_trade_no' => $out_trade_no ], secs: 60); PayReturnTo::dispatch([ 'out_trade_no' => $out_trade_no ], secs: 300);
} }
} }
return $pay_result; return $pay_result;
@ -461,13 +464,10 @@ class CorePayService extends BaseCoreService
switch ($action) { switch ($action) {
case 'pay'://支付结果通知 case 'pay'://支付结果通知
return $this->payNotify($out_trade_no, $type, $params); return $this->payNotify($out_trade_no, $type, $params);
break;
case 'refund': case 'refund':
return ( new CoreRefundService() )->refundNotify($out_trade_no, $type, $params); return ( new CoreRefundService() )->refundNotify($out_trade_no, $type, $params);
break;
case 'transfer': case 'transfer':
return ( new CoreTransferService() )->transferNotify($out_trade_no, $params); return ( new CoreTransferService() )->transferNotify($out_trade_no, $params);
break;
} }
//找不到对应的业务 //找不到对应的业务
return true; return true;
@ -563,7 +563,6 @@ class CorePayService extends BaseCoreService
Db::rollback(); Db::rollback();
throw new PayException($e->getMessage() . $e->getFile() . $e->getLine()); throw new PayException($e->getMessage() . $e->getFile() . $e->getLine());
} }
return true;
} }
/** /**

View File

@ -13,17 +13,10 @@ namespace app\service\core\pay;
use app\dict\pay\TransferDict; use app\dict\pay\TransferDict;
use app\dict\sys\ConfigKeyDict; use app\dict\sys\ConfigKeyDict;
use app\model\pay\Pay;
use app\model\pay\Transfer;
use app\model\pay\TransferScene; use app\model\pay\TransferScene;
use app\service\core\sys\CoreConfigService; use app\service\core\sys\CoreConfigService;
use core\base\BaseCoreService; use core\base\BaseCoreService;
use core\exception\PayException;
use Exception;
use think\facade\Db;
use think\facade\Log;
use think\Model; use think\Model;
use Throwable;
/** /**
* 转账场景服务层 * 转账场景服务层
@ -41,7 +34,6 @@ class CoreTransferSceneService extends BaseCoreService
/** /**
* 获取底部导航配置 * 获取底部导航配置
* @param string $key
* @return array * @return array
*/ */
public function getWechatTransferSceneConfig() public function getWechatTransferSceneConfig()
@ -53,7 +45,6 @@ class CoreTransferSceneService extends BaseCoreService
/** /**
* 设置微信转账场景导航 * 设置微信转账场景导航
* @param array $data * @param array $data
* @param string $key
* @return SysConfig|bool|Model * @return SysConfig|bool|Model
*/ */
public function setWechatTransferSceneConfig(array $data) public function setWechatTransferSceneConfig(array $data)
@ -96,6 +87,7 @@ class CoreTransferSceneService extends BaseCoreService
/** /**
* 通过业务设置转账场景的配置信息 * 通过业务设置转账场景的配置信息
* @param $type
* @param $data * @param $data
* @return void * @return void
*/ */

View File

@ -14,8 +14,6 @@ namespace app\service\core\pay;
use app\dict\pay\TransferDict; use app\dict\pay\TransferDict;
use app\model\pay\Pay; use app\model\pay\Pay;
use app\model\pay\Transfer; use app\model\pay\Transfer;
use app\model\pay\TransferScene;
use app\service\core\sys\CoreConfigService;
use core\base\BaseCoreService; use core\base\BaseCoreService;
use core\exception\PayException; use core\exception\PayException;
use Exception; use Exception;

View File

@ -11,6 +11,7 @@
namespace app\service\core\sys; namespace app\service\core\sys;
use app\dict\sys\StorageDict;
use app\model\sys\SysAttachment; use app\model\sys\SysAttachment;
use app\service\core\upload\CoreFileService; use app\service\core\upload\CoreFileService;
use core\base\BaseCoreService; use core\base\BaseCoreService;
@ -117,13 +118,29 @@ class CoreAttachmentService extends BaseCoreService
if(empty($list)) if(empty($list))
throw new UploadFileException('PLEACE_SELECT_IMAGE'); throw new UploadFileException('PLEACE_SELECT_IMAGE');
$ids = array_column($list, 'att_id'); $del_success_ids = [];
foreach($list as $v){ foreach($list as $v){
try {
$file_driver = (new CoreFileService())->driver($v['storage_type']); $file_driver = (new CoreFileService())->driver($v['storage_type']);
//读取上传附件的信息用于后续得校验和数据写入,删除失败直接通过 //读取上传附件的信息用于后续得校验和数据写入,删除失败直接通过
$file_driver->delete($v['path']); $file_driver->delete($v['path']);
} catch (\Exception $e) {
// 如果附件在云存储中删除失败后 尝试该资源是否是在平台云存储中
if ($v['storage_type'] != StorageDict::LOCAL) {
try {
$file_driver = (new CoreFileService())->driver(0, $v['storage_type']);
$file_driver->delete($v['path']);
} catch (\Exception $e) {
if (!empty($del_success_ids)) {
$this->model->destroy($del_success_ids);
} }
$this->model->destroy($ids); throw new UploadFileException($e->getMessage());
}
}
}
$del_success_ids[] = $v['att_id'];
}
$this->model->destroy($del_success_ids);
return true; return true;
} }
} }

View File

@ -14,8 +14,10 @@ namespace app\service\core\sys;
use app\dict\sys\ExportDict; use app\dict\sys\ExportDict;
use app\model\sys\SysExport; use app\model\sys\SysExport;
use core\base\BaseCoreService; use core\base\BaseCoreService;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment; use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use think\facade\Log; use think\facade\Log;
@ -111,7 +113,7 @@ class CoreExportService extends BaseCoreService
$data_list = []; $data_list = [];
foreach ($data_array as $v) foreach ($data_array as $v)
{ {
$data_list = empty($data_list) ? $v : array_merge($data_list, $v); $data_list = array_merge($data_list, $v );
} }
return $data_list; return $data_list;
} }
@ -195,9 +197,17 @@ class CoreExportService extends BaseCoreService
foreach ($data as $item) { foreach ($data as $item) {
foreach ($data_column as $k => $v) foreach ($data_column as $k => $v)
{ {
$sheet->setCellValue($v['excel_column_name'] . $row, $item[$k]); $cell_value = $item[$k] ?? '';
// 将样式应用到单元格 $cell_coordinate = $v['excel_column_name'] . $row;
$sheet->getStyle($v['excel_column_name'] . $row)->applyFromArray($style_array); // 步骤1获取单元格对象
$cell = $sheet->getCell($cell_coordinate);
// 步骤2强制单元格格式为纯文本核心
$cell->getStyle()->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_TEXT);
// 步骤3显式赋值为字符串类型避免解析为公式核心
$cell->setValueExplicit($cell_value, DataType::TYPE_STRING);
// 将样式应用到单元格(原有逻辑保留)
$sheet->getStyle($cell_coordinate)->applyFromArray($style_array);
// todo 合并行 // todo 合并行
if (isset($v['merge_type']) && $v['merge_type'] == 'column') { if (isset($v['merge_type']) && $v['merge_type'] == 'column') {

View File

@ -65,7 +65,7 @@ class CoreWeappCloudService extends CoreCloudBaseService
// 如果不存在编译版小程序 // 如果不存在编译版小程序
if ($compile_addon->isEmpty()) { if ($compile_addon->isEmpty()) {
dir_copy($this->root_path . 'uni-app', $uni_dir, exclude_dirs: [ 'node_modules', 'unpackage', 'dist' ]); dir_copy($this->root_path . 'uni-app', $uni_dir, exclude_dirs: [ 'node_modules', 'unpackage', 'dist', '.git' ]);
// $this->handleTabbar($uni_dir . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR); // $this->handleTabbar($uni_dir . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR);
// 替换env文件 // 替换env文件
$this->weappEnvReplace($uni_dir . DIRECTORY_SEPARATOR . '.env.production'); $this->weappEnvReplace($uni_dir . DIRECTORY_SEPARATOR . '.env.production');
@ -90,7 +90,7 @@ class CoreWeappCloudService extends CoreCloudBaseService
'do' => 1, 'do' => 1,
'timestamp' => time() 'timestamp' => time()
]; ];
$response = ( new CloudService() )->httpPost('cloud/weapp?' . http_build_query($query), [ $response = ( new CloudService(true) )->httpPost('cloud/weapp?' . http_build_query($query), [
'multipart' => [ 'multipart' => [
[ [
'name' => 'file', 'name' => 'file',
@ -189,7 +189,7 @@ class CoreWeappCloudService extends CoreCloudBaseService
$query = [ $query = [
'authorize_code' => $this->auth_code, 'authorize_code' => $this->auth_code,
]; ];
$preview_url = ( new CloudService() )->getUrl('cloud/get_weapp_preview?' . http_build_query($query)); $preview_url = ( new CloudService(true) )->getUrl('cloud/get_weapp_preview?' . http_build_query($query));
try { try {
$path = runtime_path() . uniqid() . '.jpg'; $path = runtime_path() . uniqid() . '.jpg';
@ -211,7 +211,7 @@ class CoreWeappCloudService extends CoreCloudBaseService
'authorize_code' => $this->auth_code, 'authorize_code' => $this->auth_code,
'timestamp' => $timestamp 'timestamp' => $timestamp
]; ];
$build_log = ( new CloudService() )->httpGet('cloud/get_weapp_logs?' . http_build_query($query)); $build_log = ( new CloudService(true) )->httpGet('cloud/get_weapp_logs?' . http_build_query($query));
if (isset($build_log[ 'data' ]) && isset($build_log[ 'data' ][ 0 ]) && is_array($build_log[ 'data' ][ 0 ])) { if (isset($build_log[ 'data' ]) && isset($build_log[ 'data' ][ 0 ]) && is_array($build_log[ 'data' ][ 0 ])) {
$last = end($build_log[ 'data' ][ 0 ]); $last = end($build_log[ 'data' ][ 0 ]);

View File

@ -138,12 +138,13 @@ class CoreWechatServeService extends BaseCoreService
} }
$scene = [ $sceneKey => $key ]; $scene = [ $sceneKey => $key ];
$param = [ $param = [
'expire_seconds' => $expire_seconds, // 二维码的有效时间 'expire_seconds' => $expire_seconds,
'action_name' => $type, 'action_name' => $type,
'action_info' => [ 'action_info' => [
'scene' => $scene 'scene' => $scene
], ],
]; ];
return $api->postJson('cgi-bin/qrcode/create', $param); $response = $api->postJson('cgi-bin/qrcode/create', $param);
return json_decode($response->getContent(), true);
} }
} }

View File

@ -0,0 +1,85 @@
<?php
namespace app\upgrade\v158;
use app\model\diy\Diy;
use app\model\diy_form\DiyForm;
class Upgrade
{
public function handle()
{
$this->handleDiyData();
$this->handleDiyFormData();
}
/**
* 处理自定义数据
* @return void
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function handleDiyData()
{
$diy_model = new Diy();
$where = [
['value', '<>', ''],
];
$field = 'id,value';
$list = $diy_model->where($where)->field($field)->select()->toArray();
$components_names = ['GoodsList','ManyGoodsList','ShopExchangeGoods','ShopGoodsRecommend','SingleRecommend','ShopNewcomer','ShopGoodsRanking','ShopGoodsHot'];
if (!empty($list)) {
foreach ($list as $k => $v) {
$diy_data = json_decode($v['value'], true);
$diy_data['global']['copyright']['textColor'] = '#ccc';
foreach ($diy_data['value'] as $k1=>$v1) {
if (in_array($v1['componentName'],$components_names)){
$diy_data['value'][$k1]['mode'] = 'aspectFill';
}
}
$diy_data = json_encode($diy_data);
$diy_model->where([['id', '=', $v['id']]])->update(['value' => $diy_data]);
}
}
}
/**
* 处理万能表单数据
* @return void
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function handleDiyFormData()
{
$diy_form_model = new DiyForm();
$where = [
['value', '<>', '']
];
$field = 'form_id,value';
$list = $diy_form_model->where($where)->field($field)->select()->toArray();
$components_names = ['GoodsList','ManyGoodsList','ShopExchangeGoods','ShopGoodsRecommend','SingleRecommend','ShopNewcomer','ShopGoodsRanking','ShopGoodsHot'];
if (!empty($list)) {
foreach ($list as $k => $v) {
$diy_data = $v['value'];
if (!isset($diy_data['global']['copyright']['textColor'])) {
$diy_data['global']['copyright']['textColor'] = '#ccc';
}
foreach ($diy_data['value'] as $k1=>$v1) {
if (in_array($v1['componentName'],$components_names)){
$diy_data['value'][$k1]['mode'] = 'aspectFill';
}
}
$diy_form_model->where([['form_id', '=', $v['form_id']]])->update(['value' => $diy_data]);
}
}
}
}

View File

@ -0,0 +1,2 @@
ALTER TABLE `verify`
CHANGE COLUMN `value` `value` TEXT DEFAULT NULL COMMENT '核销内容';

View File

@ -6,8 +6,8 @@ use core\dict\DictLoader;
$data = [ $data = [
// 指令定义 // 指令定义
'commands' => [ 'commands' => [
'addon:install' => 'app\command\Addon\Install', 'addon:install' => 'app\command\addon\Install',
'addon:uninstall' => 'app\command\Addon\Uninstall', 'addon:uninstall' => 'app\command\addon\Uninstall',
'menu:refresh' => 'app\command\Menu', 'menu:refresh' => 'app\command\Menu',
//消息队列 自定义命令 //消息队列 自定义命令
'queue:work' => 'app\command\queue\Queue', 'queue:work' => 'app\command\queue\Queue',
@ -19,7 +19,7 @@ $data = [
'workerman' => 'app\command\workerman\Workerman', 'workerman' => 'app\command\workerman\Workerman',
//重置管理员密码 //重置管理员密码
'reset:password' => 'app\command\Resetpassword', 'reset:password' => 'app\command\Resetpassword',
'refresh:area' => 'app\command\refreshAreaCommand', 'refresh:area' => 'app\command\RefreshAreaCommand',
], ],
]; ];
return (new DictLoader("Console"))->load($data); return (new DictLoader("Console"))->load($data);

View File

@ -1,5 +1,5 @@
<?php <?php
return [ return [
'version' => '1.5.7', 'version' => '1.5.8',
'code' => '202511120001' 'code' => '202603210001'
]; ];

View File

@ -233,8 +233,12 @@ class Alipay extends BasePay
'out_trade_no' => $out_trade_no 'out_trade_no' => $out_trade_no
]; ];
} else { } else {
//todo 这儿可以抛出错误 return [
return false; 'status' => RefundDict::FAIL,
'refund_no' => $refund_no,
'out_trade_no' => $out_trade_no,
'fail_reason' => $result['sub_msg'] ?? ''
];
} }
} }

View File

@ -130,13 +130,14 @@ class Wechatpay extends BasePay
public function app(array $params) public function app(array $params)
{ {
try { try {
return $this->returnFormat(Pay::wechat()->app([ $result = $this->returnFormat(Pay::wechat()->app([
'out_trade_no' => $params['out_trade_no'], 'out_trade_no' => $params['out_trade_no'],
'description' => $params['body'], 'description' => $params['body'],
'amount' => [ 'amount' => [
'total' => $params['money'], 'total' => $params['money'],
], ],
])); ]));
return ['orderInfo' => $result];
} catch (\Exception $e) { } catch (\Exception $e) {
if ($e instanceof InvalidResponseException) { if ($e instanceof InvalidResponseException) {
throw new PayException($e->response->all()['message'] ?? ''); throw new PayException($e->response->all()['message'] ?? '');

View File

@ -49,7 +49,7 @@ class Niuyun extends BaseSms
*/ */
public function send(string $mobile, string $template_id, array $data = []) public function send(string $mobile, string $template_id, array $data = [])
{ {
Log::write("SEND_NY_SMS pre " . json_encode($data, 256)); Log::write("SEND_NY_SMS pre mobile: ".$mobile.' tem_id:'.$template_id . json_encode($data, 256));
if (empty($this->signature)) { if (empty($this->signature)) {
throw new CommonException('签名未配置'); throw new CommonException('签名未配置');
} }

View File

@ -17,6 +17,7 @@ use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use EasyWeChat\Kernel\Support\Collection; use EasyWeChat\Kernel\Support\Collection;
use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use think\facade\Log;
class Weapp extends BaseTemplate class Weapp extends BaseTemplate
@ -42,12 +43,13 @@ class Weapp extends BaseTemplate
public function send(array $data) public function send(array $data)
{ {
$api = CoreWeappService::appApiClient(); $api = CoreWeappService::appApiClient();
$api->postJson('cgi-bin/message/subscribe/send', [ $res = $api->postJson('cgi-bin/message/subscribe/send', [
'template_id' => $data['template_id'], // 所需下发的订阅模板id 'template_id' => $data['template_id'], // 所需下发的订阅模板id
'touser' => $data['openid'], // 接收者(用户)的 openid 'touser' => $data['openid'], // 接收者(用户)的 openid
'page' => $data['page'], // 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,示例index?foo=bar。该字段不填则模板无跳转。 'page' => $data['page'], // 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,示例index?foo=bar。该字段不填则模板无跳转。
'data' => $data['data'], 'data' => $data['data'],
]); ]);
Log::write("发送小程序消息Response-" . json_encode($res->toArray(), 256));
} }
/** /**
@ -60,11 +62,13 @@ class Weapp extends BaseTemplate
public function addTemplate(array $data) public function addTemplate(array $data)
{ {
$api = CoreWeappService::appApiClient(); $api = CoreWeappService::appApiClient();
return $api->postJson('wxaapi/newtmpl/addtemplate', [ $res = $api->postJson('wxaapi/newtmpl/addtemplate', [
'tid' => $data['tid'], 'tid' => $data['tid'],
'kidList' => $data['kid_list'], 'kidList' => $data['kid_list'],
'sceneDesc' => $data['scene_desc'], 'sceneDesc' => $data['scene_desc'],
]); ]);
Log::write("添加小程序模版Response-" . json_encode($res->toArray(), 256));
return $res;
} }
/** /**
@ -77,9 +81,11 @@ class Weapp extends BaseTemplate
public function delete(array $data) public function delete(array $data)
{ {
$api = CoreWeappService::appApiClient(); $api = CoreWeappService::appApiClient();
return $api->postJson('wxaapi/newtmpl/deltemplate', [ $res = $api->postJson('wxaapi/newtmpl/deltemplate', [
'priTmplId' => $data['template_id'], 'priTmplId' => $data['template_id'],
]); ]);
Log::write("删除小程序模版Response-" . json_encode($res->toArray(), 256));
return $res;
} }
/** /**

View File

@ -0,0 +1,100 @@
<?php
namespace core\util\http;
use core\util\http\src\HasHttpRequests;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface;
class HttpClient
{
use HasHttpRequests;
/**
*
* @var \think\facade\Request|\think\Request
*/
protected $request;
/**
*/
public function __construct()
{
}
/**
* @param string $url
* @param array $data
* @return array|Response|object|ResponseInterface
* @throws GuzzleException
*/
public function httpPost(string $url, array $data = [], array $options = [])
{
return $this->request($url, 'POST', array_merge([
'json' => $data,
'headers' => [
'Content-Type' => 'application/json;charset=utf-8'
]
], $options));
}
/**
* @param string $url
* @param array $data
* @return array|Response|object|ResponseInterface
* @throws GuzzleException
*/
public function httpPut(string $url, array $data = [], array $options = [])
{
return $this->request($url, 'PUT', array_merge([
'json' => $data,
'headers' => [
'Content-Type' => 'application/json;charset=utf-8'
]
], $options));
}
/**
* @param string $url
* @param string $method
* @param array $options
* @param bool $returnRaw
*
* @return ResponseInterface
* @throws GuzzleException
*/
public function request(string $url, string $method = 'GET', array $options = [], bool $returnRaw = false)
{
$response = $this->toRequest($url, $method, $options);
return $response;
}
/**
* @param string $url
* @param array $query
* @return array|object|Response|ResponseInterface
* @throws GuzzleException
*/
public function httpGet(string $url, array $query = [], array $options = [])
{
return $this->request($url, 'GET', array_merge([
'query' => $query,
], $options));
}
/**
* @param string $url
* @param array $data
* @param array $query
* @return array|Response|object|ResponseInterface
* @throws GuzzleException
*/
public function httpPostJson(string $url, array $data = [], array $query = [])
{
return $this->request($url, 'POST', ['query' => $query, 'json' => $data]);
}
}

View File

@ -0,0 +1,183 @@
<?php
namespace core\util\http\src;
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\HandlerStack;
use Psr\Http\Message\ResponseInterface;
use function GuzzleHttp\choose_handler;
trait HasHttpRequests
{
/**
* curl的自定义选项
* @var array
*/
protected static array $defaults = [
'curl' => [
CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
],
];
/**
* @var ClientInterface
*/
protected $httpClient;
/**
* @var array
*/
protected array $middlewares = [];
/**
* @var HandlerStack
*/
protected $handlerStack;
/**
* @param array $defaults
* @return void
*/
public static function setDefaultOptions(array $defaults = [])
{
self::$defaults = $defaults;
}
/**
* @return array
*/
public static function getDefaultOptions(): array
{
return self::$defaults;
}
/**
* @param callable $middleware
* @param string|null $name
* @return $this
*/
public function pushMiddleware(callable $middleware, string $name = null)
{
if (!is_null($name)) {
$this->middlewares[$name] = $middleware;
} else {
$this->middlewares[] = $middleware;
}
return $this;
}
/**
* @return array
*/
public function getMiddlewares(): array
{
return $this->middlewares;
}
/**
* @param $url
* @param string $method
* @param array $options
* @return ResponseInterface
* @throws GuzzleException
*/
public function toRequest($url, string $method = 'GET', array $options = [])
{
$method = strtoupper($method);
$options = array_merge(self::$defaults, $options, ['handler' => $this->getHandlerStack()]);
$options = $this->fixJsonIssue($options);
if (property_exists($this, 'baseUri') && !is_null($this->baseUri)) {
$options['base_uri'] = $this->baseUri;
}
$options['connect_timeout'] = 10;
$response = $this->getHttpClient()->request($method, $url, $options);
$response->getBody()->rewind();
return json_decode($response->getBody()->getContents(), true);
}
/**
* @return HandlerStack
*/
public function getHandlerStack(): HandlerStack
{
if ($this->handlerStack) {
return $this->handlerStack;
}
$this->handlerStack = HandlerStack::create($this->getGuzzleHandler());
foreach ($this->middlewares as $name => $middleware) {
$this->handlerStack->push($middleware, $name);
}
return $this->handlerStack;
}
/**
* @param HandlerStack $handlerStack
*
* @return $this
*/
public function setHandlerStack(HandlerStack $handlerStack)
{
$this->handlerStack = $handlerStack;
return $this;
}
/**
* @return callable
*/
protected function getGuzzleHandler()
{
return choose_handler();
}
/**
* @param array $options
* @return array
*/
protected function fixJsonIssue(array $options): array
{
if (isset($options['json']) && is_array($options['json'])) {
$options['headers'] = array_merge($options['headers'] ?? [], ['Content-Type' => 'application/json']);
if (empty($options['json'])) {
$options['body'] = \GuzzleHttp\json_encode($options['json'], JSON_FORCE_OBJECT);
} else {
$options['body'] = \GuzzleHttp\json_encode($options['json'], JSON_UNESCAPED_UNICODE);
}
unset($options['json']);
}
return $options;
}
/**
* @return ClientInterface
*/
public function getHttpClient(): ClientInterface
{
if (!($this->httpClient instanceof ClientInterface)) {
$this->httpClient = new Client(['handler' => HandlerStack::create($this->getGuzzleHandler())]);
}
return $this->httpClient;
}
/**
* @param ClientInterface $httpClient
* @return $this
*/
public function setHttpClient(ClientInterface $httpClient)
{
$this->httpClient = $httpClient;
return $this;
}
}

View File

@ -30,6 +30,9 @@ class CloudService
$local_cloud_compile_config = (new CoreConfigService())->getConfig(0, 'LOCAL_CLOUD_COMPILE_CONFIG')['value'] ?? []; $local_cloud_compile_config = (new CoreConfigService())->getConfig(0, 'LOCAL_CLOUD_COMPILE_CONFIG')['value'] ?? [];
if (!empty($local_cloud_compile_config) && isset($local_cloud_compile_config['isOpen']) && $local_cloud_compile_config['isOpen'] == 1){ if (!empty($local_cloud_compile_config) && isset($local_cloud_compile_config['isOpen']) && $local_cloud_compile_config['isOpen'] == 1){
$baseUri = $local_cloud_compile_config['baseUri'] ?? ''; $baseUri = $local_cloud_compile_config['baseUri'] ?? '';
if (empty($baseUri)){
throw new CommonException("已开启`第三方云编译`,但未配置云编译服务器地址,详情查看:平台端》云编译》第三方云编译");
}
} }
if (!empty($local_cloud_compile)){ if (!empty($local_cloud_compile)){

View File

@ -34,6 +34,7 @@ trait AccessToken
{ {
$this->access_token = ''; $this->access_token = '';
Cache::delete($this->access_token_cache); Cache::delete($this->access_token_cache);
if (file_exists(public_path() . 'access_token.txt')) unlink(file_exists(public_path() . 'access_token.txt'));
return $this; return $this;
} }
/** /**
@ -55,6 +56,9 @@ trait AccessToken
if (empty($this->access_token)) { if (empty($this->access_token)) {
$this->access_token = Cache::get($this->access_token_cache, ''); $this->access_token = Cache::get($this->access_token_cache, '');
} }
if (empty($this->access_token) && file_exists(public_path() . 'access_token.txt')) {
$this->access_token = file_get_contents(public_path() . 'access_token.txt');
}
return $this->access_token; return $this->access_token;
} }
@ -67,7 +71,9 @@ trait AccessToken
{ {
$access_token_info = $this->httpGet('auth', ['code' => $this->code, 'secret' => $this->secret, 'token' => $this->createToken(), 'product_key' => self::PRODUCT, 'redirect_uri' => $this->getDomain(false)]); $access_token_info = $this->httpGet('auth', ['code' => $this->code, 'secret' => $this->secret, 'token' => $this->createToken(), 'product_key' => self::PRODUCT, 'redirect_uri' => $this->getDomain(false)]);
if (isset($access_token_info['code']) && $access_token_info['code'] != 1) throw new NiucloudException($access_token_info['msg']); if (isset($access_token_info['code']) && $access_token_info['code'] != 1) throw new NiucloudException($access_token_info['msg']);
if (isset($access_token_info['data']['token']) && !empty($access_token_info['data']['token'])) {
$this->setAccessToken($access_token_info['data']['token']); $this->setAccessToken($access_token_info['data']['token']);
} }
}
} }

View File

@ -164,7 +164,10 @@ trait HasHttpRequests
public function getHttpClient(): ClientInterface public function getHttpClient(): ClientInterface
{ {
if (!($this->httpClient instanceof ClientInterface)) { if (!($this->httpClient instanceof ClientInterface)) {
$this->httpClient = new Client(['handler' => HandlerStack::create($this->getGuzzleHandler())]); $this->httpClient = new Client([
'handler' => HandlerStack::create($this->getGuzzleHandler()),
// 'proxy'=>''//调试放开
]);
} }
return $this->httpClient; return $this->httpClient;