From 074aac042399ae9491165628b031ef3ca0a0b56e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=A8=E6=A0=88=E5=B0=8F=E5=AD=A6=E7=94=9F?= <1518079521@qq.com> Date: Fri, 30 May 2025 09:45:43 +0800 Subject: [PATCH] up --- .../app/adminapi/controller/addon/Addon.php | 26 + .../app/adminapi/controller/addon/Upgrade.php | 15 +- .../app/adminapi/controller/home/Site.php | 1 + .../app/adminapi/controller/member/Member.php | 3 + .../app/adminapi/controller/notice/NiuSms.php | 409 ++++++++ .../app/adminapi/controller/notice/Notice.php | 2 +- .../app/adminapi/controller/site/UserLog.php | 10 + .../controller/wxoplatform/Oplatform.php | 7 + .../controller/wxoplatform/WeappVersion.php | 20 + niucloud/app/adminapi/route/addon.php | 5 + niucloud/app/adminapi/route/notice.php | 43 + niucloud/app/adminapi/route/site.php | 1 + niucloud/app/adminapi/route/upgrade.php | 9 +- niucloud/app/adminapi/route/wxoplatform.php | 6 + niucloud/app/api/controller/member/Member.php | 1 + niucloud/app/dict/menu/admin.php | 904 +++++++++--------- niucloud/app/dict/menu/site.php | 29 + niucloud/app/dict/notice/NoticeDict.php | 71 +- niucloud/app/dict/notice/NoticeTypeDict.php | 156 +++ niucloud/app/dict/notice/notice.php | 4 +- niucloud/app/dict/notice/sms.php | 4 + niucloud/app/dict/schedule/schedule.php | 4 +- niucloud/app/dict/sys/CloudDict.php | 3 + niucloud/app/dict/sys/ConfigKeyDict.php | 2 + niucloud/app/dict/sys/SmsDict.php | 12 + niucloud/app/dict/sys/StorageDict.php | 1 + niucloud/app/dict/sys/UpgradeDict.php | 3 + niucloud/app/install/source/database.sql | 27 +- niucloud/app/job/notice/Notice.php | 19 +- niucloud/app/lang/zh-cn/api.php | 22 +- niucloud/app/lang/zh-cn/dict.php | 28 +- niucloud/app/lang/zh-cn/validate.php | 1 + niucloud/app/listener/notice/Sms.php | 39 +- .../notice_template/BaseNoticeTemplate.php | 4 +- .../listener/system/WeappAuthChangeAfter.php | 4 - niucloud/app/model/site/Site.php | 2 +- niucloud/app/model/site/SiteGroup.php | 28 + niucloud/app/model/sys/NiuSmsTemplate.php | 49 + niucloud/app/model/sys/SysConfig.php | 4 + niucloud/app/model/sys/SysUpgradeRecords.php | 10 + .../service/admin/home/AuthSiteService.php | 13 +- .../service/admin/notice/NiuSmsService.php | 631 ++++++++++++ .../service/admin/notice/NoticeService.php | 33 +- .../app/service/admin/notice/SmsService.php | 13 +- .../service/admin/site/SiteGroupService.php | 2 +- .../app/service/admin/site/UserLogService.php | 5 + .../admin/upgrade/BackupRecordsService.php | 88 +- .../service/admin/upgrade/BackupService.php | 28 - .../service/admin/upgrade/RestoreService.php | 43 +- .../admin/upgrade/UpgradeRecordsService.php | 32 +- .../service/admin/upgrade/UpgradeService.php | 287 ++++-- .../admin/upload/StorageConfigService.php | 2 +- .../admin/wxoplatform/OplatformService.php | 23 +- .../admin/wxoplatform/WeappVersionService.php | 32 +- .../app/service/api/diy/DiyConfigService.php | 2 +- .../core/addon/CoreAddonCloudService.php | 6 +- .../service/core/addon/CoreAddonService.php | 38 +- niucloud/app/service/core/http/HttpHelper.php | 92 ++ .../service/core/member/CoreMemberService.php | 2 + .../app/service/core/menu/CoreMenuService.php | 68 +- .../core/niucloud/CoreCloudBuildService.php | 115 +-- .../core/niucloud/CoreModuleService.php | 22 + .../service/core/notice/CoreNiuSmsService.php | 388 ++++++++ .../service/core/notice/CoreNoticeService.php | 4 +- .../service/core/notice/CoreSmsService.php | 3 +- .../app/service/core/notice/NoticeService.php | 12 +- .../service/core/pay/CoreRefundService.php | 124 ++- .../service/core/pay/CoreTransferService.php | 161 ++-- .../service/core/upload/CoreFileService.php | 23 +- .../core/weapp/CoreWeappCloudService.php | 59 +- .../core/wxoplatform/CoreOplatformService.php | 12 +- niucloud/app/upgrade/v110/upgrade.sql | 28 + .../app/validate/member/CashOutConfig.php | 4 +- niucloud/app/validate/member/Member.php | 8 +- niucloud/config/version.php | 4 +- niucloud/core/dict/BaseDict.php | 36 + niucloud/core/dict/Notice.php | 15 +- niucloud/core/sms/Niuyun.php | 142 +++ niucloud/core/util/DbBackup.php | 126 ++- 79 files changed, 3720 insertions(+), 994 deletions(-) create mode 100644 niucloud/app/adminapi/controller/notice/NiuSms.php create mode 100644 niucloud/app/model/sys/NiuSmsTemplate.php create mode 100644 niucloud/app/service/admin/notice/NiuSmsService.php create mode 100644 niucloud/app/service/core/http/HttpHelper.php create mode 100644 niucloud/app/service/core/notice/CoreNiuSmsService.php create mode 100644 niucloud/app/upgrade/v110/upgrade.sql create mode 100644 niucloud/core/sms/Niuyun.php diff --git a/niucloud/app/adminapi/controller/addon/Addon.php b/niucloud/app/adminapi/controller/addon/Addon.php index a017c3df4..b2749820a 100644 --- a/niucloud/app/adminapi/controller/addon/Addon.php +++ b/niucloud/app/adminapi/controller/addon/Addon.php @@ -20,6 +20,11 @@ use think\Response; class Addon extends BaseAdminController { + + public function init() + { + return success((new CoreAddonService())->getInitList()); + } /** * 获取已下载插架 */ @@ -183,4 +188,25 @@ class Addon extends BaseAdminController public function upgrade($addon = ''){ return success('DOWNLOAD_SUCCESS', (new AddonService())->upgrade($addon)); } + + /** + * 获取首页应用标签 + */ + public function getIndexAddonLabelList() + { + return success((new CoreAddonService())->getIndexAddonLabelList()); + } + + /** + * 获取首页应用 + * @return Response + */ + public function getIndexAddonList() + { + $data = $this->request->params([ + ['label_id', ''], + ]); + return success((new CoreAddonService())->getIndexAddonList($data['label_id'])); + } + } diff --git a/niucloud/app/adminapi/controller/addon/Upgrade.php b/niucloud/app/adminapi/controller/addon/Upgrade.php index 63295c584..6f213af04 100644 --- a/niucloud/app/adminapi/controller/addon/Upgrade.php +++ b/niucloud/app/adminapi/controller/addon/Upgrade.php @@ -25,7 +25,11 @@ class Upgrade extends BaseAdminController */ public function upgrade($addon = '') { - return success(data: ( new UpgradeService() )->upgrade($addon)); + $data = $this->request->params([ + ['is_need_backup', true], + ['is_need_cloudbuild', true], + ]); + return success(data: ( new UpgradeService() )->upgrade($addon, $data)); } /** @@ -73,7 +77,7 @@ class Upgrade extends BaseAdminController */ public function clearUpgradeTask() { - return success(data: ( new UpgradeService() )->clearUpgradeTask()); + return success(data: ( new UpgradeService() )->clearUpgradeTask(0, 1)); } public function operate($operate) { @@ -92,4 +96,11 @@ class Upgrade extends BaseAdminController return success(( new UpgradeRecordsService() )->getPage($data)); } + public function delRecords() { + $data = $this->request->params([ + [ 'ids', '' ], + ]); + ( new UpgradeRecordsService() )->del($data['ids']); + return success('DELETE_SUCCESS'); + } } diff --git a/niucloud/app/adminapi/controller/home/Site.php b/niucloud/app/adminapi/controller/home/Site.php index 54eccedd1..38f194b24 100644 --- a/niucloud/app/adminapi/controller/home/Site.php +++ b/niucloud/app/adminapi/controller/home/Site.php @@ -27,6 +27,7 @@ class Site extends BaseAdminController ['keywords', ''], ['status', ''], ['app', ''], + ['sort', ''], ]); return success((new AuthSiteService())->getSitePage($data)); } diff --git a/niucloud/app/adminapi/controller/member/Member.php b/niucloud/app/adminapi/controller/member/Member.php index 8ab815f51..34f42b59a 100644 --- a/niucloud/app/adminapi/controller/member/Member.php +++ b/niucloud/app/adminapi/controller/member/Member.php @@ -66,6 +66,8 @@ class Member extends BaseAdminController ['member_label', []], ['sex', 0], ['birthday', ''], + ['remark', ''], + ['id_card', ''], ]); $this->validate($data, 'app\validate\member\Member.add'); $res = (new MemberService())->add($data); @@ -85,6 +87,7 @@ class Member extends BaseAdminController ['field', $field], ]); $data[$field] = $data['value']; + $data['member_id'] = $member_id; $this->validate($data, 'app\validate\member\Member.modify'); (new MemberService())->modify($member_id, $field, $data['value']); return success('MODIFY_SUCCESS'); diff --git a/niucloud/app/adminapi/controller/notice/NiuSms.php b/niucloud/app/adminapi/controller/notice/NiuSms.php new file mode 100644 index 000000000..2dd81f693 --- /dev/null +++ b/niucloud/app/adminapi/controller/notice/NiuSms.php @@ -0,0 +1,409 @@ +request->params([ + ['is_enable', 0], + ]); + (new NiuSmsService())->enableNiuSms($params['is_enable']); + return success("SUCCESS"); + } + + + /** + * 获取基础信息 + * @return Response + */ + public function getConfig() + { + return success((new NiuSmsService())->getConfig()); + } + + public function getSmsPackageList() + { + $params = $this->request->params([ + ['package_name', ''], + ['sms_num', ''], + ['price_start', ""], + ['price_end', ""], + ['original_price_start', ""], + ['original_price_end', ""], + ['time_start', ""], + ['time_end', ""], + ]); + $list = (new NiuSmsService())->packageList($params); + return success($list); + } + + /*******牛云*******/ + public function sendMobileCode() + { + $params = $this->request->params([ + ['mobile', ''], + ['captcha_key', ''], + ['captcha_code', ''], + ]); + $data = (new NiuSmsService())->sendMobileCode($params); + return success($data); + } + + /** + * 获取图形验证码 + * @return Response + */ + public function captcha() + { + $data = (new NiuSmsService())->captcha(); + return success($data); + } + + /** + * 注册牛云短信子账号 + * @return Response + */ + public function registerAccount() + { + $data = $this->request->params([ + ['username', ""], + ['company', ""], + ['mobile', ""], + ['password', ""], + ['remark', ""], + ['key', ""], + ['code', ""], + ]); + $res = (new NiuSmsService())->registerAccount($data); + return success($res); + } + + /** + * 登录牛云短信子账号 + * @return Response + */ + public function loginAccount() + { + $params = $this->request->params([ + ['username', ""], + ['password', ""], + ]); + $data = (new NiuSmsService())->loginAccount($params); + return success($data); + } + + /** + * 获取短信发送列表 + * @param $username + * @return Response + */ + public function accountSendList($username) + { + $params = $this->request->params([ + ['content',''], + ['mobile',''], + ['smsStatus',''] + ]); + $data = (new NiuSmsService())->accountSendList($username,$params); + return success($data); + } + + /** + * 获取子账户信息 + * @param $username + * @return Response + */ + public function accountInfo($username) + { + $data = (new NiuSmsService())->accountInfo($username); + return success($data); + } + + /** + * 修改子账户信息 + * @param $username + * @return Response + */ + public function editAccount($username) + { + $params = $this->request->params([ + ['new_mobile', ""], + ['mobile', ""], + ['code', ""], + ['key', ""], + ['signature', ""], + ]); + $data = (new NiuSmsService())->editAccount($username, $params); + return success($data); + } + + /** + * 重置密码 + * @param $username + * @return Response + */ + public function resetPassword($username) + { + $params = $this->request->params([ + ['mobile', ''], + ['code', ''], + ['key', ''], + ]); + $data = (new NiuSmsService())->resetPassword($username, $params); + return success($data); + } + + /** + * 忘记密码 + * @param $username + * @return Response + */ + public function forgetPassword($username) + { + $params = $this->request->params([ + ['mobile', ''], + ['code', ''], + ['key', ''], + ]); + $data = (new NiuSmsService())->forgetPassword($username, $params); + return success($data); + } + + /** + * 签名列表 + * @param $username + * @return Response + */ + public function signList($username) + { + $data = (new NiuSmsService())->getSignList($username); + return success($data); + } + + /** + * 签名信息 + * @param $username + * @return Response + */ + public function signInfo($username) + { + $signature = $this->request->param('signature'); + $data = (new NiuSmsService())->signInfo($username, $signature); + return success($data); + } + + public function signCreateConfig() + { + return success((new NiuSmsService())->signCreateConfig()); + } + + /** + * 签名创建、报备 + * @param $username + * @return Response + */ + public function signCreate($username) + { + $params = $this->request->params([ + ['signature', ""], + ['contentExample', ""], + ['companyName', ""], + ['creditCode', ""], + ['legalPerson', ""], + ['principalName', ""], + ['principalIdCard', ""], + ['signSource', ""], + ['signType', ""], + ['imgUrl', ""], + ['defaultSign', 0], + ]); + (new NiuSmsService())->signCreate($username, $params); + return success("SUCCESS"); + } + + public function signDelete($username) + { + $params = $this->request->params([ + ['signatures', []] + ]); + $data = (new NiuSmsService())->signDelete($username, $params); + return success($data); + } + + /** + * 同步模版状态 + * @param $sms_type + * @param $username + * @return Response + */ + public function templateSync($sms_type, $username) + { + $data = (new NiuSmsService())->syncTemplateList($sms_type, $username); + return success($data); + } + + /** + * 模版列表 + * @param $sms_type + * @param $username + * @return Response + */ + public function templateList($sms_type, $username) + { + $data = (new NiuSmsService())->getTemplateList($sms_type, $username); + return success($data); + } + + /** + * 模版信息 + * @param $sms_type + * @param $username + * @return Response + */ + public function templateInfo($sms_type, $username) + { + $template_key = $this->request->param('template_key'); + $data = (new NiuSmsService())->templateInfo($sms_type, $username, $template_key); + return success($data); + } + + /** + * 创建模版需要的配置 + * @return Response + */ + public function templateCreateConfig() + { + return success((new NiuSmsService())->templateCreateConfig()); + } + + /** + * 创建模版 + * @param $sms_type + * @param $username + * @return Response + */ + public function templateCreate($sms_type, $username) + { + $params = $this->request->params([ + ['template_key', ""], + ['template_type', ""], + ['params_json', ""], + ['template_id', ""], + ]); + $data = (new NiuSmsService())->templateUpsert($sms_type, $username, $params); + return success($data); + } + + /** + * 创建订单 + * @param $username + * @return Response + */ + public function createOrder($username) + { + $params = $this->request->params([ + ['package_id', 0] + ]); + $data = (new NiuSmsService())->createOrder($username, $params['package_id']); + return success($data); + + } + + /** + * 订单计算 + * @param $username + * @return Response + */ + public function calculate($username) + { + $params = $this->request->params([ + ['package_id', 0] + ]); + $data = (new NiuSmsService())->calculate($username, $params['package_id']); + return success($data); + + } + + /** + * 获取支付信息 + * @param $username + * @return Response + */ + public function getPayInfo($username) + { + $params = $this->request->params([ + ['out_trade_no', ''] + ]); + $data = (new NiuSmsService())->getPayInfo($username, $params); + return success($data); + } + + /** + * 充值、订单列表 + * @param $username + * @return Response + */ + public function orderList($username) + { + $params = $this->request->params([ + ['out_trade_no', ''], + ['order_status', ''], + ['create_time_start', ''], + ['create_time_end', ''], + ]); + $data = (new NiuSmsService())->orderList($username,$params); + return success($data); + } + + /** + * 订单详情 + * @param $username + * @return Response + */ + public function orderInfo($username) + { + $params = $this->request->params([ + ['out_trade_no', ''] + ]); + $data = (new NiuSmsService())->orderInfo($username, $params['out_trade_no']); + return success($data); + } + + /** + * 订单状态 + * @param $username + * @return Response + */ + public function orderStatus($username) + { + $params = $this->request->params([ + ['out_trade_no', ''] + ]); + $data = (new NiuSmsService())->orderStatus($username, $params['out_trade_no']); + return success($data); + } +} diff --git a/niucloud/app/adminapi/controller/notice/Notice.php b/niucloud/app/adminapi/controller/notice/Notice.php index 4d62ed702..58de67574 100644 --- a/niucloud/app/adminapi/controller/notice/Notice.php +++ b/niucloud/app/adminapi/controller/notice/Notice.php @@ -13,6 +13,7 @@ namespace app\adminapi\controller\notice; use app\dict\sys\SmsDict; use app\service\admin\notice\NoticeService; +use app\service\admin\notice\NiuSmsService; use app\service\admin\notice\SmsService; use core\base\BaseAdminController; use core\exception\AdminException; @@ -111,5 +112,4 @@ class Notice extends BaseAdminController (new NoticeService())->edit($data['key'], $data['type'], $data); return success(); } - } diff --git a/niucloud/app/adminapi/controller/site/UserLog.php b/niucloud/app/adminapi/controller/site/UserLog.php index 31a9387e0..9ee64bd3b 100644 --- a/niucloud/app/adminapi/controller/site/UserLog.php +++ b/niucloud/app/adminapi/controller/site/UserLog.php @@ -47,5 +47,15 @@ class UserLog extends BaseAdminController return success((new UserLogService())->getInfo($id)); } + /** + * 清空日志 + * @return Response + */ + public function destroy() + { + (new UserLogService())->destroy(); + return success("SUCCESS"); + } + } diff --git a/niucloud/app/adminapi/controller/wxoplatform/Oplatform.php b/niucloud/app/adminapi/controller/wxoplatform/Oplatform.php index 878ae01cd..2774fedb4 100644 --- a/niucloud/app/adminapi/controller/wxoplatform/Oplatform.php +++ b/niucloud/app/adminapi/controller/wxoplatform/Oplatform.php @@ -37,4 +37,11 @@ class Oplatform extends BaseAdminController ]); return success((new OplatformService())->authorization($data)); } + + public function getAuthRecord() { + $data = $this->request->params([ + ['name', ''], + ]); + return success((new OplatformService())->getAuthRecord($data)); + } } diff --git a/niucloud/app/adminapi/controller/wxoplatform/WeappVersion.php b/niucloud/app/adminapi/controller/wxoplatform/WeappVersion.php index 4078f2a46..0aa4870fb 100644 --- a/niucloud/app/adminapi/controller/wxoplatform/WeappVersion.php +++ b/niucloud/app/adminapi/controller/wxoplatform/WeappVersion.php @@ -58,4 +58,24 @@ class WeappVersion extends BaseAdminController (new WeappVersionService())->siteWeappCommit(); return success(); } + + public function undoAudit() { + $data = $this->request->params([ + ['id', ""] + ]); + (new WeappVersionService())->undoAudit($data['id']); + return success(); + } + + /** + * 同步套餐下站点小程序 + * @return Response + */ + public function syncSiteWeapp() { + $data = $this->request->params([ + ['site_group_id', 0] + ]); + (new WeappVersionService())->syncSiteGroupAuthWeapp($data['site_group_id']); + return success(); + } } diff --git a/niucloud/app/adminapi/route/addon.php b/niucloud/app/adminapi/route/addon.php index 61c12a4a7..277dd68a8 100644 --- a/niucloud/app/adminapi/route/addon.php +++ b/niucloud/app/adminapi/route/addon.php @@ -19,6 +19,7 @@ use think\facade\Route; */ Route::group(function () { //获取本地插件 + Route::get('addon/init', 'addon.Addon/init'); Route::get('addon/local', 'addon.Addon/getLocalAddonList'); //获取插件列表 Route::get('addon', 'addon.Addon/lists'); @@ -53,6 +54,10 @@ Route::group(function () { // 取消安装任务 Route::put('addon/install/cancel/:addon', 'addon.Addon/cancleInstall'); + //首页展示应用标签列表 + Route::get('app/label/index', 'addon.Addon/getIndexAddonLabelList'); + //首页展示应用列表 + Route::get('app/index', 'addon.Addon/getIndexAddonList'); /******************************************************************开发插件 *******************************************************/ //开发插件列表 Route::get('addon_develop', 'addon.AddonDevelop/lists'); diff --git a/niucloud/app/adminapi/route/notice.php b/niucloud/app/adminapi/route/notice.php index 1288bb05a..8471d849b 100644 --- a/niucloud/app/adminapi/route/notice.php +++ b/niucloud/app/adminapi/route/notice.php @@ -45,6 +45,49 @@ Route::group('notice', function () { //短信发送记录详情 Route::get('sms/log/:id', 'notice.SmsLog/info'); + Route::group('niusms', function () { + Route::get('packages', 'notice.NiuSms/getSmsPackageList'); + //发送验证短信 + Route::post('send', 'notice.NiuSms/sendMobileCode'); + Route::get('captcha', 'notice.NiuSms/captcha'); + + Route::get('config', 'notice.NiuSms/getConfig'); + Route::put('enable', 'notice.NiuSms/enable'); + Route::group('account', function () { + Route::post('register', 'notice.NiuSms/registerAccount'); + Route::post('login', 'notice.NiuSms/loginAccount'); + Route::post('edit/:username', 'notice.NiuSms/editAccount'); + 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('info/:username', 'notice.NiuSms/accountInfo'); + }); + + Route::group('order', function () { + Route::get('list/:username', 'notice.NiuSms/orderList'); + Route::post('calculate/:username', 'notice.NiuSms/calculate'); + Route::post('create/:username', 'notice.NiuSms/createOrder'); + Route::get('info/:username', 'notice.NiuSms/orderInfo'); + Route::get('status/:username', 'notice.NiuSms/orderStatus'); + Route::get('pay/:username', 'notice.NiuSms/getPayInfo'); + }); + Route::group('sign', function () { + Route::get('list/:username', 'notice.NiuSms/signList'); + Route::get('info/:username', 'notice.NiuSms/signInfo'); + Route::get('report/config', 'notice.NiuSms/signCreateConfig'); + Route::post('report/:username', 'notice.NiuSms/signCreate'); + Route::post('delete/:username', 'notice.NiuSms/signDelete'); + }); + + Route::group('template', function () { + Route::get('sync/:sms_type/:username', 'notice.NiuSms/templateSync'); + Route::get('list/:sms_type/:username', 'notice.NiuSms/templateList'); + Route::get('info/:sms_type/:username', 'notice.NiuSms/templateInfo'); + Route::get('report/config', 'notice.NiuSms/templateCreateConfig'); + Route::post('report/:sms_type/:username', 'notice.NiuSms/templateCreate'); + }); + }); + })->middleware([ AdminCheckToken::class, AdminCheckRole::class, diff --git a/niucloud/app/adminapi/route/site.php b/niucloud/app/adminapi/route/site.php index 4cdd45331..69def6406 100644 --- a/niucloud/app/adminapi/route/site.php +++ b/niucloud/app/adminapi/route/site.php @@ -74,6 +74,7 @@ Route::group('site', function () { Route::get('log', 'site.UserLog/lists'); //操作日志详情 Route::get('log/:id', 'site.UserLog/info'); + Route::delete('log/destroy', 'site.UserLog/destroy'); /***************************************************** 站点菜单 **************************************************/ Route::get('site/menu', 'site.Site/menu'); /***************************************************** 站点账单 *************************************************/ diff --git a/niucloud/app/adminapi/route/upgrade.php b/niucloud/app/adminapi/route/upgrade.php index 935f5e893..be9598f06 100644 --- a/niucloud/app/adminapi/route/upgrade.php +++ b/niucloud/app/adminapi/route/upgrade.php @@ -30,19 +30,22 @@ Route::group('', function () { Route::post('upgrade/clear', 'addon.Upgrade/clearUpgradeTask'); // 升级环境检测 - Route::get('upgrade/check/[:addon]', 'addon.Upgrade/upgradePreCheck'); + Route::get('upgrade/check/[:addon]', 'addon.Upgrade/upgradePreCheck')->pattern(['addon' => '[\w|\,]+']); // 升级 - Route::post('upgrade/[:addon]', 'addon.Upgrade/upgrade'); + Route::post('upgrade/[:addon]', 'addon.Upgrade/upgrade')->pattern(['addon' => '[\w|\,]+']); // 获取升级内容 - Route::get('upgrade/[:addon]', 'addon.Upgrade/getUpgradeContent'); + Route::get('upgrade/[:addon]', 'addon.Upgrade/getUpgradeContent')->pattern(['addon' => '[\w|\,]+']); Route::post('upgrade/operate/:operate', 'addon.Upgrade/operate'); // 升级记录分页列表 Route::get('upgrade/records', 'addon.Upgrade/getRecords'); + // 删除升级记录 + Route::delete('upgrade/records', 'addon.Upgrade/delRecords'); + // 备份记录分页列表 Route::get('backup/records', 'addon.Backup/getRecords'); diff --git a/niucloud/app/adminapi/route/wxoplatform.php b/niucloud/app/adminapi/route/wxoplatform.php index 62bf78bc2..c3bc228d2 100644 --- a/niucloud/app/adminapi/route/wxoplatform.php +++ b/niucloud/app/adminapi/route/wxoplatform.php @@ -30,6 +30,8 @@ Route::group('wxoplatform', function () { Route::get('authorizationUrl', 'wxoplatform.Oplatform/getAuthorizationUrl'); // 确认授权 Route::get('authorization', 'wxoplatform.Oplatform/authorization'); + // 授权记录 + Route::get('authorization/record', 'wxoplatform.Oplatform/getAuthRecord'); // 平台提交小程序版本 Route::post('weapp/version/commit', 'wxoplatform.WeappVersion/weappCommit'); // 获取最后一次提交记录 @@ -40,6 +42,10 @@ Route::group('wxoplatform', function () { Route::post('site/weapp/commit', 'wxoplatform.WeappVersion/siteWeappCommit'); // 按站点套餐获取提交记录 Route::get('sitegroup/commit', 'wxoplatform.WeappVersion/getSiteGroupCommitRecord'); + // 撤销审核 + Route::put('undo/weappaudit', 'wxoplatform.WeappVersion/undoAudit'); + // 同步套餐下站点小程序 + Route::post('async/siteweapp', 'wxoplatform.WeappVersion/syncSiteWeapp'); })->middleware([ AdminCheckToken::class, AdminCheckRole::class, diff --git a/niucloud/app/api/controller/member/Member.php b/niucloud/app/api/controller/member/Member.php index 3f378e4dd..0c5660a7a 100644 --- a/niucloud/app/api/controller/member/Member.php +++ b/niucloud/app/api/controller/member/Member.php @@ -50,6 +50,7 @@ class Member extends BaseApiController [ 'field', $field ], ]); $data[ $field ] = $data[ 'value' ]; + $data['member_id'] = $this->request->memberId(); $this->validate($data, 'app\validate\member\Member.modify'); ( new MemberService() )->modify($field, $data[ 'value' ]); return success('MODIFY_SUCCESS'); diff --git a/niucloud/app/dict/menu/admin.php b/niucloud/app/dict/menu/admin.php index a83733718..646bac590 100644 --- a/niucloud/app/dict/menu/admin.php +++ b/niucloud/app/dict/menu/admin.php @@ -6,7 +6,7 @@ return [ 'menu_short_name' => '首页', 'parent_key' => '', 'menu_type' => '1', - 'icon' => 'iconfont iconshouye2', + 'icon' => 'iconfont iconshouyec', 'api_url' => '', 'router_path' => 'index', 'view_path' => 'index/index', @@ -37,7 +37,7 @@ return [ 'menu_short_name' => '配置', 'parent_key' => '', 'menu_type' => '0', - 'icon' => 'iconfont iconshezhi11', + 'icon' => 'iconfont iconshezhi2', 'api_url' => '', 'router_path' => '', 'view_path' => '', @@ -51,7 +51,7 @@ return [ 'menu_key' => 'website_setting', 'menu_short_name' => '网站设置', 'menu_type' => '0', - 'icon' => 'iconfont iconwangzhanshezhi', + 'icon' => 'iconfont iconwangzhanshezhic', 'api_url' => '', 'router_path' => '', 'view_path' => '', @@ -65,7 +65,7 @@ return [ 'menu_key' => 'base_setting', 'menu_short_name' => '基础设置', 'menu_type' => '1', - 'icon' => 'iconfont iconjichushezhi1', + 'icon' => 'iconfont iconjichushezhic', 'api_url' => 'sys/config/website', 'router_path' => 'setting/website/system', 'view_path' => 'setting/system', @@ -95,7 +95,7 @@ return [ 'menu_key' => 'setting_copyright', 'menu_short_name' => '版权设置', 'menu_type' => '1', - 'icon' => 'iconfont iconbanquanshezhi', + 'icon' => 'iconfont iconbanquanshezhic', 'api_url' => 'sys/config/copyright', 'router_path' => 'setting/website/copyright', 'view_path' => 'setting/copyright', @@ -127,7 +127,7 @@ return [ 'menu_key' => 'auth', 'menu_short_name' => '权限设置', 'menu_type' => '0', - 'icon' => 'iconfont iconquanxianshezhi', + 'icon' => 'iconfont iconquanxianshezhic', 'api_url' => '', 'router_path' => '', 'view_path' => '', @@ -137,11 +137,11 @@ return [ 'is_show' => '1', 'children' => [ [ - 'menu_name' => '管理员', + 'menu_name' => '管理员列表', 'menu_key' => 'auth_list', - 'menu_short_name' => '管理员', + 'menu_short_name' => '管理员列表', 'menu_type' => '1', - 'icon' => 'iconfont iconguanliyuan', + 'icon' => 'iconfont iconguanliyuanc', 'api_url' => 'site/user', 'router_path' => 'setting/auth/user', 'view_path' => 'auth/user', @@ -255,14 +255,14 @@ return [ 'menu_key' => 'auth_role', 'menu_short_name' => '管理员角色', 'menu_type' => '1', - 'icon' => 'iconfont iconguanliyuanjiaose', + 'icon' => 'iconfont iconguanliyuanjiaosec', 'api_url' => 'sys/role', 'router_path' => 'setting/auth/role', 'view_path' => 'auth/role', 'methods' => 'get', 'sort' => '70', 'status' => '1', - 'is_show' => '1', + 'is_show' => '0', 'children' => [ [ 'menu_name' => '新增', @@ -313,7 +313,7 @@ return [ 'menu_key' => 'auth_log', 'menu_short_name' => '操作日志', 'menu_type' => '1', - 'icon' => 'iconfont iconcaozuorizhi', + 'icon' => 'iconfont iconcaozuorizhic', 'api_url' => 'sys/log', 'router_path' => 'setting/auth/log', 'view_path' => 'auth/log', @@ -329,7 +329,7 @@ return [ 'menu_key' => 'setting_storage', 'menu_short_name' => '存储设置', 'menu_type' => '1', - 'icon' => 'iconfont iconcunchushezhi', + 'icon' => 'iconfont iconcunchushezhic', 'api_url' => 'sys/storage', 'router_path' => 'setting/storage', 'view_path' => 'setting/storage', @@ -373,7 +373,7 @@ return [ 'menu_key' => 'setting_login', 'menu_short_name' => '登录设置', 'menu_type' => '1', - 'icon' => 'iconfont icondenglushezhi', + 'icon' => 'iconfont icondenglushezhic', 'api_url' => 'sys/config/login', 'router_path' => 'setting/adminlogin', 'view_path' => 'setting/adminlogin', @@ -402,76 +402,44 @@ return [ 'menu_name' => '微信开放平台', 'menu_key' => 'wx_oplatform', 'menu_short_name' => '微信开放平台', - 'menu_type' => '0', - 'icon' => 'iconfont iconweixinkaifangpingtai', - 'api_url' => '', - 'router_path' => '', - 'view_path' => '', + 'menu_type' => '1', + 'icon' => 'iconfont iconweixinkaifangpingtaic', + 'api_url' => 'sys/config/wxoplatform', + 'router_path' => 'setting/oplatform', + 'view_path' => 'setting/oplatform', 'methods' => 'get', 'sort' => '60', 'status' => '1', 'is_show' => '1', 'children' => [ [ - 'menu_name' => '开放平台配置', - 'menu_key' => 'setting_oplatform', - 'menu_short_name' => '开放平台配置', - 'menu_type' => '1', - 'icon' => 'iconfont iconkaifangpingtaipeizhi', + 'menu_name' => '保存', + 'menu_key' => 'save_wxoplatform_config', + 'menu_short_name' => '保存', + 'menu_type' => '2', + 'icon' => '', 'api_url' => 'wxoplatform/config', - 'router_path' => 'setting/oplatform', - 'view_path' => 'wxoplatform/setting', - 'methods' => 'get', + 'router_path' => '', + 'view_path' => '', + 'methods' => 'put', 'sort' => '100', 'status' => '1', 'is_show' => '1', - 'children' => [ - [ - 'menu_name' => '保存', - 'menu_key' => 'save_wxoplatform_config', - 'menu_short_name' => '保存', - 'menu_type' => '2', - 'icon' => '', - 'api_url' => 'wxoplatform/config', - 'router_path' => '', - 'view_path' => '', - 'methods' => 'put', - 'sort' => '100', - 'status' => '1', - 'is_show' => '1', - ] - ] ], [ - 'menu_name' => '小程序同步', - 'menu_key' => 'oplatform_weapp_version', - 'menu_short_name' => '小程序同步', - 'menu_type' => '1', - 'icon' => 'iconfont iconxiaochengxutongbu', - 'api_url' => 'wxoplatform/weapp/commit', - 'router_path' => 'wxoplatform/weapp_version', - 'view_path' => 'wxoplatform/weapp_version', - 'methods' => 'get', - 'sort' => '99', + 'menu_name' => '同步', + 'menu_key' => 'commit_oplatform_weapp_version', + 'menu_short_name' => '同步', + 'menu_type' => '2', + 'icon' => '', + 'api_url' => 'wxoplatform/weapp/version/commit', + 'router_path' => '', + 'view_path' => '', + 'methods' => 'post', + 'sort' => '100', 'status' => '1', 'is_show' => '1', - 'children' => [ - [ - 'menu_name' => '同步', - 'menu_key' => 'commit_oplatform_weapp_version', - 'menu_short_name' => '同步', - 'menu_type' => '2', - 'icon' => '', - 'api_url' => 'wxoplatform/weapp/version/commit', - 'router_path' => '', - 'view_path' => '', - 'methods' => 'post', - 'sort' => '100', - 'status' => '1', - 'is_show' => '1', - ] - ] - ], + ] ] ], [ @@ -479,7 +447,7 @@ return [ 'menu_key' => 'attachment', 'menu_short_name' => '素材管理', 'menu_type' => '1', - 'icon' => 'iconfont iconsucaiguanli1', + 'icon' => 'iconfont iconsucaiguanlic', 'api_url' => 'sys/attachment', 'router_path' => 'setting/attachment', 'view_path' => 'tools/attachment', @@ -579,7 +547,7 @@ return [ 'menu_key' => 'map_setting', 'menu_short_name' => '地图设置', 'menu_type' => '1', - 'icon' => 'iconfont iconditu2', + 'icon' => 'iconfont iconditushezhic', 'api_url' => 'sys/config/map', 'router_path' => 'setting/map', 'view_path' => 'setting/map', @@ -609,7 +577,7 @@ return [ 'menu_key' => 'layout_setting', 'menu_short_name' => '布局设置', 'menu_type' => '1', - 'icon' => 'iconfont iconbujushezhi', + 'icon' => 'iconfont iconbujushezhic', 'api_url' => 'sys/config/layout', 'router_path' => 'setting/layout', 'view_path' => 'setting/layout', @@ -641,212 +609,180 @@ return [ 'menu_key' => 'site_manage', 'menu_short_name' => '站点', 'parent_key' => '', - 'menu_type' => '0', - 'icon' => 'iconfont iconzhandianguanli', + 'menu_type' => '1', + 'icon' => 'iconfont iconFramec-4', 'api_url' => '', - 'router_path' => '', - 'view_path' => '', + 'router_path' => 'site/manage', + 'view_path' => 'site/manage', 'methods' => '', 'sort' => '80', 'status' => '1', 'is_show' => '1', 'children' => [ [ - 'menu_name' => '站点列表', - 'menu_key' => 'site_list', - 'menu_short_name' => '站点列表', - 'menu_type' => '1', - 'icon' => 'iconfont iconzhandianliebiao', + 'menu_name' => '添加站点', + 'menu_key' => 'add_site', + 'menu_short_name' => '添加站点', + 'menu_type' => '2', + 'icon' => '', 'api_url' => 'site/site', - 'router_path' => 'site/list', - 'view_path' => 'site/list', - 'methods' => 'get', + 'router_path' => '', + 'view_path' => '', + 'methods' => 'post', 'sort' => '100', 'status' => '1', 'is_show' => '1', - 'children' => [ - [ - 'menu_name' => '添加站点', - 'menu_key' => 'add_site', - 'menu_short_name' => '添加站点', - 'menu_type' => '2', - 'icon' => '', - 'api_url' => 'site/site', - 'router_path' => '', - 'view_path' => '', - 'methods' => 'post', - 'sort' => '100', - 'status' => '1', - 'is_show' => '1', - ], - [ - 'menu_name' => '编辑站点', - 'menu_key' => 'edit_site', - 'menu_short_name' => '编辑站点', - 'menu_type' => '2', - 'icon' => '', - 'api_url' => 'site/site/', - 'router_path' => '', - 'view_path' => '', - 'methods' => 'put', - 'sort' => '100', - 'status' => '1', - 'is_show' => '1', - ], - [ - 'menu_name' => '删除站点', - 'menu_key' => 'delete_site', - 'menu_short_name' => '删除站点', - 'menu_type' => '2', - 'icon' => '', - 'api_url' => 'site/site/', - 'router_path' => '', - 'view_path' => '', - 'methods' => 'delete', - 'sort' => '100', - 'status' => '1', - 'is_show' => '1', - ], - [ - 'menu_name' => '关闭站点', - 'menu_key' => 'close_site', - 'menu_short_name' => '关闭站点', - 'menu_type' => '2', - 'icon' => '', - 'api_url' => 'site/closesite/', - 'router_path' => '', - 'view_path' => '', - 'methods' => 'put', - 'sort' => '100', - 'status' => '1', - 'is_show' => '1', - ], - [ - 'menu_name' => '开启站点', - 'menu_key' => 'open_site', - 'menu_short_name' => '开启站点', - 'menu_type' => '2', - 'icon' => '', - 'api_url' => 'site/opensite/', - 'router_path' => '', - 'view_path' => '', - 'methods' => 'put', - 'sort' => '100', - 'status' => '1', - 'is_show' => '1', - ], - ], ], [ - 'menu_name' => '站点详情', - 'menu_key' => 'site_info', - 'menu_short_name' => '站点详情', - 'menu_type' => '1', + 'menu_name' => '编辑站点', + 'menu_key' => 'edit_site', + 'menu_short_name' => '编辑站点', + 'menu_type' => '2', 'icon' => '', - 'api_url' => 'site/site/', - 'router_path' => 'site/info', - 'view_path' => 'site/info', - 'methods' => 'get', - 'sort' => '90', - 'status' => '1', - 'is_show' => '0', - ], - [ - 'menu_name' => '用户详情', - 'menu_key' => 'site_user_info', - 'menu_short_name' => '用户详情', - 'menu_type' => '1', - 'icon' => 'element OfficeBuilding', - 'api_url' => 'user/user/', - 'router_path' => 'site/user_info', - 'view_path' => 'site/user_info', - 'methods' => 'get', - 'sort' => '80', - 'status' => '1', - 'is_show' => '0', - ], - [ - 'menu_name' => '站点套餐', - 'menu_key' => 'site_group', - 'menu_short_name' => '站点套餐', - 'menu_type' => '1', - 'icon' => 'iconfont iconzhandiantaocan', - 'api_url' => 'site/group', - 'router_path' => 'site/group', - 'view_path' => 'site/group', - 'methods' => 'get', - 'sort' => '80', + 'api_url' => 'site/site/', + 'router_path' => '', + 'view_path' => '', + 'methods' => 'put', + 'sort' => '100', 'status' => '1', 'is_show' => '1', - 'children' => [ - [ - 'menu_name' => '删除站点套餐', - 'menu_key' => 'delete_site_group', - 'menu_short_name' => '删除站点套餐', - 'menu_type' => '2', - 'icon' => '', - 'api_url' => 'site/group/', - 'router_path' => '', - 'view_path' => '', - 'methods' => 'delete', - 'sort' => '100', - 'status' => '1', - 'is_show' => '1', - ] - ] ], [ - 'menu_name' => '站点套餐编辑', - 'menu_key' => 'site_group_edit', - 'menu_short_name' => '站点套餐编辑', - 'menu_type' => '1', - 'icon' => 'element PriceTag', - 'api_url' => '', - 'router_path' => 'site/group_edit', - 'view_path' => 'site/group_edit', - 'methods' => '', - 'sort' => '70', + 'menu_name' => '删除站点', + 'menu_key' => 'delete_site', + 'menu_short_name' => '删除站点', + 'menu_type' => '2', + 'icon' => '', + 'api_url' => 'site/site/', + 'router_path' => '', + 'view_path' => '', + 'methods' => 'delete', + 'sort' => '100', 'status' => '1', - 'is_show' => '0', - 'children' => [ - [ - 'menu_name' => '添加站点套餐', - 'menu_key' => 'add_site_group', - 'menu_short_name' => '添加站点套餐', - 'menu_type' => '2', - 'icon' => '', - 'api_url' => 'site/group', - 'router_path' => '', - 'view_path' => '', - 'methods' => 'post', - 'sort' => '100', - 'status' => '1', - 'is_show' => '1', - ], - [ - 'menu_name' => '编辑站点套餐', - 'menu_key' => 'edit_site_group', - 'menu_short_name' => '编辑站点套餐', - 'menu_type' => '2', - 'icon' => '', - 'api_url' => 'site/group/', - 'router_path' => '', - 'view_path' => '', - 'methods' => 'put', - 'sort' => '100', - 'status' => '1', - 'is_show' => '1', - ] - ] + 'is_show' => '1', + ], + [ + 'menu_name' => '关闭站点', + 'menu_key' => 'close_site', + 'menu_short_name' => '关闭站点', + 'menu_type' => '2', + 'icon' => '', + 'api_url' => 'site/closesite/', + 'router_path' => '', + 'view_path' => '', + 'methods' => 'put', + 'sort' => '100', + 'status' => '1', + 'is_show' => '1', + ], + [ + 'menu_name' => '开启站点', + 'menu_key' => 'open_site', + 'menu_short_name' => '开启站点', + 'menu_type' => '2', + 'icon' => '', + 'api_url' => 'site/opensite/', + 'router_path' => '', + 'view_path' => '', + 'methods' => 'put', + 'sort' => '100', + 'status' => '1', + 'is_show' => '1', + ], + [ + 'menu_name' => '删除站点套餐', + 'menu_key' => 'delete_site_group', + 'menu_short_name' => '删除站点套餐', + 'menu_type' => '2', + 'icon' => '', + 'api_url' => 'site/group/', + 'router_path' => '', + 'view_path' => '', + 'methods' => 'delete', + 'sort' => '100', + 'status' => '1', + 'is_show' => '1', ], ], ], + [ + 'menu_name' => '站点详情', + 'menu_key' => 'site_info', + 'menu_short_name' => '站点详情', + 'menu_type' => '1', + 'icon' => '', + 'api_url' => 'site/site/', + 'router_path' => 'site/info', + 'view_path' => 'site/info', + 'methods' => 'get', + 'sort' => '90', + 'status' => '1', + 'is_show' => '0', + ], + [ + 'menu_name' => '用户详情', + 'menu_key' => 'site_user_info', + 'menu_short_name' => '用户详情', + 'menu_type' => '1', + 'icon' => 'element OfficeBuilding', + 'api_url' => 'user/user/', + 'router_path' => 'site/user_info', + 'view_path' => 'site/user_info', + 'methods' => 'get', + 'sort' => '80', + 'status' => '1', + 'is_show' => '0', + ], + [ + 'menu_name' => '站点套餐编辑', + 'menu_key' => 'site_group_edit', + 'menu_short_name' => '站点套餐编辑', + 'menu_type' => '1', + 'icon' => 'element PriceTag', + 'api_url' => '', + 'router_path' => 'site/group_edit', + 'view_path' => 'site/group_edit', + 'methods' => '', + 'sort' => '70', + 'status' => '1', + 'is_show' => '0', + 'children' => [ + [ + 'menu_name' => '添加站点套餐', + 'menu_key' => 'add_site_group', + 'menu_short_name' => '添加站点套餐', + 'menu_type' => '2', + 'icon' => '', + 'api_url' => 'site/group', + 'router_path' => '', + 'view_path' => '', + 'methods' => 'post', + 'sort' => '100', + 'status' => '1', + 'is_show' => '1', + ], + [ + 'menu_name' => '编辑站点套餐', + 'menu_key' => 'edit_site_group', + 'menu_short_name' => '编辑站点套餐', + 'menu_type' => '2', + 'icon' => '', + 'api_url' => 'site/group/', + 'router_path' => '', + 'view_path' => '', + 'methods' => 'put', + 'sort' => '100', + 'status' => '1', + 'is_show' => '1', + ] + ] + ], [ 'menu_name' => '用户管理', 'menu_key' => 'site_user_list', 'menu_short_name' => '用户', 'menu_type' => '1', - 'icon' => 'iconfont iconyonghu1', + 'icon' => 'iconfont iconyonghu11', 'api_url' => 'user/user', 'router_path' => 'site/user', 'view_path' => 'site/user', @@ -984,12 +920,12 @@ return [ ] ], [ - 'menu_name' => '应用市场', + 'menu_name' => '应用管理', 'menu_key' => 'app_store', 'menu_short_name' => '应用', 'parent_key' => '', 'menu_type' => '1', - 'icon' => 'iconfont iconyingyong2', + 'icon' => 'iconfont iconFramec-5', 'api_url' => 'addon/local', 'router_path' => 'app_manage/app_store', 'view_path' => 'index/store', @@ -1057,7 +993,7 @@ return [ [ 'menu_name' => '云编译', 'menu_key' => 'cloud_build', - 'menu_short_name' => '云编译', + 'menu_short_name' => '云编译按钮', 'menu_type' => '2', 'icon' => '', 'api_url' => 'niucloud/build', @@ -1085,98 +1021,232 @@ return [ ] ], [ - 'menu_name' => '开发管理', - 'menu_key' => 'app_manage_tool', - 'menu_short_name' => '开发', + 'menu_name' => '云编译', + 'menu_key' => 'cloud_compile', + 'menu_short_name' => '云编译', 'menu_type' => '1', - 'icon' => 'iconfont icona-kaifa1', + 'icon' => 'iconfont iconyunbianyi', 'api_url' => '', - 'router_path' => 'app_manage/tools', - 'view_path' => 'index/tools', - 'methods' => 'get', - 'sort' => '77', + 'router_path' => 'tools/cloud_compile', + 'view_path' => 'tools/cloud_compile', + 'methods' => 'post', + 'sort' => '0', 'status' => '1', 'is_show' => '1', ], [ - 'menu_name' => '工具管理', + 'menu_name' => '应用开发', 'menu_key' => 'tool', - 'menu_short_name' => '工具管理', + 'menu_short_name' => '开发', 'parent_key' => '', 'menu_type' => '0', - 'icon' => 'element Edit', + 'icon' => 'iconfont iconFramec-3', 'api_url' => '', 'router_path' => '', 'view_path' => '', 'methods' => '', 'sort' => '76', 'status' => '1', - 'is_show' => '0', + 'is_show' => '1', 'children' => [ [ 'menu_name' => '插件开发', - 'menu_key' => 'addon_develop', + 'menu_key' => 'addon_expolit', 'menu_short_name' => '插件开发', - 'menu_type' => '1', - 'icon' => 'iconfont iconchajiankaifa1', + 'menu_type' => '0', + 'icon' => 'iconfont iconchajiankaifa11', 'api_url' => '', - 'router_path' => 'tools/addon', - 'view_path' => 'tools/addon/index', - 'methods' => '', - 'sort' => '110', + 'router_path' => 'tools/addon/expolit', + 'view_path' => 'tools/addon/expolit', + 'methods' => 'get', + 'sort' => '108', 'status' => '1', 'is_show' => '1', 'children' => [ + [ - 'menu_name' => '删除插件', - 'menu_key' => 'delete_develop_addon', - 'menu_short_name' => '删除插件', - 'menu_type' => '2', - 'icon' => '', - 'api_url' => 'addon/addon_develop/', - 'router_path' => '', - 'view_path' => '', - 'methods' => 'delete', - 'sort' => '100', + 'menu_name' => '开发步骤', + 'menu_key' => 'addon_develop', + 'menu_short_name' => '步骤', + 'menu_type' => '1', + 'icon' => 'iconfont iconchajiankaifa11', + 'api_url' => '', + 'router_path' => 'tools/addon', + 'view_path' => 'tools/addon/index', + 'methods' => '', + 'sort' => '111', 'status' => '1', 'is_show' => '1', ], [ - 'menu_name' => '打包插件', - 'menu_key' => 'build_develop_addon', - 'menu_short_name' => '打包插件', - 'menu_type' => '2', - 'icon' => '', - 'api_url' => 'addon/addon_develop/build/', - 'router_path' => '', - 'view_path' => '', - 'methods' => 'post', - 'sort' => '100', + 'menu_name' => '插件列表', + 'menu_key' => 'addon_list', + 'menu_short_name' => '列表', + 'menu_type' => '1', + 'icon' => 'iconfont iconchajiankaifa11', + 'api_url' => '', + 'router_path' => 'tools/addon/list', + 'view_path' => 'tools/addon/list', + 'methods' => '', + 'sort' => '110', 'status' => '1', 'is_show' => '1', - ] + 'children' => [ + [ + 'menu_name' => '删除插件', + 'menu_key' => 'delete_develop_addon', + 'menu_short_name' => '删除插件', + 'menu_type' => '2', + 'icon' => '', + 'api_url' => 'addon/addon_develop/', + 'router_path' => '', + 'view_path' => '', + 'methods' => 'delete', + 'sort' => '100', + 'status' => '1', + 'is_show' => '1', + ], + [ + 'menu_name' => '打包插件', + 'menu_key' => 'build_develop_addon', + 'menu_short_name' => '打包插件', + 'menu_type' => '2', + 'icon' => '', + 'api_url' => 'addon/addon_develop/build/', + 'router_path' => '', + 'view_path' => '', + 'methods' => 'post', + 'sort' => '100', + 'status' => '1', + 'is_show' => '1', + ] + ] + ], + [ + 'menu_name' => '代码生成', + 'menu_key' => 'code', + 'menu_short_name' => '代码生成', + 'menu_type' => '1', + 'icon' => 'iconfont icondaimashengcheng11', + 'api_url' => 'generator/generator', + 'router_path' => 'tools/code', + 'view_path' => 'tools/code/index', + 'methods' => 'get', + 'sort' => '109', + 'status' => '1', + 'is_show' => '1', + ], + [ + 'menu_name' => '生成列表', + 'menu_key' => 'code_list', + 'menu_short_name' => '生成列表', + 'menu_type' => '1', + 'icon' => 'iconfont icondaimashengcheng11', + 'api_url' => 'generator/generator', + 'router_path' => 'tools/code/list', + 'view_path' => 'tools/code/list', + 'methods' => 'get', + 'sort' => '108', + 'status' => '1', + 'is_show' => '1', + ], + + [ + 'menu_name' => '数据字典', + 'menu_key' => 'sys_dict_dict_dict_list', + 'menu_short_name' => '数据字典', + 'menu_type' => '1', + 'icon' => 'iconfont iconshujuzidian1', + 'api_url' => 'dict/post/post', + 'router_path' => 'tools/list', + 'view_path' => 'dict/list', + 'methods' => 'get', + 'sort' => '107', + 'status' => '1', + 'is_show' => '1', + 'children' => [ + [ + 'menu_name' => '数据字典添加', + 'menu_key' => 'sys_dict_dict_dict_add', + 'menu_short_name' => '数据字典添加', + 'menu_type' => '2', + 'icon' => '', + 'api_url' => 'dict', + 'router_path' => 'edit', + 'view_path' => 'dict/edit', + 'methods' => 'post', + 'sort' => '4', + 'status' => '1', + 'is_show' => '1', + ], + [ + 'menu_name' => '编辑', + 'menu_key' => 'sys_dict_dict_dict_edit', + 'menu_short_name' => '编辑', + 'menu_type' => '2', + 'icon' => '', + 'api_url' => 'dict/', + 'router_path' => 'edit', + 'view_path' => 'dict/edit', + 'methods' => 'put', + 'sort' => '3', + 'status' => '1', + 'is_show' => '1', + ], + [ + 'menu_name' => '删除', + 'menu_key' => 'sys_dict_dict_dict_delete', + 'menu_short_name' => '删除', + 'menu_type' => '2', + 'icon' => '', + 'api_url' => 'dict/', + 'router_path' => '', + 'view_path' => '', + 'methods' => 'delete', + 'sort' => '2', + 'status' => '1', + 'is_show' => '1', + ], + ], + ], + [ + 'menu_name' => '开发者key', + 'menu_key' => 'developer_token', + 'menu_short_name' => '开发者key', + 'menu_type' => '1', + 'icon' => 'iconfont iconkaifazhekry', + 'api_url' => 'sys/config/developer_token', + 'router_path' => 'tools/developer_token', + 'view_path' => 'setting/developer_token', + 'methods' => 'get', + 'sort' => '97', + 'status' => '1', + 'is_show' => '1', + 'children' => [ + [ + 'menu_name' => '保存', + 'menu_key' => 'save_developer_token', + 'menu_short_name' => '同步', + 'menu_type' => '2', + 'icon' => '', + 'api_url' => 'sys/config/developer_token', + 'router_path' => '', + 'view_path' => '', + 'methods' => 'post', + 'sort' => '100', + 'status' => '1', + 'is_show' => '1', + ] + ] + ], ] ], - [ - 'menu_name' => '代码生成', - 'menu_key' => 'code', - 'menu_short_name' => '代码生成', - 'menu_type' => '1', - 'icon' => 'iconfont icondaimashengcheng1', - 'api_url' => 'generator/generator', - 'router_path' => 'tools/code', - 'view_path' => 'tools/code/index', - 'methods' => 'get', - 'sort' => '109', - 'status' => '1', - 'is_show' => '1', - ], [ 'menu_name' => '更新缓存', 'menu_key' => 'update_cache', 'menu_short_name' => '更新缓存', 'menu_type' => '1', - 'icon' => 'nc-iconfont nc-icon-qingliV6xx', + 'icon' => 'iconfont icongengxinhuancun2', 'api_url' => 'sys/schema/clear', 'router_path' => 'tools/update_cache', 'view_path' => 'tools/updatecache', @@ -1301,84 +1371,12 @@ return [ ], ] ], - [ - 'menu_name' => '数据字典', - 'menu_key' => 'sys_dict_dict_dict_list', - 'menu_short_name' => '数据字典', - 'menu_type' => '1', - 'icon' => 'iconfont iconshujuzidian', - 'api_url' => 'dict/post/post', - 'router_path' => 'tools/list', - 'view_path' => 'dict/list', - 'methods' => 'get', - 'sort' => '107', - 'status' => '1', - 'is_show' => '1', - 'children' => [ - [ - 'menu_name' => '数据字典添加', - 'menu_key' => 'sys_dict_dict_dict_add', - 'menu_short_name' => '数据字典添加', - 'menu_type' => '2', - 'icon' => '', - 'api_url' => 'dict', - 'router_path' => 'edit', - 'view_path' => 'dict/edit', - 'methods' => 'post', - 'sort' => '4', - 'status' => '1', - 'is_show' => '1', - ], - [ - 'menu_name' => '编辑', - 'menu_key' => 'sys_dict_dict_dict_edit', - 'menu_short_name' => '编辑', - 'menu_type' => '2', - 'icon' => '', - 'api_url' => 'dict/', - 'router_path' => 'edit', - 'view_path' => 'dict/edit', - 'methods' => 'put', - 'sort' => '3', - 'status' => '1', - 'is_show' => '1', - ], - [ - 'menu_name' => '删除', - 'menu_key' => 'sys_dict_dict_dict_delete', - 'menu_short_name' => '删除', - 'menu_type' => '2', - 'icon' => '', - 'api_url' => 'dict/', - 'router_path' => '', - 'view_path' => '', - 'methods' => 'delete', - 'sort' => '2', - 'status' => '1', - 'is_show' => '1', - ], - ], - ], - [ - 'menu_name' => '环境检测', - 'menu_key' => 'tools_check_environment', - 'menu_short_name' => '环境检测', - 'menu_type' => '1', - 'icon' => 'iconfont iconhuanjingjiance1', - 'api_url' => '', - 'router_path' => 'tools/detection', - 'view_path' => 'tools/detection', - 'methods' => '', - 'sort' => '106', - 'status' => '1', - 'is_show' => '1', - ], [ 'menu_name' => '平台菜单', 'menu_key' => 'platform_menu', 'menu_short_name' => '平台菜单', 'menu_type' => '1', - 'icon' => 'iconfont iconpingtaicaidan', + 'icon' => 'iconfont iconpingtaicaidan1', 'api_url' => 'sys/menu', 'router_path' => 'tools/admin_menu', 'view_path' => 'auth/menu', @@ -1450,7 +1448,7 @@ return [ 'menu_key' => 'site_menu', 'menu_short_name' => '站点菜单', 'menu_type' => '1', - 'icon' => 'iconfont iconzhandiancaidan', + 'icon' => 'iconfont iconzhandiancaidan1', 'api_url' => 'sys/menu', 'router_path' => 'tools/site_menu', 'view_path' => 'auth/site_menu', @@ -1522,7 +1520,7 @@ return [ 'menu_key' => 'tools_schedule', 'menu_short_name' => '计划任务', 'menu_type' => '1', - 'icon' => 'iconfont iconjihuarenwu1', + 'icon' => 'iconfont iconjihuarenwu11', 'api_url' => 'sys/schedule/list', 'router_path' => 'tools/schedule', 'view_path' => 'tools/schedule', @@ -1589,6 +1587,20 @@ return [ ], ], ], + [ + 'menu_name' => '环境检测', + 'menu_key' => 'tools_check_environment', + 'menu_short_name' => '环境检测', + 'menu_type' => '1', + 'icon' => 'iconfont iconhuanjingjiance11', + 'api_url' => '', + 'router_path' => 'tools/detection', + 'view_path' => 'tools/detection', + 'methods' => '', + 'sort' => '102', + 'status' => '1', + 'is_show' => '1', + ], [ 'menu_name' => '执行日志', 'menu_key' => 'tools_schedule_log', @@ -1603,17 +1615,61 @@ return [ 'status' => '1', 'is_show' => '0' ], + [ + 'menu_name' => '备份升级', + 'menu_key' => 'backup_upgrade', + 'menu_short_name' => '备份升级', + 'menu_type' => '1', + 'icon' => 'iconfont iconbeifenjilu', + 'api_url' => '', + 'router_path' => 'tools/backup_upgrade', + 'view_path' => 'tools/backup_upgrade', + 'methods' => 'get', + 'sort' => '99', + 'status' => '1', + 'is_show' => '1', + 'children' => [ + [ + 'menu_name' => '升级记录', + 'menu_key' => 'upgrade_records', + 'menu_short_name' => '升级记录', + 'menu_type' => '1', + 'icon' => 'iconfont iconshengjijilu1', + 'api_url' => 'upgrade/records', + 'router_path' => 'tools/upgrade_records', + 'view_path' => 'tools/upgrade_records', + 'methods' => 'post', + 'sort' => '100', + 'status' => '1', + 'is_show' => '1', + ], + [ + 'menu_name' => '备份记录', + 'menu_key' => 'backup_records', + 'menu_short_name' => '备份记录', + 'menu_type' => '1', + 'icon' => 'iconfont iconbeifenjilu', + 'api_url' => 'backup/records', + 'router_path' => 'tools/backup_records', + 'view_path' => 'tools/backup_records', + 'methods' => 'post', + 'sort' => '99', + 'status' => '1', + 'is_show' => '1', + ], + ] + ], [ 'menu_name' => '授权信息', 'menu_key' => 'app_auth', 'menu_short_name' => '授权信息', 'menu_type' => '1', - 'icon' => 'iconfont iconshouquanxinxi', + 'icon' => 'iconfont iconshouquanxinxi1', 'api_url' => '', 'router_path' => 'tools/authorize', 'view_path' => 'app/authorize', 'methods' => '', - 'sort' => '102', + 'sort' => '98', 'status' => '1', 'is_show' => '1', 'children' => [ @@ -1638,86 +1694,14 @@ return [ 'menu_key' => 'system_upgrade', 'menu_short_name' => '系统更新', 'menu_type' => '1', - 'icon' => 'iconfont iconxitonggengxin', + 'icon' => 'iconfont iconxitonggengxin1', 'api_url' => '', 'router_path' => 'tools/upgrade', 'view_path' => 'app/upgrade', 'methods' => '', - 'sort' => '101', - 'status' => '1', - 'is_show' => '1', - ], - [ - 'menu_name' => '升级记录', - 'menu_key' => 'upgrade_records', - 'menu_short_name' => '升级记录', - 'menu_type' => '1', - 'icon' => 'iconfont iconshengjijilu', - 'api_url' => 'upgrade/records', - 'router_path' => 'tools/upgrade_records', - 'view_path' => 'tools/upgrade_records', - 'methods' => 'post', - 'sort' => '100', - 'status' => '1', - 'is_show' => '1', - ], - [ - 'menu_name' => '备份记录', - 'menu_key' => 'backup_records', - 'menu_short_name' => '备份记录', - 'menu_type' => '1', - 'icon' => 'iconfont iconbeifenjiluV6xx', - 'api_url' => 'backup/records', - 'router_path' => 'tools/backup_records', - 'view_path' => 'tools/backup_records', - 'methods' => 'post', - 'sort' => '99', - 'status' => '1', - 'is_show' => '1', - ], - [ - 'menu_name' => '云编译', - 'menu_key' => 'cloud_compile', - 'menu_short_name' => '云编译', - 'menu_type' => '1', - 'icon' => 'iconfont iconyun2', - 'api_url' => '', - 'router_path' => 'tools/cloud_compile', - 'view_path' => 'tools/cloud_compile', - 'methods' => 'post', - 'sort' => '98', - 'status' => '1', - 'is_show' => '1', - ], - [ - 'menu_name' => '开发者key', - 'menu_key' => 'developer_token', - 'menu_short_name' => '开发者key', - 'menu_type' => '1', - 'icon' => 'iconfont iconkaifazhekey', - 'api_url' => 'sys/config/developer_token', - 'router_path' => 'tools/developer_token', - 'view_path' => 'setting/developer_token', - 'methods' => 'get', 'sort' => '97', 'status' => '1', 'is_show' => '1', - 'children' => [ - [ - 'menu_name' => '保存', - 'menu_key' => 'save_developer_token', - 'menu_short_name' => '同步', - 'menu_type' => '2', - 'icon' => '', - 'api_url' => 'sys/config/developer_token', - 'router_path' => '', - 'view_path' => '', - 'methods' => 'post', - 'sort' => '100', - 'status' => '1', - 'is_show' => '1', - ] - ] ], ], ], diff --git a/niucloud/app/dict/menu/site.php b/niucloud/app/dict/menu/site.php index 183c16bca..0f6e6a7ee 100644 --- a/niucloud/app/dict/menu/site.php +++ b/niucloud/app/dict/menu/site.php @@ -2199,6 +2199,35 @@ return [ ] ] ], + [ + 'menu_name' => '牛云短信配置', + 'menu_key' => 'niu_sms_setting', + 'menu_short_name' => '牛云设置', + 'menu_type' => '1', + 'icon' => '', + 'api_url' => '', + 'router_path' => 'setting/niusms/setting', + 'view_path' => 'setting/sms_niu', + 'methods' => 'get', + 'sort' => '12', + 'status' => '1', + 'is_show' => '0', + 'children' => [] + ], + [ + 'menu_name' => '订单结果页', + 'menu_key' => 'sms_niu_pay_result', + 'menu_short_name' => '订单结果页', + 'menu_type' => '1', + 'icon' => '', + 'api_url' => '', + 'router_path' => 'setting/sms/pay', + 'view_path' => 'setting/sms_niu_pay_result', + 'methods' => 'get', + 'sort' => '12', + 'status' => '1', + 'is_show' => '0', + ], [ 'menu_name' => '发送记录', 'menu_key' => 'sms_notice_records', diff --git a/niucloud/app/dict/notice/NoticeDict.php b/niucloud/app/dict/notice/NoticeDict.php index eaf0a5a0f..1337d5f39 100644 --- a/niucloud/app/dict/notice/NoticeDict.php +++ b/niucloud/app/dict/notice/NoticeDict.php @@ -11,6 +11,8 @@ namespace app\dict\notice; +use app\dict\sys\ConfigKeyDict; +use app\service\core\sys\CoreConfigService; use core\dict\DictLoader; /** @@ -24,14 +26,23 @@ class NoticeDict * 获取消息 * @return array */ - public static function getNotice(string $key = '') + public static function getNotice(string $key = '',$sms_type = '') { + $site_id = (int)request()->header('site_id') ?? 0; + if (empty($sms_type)){ + $sms_type = (new CoreConfigService())->getConfigValue($site_id, ConfigKeyDict::SMS)['default'] ?? ""; + } $addon_load = new DictLoader('Notice'); $notice = $addon_load->load(['type' => 'notice']); $notice_type = NoticeTypeDict::getType(); foreach ($notice_type as $k => $v) { $var_name = $k . '_notice'; $$var_name = $addon_load->load(['type' => $k]); + foreach ($$var_name as &$vv) { + if (isset($vv['is_need_closure_content']) && $vv['is_need_closure_content'] == 1 && isset($vv['content'])) { + $vv['content'] = $vv['content'](['site_id' => $site_id, 'sms_type' => $sms_type]); + } + } } foreach ($notice as $k => $v) { @@ -51,4 +62,62 @@ class NoticeDict return $notice; } + /** + * 获取消息模版包含插件名称 + * @return array + */ + public static function getNoticeWithAddon(string $key = '',$sms_type = '') + { + $site_id = (int)request()->header('site_id') ?? 0; + if (empty($sms_type)) { + $sms_type = (new CoreConfigService())->getConfigValue($site_id, ConfigKeyDict::SMS)['default'] ?? ""; + } + //获取模版列表 + $addon_load = new DictLoader('Notice'); + $notice_template_list = $addon_load->load(['type' => 'notice', 'with_addon' => 1]); + + //获取针对性的详细内容 例如 注册的 短信通知的信息 / 微信通知的信息 + $notice_type_list = NoticeTypeDict::getType(); + $template_type_desc_list = []; + foreach ($notice_type_list as $notice_type => $v) { + $temp = $addon_load->load(['type' => $notice_type, 'with_addon' => 1]); + if (!isset($template_type_desc_list[$notice_type . '_notice'])) { + $template_type_desc_list[$notice_type . '_notice'] = []; + } + foreach ($temp as &$tmv) { + foreach ($tmv as &$tmcv) { + if (isset($tmcv['is_need_closure_content']) && $tmcv['is_need_closure_content'] == 1 && isset($tmcv['content'])) { + $tmcv['content'] = $tmcv['content'](['site_id' => $site_id, 'sms_type' => $sms_type]); + } + } + } + $template_type_desc_list[$notice_type . '_notice'] = empty($template_type_desc_list[$notice_type . '_notice']) ? $temp : array_merge($template_type_desc_list[$notice_type . '_notice'], $temp); + } + + //组合数据 + foreach ($notice_template_list as $addon => $item) { + $keys = array_keys($item); + if ($key && !in_array($key, $keys)) { + unset($notice_template_list[$addon]); + } + foreach ($item as $template_key => $value) { + if ($key && $template_key != $key) { + unset($notice_template_list[$addon][$template_key]); + continue; + } + $support_type = []; + foreach ($notice_type_list as $notice_type => $notice_type_name) { + $temp_arr = $template_type_desc_list[$notice_type . "_notice"][$addon] ?? []; + $template_keys = array_keys($temp_arr); + if (in_array($template_key, $template_keys)) { + $notice_template_list[$addon][$template_key][$notice_type] = $template_type_desc_list[$notice_type . "_notice"][$addon][$template_key]; + $support_type[] = $notice_type; + } + } + $notice_template_list[$addon][$template_key]['support_type'] = $support_type; + } + } + return $notice_template_list; + } + } \ No newline at end of file diff --git a/niucloud/app/dict/notice/NoticeTypeDict.php b/niucloud/app/dict/notice/NoticeTypeDict.php index 63719e258..fc771c4c4 100644 --- a/niucloud/app/dict/notice/NoticeTypeDict.php +++ b/niucloud/app/dict/notice/NoticeTypeDict.php @@ -20,6 +20,22 @@ class NoticeTypeDict //微信小程序 public const WEAPP = 'weapp'; + public const TEMPLATE_AUDIT_STATUS_NOT_REPORT = -1; + public const TEMPLATE_AUDIT_STATUS_WAIT = 1; + public const TEMPLATE_AUDIT_STATUS_PASS = 2; + public const TEMPLATE_AUDIT_STATUS_REFUSE = 3; + + public const TEMPLATE_TYPE_VERIFY = 1; + public const TEMPLATE_TYPE_INDUSTRY_NOTICE = 2; + public const TEMPLATE_TYPE_SEM = 3; + + + //助通签名审核状态 1- 待审核 2- 通过 3-拒绝 + public const API_AUDIT_RESULT_WAIT = 1; + public const API_AUDIT_RESULT_PASS = 2; + public const API_AUDIT_RESULT_REFUSE = 3; + public const BALANCE_RECHARGE_ADD = 1;//充值余额 + public const BALANCE_RECHARGE_REDUCE = 2;//扣减余额 /** * 获取消息类型 @@ -34,4 +50,144 @@ class NoticeTypeDict ]; } + /** + * 获取模版类型 + * @return array + */ + public static function getTemplateType($type = '') + { + $data = [ + self::TEMPLATE_TYPE_VERIFY => get_lang('dict_sms_api.template_type_verify_code'), + self::TEMPLATE_TYPE_INDUSTRY_NOTICE => get_lang('dict_sms_api.template_type_industry_notice'), + self::TEMPLATE_TYPE_SEM => get_lang('dict_sms_api.template_type_sem'), + ]; + return $type ? $data[$type] : $data; + } + + /** + * 获取消息类型 + * @return array + */ + public static function getTemplateAuditStatus($type = '') + { + $data = [ + self::TEMPLATE_AUDIT_STATUS_NOT_REPORT => get_lang('dict_sms_api.template_status_not_report'), + self::TEMPLATE_AUDIT_STATUS_WAIT => get_lang('dict_sms_api.template_status_wait'), + self::TEMPLATE_AUDIT_STATUS_PASS => get_lang('dict_sms_api.template_status_pass'), + self::TEMPLATE_AUDIT_STATUS_REFUSE => get_lang('dict_sms_api.template_status_refuse'), + ]; + return $type ? $data[$type] : $data; + } + + /** + * 获取消息类型 + * @return array + */ + public static function getSignAuditType($type = '') + { + $data = [ + self::API_AUDIT_RESULT_WAIT => get_lang('dict_sms_api.sign_audit_status_wait'), + self::API_AUDIT_RESULT_PASS => get_lang('dict_sms_api.sign_audit_status_pass'), + self::API_AUDIT_RESULT_REFUSE => get_lang('dict_sms_api.sign_audit_status_refuse'), + ]; + return $type ? $data[$type] : $data; + } + + /** + * 获取消息类型 + * @return array + */ + public static function getBalanceAllocateType($type = '') + { + $data = [ + self::BALANCE_RECHARGE_ADD => get_lang('dict_sms_api.balance_add'), + self::BALANCE_RECHARGE_REDUCE => get_lang('dict_sms_api.balance_reduce'), + ]; + return $type ? $data[$type] : $data; + } + + + public static function getSignSource($source = '') + { + return [ + ['type' => 1, 'name' => '企业名称'], + ['type' => 2, 'name' => '事业单位'], + ['type' => 3, 'name' => '商标'], + ['type' => 4, 'name' => 'APP'], + ['type' => 5, 'name' => '小程序'], + ]; + } + + public static function getSignType($type = '') + { + return [ + ['type' => 0, 'name' => '全称'], + ['type' => 1, 'name' => '简称'], + ]; + } + + public static function getSignDefault($type = '') + { + return [ + ['type' => 0, 'name' => '否'], + ['type' => 1, 'name' => '是'], + ]; + } + + const PARAMS_TYPE_VALID_CODE = 'valid_code'; + const PARAMS_TYPE_MOBILE_NUMBER = 'mobile_number'; + const PARAMS_TYPE_OTHER_NUMBER = 'other_number'; + const PARAMS_TYPE_AMOUNT = 'amount'; + const PARAMS_TYPE_DATE = 'date'; + const PARAMS_TYPE_CHINESE = 'chinese'; + const PARAMS_TYPE_OTHERS = 'others'; + public static function getApiParamsType() + { + return [ + [ + 'name' => '验证码', + 'type' => self::PARAMS_TYPE_VALID_CODE, + 'desc' => '4-6位纯数字', + 'rule' => '/^\d{4,6}$/', + ], + [ + 'name' => '手机号', + 'type' => self::PARAMS_TYPE_MOBILE_NUMBER, + 'desc' => '1-15位纯数字', + 'rule' => '/^\d{1,15}$/', + ], + [ + 'name' => '其他号码', + 'type' => self::PARAMS_TYPE_OTHER_NUMBER, + 'desc' => '1-32位字母+数字组合', + 'rule'=>'/^[a-zA-Z0-9]{1,32}$/' + ], + [ + 'name' => '金额', + 'type' => self::PARAMS_TYPE_AMOUNT, + 'desc' => '支持数字或数字的中文 (壹贰叁肆伍陆柒捌玖拾佰仟万亿 圆元整角分厘毫)', + 'rule' => "/^(?:\d+|(?:[零壹贰叁肆伍陆柒捌玖拾佰仟万亿圆角分厘毫]+|圆|元|整)+)$/u" + ], + [ + 'name' => '日期', + 'type' => self::PARAMS_TYPE_DATE, + 'desc' => '符合时间的表达方式 也支持中文:2019年9月3日16时24分35秒', + 'rule' => '' + ], + [ + 'name' => '中文', + 'type' => self::PARAMS_TYPE_CHINESE, + 'desc' => '1-32中文,支持中文园括号()', + 'rule' => '/^[\p{Han}()()]{1,32}$/u' + ], + [ + 'name' => '其他', + 'type' => self::PARAMS_TYPE_OTHERS, + 'desc' => ' 1-35个中文数字字母组合,支持中文符号和空格', + 'rule' => '/^[\p{Han}\p{N}\p{L}\p{P}\p{S}\s]{1,35}$/u', + ], + ]; + } + + } \ No newline at end of file diff --git a/niucloud/app/dict/notice/notice.php b/niucloud/app/dict/notice/notice.php index d269ea6d1..1c2577416 100644 --- a/niucloud/app/dict/notice/notice.php +++ b/niucloud/app/dict/notice/notice.php @@ -3,7 +3,7 @@ return [ 'verify_code' => [ 'key' => 'verify_code', 'receiver_type' => 0, - 'name' => '手机验证码', + 'name' => '管理端手机验证码', 'title' => '管理端验证码登录', 'async' => false, 'variable' => [ @@ -14,7 +14,7 @@ return [ 'member_verify_code' => [ 'key' => 'member_verify_code', 'receiver_type' => 1, - 'name' => '手机验证码', + 'name' => '客户端手机验证码', 'title' => '前端验证码登录,注册,手机验证', 'async' => false, 'variable' => [ diff --git a/niucloud/app/dict/notice/sms.php b/niucloud/app/dict/notice/sms.php index 80d137450..39367ec2b 100644 --- a/niucloud/app/dict/notice/sms.php +++ b/niucloud/app/dict/notice/sms.php @@ -2,16 +2,20 @@ return [ //手机验证码 'verify_code' => [ + 'is_need_closure_content' => 0, 'content' => '您的手机验证码{code},请不要轻易告诉其他人' ], 'member_verify_code' => [ + 'is_need_closure_content' => 0, 'content' => '您的手机验证码{code},请不要轻易告诉其他人', ], 'recharge_success' => [ + 'is_need_closure_content' => 0, 'content' => '您充值金额¥{price}, 充值后金额¥{balance}', ], // 'member_transfer' => [ +// 'is_need_closure_content' => 0, // 'content' => '你的编号为{transfer_no}的提现申请已通过,您现在可以在提现中点击提现收款了', // ] diff --git a/niucloud/app/dict/schedule/schedule.php b/niucloud/app/dict/schedule/schedule.php index 83640b879..2a8d22691 100644 --- a/niucloud/app/dict/schedule/schedule.php +++ b/niucloud/app/dict/schedule/schedule.php @@ -54,7 +54,9 @@ return [ 'name' => '定时清理升级/备份记录表', 'desc' => '', 'time' => [ - 'type' => 'min', + 'type' => 'day', + 'day' => 1, + 'hour' => 1, 'min' => 1 ], 'class' => 'app\job\upgrade\AutoClearUpgradeRecords', diff --git a/niucloud/app/dict/sys/CloudDict.php b/niucloud/app/dict/sys/CloudDict.php index 86c74d0b0..65676ac3a 100644 --- a/niucloud/app/dict/sys/CloudDict.php +++ b/niucloud/app/dict/sys/CloudDict.php @@ -28,6 +28,8 @@ class CloudDict const APPLET_AUDIT_FAIL = -2; + const APPLET_AUDIT_UNDO = -3; + public static function getAppletUploadStatus($status) { $status_list = [ self::APPLET_UPLOADING => get_lang('dict_cloud_applet.uploading'), @@ -36,6 +38,7 @@ class CloudDict self::APPLET_AUDITING => get_lang('dict_cloud_applet.auditing'), self::APPLET_AUDIT_FAIL => get_lang('dict_cloud_applet.audit_fail'), self::APPLET_PUBLISHED => get_lang('dict_cloud_applet.published'), + self::APPLET_AUDIT_UNDO => get_lang('dict_cloud_applet.undo') ]; return $status_list[$status] ?? ''; } diff --git a/niucloud/app/dict/sys/ConfigKeyDict.php b/niucloud/app/dict/sys/ConfigKeyDict.php index 1558582f1..a58d938b5 100644 --- a/niucloud/app/dict/sys/ConfigKeyDict.php +++ b/niucloud/app/dict/sys/ConfigKeyDict.php @@ -37,4 +37,6 @@ class ConfigKeyDict public const WECHAT_AUTHORIZATION_INFO = 'wechat_authorization_info'; public const WECHAT_TRANSFER_SCENE_CONFIG = 'WECHAT_TRANSFER_SCENE_CONFIG';//微信转账场景配置 + + public const SMS = 'SMS';//短信配置 } diff --git a/niucloud/app/dict/sys/SmsDict.php b/niucloud/app/dict/sys/SmsDict.php index 95f6155ad..f49047a2a 100644 --- a/niucloud/app/dict/sys/SmsDict.php +++ b/niucloud/app/dict/sys/SmsDict.php @@ -20,6 +20,7 @@ class SmsDict { //阿里云短信 public const ALISMS = 'aliyun'; + public const NIUSMS = 'niuyun'; //腾讯云短信 public const TENCENTSMS = 'tencent'; public const SENDING = 'sending'; @@ -39,6 +40,15 @@ class SmsDict public static function getType() { $system = [ + self::NIUSMS => [ + 'name' => '牛云短信', + //配置参数 + 'params' => [], + 'encrypt_params' => [], + 'show_type'=>'view', + 'view' => '/src/app/views/setting/sms_niu.vue', + 'component' => '', + ], self::ALISMS => [ 'name' => '阿里云短信', //配置参数 @@ -48,6 +58,7 @@ class SmsDict 'secret_key' => 'SECRET_KEY' ], 'encrypt_params' => ['secret_key'], + 'show_type'=>'component', 'component' => '/src/app/views/setting/components/sms-ali.vue', ], self::TENCENTSMS => [ @@ -60,6 +71,7 @@ class SmsDict 'secret_key' => 'SECRET_KEY' ], 'encrypt_params' => ['secret_key'], + 'show_type'=>'component', 'component' => '/src/app/views/setting/components/sms-tencent.vue', ], ]; diff --git a/niucloud/app/dict/sys/StorageDict.php b/niucloud/app/dict/sys/StorageDict.php index 106651f13..10b037f1d 100644 --- a/niucloud/app/dict/sys/StorageDict.php +++ b/niucloud/app/dict/sys/StorageDict.php @@ -39,6 +39,7 @@ class StorageDict $system = [ self::LOCAL => [ 'name' => '本地存储', + 'site_name' => '默认存储', //配置参数 'params' => [ ], diff --git a/niucloud/app/dict/sys/UpgradeDict.php b/niucloud/app/dict/sys/UpgradeDict.php index 912fb5b98..3b201a1c4 100644 --- a/niucloud/app/dict/sys/UpgradeDict.php +++ b/niucloud/app/dict/sys/UpgradeDict.php @@ -25,12 +25,15 @@ class UpgradeDict const STATUS_FAIL = 'fail'; // 失败 + const STATUS_CANCEL = 'cancel'; + public static function getStatus($status) { $status_list = [ self::STATUS_READY => get_lang('dict_upgrade.ready'), self::STATUS_COMPLETE => get_lang('dict_upgrade.complete'), self::STATUS_FAIL => get_lang('dict_upgrade.fail'), + self::STATUS_CANCEL => get_lang('dict_upgrade.cancel'), ]; return $status_list[ $status ] ?? ''; } diff --git a/niucloud/app/install/source/database.sql b/niucloud/app/install/source/database.sql index e668ecbda..19ea94fbc 100644 --- a/niucloud/app/install/source/database.sql +++ b/niucloud/app/install/source/database.sql @@ -6,7 +6,7 @@ CREATE TABLE `addon` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', `title` varchar(40) NOT NULL DEFAULT '' COMMENT '插件名称', `icon` varchar(255) NOT NULL DEFAULT '' COMMENT '插件图标', - `key` varchar(20) NOT NULL DEFAULT '' COMMENT '插件标识', + `key` varchar(255) NOT NULL DEFAULT '' COMMENT '插件标识', `desc` text NULL COMMENT '插件描述', `status` tinyint(4) NOT NULL DEFAULT 1 COMMENT '状态', `author` varchar(40) NOT NULL DEFAULT '' COMMENT '作者', @@ -363,6 +363,8 @@ CREATE TABLE `member` ( `district_id` int(11) NOT NULL DEFAULT 0 COMMENT '区县id', `address` varchar(255) NOT NULL DEFAULT '' COMMENT '详细地址', `location` varchar(255) NOT NULL DEFAULT '' COMMENT '定位地址', + `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注', +-- `id_card` varchar(50) NOT NULL DEFAULT '' COMMENT '身份证号', `delete_time` int(11) NOT NULL DEFAULT 0 COMMENT '删除时间', `update_time` int(11) NOT NULL DEFAULT 0 COMMENT '修改时间', PRIMARY KEY (`member_id`) USING BTREE @@ -503,6 +505,27 @@ CREATE TABLE `member_sign` ( ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员签到表' ROW_FORMAT = Dynamic; +DROP TABLE IF EXISTS `niu_sms_template`; +CREATE TABLE `niu_sms_template` ( + `id` INT(11) NOT NULL AUTO_INCREMENT, + `site_id` INT(11) DEFAULT 0 COMMENT '站点ID', + `sms_type` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '短信服务商类型 niuyun-牛云 aliyun-阿里云 tencent-腾讯', + `username` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '子账号名称', + `template_key` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '模版key', + `template_id` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '模版id', + `template_type` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '模版类型', + `template_content` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '模版内容', + `param_json` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '参数变量', + `status` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '上下架状态', + `audit_status` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '报备、审核状态', + `audit_msg` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '审核结果/拒绝原因', + `report_info` TEXT DEFAULT NULL COMMENT '报备、审核信息', + `create_time` INT(11) NOT NULL DEFAULT 0 COMMENT '创建时间', + `update_time` INT(11) NOT NULL DEFAULT 0 COMMENT '修改时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='牛云短信模板表'; + + DROP TABLE IF EXISTS `pay`; CREATE TABLE `pay` ( `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键', @@ -1076,7 +1099,7 @@ CREATE TABLE `sys_upgrade_records` `upgrade_key` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '升级标识', `app_key` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '插件标识', `name` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '升级名称', - `content` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '升级内容', + `content` TEXT DEFAULT NULL COMMENT '升级内容', `prev_version` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '前一版本', `current_version` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '当前版本', `status` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '状态', diff --git a/niucloud/app/job/notice/Notice.php b/niucloud/app/job/notice/Notice.php index 5d7492a38..d0c314b91 100644 --- a/niucloud/app/job/notice/Notice.php +++ b/niucloud/app/job/notice/Notice.php @@ -11,6 +11,8 @@ namespace app\job\notice; +use app\dict\sys\ConfigKeyDict; +use app\service\core\sys\CoreConfigService; use core\base\BaseJob; use core\exception\NoticeException; @@ -20,7 +22,6 @@ use core\exception\NoticeException; class Notice extends BaseJob { - /** * 消费 * @param $site_id @@ -31,11 +32,15 @@ class Notice extends BaseJob */ protected function doJob($site_id, $key, $data, $template) { - //通过业务获取模板变量属于以及发送对象 - $result = event('NoticeData', [ 'site_id' => $site_id, 'key' => $key, 'data' => $data, 'template' => $template ]); - $notice_data = array_values(array_filter($result))[ 0 ] ?? []; - if (empty($notice_data)) throw new NoticeException('NOTICE_TEMPLATE_IS_NOT_EXIST'); - event('Notice', [ 'site_id' => $site_id, 'key' => $key, 'to' => $notice_data[ 'to' ], 'vars' => $notice_data[ 'vars' ], 'template' => $template ]); - return true; + try { + //通过业务获取模板变量属于以及发送对象 + $result = event('NoticeData', ['site_id' => $site_id, 'key' => $key, 'data' => $data, 'template' => $template]); + $notice_data = array_values(array_filter($result))[0] ?? []; + if (empty($notice_data)) throw new NoticeException('NOTICE_TEMPLATE_IS_NOT_EXIST'); + event('Notice', ['site_id' => $site_id, 'key' => $key, 'to' => $notice_data['to'], 'vars' => $notice_data['vars'], 'template' => $template]); + return true; + }catch (\Exception $e){ + throw new \Exception($e->getMessage()); + } } } diff --git a/niucloud/app/lang/zh-cn/api.php b/niucloud/app/lang/zh-cn/api.php index f3286c45b..0377611ae 100644 --- a/niucloud/app/lang/zh-cn/api.php +++ b/niucloud/app/lang/zh-cn/api.php @@ -63,6 +63,8 @@ return [ 'UPGRADE_RECORD_NOT_EXIST' => '升级记录不存在', 'UPGRADE_BACKUP_CODE_NOT_FOUND' => '未找到备份的源码文件', 'UPGRADE_BACKUP_SQL_NOT_FOUND' => '未找到备份的数据库文件', + 'NOT_EXIST_UPGRADE_CONTENT' => '没有获取到可以升级的内容', + 'CLOUD_BUILD_AUTH_CODE_NOT_FOUND' => '请先填写授权码', //登录注册重置账号.... 'LOGIN_SUCCESS' => '登录成功', @@ -71,7 +73,6 @@ return [ 'LOGIN_STATE_ERROR' => '登录状态有误,请重新登录', 'USER_LOCK' => '账号被锁定', 'USER_ERROR' => '账号或密码错误', - 'USER_NOT_EXIST' => '账号不存在', 'NO_SITE_PERMISSION' => '您没有当前站点的访问权限', 'SITE_NOT_EXIST' => '站点不存在', 'LOGOUT' => '登陆退出', @@ -120,7 +121,8 @@ return [ 'BASE_IMAGE_FILE_NOT_EXIST' => 'base图片资源不能为空', 'UPLOAD_TYPE_NOT_SUPPORT' => '不支持的上传类型', 'FILE_ERROR' => '无效的资源', - 'UPLOAD_STORAGE_TYPE_ALL_CLOSE' => '至少要有一个启用的存储方式', + 'UPLOAD_STORAGE_TYPE_ALL_CLOSE' => '【站点端】至少要有一个启用的存储方式', + 'SUPER_UPLOAD_STORAGE_TYPE_ALL_CLOSE' => '【管理端】至少要有一个启用的存储方式', 'STORAGE_NOT_HAS_HTTP_OR_HTTPS' => '空间域名请补全http://或https://', @@ -312,7 +314,7 @@ return [ 'VERIFY_TYPE_ERROR' => '核销类型错误', 'VERIFY_CODE_EXPIRED' => '当前核销码已核销或已失效', 'VERIFIER_NOT_EXIST' => '核销员不存在', - 'VERIFIER_EXIST'=>'核销员已存在', + 'VERIFIER_EXIST' => '核销员已存在', 'VERIFIER_NOT_AUTH' => '该核销员没有权限', //签到相关 @@ -343,6 +345,18 @@ return [ 'WECHAT_EXIST' => '该公众号已经授权给其他站点', 'PLEASE_ADD_FIRST_SITE_GROUP' => '请先添加站点套餐', 'NOT_YET_PRESENT_TEMPLATE_LIBRARY' => '平台尚未上传小程序到模板库', + 'WEAPP_VERSION_NOT_EXIST' => '未获取到小程序版本提交记录', + 'NOT_ALLOWED_CANCEL_AUDIT' => '只有审核中的才可以撤回', - 'PRINTER_NOT_EXIST' => '打印机不存在' + 'PRINTER_NOT_EXIST' => '打印机不存在', + /*******************************************牛云短信 start ********************************************************/ + 'NIU_SMS_ENABLE_FAILED' => '需登录账号并配置签名后才能启用牛云短信', + 'ACCOUNT_ERROR_RELOGIN' => '牛云短信账号异常,请重新登录账号', + 'ACCOUNT_BIND_MOBILE_ERROR' => '手机号错误', + 'TEMPLATE_NOT_SMS_CONTENT' => '当前模版未配置短信内容', + 'TEMPLATE_ERROR' => '短信模版ID错误或审核未通过', + 'TEMPLATE_NOT_REPORT' => '短信模版暂未报备', + 'URL_NOT_FOUND' => '未配置远程服务地址,请在ENV中配置{NIU_SHOP_PREFIX}', + 'SYSTEM_IS_ERROR' => '远程服务器异常,请联系售后人员', + /*******************************************牛云短信 end ********************************************************/ ]; diff --git a/niucloud/app/lang/zh-cn/dict.php b/niucloud/app/lang/zh-cn/dict.php index 8e9a1c283..69c925ee0 100644 --- a/niucloud/app/lang/zh-cn/dict.php +++ b/niucloud/app/lang/zh-cn/dict.php @@ -76,6 +76,26 @@ return [ 'var_balance' => '会员余额', 'var_point' => '会员积分', ], + 'dict_sms_api'=>[ + + 'template_status_not_report'=>'未报备', + 'template_status_wait'=>'待审核', + 'template_status_pass'=>'审核通过', + 'template_status_refuse'=>'审核不通过', + + //验证码-1 行业通知-2 营销推广-3 + 'template_type_verify_code'=>'验证码', + 'template_type_industry_notice'=>'行业通知', + 'template_type_sem'=>'营销推广', + + 'sign_audit_status_wait'=>'待审核', + 'sign_audit_status_pass'=>'审核通过', + 'sign_audit_status_refuse'=>'审核不通过', + + 'balance_add'=>'充值', + 'balance_reduce'=>'扣减' + ], + //上传附件相关 'dict_file' => [ //上传附件类型 @@ -383,7 +403,8 @@ return [ 'auditing' => '审核中', 'audit_success' => '审核通过', 'audit_fail' => '审核失败', - 'published' => '已发布' + 'published' => '已发布', + 'undo' => '已撤回' ], 'dict_wechat_media' => [ 'type_image' => '图片', @@ -412,9 +433,10 @@ return [ 'yilianyun' => '易联云打印机' ], 'dict_upgrade' => [ - 'ready' => '准备执行', + 'ready' => '升级中', 'complete' => '完成', - 'fail' => '失败' + 'fail' => '失败', + 'cancel' => '已取消' ], 'dict_backup' => [ 'ready' => '准备执行', diff --git a/niucloud/app/lang/zh-cn/validate.php b/niucloud/app/lang/zh-cn/validate.php index 6333feb04..a73f6c8c0 100644 --- a/niucloud/app/lang/zh-cn/validate.php +++ b/niucloud/app/lang/zh-cn/validate.php @@ -66,6 +66,7 @@ return [ 'username_max' => '用户名不能超过30个字符', 'mobile_require' => '手机号必须填写', 'mobile_mobile' => '手机号格式错误', + 'mobile_unique' => '手机号已存在', 'sex_bot_exist' => '不存在的性别', 'label_name_require' => '会员标签必须填写', 'birthday_format' => '生日日期格式有误', diff --git a/niucloud/app/listener/notice/Sms.php b/niucloud/app/listener/notice/Sms.php index e8a433eec..e5b71c26c 100644 --- a/niucloud/app/listener/notice/Sms.php +++ b/niucloud/app/listener/notice/Sms.php @@ -13,24 +13,24 @@ class Sms public function handle(array $data) { - $site_id = $data[ 'site_id' ]; - $template = $data[ 'template' ];//模板 - $vars = $data[ 'vars' ];//模板变量 - $key = $data[ 'key' ]; - $to = $data[ 'to' ];//发送对象主题 - $mobile = $to[ 'mobile' ] ?? ''; + $site_id = $data['site_id']; + $template = $data['template'];//模板 + $vars = $data['vars'];//模板变量 + $key = $data['key']; + $to = $data['to'];//发送对象主题 + $mobile = $to['mobile'] ?? ''; //完全信任消息的设置, 不再依赖support_type - if ($template[ 'is_sms' ]) { - $sms_id = $template[ 'sms_id' ];//发送模板id - $content = $template[ 'sms' ][ 'content' ]; - $member_id = $to[ 'member_id' ] ?? 0; - $uid = $to[ 'uid' ] ?? 0; + if ($template['is_sms']) { + $sms_id = $template['sms_id'];//发送模板id + $content = $template['sms']['content']; + $member_id = $to['member_id'] ?? 0; + $uid = $to['uid'] ?? 0; if (!$mobile) { //会员的 if ($member_id > 0) {//查询openid - $info = ( new CoreMemberService() )->getInfoByMemberId($site_id, $member_id); - $mobile = $info[ 'mobile' ] ?? ''; - $nickname = $info[ 'nickname' ] ?? ''; + $info = (new CoreMemberService())->getInfoByMemberId($site_id, $member_id); + $mobile = $info['mobile'] ?? ''; + $nickname = $info['nickname'] ?? ''; } } @@ -49,18 +49,19 @@ class Sms 'content' => $content, 'result' => '' ); + $core_sms_service->send($site_id, $mobile, $vars, $key, $sms_id, $content); - ( new CoreNoticeLogService() )->add($site_id, $log_data); + (new CoreNoticeLogService())->add($site_id, $log_data); } catch (NoticeException $e) { - $log_data[ 'result' ] = $e->getMessage(); - ( new CoreNoticeLogService() )->add($site_id, $log_data); + $log_data['result'] = $e->getMessage(); + (new CoreNoticeLogService())->add($site_id, $log_data); //这儿决定要不要抛出 - if (!$template[ 'async' ]) { + if (!$template['async']) { throw new NoticeException($e->getMessage()); } } } else { - if (!$template[ 'async' ]) { + if (!$template['async']) { throw new NoticeException('NOTICE_NOT_OPEN_SMS'); } } diff --git a/niucloud/app/listener/notice_template/BaseNoticeTemplate.php b/niucloud/app/listener/notice_template/BaseNoticeTemplate.php index f3b4f0c6b..0e7017fc7 100644 --- a/niucloud/app/listener/notice_template/BaseNoticeTemplate.php +++ b/niucloud/app/listener/notice_template/BaseNoticeTemplate.php @@ -5,8 +5,8 @@ namespace app\listener\notice_template; class BaseNoticeTemplate { /** - * @param $vars 模板变量 - * @param $to 发送对象 + * @param $vars `模板变量` + * @param $to `发送对象` * @return array */ public function toReturn($vars, $to) diff --git a/niucloud/app/listener/system/WeappAuthChangeAfter.php b/niucloud/app/listener/system/WeappAuthChangeAfter.php index 2de06cb7f..88e4ab6df 100644 --- a/niucloud/app/listener/system/WeappAuthChangeAfter.php +++ b/niucloud/app/listener/system/WeappAuthChangeAfter.php @@ -27,12 +27,8 @@ class WeappAuthChangeAfter request()->siteId($data['site_id']); $service = new WeappVersionService(); - // 设置隐私协议 - $service->setPrivacySetting(); // 设置服务器域名 $service->setDomain(); - // 提交小程序代码 - $service->siteWeappCommit(); } else if ($data['event'] == 'unauthorized') { // 授权取消 diff --git a/niucloud/app/model/site/Site.php b/niucloud/app/model/site/Site.php index 72a80fb44..b25ef019e 100644 --- a/niucloud/app/model/site/Site.php +++ b/niucloud/app/model/site/Site.php @@ -100,7 +100,7 @@ class Site extends BaseModel public function searchAppAttr($query, $value, $data) { if ($value != '') { - $query->where('app', 'like', '%"' . $value . '"%'); + $query->where('app', 'like', '%"' . $value . '"%')->whereOr('initalled_addon', 'like', '%"' . $value . '"%'); } } diff --git a/niucloud/app/model/site/SiteGroup.php b/niucloud/app/model/site/SiteGroup.php index 6885527cf..75e47a5af 100644 --- a/niucloud/app/model/site/SiteGroup.php +++ b/niucloud/app/model/site/SiteGroup.php @@ -56,6 +56,17 @@ class SiteGroup extends BaseModel return (new Addon())->where([['key', 'in', $data['app']]])->column('title'); } + public function getAppListAttr($value, $data) + { + if (empty($data['app'])) + return []; + $list = (new Addon())->where([['key', 'in', $data['app']]])->column('title,icon'); + foreach ($list as &$item) { + $item['icon'] = is_file($item['icon']) ? image_to_base64($item['icon']) : ''; + } + return $list; + } + /** * 关联插件 * @param $value @@ -68,6 +79,23 @@ class SiteGroup extends BaseModel return []; return (new Addon())->where([['key', 'in', $data['addon']]])->column('title'); } + /** + * 关联插件 + * @param $value + * @param $data + * @return array + */ + public function getAddonListAttr($value, $data) + { + if (empty($data['addon'])) + return []; + + $list = (new Addon())->where([['key', 'in', $data['addon']]])->column('title,icon'); + foreach ($list as &$item) { + $item['icon'] = is_file($item['icon']) ? image_to_base64($item['icon']) : ''; + } + return $list; + } /** * 关键字搜索 diff --git a/niucloud/app/model/sys/NiuSmsTemplate.php b/niucloud/app/model/sys/NiuSmsTemplate.php new file mode 100644 index 000000000..cb42b687e --- /dev/null +++ b/niucloud/app/model/sys/NiuSmsTemplate.php @@ -0,0 +1,49 @@ +hasOne(Site::class, 'site_id', 'site_id'); + } } diff --git a/niucloud/app/model/sys/SysUpgradeRecords.php b/niucloud/app/model/sys/SysUpgradeRecords.php index 312c1bfa7..1a95015fe 100644 --- a/niucloud/app/model/sys/SysUpgradeRecords.php +++ b/niucloud/app/model/sys/SysUpgradeRecords.php @@ -117,4 +117,14 @@ class SysUpgradeRecords extends BaseModel { return $this->hasOne(SysBackupRecords::class, 'backup_key', 'upgrade_key'); } + + public function getContentAttr($value) { + if (!empty($value)) { + try { + return json_decode($value, true); + } catch (\Exception $e) { + } + } + return $value; + } } diff --git a/niucloud/app/service/admin/home/AuthSiteService.php b/niucloud/app/service/admin/home/AuthSiteService.php index 241208c85..478244981 100644 --- a/niucloud/app/service/admin/home/AuthSiteService.php +++ b/niucloud/app/service/admin/home/AuthSiteService.php @@ -69,8 +69,19 @@ class AuthSiteService extends BaseAdminService $condition = [ ['site_id', '<>', request()->defaultSiteId()], ]; + $order = 'create_time desc'; + if (!empty($where['sort'])){ + if($where['sort'] == 'site_id'){ + $order = "{$where['sort']} asc"; + }else{ + $order = "{$where['sort']} desc"; + } + } if (!AuthService::isSuperAdmin()) $condition[] = ['site_id', 'in', $this->getSiteIds()]; - $search_model = $this->model->where($condition)->withSearch([ 'create_time', 'expire_time', 'keywords', 'status', 'group_id', 'app' ], $where)->with(['groupName'])->field($field)->append([ 'status_name' ])->order('create_time desc'); + $search_model = $this->model->where($condition) + ->withSearch([ 'create_time', 'expire_time', 'keywords', 'status', 'group_id', 'app' ], $where) + ->with(['groupName'])->field($field)->append([ 'status_name' ]) + ->order($order); $theme_color = (new ConfigService())->getThemeColor(); diff --git a/niucloud/app/service/admin/notice/NiuSmsService.php b/niucloud/app/service/admin/notice/NiuSmsService.php new file mode 100644 index 000000000..bbc1e3c98 --- /dev/null +++ b/niucloud/app/service/admin/notice/NiuSmsService.php @@ -0,0 +1,631 @@ +template_model = new NiuSmsTemplate(); + $this->niu_service = new CoreNiuSmsService(); + } + + public function enableNiuSms($enable) + { + if ($enable == 1) { + $config = $this->niu_service->getNiuLoginConfig(true); + if (empty($config) || !isset($config[SmsDict::NIUSMS]) || empty($config[SmsDict::NIUSMS]['username']) || empty($config[SmsDict::NIUSMS]['password']) || empty($config[SmsDict::NIUSMS]['signature'])) { + throw new AdminException("NIU_SMS_ENABLE_FAILED"); + } + $this->niu_service->setNiuLoginConfig(['default' => SmsDict::NIUSMS]); + } else { + $this->niu_service->setNiuLoginConfig(['default' => '']); + } + } + + /** + * 获取当前登录的牛云短信账号 + * @return array + */ + public function getConfig() + { + $login_config = $this->niu_service->getNiuLoginConfig(true); + return [ + 'is_login' => empty($login_config[SmsDict::NIUSMS]) ? 0 : 1, + 'username' => $login_config[SmsDict::NIUSMS]['username'] ?? '', + 'is_enable' => (($login_config['default'] ?? '') == SmsDict::NIUSMS) ? 1 : 0, + ]; + } + + /** + * 获取套餐列表 + * @param $params + * @return mixed + */ + public function packageList($params) + { + $res = $this->niu_service->packageList($params); + return $res; + } + + /** + * 发送动态码 + * @param $mobile + * @return mixed + */ + public function sendMobileCode($params) + { + $res = $this->niu_service->sendMobileCode($params); + return $res; + } + + /** + * 发送动态码 + * @param $mobile + * @return mixed + */ + public function captcha() + { + $res = $this->niu_service->captcha(); + return $res; + } + + /** + * 注册牛云短信账号 + * @param $data + * @return mixed + */ + public function registerAccount($data) + { + $res = $this->niu_service->registerAccount($data); + return $res; + } + + /** + * 登录牛云短信账号 + * @param $params + * @return mixed + */ + public function loginAccount($params) + { + $account_info = $this->niu_service->loginAccount($params); + if ($account_info) { + (new CoreNiuSmsService())->setNiuLoginConfig($params); + } + return $account_info; + } + + /** + * 编辑牛云短信账号信息(暂时只有 手机号和默认签名) + * @param $username + * @param $params + * @return mixed + */ + public function editAccount($username, $params) + { + $res = $this->niu_service->editAccount($username, $params); + $this->niu_service->setNiuLoginConfig($params); + return $res; + } + + /** + * 获取牛云短信账号信息 + * @param $username + * @return mixed + */ + public function accountInfo($username) + { + $res = $this->niu_service->accountInfo($username); + return $res; + } + + /** + * 重置转牛云短信账号密码 + * @param $username + * @param $params + * @return mixed + */ + public function resetPassword($username, $params) + { + $account_info = $this->accountInfo($username); + $mobile_arr = explode(",", $account_info['mobiles']); + if (!in_array($params['mobile'], $mobile_arr)) { + throw new ApiException('ACCOUNT_BIND_MOBILE_ERROR'); + } + $res = $this->niu_service->resetPassword($username, $params); + $this->niu_service->setNiuLoginConfig(['username' => $username, 'password' => $res['newPassword']]); + return [ + 'password' => $res['newPassword'], + ]; + } + + /** + * 重置转牛云短信账号密码 + * @param $username + * @param $params + * @return mixed + */ + public function forgetPassword($username, $params) + { + $account_info = $this->accountInfo($username); + $mobile_arr = explode(",", $account_info['mobiles']); + if (!in_array($params['mobile'], $mobile_arr)) { + throw new ApiException('ACCOUNT_BIND_MOBILE_ERROR'); + } + $res = $this->niu_service->resetPassword($username, $params); + $this->niu_service->setNiuLoginConfig(['username' => $username, 'password' => $res['newPassword']]); + return [ + 'password' => $res['newPassword'], + ]; + } + + /** + * 获取牛云短信账号发送短信列表 + * @param $username + * @return array + */ + public function accountSendList($username, $params) + { + $res = $this->niu_service->accountSendList($username, $params); + $return = $this->formatListPaginate($res['page']); + $return['data'] = $res['records']; + return $return; + } + + /** + * 获取签名列表 + * @param $username + * @return array + */ + public function getSignList($username) + { + $res = $this->niu_service->signList($username); + $return = $this->formatListPaginate($res['page']); + $return['data'] = $res['signatures']; + $config = $this->niu_service->getNiuLoginConfig(); + foreach ($return['data'] as &$item) { + $item['auditResultName'] = NoticeTypeDict::getSignAuditType($item['auditResult']); + $item['createTime'] = date('Y-m-d H:i:s', ($item['createTime'] / 1000)); + $item['is_default'] = ($config['signature'] == $item['sign']) ? 1 : 0; + } + return $return; + } + + /** + * 获取签名信息 + * @param $username + * @param $signature + * @return mixed + */ + public function signInfo($username, $signature) + { + return $this->niu_service->signInfo($username, $signature); + } + + /** + * 获取创建签名初始化的配置信息 + * @return array + */ + public function signCreateConfig() + { + return [ + 'sign_source_list' => NoticeTypeDict::getSignSource(), + 'sign_type_list' => NoticeTypeDict::getSignType(), + 'sign_default_list' => NoticeTypeDict::getSignDefault() + ]; + } + + /** + * 签名创建 + * @param $username + * @param $params + */ + public function signCreate($username, $params) + { + $res = $this->niu_service->signCreate($username, $params); + if (!empty($res['failList'])) { + throw new AdminException($res['failList'][0]['msg']); + } + } + + /** + * 签名创建 + * @param $username + * @param $params + */ + public function signDelete($username, $params) + { + $config = $this->niu_service->getNiuLoginConfig(); + $params['password'] = $config['password']; + $fail_list = $this->niu_service->signDelete($username, $params); + if (in_array($config['signature'], $params['signatures']) && !in_array($config['signature'], $fail_list)) { + $this->editAccount($username, ['signature' => '']); + } + return $fail_list; + } + + /** + * 拉取模版状态 + * @param $sms_type + * @param $username + * @param $page + * @return void|array + */ + public function syncTemplateList($sms_type, $username) + { + $template_list = $this->getTemplateList($sms_type, $username); + $repeat_name_arr = []; + $is_repeat = 0; + foreach ($template_list as $item) { + $repeat_name_arr[$item['name']][] = $item['addon']; + if (count($repeat_name_arr[$item['name']]) > 1) { + $is_repeat = 1; + } + } + if ($is_repeat == 1) { + foreach ($repeat_name_arr as $name => $values) { + if (count($values) == 1) { + unset($repeat_name_arr[$name]); + } + } + return ['repeat_list' => $repeat_name_arr]; + }else{ + $repeat_name_arr = []; + } + $this->execsync($sms_type, $username, $template_list); + return ['repeat_list' => $repeat_name_arr]; + } + + private function execsync($sms_type, $username, $template_list, $page = 1) + { + $name_template_list = array_column($template_list, null, 'name'); + $limit = 100; + $api_template_data = $this->niu_service->templateList($username, ['size' => $limit]); + + $total = $api_template_data['page']['total']; + $templates = $api_template_data['templates']; + $insert = []; + foreach ($templates as $template) { + $tem_id = $template['temId']; + + //拉取回来的模版在项目中未配置 + if (!isset($name_template_list[$template['temName']])) { + continue; + } + if (!empty($template['extend'])) { + $template_key = $template['extend']['template_key'] ?? ""; + } else { + $template_key = $name_template_list[$template['temName']]['key']; + } + $model_info = $this->template_model->where([ + ['sms_type', '=', $sms_type], + ['username', '=', $username], + ['site_id', '=', $this->site_id], + ['template_key', '=', $template_key] + ])->findOrEmpty(); + $data = [ + 'site_id' => $this->site_id, + 'sms_type' => $sms_type, + 'username' => $username, + 'template_key' => $template_key, + 'template_content' => $template['temContent'], + 'param_json' => $template['paramJson'], + 'template_type' => $template['temType'], + 'audit_status' => $template['auditResult'], + 'audit_msg' => $template['auditMsg'], + 'template_id' => $tem_id, + 'report_info' => $template, + 'create_time' => $template['createTime'] / 1000, + 'update_time' => time(), + ]; + if ($model_info->isEmpty()) { + $insert[] = $data; + continue; + } + $this->template_model->where('id', $model_info->id)->update($data); + } + if (!empty($insert)) { + $this->template_model->insertAll($insert); + } + if ($total > $limit * $page) { + $this->execsync($sms_type, $username, $page + 1); + } + } + + /** + * 获取模版列表 + * @param $sms_type + * @param $username + * @param $template_key + * @return array + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function getTemplateList($sms_type, $username, $template_key = '') + { + $config = $this->niu_service->getNiuLoginConfig(); + if (empty($config) || $config['username'] != $username) { + throw new AdminException('ACCOUNT_ERROR_RELOGIN'); + } + $list = NoticeDict::getNoticeWithAddon($template_key,SmsDict::NIUSMS); + $list = $this->formatTemplateList($list); + + + $searchKeys = array_column($list, 'key'); + + $report_list = $this->template_model->whereIn('template_key', $searchKeys)->where([ + ['sms_type', '=', $sms_type], + ['username', '=', $username], + ['site_id', '=', $this->site_id] + ])->select()->toArray(); + $report_list = array_column($report_list, null, 'template_key'); + foreach ($list as &$item) { + $template_key = $item['key']; + $report_info = $report_list[$template_key] ?? []; + $item['template_id'] = $report_info['template_id'] ?? 0; + $item['template_type_name'] = !empty($report_info['template_type']) ? NoticeTypeDict::getTemplateType($report_info['template_type']) : ""; + $item['sms_type'] = $report_info['sms_type'] ?? $sms_type; + $item['site_id'] = $report_info['site_id'] ?? $this->site_id; + $item['username'] = $report_info['username'] ?? $username; + + $audit_status = $report_info['audit_status'] ?? NoticeTypeDict::TEMPLATE_AUDIT_STATUS_NOT_REPORT; + $item['audit_info'] = [ + 'audit_msg' => $report_info['audit_msg'] ?? '', + 'audit_status' => $audit_status, + 'audit_status_name' => NoticeTypeDict::getTemplateAuditStatus($audit_status), + ]; + } + return $list; + } + + public function checkTemplateAudit($template_key, $template_id) + { + $config = $this->niu_service->getNiuLoginConfig(); + if (empty($config)) { + return false; + } + $template_info = $this->template_model->where([ + ['sms_type', '=', SmsDict::NIUSMS], + ['template_id', '=', $template_id], + ['username', '=', $config['username']], + ['template_key', '=', $template_key], + ])->findOrEmpty(); + if (empty($template_info) || $template_info['audit_status'] != NoticeTypeDict::TEMPLATE_AUDIT_STATUS_PASS) { + return false; + } + return $template_info; + } + + /** + * 格式化模版列表返回数据 + * @param $list + * @return array + */ + private function formatTemplateList($list) + { + $return = []; + $addon_arr = array_keys($list); + $addon_list = (new Addon())->whereIn('key', $addon_arr)->field('key,title')->select()->toArray(); + $addon_list = array_column($addon_list, 'title', 'key'); + foreach ($list as $addon => $item) { + foreach ($item as $value) { + $temp = $value; +// $temp['addon'] = $addon; + $temp['addon'] = $addon_list[$addon] ?? '系统'; + $str = $temp['sms']['content'] ?? ""; + if (empty($str)){ + continue; + } + preg_match_all('/\{(.*?)\}/', $str, $matches); + $result = $matches[1]; + foreach ($temp['variable'] as $k => $v) { + if (!in_array($k, $result)) { + unset($temp['variable'][$k]); + } + } + $return[] = $temp; + } + } + return $return; + } + + /** + * 获取模版信息 + * @param $sms_type + * @param $username + * @param $template_key + * @return mixed + */ + public function templateInfo($sms_type, $username, $template_key) + { + $template_info = $this->template_model->where([ + ['site_id', '=', $this->site_id], + ['username', '=', $username], + ['sms_type', '=', $sms_type], + ['template_key', '=', $template_key], + ])->findOrEmpty(); + if ($template_info->isEmpty()) { + throw new AdminException('TEMPLATE_NOT_REPORT'); + } + $res = $this->niu_service->templateInfo($username, $template_info->template_id); + $template_info->audit_status = $res['auditResult'] ?? $template_info->audit_status; + $template_info->save(); + return $template_info->toArray(); + } + + /** + * 获取模版创建使用的初始化配置信息 + * @return array + */ + public function templateCreateConfig() + { + return [ + 'template_params_type_list' => NoticeTypeDict::getApiParamsType(), + 'template_type_list' => NoticeTypeDict::getTemplateType(), + 'template_status_list' => NoticeTypeDict::getTemplateAuditStatus() + ]; + } + + /** + * 报备/编辑模版 + * @param $sms_type + * @param $username + * @param $params + * @return mixed + */ + public function templateUpsert($sms_type, $username, $params) + { + //niusms + $template_key = $params['template_key']; + $template_info = $this->getTemplateList($sms_type, $username, $template_key)[0]; + if (empty($template_info['sms']['content'])) { + throw new AdminException('TEMPLATE_NOT_SMS_CONTENT'); + } + $config = $this->niu_service->getNiuLoginConfig(); + $data = [ + 'temName' => $template_info['name'], + 'temType' => $params['template_type'], + 'temContent' => $template_info['sms']['content'], + 'paramJson' => $params['params_json'], + 'extend' => json_encode(['template_key' => $template_key]), + 'signature' => $config['signature'], + ]; + if ($params['template_id']) { + $data['temId'] = $params['template_id']; + } + $res = $this->niu_service->templateCreate($username, $data); + $tem_id = $res['temId'] ?? 0; + $model_info = $this->template_model->where('template_key', $template_key)->findOrEmpty(); + if ($model_info->isEmpty()) { + $this->template_model->create([ + 'site_id' => $this->site_id, + 'sms_type' => $sms_type, + 'username' => $username, + 'template_key' => $template_key, + 'audit_status' => NoticeTypeDict::TEMPLATE_AUDIT_STATUS_WAIT, + 'template_id' => $tem_id, + 'report_info' => $res ?? [], + 'create_time' => time(), + 'update_time' => time(), + ]); + } else { + $model_info->audit_status = NoticeTypeDict::TEMPLATE_AUDIT_STATUS_WAIT; + $model_info->template_id = $tem_id; + $model_info->report_info = $res ?? []; + $model_info->update_time = time(); + $model_info->save(); + } + return $res ?? []; + } + + /** + * 格式化列表接口分页器 + * @param $data + * @return array + */ + private function formatListPaginate($data) + { + return [ + 'total' => $data['total'], + 'per_page' => $data['size'], + 'current_page' => $data['currentPage'], + 'last_page' => $data['totalPage'], + ]; + } + + /** + * 获取订单列表 + * @param $username + * @return mixed + */ + public function orderList($username, $params) + { + $res = $this->niu_service->orderList($username, $params); + return $res; + } + + /** + * 创建订单 + * @param $username + * @param $package_id + * @return mixed + */ + public function createOrder($username, $package_id) + { + $res = $this->niu_service->orderCreate($username, ['package_id' => $package_id]); + return $res; + } + + /** + * 计算订单 + * @param $username + * @param $package_id + * @return mixed + */ + public function calculate($username, $package_id) + { + $res = $this->niu_service->calculate($username, ['package_id' => $package_id]); + return $res; + } + + /** + * 获取支付使用信息 + * @param $username + * @param $params + * @return mixed + */ + public function getPayInfo($username, $params) + { + $res = $this->niu_service->orderPayInfo($username, $params); + return $res; + } + + /** + * 获取订单信息 + * @param $username + * @param $out_trade_no + * @return mixed + */ + public function orderInfo($username, $out_trade_no) + { + $res = $this->niu_service->orderInfo($username, $out_trade_no); + return $res; + } + + /** + * 获取订单状态 + * @param $username + * @param $out_trade_no + * @return mixed + */ + public function orderStatus($username, $out_trade_no) + { + $res = $this->niu_service->orderStatus($username, $out_trade_no); + return $res; + } + +} diff --git a/niucloud/app/service/admin/notice/NoticeService.php b/niucloud/app/service/admin/notice/NoticeService.php index 41ba39c2e..7041a886b 100644 --- a/niucloud/app/service/admin/notice/NoticeService.php +++ b/niucloud/app/service/admin/notice/NoticeService.php @@ -13,11 +13,13 @@ namespace app\service\admin\notice; use app\dict\notice\NoticeDict; use app\dict\notice\NoticeTypeDict; +use app\dict\sys\ConfigKeyDict; +use app\dict\sys\SmsDict; use app\model\sys\SysNotice; use app\service\core\notice\CoreNoticeService; +use app\service\core\sys\CoreConfigService; use core\base\BaseAdminService; use core\exception\AdminException; -use think\Response; /** * 消息管理服务层 @@ -56,7 +58,8 @@ class NoticeService extends BaseAdminService * @param $value * @return bool */ - public function modify(string $key, string $field_type, $value){ + public function modify(string $key, string $field_type, $value) + { $data = array( $field_type => $value ); @@ -71,9 +74,9 @@ class NoticeService extends BaseAdminService */ public function editMessageStatus(string $key, string $type, int $status) { - if(!array_key_exists($type, NoticeTypeDict::getType())) throw new AdminException('NOTICE_TYPE_NOT_EXIST'); - if(!array_key_exists($key, NoticeDict::getNotice())) return fail('NOTICE_TYPE_NOT_EXIST'); - return (new CoreNoticeService())->edit($this->site_id, $key, ['is_'.$type => $status]); + if (!array_key_exists($type, NoticeTypeDict::getType())) throw new AdminException('NOTICE_TYPE_NOT_EXIST'); + if (!array_key_exists($key, NoticeDict::getNotice())) return fail('NOTICE_TYPE_NOT_EXIST'); + return (new CoreNoticeService())->edit($this->site_id, $key, ['is_' . $type => $status]); } /** @@ -84,11 +87,10 @@ class NoticeService extends BaseAdminService */ public function edit(string $key, string $type, array $data) { - if(!array_key_exists($type, NoticeTypeDict::getType())) throw new AdminException('NOTICE_TYPE_NOT_EXIST'); - if(!array_key_exists($key, NoticeDict::getNotice())) return fail('NOTICE_TYPE_NOT_EXIST'); - $save_data = ['is_'.$type => $data['status']]; - switch ($type) - { + if (!array_key_exists($type, NoticeTypeDict::getType())) throw new AdminException('NOTICE_TYPE_NOT_EXIST'); + if (!array_key_exists($key, NoticeDict::getNotice())) return fail('NOTICE_TYPE_NOT_EXIST'); + $save_data = ['is_' . $type => $data['status']]; + switch ($type) { case NoticeTypeDict::SMS: $save_data['sms_id'] = $data['sms_id'] ?? ''; break; @@ -99,9 +101,16 @@ class NoticeService extends BaseAdminService case NoticeTypeDict::WEAPP: break; } + if ($type == NoticeTypeDict::SMS && $data['status'] == 1) { + $info = (new CoreConfigService())->getConfigValue($this->site_id, ConfigKeyDict::SMS); + if ($info['default'] == SmsDict::NIUSMS) { + $res = (new NiuSmsService())->checkTemplateAudit($data['key'], $data['sms_id']); + if (!$res) { + throw new AdminException('TEMPLATE_ERROR'); + } + } + } return (new CoreNoticeService())->edit($this->site_id, $key, $save_data); } - - } diff --git a/niucloud/app/service/admin/notice/SmsService.php b/niucloud/app/service/admin/notice/SmsService.php index e1398ca76..9b8cdf505 100644 --- a/niucloud/app/service/admin/notice/SmsService.php +++ b/niucloud/app/service/admin/notice/SmsService.php @@ -12,6 +12,7 @@ namespace app\service\admin\notice; use app\dict\common\CommonDict; +use app\dict\sys\ConfigKeyDict; use app\dict\sys\SmsDict; use app\service\core\sys\CoreConfigService; use core\base\BaseAdminService; @@ -34,8 +35,8 @@ class SmsService extends BaseAdminService public function getList() { $sms_type_list = SmsDict::getType(); - $info = (new CoreConfigService())->getConfig($this->site_id, 'SMS'); - if(empty($info)) + $info = (new CoreConfigService())->getConfig($this->site_id, ConfigKeyDict::SMS); + if(empty($info) || !isset($info['value']['default'])) { $config_type = ['default' => ''];//初始化 }else @@ -74,8 +75,8 @@ class SmsService extends BaseAdminService { $sms_type_list = SmsDict::getType(); if(!array_key_exists($sms_type, $sms_type_list)) throw new AdminException('SMS_TYPE_NOT_EXIST'); - $info = (new CoreConfigService())->getConfig($this->site_id, 'SMS'); - if(empty($info)) + $info = (new CoreConfigService())->getConfig($this->site_id, ConfigKeyDict::SMS); + if(empty($info) || !isset($info['value']['default'])) { $config_type = ['default' => ''];//初始化 }else @@ -111,8 +112,8 @@ class SmsService extends BaseAdminService { $sms_type_list = SmsDict::getType(); if(!array_key_exists($sms_type, $sms_type_list)) throw new AdminException('SMS_TYPE_NOT_EXIST'); - $info = (new CoreConfigService())->getConfig($this->site_id, 'SMS'); - if(empty($info)) + $info = (new CoreConfigService())->getConfig($this->site_id, ConfigKeyDict::SMS); + if(empty($info) || !isset($info['value']['default'])) { $config['default'] = ''; diff --git a/niucloud/app/service/admin/site/SiteGroupService.php b/niucloud/app/service/admin/site/SiteGroupService.php index 8665bcb67..6a95a6af1 100644 --- a/niucloud/app/service/admin/site/SiteGroupService.php +++ b/niucloud/app/service/admin/site/SiteGroupService.php @@ -50,7 +50,7 @@ class SiteGroupService extends BaseAdminService public function getPage(array $where = []) { $field = 'group_id, group_name, group_desc, app, addon, create_time, update_time'; - $search_model = $this->model->withSearch([ 'keywords' ], $where)->field($field)->append([ 'app_name', 'addon_name' ])->order('create_time desc'); + $search_model = $this->model->withSearch([ 'keywords' ], $where)->field($field)->append([ 'app_name','app_list', 'addon_name','addon_list' ])->order('create_time desc'); $list = $this->pageQuery($search_model); return $list; } diff --git a/niucloud/app/service/admin/site/UserLogService.php b/niucloud/app/service/admin/site/UserLogService.php index 06f02e55e..d911c1a3e 100644 --- a/niucloud/app/service/admin/site/UserLogService.php +++ b/niucloud/app/service/admin/site/UserLogService.php @@ -68,4 +68,9 @@ class UserLogService extends BaseAdminService $res = $this->model->create($data); return $res->id; } + + public function destroy() + { + (new SysUserLog())->whereRaw("1=1")->delete(); + } } \ No newline at end of file diff --git a/niucloud/app/service/admin/upgrade/BackupRecordsService.php b/niucloud/app/service/admin/upgrade/BackupRecordsService.php index c3c10d4e6..e41a701f9 100644 --- a/niucloud/app/service/admin/upgrade/BackupRecordsService.php +++ b/niucloud/app/service/admin/upgrade/BackupRecordsService.php @@ -284,7 +284,7 @@ class BackupRecordsService extends BaseAdminService $res = [ 'code' => 1, 'data' => [], 'msg' => '' ]; $cache_data = Cache::get($this->cache_restore_key); - if (!empty($cache_data)) { + if (!empty($cache_data) && !empty($cache_data[ 'key' ])) { $key = $cache_data[ 'key' ]; } else { $key = uniqid(); @@ -330,19 +330,26 @@ class BackupRecordsService extends BaseAdminService $this->backupCode($key); } elseif ($data[ 'task' ] == 'backupSql') { - - //备份数据库 - $res[ 'data' ] = [ - 'content' => '备份数据库', - 'task' => 'restoreCode' - ]; + $backup_result = $this->backupSql($key); + if ($backup_result === true) { + //备份数据库 + $res[ 'data' ] = [ + 'content' => '数据库备份完成', + 'task' => 'restoreCode' + ]; + } else { + $res[ 'data' ] = [ + 'content' => '', + 'task' => 'backupSql' + ]; + if ($backup_result % 5 == 0) { + $res[ 'data' ][ 'content' ] = $backup_result == 0 ? '数据库开始备份' : '数据库备份中已备份'. $backup_result . '%'; + } + } $temp = Cache::get($this->cache_restore_key); $temp[ 'data' ][] = $res[ 'data' ]; Cache::set($this->cache_restore_key, $temp); - - $this->backupSql($key); - } elseif ($data[ 'task' ] == 'restoreCode') { $res[ 'data' ] = [ @@ -359,19 +366,29 @@ class BackupRecordsService extends BaseAdminService dir_copy($info[ 'backup_code_dir' ], rtrim($root_path, DIRECTORY_SEPARATOR)); } elseif ($data[ 'task' ] == 'restoreSql') { + // 恢复数据库备份 + $db = new DbBackup($info[ 'backup_sql_dir' ]); + $restore_result = $db->restoreDatabase(); - $res[ 'data' ] = [ - 'content' => '恢复数据库备份', - 'task' => 'restoreData' - ]; + if ($restore_result === true) { + $res[ 'data' ] = [ + 'content' => '数据库恢复完成', + 'task' => 'restoreData' + ]; + } else { + $res[ 'data' ] = [ + 'content' => '', + 'task' => 'restoreSql' + ]; + $restore_progress = $db->getRestoreProgress(); + if ($restore_progress % 5 == 0) { + $res[ 'data' ]['content'] = $restore_progress == 0 ? '数据库开始恢复' : '数据库恢复中已恢复'. $restore_progress . '%'; + } + } $temp = Cache::get($this->cache_restore_key); $temp[ 'data' ][] = $res[ 'data' ]; Cache::set($this->cache_restore_key, $temp); - - // 恢复数据库备份 - $db = new DbBackup($info[ 'backup_sql_dir' ]); - $db->restoreDatabase(); } elseif ($data[ 'task' ] == 'restoreData') { $res[ 'data' ] = [ @@ -489,18 +506,23 @@ class BackupRecordsService extends BaseAdminService $this->backupCode($key); } elseif ($data[ 'task' ] == 'backupSql') { + $backup_result = $this->backupSql($key); + if ($backup_result === true || $backup_result == 100) { + //备份数据库 + $res[ 'data' ] = [ + 'content' => '数据库备份完成', + 'task' => 'backComplete' + ]; + } else { + $res[ 'data' ] = [ + 'content' => $backup_result == 0 ? '数据库开始备份' : '数据库备份已备份'. $backup_result . '%', + 'task' => 'backupSql' + ]; + } - //备份数据库 - $res[ 'data' ] = [ - 'content' => '备份数据库', - 'task' => 'backComplete' - ]; - $temp = Cache::get($this->cache_key); + $temp = Cache::get($this->cache_restore_key); $temp[ 'data' ][] = $res[ 'data' ]; - Cache::set($this->cache_key, $temp); - - $this->backupSql($key); - + Cache::set($this->cache_restore_key, $temp); } elseif ($data[ 'task' ] == 'backComplete') { $res[ 'data' ] = [ @@ -629,8 +651,6 @@ class BackupRecordsService extends BaseAdminService // 创建目录 dir_mkdir($backup_dir); - $db = new DbBackup($backup_dir, 1024 * 1024 * 2); - $prefix = config('database.connections.' . config('database.default'))[ 'prefix' ]; // 不需要备份的表 @@ -642,9 +662,13 @@ class BackupRecordsService extends BaseAdminService "{$prefix}sys_upgrade_records", "{$prefix}sys_backup_records" ]; - $db->setExcludeTables($not_need_backup)->backupDatabaseSegment(); - return true; + $db = new DbBackup($backup_dir, 1024 * 1024 * 2, $not_need_backup, key: $backup_key); + + $result = $db->backupDatabaseSegment(); + if ($result === true) return true; + + return $db->getBackupProgress(); } } diff --git a/niucloud/app/service/admin/upgrade/BackupService.php b/niucloud/app/service/admin/upgrade/BackupService.php index df055d7aa..8129cfe9a 100644 --- a/niucloud/app/service/admin/upgrade/BackupService.php +++ b/niucloud/app/service/admin/upgrade/BackupService.php @@ -47,32 +47,4 @@ class BackupService extends UpgradeService return true; } - - /** - * 备份数据库 - * @return void - */ - public function backupSql() - { - $backup_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR; - // 创建目录 - dir_mkdir($backup_dir); - - $db = new DbBackup($backup_dir, 1024 * 1024 * 2); - - $prefix = config('database.connections.' . config('database.default'))[ 'prefix' ]; - - // 不需要备份的表 - $not_need_backup = [ - "{$prefix}sys_schedule_log", - "{$prefix}sys_user_log", - "{$prefix}jobs", - "{$prefix}jobs_failed", - "{$prefix}sys_upgrade_records", - "{$prefix}sys_backup_records" - ]; - $db->setExcludeTables($not_need_backup)->backupDatabaseSegment(); - - return true; - } } diff --git a/niucloud/app/service/admin/upgrade/RestoreService.php b/niucloud/app/service/admin/upgrade/RestoreService.php index 2668b44b5..47544b068 100644 --- a/niucloud/app/service/admin/upgrade/RestoreService.php +++ b/niucloud/app/service/admin/upgrade/RestoreService.php @@ -11,52 +11,11 @@ namespace app\service\admin\upgrade; - -use app\dict\sys\AppTypeDict; -use app\model\site\Site; -use core\util\DbBackup; - /** + * todo 废弃,后续删除 * 框架及插件升级恢复备份 * @package app\service\core\upgrade */ class RestoreService extends UpgradeService { - /** - * 恢复代码备份 - * @return true - */ - public function restoreCode() - { - $backup_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'code' . DIRECTORY_SEPARATOR; - if (is_dir($backup_dir)) { - // 删除前端文件 -// if (is_dir(public_path() . 'admin')) del_target_dir(public_path() . 'admin', true); -// if (is_dir(public_path() . 'wap')) del_target_dir(public_path() . 'wap', true); -// if (is_dir(public_path() . 'web')) del_target_dir(public_path() . 'web', true); - dir_copy($backup_dir, rtrim($this->root_path, DIRECTORY_SEPARATOR)); - } - return true; - } - - /** - * 恢复数据库备份 - * @return true - */ - public function restoreSql() - { - $backup_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR; - if (is_dir($backup_dir)) { - $db = new DbBackup($backup_dir); - $db->restoreDatabase(); - - $site_model = new Site(); - $site_model->where([ - [ 'site_id', '<>', 0 ], - [ 'app_type', '=', AppTypeDict::ADMIN ] - ])->update([ 'site_id' => 0 ]); - } - return true; - } - } diff --git a/niucloud/app/service/admin/upgrade/UpgradeRecordsService.php b/niucloud/app/service/admin/upgrade/UpgradeRecordsService.php index 023270716..cd309d260 100644 --- a/niucloud/app/service/admin/upgrade/UpgradeRecordsService.php +++ b/niucloud/app/service/admin/upgrade/UpgradeRecordsService.php @@ -37,12 +37,16 @@ class UpgradeRecordsService extends BaseAdminService { $data[ 'create_time' ] = time(); $res = $this->model->create($data); + // 关联备份记录 - ( new BackupRecordsService() )->add([ - 'version' => $data[ 'current_version' ], - 'backup_key' => $data[ 'upgrade_key' ], - 'content' => '自动备份' - ]); + $is_need_backup = $data['is_need_backup'] ?? true; + if ($is_need_backup) { + ( new BackupRecordsService() )->add([ + 'version' => $data[ 'current_version' ], + 'backup_key' => $data[ 'upgrade_key' ], + 'content' => '自动备份' + ]); + } return $res->id; } @@ -80,9 +84,9 @@ class UpgradeRecordsService extends BaseAdminService * @param $fail_reason * @return void */ - public function failed($upgrade_key) + public function failed($upgrade_key, $fail_reason = []) { - $this->model->where([ [ 'upgrade_key', '=', $upgrade_key ] ])->delete(); + $this->model->where([ [ 'upgrade_key', '=', $upgrade_key ] ])->update(['status' => UpgradeDict::STATUS_FAIL, 'fail_reason' => $fail_reason ]); ( new BackupRecordsService() )->failed($upgrade_key); } @@ -104,13 +108,21 @@ class UpgradeRecordsService extends BaseAdminService */ public function getPage(array $where = []) { - $field = 'id, upgrade_key, app_key, name, content, prev_version, current_version, complete_time'; + $field = 'id, upgrade_key, app_key, name, content, prev_version, current_version, complete_time, create_time, status, fail_reason'; $order = "id desc"; $search_model = $this->model->where([ - [ 'status', '=', UpgradeDict::STATUS_COMPLETE ], +// [ 'status', '=', UpgradeDict::STATUS_COMPLETE ], [ 'name|content|current_version', 'like', '%' . $where[ 'name' ] . '%' ] - ])->field($field)->order($order); + ])->field($field)->order($order)->append(['status_name']); return $this->pageQuery($search_model); } + /** + * 刪除升级记录 + * @param $ids + * @return void + */ + public function del($ids) { + $this->model->where([['id', 'in', $ids]])->delete(); + } } diff --git a/niucloud/app/service/admin/upgrade/UpgradeService.php b/niucloud/app/service/admin/upgrade/UpgradeService.php index 8bb1dfb30..cd63b1947 100644 --- a/niucloud/app/service/admin/upgrade/UpgradeService.php +++ b/niucloud/app/service/admin/upgrade/UpgradeService.php @@ -12,8 +12,12 @@ namespace app\service\admin\upgrade; use app\dict\addon\AddonDict; +use app\dict\sys\AppTypeDict; +use app\dict\sys\BackupDict; use app\dict\sys\UpgradeDict; use app\model\addon\Addon; +use app\model\site\Site; +use app\model\sys\SysBackupRecords; use app\service\admin\install\InstallSystemService; use app\service\admin\sys\ConfigService; use app\service\core\addon\CoreAddonCloudService; @@ -29,6 +33,7 @@ use app\service\core\schedule\CoreScheduleInstallService; use core\base\BaseAdminService; use core\exception\CloudBuildException; use core\exception\CommonException; +use core\util\DbBackup; use core\util\niucloud\BaseNiucloudClient; use think\facade\Cache; use think\facade\Db; @@ -55,9 +60,9 @@ class UpgradeService extends BaseAdminService private $steps = [ 'requestUpgrade' => [ 'step' => 'requestUpgrade', 'title' => '请求升级' ], - 'downloadFile' => [ 'step' => 'downloadFile', 'title' => '下载更新文件' ], + 'downloadFile' => [ 'step' => 'downloadFile', 'title' => '' ], 'backupCode' => [ 'step' => 'backupCode', 'title' => '备份源码' ], - 'backupSql' => [ 'step' => 'backupSql', 'title' => '备份数据库' ], + 'backupSql' => [ 'step' => 'backupSql', 'title' => '' ], 'coverCode' => [ 'step' => 'coverCode', 'title' => '合并更新文件' ], 'handleUniapp' => [ 'step' => 'handleUniapp', 'title' => '处理uniapp' ], 'refreshMenu' => [ 'step' => 'refreshMenu', 'title' => '刷新菜单' ], @@ -74,6 +79,10 @@ class UpgradeService extends BaseAdminService $this->root_path = dirname(root_path()) . DIRECTORY_SEPARATOR; $this->upgrade_dir = $this->root_path . 'upgrade' . DIRECTORY_SEPARATOR; $this->upgrade_task = Cache::get($this->cache_key); + + if (!empty($this->upgrade_task) && !isset($this->upgrade_task[ 'upgrade_apps' ])) { + $this->upgrade_task[ 'upgrade_apps' ] = [ AddonDict::FRAMEWORK_KEY ]; + } } /** @@ -134,7 +143,8 @@ class UpgradeService extends BaseAdminService 'public' . DIRECTORY_SEPARATOR . 'upload', 'public' . DIRECTORY_SEPARATOR . 'file', 'runtime', - 'vendor' + 'vendor', + '.user.ini' ]; $check_res = array_merge2($check_res, checkDirPermissions(project_path() . 'niucloud', [], $exclude_niucloud_dir)); @@ -165,31 +175,37 @@ class UpgradeService extends BaseAdminService * @param $addon * @return array */ - public function upgrade(string $addon = '') + public function upgrade(string $addon = '', $data = []) { if ($this->upgrade_task) throw new CommonException('UPGRADE_TASK_EXIST'); $upgrade_content = $this->getUpgradeContent($addon); + if (empty($upgrade_content['content'])) throw new CommonException("NOT_EXIST_UPGRADE_CONTENT"); + $upgrade_title = '框架'; $upgrade = [ 'product_key' => BaseNiucloudClient::PRODUCT, 'framework_version' => config('version.version') ]; - if (!$addon) { - $upgrade[ 'app_key' ] = AddonDict::FRAMEWORK_KEY; - $upgrade[ 'version' ] = config('version.version'); - } else { - $upgrade[ 'app_key' ] = $addon; - $upgrade[ 'version' ] = ( new Addon() )->where([ [ 'key', '=', $addon ] ])->value('version'); - $upgrade_title = ( new Addon() )->where([ [ 'key', '=', $addon ] ])->value('title'); - // 判断框架版本是否低于插件支持版本 - $last_version = $upgrade_content[ 'version_list' ][ count($upgrade_content[ 'version_list' ]) - 1 ]; - if (str_replace('.', '', config('version.version')) < str_replace('.', '', $last_version[ 'niucloud_version' ][ 'version_no' ])) { - throw new CommonException('BEFORE_UPGRADING_NEED_UPGRADE_FRAMEWORK'); - } - } + $upgrade[ 'app_key' ] = $upgrade_content['content'][0]['app']['app_key']; + $upgrade[ 'version' ] = $upgrade_content['content'][0]['version']; + +// if (!$addon) { +// $upgrade[ 'app_key' ] = AddonDict::FRAMEWORK_KEY; +// $upgrade[ 'version' ] = config('version.version'); +// } else { +// $upgrade[ 'app_key' ] = $addon; +// $upgrade[ 'version' ] = ( new Addon() )->where([ [ 'key', '=', $addon ] ])->value('version'); +// $upgrade_title = ( new Addon() )->where([ [ 'key', '=', $addon ] ])->value('title'); +// +// // 判断框架版本是否低于插件支持版本 +// $last_version = $upgrade_content[ 'version_list' ][ count($upgrade_content[ 'version_list' ]) - 1 ]; +// if (str_replace('.', '', config('version.version')) < str_replace('.', '', $last_version[ 'niucloud_version' ][ 'version_no' ])) { +// throw new CommonException('BEFORE_UPGRADING_NEED_UPGRADE_FRAMEWORK'); +// } +// } $response = ( new CoreAddonCloudService() )->upgradeAddon($upgrade); if (isset($response[ 'code' ]) && $response[ 'code' ] == 0) throw new CommonException($response[ 'msg' ]); @@ -202,6 +218,20 @@ class UpgradeService extends BaseAdminService dir_mkdir($upgrade_dir); } + // 是否需要备份 + $is_need_backup = $data['is_need_backup'] ?? true; + if (!$is_need_backup) { + unset($this->steps['backupCode']); + unset($this->steps['backupSql']); + } + + // 是否需要云编译 + $is_need_cloudbuild = $data['is_need_cloudbuild'] ?? true; + if (!$is_need_cloudbuild) { + unset($this->steps['cloudBuild']); + unset($this->steps['gteCloudBuildLog']); + } + $upgrade_task = [ 'key' => $key, 'upgrade' => $upgrade, @@ -209,19 +239,26 @@ class UpgradeService extends BaseAdminService 'step' => 'requestUpgrade', 'executed' => [ 'requestUpgrade' ], 'log' => [ $this->steps[ 'requestUpgrade' ][ 'title' ] ], - 'params' => [ 'token' => $response[ 'token' ] ], - 'upgrade_content' => $upgrade_content + 'params' => [ 'app_key' => $upgrade[ 'app_key' ], 'token' => $response[ 'token' ] ], + 'upgrade_content' => $upgrade_content, + 'upgrade_apps' => $upgrade_content['upgrade_apps'], + 'is_need_backup' => $is_need_backup, ]; + foreach ($upgrade_content[ 'content' ] as $k => $v) { + unset($upgrade_content[ 'content' ][ $k ][ 'version_list' ]); + } + // 记录升级日志 ( new UpgradeRecordsService() )->add([ 'upgrade_key' => $upgrade_task[ 'key' ], 'app_key' => $upgrade[ 'app_key' ], 'name' => $upgrade_title, - 'content' => "{$upgrade_title} 升级 v{$upgrade_content['version']} 到 v{$upgrade_content['upgrade_version']}版本", - 'prev_version' => "v{$upgrade_content['version']}", - 'current_version' => "v{$upgrade_content['upgrade_version']}", - 'status' => UpgradeDict::STATUS_READY + 'content' => json_encode($upgrade_content), + 'prev_version' => "", + 'current_version' => "", + 'status' => UpgradeDict::STATUS_READY, + 'is_need_backup' => $is_need_backup ]); Cache::set($this->cache_key, $upgrade_task); @@ -303,13 +340,35 @@ class UpgradeService extends BaseAdminService * @param $step * @return true|null */ - public function downloadFile(string $token, string $dir = '', int $index = -1, $step = 0, $length = 0) + public function downloadFile(string $app_key, string $token, string $dir = '', int $index = -1, $step = 0, $length = 0) { if (!$dir) { - $dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'download' . DIRECTORY_SEPARATOR; + $dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'download' . DIRECTORY_SEPARATOR . $app_key . DIRECTORY_SEPARATOR; dir_mkdir($dir); } - $res = ( new CoreAddonCloudService() )->downloadUpgradeFile($token, $dir, $index, $step, $length); + $res = ( new CoreAddonCloudService() )->downloadUpgradeFile($app_key, $token, $dir, $index, $step, $length); + + if ($res === true) { + $index = array_search($app_key, $this->upgrade_task['upgrade_apps']); + if ($app_key == AddonDict::FRAMEWORK_KEY) { + $this->upgrade_task['log'][] = "下载更新文件"; + } else { + $this->upgrade_task['log'][] = "下载". $this->upgrade_task['upgrade_content']['content'][$index]['app']['app_name'] ."更新文件"; + } + $index++; + if (isset($this->upgrade_task['upgrade_apps'][$index])) { + $upgrade = [ + 'product_key' => BaseNiucloudClient::PRODUCT, + 'framework_version' => config('version.version'), + 'app_key' => $this->upgrade_task['upgrade_content']['content'][$index]['app']['app_key'], + 'version' => $this->upgrade_task['upgrade_content']['content'][$index]['version'] + ]; + $response = ( new CoreAddonCloudService() )->upgradeAddon($upgrade); + if (isset($response[ 'code' ]) && $response[ 'code' ] == 0) throw new CommonException($response[ 'msg' ]); + + return ['app_key' => $upgrade[ 'app_key' ], 'token' => $response[ 'token' ]]; + } + } return $res; } @@ -327,23 +386,49 @@ class UpgradeService extends BaseAdminService * 备份数据库 * @return true */ - public function backupSql() + public function backupSql($index = 0) { - ( new BackupService() )->backupSql(); - return true; + $backup_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR; + // 创建目录 + dir_mkdir($backup_dir); + + $db = new DbBackup($backup_dir, 1024 * 1024 * 2, key: $this->upgrade_task[ 'key' ]); + + $prefix = config('database.connections.' . config('database.default'))[ 'prefix' ]; + + // 不需要备份的表 + $not_need_backup = [ + "{$prefix}sys_schedule_log", + "{$prefix}sys_user_log", + "{$prefix}jobs", + "{$prefix}jobs_failed", + "{$prefix}sys_upgrade_records", + "{$prefix}sys_backup_records" + ]; + + $result = $db->setExcludeTables($not_need_backup)->backupDatabaseSegment(); + if ($db->getBackupProgress() == 100) { + $this->upgrade_task[ 'log' ][] = "数据库备份完成"; + } else { + $this->upgrade_task[ 'log' ][] = $db->getBackupProgress() == 0 ? '数据库开始备份' : '数据库备份已备份'. $db->getBackupProgress() . '%'; + } + if ($result === true) return true; + return ['index' => $result]; } /** * 覆盖更新升级的代码 * @return void */ - public function coverCode($index = 0) + public function coverCode($index = 0, $addon = "") { $this->upgrade_task[ 'is_cover' ] = 1; - $addon = $this->upgrade_task[ 'upgrade' ][ 'app_key' ]; + if (empty($addon)) $addon = $this->upgrade_task['upgrade_apps'][0]; - $version_list = array_reverse($this->upgrade_task[ 'upgrade_content' ][ 'version_list' ]); - $code_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'download' . DIRECTORY_SEPARATOR . 'code' . DIRECTORY_SEPARATOR; + $app_index = array_search($addon, $this->upgrade_task['upgrade_apps']); + + $version_list = array_reverse($this->upgrade_task[ 'upgrade_content' ]['content'][$app_index][ 'version_list' ]); + $code_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'download' . DIRECTORY_SEPARATOR . $addon . DIRECTORY_SEPARATOR . 'code' . DIRECTORY_SEPARATOR; $version_item = $version_list[ $index ]; $version_no = $version_item[ 'version_no' ]; @@ -394,8 +479,12 @@ class UpgradeService extends BaseAdminService $index++; if ($index < count($version_list)) { - return compact('index'); + return compact('index', 'addon'); } else { + $app_index++; + if (isset($this->upgrade_task['upgrade_apps'][$app_index])) { + return ['index' => 0, 'addon' => $this->upgrade_task['upgrade_apps'][$app_index]]; + } return true; } } @@ -466,7 +555,9 @@ class UpgradeService extends BaseAdminService */ public function handleUniapp() { - $code_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'download' . DIRECTORY_SEPARATOR . 'code' . DIRECTORY_SEPARATOR; + $key = end($this->upgrade_task['upgrade_apps']); + + $code_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'download' . DIRECTORY_SEPARATOR . $key . DIRECTORY_SEPARATOR . 'code' . DIRECTORY_SEPARATOR; $exclude_files = [ '.env.development', '.env.production', 'manifest.json' ]; dir_copy($code_dir . 'uni-app', $this->root_path . 'uni-app', exclude_files: $exclude_files); @@ -537,12 +628,20 @@ class UpgradeService extends BaseAdminService * 刷新菜单 * @return void */ - public function refreshMenu() + public function refreshMenu($addon = "") { - if ($this->upgrade_task[ 'upgrade' ][ 'app_key' ] == AddonDict::FRAMEWORK_KEY) { + if (empty($addon)) $addon = $this->upgrade_task['upgrade_apps'][0]; + $app_index = array_search($addon, $this->upgrade_task['upgrade_apps']); + + if ($addon == AddonDict::FRAMEWORK_KEY) { ( new InstallSystemService() )->installMenu(); } else { - ( new CoreMenuService() )->refreshAddonMenu($this->upgrade_task[ 'upgrade' ][ 'app_key' ]); + ( new CoreMenuService() )->refreshAddonMenu($addon); + } + + $app_index++; + if (isset($this->upgrade_task['upgrade_apps'][$app_index])) { + return ['addon' => $this->upgrade_task['upgrade_apps'][$app_index]]; } return true; } @@ -551,12 +650,20 @@ class UpgradeService extends BaseAdminService * 安装计划任务 * @return true */ - public function installSchedule() + public function installSchedule($addon = "") { - if ($this->upgrade_task[ 'upgrade' ][ 'app_key' ] == AddonDict::FRAMEWORK_KEY) { + if (empty($addon)) $addon = $this->upgrade_task['upgrade_apps'][0]; + $app_index = array_search($addon, $this->upgrade_task['upgrade_apps']); + + if ($addon == AddonDict::FRAMEWORK_KEY) { ( new CoreScheduleInstallService() )->installSystemSchedule(); } else { - ( new CoreScheduleInstallService() )->installAddonSchedule($this->upgrade_task[ 'upgrade' ][ 'app_key' ]); + ( new CoreScheduleInstallService() )->installAddonSchedule($addon); + } + + $app_index++; + if (isset($this->upgrade_task['upgrade_apps'][$app_index])) { + return ['addon' => $this->upgrade_task['upgrade_apps'][$app_index]]; } return true; } @@ -614,12 +721,13 @@ class UpgradeService extends BaseAdminService */ public function upgradeComplete() { - $addon = $this->upgrade_task[ 'upgrade' ][ 'app_key' ]; - if ($addon != AddonDict::FRAMEWORK_KEY) { - $core_addon_service = new CoreAddonService(); - $install_data = $core_addon_service->getAddonConfig($addon); - $install_data[ 'icon' ] = 'addon/' . $addon . '/icon.png'; - $core_addon_service->set($install_data); + foreach ($this->upgrade_task['upgrade_apps'] as $addon) { + if ($addon != AddonDict::FRAMEWORK_KEY) { + $core_addon_service = new CoreAddonService(); + $install_data = $core_addon_service->getAddonConfig($addon); + $install_data[ 'icon' ] = 'addon/' . $addon . '/icon.png'; + $core_addon_service->set($install_data); + } } // 执行完成,更新升级记录状态,备份记录状态 ( new UpgradeRecordsService() )->complete($this->upgrade_task[ 'key' ]); @@ -642,12 +750,10 @@ class UpgradeService extends BaseAdminService } $steps[ 'restoreComplete' ] = [ 'step' => 'restoreComplete', 'title' => '备份恢复完成' ]; $this->upgrade_task[ 'steps' ] = $steps; + $this->upgrade_task[ 'params' ] = []; Cache::set($this->cache_key, $this->upgrade_task); Log::write('升级出错之后的处理:'.json_encode($fail_reason)); - - // 执行失败,更新升级记录状态,备份记录状态 - ( new UpgradeRecordsService() )->failed($this->upgrade_task[ 'key' ]); } /** @@ -656,11 +762,17 @@ class UpgradeService extends BaseAdminService */ public function restoreCode() { + if ($this->upgrade_task['is_need_backup']) { + $backup_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'code' . DIRECTORY_SEPARATOR; + } else { + $backup_dir = $this->upgrade_dir . $this->upgrade_task['upgrade_content']['last_backup'][ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'code' . DIRECTORY_SEPARATOR; + } try { - ( new RestoreService() )->restoreCode(); + if (is_dir($backup_dir)) { + dir_copy($backup_dir, rtrim($this->root_path, DIRECTORY_SEPARATOR)); + } return true; } catch (\Exception $e) { - $backup_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'code' . DIRECTORY_SEPARATOR; $this->upgrade_task[ 'error' ][] = '源码备份恢复失败稍后请手动恢复,源码备份文件路径:' . $backup_dir . ',失败原因:' . $e->getMessage() . $e->getFile() . $e->getLine(); Cache::set($this->cache_key, $this->upgrade_task); return true; @@ -671,13 +783,34 @@ class UpgradeService extends BaseAdminService * 恢复数据库 * @return void */ - public function restoreSql() + public function restoreSql($index = 0) { + if ($this->upgrade_task['is_need_backup']) { + $backup_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR; + } else { + $backup_dir = $this->upgrade_dir . $this->upgrade_task['upgrade_content']['last_backup'][ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR; + } try { - ( new RestoreService() )->restoreSql(); + if (is_dir($backup_dir)) { + $db = new DbBackup($backup_dir, key: $this->upgrade_task[ 'key' ]); + $result = $db->restoreDatabase(); + if ($result !== true) return ['index' => $result]; + + $restore_progress = $db->getRestoreProgress(); + if ($restore_progress % 5 == 0) { + $this->upgrade_task[ 'log' ][] = $restore_progress == 0 ? '数据库开始恢复' : '数据库恢复中已恢复'. $restore_progress . '%'; + } + } + + // 处理admin站点不为0的问题 + $site_model = new Site(); + $site_model->where([ + [ 'site_id', '<>', 0 ], + [ 'app_type', '=', AppTypeDict::ADMIN ] + ])->update([ 'site_id' => 0 ]); + return true; } catch (\Exception $e) { - $backup_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR; $this->upgrade_task[ 'error' ][] = '数据库备份恢复失败稍后请手动恢复,数据库备份文件路径:' . $backup_dir . ',失败原因:' . $e->getMessage() . $e->getFile() . $e->getLine(); Cache::set($this->cache_key, $this->upgrade_task); return true; @@ -686,6 +819,7 @@ class UpgradeService extends BaseAdminService public function restoreComplete() { + ( new UpgradeRecordsService() )->failed($this->upgrade_task[ 'key' ], $this->upgrade_task['error']); $this->clearUpgradeTask(2); return true; } @@ -698,18 +832,46 @@ class UpgradeService extends BaseAdminService */ public function getUpgradeContent(string $addon = '') { + $content = [ + 'content' => [], + 'upgrade_apps' => [] + ]; + $upgrade = [ 'product_key' => BaseNiucloudClient::PRODUCT ]; + $apps = []; if (!$addon) { $upgrade[ 'app_key' ] = AddonDict::FRAMEWORK_KEY; $upgrade[ 'version' ] = config('version.version'); + array_push($apps, $upgrade); } else { - $upgrade[ 'app_key' ] = $addon; - $upgrade[ 'version' ] = ( new Addon() )->where([ [ 'key', '=', $addon ] ])->value('version'); + $addons = array_filter(explode(',', $addon)); + foreach ($addons as $key) { + $info = ( new Addon() )->where([ [ 'key', '=', $key ] ])->field('version,type')->find(); + $upgrade[ 'app_key' ] = $key; + $upgrade[ 'version' ] = $info['version']; + if ($info['type'] == 'app') { + array_unshift($apps, $upgrade); + } else { + array_push($apps, $upgrade); + } + } } - return ( new CoreModuleService() )->getUpgradeContent($upgrade)[ 'data' ] ?? []; + foreach ($apps as $item) { + $upgrade_content = ( new CoreModuleService() )->getUpgradeContent($item)[ 'data' ] ?? []; + if (!empty($upgrade_content)) { + $content['content'][] = $upgrade_content; + $content['upgrade_apps'][] = $upgrade_content['app']['app_key']; + } + } + + if (!empty($content['content'])) { + $content['last_backup'] = (new SysBackupRecords())->where([ ['status', '=', BackupDict::STATUS_COMPLETE ] ])->order('complete_time desc')->find(); + } + + return $content; } /** @@ -725,13 +887,20 @@ class UpgradeService extends BaseAdminService * 清除升级任务 * @return true */ - public function clearUpgradeTask(int $delayed = 0) + public function clearUpgradeTask(int $delayed = 0, int $is_active = 0) { + // 主动取消升级 + if ($is_active && $this->upgrade_task && !empty($this->upgrade_task[ 'key' ])) { + ( new UpgradeRecordsService() )->edit([ [ 'upgrade_key', '=', $this->upgrade_task[ 'key' ] ], ['status', '=', UpgradeDict::STATUS_READY ] ], ['status' => UpgradeDict::STATUS_CANCEL]); + } + if ($delayed) { Cache::set($this->cache_key, $this->upgrade_task, $delayed); } else { Cache::set($this->cache_key, null); } + // 清除云编译的任务缓存 + ( new CoreCloudBuildService() )->clearTask(); return true; } diff --git a/niucloud/app/service/admin/upload/StorageConfigService.php b/niucloud/app/service/admin/upload/StorageConfigService.php index 9a10d97e1..6fecb6110 100644 --- a/niucloud/app/service/admin/upload/StorageConfigService.php +++ b/niucloud/app/service/admin/upload/StorageConfigService.php @@ -45,7 +45,7 @@ class StorageConfigService extends BaseAdminService $data = []; $data['storage_type'] = $k; $data['is_use'] = $k == $config_type['default'] ? StorageDict::ON : StorageDict::OFF; - $data['name'] = $v['name']; + $data['name'] = ($this->site_id != 0 && $k == StorageDict::LOCAL) ? ($v['site_name'] ?? $v['name']) : $v['name']; $data['component'] = $v['component']; foreach ($v['params'] as $k_param => $v_param) { $value = $config_type[$k][$k_param] ?? ''; diff --git a/niucloud/app/service/admin/wxoplatform/OplatformService.php b/niucloud/app/service/admin/wxoplatform/OplatformService.php index b68723b66..2476f4b16 100644 --- a/niucloud/app/service/admin/wxoplatform/OplatformService.php +++ b/niucloud/app/service/admin/wxoplatform/OplatformService.php @@ -64,13 +64,16 @@ class OplatformService extends BaseAdminService $this->weappCheck($authorizer_info, $authorization_info); $service = new CoreWeappConfigService(); - $service->setWeappConfig($this->site_id, [ + $config_data = [ 'weapp_name' => $authorizer_info['nick_name'], 'weapp_original' => $authorizer_info['user_name'], 'app_id' => $authorization_info['authorizer_appid'], 'qr_code' => (new CoreFetchService())->image($authorizer_info['qrcode_url'], $this->site_id, $qrcode_dir)['url'], 'is_authorization' => 1 - ]); + ]; + $service->setWeappConfig($this->site_id, $config_data); + + $result['authorizer_info']['qrcode_url'] = $config_data['qr_code']; $service->setWeappAuthorizationInfo($this->site_id, $result); // 授权成功之后调用 @@ -79,13 +82,15 @@ class OplatformService extends BaseAdminService $this->wechatCheck($authorizer_info, $authorization_info); $service = new CoreWechatConfigService(); - $service->setWechatConfig($this->site_id, [ + $config_data = [ 'wechat_name' => $authorizer_info['nick_name'], 'wechat_original' => $authorizer_info['user_name'], 'app_id' => $authorization_info['authorizer_appid'], 'qr_code' => (new CoreFetchService())->image($authorizer_info['qrcode_url'], $this->site_id, $qrcode_dir)['url'], 'is_authorization' => 1 - ]); + ]; + $service->setWechatConfig($this->site_id, $config_data); + $result['authorizer_info']['qrcode_url'] = $config_data['qr_code']; $service->setWechatAuthorizationInfo($this->site_id, $result); // 授权成功之后调用 @@ -153,4 +158,14 @@ class OplatformService extends BaseAdminService if (!in_array($k, $authority)) throw new CommonException("请将{$v}的权限授权给我们"); } } + + public function getAuthRecord($data) { + $condition = [ + ['config_key', 'in', [ ConfigKeyDict::WECHAT_AUTHORIZATION_INFO, ConfigKeyDict::WEAPP_AUTHORIZATION_INFO ] ] + ]; + $search_model = (new SysConfig())->field('*')->where($condition)->with(['site' => function($query){ + $query->field('site_id,site_name'); + }])->order('update_time desc'); + return $this->pageQuery($search_model); + } } diff --git a/niucloud/app/service/admin/wxoplatform/WeappVersionService.php b/niucloud/app/service/admin/wxoplatform/WeappVersionService.php index 9a6a4fbf9..98a68994d 100644 --- a/niucloud/app/service/admin/wxoplatform/WeappVersionService.php +++ b/niucloud/app/service/admin/wxoplatform/WeappVersionService.php @@ -86,6 +86,7 @@ class WeappVersionService extends BaseAdminService 'version_no' => $version_no, 'create_time' => time(), 'task_key' => $upload_res['key'], + 'template_id' => '' ]); // 获取小程序版本提交结果 @@ -179,8 +180,6 @@ class WeappVersionService extends BaseAdminService if ($template_item['user_version'] == $version['user_version']) { (new WxOplatfromWeappVersion())->update(['template_id' => $template_item['template_id'] ], ['task_key' => $task_key]); - (new self())->getSiteGroupAuthWeapp($version['site_group_id']); - // 删除之前的模板 $prev = (new WxOplatfromWeappVersion())->where([ [ 'site_group_id', '=', $version['site_group_id'] ], ['id', '<', $version['id'] ] ])->order('id desc')->findOrEmpty(); if (!$prev->isEmpty() && !empty($prev['template_id'])) { @@ -201,11 +200,14 @@ class WeappVersionService extends BaseAdminService } /** - * 查询站点下是否存在已授权的小程序 + * 同步站点套餐中已授权的小程序 * @param $site_group_id * @return void */ - private function getSiteGroupAuthWeapp($site_group_id) { + public function syncSiteGroupAuthWeapp($site_group_id) { + $version = (new WxOplatfromWeappVersion())->where([ ['site_group_id', '=', $site_group_id], ['template_id', '<>', ''] ])->order('id desc')->findOrEmpty(); + if ($version->isEmpty()) throw new CommonException('NOT_YET_PRESENT_TEMPLATE_LIBRARY'); + $site_ids = (new Site())->where([ ['group_id', '=', $site_group_id] ])->column('site_id'); if (!empty($site_ids)) { $auth_site_ids = (new SysConfig())->where([ ['site_id', 'in', $site_ids ], ['config_key', '=', 'weapp_authorization_info'] ])->column('site_id'); @@ -360,4 +362,26 @@ class WeappVersionService extends BaseAdminService ]); return true; } + + /** + * 撤销审核 + * @return void + */ + public function undoAudit($id) { + $model = new WeappVersion(); + $version = $model->where([ ['site_id', '=', $this->site_id], ['id', '=', $id] ])->findOrEmpty(); + if ($version->isEmpty()) throw new CommonException('WEAPP_VERSION_NOT_EXIST'); + if ($version->status != CloudDict::APPLET_AUDITING) throw new CommonException('NOT_ALLOWED_CANCEL_AUDIT'); + + $result = CoreOplatformService::undocodeAudit($this->site_id); + if (isset($result['errcode']) && $result['errcode'] != 0) throw new CommonException($result['errmsg']); + + $update_data = [ + 'status' => CloudDict::APPLET_AUDIT_UNDO, + 'update_time' => time() + ]; + (new WeappVersion())->update($update_data, [ 'id' => $id ]); + return true; + } + } diff --git a/niucloud/app/service/api/diy/DiyConfigService.php b/niucloud/app/service/api/diy/DiyConfigService.php index 823fa569b..e20640e98 100644 --- a/niucloud/app/service/api/diy/DiyConfigService.php +++ b/niucloud/app/service/api/diy/DiyConfigService.php @@ -95,4 +95,4 @@ class DiyConfigService extends BaseApiService return ( new CoreDiyConfigService() )->getStartUpPageConfig($this->site_id, $type); } -} \ No newline at end of file +} diff --git a/niucloud/app/service/core/addon/CoreAddonCloudService.php b/niucloud/app/service/core/addon/CoreAddonCloudService.php index ae064885b..216961681 100644 --- a/niucloud/app/service/core/addon/CoreAddonCloudService.php +++ b/niucloud/app/service/core/addon/CoreAddonCloudService.php @@ -294,7 +294,7 @@ class CoreAddonCloudService extends CoreCloudBaseService * @param string $token * @return void */ - public function downloadUpgradeFile(string $token, string $dir = '', int $index = -1, $step = 0, $length = 0) { + public function downloadUpgradeFile(string $app_key, string $token, string $dir = '', int $index = -1, $step = 0, $length = 0) { $query = [ 'authorize_code' => $this->auth_code, 'token' => $token @@ -310,7 +310,7 @@ class CoreAddonCloudService extends CoreCloudBaseService $step = (int)ceil($length / $chunk_size); $index++; - return compact('token', 'dir', 'index', 'step', 'length'); + return compact('app_key', 'token', 'dir', 'index', 'step', 'length'); } else { $zip_file = $dir . 'upgrade.zip'; $zip_resource = fopen($zip_file, 'a'); @@ -327,7 +327,7 @@ class CoreAddonCloudService extends CoreCloudBaseService fclose($zip_resource); $index++; - return compact('token', 'dir', 'index', 'step', 'length'); + return compact('app_key', 'token', 'dir', 'index', 'step', 'length'); } else { $zip = new \ZipArchive(); if ($zip->open($zip_file) === true) { diff --git a/niucloud/app/service/core/addon/CoreAddonService.php b/niucloud/app/service/core/addon/CoreAddonService.php index 591ddd9fd..c492de3e8 100644 --- a/niucloud/app/service/core/addon/CoreAddonService.php +++ b/niucloud/app/service/core/addon/CoreAddonService.php @@ -31,6 +31,13 @@ class CoreAddonService extends CoreAddonBaseService $this->model = new Addon(); } + public function getInitList() + { + return [ + 'type_list' => AddonDict::getType() + ]; + } + /** * 获取已下载的插件 * @return array @@ -60,7 +67,7 @@ class CoreAddonService extends CoreAddonBaseService $list[$v['app']['app_key']] = $data; } $online_app_list = array_column($list, 'key'); - } catch ( Throwable $e ) { + } catch (Throwable $e) { $error = $e->getMessage(); } $files = get_files_by_dir($this->addon_path); @@ -74,7 +81,7 @@ class CoreAddonService extends CoreAddonBaseService $data['install_info'] = $install_addon_list[$key] ?? []; $data['is_download'] = true; $data['is_local'] = in_array($data['key'], $online_app_list) ? false : true; - $data['version'] = isset($list[ $data['key'] ]) ? $list[ $data['key'] ]['version'] : $data['version']; + $data['version'] = isset($list[$data['key']]) ? $list[$data['key']]['version'] : $data['version']; $list[$key] = $data; } } @@ -206,7 +213,8 @@ class CoreAddonService extends CoreAddonBaseService * 查询已安装的有效的应用 * @return array */ - public function getInstallAddonList(){ + public function getInstallAddonList() + { $addon_list = $this->model->where([['status', '=', AddonDict::ON]])->append(['status_name'])->column('title, icon, key, desc, status, type, support_app', 'key'); if (!empty($addon_list)) { foreach ($addon_list as &$data) { @@ -267,13 +275,31 @@ class CoreAddonService extends CoreAddonBaseService $data['cover'] = is_file($data['cover']) ? image_to_base64($data['cover']) : ''; $data['type_name'] = empty($data['type']) ? '' : AddonDict::getType()[$data['type']] ?? ''; } - if(isset($data['support_app']) && !empty($data['support_app'])) - { + if (isset($data['support_app']) && !empty($data['support_app'])) { $data['support_type'] = 2; - }else{ + } else { $data['support_type'] = 1; } return $data; } + /** + * 获取首页应用标签 + * @return array + */ + public function getIndexAddonLabelList() + { + return (new CoreModuleService())->getIndexModuleLabelList()['data'] ?? []; + } + + /** + * 获取首页应用 + * @param int $label_id + * @return array + */ + public function getIndexAddonList($label_id) + { + return (new CoreModuleService())->getIndexModuleList($label_id)['data'] ?? []; + } + } diff --git a/niucloud/app/service/core/http/HttpHelper.php b/niucloud/app/service/core/http/HttpHelper.php new file mode 100644 index 000000000..544859df5 --- /dev/null +++ b/niucloud/app/service/core/http/HttpHelper.php @@ -0,0 +1,92 @@ +formatNiuCloudReturn($this->httpRequest('GET', $url, $data)); + } + + public function put($url, $data = []) + { + return $this->formatNiuCloudReturn($this->httpRequest('PUT', $url, $data)); + } + + public function post($url, $data = []) + { + return $this->formatNiuCloudReturn($this->httpRequest('POST', $url, $data)); + } + + public function formatNiuCloudReturn($return) + { + if ($return['code'] != 1) { + throw new \Exception($return['msg']); + } + return $return['data']; + } + + /** + * @param string $method + * @param string $url + * @param array $data + * @return mixed + * @throws \Exception + */ + public function httpRequest(string $method, string $url, array $data = []) + { + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + if (!empty($_SERVER['HTTP_USER_AGENT'])) { + curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); + } + curl_setopt($curl, CURLOPT_TIMEOUT, 30); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_HEADER, false); + curl_setopt($curl, CURLOPT_PROXY, ''); // 清空代理设置 + curl_setopt($curl, CURLOPT_HTTPHEADER, [ + 'Content-Type: application/json; charset=utf-8', + ]); + + // 根据请求方法设置不同的CURL选项 + switch (strtoupper($method)) { + case 'POST': + curl_setopt($curl, CURLOPT_POST, true); + curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data)); + break; + case 'PUT': + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); + curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data)); + break; + case 'GET': + // 对于GET请求,参数通常放在URL中,而不是请求体 + if (!empty($data)) { + $url = $url . (strpos($url, '?') === false ? '?' : '&') . http_build_query($data); + curl_setopt($curl, CURLOPT_URL, $url); + } + // 同时设置HTTP基本认证的另一种方式(保留原代码中的设置) + curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); +// curl_setopt($curl, CURLOPT_USERPWD, "[$username]:[$password]"); + break; + default: + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, strtoupper($method)); + if (!empty($data)) { + curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data)); + } + } + + $result = curl_exec($curl); + if (curl_errno($curl)) { + throw new \Exception(curl_error($curl)); + } + curl_close($curl); + $response_data = json_decode($result, true); + if(empty($response_data)){ + throw new \Exception("SYSTEM_IS_ERROR"); + } + return $response_data; + } +} \ No newline at end of file diff --git a/niucloud/app/service/core/member/CoreMemberService.php b/niucloud/app/service/core/member/CoreMemberService.php index ca28c8c99..eb3dc6bc5 100644 --- a/niucloud/app/service/core/member/CoreMemberService.php +++ b/niucloud/app/service/core/member/CoreMemberService.php @@ -48,6 +48,8 @@ class CoreMemberService extends BaseCoreService { $field_name = match ($field) { 'nickname' => 'nickname', + 'mobile' => 'mobile', + 'id_card' => 'id_card', 'headimg' => 'headimg', 'member_label' => 'member_label', 'member_level' => 'member_level', diff --git a/niucloud/app/service/core/menu/CoreMenuService.php b/niucloud/app/service/core/menu/CoreMenuService.php index 2b1455812..2847e201a 100644 --- a/niucloud/app/service/core/menu/CoreMenuService.php +++ b/niucloud/app/service/core/menu/CoreMenuService.php @@ -57,9 +57,9 @@ class CoreMenuService extends BaseCoreService */ public function deleteByAddon(string $addon, bool $is_all = true) { - $where = [['addon', '=', $addon]]; - if(!$is_all){ - $where[] = ['source', '=', MenuDict::SYSTEM]; + $where = [ [ 'addon', '=', $addon ] ]; + if (!$is_all) { + $where[] = [ 'source', '=', MenuDict::SYSTEM ]; } Db::name("sys_menu")->where($where)->delete(); return true; @@ -71,9 +71,9 @@ class CoreMenuService extends BaseCoreService public function refreshAllAddonMenu() { - $addons = (new Addon())->field("key")->select()->toArray(); + $addons = ( new Addon() )->field("key")->select()->toArray(); foreach ($addons as $k => $v) { - $this->refreshAddonMenu($v["key"]); + $this->refreshAddonMenu($v[ "key" ]); } return true; } @@ -87,21 +87,24 @@ class CoreMenuService extends BaseCoreService { $addon_loader = new DictLoader("Menu"); - $addon_admin_tree = $addon_loader->load(["addon" => $addon, "app_type" => "admin"]); - $addon_site_tree = $addon_loader->load(["addon" => $addon, "app_type" => "site"]); + $addon_admin_tree = $addon_loader->load([ "addon" => $addon, "app_type" => "admin" ]); + $addon_site_tree = $addon_loader->load([ "addon" => $addon, "app_type" => "site" ]); + + if (isset($addon_admin_tree[ 'delete' ])) unset($addon_admin_tree[ 'delete' ]); + if (isset($addon_site_tree[ 'delete' ])) unset($addon_site_tree[ 'delete' ]); - if (isset($addon_admin_tree['delete'])) unset($addon_admin_tree['delete']); - if (isset($addon_site_tree['delete'])) unset($addon_site_tree['delete']); $menu_list = []; + if (!empty($addon_admin_tree)) { $menu_list = array_merge($menu_list, $this->loadMenu($addon_admin_tree, "admin", $addon)); } + if (!empty($addon_site_tree)) { $menu_list = array_merge($menu_list, $this->loadMenu($addon_site_tree, "site", $addon)); } + $this->deleteByAddon($addon, false); - if(!empty($menu_list)) - { + if (!empty($menu_list)) { $this->install($menu_list); } @@ -134,28 +137,28 @@ class CoreMenuService extends BaseCoreService if (is_array($tree)) { foreach ($tree as $key => $value) { $item = [ - 'menu_name' => $value['menu_name'], - 'menu_short_name' => $value['menu_short_name'] ?? '', - 'menu_key' => $value['menu_key'], + 'menu_name' => $value[ 'menu_name' ], + 'menu_short_name' => $value[ 'menu_short_name' ] ?? '', + 'menu_key' => $value[ 'menu_key' ], 'app_type' => $app_type, 'addon' => $addon, - 'parent_key' => $value['parent_key'] ?? $parent_key, - 'menu_type' => $value['menu_type'], - 'icon' => $value['icon'] ?? '', - 'api_url' => $value['api_url'] ?? '', - 'router_path' => $value['router_path'] ?? '', - 'view_path' => $value['view_path'] ?? '', - 'methods' => $value['methods'] ?? '', - 'sort' => $value['sort'] ?? '', + 'parent_key' => $value[ 'parent_key' ] ?? $parent_key, + 'menu_type' => $value[ 'menu_type' ], + 'icon' => $value[ 'icon' ] ?? '', + 'api_url' => $value[ 'api_url' ] ?? '', + 'router_path' => $value[ 'router_path' ] ?? '', + 'view_path' => $value[ 'view_path' ] ?? '', + 'methods' => $value[ 'methods' ] ?? '', + 'sort' => $value[ 'sort' ] ?? '', 'status' => 1, - 'is_show' => $value['is_show'] ?? 1 + 'is_show' => $value[ 'is_show' ] ?? 1 ]; $refer = $value; - if (isset($refer['children'])) { - unset($refer['children']); + if (isset($refer[ 'children' ])) { + unset($refer[ 'children' ]); $menu_list[] = $item; - $p_key = $refer['menu_key']; - $this->menuTreeToList($value['children'], $p_key, $app_type, $addon, $menu_list); + $p_key = $refer[ 'menu_key' ]; + $this->menuTreeToList($value[ 'children' ], $p_key, $app_type, $addon, $menu_list); } else { $menu_list[] = $item; } @@ -185,12 +188,13 @@ class CoreMenuService extends BaseCoreService * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException */ - public function getRoutePathByMenuKey($menu_key, $paths = []) { - $menu = $this->model->where([ ['menu_key', '=', $menu_key], ['app_type', '=', 'site'] ])->field('parent_key,router_path')->find(); + public function getRoutePathByMenuKey($menu_key, $paths = []) + { + $menu = $this->model->where([ [ 'menu_key', '=', $menu_key ], [ 'app_type', '=', 'site' ] ])->field('parent_key,router_path')->find(); if (empty($menu)) return ''; - array_unshift($paths, $menu['router_path']); - if (!empty($menu['parent_key'])) { - return $this->getRoutePathByMenuKey($menu['parent_key'], $paths); + array_unshift($paths, $menu[ 'router_path' ]); + if (!empty($menu[ 'parent_key' ])) { + return $this->getRoutePathByMenuKey($menu[ 'parent_key' ], $paths); } else { return implode('/', $paths); } diff --git a/niucloud/app/service/core/niucloud/CoreCloudBuildService.php b/niucloud/app/service/core/niucloud/CoreCloudBuildService.php index 305766f37..20462d190 100644 --- a/niucloud/app/service/core/niucloud/CoreCloudBuildService.php +++ b/niucloud/app/service/core/niucloud/CoreCloudBuildService.php @@ -43,7 +43,7 @@ class CoreCloudBuildService extends BaseCoreService parent::__construct(); $this->root_path = project_path(); $this->build_task = Cache::get($this->cache_key); - $this->auth_code = ( new CoreNiucloudConfigService() )->getNiucloudConfig()[ 'auth_code' ] ?? ''; + $this->auth_code = (new CoreNiucloudConfigService())->getNiucloudConfig()['auth_code'] ?? ''; } /** @@ -78,35 +78,35 @@ class CoreCloudBuildService extends BaseCoreService clearstatcache(); // 校验niucloud/public niucloud/vendor 目录是否可读可写 - $data[ 'dir' ][ 'is_readable' ][] = [ 'dir' => str_replace(project_path(), '', public_path()), 'status' => is_readable(public_path()) ]; - $data[ 'dir' ][ 'is_readable' ][] = [ 'dir' => str_replace(project_path(), '', $niucloud_dir . 'vendor'), 'status' => is_readable($niucloud_dir . 'vendor') ]; + $data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', public_path()), 'status' => is_readable(public_path())]; + $data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', $niucloud_dir . 'vendor'), 'status' => is_readable($niucloud_dir . 'vendor')]; - $data[ 'dir' ][ 'is_write' ][] = [ 'dir' => str_replace(project_path(), '', public_path()), 'status' => is_write(public_path()) ]; - $data[ 'dir' ][ 'is_write' ][] = [ 'dir' => str_replace(project_path(), '', $niucloud_dir . 'vendor'), 'status' => is_write($niucloud_dir . 'vendor') ]; + $data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', public_path()), 'status' => is_write(public_path())]; + $data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', $niucloud_dir . 'vendor'), 'status' => is_write($niucloud_dir . 'vendor')]; // 校验niucloud/public下 wap web admin 目录及文件是否可读可写 $check_res = checkDirPermissions(public_path() . 'wap'); $check_res = array_merge2($check_res, checkDirPermissions(public_path() . 'admin')); $check_res = array_merge2($check_res, checkDirPermissions(public_path() . 'web')); - if (!empty($check_res[ 'unreadable' ])) { - foreach ($check_res[ 'unreadable' ] as $item) { - $data[ 'dir' ][ 'is_readable' ][] = [ 'dir' => str_replace(project_path(), '', $item), 'status' => false ]; + if (!empty($check_res['unreadable'])) { + foreach ($check_res['unreadable'] as $item) { + $data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', $item), 'status' => false]; } } - if (!empty($check_res[ 'not_writable' ])) { - foreach ($check_res[ 'not_writable' ] as $item) { - $data[ 'dir' ][ 'is_write' ][] = [ 'dir' => str_replace(project_path(), '', $item), 'status' => false ]; + if (!empty($check_res['not_writable'])) { + foreach ($check_res['not_writable'] as $item) { + $data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', $item), 'status' => false]; } } $check_res = array_merge( - array_column($data[ 'dir' ][ 'is_readable' ], 'status'), - array_column($data[ 'dir' ][ 'is_write' ], 'status') + array_column($data['dir']['is_readable'], 'status'), + array_column($data['dir']['is_write'], 'status') ); // 是否通过校验 - $data[ 'is_pass' ] = !in_array(false, $check_res); + $data['is_pass'] = !in_array(false, $check_res); return $data; } @@ -117,9 +117,12 @@ class CoreCloudBuildService extends BaseCoreService */ public function cloudBuild() { + if (empty($this->auth_code)) { + throw new CommonException('CLOUD_BUILD_AUTH_CODE_NOT_FOUND'); + } if ($this->build_task) throw new CommonException('CLOUD_BUILD_TASK_EXIST'); - $action_token = ( new CoreModuleService() )->getActionToken('cloudbuild', [ 'data' => [ 'product_key' => BaseNiucloudClient::PRODUCT ] ]); + $action_token = (new CoreModuleService())->getActionToken('cloudbuild', ['data' => ['product_key' => BaseNiucloudClient::PRODUCT]]); // 上传任务key $task_key = uniqid(); @@ -131,33 +134,33 @@ class CoreCloudBuildService extends BaseCoreService // 拷贝composer文件 file_put_contents($package_dir . 'composer.json', file_get_contents(root_path() . 'composer.json')); // 拷贝手机端文件 - $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()) { - 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']); $this->handleUniapp($package_dir . 'uni-app'); } // 拷贝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()) { - 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']); } // 拷贝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()) { - 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']); } $this->handleCustomPort($package_dir); $zip_file = $temp_dir . DIRECTORY_SEPARATOR . 'build.zip'; - ( new CoreAddonDevelopDownloadService('') )->compressToZip($package_dir, $zip_file); + (new CoreAddonDevelopDownloadService(''))->compressToZip($package_dir, $zip_file); $query = [ 'authorize_code' => $this->auth_code, 'timestamp' => time(), - 'token' => $action_token[ 'data' ][ 'token' ] ?? '' + 'token' => $action_token['data']['token'] ?? '' ]; - $response = ( new CloudService() )->httpPost('cloud/build?' . http_build_query($query), [ + $response = (new CloudService())->httpPost('cloud/build?' . http_build_query($query), [ 'multipart' => [ [ 'name' => 'file', @@ -167,11 +170,11 @@ class CoreCloudBuildService extends BaseCoreService ], 'timeout' => 300.0 ]); - if (isset($response[ 'code' ]) && $response[ 'code' ] == 0) throw new CloudBuildException($response[ 'msg' ]); + if (isset($response['code']) && $response['code'] == 0) throw new CloudBuildException($response['msg']); $this->build_task = [ 'task_key' => $task_key, - 'timestamp' => $query[ 'timestamp' ] + 'timestamp' => $query['timestamp'] ]; Cache::set($this->cache_key, $this->build_task); @@ -180,7 +183,7 @@ class CoreCloudBuildService extends BaseCoreService private function handleUniapp(string $dir) { - $addon = ( new Addon() )->where([ [ 'status', '=', AddonDict::ON ] ])->value('key', ''); + $addon = (new Addon())->where([['status', '=', AddonDict::ON]])->value('key', ''); $this->compileDiyComponentsCode($dir . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR, $addon); } @@ -189,13 +192,13 @@ class CoreCloudBuildService extends BaseCoreService $addons = get_site_addons(); foreach ($addons as $addon) { - $custom_port = ( new CoreAddonBaseService() )->getAddonConfig($addon)[ 'port' ] ?? []; + $custom_port = (new CoreAddonBaseService())->getAddonConfig($addon)['port'] ?? []; if (!empty($custom_port)) { $addon_path = root_path() . 'addon' . DIRECTORY_SEPARATOR . $addon . DIRECTORY_SEPARATOR; foreach ($custom_port as $port) { - if (is_dir($addon_path . $port[ 'name' ])) { - dir_copy($addon_path . $port[ 'name' ], $package_dir . $port[ 'name' ]); - $json_path = $package_dir . $port[ 'name' ] . DIRECTORY_SEPARATOR . 'info.json'; + if (is_dir($addon_path . $port['name'])) { + dir_copy($addon_path . $port['name'], $package_dir . $port['name']); + $json_path = $package_dir . $port['name'] . DIRECTORY_SEPARATOR . 'info.json'; file_put_contents($json_path, json_encode($port)); } } @@ -222,14 +225,14 @@ class CoreCloudBuildService extends BaseCoreService $query = [ 'authorize_code' => $this->auth_code, - 'timestamp' => $this->build_task[ 'timestamp' ] + 'timestamp' => $this->build_task['timestamp'] ]; - $build_log = ( new CloudService() )->httpGet('cloud/get_build_logs?' . http_build_query($query)); + $build_log = (new CloudService())->httpGet('cloud/get_build_logs?' . http_build_query($query)); - if (isset($build_log[ 'data' ]) && isset($build_log[ 'data' ][ 0 ]) && is_array($build_log[ 'data' ][ 0 ])) { - $last = end($build_log[ 'data' ][ 0 ]); - if ($last[ 'percent' ] == 100 && $last[ 'code' ] == 1) { - $build_log[ 'data' ][ 0 ] = $this->buildSuccess($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]); + if ($last['percent'] == 100 && $last['code'] == 1) { + $build_log['data'][0] = $this->buildSuccess($build_log['data'][0]); } } return $build_log; @@ -245,40 +248,40 @@ class CoreCloudBuildService extends BaseCoreService try { $query = [ 'authorize_code' => $this->auth_code, - 'timestamp' => $this->build_task[ 'timestamp' ] + 'timestamp' => $this->build_task['timestamp'] ]; $chunk_size = 1 * 1024 * 1024; - $temp_dir = runtime_path() . 'backup' . DIRECTORY_SEPARATOR . 'cloud_build' . DIRECTORY_SEPARATOR . $this->build_task[ 'task_key' ] . DIRECTORY_SEPARATOR; + $temp_dir = runtime_path() . 'backup' . DIRECTORY_SEPARATOR . 'cloud_build' . DIRECTORY_SEPARATOR . $this->build_task['task_key'] . DIRECTORY_SEPARATOR; - if (!isset($this->build_task[ 'index' ])) { - $response = ( new CloudService() )->request('HEAD', 'cloud/build_download?' . http_build_query($query), [ - 'headers' => [ 'Range' => 'bytes=0-' ] + if (!isset($this->build_task['index'])) { + $response = (new CloudService())->request('HEAD', 'cloud/build_download?' . http_build_query($query), [ + 'headers' => ['Range' => 'bytes=0-'] ]); $length = $response->getHeader('Content-range'); - $length = (int) explode("/", $length[ 0 ])[ 1 ]; - $step = (int) ceil($length / $chunk_size); + $length = (int)explode("/", $length[0])[1]; + $step = (int)ceil($length / $chunk_size); - $this->build_task = array_merge($this->build_task, [ 'step' => $step, 'index' => 0, 'length' => $length ]); + $this->build_task = array_merge($this->build_task, ['step' => $step, 'index' => 0, 'length' => $length]); Cache::set($this->cache_key, $this->build_task); } else { $zip_file = $temp_dir . 'download.zip'; $zip_resource = fopen($zip_file, 'a'); - if (( $this->build_task[ 'index' ] + 1 ) <= $this->build_task[ 'step' ]) { - $start = $this->build_task[ 'index' ] * $chunk_size; - $end = ( $this->build_task[ 'index' ] + 1 ) * $chunk_size; - $end = min($end, $this->build_task[ 'length' ]); + if (($this->build_task['index'] + 1) <= $this->build_task['step']) { + $start = $this->build_task['index'] * $chunk_size; + $end = ($this->build_task['index'] + 1) * $chunk_size; + $end = min($end, $this->build_task['length']); - $response = ( new CloudService() )->request('GET', 'cloud/build_download?' . http_build_query($query), [ - 'headers' => [ 'Range' => "bytes={$start}-{$end}" ] + $response = (new CloudService())->request('GET', 'cloud/build_download?' . http_build_query($query), [ + 'headers' => ['Range' => "bytes={$start}-{$end}"] ]); fwrite($zip_resource, $response->getBody()); fclose($zip_resource); - $this->build_task[ 'index' ] += 1; + $this->build_task['index'] += 1; Cache::set($this->cache_key, $this->build_task); - $log[] = [ 'code' => 1, 'action' => '编译包下载中,已下载' . round($this->build_task[ 'index' ] / $this->build_task[ 'step' ] * 100) . '%', 'percent' => '100' ]; + $log[] = ['code' => 1, 'action' => '编译包下载中,已下载' . round($this->build_task['index'] / $this->build_task['step'] * 100) . '%', 'percent' => '100']; } else { // 解压文件 $zip = new \ZipArchive(); @@ -302,12 +305,12 @@ class CoreCloudBuildService extends BaseCoreService $this->clearTask(); } else { - $log[] = [ 'code' => 0, 'msg' => '编译包解压失败', 'action' => '编译包解压', 'percent' => '100' ]; + $log[] = ['code' => 0, 'msg' => '编译包解压失败', 'action' => '编译包解压', 'percent' => '100']; } } } } catch (\Exception $e) { - $log[] = [ 'code' => 0, 'msg' => $e->getMessage(), 'action' => '', 'percent' => '100' ]; + $log[] = ['code' => 0, 'msg' => $e->getMessage(), 'action' => '', 'percent' => '100']; $this->clearTask(); } return $log; @@ -320,7 +323,7 @@ class CoreCloudBuildService extends BaseCoreService public function clearTask() { if (!$this->build_task) return; - $temp_dir = runtime_path() . 'backup' . DIRECTORY_SEPARATOR . 'cloud_build' . DIRECTORY_SEPARATOR . $this->build_task[ 'task_key' ] . DIRECTORY_SEPARATOR;; + $temp_dir = runtime_path() . 'backup' . DIRECTORY_SEPARATOR . 'cloud_build' . DIRECTORY_SEPARATOR . $this->build_task['task_key'] . DIRECTORY_SEPARATOR;; @del_target_dir($temp_dir, true); Cache::set($this->cache_key, null); } diff --git a/niucloud/app/service/core/niucloud/CoreModuleService.php b/niucloud/app/service/core/niucloud/CoreModuleService.php index 796286220..a0678592c 100644 --- a/niucloud/app/service/core/niucloud/CoreModuleService.php +++ b/niucloud/app/service/core/niucloud/CoreModuleService.php @@ -33,6 +33,28 @@ class CoreModuleService extends BaseNiucloudClient return $this->httpGet('member_app_all', $params); } + public function getIndexModuleLabelList() + { + $params = [ + 'code' => $this->code, + 'secret' => $this->secret, + ]; + return $this->httpGet('store/label/all', $params); + } + + public function getIndexModuleList($label_id) + { + $params = [ + 'code' => $this->code, + 'secret' => $this->secret, + 'labels' => [$label_id], + 'product_key' => self::PRODUCT, + 'is_recommend' => 1, + 'order_field' => 'sale_num desc, visit_num desc', + ]; + return $this->httpGet('store/app', $params); + } + /** * 授权信息 * @param $module_id diff --git a/niucloud/app/service/core/notice/CoreNiuSmsService.php b/niucloud/app/service/core/notice/CoreNiuSmsService.php new file mode 100644 index 000000000..c9172d5bd --- /dev/null +++ b/niucloud/app/service/core/notice/CoreNiuSmsService.php @@ -0,0 +1,388 @@ +niushop_url_prefix = $niushop_url_prefix; + } + } + + /** + * 设置账号缓存 + * @param $params + * @return \app\model\sys\SysConfig|bool|\think\Model + */ + public function setNiuLoginConfig($params) + { + $config = $this->getNiuLoginConfig(true); + $config['default'] = $params['default'] ?? ($config['default'] ?? ""); + $config[SmsDict::NIUSMS] = [ + 'username' => $params['username'] ?? $config[SmsDict::NIUSMS]['username'] ?? "", + 'password' => $params['password'] ?? $config[SmsDict::NIUSMS]['password'] ?? "", + 'signature' => $params['signature'] ?? $config[SmsDict::NIUSMS]['signature'] ?? "", + ]; + return (new CoreConfigService())->setConfig($this->site_id, ConfigKeyDict::SMS, $config); + } + + public function getNiuLoginConfig($is_all = false) + { + $config = (new CoreConfigService())->getConfigValue($this->site_id, ConfigKeyDict::SMS); + if ($is_all) { + return $config; + } + return $config[SmsDict::NIUSMS] ?? []; + } + + /** + * 发验证短信 + * @param $mobile + * @return mixed + */ + public function packageList($params) + { + $url = $this->niushop_url_prefix . self::PACKAGE_LIST_URL; + $res = (new HttpHelper())->get($url, $params + $this->getPageParam()); + return $res; + } + + /** + * 发验证短信 + * @param $mobile + * @return mixed + */ + public function sendMobileCode($params) + { + $url = $this->niushop_url_prefix . self::SEND_CODE_URL; + $res = (new HttpHelper())->post($url, $params); + return $res; + } + + /** + * 发验证短信 + * @param $mobile + * @return mixed + */ + public function captcha() + { + $url = $this->niushop_url_prefix . self::SEND_CAPTCHA_URL; + $res = (new HttpHelper())->get($url); + return $res; + } + + /** + * 注册牛云短信子账号 + * @param $params + * @return mixed + */ + public function registerAccount($params) + { + $res = (new HttpHelper())->post($this->niushop_url_prefix . self::ACCOUNT_REGISTER_URL, $params); + return $res; + } + + /** + * 登录牛云短信子账号 + * @param $params + * @return mixed + */ + public function loginAccount($params) + { + $url = $this->niushop_url_prefix . sprintf(self::LOGIN_ACCOUNT_URL, $params['username']); + $res = (new HttpHelper())->post($url, $params); + return $res; + } + + /** + * 获取牛云短信子账号信息 + * @param $username + * @return mixed + */ + public function accountInfo($username) + { + $url = $this->niushop_url_prefix . sprintf(self::ACCOUNT_INFO_URL, $username); + $res = (new HttpHelper())->get($url); + $config = $this->getNiuLoginConfig(); + if ($config['username'] == $res['username']) { + $res['signature'] = $config['signature'] ?? ""; + } + return $res; + } + + /** + * 获取牛云短信子账号信息 + * @param $username + * @return mixed + */ + public function accountSendList($username, $params) + { + $url = $this->niushop_url_prefix . sprintf(self::ACCOUNT_SEND_LIST_URL, $username); + $res = (new HttpHelper())->get($url, $this->getPageParam() + $params); + return $res; + } + + /** + * 更新账号信息 (手机号 默认签名) + * @param $username + * @param $params + * @return mixed + */ + public function editAccount($username, $params) + { + $url = $this->niushop_url_prefix . sprintf(self::ACCOUNT_EDIT_URL, $username); + $res = (new HttpHelper())->put($url, $params); + return $res; + } + + /** + * 重置密码 + * @param $username + * @param $params + * @return mixed + */ + public function resetPassword($username, $params) + { + $url = $this->niushop_url_prefix . sprintf(self::RESET_PASSWORD_URL, $username); + $res = (new HttpHelper())->put($url, $params); + return $res; + } + + + /**********************签名处理*********************/ + + /** + * 获取签名列表 + * @param $data + * @return mixed + */ + public function signList($username) + { + $url = $this->niushop_url_prefix . sprintf(self::SIGN_LIST_URL, $username); + $res = (new HttpHelper())->get($url, $this->getPageParam()); + return $res; + } + + /** + * 获取签名信息 + * @param $data + * @return mixed + */ + public function signInfo($username, $signature) + { + $url = $this->niushop_url_prefix . sprintf(self::SIGN_INFO_URL, $username); + $res = (new HttpHelper())->get($url, ['signature' => $signature]); + return $res; + } + + /** + * 报备签名 + * @param $data + * @return mixed + */ + public function signCreate($username, $params) + { + $url = $this->niushop_url_prefix . sprintf(self::SIGN_ADD_URL, $username); + $res = (new HttpHelper())->post($url, $params); + return $res; + } + + /** + * 报备签名 + * @param $data + * @return mixed + */ + public function signDelete($username, $params) + { + $time = time(); + $request['tKey'] = $time; + $request['password'] = md5(md5($params['password']) . $time); + $request['username'] = $username; + $request['remark'] = $params['remark'] ?? ''; + $request['signatureList'] = $params['signatures']; + $url = "https://api-shss.zthysms.com/sms/v1/sign/delete"; + $res = (new HttpHelper())->httpRequest('POST', $url, $request); + if ($res['code'] != 200) { + throw new \Exception($res['msg']); + } + return $res['failList'] ?? []; + + } + + + + /**********************模版处理*********************/ + /** + * 获取模版列表 + * @param $data + * @return mixed + */ + public function templateList($username, $params) + { + $params = array_merge($params, $this->getPageParam()); + $params['limit'] = $params['limit'] ?? 100; + $url = $this->niushop_url_prefix . sprintf(self::TEMPLATE_LIST_URL, $username); + $res = (new HttpHelper())->get($url, $params); + return $res; + } + + /** + * 获取模版详情 + * @param $data + * @return mixed + */ + public function templateInfo($username, $tem_id) + { + $url = $this->niushop_url_prefix . sprintf(self::TEMPLATE_INFO_URL, $username); + $res = (new HttpHelper())->get($url, [ + 'tem_id' => $tem_id + ]); + return $res; + } + + /** + * 获取签名列表 + * @param $params + * @return mixed + */ + public function templateCreate($username, $params) + { + $url = $this->niushop_url_prefix . sprintf(self::TEMPLATE_ADD_URL, $username); + $res = (new HttpHelper())->post($url, $params); + return $res; + } + + + /** + * 获取订单列表 + * @param $params + * @return mixed + */ + public function orderList($username, $params) + { + $url = $this->niushop_url_prefix . sprintf(self::ORDER_LIST_URL, $username); + $res = (new HttpHelper())->get($url, $this->getPageParam() + $params); + return $res; + } + + /** + * 获取订单详情 + * @param $username + * @param $out_trade_no + * @return mixed + */ + public function orderInfo($username, $out_trade_no) + { + $url = $this->niushop_url_prefix . sprintf(self::ORDER_INFO_URL, $username, $out_trade_no); + $res = (new HttpHelper())->get($url); + return $res; + } + + /** + * 获取订单状态 + * @param $username + * @param $out_trade_no + * @return mixed + */ + public function orderStatus($username, $out_trade_no) + { + $url = $this->niushop_url_prefix . sprintf(self::ORDER_STATUS_URL, $username, $out_trade_no); + $res = (new HttpHelper())->get($url); + return $res; + } + + /** + * 创建订单 + * @param $username + * @return mixed + */ + public function orderCreate($username, $params) + { + $url = $this->niushop_url_prefix . sprintf(self::ORDER_CREATE_URL, $username); + $res = (new HttpHelper())->post($url, $params); + return $res; + } + + /** + * 创建订单 + * @param $username + * @return mixed + */ + public function calculate($username, $params) + { + $url = $this->niushop_url_prefix . sprintf(self::ORDER_CALCULATE_URL, $username); + $res = (new HttpHelper())->post($url, $params); + return $res; + } + + /** + * 获取订单支付信息 + * @param $username + * @return mixed + */ + public function orderPayInfo($username, $params) + { + // 判断是否为https协议 + $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http'; + // 获取域名(含端口) + $host = $_SERVER['HTTP_HOST']; + // 组合成全域名 + $return_url = $protocol . '://' . $host . "/site/setting/sms/pay"; + + $url = $this->niushop_url_prefix . sprintf(self::ORDER_PAY_URL, $username); + $params['notify_url'] = $this->niushop_url_prefix . self::ORDER_NOTIFY_URL; + //TODO::待添加支付结果页面 + $params['return_url'] = $return_url; + $res = (new HttpHelper())->post($url, $params); + return $res; + } +} \ No newline at end of file diff --git a/niucloud/app/service/core/notice/CoreNoticeService.php b/niucloud/app/service/core/notice/CoreNoticeService.php index 529c6c058..ccbb759f5 100644 --- a/niucloud/app/service/core/notice/CoreNoticeService.php +++ b/niucloud/app/service/core/notice/CoreNoticeService.php @@ -114,7 +114,9 @@ class CoreNoticeService extends BaseCoreService 'weapp_template_id' => '', 'sms_id' => '', 'wechat_first' => '', - 'wechat_remark' => '' + 'wechat_remark' => '', + 'audit_status'=>'wait', + 'sign'=>'', ]); } $item['notice'][] = $notice_item; diff --git a/niucloud/app/service/core/notice/CoreSmsService.php b/niucloud/app/service/core/notice/CoreSmsService.php index 2bf0be8d1..3a01686e3 100644 --- a/niucloud/app/service/core/notice/CoreSmsService.php +++ b/niucloud/app/service/core/notice/CoreSmsService.php @@ -11,6 +11,7 @@ namespace app\service\core\notice; +use app\dict\sys\ConfigKeyDict; use app\dict\sys\SmsDict; use app\service\core\sys\CoreConfigService; use core\base\BaseCoreService; @@ -91,7 +92,7 @@ class CoreSmsService extends BaseCoreService */ public function getDefaultSmsConfig(int $site_id) { - $info = (new CoreConfigService())->getConfig($site_id, 'SMS')['value'] ?? []; + $info = (new CoreConfigService())->getConfig($site_id, ConfigKeyDict::SMS)['value'] ?? []; if (empty($info)) throw new NoticeException('NOTICE_SMS_NOT_OPEN'); diff --git a/niucloud/app/service/core/notice/NoticeService.php b/niucloud/app/service/core/notice/NoticeService.php index 6466dfa30..156e79133 100644 --- a/niucloud/app/service/core/notice/NoticeService.php +++ b/niucloud/app/service/core/notice/NoticeService.php @@ -35,12 +35,18 @@ class NoticeService extends BaseCoreService * @param $key * @param $data * @return false|mixed + * @throws \Exception */ public static function send($site_id, $key, $data){ - $template = (new CoreNoticeService())->getInfo($site_id, $key); - if(empty($template)) return false; + try { + $template = (new CoreNoticeService())->getInfo($site_id, $key); + if(empty($template)) return false; - return Notice::dispatch(['site_id' => $site_id, 'key' => $key, 'data' => $data, 'template' => $template], is_async:$template['async']); + return Notice::dispatch(['site_id' => $site_id, 'key' => $key, 'data' => $data, 'template' => $template], is_async:$template['async']); + + }catch (\Exception $e){ + throw new \Exception($e->getMessage()); + } } } \ No newline at end of file diff --git a/niucloud/app/service/core/pay/CoreRefundService.php b/niucloud/app/service/core/pay/CoreRefundService.php index 60fcb2f5c..ddb94969b 100644 --- a/niucloud/app/service/core/pay/CoreRefundService.php +++ b/niucloud/app/service/core/pay/CoreRefundService.php @@ -27,6 +27,7 @@ use Throwable; class CoreRefundService extends BaseCoreService { protected $pay_event; + public function __construct() { parent::__construct(); @@ -42,10 +43,18 @@ class CoreRefundService extends BaseCoreService * @param string $reason * @return string|null */ - public function create(int $site_id, string $out_trade_no, float $money, string $reason = '', $trade_type = '', $trade_id = ''){ + public function create(int $site_id, string $out_trade_no, float $money, string $reason = '', $trade_type = '', $trade_id = '') + { //通过交易流水号获取支付单据 - $pay = (new CorePayService())->findPayInfoByOutTradeNo($site_id, $out_trade_no); - if($pay->isEmpty()) throw new PayException('ALIPAY_TRANSACTION_NO_NOT_EXIST');//单据不存在 + $pay = ( new CorePayService() )->findPayInfoByOutTradeNo($site_id, $out_trade_no); + if ($pay->isEmpty()) throw new PayException('ALIPAY_TRANSACTION_NO_NOT_EXIST');//单据不存在 + + // 查询当前支付已存在的退款单据,所有的退款总额不能超过支付单据的支付金额 + $total_refund_money = $this->model->where([ [ 'out_trade_no', '=', $out_trade_no ], [ 'status', '<>', RefundDict::FAIL ] ])->sum('money'); + + $comparison = bccomp(bcadd($total_refund_money, $money), $pay[ 'money' ]); // 浮点数直接进行比较会出现精度问题 + if ($comparison > 0) throw new PayException('退款金额不能超过支付总额'); // 退款金额不能超过支付总额 + //校验当前数据是否存在 //存在就修改,不存在就创建 $refund_no = create_no(); @@ -72,26 +81,27 @@ class CoreRefundService extends BaseCoreService * @param string $voucher * @return true */ - public function refund(int $site_id, string $refund_no, $voucher = '', $refund_type = RefundDict::BACK, $main_type = '', $main_id = 0){ + public function refund(int $site_id, string $refund_no, $voucher = '', $refund_type = RefundDict::BACK, $main_type = '', $main_id = 0) + { $refund = $this->findByRefundNo($site_id, $refund_no); - if($refund->isEmpty()) throw new PayException('REFUND_NOT_EXIST'); + if ($refund->isEmpty()) throw new PayException('REFUND_NOT_EXIST'); $out_trade_no = $refund->out_trade_no; $money = $refund->money; - $pay = (new CorePayService())->findPayInfoByOutTradeNo($site_id, $out_trade_no); - if($pay->isEmpty()) throw new PayException('ALIPAY_TRANSACTION_NO_NOT_EXIST');//单据不存在 - try{ + $pay = ( new CorePayService() )->findPayInfoByOutTradeNo($site_id, $out_trade_no); + if ($pay->isEmpty()) throw new PayException('ALIPAY_TRANSACTION_NO_NOT_EXIST');//单据不存在 + try { //存入退款方式 - $refund->save(['refund_type' => $refund_type]); - if($refund_type == RefundDict::BACK){ + $refund->save([ 'refund_type' => $refund_type ]); + if ($refund_type == RefundDict::BACK) { //判断成功的话,可以直接调用退款成功 - $pay_result = $this->pay_event->init($site_id, $refund->channel, $refund->type)->refund($out_trade_no, $money, $pay['money'], $refund_no, $voucher); + $pay_result = $this->pay_event->init($site_id, $refund->channel, $refund->type)->refund($out_trade_no, $money, $pay[ 'money' ], $refund_no, $voucher); $this->refundNotify($site_id, $out_trade_no, $refund->type, $pay_result); - }else if($refund_type == RefundDict::OFFLINE){ - $pay_result = $this->pay_event->init($site_id, $refund->channel, PayDict::OFFLINEPAY)->refund($out_trade_no, $money, $pay['money'], $refund_no, $voucher); + } else if ($refund_type == RefundDict::OFFLINE) { + $pay_result = $this->pay_event->init($site_id, $refund->channel, PayDict::OFFLINEPAY)->refund($out_trade_no, $money, $pay[ 'money' ], $refund_no, $voucher); $this->refundNotify($site_id, $out_trade_no, $refund->type, $pay_result, $main_type, $main_id); } - }catch ( Throwable $e) { + } catch (Throwable $e) { throw new PayException($e->getMessage()); } return true; @@ -103,10 +113,11 @@ class CoreRefundService extends BaseCoreService * @param string $refund_no * @return void */ - public function findByRefundNo(int $site_id, string $refund_no){ + public function findByRefundNo(int $site_id, string $refund_no) + { return $this->model->where([ - ['site_id', '=', $site_id], - ['refund_no', '=', $refund_no], + [ 'site_id', '=', $site_id ], + [ 'refund_no', '=', $refund_no ], ])->findOrEmpty(); } @@ -121,25 +132,26 @@ class CoreRefundService extends BaseCoreService * @param $main_id * @return true */ - public function refundNotify(int $site_id, $out_trade_no, string $type, array $params = [], $main_type = '', $main_id = 0){ - $refund_no = $params['refund_no']; + public function refundNotify(int $site_id, $out_trade_no, string $type, array $params = [], $main_type = '', $main_id = 0) + { + $refund_no = $params[ 'refund_no' ]; $refund = $this->findByRefundNo($site_id, $refund_no); - if($refund->isEmpty()) throw new PayException('REFUND_NOT_EXIST'); - if(!in_array($refund['status'], [RefundDict::WAIT, RefundDict::DEALING])) throw new PayException('REFUND_IS_CHANGE');//只有待退款和退款中的退款单据可以 + if ($refund->isEmpty()) throw new PayException('REFUND_NOT_EXIST'); + if (!in_array($refund[ 'status' ], [ RefundDict::WAIT, RefundDict::DEALING ])) throw new PayException('REFUND_IS_CHANGE');//只有待退款和退款中的退款单据可以 - $status = $params['status'];//第三方支付的状态,根据状态进行下一步业务 + $status = $params[ 'status' ];//第三方支付的状态,根据状态进行下一步业务 // 启动事务 Db::startTrans(); try { - switch($status){ + switch ($status) { case RefundDict::SUCCESS://退款成功 $this->refundSuccess($site_id, [ 'out_trade_no' => $out_trade_no, 'refund_no' => $refund_no, - 'trade_type' => $refund['trade_type'], - 'trade_id' => $refund['trade_id'], + 'trade_type' => $refund[ 'trade_type' ], + 'trade_id' => $refund[ 'trade_id' ], 'main_type' => $main_type, 'main_id' => $main_id ]); @@ -155,14 +167,14 @@ class CoreRefundService extends BaseCoreService $this->refundFail($site_id, [ 'out_trade_no' => $out_trade_no, 'refund_no' => $refund_no, - 'fail_reason' => $params['fail_reason'] ?? '' + 'fail_reason' => $params[ 'fail_reason' ] ?? '' ]); break; } // 提交事务 Db::commit(); return true; - } catch ( Throwable $e) { + } catch (Throwable $e) { // 回滚事务 Db::rollback(); throw new PayException($e->getMessage()); @@ -175,21 +187,24 @@ class CoreRefundService extends BaseCoreService * @param $data * @return true */ - public function check($site_id, $data){ - $out_trade_no = $data['out_trade_no']; - $refund_no = $data['refund_no']; + public function check($site_id, $data) + { + $out_trade_no = $data[ 'out_trade_no' ]; + $refund_no = $data[ 'refund_no' ]; $refund = $this->findByRefundNo($site_id, $refund_no); - if($refund->isEmpty()) throw new PayException('REFUND_NOT_EXIST'); - if(!in_array($refund['status'], [RefundDict::WAIT, RefundDict::DEALING])) throw new PayException('REFUND_IS_CHANGE');//只有待退款和退款中的退款单据可以 + if ($refund->isEmpty()) throw new PayException('REFUND_NOT_EXIST'); + if (!in_array($refund[ 'status' ], [ RefundDict::WAIT, RefundDict::DEALING ])) throw new PayException('REFUND_IS_CHANGE');//只有待退款和退款中的退款单据可以 //查询第三方退款单据 $refund_info = $this->pay_event->init($site_id, $refund->channel, $refund->type)->getRefund($out_trade_no, $refund_no); //这儿的refund_info 已经统一整理成公共的数据格式 - $status = $refund_info['status']; - switch($status){ + $status = $refund_info[ 'status' ]; + switch ($status) { case RefundDict::SUCCESS://退款成功 $this->refundSuccess($site_id, [ 'out_trade_no' => $out_trade_no, 'refund_no' => $refund_no, + 'trade_type' => $refund[ 'trade_type' ], + 'trade_id' => $refund[ 'trade_id' ], ]); break; case RefundDict::DEALING://退款处理中 @@ -202,7 +217,7 @@ class CoreRefundService extends BaseCoreService $this->refundFail($site_id, [ 'out_trade_no' => $out_trade_no, 'refund_no' => $refund_no, - 'fail_reason' => $refund_info['fail_reason'] + 'fail_reason' => $refund_info[ 'fail_reason' ] ]); break; } @@ -215,19 +230,20 @@ class CoreRefundService extends BaseCoreService * @param array $data * @return bool */ - public function refundSuccess(int $site_id, array $data){ + public function refundSuccess(int $site_id, array $data) + { - $out_trade_no = $data['out_trade_no']; - $refund_no = $data['refund_no']; + $out_trade_no = $data[ 'out_trade_no' ]; + $refund_no = $data[ 'refund_no' ]; $this->model->where([ - ['site_id', '=', $site_id], - ['refund_no', '=', $refund_no] + [ 'site_id', '=', $site_id ], + [ 'refund_no', '=', $refund_no ] ])->update([ 'status' => RefundDict::SUCCESS ]); - $pay = (new CorePayService())->findPayInfoByOutTradeNo($site_id, $out_trade_no); - $result = event('RefundSuccess', ['refund_no' => $refund_no, 'trade_type' => $pay->trade_type, 'site_id' => $site_id, 'trade_id' => $data['trade_id']]); - if(!check_event_result($result)){ + $pay = ( new CorePayService() )->findPayInfoByOutTradeNo($site_id, $out_trade_no); + $result = event('RefundSuccess', [ 'refund_no' => $refund_no, 'trade_type' => $pay->trade_type, 'site_id' => $site_id, 'trade_id' => $data[ 'trade_id' ] ]); + if (!check_event_result($result)) { return false; } return true; @@ -239,14 +255,15 @@ class CoreRefundService extends BaseCoreService * @param array $data * @return true */ - public function refundFail(int $site_id, array $data){ - $refund_no = $data['refund_no']; + public function refundFail(int $site_id, array $data) + { + $refund_no = $data[ 'refund_no' ]; $this->model->where([ - ['site_id', '=', $site_id], - ['refund_no', '=', $refund_no] + [ 'site_id', '=', $site_id ], + [ 'refund_no', '=', $refund_no ] ])->update([ 'status' => RefundDict::FAIL, - 'fail_reason' => $data['fail_reason'] + 'fail_reason' => $data[ 'fail_reason' ] ]); return true; } @@ -257,12 +274,13 @@ class CoreRefundService extends BaseCoreService * @param array $data * @return true */ - public function refundDealing(int $site_id, array $data){ - $out_trade_no = $data['out_trade_no']; - $refund_no = $data['refund_no']; + public function refundDealing(int $site_id, array $data) + { + $out_trade_no = $data[ 'out_trade_no' ]; + $refund_no = $data[ 'refund_no' ]; $this->model->where([ - ['site_id', '=', $site_id], - ['refund_no', '=', $refund_no] + [ 'site_id', '=', $site_id ], + [ 'refund_no', '=', $refund_no ] ])->update([ 'status' => RefundDict::DEALING ]); diff --git a/niucloud/app/service/core/pay/CoreTransferService.php b/niucloud/app/service/core/pay/CoreTransferService.php index 4ac21dcd5..c840929cd 100644 --- a/niucloud/app/service/core/pay/CoreTransferService.php +++ b/niucloud/app/service/core/pay/CoreTransferService.php @@ -32,6 +32,7 @@ use Throwable; class CoreTransferService extends BaseCoreService { protected $pay_event; + public function __construct() { parent::__construct(); @@ -50,7 +51,8 @@ class CoreTransferService extends BaseCoreService * @return string|null * @throws Exception */ - public function create(int $site_id, string $main_type, int $main_id, float $money, string $trade_type, string $remark){ + public function create(int $site_id, string $main_type, int $main_id, float $money, string $trade_type, string $remark) + { $transfer_no = create_no(); $transfer_data = array( 'site_id' => $site_id, @@ -75,77 +77,78 @@ class CoreTransferService extends BaseCoreService * @param array $data * @return true */ - public function transfer(int $site_id, string $transfer_no, string $transfer_type, array $data){ + public function transfer(int $site_id, string $transfer_no, string $transfer_type, array $data) + { $transfer = $this->findTransferByTransferNo($site_id, $transfer_no); - if($transfer->isEmpty()) throw new PayException('TRANSFER_ORDER_INVALID'); - if(!in_array($transfer['transfer_status'], [TransferDict::WAIT, TransferDict::FAIL])) throw new PayException('TRANFER_STATUS_NOT_IN_WAIT_TANSFER'); + if ($transfer->isEmpty()) throw new PayException('TRANSFER_ORDER_INVALID'); + if (!in_array($transfer[ 'transfer_status' ], [ TransferDict::WAIT, TransferDict::FAIL ])) throw new PayException('TRANFER_STATUS_NOT_IN_WAIT_TANSFER'); - $transfer_account = $data['transfer_account'] ?? ''; - $transfer_realname = $data['transfer_realname'] ?? ''; + $transfer_account = $data[ 'transfer_account' ] ?? ''; + $transfer_realname = $data[ 'transfer_realname' ] ?? ''; $transfer_data = array( 'transfer_type' => $transfer_type,//转账方式 'transfer_realname' => $transfer_realname,//名称 - 'transfer_mobile' => $data['transfer_mobile'] ?? '',//手机号 - 'transfer_bank' => $data['transfer_bank'] ?? '',//转账银行 + 'transfer_mobile' => $data[ 'transfer_mobile' ] ?? '',//手机号 + 'transfer_bank' => $data[ 'transfer_bank' ] ?? '',//转账银行 'transfer_account' => $transfer_account,//转账账号 - 'openid' => $data['openid'] ?? '', - 'transfer_voucher' => $data['transfer_voucher'] ?? '', - 'transfer_remark' => $data['transfer_remark'] ?? '', - 'transfer_payee' => $data['transfer_payee'] ?? [], - 'transfer_payment_code' => $data['transfer_payment_code'] ?? '' + 'openid' => $data[ 'openid' ] ?? '', + 'transfer_voucher' => $data[ 'transfer_voucher' ] ?? '', + 'transfer_remark' => $data[ 'transfer_remark' ] ?? '', + 'transfer_payee' => $data[ 'transfer_payee' ] ?? [], + 'transfer_payment_code' => $data[ 'transfer_payment_code' ] ?? '' ); $transfer->save($transfer_data); - switch($transfer_type){ + switch ($transfer_type) { case TransferDict::WECHAT: // $out_batch_no = create_no(); - $transfer_account = $data['transfer_payee'] ?? []; - $scene_data = (new CoreTransferSceneService())->getSceneInfoByType($site_id, $transfer['trade_type']); + $transfer_account = $data[ 'transfer_payee' ] ?? []; + $scene_data = ( new CoreTransferSceneService() )->getSceneInfoByType($site_id, $transfer[ 'trade_type' ]); //通过业务获取业务场景 - $temp_infos = $scene_data['infos'] ?? [];//转账场景信息 - if(!empty($temp_infos)){ + $temp_infos = $scene_data[ 'infos' ] ?? [];//转账场景信息 + if (!empty($temp_infos)) { $transfer_scene_report_infos = []; - foreach($temp_infos as $key => $item){ + foreach ($temp_infos as $key => $item) { $transfer_scene_report_infos[] = [ 'info_type' => $key, 'info_content' => $item ]; } } - $transfer_account['transfer_scene_report_infos'] = $transfer_scene_report_infos ?? [];// - $transfer_account['user_recv_perception'] = $scene_data['perception'];//收款感知 - $transfer_account['transfer_scene_id'] = $scene_data['scene_id']; + $transfer_account[ 'transfer_scene_report_infos' ] = $transfer_scene_report_infos ?? [];// + $transfer_account[ 'user_recv_perception' ] = $scene_data[ 'perception' ];//收款感知 + $transfer_account[ 'transfer_scene_id' ] = $scene_data[ 'scene_id' ]; // $transfer_account['out_batch_no'] = $out_batch_no; break; } $params = []; $return_result = []; - if(TransferDict::getTransferType()[$transfer_type]['is_online']){ + if (TransferDict::getTransferType()[ $transfer_type ][ 'is_online' ]) { try { - $result = $this->pay_event->init($site_id, 'transfer', $transfer_type)->transfer($transfer['money'], $transfer_no, $transfer_account, $transfer_realname, $transfer['remark']); + $result = $this->pay_event->init($site_id, 'transfer', $transfer_type)->transfer($transfer[ 'money' ], $transfer_no, $transfer_account, $transfer_realname, $transfer[ 'remark' ]); // $params['batch_id'] = $result['batch_id']; // $params['out_batch_no'] = $result['out_batch_no']; //将返回的数据交给转账通知 - if($transfer_type == TransferDict::WECHAT){ + if ($transfer_type == TransferDict::WECHAT) { $update_data = [ - 'out_batch_no' => $result['transfer_bill_no'] ?? '', - 'package_info' => $result['package_info'] ?? '', - 'extra' => $result['extra'] ?? [], + 'out_batch_no' => $result[ 'transfer_bill_no' ] ?? '', + 'package_info' => $result[ 'package_info' ] ?? '', + 'extra' => $result[ 'extra' ] ?? [], ]; $transfer->save($update_data); - $return_result['status'] = $result['status']; - $return_result['package_info'] = $result['package_info']; - $return_result['extra'] = $result['extra'] ?? []; + $return_result[ 'status' ] = $result[ 'status' ]; + $return_result[ 'package_info' ] = $result[ 'package_info' ]; + $return_result[ 'extra' ] = $result[ 'extra' ] ?? []; } $this->transferNotify($site_id, $transfer_no, $result); // return true; - }catch( Throwable $e){ - $this->fail($site_id, $transfer_no, ['reason' => get_lang($e->getMessage())]); + } catch (Throwable $e) { + $this->fail($site_id, $transfer_no, [ 'reason' => get_lang($e->getMessage()) ]); throw new PayException($e->getMessage()); } - }else{ + } else { $return_result = [ 'status' => TransferDict::SUCCESS, ]; @@ -154,16 +157,18 @@ class CoreTransferService extends BaseCoreService return $return_result; } + /** * 通过转账单号查询转账 * @param int $site_id * @param string $transfer_no * @return Pay|array|mixed|Model */ - public function findTransferByTransferNo(int $site_id, string $transfer_no){ + public function findTransferByTransferNo(int $site_id, string $transfer_no) + { $where = array( - ['site_id', '=', $site_id], - ['transfer_no', '=', $transfer_no] + [ 'site_id', '=', $site_id ], + [ 'transfer_no', '=', $transfer_no ] ); return $this->model->where($where)->findOrEmpty(); } @@ -176,16 +181,17 @@ class CoreTransferService extends BaseCoreService * @param $params * @return true */ - public function transferNotify(int $site_id, string $transfer_no, $params){ - Log::write('transferNotify'.$transfer_no); + public function transferNotify(int $site_id, string $transfer_no, $params) + { + Log::write('transferNotify' . $transfer_no); $transfer = $this->findTransferByTransferNo($site_id, $transfer_no); - if($transfer->isEmpty()) throw new PayException('TRANSFER_ORDER_INVALID'); - if(!in_array($transfer['transfer_status'], [TransferDict::WAIT, TransferDict::DEALING, TransferDict::FAIL, TransferDict::WAIT_USER, TransferDict::WAIT_USER_ING, TransferDict::FAIL_ING])) throw new PayException('TRANFER_STATUS_NOT_IN_WAIT_TANSFER'); - $status = $params['status'] ?? TransferDict::DEALING; - Log::write('transferNotifyStatus'.$status); - switch($status){ + if ($transfer->isEmpty()) throw new PayException('TRANSFER_ORDER_INVALID'); + if (!in_array($transfer[ 'transfer_status' ], [ TransferDict::WAIT, TransferDict::DEALING, TransferDict::FAIL, TransferDict::WAIT_USER, TransferDict::WAIT_USER_ING, TransferDict::FAIL_ING ])) throw new PayException('TRANFER_STATUS_NOT_IN_WAIT_TANSFER'); + $status = $params[ 'status' ] ?? TransferDict::DEALING; + Log::write('transferNotifyStatus' . $status); + switch ($status) { case TransferDict::SUCCESS: - Log::write('transferNotifyStatus1'.$status); + Log::write('transferNotifyStatus1' . $status); $this->success($site_id, $transfer_no); break; case TransferDict::FAIL: @@ -200,6 +206,7 @@ class CoreTransferService extends BaseCoreService } return true; } + /** * 转账完成 * @param int $site_id @@ -208,11 +215,12 @@ class CoreTransferService extends BaseCoreService * @param array $params * @return bool */ - public function success(int $site_id, string $transfer_no, array $params = []){ + public function success(int $site_id, string $transfer_no, array $params = []) + { $transfer = $this->findTransferByTransferNo($site_id, $transfer_no); - Log::write('transferNotifyStatus2'.$transfer['transfer_status']); - if($transfer->isEmpty()) throw new PayException('TRANSFER_ORDER_INVALID'); - if(!in_array($transfer['transfer_status'], [TransferDict::WAIT, TransferDict::DEALING, TransferDict::FAIL,TransferDict::WAIT_USER, TransferDict::WAIT_USER_ING, TransferDict::FAIL_ING])) throw new PayException('TRANFER_STATUS_NOT_IN_WAIT_TANSFER'); + Log::write('transferNotifyStatus2' . $transfer[ 'transfer_status' ]); + if ($transfer->isEmpty()) throw new PayException('TRANSFER_ORDER_INVALID'); + if (!in_array($transfer[ 'transfer_status' ], [ TransferDict::WAIT, TransferDict::DEALING, TransferDict::FAIL, TransferDict::WAIT_USER, TransferDict::WAIT_USER_ING, TransferDict::FAIL_ING ])) throw new PayException('TRANFER_STATUS_NOT_IN_WAIT_TANSFER'); $trade_type = $transfer->trade_type; $data = [ @@ -226,16 +234,16 @@ class CoreTransferService extends BaseCoreService Db::startTrans(); try { $transfer->save($data); - Log::write('transferNotifyStatus3'.TransferDict::SUCCESS); - $result = event('TransferSuccess', ['transfer_no' => $transfer_no, 'trade_type' => $trade_type, 'site_id' => $site_id]); - if(!check_event_result($result)){ + Log::write('transferNotifyStatus3' . TransferDict::SUCCESS); + $result = event('TransferSuccess', [ 'transfer_no' => $transfer_no, 'trade_type' => $trade_type, 'site_id' => $site_id ]); + if (!check_event_result($result)) { Db::rollback(); return false; } // 提交事务 Db::commit(); return true; - } catch ( Throwable $e) { + } catch (Throwable $e) { // 回滚事务 Db::rollback(); throw new PayException($e->getMessage()); @@ -251,15 +259,16 @@ class CoreTransferService extends BaseCoreService * @param array $params * @return true */ - public function fail(int $site_id, string $transfer_no, array $params = []){ + public function fail(int $site_id, string $transfer_no, array $params = []) + { $transfer = $this->findTransferByTransferNo($site_id, $transfer_no); - if($transfer->isEmpty()) throw new PayException('TRANSFER_ORDER_INVALID'); - if(!in_array($transfer['transfer_status'], [TransferDict::WAIT, TransferDict::DEALING, TransferDict::FAIL,TransferDict::WAIT_USER, TransferDict::WAIT_USER_ING, TransferDict::FAIL_ING])) throw new PayException('TRANFER_STATUS_NOT_IN_WAIT_TANSFER'); + if ($transfer->isEmpty()) throw new PayException('TRANSFER_ORDER_INVALID'); + if (!in_array($transfer[ 'transfer_status' ], [ TransferDict::WAIT, TransferDict::DEALING, TransferDict::FAIL, TransferDict::WAIT_USER, TransferDict::WAIT_USER_ING, TransferDict::FAIL_ING ])) throw new PayException('TRANFER_STATUS_NOT_IN_WAIT_TANSFER'); $data = array( 'transfer_time' => time(), 'transfer_status' => TransferDict::FAIL, - 'transfer_fail_reason' => $params['reason'] ?? '' + 'transfer_fail_reason' => $params[ 'reason' ] ?? '' ); //允许修改的值 @@ -268,17 +277,18 @@ class CoreTransferService extends BaseCoreService } - public function check(int $site_id, array $data){ - $transfer_no = $data['transfer_no']; + public function check(int $site_id, array $data) + { + $transfer_no = $data[ 'transfer_no' ]; $transfer = $this->findTransferByTransferNo($site_id, $transfer_no); - if($transfer->isEmpty()) throw new PayException('TRANSFER_ORDER_INVALID'); - if(!in_array($transfer['transfer_status'], [TransferDict::WAIT, TransferDict::DEALING, TransferDict::FAIL,TransferDict::WAIT_USER, TransferDict::WAIT_USER_ING, TransferDict::FAIL_ING]) ) throw new PayException('TRANFER_IS_CHANGE');//只有待转账和转账中的订单可以校验 + if ($transfer->isEmpty()) throw new PayException('TRANSFER_ORDER_INVALID'); + if (!in_array($transfer[ 'transfer_status' ], [ TransferDict::WAIT, TransferDict::DEALING, TransferDict::FAIL, TransferDict::WAIT_USER, TransferDict::WAIT_USER_ING, TransferDict::FAIL_ING ])) throw new PayException('TRANFER_IS_CHANGE');//只有待转账和转账中的订单可以校验 //查询第三方支付单据 - $transfer_info = $this->pay_event->init($site_id, 'transfer', $transfer->transfer_type)->getTransfer($transfer_no, $transfer['out_batch_no'] ?? ''); - if(empty($transfer_info)) throw new PayException('TRANSFER_ORDER_INVALID');//查询不到转账信息 - $status = $transfer_info['status']; - switch($status){ + $transfer_info = $this->pay_event->init($site_id, 'transfer', $transfer->transfer_type)->getTransfer($transfer_no, $transfer[ 'out_batch_no' ] ?? ''); + if (empty($transfer_info)) throw new PayException('TRANSFER_ORDER_INVALID');//查询不到转账信息 + $status = $transfer_info[ 'status' ]; + switch ($status) { case TransferDict::SUCCESS: $this->success($site_id, $transfer_no); break; @@ -301,10 +311,11 @@ class CoreTransferService extends BaseCoreService * @param $type * @return true */ - public function dealing(int $site_id, $transfer_no, $status){ + public function dealing(int $site_id, $transfer_no, $status) + { $this->model->where([ - ['site_id', '=', $site_id], - ['transfer_no', '=', $transfer_no] + [ 'site_id', '=', $site_id ], + [ 'transfer_no', '=', $transfer_no ] ])->update( [ // 'transfer_status' => TransferDict::DEALING, @@ -342,29 +353,27 @@ class CoreTransferService extends BaseCoreService * @param string $transfer_no * @return void */ - public function cancel(int $site_id, string $transfer_no){ + public function cancel(int $site_id, string $transfer_no) + { try { - $transfer_no = $transfer_no; $transfer = $this->findTransferByTransferNo($site_id, $transfer_no); - if($transfer->isEmpty()) throw new PayException('TRANSFER_ORDER_INVALID'); - if(!in_array($transfer['transfer_status'], [TransferDict::WAIT, TransferDict::DEALING, TransferDict::FAIL,TransferDict::WAIT_USER, TransferDict::WAIT_USER_ING, TransferDict::FAIL_ING]) ) throw new PayException('TRANFER_IS_CHANGE');//只有待转账和转账中的订单可以校验 + if ($transfer->isEmpty()) throw new PayException('TRANSFER_ORDER_INVALID'); + if (!in_array($transfer[ 'transfer_status' ], [ TransferDict::WAIT, TransferDict::DEALING, TransferDict::FAIL, TransferDict::WAIT_USER, TransferDict::WAIT_USER_ING, TransferDict::FAIL_ING ])) throw new PayException('TRANFER_IS_CHANGE');//只有待转账和转账中的订单可以校验 //查询第三方支付单据 $result = $this->pay_event->init($site_id, 'transfer', $transfer->transfer_type)->transferCancel([ 'transfer_no' => $transfer_no ]); $this->transferNotify($site_id, $transfer_no, $result); - if($result['status'] == TransferDict::FAIL_ING){//撤销中的话也要返回错误,不能让业务认为撤销成功了 + if ($result[ 'status' ] == TransferDict::FAIL_ING) {//撤销中的话也要返回错误,不能让业务认为撤销成功了 throw new PayException('TRANSFER_IS_FAILING'); } return true; - }catch( Throwable $e){ - + } catch (Throwable $e) { throw new PayException($e->getMessage()); } } - } diff --git a/niucloud/app/service/core/upload/CoreFileService.php b/niucloud/app/service/core/upload/CoreFileService.php index aac119762..eeaa3a289 100644 --- a/niucloud/app/service/core/upload/CoreFileService.php +++ b/niucloud/app/service/core/upload/CoreFileService.php @@ -11,6 +11,7 @@ namespace app\service\core\upload; +use app\dict\sys\StorageDict; use core\base\BaseCoreService; use core\exception\UploadFileException; use core\upload\FileDriver; @@ -80,15 +81,27 @@ class CoreFileService extends BaseCoreService * @throws Exception */ public function driver(int $site_id, string $storage_type = ''){ - if(!empty($storage_type)){ - self::$storage_type = $storage_type; - $core_storage_service = new CoreStorageService(); - $storage_config = $core_storage_service->getStorageByType($site_id, $storage_type); - }else{ + + //是租户且设置的为默认 则按照超级管理员的默认来使用 + $tenant_is_default = ($site_id != 0 && $storage_type == StorageDict::LOCAL); + if ($tenant_is_default){ + $site_id = 0; + $storage_type = ''; + } + if(empty($storage_type)){ $core_storage_service = new CoreStorageService(); $storage_config = $core_storage_service->getDefaultStorage($site_id); if(empty($storage_config)) throw new UploadFileException('UPLOAD_STORAGE_TYPE_ALL_CLOSE'); + //若获取到的存储类型为`默认` 则获取超级管理的配置 + if ($storage_config['storage_type'] == StorageDict::LOCAL){ + $storage_config = $core_storage_service->getDefaultStorage(0); + if(empty($storage_config)) throw new UploadFileException('SUPER_UPLOAD_STORAGE_TYPE_ALL_CLOSE'); + } self::$storage_type = $storage_config['storage_type']; + }else{ + self::$storage_type = $storage_type; + $core_storage_service = new CoreStorageService(); + $storage_config = $core_storage_service->getStorageByType($site_id, $storage_type); } $storage_config = $storage_config ?? []; $storage_config['storage_type'] = self::$storage_type; diff --git a/niucloud/app/service/core/weapp/CoreWeappCloudService.php b/niucloud/app/service/core/weapp/CoreWeappCloudService.php index bbcc5947c..9d03ec3e0 100644 --- a/niucloud/app/service/core/weapp/CoreWeappCloudService.php +++ b/niucloud/app/service/core/weapp/CoreWeappCloudService.php @@ -13,6 +13,7 @@ namespace app\service\core\weapp; use app\dict\addon\AddonDict; use app\model\addon\Addon; +use app\service\api\diy\DiyConfigService; use app\service\core\addon\CoreAddonDevelopDownloadService; use app\service\core\addon\WapTrait; use app\service\core\niucloud\CoreCloudBaseService; @@ -84,7 +85,7 @@ class CoreWeappCloudService extends CoreCloudBaseService // 如果不存在编译版小程序 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' ]); $this->handleUniapp($uni_dir); // 替换env文件 $this->weappEnvReplace($uni_dir . DIRECTORY_SEPARATOR . '.env.production'); @@ -139,12 +140,14 @@ class CoreWeappCloudService extends CoreCloudBaseService $local_addon = ( new Addon() )->where([ [ 'status', '=', AddonDict::ON ] ])->column('key'); // 移除uniapp中该站点没有的插件 - $diff_addon = array_filter(array_map(function($key) use ($site_addon) { + $diff_addon = array_filter(array_map(function ($key) use ($site_addon) { if (!in_array($key, $site_addon)) return $key; }, $local_addon)); $this->handlePageCode($dir . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR, $site_addon); + $this->handleTabbar($dir . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR, $site_addon); + if (!empty($diff_addon)) { foreach ($diff_addon as $addon) { $this->addon = $addon; @@ -178,7 +181,7 @@ class CoreWeappCloudService extends CoreCloudBaseService $page_end = strtoupper($addon) . '_PAGE_END'; // 对0.2.0之前的版本做处理 - $uniapp_pages[ 'pages' ] = preg_replace_callback('/(.*)(\\r\\n.*\/\/ PAGE_END.*)/s', function($match) { + $uniapp_pages[ 'pages' ] = preg_replace_callback('/(.*)(\\r\\n.*\/\/ PAGE_END.*)/s', function ($match) { return $match[ 1 ] . ( substr($match[ 1 ], -1) == ',' ? '' : ',' ) . $match[ 2 ]; }, $uniapp_pages[ 'pages' ]); @@ -190,7 +193,7 @@ class CoreWeappCloudService extends CoreCloudBaseService } $content = @file_get_contents($compile_path . "pages.json"); - $content = preg_replace_callback('/(.*\/\/ \{\{ PAGE_BEGAIN \}\})(.*)(\/\/ \{\{ PAGE_END \}\}.*)/s', function($match) use ($pages) { + $content = preg_replace_callback('/(.*\/\/ \{\{ PAGE_BEGAIN \}\})(.*)(\/\/ \{\{ PAGE_END \}\}.*)/s', function ($match) use ($pages) { return $match[ 1 ] . PHP_EOL . implode(PHP_EOL, $pages) . PHP_EOL . $match[ 3 ]; }, $content); @@ -198,6 +201,54 @@ class CoreWeappCloudService extends CoreCloudBaseService return file_put_contents($compile_path . "pages.json", $content); } + /** + * 处理底部导航 + * @param $compile_path + * @param $addon_arr + * @return void + */ + public function handleTabbar($compile_path, $addon_arr = []) + { + $bottomList = array_column(( new DiyConfigService() )->getBottomList(), null, 'key'); + $tabbarList = []; + if (empty($addon_arr)) { + foreach ($bottomList as $app_item) { + array_push($tabbarList, ...$app_item[ 'value' ][ 'list' ]); + } + } else { + foreach ($addon_arr as $addon) { + if (isset($bottomList[ $addon ])) { + array_push($tabbarList, ...$bottomList[ $addon ][ 'value' ][ 'list' ]); + } + } + } + + $tabbarList = array_map(function ($item) { + if (strpos($item[ 'link' ][ 'url' ], '?') !== false) { + $item[ 'link' ][ 'url' ] = explode('?', $item[ 'link' ][ 'url' ])[0]; + } + $link = array_filter(explode('/', $item[ 'link' ][ 'url' ])); + $item[ 'link' ] = $item[ 'link' ][ 'url' ]; + $item[ 'component' ] = implode('-', $link); + $item[ 'name' ] = lcfirst(implode('', array_map(function ($str) { + return ucfirst($str); + }, $link))); + return $item; + }, $tabbarList); + $tabbarList = array_column($tabbarList, null, 'name'); + + if (isset($tabbarList[ 'appPagesIndexIndex' ])) unset($tabbarList[ 'appPagesIndexIndex' ]); + if (isset($tabbarList[ 'appPagesMemberIndex' ])) unset($tabbarList[ 'appPagesMemberIndex' ]); + + // 处理vue文件 + $tpl = str_replace('/', DIRECTORY_SEPARATOR, public_path() . 'static/tpl/tabbar.tpl'); + $content = view($tpl, [ 'tabbarList' => $tabbarList ])->getContent(); + file_put_contents(str_replace('/', DIRECTORY_SEPARATOR, $compile_path . 'app/pages/index/tabbar.vue'), $content); + + // 处理tabbar.json + file_put_contents($compile_path . 'tabbar.json', json_encode(array_column($tabbarList, 'link'), JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); + } + /** * 小程序上传env文件处理 * @param string $env_file diff --git a/niucloud/app/service/core/wxoplatform/CoreOplatformService.php b/niucloud/app/service/core/wxoplatform/CoreOplatformService.php index 14ca40090..33940b39d 100644 --- a/niucloud/app/service/core/wxoplatform/CoreOplatformService.php +++ b/niucloud/app/service/core/wxoplatform/CoreOplatformService.php @@ -242,7 +242,7 @@ class CoreOplatformService extends BaseCoreService $app = CoreWeappService::app($site_id); return $app->getClient()->post('/cgi-bin/component/getprivacysetting', [ 'json' => [ - 'privacy_ver' => 1 + 'privacy_ver' => 2 ] ])->toArray(); } @@ -263,7 +263,7 @@ class CoreOplatformService extends BaseCoreService $app = CoreWeappService::app($site_id); return $app->getClient()->post('/cgi-bin/component/setprivacysetting', [ 'json' => [ - 'privacy_ver' => $data['privacy_ver'] ?? 2, + 'privacy_ver' => 2, 'setting_list' => $data['setting_list'], 'owner_setting' => $data['owner_setting'], 'sdk_privacy_info_list' => $data['sdk_privacy_info_list'] ?? [] @@ -320,4 +320,12 @@ class CoreOplatformService extends BaseCoreService ] ])->toArray(); } + + /** + * 撤回代码审核 + */ + public static function undocodeAudit($site_id) { + $app = CoreWeappService::app($site_id); + return $app->getClient()->get('/wxa/undocodeaudit')->toArray(); + } } diff --git a/niucloud/app/upgrade/v110/upgrade.sql b/niucloud/app/upgrade/v110/upgrade.sql new file mode 100644 index 000000000..d272a83c8 --- /dev/null +++ b/niucloud/app/upgrade/v110/upgrade.sql @@ -0,0 +1,28 @@ + +ALTER TABLE `sys_upgrade_records` CHANGE COLUMN content content TEXT DEFAULT NULL COMMENT '升级内容'; + +DROP TABLE IF EXISTS `niu_sms_template`; +CREATE TABLE `niu_sms_template` ( + `id` INT(11) NOT NULL AUTO_INCREMENT, + `site_id` INT(11) DEFAULT 0 COMMENT '站点ID', + `sms_type` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '短信服务商类型 niuyun-牛云 aliyun-阿里云 tencent-腾讯', + `username` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '子账号名称', + `template_key` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '模版key', + `template_id` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '模版id', + `template_type` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '模版类型', + `template_content` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '模版内容', + `param_json` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '参数变量', + `status` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '上下架状态', + `audit_status` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '报备、审核状态', + `audit_msg` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '审核结果/拒绝原因', + `report_info` TEXT DEFAULT NULL COMMENT '报备、审核信息', + `create_time` INT(11) NOT NULL DEFAULT 0 COMMENT '创建时间', + `update_time` INT(11) NOT NULL DEFAULT 0 COMMENT '修改时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='牛云短信模板表'; + +ALTER TABLE `member` ADD COLUMN `remark` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '备注'; + +ALTER TABLE `member` MODIFY `remark` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '备注' AFTER `location`; + +ALTER TABLE `addon` CHANGE COLUMN `key` `key` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '插件标识'; diff --git a/niucloud/app/validate/member/CashOutConfig.php b/niucloud/app/validate/member/CashOutConfig.php index 1fdb7b2e1..032651875 100644 --- a/niucloud/app/validate/member/CashOutConfig.php +++ b/niucloud/app/validate/member/CashOutConfig.php @@ -26,7 +26,7 @@ class CashOutConfig extends Validate 'rate' => 'between:0,100', //提现手续费比率 'is_auto_verify' => 'in:0,1', //是否自动审核 'is_auto_transfer' => 'in:0,1', //是否自动转账 - 'transfer_type' => 'require', + 'transfer_type' => 'requireIf:is_open,1', ]; protected $message = [ @@ -35,7 +35,7 @@ class CashOutConfig extends Validate 'rate.between' => 'validate_member.cash_out_rate_between', 'is_auto_verify.in' => 'validate_member.cash_out_is_auto_verify_in', 'is_auto_transfer.in' => 'validate_member.cash_out_is_auto_transfer_in', - 'transfer_type.require' => 'validate_member_cash_out_config.transfer_type_require', + 'transfer_type.requireIf' => 'validate_member_cash_out_config.transfer_type_require', ]; protected $scene = [ diff --git a/niucloud/app/validate/member/Member.php b/niucloud/app/validate/member/Member.php index 52119d254..f8015a2b4 100644 --- a/niucloud/app/validate/member/Member.php +++ b/niucloud/app/validate/member/Member.php @@ -27,7 +27,7 @@ class Member extends Validate protected $rule = [ 'nickname' => 'requireWithout:field|max:30|requireIf:field,nickname', - 'mobile' => 'mobile', + 'mobile' => 'mobile|unique:member', 'sex' => 'checkSex', 'birthday' => 'date', 'username' => 'require|checkUsername', @@ -39,8 +39,8 @@ class Member extends Validate 'nickname.requireWithout' => 'validate_member.nickname_require', 'nickname.requireIf' => 'validate_member.nickname_require', 'nickname.max' => 'validate_member.nickname_max', - 'mobile.require' => 'validate_member.mobile_require', 'mobile.mobile' => 'validate_member.mobile_mobile', + 'mobile.unique' => 'validate_member.mobile_unique', 'birthday' => 'validate_member.birthday_format', 'username.require' => 'validate_member.username_require', 'username.unique' => 'validate_member.username_is_exist', @@ -52,8 +52,8 @@ class Member extends Validate protected $scene = [ 'add' => ['birthday', 'mobile', 'password'], - 'edit' => ['sex', 'birthday'], - 'modify' => ['sex', 'birthday'], + 'edit' => ['sex', 'birthday','mobile'], + 'modify' => ['sex', 'birthday','mobile'], 'account_register' => ['username', 'password', 'mobile'], 'reset_password' => ['password', 'mobile'], 'set_status' => ['status'] diff --git a/niucloud/config/version.php b/niucloud/config/version.php index 9faf7328a..2fa260c2d 100644 --- a/niucloud/config/version.php +++ b/niucloud/config/version.php @@ -1,6 +1,6 @@ '1.0.2', - 'code' => '202504180002' + 'version' => '1.1.0', + 'code' => '202505300001' ]; diff --git a/niucloud/core/dict/BaseDict.php b/niucloud/core/dict/BaseDict.php index 591d101ca..668cbd957 100644 --- a/niucloud/core/dict/BaseDict.php +++ b/niucloud/core/dict/BaseDict.php @@ -179,6 +179,42 @@ abstract class BaseDict extends Storage return $files_data; } + /** + * 加载文件数据 + * @param $files + * @return array + */ + protected function loadFilesWithAddon($files) + { + $default_sort = 100000; + $files_data = []; + if (!empty($files)) { + foreach ($files as $addon => $file) { + $config = include $file; + + if (!empty($config)) { + $temp[$addon] = $config; + $config = $temp; + if (isset($config['file_sort'])) { + $sort = $config['file_sort']; + unset($config['file_sort']); + $sort = $sort * 10; + while (array_key_exists($sort, $files_data)) { + $sort++; + } + $files_data[$sort] = $config; + } else { + $files_data[$default_sort] = $config; + $default_sort++; + } + } + } + } + ksort($files_data); + return $files_data; + } + + /** * 加载 * @return mixed diff --git a/niucloud/core/dict/Notice.php b/niucloud/core/dict/Notice.php index ec46b9af5..1eab9568f 100644 --- a/niucloud/core/dict/Notice.php +++ b/niucloud/core/dict/Notice.php @@ -20,19 +20,24 @@ class Notice extends BaseDict */ public function load(array $data) { + $with_addon = ($data['with_addon'] ?? 0) == 1; $template_files = []; - $system_path = $this->getDictPath() . "notice" . DIRECTORY_SEPARATOR . $data[ 'type' ] . ".php"; + $system_path = $this->getDictPath() . "notice" . DIRECTORY_SEPARATOR . $data['type'] . ".php"; if (is_file($system_path)) { - $template_files[] = $system_path; + $template_files['app'] = $system_path; } $addons = $this->getLocalAddons(); foreach ($addons as $v) { - $template_path = $this->getAddonDictPath($v) . "notice" . DIRECTORY_SEPARATOR . $data[ 'type' ] . ".php"; + $template_path = $this->getAddonDictPath($v) . "notice" . DIRECTORY_SEPARATOR . $data['type'] . ".php"; if (is_file($template_path)) { - $template_files[] = $template_path; + $template_files[$v] = $template_path; } } - $template_files_data = $this->loadFiles($template_files); + if ($with_addon) { + $template_files_data = $this->loadFilesWithAddon($template_files); + } else { + $template_files_data = $this->loadFiles($template_files); + } $template_data_array = []; foreach ($template_files_data as $file_data) { diff --git a/niucloud/core/sms/Niuyun.php b/niucloud/core/sms/Niuyun.php new file mode 100644 index 000000000..48e0caebd --- /dev/null +++ b/niucloud/core/sms/Niuyun.php @@ -0,0 +1,142 @@ +username = $config['username'] ?? ''; + $this->password = $config['password'] ?? ''; + $this->signature = $config['signature'] ?? ''; + } + + + /** + * 模版发送短信 + * @param string $mobile + * @param string $template_id + * @param array $data + * @return void + */ + public function send(string $mobile, string $template_id, array $data = []) + { + Log::write("send niu sms pre ".json_encode($data,256)); + if (empty($this->signature)) { + throw new CommonException('签名未配置'); + } + $template_info = (new NiuSmsTemplate())->where('template_id', $template_id)->findOrEmpty(); + Log::write("send niu sms pre signature".json_encode($template_info->toArray(),256)); + + if ($template_info->isEmpty()) { + throw new CommonException('模版未报备'); + } + if ($template_info->audit_status != NoticeTypeDict::API_AUDIT_RESULT_PASS) { + throw new CommonException('模版审核未通过'); + } + $url = sprintf(self::SEND_URL, $this->username); + $template_info = $template_info->toArray(); + $data = $this->formatParams($data, $template_info); + $params['records'] = [ + [ + 'mobile' => $mobile, + 'tpContent' => $data + ] + ]; + $params['tpId'] = $template_id; + $params['username'] = $this->username; + $tKey = time(); + $params['tKey'] = $tKey; + $params['password'] = md5(md5($this->password) . $tKey); + $params['signature'] = $this->signature; + Log::write("send niu sms params ".json_encode($params,256)); + try { + $res = (new HttpHelper())->httpRequest('POST', $url, $params); + Log::write("send niu sms res ".json_encode($res,256)); + if ($res['code'] != 200) { + throw new CommonException($res['msg']); + } + return $res; + } catch (\Exception $e) { + throw new CommonException($e->getMessage()); + } + } + + private function formatParams($data, $template_info) + { + $params_json = $template_info['param_json']; + $params_type_arr = NoticeTypeDict::getApiParamsType(); + $type_arr = array_column($params_type_arr, null, 'type'); + $return = []; + foreach ($params_json as $param => $validate) { + $value = $data[$param]; + $pattern = $type_arr[$validate]['rule'] ?? ''; + if (empty($pattern)) { + $return[$param] = $value; + }else{ + if (preg_match($type_arr[$validate]['rule'], $value)) { + $return[$param] = $value; + } else { + if ($validate == NoticeTypeDict::PARAMS_TYPE_CHINESE) { + $value = str_sub($value, 32); + $return[$param] = $value; + } + if ($validate == NoticeTypeDict::PARAMS_TYPE_OTHERS) { + $value = str_sub($value, 35); + $return[$param] = $value; + } + } + } + } + return $return; + } + + public function modify(string $sign, string $mobile, string $code) + { + } + + public function template(int $page = 0, int $limit = 10, int $type = 1) + { + } + + public function apply(string $title, string $content, int $type) + { + } + + public function localTemplate(int $type, int $page, int $limit) + { + } + + public function record($id) + { + } +} \ No newline at end of file diff --git a/niucloud/core/util/DbBackup.php b/niucloud/core/util/DbBackup.php index a5ffcd412..1c3e19925 100644 --- a/niucloud/core/util/DbBackup.php +++ b/niucloud/core/util/DbBackup.php @@ -1,54 +1,110 @@ key = $key; + $cache = $this->getCache(); $this->backupPath = $backupPath; $this->maxFileSize = $maxFileSize; $this->excludeTables = $excludeTables; if (!is_dir($this->backupPath)) { mkdir($this->backupPath, 0777, true); } + $this->currentFileIndex = $cache['currentFileIndex'] ?? 0; $this->currentFile = $this->backupPath . '/backup_' . $this->currentFileIndex . '.sql'; + $this->tables = $cache['tables'] ?? []; + $this->totalTables = count($this->getAllTables()); + $this->processedTables = $cache['processedTables'] ?? 0; + $this->tableOffset = $cache['tableOffset'] ?? []; + $this->currentFileSize = $cache['currentFileSize'] ?? 0; + $this->restoreIndex = $cache['restoreIndex'] ?? 0; + $this->startime = time(); + } + + private function getCache() { + $cache = Cache::get('db_backup_' . $this->key, []); + return $cache; + } + + private function setCache() { + $cache = [ + 'currentFileIndex' => $this->currentFileIndex, + 'processedTables' => $this->processedTables, + 'tableOffset' => $this->tableOffset, + 'currentFileSize' => $this->currentFileSize, + 'restoreIndex' => $this->restoreIndex, + 'tables' => $this->tables + ]; + Cache::set('db_backup_' . $this->key, $cache, 3600); } public function setExcludeTables($tables) { + $this->tables = []; $this->excludeTables = $tables; + $this->totalTables = count($this->getAllTables()); return $this; } public function backupDatabaseSegment($limit = 1000) { - $tables = $this->getAllTables(); - foreach ($tables as $table) { - if (in_array($table, $this->excludeTables)) { - continue; - } - if (!isset($this->tableOffset[$table])) { - $this->tableOffset[$table] = 0; - $this->backupTableStructure($table); - } - while (true) { - $data = Db::table($table)->limit($this->tableOffset[$table], $limit)->select()->toArray(); - if (empty($data)) { - break; + $tables = array_slice($this->getAllTables(), $this->processedTables); + if (!empty($tables)) { + foreach ($tables as $table) { + if (!isset($this->tableOffset[$table])) { + $this->tableOffset[$table] = 0; + $this->backupTableStructure($table); } - $this->backupTableData($table, $data); - $this->tableOffset[$table] += $limit; + + while (true) { + $data = Db::table($table)->limit($this->tableOffset[$table], $limit)->select()->toArray(); + if (empty($data)) { + break; + } + $this->backupTableData($table, $data); + $this->tableOffset[$table] += $limit; + + if (time() - $this->startime > $this->maxExecuteTime) { + $this->setCache(); + return $this->processedTables; + } + } + + if (time() - $this->startime > $this->maxExecuteTime) { + $this->setCache(); + return $this->processedTables; + } + + $this->processedTables++; } } + return true; + } + + public function getBackupProgress() { + return round($this->processedTables / $this->totalTables * 100); } private function backupTableStructure($table) @@ -110,12 +166,18 @@ class DbBackup private function getAllTables() { + if (!empty($this->tables)) return $this->tables; + $tables = Db::query('SHOW TABLES'); - $tableNames = []; + $this->tables = []; foreach ($tables as $table) { - $tableNames[] = current($table); + $table_name = current($table); + if (in_array($table_name, $this->excludeTables)) { + continue; + } + $this->tables[] = $table_name; } - return $tableNames; + return $this->tables; } private function getTableCreateQuery($tableName) @@ -134,14 +196,26 @@ class DbBackup public function restoreDatabase() { $backupFiles = glob($this->backupPath . '/backup_*.sql'); - foreach ($backupFiles as $backupFile) { - $sql = file_get_contents($backupFile); - $queries = explode(";\n", $sql); - foreach ($queries as $query) { - if (trim($query) !== '') { - Db::execute($query); - } + natsort($backupFiles); + $backupFiles = array_values($backupFiles); + + if ($this->restoreIndex >= count($backupFiles)) return true; + $backupFile = $backupFiles[$this->restoreIndex]; + + $sql = file_get_contents($backupFile); + $queries = explode(";\n", $sql); + foreach ($queries as $query) { + if (trim($query) !== '') { + Db::execute($query); } } + $this->restoreIndex++; + $this->setCache(); + return $this->restoreIndex; + } + + public function getRestoreProgress() { + $backupFiles = glob($this->backupPath . '/backup_*.sql'); + return round($this->restoreIndex / count($backupFiles) * 100); } }