This commit is contained in:
全栈小学生 2025-06-11 09:22:55 +08:00
parent eef89d9ef1
commit 3b398f9cfc
69 changed files with 2876 additions and 465 deletions

View File

@ -45,7 +45,7 @@ class ExceptionHandle extends Handle
{
// 使用内置的方式记录异常日志
// parent::report($exception);
if (!$this->isIgnoreReport($e)) {
if (!$this->isIgnoreReport($e) && env('app_debug', false)) {
$data = [
'file' => $e->getFile(),
'line' => $e->getLine(),

View File

@ -20,6 +20,11 @@ use think\Response;
class Addon extends BaseAdminController
{
public function init()
{
return success((new CoreAddonService())->getInitList());
}
/**
* 获取已下载插架
*/
@ -158,17 +163,15 @@ class Addon extends BaseAdminController
public function getInstallList(){
return success(data:(new AddonService())->getInstallList());
}
/**
* 查询已安装有效应用
*/
public function getAddonList()
{
return success((new CoreAddonService())->getAddonMemuList());
return success((new CoreAddonService())->getInstallAddonList());
}
public function getAddonByKey($key){
return success((new AddonService())->getInfoByKey($key));
}
/**
* 插件类型
* @return Response
@ -190,4 +193,25 @@ class Addon extends BaseAdminController
{
return success(data:(new AddonService())->getShowAppTools());
}
/**
* 获取首页应用标签
*/
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']));
}
}

View File

@ -26,7 +26,8 @@ class Upgrade extends BaseAdminController
public function upgrade($addon = '')
{
$data = $this->request->params([
['is_need_backup', true]
['is_need_backup', true],
['is_need_cloudbuild', true],
]);
return success(data: ( new UpgradeService() )->upgrade($addon, $data));
}

View File

@ -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');

View File

@ -0,0 +1,430 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\adminapi\controller\notice;
use app\service\admin\notice\NiuSmsService;
use core\base\BaseAdminController;
use think\Response;
class NiuSms extends BaseAdminController
{
/**
* 启用牛云短信
* @return Response
*/
public function enable()
{
$params = $this->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', ""],
['signature', ""],
/*以下为实名信息*/
['contentExample', ""],
['companyName', ""],
['creditCode', ""],
['legalPerson', ""],
['principalName', ""],
['principalIdCard', ""],
['principalMobile', ""],
['signSource', ""],
['signType', ""],
['imgUrl', ""],
]);
$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', ""],
['principalMobile', ""],
['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
* @param $template_id
* @return Response
*/
public function templateDelete($username, $template_id)
{
(new NiuSmsService())->templateDelete($username, $template_id);
return success('DELETE_SUCCESS');
}
/**
* 创建订单
* @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);
}
}

View File

@ -111,5 +111,4 @@ class Notice extends BaseAdminController
(new NoticeService())->edit($data['key'], $data['type'], $data);
return success();
}
}

View File

@ -26,6 +26,7 @@ class Account extends BaseAdminController
{
$data = $this->request->params([
['type', ''],
['trade_no', ''],
['create_time', []],
]);
return success((new AccountLogService())->getPage($data));

View File

@ -136,29 +136,4 @@ class Attachment extends BaseAdminController
return success();
}
/**
* 获取图标库分类列表
*/
public function getIconCategoryList()
{
$data = $this->request->params([
['name', ''],
]);
return success((new AttachmentService())->getIconCategoryList($data));
}
/**
* 获取图标库列表
*/
public function getIconList()
{
$data = $this->request->params([
['page', 0],
['limit', 0],
['cate_id', 0],
['real_name', ''],
]);
return success((new AttachmentService())->getIconList($data));
}
}

View File

@ -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");
}
}

View File

@ -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');

View File

@ -45,6 +45,50 @@ 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');
Route::delete(':username/:template_id', 'notice.NiuSms/templateDelete');
});
});
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,

View File

@ -133,10 +133,6 @@ Route::group('sys', function() {
Route::put('upload/config', 'upload.Upload/setUploadConfig');
//获取上传设置
Route::get('upload/config', 'upload.Upload/getUploadConfig');
// 获取图标库列表
Route::get('attachment/icon_category', 'sys.Attachment/getIconCategoryList');
// 获取图标库列表
Route::get('attachment/icon', 'sys.Attachment/getIconList');
/***************************************************** 协议管理 ****************************************************/
//消息列表
Route::get('agreement', 'sys.Agreement/lists');

View File

@ -33,12 +33,15 @@ Route::group('user', function () {
Route::put(':uid', 'user.User/edit');
//修改用户属性
Route::put(':uid/:field', 'user.User/modify');
//删除用户
Route::delete(':uid', 'user.User/del');
/***************************************************** 操作日志 **************************************************/
//操作日志列表
Route::get('userlog', 'user.UserLog/lists');
//操作日志详情
Route::get('userlog/:id', 'user.UserLog/info');
Route::delete('userlog/destroy', 'user.UserLog/destroy');
})->middleware([
AdminCheckToken::class,

View File

@ -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');

View File

@ -182,7 +182,7 @@ class Workerman extends Command
$addon_path = $addon_dir . $v[ 'key' ] . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'job';
if (is_dir($addon_path)) {
search_dir($addon_path, $addon_data, root_path());
$class_list = array_merge($class_list, $addon_data);
$class_list = array_merge($class_list, array_filter($addon_data));
}
}

View File

@ -0,0 +1,60 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\dict\common;
/**
* 渠道枚举类
* Class ChannelDict
* @package app\dict\common
*/
class CommonActiveDict
{
const IMPULSE_BUY = 'impulse_buy';
const GIFTCARD = 'gift_card';
const DISCOUNT = 'discount';// 限时折扣
const EXCHANGE = 'exchange';// 积分商城
const MANJIANSONG = 'manjiansong'; // 满减送
const NEWCOMER_DISCOUNT = 'newcomer_discount'; // 新人专享
public static function getActiveShort($active)
{
$data = [
self::IMPULSE_BUY => [
'name' => get_lang('common_active_short.impulse_buy'),
'bg_color' => "#FFAE42"
],
self::GIFTCARD => [
'name' => get_lang('common_active_short.gift_card'),
'bg_color' => '#FF0000'
],
self::DISCOUNT => [
'name' => get_lang('common_active_short.discount'),
'bg_color' => '#38B0DE'
],
self::EXCHANGE => [
'name' => get_lang('common_active_short.exchange'),
'bg_color' => '#00FFFF'
],
self::MANJIANSONG => [
'name' => get_lang('common_active_short.manjiansong'),
'bg_color' => '#00FF00'
],
self::NEWCOMER_DISCOUNT => [
'name' => get_lang('common_active_short.newcomer_discount'),
'bg_color' => '#70DB93'
],
];
return !empty($active) ? $data[$active] : $data;
}
}

View File

@ -2419,6 +2419,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',

View File

@ -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,22 @@ class NoticeDict
* 获取消息
* @return array
*/
public static function getNotice(string $key = '')
public static function getNotice(string $key = '',$sms_type = '')
{
if (empty($sms_type)){
$sms_type = (new CoreConfigService())->getConfigValue(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'](['sms_type' => $sms_type]);
}
}
}
foreach ($notice as $k => $v) {
@ -51,4 +61,62 @@ class NoticeDict
return $notice;
}
}
/**
* 获取消息模版包含插件名称
* @return array
*/
public static function getNoticeWithAddon(string $key = '',$sms_type = '')
{
if (empty($sms_type)) {
$sms_type = (new CoreConfigService())->getConfigValue(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'](['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]);
continue;
}
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;
}
}

View File

@ -20,6 +20,24 @@ class NoticeTypeDict
//微信小程序
public const WEAPP = 'weapp';
public const TEMPLATE_AUDIT_STATUS_NEED_AGAIN_REPORT = -3;
public const TEMPLATE_AUDIT_STATUS_NEED_EDIT = -2;
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 +52,156 @@ 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_NEED_AGAIN_REPORT => get_lang('dict_sms_api.template_status_again_report'),
self::TEMPLATE_AUDIT_STATUS_NEED_EDIT => get_lang('dict_sms_api.template_status_need_edit'),
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$/',
'min'=>4,
'max'=>6
],
[
'name' => '手机号',
'type' => self::PARAMS_TYPE_MOBILE_NUMBER,
'desc' => '1-15位纯数字',
'rule' => '/^\d$/',
'min'=>1,
'max'=>15
],
[
'name' => '其他号码',
'type' => self::PARAMS_TYPE_OTHER_NUMBER,
'desc' => '1-32位字母+数字组合',
'rule'=>'/^[a-zA-Z0-9]$/',
'min'=>1,
'max'=>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}()]$/u',
'min'=>1,
'max'=>32
],
[
'name' => '其他',
'type' => self::PARAMS_TYPE_OTHERS,
'desc' => ' 1-35个中文数字字母组合支持中文符号和空格',
'rule' => '/^[\p{Han}\p{N}\p{L}\p{P}\p{S}\s]$/u',
'min'=>1,
'max'=>35
],
];
}
}

View File

@ -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' => [

View File

@ -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}的提现申请已通过,您现在可以在提现中点击提现收款了',
// ]

View File

@ -48,5 +48,17 @@ return [
],
'class' => 'app\job\upgrade\AutoClearUpgradeRecords',
'function' => ''
],[
'key' => 'auto_clear_user_log',
'name' => '定时清理用户操作日志',
'desc' => '',
'time' => [
'type' => 'day',
'day' => 1,
'hour' => 1,
'min' => 1
],
'class' => 'app\job\sys\ClearUserLog',
'function' => ''
],
];

View File

@ -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';//短信配置
}

View File

@ -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',
],
];

View File

