440 lines
13 KiB
PHP
440 lines
13 KiB
PHP
|
<?php
|
|||
|
|
|||
|
// +----------------------------------------------------------------------
|
|||
|
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
|||
|
// +----------------------------------------------------------------------
|
|||
|
// | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
|
|||
|
// +----------------------------------------------------------------------
|
|||
|
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
|||
|
// +----------------------------------------------------------------------
|
|||
|
// | Author: CRMEB Team <admin@crmeb.com>
|
|||
|
// +----------------------------------------------------------------------
|
|||
|
|
|||
|
|
|||
|
namespace crmeb\services;
|
|||
|
|
|||
|
|
|||
|
use app\common\dao\system\sms\SmsRecordDao;
|
|||
|
use app\common\repositories\store\broadcast\BroadcastRoomRepository;
|
|||
|
use app\common\repositories\store\order\StoreGroupOrderRepository;
|
|||
|
use app\common\repositories\store\order\StoreOrderRepository;
|
|||
|
use app\common\repositories\store\order\StoreRefundOrderRepository;
|
|||
|
use app\common\repositories\store\product\ProductRepository;
|
|||
|
use app\common\repositories\store\product\ProductTakeRepository;
|
|||
|
use app\common\repositories\store\service\StoreServiceRepository;
|
|||
|
use app\common\repositories\system\config\ConfigValueRepository;
|
|||
|
use app\common\repositories\system\notice\SystemNoticeConfigRepository;
|
|||
|
use crmeb\exceptions\SmsException;
|
|||
|
use FormBuilder\Exception\FormBuilderException;
|
|||
|
use FormBuilder\Factory\Elm;
|
|||
|
use FormBuilder\Form;
|
|||
|
use think\exception\ValidateException;
|
|||
|
use think\facade\Cache;
|
|||
|
use think\facade\Config;
|
|||
|
use think\facade\Route;
|
|||
|
|
|||
|
/**
|
|||
|
* Class YunxinSmsService
|
|||
|
* @package crmeb\services
|
|||
|
* @author xaboy
|
|||
|
* @day 2020-05-18
|
|||
|
*/
|
|||
|
class YunxinSmsService
|
|||
|
{
|
|||
|
/**
|
|||
|
* api
|
|||
|
*/
|
|||
|
const API = 'https://sms.crmeb.net/api/';
|
|||
|
// const API = 'http://plat.crmeb.net/api/';
|
|||
|
|
|||
|
/**
|
|||
|
* @var array
|
|||
|
*/
|
|||
|
protected $config;
|
|||
|
|
|||
|
/**
|
|||
|
* YunxinSmsService constructor.
|
|||
|
* @param array $config
|
|||
|
*/
|
|||
|
public function __construct(array $config = [])
|
|||
|
{
|
|||
|
$this->config = $config;
|
|||
|
if (isset($this->config['sms_token'])) {
|
|||
|
$this->config['sms_token'] = $this->getToken();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @return string
|
|||
|
* @author xaboy
|
|||
|
* @day 2020-05-18
|
|||
|
*/
|
|||
|
protected function getToken()
|
|||
|
{
|
|||
|
return md5($this->config['sms_account'] . $this->config['sms_token']);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @author xaboy
|
|||
|
* @day 2020-05-18
|
|||
|
*/
|
|||
|
public function checkConfig()
|
|||
|
{
|
|||
|
if (!isset($this->config['sms_account']) || !$this->config['sms_account']) {
|
|||
|
throw new ValidateException('请登录短信账户');
|
|||
|
}
|
|||
|
if (!isset($this->config['sms_token']) || !$this->config['sms_token']) {
|
|||
|
throw new ValidateException('请登录短信账户');
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 发送注册验证码
|
|||
|
* @param $phone
|
|||
|
* @return mixed
|
|||
|
*/
|
|||
|
public function captcha($phone)
|
|||
|
{
|
|||
|
return json_decode(HttpService::getRequest(self::API . 'sms/captcha', compact('phone')), true);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 短信注册
|
|||
|
* @param $account
|
|||
|
* @param $password
|
|||
|
* @param $url
|
|||
|
* @param $phone
|
|||
|
* @param $code
|
|||
|
* @param $sign
|
|||
|
* @return mixed
|
|||
|
*/
|
|||
|
public function register($account, $password, $url, $phone, $code, $sign)
|
|||
|
{
|
|||
|
return $this->registerData(compact('account', 'password', 'url', 'phone', 'code', 'sign'));
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @param array $data
|
|||
|
* @return mixed
|
|||
|
* @author xaboy
|
|||
|
* @day 2020-05-18
|
|||
|
*/
|
|||
|
public function registerData(array $data)
|
|||
|
{
|
|||
|
return json_decode(HttpService::postRequest(self::API . 'sms/register', $data), true);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 公共短信模板列表
|
|||
|
* @param array $data
|
|||
|
* @return mixed
|
|||
|
*/
|
|||
|
public function publictemp(array $data = [])
|
|||
|
{
|
|||
|
$this->checkConfig();
|
|||
|
$data['account'] = $this->config['sms_account'];
|
|||
|
$data['token'] = $this->config['sms_token'];
|
|||
|
$data['source'] = 'crmeb_merchant';
|
|||
|
return json_decode(HttpService::postRequest(self::API . 'sms/publictemp', $data), true);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 公共短信模板添加
|
|||
|
* @param $id
|
|||
|
* @param $tempId
|
|||
|
* @return mixed
|
|||
|
*/
|
|||
|
public function use($id, $tempId)
|
|||
|
{
|
|||
|
$this->checkConfig();
|
|||
|
$data = [
|
|||
|
'account' => $this->config['sms_account'],
|
|||
|
'token' => $this->config['sms_token'],
|
|||
|
'id' => $id,
|
|||
|
'tempId' => $tempId,
|
|||
|
];
|
|||
|
|
|||
|
return json_decode(HttpService::postRequest(self::API . 'sms/use', $data), true);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @param string $templateId
|
|||
|
* @return mixed
|
|||
|
* @author xaboy
|
|||
|
* @day 2020-05-18
|
|||
|
*/
|
|||
|
public function getTemplateCode(string $templateId)
|
|||
|
{
|
|||
|
return Config::get('sms.template_id.' . $templateId);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 原 send 方法 (弃用)
|
|||
|
* 发送短信
|
|||
|
* @param string $phone
|
|||
|
* @param string $templateId
|
|||
|
* @param array $data
|
|||
|
* @return bool|string
|
|||
|
* @throws SmsException
|
|||
|
*/
|
|||
|
public function sendDe(string $phone, string $templateId, array $data = [])
|
|||
|
{
|
|||
|
if (!$phone) {
|
|||
|
throw new SmsException('Mobile number cannot be empty');
|
|||
|
}
|
|||
|
|
|||
|
$this->checkConfig();
|
|||
|
|
|||
|
$formData['uid'] = $this->config['sms_account'];
|
|||
|
$formData['token'] = $this->config['sms_token'];
|
|||
|
$formData['mobile'] = $phone;
|
|||
|
$formData['template'] = $this->getTemplateCode($templateId);
|
|||
|
if (is_null($formData['template']))
|
|||
|
throw new SmsException('Missing template number');
|
|||
|
|
|||
|
$formData['param'] = json_encode($data);
|
|||
|
$resource = json_decode(HttpService::postRequest(self::API . 'sms/send', $formData), true);
|
|||
|
if ($resource['status'] === 400) {
|
|||
|
throw new SmsException($resource['msg']);
|
|||
|
} else {
|
|||
|
app()->make(SmsRecordDao::class)->create([
|
|||
|
'uid' => $formData['uid'],
|
|||
|
'phone' => $phone,
|
|||
|
'content' => $resource['data']['content'],
|
|||
|
'template' => $resource['data']['template'],
|
|||
|
'record_id' => $resource['data']['id']
|
|||
|
]);
|
|||
|
}
|
|||
|
return $resource;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 账号信息
|
|||
|
* @return mixed
|
|||
|
*/
|
|||
|
public function count()
|
|||
|
{
|
|||
|
$this->checkConfig();
|
|||
|
return json_decode(HttpService::postRequest(self::API . 'sms/userinfo', [
|
|||
|
'account' => $this->config['sms_account'],
|
|||
|
'token' => $this->config['sms_token']
|
|||
|
]), true);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 支付套餐
|
|||
|
* @param $page
|
|||
|
* @param $limit
|
|||
|
* @return mixed
|
|||
|
*/
|
|||
|
public function meal($page, $limit)
|
|||
|
{
|
|||
|
return json_decode(HttpService::getRequest(self::API . 'sms/meal', [
|
|||
|
'page' => $page,
|
|||
|
'limit' => $limit
|
|||
|
]), true);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 支付码
|
|||
|
* @param $payType
|
|||
|
* @param $mealId
|
|||
|
* @param $price
|
|||
|
* @param $attach
|
|||
|
* @param $notify
|
|||
|
* @return mixed
|
|||
|
*/
|
|||
|
public function pay($payType, $mealId, $price, $attach, $notify = null)
|
|||
|
{
|
|||
|
$this->checkConfig();
|
|||
|
$data['uid'] = $this->config['sms_account'];
|
|||
|
$data['token'] = $this->config['sms_token'];
|
|||
|
$data['payType'] = $payType;
|
|||
|
$data['mealId'] = $mealId;
|
|||
|
$data['notify'] = $notify ?? Route::buildUrl('SmsNotify')->build();
|
|||
|
$data['price'] = $price;
|
|||
|
$data['attach'] = $attach;
|
|||
|
return json_decode(HttpService::postRequest(self::API . 'sms/mealpay', $data), true);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 申请模板消息
|
|||
|
* @param $title
|
|||
|
* @param $content
|
|||
|
* @param $type
|
|||
|
* @return mixed
|
|||
|
*/
|
|||
|
public function apply($title, $content, $type)
|
|||
|
{
|
|||
|
$this->checkConfig();
|
|||
|
$data['account'] = $this->config['sms_account'];
|
|||
|
$data['token'] = $this->config['sms_token'];
|
|||
|
$data['title'] = $title;
|
|||
|
$data['content'] = $content;
|
|||
|
$data['type'] = $type;
|
|||
|
return json_decode(HttpService::postRequest(self::API . 'sms/apply', $data), true);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 短信模板列表
|
|||
|
* @param $data
|
|||
|
* @return mixed
|
|||
|
*/
|
|||
|
public function template(array $data)
|
|||
|
{
|
|||
|
$this->checkConfig();
|
|||
|
return json_decode(HttpService::postRequest(self::API . 'sms/template', $data + [
|
|||
|
'account' => $this->config['sms_account'], 'token' => $this->config['sms_token']
|
|||
|
]), true);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 获取短息记录状态
|
|||
|
* @param $record_id
|
|||
|
* @return mixed
|
|||
|
*/
|
|||
|
public function getStatus(array $record_id)
|
|||
|
{
|
|||
|
return json_decode(HttpService::postRequest(self::API . 'sms/status', [
|
|||
|
'record_id' => json_encode($record_id)
|
|||
|
]), true);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @return YunxinSmsService
|
|||
|
* @author xaboy
|
|||
|
* @day 2020-05-18
|
|||
|
*/
|
|||
|
public static function create()
|
|||
|
{
|
|||
|
/** @var ConfigValueRepository $make */
|
|||
|
$make = app()->make(ConfigValueRepository::class);
|
|||
|
$config = $make->more(['sms_account', 'sms_token'], 0);
|
|||
|
|
|||
|
return new static($config);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @param string $sms_account
|
|||
|
* @param string $sms_token
|
|||
|
* @return $this
|
|||
|
* @author xaboy
|
|||
|
* @day 2020-05-18
|
|||
|
*/
|
|||
|
public function setConfig(string $sms_account, string $sms_token)
|
|||
|
{
|
|||
|
$this->config = compact('sms_token', 'sms_account');
|
|||
|
$this->config['sms_token'] = $this->getToken();
|
|||
|
return $this;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @return Form
|
|||
|
* @throws FormBuilderException
|
|||
|
* @author xaboy
|
|||
|
* @day 2020-05-18
|
|||
|
*/
|
|||
|
public function form()
|
|||
|
{
|
|||
|
return Elm::createForm(Route::buildUrl('smsCreate')->build(), [
|
|||
|
Elm::input('title', '模板名称:')->placeholder('请输入模版名称'),
|
|||
|
Elm::input('content', '模板内容:')->type('textarea')->placeholder('请输入模版内容'),
|
|||
|
Elm::radio('type', '模板类型:', 1)->options([['label' => '验证码', 'value' => 1], ['label' => '通知', 'value' => 2], ['label' => '推广', 'value' => 3]])
|
|||
|
])->setTitle('申请短信模板');
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @return mixed
|
|||
|
* @author xaboy
|
|||
|
* @day 2020-05-18
|
|||
|
*/
|
|||
|
public function account()
|
|||
|
{
|
|||
|
$this->checkConfig();
|
|||
|
return $this->config['sms_account'];
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @Author:Qinii
|
|||
|
* @Date: 2020/9/19
|
|||
|
* @param $data
|
|||
|
* @return mixed
|
|||
|
*/
|
|||
|
public function smsChange($data)
|
|||
|
{
|
|||
|
$this->checkConfig();
|
|||
|
$data['account'] = $this->config['sms_account'];
|
|||
|
$data['token'] = $this->config['sms_token'];
|
|||
|
return json_decode(HttpService::postRequest(self::API . 'sms/modify', $data), true);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @Author:Qinii
|
|||
|
* @Date: 2020/9/19
|
|||
|
* @param $phone
|
|||
|
* @param $code
|
|||
|
* @param $type
|
|||
|
* @return bool
|
|||
|
*/
|
|||
|
public function checkSmsCode($phone, $code, $type)
|
|||
|
{
|
|||
|
if (!env('DEVELOPMENT',false)) {
|
|||
|
$sms_key = $this->sendSmsKey($phone, $type);
|
|||
|
if (!$cache_code = Cache::get($sms_key)) return false;
|
|||
|
if ($code != $cache_code) return false;
|
|||
|
Cache::delete($sms_key);
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @Author:Qinii
|
|||
|
* @Date: 2020/9/19
|
|||
|
* @param $phone
|
|||
|
* @param string $type
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function sendSmsKey($phone, $type = 'login')
|
|||
|
{
|
|||
|
switch ($type) {
|
|||
|
case 'login': //登录
|
|||
|
return 'api_login_' . $phone;
|
|||
|
break;
|
|||
|
case 'binding': //绑定手机号
|
|||
|
return 'api_binding_' . $phone;
|
|||
|
break;
|
|||
|
case 'intention': //申请入住
|
|||
|
return 'merchant_intention_' . $phone;
|
|||
|
break;
|
|||
|
case 'change_pwd': //修改密码
|
|||
|
return 'change_pwd_' . $phone;
|
|||
|
break;
|
|||
|
case 'change_phone': //修改手机号
|
|||
|
return 'change_phone_' . $phone;
|
|||
|
break;
|
|||
|
default:
|
|||
|
return 'crmeb_' . $phone;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public function send(string $phone, string $templateId, array $data = [])
|
|||
|
{
|
|||
|
try {
|
|||
|
$make = app()->make(CrmebServeServices::class)->sms();
|
|||
|
$resource = $make->send($phone, $this->getTemplateCode($templateId), $data);
|
|||
|
if ($resource) {
|
|||
|
app()->make(SmsRecordDao::class)->create([
|
|||
|
'uid' => $this->config['sms_account'],
|
|||
|
'phone' => $phone,
|
|||
|
'content' => $resource['content'],
|
|||
|
'template' => $resource['template'],
|
|||
|
'record_id' => $resource['id'],
|
|||
|
]);
|
|||
|
}
|
|||
|
} catch (\Exception $exception) {
|
|||
|
throw new SmsException($exception->getMessage());
|
|||
|
}
|
|||
|
}
|
|||
|
}
|