@ -39,6 +39,7 @@ class StorageDict
$system = [
self::LOCAL => [
'name' => '本地存储',
'site_name' => '默认存储',
//配置参数
'params' => [
],

View File

@ -16,7 +16,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 '作者',
@ -341,6 +341,7 @@ CREATE TABLE `member` (
`sex` tinyint(4) NOT NULL DEFAULT 0 COMMENT '性别 0保密 1男 2女',
`status` tinyint(4) NOT NULL DEFAULT 1 COMMENT '用户状态 用户状态默认为1',
`birthday` varchar(20) NOT NULL DEFAULT '' COMMENT '出生日期',
`id_card` varchar(50) NOT NULL DEFAULT '' COMMENT '身份证号',
`point` int(11) NOT NULL DEFAULT 0 COMMENT '可用积分',
`point_get` int(11) NOT NULL DEFAULT 0 COMMENT '累计获取积分',
`balance` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '可用余额',
@ -361,6 +362,7 @@ 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 '备注',
`delete_time` int(11) NOT NULL DEFAULT 0 COMMENT '删除时间',
`update_time` int(11) NOT NULL DEFAULT 0 COMMENT '修改时间',
PRIMARY KEY (`member_id`) USING BTREE
@ -494,6 +496,26 @@ 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,
`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 '主键',

View File

@ -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 $key
@ -30,11 +31,15 @@ class Notice extends BaseJob
*/
protected function doJob($key, $data, $template)
{
//通过业务获取模板变量属于以及发送对象
$result = event('NoticeData', [ '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', [ 'key' => $key, 'to' => $notice_data[ 'to' ], 'vars' => $notice_data[ 'vars' ], 'template' => $template ]);
return true;
try {
//通过业务获取模板变量属于以及发送对象
$result = event('NoticeData', ['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', ['key' => $key, 'to' => $notice_data['to'], 'vars' => $notice_data['vars'], 'template' => $template]);
return true;
}catch (\Exception $e){
throw new \Exception($e->getMessage());
}
}
}

View File

@ -0,0 +1,25 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\job\sys;
use app\model\sys\SysUserLog;
use core\base\BaseJob;
class ClearUserLog extends BaseJob
{
public function doJob()
{
(new SysUserLog())->where('create_time','<',time()-7*24*60*60)->delete();
return true;
}
}

View File

@ -61,6 +61,8 @@ return [
'UPGRADE_BACKUP_CODE_NOT_FOUND' => '未找到备份的源码文件',
'UPGRADE_BACKUP_SQL_NOT_FOUND' => '未找到备份的数据库文件',
'NOT_EXIST_UPGRADE_CONTENT' => '没有获取到可以升级的内容',
'CLOUD_BUILD_AUTH_CODE_NOT_FOUND' => '请先填写授权码',
'TASK_CYCLE_ERROR' => '任务周期填写错误',
//登录注册重置账号....
'LOGIN_SUCCESS' => '登录成功',
@ -73,6 +75,7 @@ return [
'OLD_PASSWORD_ERROR' => '原始密码不正确',
'MOBILE_LOGIN_UNOPENED' => '手机号登录注册未开启',
'APP_TYPE_NOT_EXIST' => '无效的登录端口',
"SUPER_ADMIN_NOT_ALLOW_DEL" => "超级管理员不允许删除",
//用户组权限
@ -211,9 +214,6 @@ return [
'CURR_SITE_IS_NOT_OPEN_SSL' => '微信小程序请求地址只支持https请先配置ssl',
'WECHAT_MINI_PROGRAM_CODE_GENERATION_FAILED' => '微信小程序码生成失败',
//站点相关
'SITE_CLOSE_NOT_ALLOW' => '站点已停止',
//支付相关(todo 注意:7段不共享)
'ALIPAY_TRANSACTION_NO_NOT_EXIST' => '无效的支付交易号',
'PAYMENT_METHOD_NOT_SUPPORT' => '您选择到支付方式不受业务支持',
@ -279,8 +279,6 @@ return [
// 授权相关
'AUTH_NOT_EXISTS' => '未获取到授权信息',
/********************************************************* home端专用 **************************************/
// 云服务
'CLOUD_WEAPP_COMPILE_NOT_EXIST' => '未找到微信小程序编译包',
'WEAPP_APPID_EMPTY' => '还没有配置微信小程序',
@ -294,7 +292,7 @@ return [
'VERIFY_TYPE_ERROR' => '核销类型错误',
'VERIFY_CODE_EXPIRED' => '当前核销码已核销或已失效',
'VERIFIER_NOT_EXIST' => '核销员不存在',
'VERIFIER_EXIST'=>'核销员已存在',
'VERIFIER_EXIST' => '核销员已存在',
'VERIFIER_NOT_AUTH' => '该核销员没有权限',
//签到相关
@ -319,5 +317,18 @@ return [
'DIRECTORY' => '目录',
'WAS_NOT_CREATED' => '创建失败',
'PRINTER_NOT_EXIST' => '打印机不存在'
'PRINTER_NOT_EXIST' => '打印机不存在',
/*******************************************牛云短信 start ********************************************************/
'NIU_SMS_ENABLE_FAILED' => '需登录账号并配置签名后才能启用牛云短信',
'ACCOUNT_ERROR_RELOGIN' => '牛云短信账号异常,请重新登录账号',
'ACCOUNT_BIND_MOBILE_ERROR' => '手机号错误',
'TEMPLATE_NOT_SMS_CONTENT' => '当前模版未配置短信内容',
'TEMPLATE_IS_PASS' => '审核通过的模版不允许修改',
'TEMPLATE_NOT_REPORT' => '短信模版暂未报备',
'URL_NOT_FOUND' => '未配置远程服务地址请在ENV中配置{NIU_SHOP_PREFIX}',
'SYSTEM_IS_ERROR' => '远程服务器异常,请联系售后人员',
'TEMPLATE_ERROR' => '短信模版ID错误或审核未通过',
'TEMPLATE_USE_ERROR' => '短信模版参数不一致需修改/重新报备',
/*******************************************牛云短信 end ********************************************************/
];

View File

@ -76,6 +76,27 @@ return [
'var_balance' => '会员余额',
'var_point' => '会员积分',
],
'dict_sms_api'=>[
'template_status_again_report'=>'需重新报备',
'template_status_need_edit'=>'需修改报备参数',
'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' => [
//上传附件类型
@ -376,6 +397,7 @@ return [
'oct' => '10月',
'nov' => '11月',
'dec' => '12月',
],
'dict_site_layout' => [
'default' => '默认'
@ -387,7 +409,8 @@ return [
'auditing' => '审核中',
'audit_success' => '审核通过',
'audit_fail' => '审核失败',
'published' => '已发布'
'published' => '已发布',
'undo' => '已撤回'
],
'dict_wechat_media' => [
'type_image' => '图片',
@ -425,5 +448,13 @@ return [
'ready' => '准备执行',
'complete' => '完成',
'fail' => '失败'
],
'common_active_short'=>[
'impulse_buy'=>'顺',
'gift_card'=>'礼',
'discount'=>'折',
'exchange'=>'积',
'manjiansong'=>'满减',
'newcomer_discount'=>'新',
]
];

View File

@ -50,6 +50,7 @@ return [
'username_max' => '用户名不能超过30个字符',
'mobile_require' => '手机号必须填写',
'mobile_mobile' => '手机号格式错误',
'mobile_unique' => '手机号已存在',
'sex_bot_exist' => '不存在的性别',
'label_name_require' => '会员标签必须填写',
'birthday_format' => '生日日期格式有误',

View File

@ -22,6 +22,7 @@ class Sms
if ($template[ 'is_sms' ]) {
$sms_id = $template[ 'sms_id' ];//发送模板id
$content = $template[ 'sms' ][ 'content' ];
$url_params = $template[ 'sms' ][ 'url_params' ] ?? [];
$member_id = $to[ 'member_id' ] ?? 0;
$uid = $to[ 'uid' ] ?? 0;
if (!$mobile) {
@ -48,7 +49,8 @@ class Sms
'content' => $content,
'result' => ''
);
$core_sms_service->send($mobile, $vars, $key, $sms_id, $content);
$core_sms_service->send($mobile, $vars, $key, $sms_id, $content, $url_params);
( new CoreNoticeLogService() )->add($log_data);
} catch (NoticeException $e) {
$log_data[ 'result' ] = $e->getMessage();

View File

@ -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)

View File

@ -44,7 +44,7 @@ class AccountLog extends BaseModel
*/
public function getTypeNameAttr($value, $data)
{
return AccountLogDict::getType()[$data['type']] ?? '';
return AccountLogDict::getType()[ $data[ 'type' ] ] ?? '';
}
/**
@ -55,10 +55,10 @@ class AccountLog extends BaseModel
*/
public function getPayInfoAttr($value, $data)
{
return match ($data['type']) {
'pay' => (new Pay())->where([['out_trade_no', '=', $data['trade_no']]])->append(['type_name'])->findOrEmpty()->toArray(),
'refund' => (new Refund())->where([['refund_no', '=', $data['trade_no']]])->append(['type_name'])->findOrEmpty()->toArray(),
'transfer' => (new Transfer())->where([['transfer_no', '=', $data['trade_no']]])->append(['transfer_type_name'])->findOrEmpty()->toArray(),
return match ( $data[ 'type' ] ) {
'pay' => ( new Pay() )->where([ [ 'out_trade_no', '=', $data[ 'trade_no' ] ] ])->append([ 'type_name' ])->findOrEmpty()->toArray(),
'refund' => ( new Refund() )->where([ [ 'refund_no', '=', $data[ 'trade_no' ] ] ])->append([ 'type_name' ])->findOrEmpty()->toArray(),
'transfer' => ( new Transfer() )->where([ [ 'transfer_no', '=', $data[ 'trade_no' ] ] ])->append([ 'transfer_type_name' ])->findOrEmpty()->toArray(),
default => [],
};
}
@ -77,6 +77,20 @@ class AccountLog extends BaseModel
}
}
/**
* 状态字段转化
* @param $query
* @param $value
* @param $data
* @return void
*/
public function searchTradeNoAttr($query, $value, $data)
{
if ($value != '') {
$query->where('trade_no', 'like', "%$value%");
}
}
/**
* 金额转化
* @param $value
@ -85,10 +99,10 @@ class AccountLog extends BaseModel
*/
public function getMoneyAttr($value, $data)
{
if (str_contains($data['money'], "-")) {
return $data['money'];
if (str_contains($data[ 'money' ], "-")) {
return $data[ 'money' ];
} else {
return "+" . $data['money'];
return "+" . $data[ 'money' ];
}
}
@ -100,14 +114,14 @@ class AccountLog extends BaseModel
*/
public function searchCreateTimeAttr(Query $query, $value, $data)
{
$start_time = empty($value[0]) ? 0 : strtotime($value[0]);
$end_time = empty($value[1]) ? 0 : strtotime($value[1]);
$start_time = empty($value[ 0 ]) ? 0 : strtotime($value[ 0 ]);
$end_time = empty($value[ 1 ]) ? 0 : strtotime($value[ 1 ]);
if ($start_time > 0 && $end_time > 0) {
$query->whereBetweenTime('create_time', $start_time, $end_time);
} else if ($start_time > 0 && $end_time == 0) {
$query->where([['create_time', '>=', $start_time]]);
$query->where([ [ 'create_time', '>=', $start_time ] ]);
} else if ($start_time == 0 && $end_time > 0) {
$query->where([['create_time', '<=', $end_time]]);
$query->where([ [ 'create_time', '<=', $end_time ] ]);
}
}

View File

@ -0,0 +1,49 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\model\sys;
use app\dict\notice\NoticeTypeDict;
use core\base\BaseModel;
/**
* 牛云短信消息模型审核表
* Class SysMessage
* @package app\model\sys
*/
class NiuSmsTemplate extends BaseModel
{
/**
* 数据表主键
* @var string
*/
protected $pk = 'id';
public $json = ['report_info','param_json'];
public $jsonAssoc = true;
/**
* 模型名称
* @var string
*/
protected $name = 'niu_sms_template';
public function getTemplateTypeNameAttr($value, $data)
{
return NoticeTypeDict::getTemplateType($data['template_type']);
}
public function getAuditStatusNameAttr($value, $data)
{
return NoticeTypeDict::getTemplateAuditStatus($data['audit_status']);
}
}

View File

@ -190,6 +190,9 @@ class GenerateService extends BaseAdminService
$table_name = preg_replace("/^{$tablePrefix}/", '', $table_info['Name'], 1);
$fields = Db::name($table_name)->getFields();
$generate_table = (new GenerateTable())->where([ [ 'table_name', '=', $table_name] ])->findOrEmpty();
if (!$generate_table->isEmpty()) return $generate_table['id'];
$add_table_data = [
'table_name' => $table_name,
'table_content' => $table_info['Comment'],

View File

@ -37,7 +37,7 @@ class MemberCashOutService extends BaseAdminService
public function getPage(array $where = [])
{
$field = 'id,cash_out_no,member_cash_out.member_id,account_type,transfer_type,transfer_realname,transfer_mobile,transfer_bank,transfer_account,transfer_fail_reason,transfer_status,transfer_time,apply_money,rate,service_money,member_cash_out.money,audit_time,member_cash_out.status,remark,member_cash_out.create_time,refuse_reason,transfer_no, transfer_payment_code';
$field = 'id,cash_out_no,member_cash_out.member_id,account_type,transfer_type,transfer_realname,transfer_mobile,transfer_bank,transfer_account,transfer_fail_reason,transfer_status,transfer_time,apply_money,rate,service_money,member_cash_out.money,audit_time,member_cash_out.status,member_cash_out.remark,member_cash_out.create_time,refuse_reason,transfer_no, transfer_payment_code';
$member_where = [];
if(!empty($where['keywords']))
{

View File

@ -0,0 +1,676 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\admin\notice;
use app\dict\notice\NoticeDict;
use app\dict\notice\NoticeTypeDict;
use app\dict\sys\SmsDict;
use app\model\addon\Addon;
use app\model\sys\NiuSmsTemplate;
use app\service\core\notice\CoreNiuSmsService;
use core\base\BaseAdminService;
use core\exception\AdminException;
use core\exception\ApiException;
/**
* 消息管理服务层
*/
class NiuSmsService extends BaseAdminService
{
public function __construct()
{
parent::__construct();
$this->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)
{
$data['imgUrl'] = !empty($data['imgUrl']) ? request()->domain() . $data['imgUrl'] : "";
$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)
{
$params['imgUrl'] = !empty($params['imgUrl']) ? request()->domain() . $params['imgUrl'] : "";
$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],
['template_key', '=', $template_key]
])->findOrEmpty();
$data = [
'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],
])->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['username'] = $report_info['username'] ?? $username;
$params_json = array_keys($report_info['param_json'] ?? []);
sort($params_json);
$variable = array_keys($item['variable'] ?? []);
sort($variable);
$audit_status = $report_info['audit_status'] ?? NoticeTypeDict::TEMPLATE_AUDIT_STATUS_NOT_REPORT;
if (!empty($report_info) && $variable != $params_json) {
$error_status = $audit_status == NoticeTypeDict::TEMPLATE_AUDIT_STATUS_PASS
? NoticeTypeDict::TEMPLATE_AUDIT_STATUS_NEED_AGAIN_REPORT
: NoticeTypeDict::TEMPLATE_AUDIT_STATUS_NEED_EDIT;
}
$item['audit_info'] = [
'audit_msg' => $report_info['audit_msg'] ?? '',
'audit_status' => $audit_status,
'audit_status_name' => NoticeTypeDict::getTemplateAuditStatus($audit_status),
'error_status' => $error_status ?? '',
'error_status_name' => !empty($error_status) ? NoticeTypeDict::getTemplateAuditStatus($error_status) : ""
];
}
return $list;
}
public function checkTemplateAudit($template_key, $template_id)
{
$config = $this->niu_service->getNiuLoginConfig(true);
//当前使用短信功能提供商非牛云短信无需校验模版ID是否正常
if ($config['default'] != SmsDict::NIUSMS) {
return true;
}
$config = $config[SmsDict::NIUSMS];
if (empty($config)) {
throw new AdminException('TEMPLATE_ERROR');
}
$template_info = $this->template_model->where([
['sms_type', '=', SmsDict::NIUSMS],
['template_id', '=', $template_id],
['username', '=', $config['username']],
['template_key', '=', $template_key],
])->findOrEmpty()->toArray();
$params_json = array_keys($template_info['param_json'] ?? []);
sort($params_json);
$template_config = $this->getTemplateList(SmsDict::NIUSMS, $config['username'], $template_key)[0];
$variable = array_keys($template_config['variable'] ?? []);
sort($variable);
if (!empty($template_info) && $variable != $params_json) {
throw new AdminException('TEMPLATE_USE_ERROR');
}
if (empty($template_info) || $template_info['audit_status'] != NoticeTypeDict::TEMPLATE_AUDIT_STATUS_PASS) {
throw new AdminException('TEMPLATE_ERROR');
}
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([
['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');
}
$model_info = $this->template_model->where('template_key', $template_key)->findOrEmpty();
if (!$model_info->isEmpty() && $model_info->audit_status == NoticeTypeDict::TEMPLATE_AUDIT_STATUS_PASS) {
throw new AdminException('TEMPLATE_IS_PASS');
}
$config = $this->niu_service->getNiuLoginConfig();
$data = [
'temName' => $template_info['name'],
'temType' => $params['template_type'],
'temContent' => $template_info['sms']['content'],
'paramJson' => $params['params_json'],
'extend' => ['template_key' => $template_key],
'signature' => $config['signature'],
'temId' => $params['template_id'],
];
$res = $this->niu_service->templateCreate($username, $data);
$tem_id = $res['temId'] ?? 0;
if ($model_info->isEmpty()) {
$this->template_model->create([
'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 $username
* @param $template_id
* @return void
* @throws \Exception
*/
public function templateDelete($username, $template_id)
{
$config = $this->niu_service->getNiuLoginConfig();
$params['password'] = $config['password'];
$params['template_id'] = $template_id;
$this->niu_service->templateDelete($username, $params);
$this->template_model->where('template_id', $template_id)->delete();
}
/**
* 格式化列表接口分页器
* @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;
}
}

View File

@ -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($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($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,10 @@ class NoticeService extends BaseAdminService
case NoticeTypeDict::WEAPP:
break;
}
if ($type == NoticeTypeDict::SMS && $data['status'] == 1) {
(new NiuSmsService())->checkTemplateAudit($data['key'], $data['sms_id']);
}
return (new CoreNoticeService())->edit($key, $save_data);
}
}

View File

@ -12,10 +12,12 @@
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;
use core\exception\AdminException;
use think\Response;
/**
* 短信配置服务层
@ -33,8 +35,8 @@ class SmsService extends BaseAdminService
public function getList()
{
$sms_type_list = SmsDict::getType();
$info = (new CoreConfigService())->getConfig('SMS');
if(empty($info))
$info = (new CoreConfigService())->getConfig(ConfigKeyDict::SMS);
if(empty($info) || !isset($info['value']['default']))
{
$config_type = ['default' => ''];//初始化
}else
@ -73,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('SMS');
if(empty($info))
$info = (new CoreConfigService())->getConfig(ConfigKeyDict::SMS);
if(empty($info) || !isset($info['value']['default']))
{
$config_type = ['default' => ''];//初始化
}else
@ -110,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('SMS');
if(empty($info))
$info = (new CoreConfigService())->getConfig(ConfigKeyDict::SMS);
if(empty($info) || !isset($info['value']['default']))
{
$config['default'] = '';
@ -132,7 +134,7 @@ class SmsService extends BaseAdminService
$config[$sms_type][$k_param] = $value;
}
return (new CoreConfigService())->setConfig('SMS', $config);
return (new CoreConfigService())->setConfig(ConfigKeyDict::SMS, $config);
}

View File

@ -37,9 +37,8 @@ class AccountLogService extends BaseAdminService
*/
public function getPage(array $where = [])
{
$field = 'id, type, money, trade_no, create_time';
$search_model = $this->model->withSearch([ 'create_time', 'type' ], $where)->field($field)->append([ 'type_name', 'money', 'pay_info' ])->order('create_time desc');
$search_model = $this->model->withSearch([ 'create_time', 'type', 'trade_no' ], $where)->field($field)->append([ 'type_name', 'money', 'pay_info' ])->order('create_time desc');
return $this->pageQuery($search_model);
}

View File

@ -12,8 +12,10 @@
namespace app\service\admin\schedule;
use app\dict\schedule\ScheduleDict;
use app\service\core\schedule\CoreScheduleService;
use core\base\BaseAdminService;
use core\exception\AdminException;
/**
@ -67,7 +69,11 @@ class ScheduleService extends BaseAdminService
*/
public function add(array $data)
{
$res = (new CoreScheduleService())->add($data);
if (!empty($data['time'])) {
$this->checkTimeCycle($data['time']);
}
(new CoreScheduleService())->add($data);
return true;
}
@ -80,10 +86,42 @@ class ScheduleService extends BaseAdminService
*/
public function edit(int $id, array $data)
{
if (!empty($data['time'])) {
$this->checkTimeCycle($data['time']);
}
(new CoreScheduleService())->edit($id, $data);
return true;
}
/**
* 校验任务时间配置
* @param array $time
* @throws AdminException
*/
protected function checkTimeCycle(array $time)
{
$type = $time['type'] ?? null;
// 配置要求字段
$rules = [
ScheduleDict::MIN => ['min'],
ScheduleDict::HOUR => ['hour', 'min'],
ScheduleDict::DAY => ['day', 'hour', 'min'],
ScheduleDict::WEEK => ['hour', 'min'],
ScheduleDict::MONTH => ['day', 'hour', 'min'],
];
if (!isset($rules[$type])) {
throw new AdminException('TASK_CYCLE_ERROR');
}
foreach ($rules[$type] as $field) {
if (empty($time[$field])) {
throw new AdminException('TASK_CYCLE_ERROR');
}
}
}
/**
* 删除
* @param int $id
@ -111,4 +149,4 @@ class ScheduleService extends BaseAdminService
{
return (new CoreScheduleService())->doSchedule($id);
}
}
}

View File

@ -236,77 +236,4 @@ class AttachmentService extends BaseAdminService
return SysAttachmentCategory::where($where)->field('id,name,type')->order('id desc')->select()->toArray();
}
/**
* 获取图标库分类列表
* @param array $data
* @return array|null
*/
public function getIconCategoryList(array $data)
{
$icon_list = IconDict::getIcon();
foreach ($icon_list as $k => $v) {
unset($icon_list[ $k ][ 'glyphs' ]);
if (isset($data[ 'name' ]) && $data[ 'name' ] != '' && !str_contains($v[ 'name' ], $data[ 'name' ])) {
unset($icon_list[ $k ]);
}
}
return array_values($icon_list);
}
/**
* 获取图标库列表
* @param array $data
* @return array|null
*/
public function getIconList(array $data)
{
$icon_list = IconDict::getIcon();
$res = [
'current_page' => intval($data[ 'page' ]),
'per_page' => intval($data[ 'limit' ]),
'data' => [],
'total' => 0
];
$temp_data = [];
foreach ($icon_list as $v) {
$icon = $v[ 'glyphs' ]; // 图标列表
foreach ($icon as $ck => $cv) {
// 素材表中数据保持要一致
$icon[ $ck ][ 'att_id' ] = $cv[ 'icon_id' ];
$icon[ $ck ][ 'url' ] = $v[ 'font_family' ] . ' ' . $v[ 'css_prefix_text' ] . $cv[ 'font_class' ];
$icon[ $ck ][ 'real_name' ] = $cv[ 'name' ];
// 查询名称
if (!empty($data[ 'real_name' ]) && !str_contains($cv[ 'name' ], $data[ 'real_name' ])) {
unset($icon[ $ck ]);
}
}
$icon = array_values($icon);
if (!empty($data[ 'cate_id' ]) && $data[ 'cate_id' ] == $v[ 'id' ]) {
// 查询指定分类下的图标
$temp_data = $icon;
break;
} else {
// 查询全部图标
$temp_data = array_merge($temp_data, $icon);
}
}
// 手动分页
$res[ 'total' ] = count($temp_data); // 总数量
$start = ( $res[ 'current_page' ] - 1 ) * $res[ 'per_page' ]; // 数组下标从0 开始
$icon_list = array_slice($temp_data, $start, $res[ 'per_page' ]);
$res[ 'data' ] = $icon_list;
return $res;
}
}

View File

@ -370,7 +370,7 @@ class BackupRecordsService extends BaseAdminService
if ($restore_result === true) {
$res[ 'data' ] = [
'content' => '恢复数据库备份',
'content' => '数据库恢复完成',
'task' => 'restoreData'
];
} else {
@ -378,6 +378,10 @@ class BackupRecordsService extends BaseAdminService
'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);
@ -393,6 +397,7 @@ class BackupRecordsService extends BaseAdminService
$temp = Cache::get($this->cache_restore_key);
$temp[ 'data' ][] = $res[ 'data' ];
Cache::set($this->cache_restore_key, $temp);
// todo 恢复数据
} elseif ($data[ 'task' ] == 'restoreComplete') {

View File

@ -12,6 +12,7 @@
namespace app\service\admin\upgrade;
/**
* todo 废弃,后续删除
* 框架及插件升级恢复备份
* @package app\service\core\upgrade
*/

View File

@ -91,6 +91,7 @@ class UpgradeService extends BaseAdminService
public function upgradePreCheck(string $addon = '')
{
$niucloud_dir = $this->root_path . 'niucloud' . DIRECTORY_SEPARATOR;
$upgrade_dir = $this->root_path . 'upgrade' . DIRECTORY_SEPARATOR;
$admin_dir = $this->root_path . 'admin' . DIRECTORY_SEPARATOR;
$web_dir = $this->root_path . 'web' . DIRECTORY_SEPARATOR;
$wap_dir = $this->root_path . 'uni-app' . DIRECTORY_SEPARATOR;
@ -110,11 +111,14 @@ class UpgradeService extends BaseAdminService
];
$data[ 'dir' ][ 'is_readable' ][] = [ 'dir' => str_replace(project_path(), '', $niucloud_dir), 'status' => is_readable($niucloud_dir) ];
$data[ 'dir' ][ 'is_readable' ][] = [ 'dir' => str_replace(project_path(), '', $upgrade_dir), 'status' => is_readable($upgrade_dir) ];
$data[ 'dir' ][ 'is_readable' ][] = [ 'dir' => str_replace(project_path(), '', $admin_dir), 'status' => is_readable($admin_dir) ];
$data[ 'dir' ][ 'is_readable' ][] = [ 'dir' => str_replace(project_path(), '', $web_dir), 'status' => is_readable($web_dir) ];
$data[ 'dir' ][ 'is_readable' ][] = [ 'dir' => str_replace(project_path(), '', $wap_dir), 'status' => is_readable($wap_dir) ];
$data[ 'dir' ][ 'is_write' ][] = [ 'dir' => str_replace(project_path(), '', $niucloud_dir), 'status' => is_write($niucloud_dir) ];
$data[ 'dir' ][ 'is_write' ][] = [ 'dir' => str_replace(project_path(), '', $upgrade_dir), 'status' => is_write($upgrade_dir) ];
$data[ 'dir' ][ 'is_write' ][] = [ 'dir' => str_replace(project_path(), '', $admin_dir), 'status' => is_write($admin_dir) ];
$data[ 'dir' ][ 'is_write' ][] = [ 'dir' => str_replace(project_path(), '', $web_dir), 'status' => is_write($web_dir) ];
$data[ 'dir' ][ 'is_write' ][] = [ 'dir' => str_replace(project_path(), '', $wap_dir), 'status' => is_write($wap_dir) ];
@ -178,32 +182,43 @@ class UpgradeService extends BaseAdminService
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");
if (empty($upgrade_content['content'])) throw new CommonException("NOT_EXIST_UPGRADE_CONTENT");
// 过滤掉没有更新版本的插件
$upgrade_content['content'] = array_values(array_filter(array_map(function ($item){
if (!empty($item['version_list'])) return $item;
}, $upgrade_content['content'])));
if (empty($upgrade_content['content'])) throw new CommonException("NOT_EXIST_UPGRADE_CONTENT");
$upgrade_content['upgrade_apps'] = [];
foreach ($upgrade_content['content'] as $item) {
$upgrade_content['upgrade_apps'][] = $item['app']['app_key'];
}
$upgrade_title = '框架';
$upgrade = [
'product_key' => BaseNiucloudClient::PRODUCT,
'framework_version' => config('version.version')
];
$upgrade[ 'app_key' ] = $upgrade_content[ 'content' ][ 0 ][ 'app' ][ 'app_key' ];
$upgrade[ 'version' ] = $upgrade_content[ 'content' ][ 0 ][ 'version' ];
$upgrade[ 'app_key' ] = $upgrade_content['content'][0]['app']['app_key'];
$upgrade[ 'version' ] = $upgrade_content['content'][0]['version'];
if (!$addon) {
$upgrade_title = '框架';
// if (!$addon) {
// $upgrade[ 'app_key' ] = AddonDict::FRAMEWORK_KEY;
$upgrade[ 'version' ] = config('version.version');
} else {
// $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', 'in', $addon ] ])->field('title')->select()->toArray();
$upgrade_title = implode(',', array_column($upgrade_title, 'title'));
// $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' ]);
@ -217,10 +232,17 @@ class UpgradeService extends BaseAdminService
}
// 是否需要备份
$is_need_backup = $data[ 'is_need_backup' ] ?? true;
$is_need_backup = $data['is_need_backup'] ?? true;
if (!$is_need_backup) {
unset($this->steps[ 'backupCode' ]);
unset($this->steps[ 'backupSql' ]);
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 = [
@ -232,8 +254,8 @@ class UpgradeService extends BaseAdminService
'log' => [ $this->steps[ 'requestUpgrade' ][ 'title' ] ],
'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
'upgrade_apps' => $upgrade_content['upgrade_apps'],
'is_need_backup' => $is_need_backup,
];
foreach ($upgrade_content[ 'content' ] as $k => $v) {
@ -340,24 +362,24 @@ class UpgradeService extends BaseAdminService
$res = ( new CoreAddonCloudService() )->downloadUpgradeFile($app_key, $token, $dir, $index, $step, $length);
if ($res === true) {
$index = array_search($app_key, $this->upgrade_task[ 'upgrade_apps' ]);
$index = array_search($app_key, $this->upgrade_task['upgrade_apps']);
if ($app_key == AddonDict::FRAMEWORK_KEY) {
$this->upgrade_task[ 'log' ][] = "下载更新文件";
$this->upgrade_task['log'][] = "下载更新文件";
} else {
$this->upgrade_task[ 'log' ][] = "下载" . $this->upgrade_task[ 'upgrade_content' ][ 'content' ][ $index ][ 'app' ][ 'app_name' ] . "更新文件";
$this->upgrade_task['log'][] = "下载". $this->upgrade_task['upgrade_content']['content'][$index]['app']['app_name'] ."更新文件";
}
$index++;
if (isset($this->upgrade_task[ 'upgrade_apps' ][ $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' ]
'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 ['app_key' => $upgrade[ 'app_key' ], 'token' => $response[ 'token' ]];
}
}
return $res;
@ -401,10 +423,10 @@ class UpgradeService extends BaseAdminService
if ($db->getBackupProgress() == 100) {
$this->upgrade_task[ 'log' ][] = "数据库备份完成";
} else {
$this->upgrade_task[ 'log' ][] = $db->getBackupProgress() == 0 ? '数据库开始备份' : '数据库备份已备份' . $db->getBackupProgress() . '%';
$this->upgrade_task[ 'log' ][] = $db->getBackupProgress() == 0 ? '数据库开始备份' : '数据库备份已备份'. $db->getBackupProgress() . '%';
}
if ($result === true) return true;
return [ 'index' => $result ];
return ['index' => $result];
}
/**
@ -414,11 +436,11 @@ class UpgradeService extends BaseAdminService
public function coverCode($index = 0, $addon = "")
{
$this->upgrade_task[ 'is_cover' ] = 1;
if (empty($addon)) $addon = $this->upgrade_task[ 'upgrade_apps' ][ 0 ];
if (empty($addon)) $addon = $this->upgrade_task['upgrade_apps'][0];
$app_index = array_search($addon, $this->upgrade_task[ 'upgrade_apps' ]);
$app_index = array_search($addon, $this->upgrade_task['upgrade_apps']);
$version_list = array_reverse($this->upgrade_task[ 'upgrade_content' ][ 'content' ][ $app_index ][ 'version_list' ]);
$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 ];
@ -473,8 +495,8 @@ class UpgradeService extends BaseAdminService
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 ] ];
if (isset($this->upgrade_task['upgrade_apps'][$app_index])) {
return ['index' => 0, 'addon' => $this->upgrade_task['upgrade_apps'][$app_index]];
}
return true;
}
@ -546,7 +568,7 @@ class UpgradeService extends BaseAdminService
*/
public function handleUniapp()
{
$key = end($this->upgrade_task[ 'upgrade_apps' ]);
$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' ];
@ -621,8 +643,8 @@ class UpgradeService extends BaseAdminService
*/
public function refreshMenu($addon = "")
{
if (empty($addon)) $addon = $this->upgrade_task[ 'upgrade_apps' ][ 0 ];
$app_index = array_search($addon, $this->upgrade_task[ 'upgrade_apps' ]);
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();
@ -631,8 +653,8 @@ class UpgradeService extends BaseAdminService
}
$app_index++;
if (isset($this->upgrade_task[ 'upgrade_apps' ][ $app_index ])) {
return [ 'addon' => $this->upgrade_task[ 'upgrade_apps' ][ $app_index ] ];
if (isset($this->upgrade_task['upgrade_apps'][$app_index])) {
return ['addon' => $this->upgrade_task['upgrade_apps'][$app_index]];
}
return true;
}
@ -643,8 +665,8 @@ class UpgradeService extends BaseAdminService
*/
public function installSchedule($addon = "")
{
if (empty($addon)) $addon = $this->upgrade_task[ 'upgrade_apps' ][ 0 ];
$app_index = array_search($addon, $this->upgrade_task[ 'upgrade_apps' ]);
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();
@ -653,8 +675,8 @@ class UpgradeService extends BaseAdminService
}
$app_index++;
if (isset($this->upgrade_task[ 'upgrade_apps' ][ $app_index ])) {
return [ 'addon' => $this->upgrade_task[ 'upgrade_apps' ][ $app_index ] ];
if (isset($this->upgrade_task['upgrade_apps'][$app_index])) {
return ['addon' => $this->upgrade_task['upgrade_apps'][$app_index]];
}
return true;
}
@ -712,7 +734,7 @@ class UpgradeService extends BaseAdminService
*/
public function upgradeComplete()
{
foreach ($this->upgrade_task[ 'upgrade_apps' ] as $addon) {
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);
@ -744,7 +766,7 @@ class UpgradeService extends BaseAdminService
$this->upgrade_task[ 'params' ] = [];
Cache::set($this->cache_key, $this->upgrade_task);
Log::write('升级出错之后的处理:' . json_encode($fail_reason));
Log::write('升级出错之后的处理:'.json_encode($fail_reason));
}
/**
@ -753,10 +775,10 @@ class UpgradeService extends BaseAdminService
*/
public function restoreCode()
{
if ($this->upgrade_task[ 'is_need_backup' ]) {
if (!isset($this->upgrade_task['is_need_backup']) || $this->upgrade_task['is_need_backup']) {
$backup_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'code' . DIRECTORY_SEPARATOR;
} else {
$backup_dir = $this->upgrade_dir . $this->upgrade_task[ 'upgrade_content' ][ 'last_backup' ][ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'code' . DIRECTORY_SEPARATOR;
$backup_dir = $this->upgrade_dir . $this->upgrade_task['upgrade_content']['last_backup'][ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'code' . DIRECTORY_SEPARATOR;
}
try {
if (is_dir($backup_dir)) {
@ -776,16 +798,21 @@ class UpgradeService extends BaseAdminService
*/
public function restoreSql($index = 0)
{
if ($this->upgrade_task[ 'is_need_backup' ]) {
if (!isset($this->upgrade_task['is_need_backup']) || $this->upgrade_task['is_need_backup']) {
$backup_dir = $this->upgrade_dir . $this->upgrade_task[ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR;
} else {
$backup_dir = $this->upgrade_dir . $this->upgrade_task[ 'upgrade_content' ][ 'last_backup' ][ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR;
$backup_dir = $this->upgrade_dir . $this->upgrade_task['upgrade_content']['last_backup'][ 'key' ] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR;
}
try {
if (is_dir($backup_dir)) {
$db = new DbBackup($backup_dir, key: $this->upgrade_task[ 'key' ]);
$result = $db->restoreDatabase();
if ($result !== true) return [ 'index' => $result ];
if ($result !== true) return ['index' => $result];
$restore_progress = $db->getRestoreProgress();
if ($restore_progress % 5 == 0) {
$this->upgrade_task[ 'log' ][] = $restore_progress == 0 ? '数据库开始恢复' : '数据库恢复中已恢复'. $restore_progress . '%';
}
}
return true;
@ -798,7 +825,7 @@ class UpgradeService extends BaseAdminService
public function restoreComplete()
{
( new UpgradeRecordsService() )->failed($this->upgrade_task[ 'key' ], $this->upgrade_task[ 'error' ]);
( new UpgradeRecordsService() )->failed($this->upgrade_task[ 'key' ], $this->upgrade_task['error']);
$this->clearUpgradeTask(2);
return true;
}
@ -829,8 +856,8 @@ class UpgradeService extends BaseAdminService
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') {
$upgrade[ 'version' ] = $info['version'];
if ($info['type'] == 'app') {
array_unshift($apps, $upgrade);
} else {
array_push($apps, $upgrade);
@ -841,13 +868,13 @@ class UpgradeService extends BaseAdminService
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' ];
$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();
if (!empty($content['content'])) {
$content['last_backup'] = (new SysBackupRecords())->where([ ['status', '=', BackupDict::STATUS_COMPLETE ] ])->order('complete_time desc')->find();
}
return $content;
@ -870,7 +897,7 @@ class UpgradeService extends BaseAdminService
{
// 主动取消升级
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 ]);
( new UpgradeRecordsService() )->edit([ [ 'upgrade_key', '=', $this->upgrade_task[ 'key' ] ], ['status', '=', UpgradeDict::STATUS_READY ] ], ['status' => UpgradeDict::STATUS_CANCEL]);
}
if ($delayed) {

View File

@ -66,4 +66,9 @@ class UserLogService extends BaseAdminService
$res = $this->model->create($data);
return $res->id;
}
public function destroy()
{
(new SysUserLog())->whereRaw("1=1")->delete();
}
}

View File

@ -32,6 +32,7 @@ use think\Model;
class UserService extends BaseAdminService
{
public static $cache_tag_name = 'user_cache';
public function __construct()
{
parent::__construct();
@ -46,16 +47,16 @@ class UserService extends BaseAdminService
{
$field = 'uid,username,head_img,real_name,last_ip,last_time,login_count,status, role_ids, is_admin';
$search = [
'username' => $where['username'],
'realname' => $where['realname'],
'create_time' => $where['create_time']
'username' => $where[ 'username' ],
'realname' => $where[ 'realname' ],
'create_time' => $where[ 'create_time' ]
];
if (!empty($where['role'])) {
$search['role_ids'] = $where['role'];
if (!empty($where[ 'role' ])) {
$search[ 'role_ids' ] = $where[ 'role' ];
}
$search_model = (new SysUser())->withSearch(['username', 'realname', 'create_time', 'role_ids'], $search)->field($field)->order('uid desc')->append(['status_name']);
$search_model = ( new SysUser() )->withSearch([ 'username', 'realname', 'create_time', 'role_ids' ], $search)->field($field)->order('uid desc')->append([ 'status_name' ]);
return $this->pageQuery($search_model, function ($item, $key) {
$role_ids = $item['role_ids'] ?? [];
$role_ids = $item[ 'role_ids' ] ?? [];
$item->role_data = $this->getRoleByUserRoleIds($role_ids);
});
}
@ -66,20 +67,21 @@ class UserService extends BaseAdminService
* @param int $uid
* @return array
*/
public function getInfo(int $uid){
public function getInfo(int $uid)
{
$where = array(
['uid', '=', $uid],
[ 'uid', '=', $uid ],
);
$field = 'uid, username, head_img, real_name, last_ip, last_time, create_time, login_count, status, delete_time, update_time, role_ids, is_admin';
$user = (new SysUser())->where($where)->field($field)->findOrEmpty();
$user = ( new SysUser() )->where($where)->field($field)->findOrEmpty();
if ($user->isEmpty())
return [];
if (!empty($user?->userrole)) {
$user->userrole->appendData(['role_array' => $this->getRoleByUserRoleIds($user->role_ids ?? [])]);
$user->userrole->appendData([ 'role_array' => $this->getRoleByUserRoleIds($user->role_ids ?? []) ]);
}
return $user->append(['status_name'])->toArray();
return $user->append([ 'status_name' ])->toArray();
}
/**
@ -88,18 +90,19 @@ class UserService extends BaseAdminService
* @return bool
* @throws Exception
*/
public function add(array $data){
public function add(array $data)
{
$user_data = [
'username' => $data['username'],
'head_img' => $data['head_img'],
'status' => $data['status'],
'real_name' => $data['real_name'],
'password' => create_password($data['password']),
'username' => $data[ 'username' ],
'head_img' => $data[ 'head_img' ],
'status' => $data[ 'status' ],
'real_name' => $data[ 'real_name' ],
'password' => create_password($data[ 'password' ]),
'is_admin' => $data['is_admin'],
'role_ids' => $data['role_ids'],
'is_admin' => $data[ 'is_admin' ],
'role_ids' => $data[ 'role_ids' ],
];
$user = (new SysUser())->create($user_data);
$user = ( new SysUser() )->create($user_data);
return $user?->uid;
}
@ -110,17 +113,18 @@ class UserService extends BaseAdminService
*/
public function addUser($data)
{
$role_ids = $data['role_ids'] ?? [];
$is_admin = $data['is_admin'] ?? 0;
$role_ids = $data[ 'role_ids' ] ?? [];
$is_admin = $data[ 'is_admin' ] ?? 0;
$data['is_admin'] = $is_admin;
if(!$is_admin){
$data['role_ids'] = $role_ids;
$data[ 'is_admin' ] = $is_admin;
if (!$is_admin) {
$data[ 'role_ids' ] = $role_ids;
}
//添加用户
$uid = $this->add($data);
return $uid;
}
/**
* 更新对应站点用户
* @param $uid
@ -129,11 +133,11 @@ class UserService extends BaseAdminService
*/
public function editUser($uid, $data)
{
$role_ids = $data['role_ids'] ?? [];
$is_admin = $data['is_admin'] ?? 0;
$data['is_admin'] = $is_admin;
if(!$is_admin){
$data['role_ids'] = $role_ids;
$role_ids = $data[ 'role_ids' ] ?? [];
$is_admin = $data[ 'is_admin' ] ?? 0;
$data[ 'is_admin' ] = $is_admin;
if (!$is_admin) {
$data[ 'role_ids' ] = $role_ids;
}
$this->edit($uid, $data);
return true;
@ -149,12 +153,12 @@ class UserService extends BaseAdminService
*/
public function modify(int $uid, string $field, $data)
{
$field_name = match ($field) {
$field_name = match ( $field ) {
'password' => 'password',
'real_name' => 'real_name',
'head_img' => 'head_img',
};
return $this->edit($uid, [$field_name => $data]);
return $this->edit($uid, [ $field_name => $data ]);
}
/**
@ -162,8 +166,9 @@ class UserService extends BaseAdminService
* @param int $uid
* @return bool|true
*/
public function lock(int $uid){
return $this->edit($uid, ['status' => UserDict::OFF]);
public function lock(int $uid)
{
return $this->edit($uid, [ 'status' => UserDict::OFF ]);
}
/**
@ -171,8 +176,9 @@ class UserService extends BaseAdminService
* @param int $uid
* @return bool|true
*/
public function unlock(int $uid){
return $this->edit($uid, ['status' => UserDict::ON]);
public function unlock(int $uid)
{
return $this->edit($uid, [ 'status' => UserDict::ON ]);
}
/**
@ -183,12 +189,10 @@ class UserService extends BaseAdminService
*/
public function checkUsername($username)
{
$count = (new SysUser())->where([['username', '=', $username]])->count();
if($count > 0)
{
$count = ( new SysUser() )->where([ [ 'username', '=', $username ] ])->count();
if ($count > 0) {
return true;
}
else return false;
} else return false;
}
/**
@ -196,9 +200,10 @@ class UserService extends BaseAdminService
* @param int $uid
* @return SysUser|array|mixed|Model
*/
public function find(int $uid){
public function find(int $uid)
{
$user = (new SysUser())->findOrEmpty($uid);
$user = ( new SysUser() )->findOrEmpty($uid);
if ($user->isEmpty())
throw new AdminException('USER_NOT_EXIST');
return $user;
@ -210,44 +215,45 @@ class UserService extends BaseAdminService
* @param array $data
* @return true
*/
public function edit(int $uid, array $data){
public function edit(int $uid, array $data)
{
$user = $this->find($uid);
$user_data = [
];
$is_off_status = false;
if(isset($data['status'])){
$user_data['status'] = $data['status'];
if($data['status'] == UserDict::OFF)
if (isset($data[ 'status' ])) {
$user_data[ 'status' ] = $data[ 'status' ];
if ($data[ 'status' ] == UserDict::OFF)
$is_off_status = true;
}
if(isset($data['head_img'])){
$user_data['head_img'] = $data['head_img'];
if (isset($data[ 'head_img' ])) {
$user_data[ 'head_img' ] = $data[ 'head_img' ];
}
if(isset($data['real_name'])){
$user_data['real_name'] = $data['real_name'];
if (isset($data[ 'real_name' ])) {
$user_data[ 'real_name' ] = $data[ 'real_name' ];
}
$password = $data['password'] ?? '';
$password = $data[ 'password' ] ?? '';
$is_change_password = false;
if(!empty($password) && !check_password($password, $user->password)){
$user_data['password'] = create_password($password);
if (!empty($password) && !check_password($password, $user->password)) {
$user_data[ 'password' ] = create_password($password);
$is_change_password = true;
}
if(isset($data['role_ids'])){
$user_data['role_ids'] = $data['role_ids'];
if (isset($data[ 'role_ids' ])) {
$user_data[ 'role_ids' ] = $data[ 'role_ids' ];
}
if(empty($user_data))
if (empty($user_data))
return true;
//更新用户信息
$user->save($user_data);
//更新权限 禁用用户 修改密码 都会清理token
if($is_off_status || $is_change_password){
if ($is_off_status || $is_change_password) {
LoginService::clearToken($uid);
}
//清除用户缓存
$cache_name = 'user_role_'.$uid;
$cache_name = 'user_role_' . $uid;
Cache::delete($cache_name);
return true;
}
@ -257,13 +263,18 @@ class UserService extends BaseAdminService
* @param int $uid
* @return true
*/
public function del(int $uid){
public function del(int $uid)
{
$where = [
['uid', '=', $uid]
[ 'uid', '=', $uid ]
];
(new SysUser())->where($where)->delete();
$user = ( new SysUser() )->where($where)->findOrEmpty();
if ($user->isEmpty()) throw new AdminException('USER_NOT_EXIST');
if ($user->is_admin) throw new AdminException("SUPER_ADMIN_NOT_ALLOW_DEL");
$user->delete();
LoginService::clearToken($uid);
Cache::delete('user_role_' . $uid);
return true;
}
/**
@ -271,8 +282,9 @@ class UserService extends BaseAdminService
* @param string $username
* @return SysUser|array|mixed|Model
*/
public function getUserInfoByUsername(string $username){
return (new SysUser())->where([['username', '=',$username]])->findOrEmpty();
public function getUserInfoByUsername(string $username)
{
return ( new SysUser() )->where([ [ 'username', '=', $username ] ])->findOrEmpty();
}
/**
@ -283,7 +295,7 @@ class UserService extends BaseAdminService
public function getUserAll(array $where)
{
$field = 'uid, username, head_img';
return (new SysUser())->withSearch(['username', 'realname', 'create_time'], $where)
return ( new SysUser() )->withSearch([ 'username', 'realname', 'create_time' ], $where)
->field($field)
->order('uid desc')
->select()
@ -295,39 +307,42 @@ class UserService extends BaseAdminService
* @param int $uid
* @return mixed|string
*/
public function getUserCache(int $uid){
$cache_name = 'user_role_'.$uid;
public function getUserCache(int $uid)
{
$cache_name = 'user_role_' . $uid;
return cache_remember(
$cache_name,
function() use($uid) {
function () use ($uid) {
$where = array(
['uid', '=', $uid],
[ 'uid', '=', $uid ],
);
$field = 'uid, username, head_img, real_name, last_ip, last_time, create_time, login_count, status, delete_time, update_time, role_ids, is_admin';
$user = (new SysUser())->where($where)->field($field)->append(['status_name'])->findOrEmpty();
$user = ( new SysUser() )->where($where)->field($field)->append([ 'status_name' ])->findOrEmpty();
return $user->toArray();
},
[self::$cache_tag_name, RoleService::$cache_tag_name]
[ self::$cache_tag_name, RoleService::$cache_tag_name ]
);
}
/**
* 通过角色id组获取角色
* @param array $role_ids
* @return mixed
*/
public function getRoleByUserRoleIds(array $role_ids){
public function getRoleByUserRoleIds(array $role_ids)
{
sort($role_ids);
$cache_name = 'role_by_ids_'.md5(implode(',', $role_ids));
$cache_name = 'role_by_ids_' . md5(implode(',', $role_ids));
return cache_remember(
$cache_name,
function() use($role_ids) {
function () use ($role_ids) {
$where = array(
['role_id', 'in', $role_ids],
[ 'role_id', 'in', $role_ids ],
);
return SysRole::where($where)->column('role_name');
},
[RoleService::$cache_tag_name]
[ RoleService::$cache_tag_name ]
);
}
}

View File

@ -16,7 +16,6 @@ use app\dict\diy\TemplateDict;
use app\model\diy\Diy;
use app\model\diy\DiyTheme;
use app\service\core\addon\CoreAddonService;
use app\service\core\diy\CoreDiyService;
use core\base\BaseApiService;
/**

View File

@ -32,6 +32,13 @@ class CoreAddonService extends CoreAddonBaseService
$this->model = new Addon();
}
public function getInitList()
{
return [
'type_list' => AddonDict::getType()
];
}
/**
* 获取已下载的插件
* @return array

View File

@ -132,7 +132,6 @@ class CoreDiyFormRecordsService extends BaseCoreService
$data[ 'create_time' ] = time();
// todo $data[ 'value' ] 考虑过滤存储数据,靠后完善,修改表单可能会用到
$res = $this->model->create($data);
$diy_form_records_fields_model = new DiyFormRecordsFields();
@ -191,7 +190,7 @@ class CoreDiyFormRecordsService extends BaseCoreService
$diy_form_records_fields[] = [
'form_id' => $data[ 'form_id' ], // 所属万能表单id
// 'form_field_id'=>'', // todo 暂无,靠后完善
'record_id' => $res->record_id, // 关联表单填写记录id
// 'record_id' => $res->record_id, // 关联表单填写记录id
'member_id' => $data[ 'member_id' ], // 填写会员id
'field_key' => $component[ 'id' ], // 字段唯一标识
'field_type' => $component[ 'componentName' ], // 字段类型
@ -208,8 +207,11 @@ class CoreDiyFormRecordsService extends BaseCoreService
}
}
if (!empty($diy_form_records_fields)) {
$res = $this->model->create($data);
foreach ($diy_form_records_fields as &$item){
$item['record_id'] = $res->record_id;
}
$diy_form_records_fields_model->insertAll($diy_form_records_fields);
$diy_form = new DiyForm();
@ -224,7 +226,7 @@ class CoreDiyFormRecordsService extends BaseCoreService
}
Db::commit();
return $res->record_id;
return $res->record_id ?? 0;
} catch (\Exception $e) {
Db::rollback();
throw new CommonException($e->getMessage());

View File

@ -0,0 +1,92 @@
<?php
namespace app\service\core\http;
class HttpHelper
{
public function get($url, $data = [])
{
return $this->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;
}
}

View File

@ -47,6 +47,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',

View File

@ -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,16 +87,18 @@ class CoreMenuService extends BaseCoreService
{
$addon_loader = new DictLoader("Menu");
$addon_admin_tree = $addon_loader->load(["addon" => $addon, "app_type" => "admin"]);
$addon_admin_tree = $addon_loader->load([ "addon" => $addon, "app_type" => "admin" ]);
if (isset($addon_admin_tree[ 'delete' ])) unset($addon_admin_tree[ 'delete' ]);
if (isset($addon_admin_tree['delete'])) unset($addon_admin_tree['delete']);
$menu_list = [];
if (!empty($addon_admin_tree)) {
$menu_list = array_merge($menu_list, $this->loadMenu($addon_admin_tree, "admin", $addon));
}
$this->deleteByAddon($addon, false);
if(!empty($menu_list))
{
if (!empty($menu_list)) {
$this->install($menu_list);
}
@ -129,28 +131,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;
}
@ -180,12 +182,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', '=', 'admin'] ])->field('parent_key,router_path')->find();
public function getRoutePathByMenuKey($menu_key, $paths = [])
{
$menu = $this->model->where([ [ 'menu_key', '=', $menu_key ] ])->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);
}

View File

@ -0,0 +1,407 @@
<?php
namespace app\service\core\notice;
use app\dict\sys\ConfigKeyDict;
use app\dict\sys\SmsDict;
use app\service\core\http\HttpHelper;
use app\service\core\sys\CoreConfigService;
use core\base\BaseAdminService;
class CoreNiuSmsService extends BaseAdminService
{
/*************************牛云短信处理****************************/
private const PACKAGE_LIST_URL = '/niusms/packages';
private const SEND_CODE_URL = '/niusms/send';
/***子账号相关***/
private const SEND_CAPTCHA_URL = '/niusms/captcha';
private const LOGIN_ACCOUNT_URL = '/niusms/account/login/%s';
private const ACCOUNT_REGISTER_URL = '/niusms/account/register';
private const ACCOUNT_INFO_URL = '/niusms/account/info/%s';
private const ACCOUNT_EDIT_URL = '/niusms/account/edit/%s';
private const ACCOUNT_SEND_LIST_URL = '/niusms/account/send_list/%s';
private const RESET_PASSWORD_URL = '/niusms/account/reset/password/%s';
/**签名相关**/
private const SIGN_LIST_URL = '/niusms/sign/%s/list';
private const SIGN_INFO_URL = '/niusms/sign/%s/info';
private const SIGN_ADD_URL = '/niusms/sign/%s/add';
/**模版相关**/
private const TEMPLATE_LIST_URL = '/niusms/template/%s/list';
private const TEMPLATE_INFO_URL = '/niusms/template/%s/info';
private const TEMPLATE_ADD_URL = '/niusms/template/%s/add';
/*****订单相关*****/
private const ORDER_LIST_URL = '/niusms/order/list/%s';
private const ORDER_CREATE_URL = '/niusms/order/create/%s';
private const ORDER_NOTIFY_URL = "/niusms/pay/notify";
private const ORDER_CALCULATE_URL = '/niusms/order/calculate/%s';
private const ORDER_PAY_URL = '/niusms/pay/info/%s';
private const ORDER_INFO_URL = '/niusms/order/info/%s/%s';
private const ORDER_STATUS_URL = '/niusms/order/status/%s/%s';
private $niushop_url_prefix = null;
/**
* @throws \Exception
*/
public function __construct()
{
parent::__construct();
$niushop_url_prefix = env('NIU_SHOP_PREFIX', 'https://api.niucloud.com/openapi');
if (empty($niushop_url_prefix)) {
throw new \Exception('URL_NOT_FOUND');
} else {
$this->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(ConfigKeyDict::SMS, $config);
}
public function getNiuLoginConfig($is_all = false)
{
$config = (new CoreConfigService())->getConfigValue(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 $data
* @return mixed
*/
public function templateDelete($username, $params)
{
$time = time();
$request['tKey'] = $time;
$request['password'] = md5(md5($params['password']) . $time);
$request['username'] = $username;
$request['temId'] = $params['template_id'] ?? '';
$url = "https://api-shss.zthysms.com/sms/v2/template/delete";
$res = (new HttpHelper())->httpRequest('POST', $url, $request);
if ($res['code'] != 200) {
throw new \Exception('ZT'.$res['code'].":".$res['msg']);
}
}
/**
* 获取订单列表
* @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;
}
}

View File

@ -111,7 +111,9 @@ class CoreNoticeService extends BaseCoreService
'weapp_template_id' => '',
'sms_id' => '',
'wechat_first' => '',
'wechat_remark' => ''
'wechat_remark' => '',
'audit_status'=>'wait',
'sign'=>'',
]);
}
$item['notice'][] = $notice_item;
@ -132,7 +134,7 @@ class CoreNoticeService extends BaseCoreService
public function getInfo(string $key)
{
if (!array_key_exists($key, NoticeDict::getNotice())) throw new NoticeException('NOTICE_TYPE_NOT_EXIST');
$info = $this->model->where([ [ 'id', '>', 0 ], [ 'key', '=', $key ] ])->findOrEmpty()->toArray();
$info = $this->model->where([ [ 'key', '=', $key ] ])->findOrEmpty()->toArray();
if (!empty($info)) {
$notice = array_merge(NoticeDict::getNotice($key), $info);
} else {
@ -172,7 +174,7 @@ class CoreNoticeService extends BaseCoreService
$wechat = $notice_template[ 'wechat' ] ?? [];
$this->model->create(array_merge([
'key' => $key,
'sms_content' => $notice_template['sms'][ 'content' ] ?? '',
'sms_content' => $notice_template[ 'sms']['content' ] ?? '',
'wechat_first' => $data[ 'wechat_first' ] ?? ( $wechat[ 'first' ] ?? '' ),
'wechat_remark' => $data[ 'wechat_remark' ] ?? ( $wechat[ 'remark' ] ?? '' ),
], $data));

View File

@ -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;
@ -29,7 +30,7 @@ class CoreSmsService extends BaseCoreService
parent::__construct();
}
public function send($mobile, $params, $key, $template_id, $content)
public function send($mobile, $params, $key, $template_id, $content,$url_params=[])
{
//查询配置
$config = $this->getDefaultSmsConfig();
@ -46,9 +47,9 @@ class CoreSmsService extends BaseCoreService
'params' => $params,
'status' => SmsDict::SENDING
]);
$sms_driver = new SmsLoader($sms_type, $config);
$params = $this->makeUp($params, $content, $sms_type);
$params['url_params'] = $url_params;
$result = $sms_driver->send($mobile, $template_id, $params);
if (!$result) {
@ -90,7 +91,7 @@ class CoreSmsService extends BaseCoreService
*/
public function getDefaultSmsConfig()
{
$info = (new CoreConfigService())->getConfig('SMS')['value'] ?? [];
$info = (new CoreConfigService())->getConfig(ConfigKeyDict::SMS)['value'] ?? [];
if (empty($info))
throw new NoticeException('NOTICE_SMS_NOT_OPEN');
@ -101,4 +102,4 @@ class CoreSmsService extends BaseCoreService
return array_merge($config, $info[$sms_type] ?? []);
}
}
}

View File

@ -34,12 +34,18 @@ class NoticeService extends BaseCoreService
* @param $key
* @param $data
* @return false|mixed
* @throws \Exception
*/
public static function send($key, $data){
$template = (new CoreNoticeService())->getInfo($key);
if(empty($template)) return false;
try {
$template = (new CoreNoticeService())->getInfo($key);
if(empty($template)) return false;
return Notice::dispatch(['key' => $key, 'data' => $data, 'template' => $template], is_async:$template['async']);
return Notice::dispatch(['key' => $key, 'data' => $data, 'template' => $template], is_async:$template['async']);
}catch (\Exception $e){
throw new \Exception($e->getMessage());
}
}
}
}

View File

@ -27,6 +27,7 @@ use Throwable;
class CoreRefundService extends BaseCoreService
{
protected $pay_event;
public function __construct()
{
parent::__construct();
@ -41,16 +42,17 @@ class CoreRefundService extends BaseCoreService
* @param string $reason
* @return string|null
*/
public function create(string $out_trade_no, float $money, string $reason = '', $trade_type = '', $trade_id = ''){
public function create(string $out_trade_no, float $money, string $reason = '', $trade_type = '', $trade_id = '')
{
//通过交易流水号获取支付单据
$pay = (new CorePayService())->findPayInfoByOutTradeNo($out_trade_no);
if($pay->isEmpty()) throw new PayException('ALIPAY_TRANSACTION_NO_NOT_EXIST');//单据不存在
$pay = ( new CorePayService() )->findPayInfoByOutTradeNo($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');
// 查询当前支付已存在的退款单据,所有的退款总额不能超过支付单据的支付金额
$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('退款金额不能超过支付总额');//退款金额不能超过支付总额
$comparison = bccomp(bcadd($total_refund_money, $money), $pay[ 'money' ]); // 浮点数直接进行比较会出现精度问题
if ($comparison > 0) throw new PayException('退款金额不能超过支付总额'); // 退款金额不能超过支付总额
//校验当前数据是否存在
//存在就修改,不存在就创建
@ -76,26 +78,27 @@ class CoreRefundService extends BaseCoreService
* @param string $voucher
* @return true
*/
public function refund(string $refund_no, $voucher = '', $refund_type = RefundDict::BACK, $main_type = '', $main_id = 0){
public function refund(string $refund_no, $voucher = '', $refund_type = RefundDict::BACK, $main_type = '', $main_id = 0)
{
$refund = $this->findByRefundNo($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($out_trade_no);
if($pay->isEmpty()) throw new PayException('ALIPAY_TRANSACTION_NO_NOT_EXIST');//单据不存在
try{
$pay = ( new CorePayService() )->findPayInfoByOutTradeNo($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($refund->channel, $refund->type)->refund($out_trade_no, $money, $pay['money'], $refund_no, $voucher);
$pay_result = $this->pay_event->init($refund->channel, $refund->type)->refund($out_trade_no, $money, $pay[ 'money' ], $refund_no, $voucher);
$this->refundNotify($out_trade_no, $refund->type, $pay_result);
}else if($refund_type == RefundDict::OFFLINE){
$pay_result = $this->pay_event->init($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($refund->channel, PayDict::OFFLINEPAY)->refund($out_trade_no, $money, $pay[ 'money' ], $refund_no, $voucher);
$this->refundNotify($out_trade_no, $refund->type, $pay_result, $main_type, $main_id);
}
}catch ( Throwable $e) {
} catch (Throwable $e) {
throw new PayException($e->getMessage());
}
return true;
@ -106,9 +109,10 @@ class CoreRefundService extends BaseCoreService
* @param string $refund_no
* @return void
*/
public function findByRefundNo(string $refund_no){
public function findByRefundNo(string $refund_no)
{
return $this->model->where([
['refund_no', '=', $refund_no],
[ 'refund_no', '=', $refund_no ],
])->findOrEmpty();
}
@ -122,25 +126,26 @@ class CoreRefundService extends BaseCoreService
* @param $main_id
* @return true
*/
public function refundNotify($out_trade_no, string $type, array $params = [], $main_type = '', $main_id = 0){
$refund_no = $params['refund_no'];
public function refundNotify($out_trade_no, string $type, array $params = [], $main_type = '', $main_id = 0)
{
$refund_no = $params[ 'refund_no' ];
$refund = $this->findByRefundNo($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([
'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
]);
@ -156,14 +161,14 @@ class CoreRefundService extends BaseCoreService
$this->refundFail([
'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 +180,24 @@ class CoreRefundService extends BaseCoreService
* @param $data
* @return true
*/
public function check($data){
$out_trade_no = $data['out_trade_no'];
$refund_no = $data['refund_no'];
public function check($data)
{
$out_trade_no = $data[ 'out_trade_no' ];
$refund_no = $data[ 'refund_no' ];
$refund = $this->findByRefundNo($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($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([
'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 +210,7 @@ class CoreRefundService extends BaseCoreService
$this->refundFail([
'out_trade_no' => $out_trade_no,
'refund_no' => $refund_no,
'fail_reason' => $refund_info['fail_reason']
'fail_reason' => $refund_info[ 'fail_reason' ]
]);
break;
}
@ -214,18 +222,19 @@ class CoreRefundService extends BaseCoreService
* @param array $data
* @return bool
*/
public function refundSuccess(array $data){
public function refundSuccess(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([
['refund_no', '=', $refund_no]
[ 'refund_no', '=', $refund_no ]
])->update([
'status' => RefundDict::SUCCESS
]);
$pay = (new CorePayService())->findPayInfoByOutTradeNo($out_trade_no);
$result = event('RefundSuccess', ['refund_no' => $refund_no, 'trade_type' => $pay->trade_type, 'trade_id' => $data['trade_id']]);
if(!check_event_result($result)){
$pay = ( new CorePayService() )->findPayInfoByOutTradeNo($out_trade_no);
$result = event('RefundSuccess', [ 'refund_no' => $refund_no, 'trade_type' => $pay->trade_type, 'trade_id' => $data[ 'trade_id' ] ]);
if (!check_event_result($result)) {
return false;
}
return true;
@ -236,13 +245,14 @@ class CoreRefundService extends BaseCoreService
* @param array $data
* @return true
*/
public function refundFail(array $data){
$refund_no = $data['refund_no'];
public function refundFail(array $data)
{
$refund_no = $data[ 'refund_no' ];
$this->model->where([
['refund_no', '=', $refund_no]
[ 'refund_no', '=', $refund_no ]
])->update([
'status' => RefundDict::FAIL,
'fail_reason' => $data['fail_reason']
'fail_reason' => $data[ 'fail_reason' ]
]);
return true;
}
@ -252,11 +262,12 @@ class CoreRefundService extends BaseCoreService
* @param array $data
* @return true
*/
public function refundDealing(array $data){
$out_trade_no = $data['out_trade_no'];
$refund_no = $data['refund_no'];
public function refundDealing(array $data)
{
$out_trade_no = $data[ 'out_trade_no' ];
$refund_no = $data[ 'refund_no' ];
$this->model->where([
['refund_no', '=', $refund_no]
[ 'refund_no', '=', $refund_no ]
])->update([
'status' => RefundDict::DEALING
]);

View File

@ -67,7 +67,7 @@ class CoreWeappCloudService extends CoreCloudBaseService
// 如果不存在编译版小程序
if ($compile_addon->isEmpty()) {
dir_copy($this->root_path . 'uni-app', $uni_dir, exclude_dirs: [ 'node_modules', 'unpackage', 'dist' ]);
// $this->handleTabbar($uni_dir . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR);
$this->handleTabbar($uni_dir . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR);
// 替换env文件
$this->weappEnvReplace($uni_dir . DIRECTORY_SEPARATOR . '.env.production');
} else {
@ -123,6 +123,9 @@ class CoreWeappCloudService extends CoreCloudBaseService
}
$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);

View File

@ -0,0 +1,29 @@
DROP TABLE IF EXISTS `niu_sms_template`;
CREATE TABLE `niu_sms_template` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`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 `id_card` VARCHAR(30) DEFAULT '' COMMENT '身份证号';
ALTER TABLE `member` MODIFY `id_card` VARCHAR(30) DEFAULT '' COMMENT '身份证号' AFTER `birthday`;
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 '插件标识';

View File

@ -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 = [

View File

@ -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']
@ -86,4 +86,4 @@ class Member extends Validate
{
return isset(MemberDict::getStatus()[$value]) ? true : get_lang("validate_member.not_exit_status");
}
}
}

View File

@ -1,6 +1,6 @@
<?php
return [
'version' => '1.5.3',
'code' => '2025052201'
'version' => '1.5.4',
'code' => '2025061001'
];

View File

@ -154,6 +154,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

View File

@ -1,50 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace core\dict;
/**
* 图标
* Class Icon
* @package core\dict
*/
class Icon extends BaseDict
{
/**
* @param array $data
* @return array
*/
public function load(array $data): array
{
$sys_path = dirname(app()->getRootPath()) . str_replace('/', DIRECTORY_SEPARATOR, '/admin/src/styles/icon');
$file_arr = getFileMap($sys_path);
$icon_arr = [];
if (!empty($file_arr)) {
foreach ($file_arr as $ck => $cv) {
if (str_contains($cv, '.json')) {
$json_string = file_get_contents($ck);
$icon = json_decode($json_string, true, 512, JSON_THROW_ON_ERROR);
$icon_arr[] = $icon;
}
}
}
if (count($icon_arr) > 1) {
$last_icon = array_pop($icon_arr); // 最后一个
$first_icon = array_shift($icon_arr); // 第一个
array_unshift($icon_arr, $last_icon); // 将系统图标放到第一位置
$icon_arr[] = $first_icon; // 交换位置
}
return $icon_arr;
}
}

View File

@ -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) {

View File

@ -0,0 +1,140 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace core\sms;
use app\dict\notice\NoticeTypeDict;
use app\model\sys\NiuSmsTemplate;
use app\service\core\http\HttpHelper;
use core\exception\CommonException;
use think\facade\Log;
class Niuyun extends BaseSms
{
protected $username = '';
protected $password = '';
protected $signature = '';
// private const SEND_URL = "https://api-ogw.zthysms.com/partner/v1/sms/sub-accounts/message/%s/template";
private const SEND_URL = "https://api-shss.zthysms.com/v2/sendSmsTp";
/**
* @param array $config
* @return void
*/
protected function initialize(array $config = [])
{
Log::write("SEND_NY_SMS init " . json_encode($config, 256));
parent::initialize($config);
$this->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_NY_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_NY_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 = self::SEND_URL;
$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_NY_SMS params " . json_encode($params, 256));
try {
$res = (new HttpHelper())->httpRequest('POST', $url, $params);
Log::write("SEND_NY_SMS res " . json_encode($res, 256));
if ($res['code'] != 200) {
throw new CommonException('ZT-' . $res['code'] . ":" . $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'] ?? '';
$max = $type_arr[$validate]['max'] ?? 1;
$min = $type_arr[$validate]['max'] ?? mb_strlen($value);
if (!empty($pattern) && in_array($validate, [NoticeTypeDict::PARAMS_TYPE_CHINESE, NoticeTypeDict::PARAMS_TYPE_OTHERS])) {
$value = str_replace(' ', '', $value);
$value = str_replace('.', '', $value);
$filtered = preg_replace($pattern, '', $value);
$value = (mb_strlen($filtered, 'UTF-8') >= $min && mb_strlen($filtered, 'UTF-8') <= 35)
? $filtered // 长度合法,保留过滤后的字符串
: mb_substr($filtered, 0, $max); // 长度非法,返回空字符串
}
if (empty($value)) {
Log::write("SEND_NY_SMS 参数异常,无法发送 param:" . $param);
throw new \Exception('NY:参数异常,无法发送');
}
$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)
{
}
}

View File

@ -213,4 +213,9 @@ class DbBackup
$this->setCache();
return $this->restoreIndex;
}
public function getRestoreProgress() {
$backupFiles = glob($this->backupPath . '/backup_*.sql');
return round($this->restoreIndex / count($backupFiles) * 100);
}
}