From 7aeb7950ed50c9e24c804b89d4307ae99362294e Mon Sep 17 00:00:00 2001
From: Anyon <zoujingli@qq.com>
Date: Fri, 4 May 2018 17:01:43 +0800
Subject: [PATCH] =?UTF-8?q?[=E6=9B=B4=E6=96=B0]=E5=A2=9E=E5=8A=A0=E9=98=BF?=
 =?UTF-8?q?=E9=87=8C=E4=BA=91=E7=9F=AD=E4=BF=A1=E6=94=AF=E6=8C=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 extend/service/AlismsService.php    | 169 ++++++++++++++++++++++++++++
 vendor/autoload.php                 |   2 +-
 vendor/composer/autoload_real.php   |  14 +--
 vendor/composer/autoload_static.php |   8 +-
 4 files changed, 181 insertions(+), 12 deletions(-)
 create mode 100644 extend/service/AlismsService.php

diff --git a/extend/service/AlismsService.php b/extend/service/AlismsService.php
new file mode 100644
index 000000000..d5077c868
--- /dev/null
+++ b/extend/service/AlismsService.php
@@ -0,0 +1,169 @@
+<?php
+
+namespace service;
+
+/**
+ * 阿里云短信服务
+ * Class AlismsService
+ * @package service
+ * @config 需要在config目录定义配置文件
+ * @configParam aliyun.SmsAppid 阿里云短信APPID
+ * @configParam aliyun.SmsAppkey 阿里云短信APPKEY
+ */
+class AlismsService
+{
+
+    /**
+     * 短信发送记录查询
+     * @param string $PhoneNumber 短信接收号码
+     * @param string $SendDate 短信发送日期,格式Ymd,支持近30天记录查询
+     * @param integer $PageSize 分页大小
+     * @param integer $CurrentPage 当前页码
+     * @param null|string $BizId 设置发送短信流水号(可选)
+     * @return bool|array
+     */
+    public static function query($PhoneNumber, $SendDate, $PageSize = 10, $CurrentPage = 1, $BizId = null)
+    {
+        $params = [];
+        $params["SendDate"] = $SendDate;
+        $params["PageSize"] = $PageSize;
+        $params["CurrentPage"] = $CurrentPage;
+        $params["PhoneNumber"] = $PhoneNumber;
+        is_null($BizId) || $params["BizId"] = $BizId;
+        return self::request("dysmsapi.aliyuncs.com", array_merge($params, [
+            "RegionId" => "cn-hangzhou",
+            "Action"   => "QuerySendDetails",
+            "Version"  => "2017-05-25",
+        ]), true);
+    }
+
+    /**
+     * 批量发送短信
+     * @param array $PhoneNumbers 待发送手机号
+     * @param string $TemplateCode 短信模板Code
+     * @param array $SignNames 短信签名
+     * @param array $TemplateParams 模板中的变量
+     * @param array $SmsUpExtendCodes 上行短信扩展码
+     * @return bool|array
+     */
+    public static function batchSend(array $PhoneNumbers, $TemplateCode, array $SignNames, array $TemplateParams, $SmsUpExtendCodes = [])
+    {
+        $params = [];
+        $params["SignNameJson"] = $SignNames;
+        $params["TemplateCode"] = $TemplateCode;
+        $params["PhoneNumberJson"] = $PhoneNumbers;
+        $params["TemplateParamJson"] = $TemplateParams;
+        if (!empty($SmsUpExtendCodes)) {
+            $params["SmsUpExtendCodeJson"] = json_encode($SmsUpExtendCodes);
+        }
+        $params["TemplateParamJson"] = json_encode($params["TemplateParamJson"], JSON_UNESCAPED_UNICODE);
+        $params["SignNameJson"] = json_encode($params["SignNameJson"], JSON_UNESCAPED_UNICODE);
+        $params["PhoneNumberJson"] = json_encode($params["PhoneNumberJson"], JSON_UNESCAPED_UNICODE);
+        if (!empty($params["SmsUpExtendCodeJson"]) && is_array($params["SmsUpExtendCodeJson"])) {
+            $params["SmsUpExtendCodeJson"] = json_encode($params["SmsUpExtendCodeJson"], JSON_UNESCAPED_UNICODE);
+        }
+        return self::request("dysmsapi.aliyuncs.com", array_merge($params, [
+            "RegionId" => "cn-hangzhou",
+            "Action"   => "SendBatchSms",
+            "Version"  => "2017-05-25",
+        ]), true);
+    }
+
+    /**
+     * 发送短信
+     * @param string $PhoneNumbers 短信接收号码
+     * @param string $TemplateCode 短信模板Code
+     * @param string $SignName 短信签名
+     * @param array $TemplateParam 设置模板参数
+     * @param null|string $OutId 设置发送短信流水号(可选)
+     * @param null|string $SmsUpExtendCode 上行短信扩展码(可选)
+     * @return bool|array
+     */
+    public static function send($PhoneNumbers, $TemplateCode, $SignName, array $TemplateParam, $OutId = null, $SmsUpExtendCode = null)
+    {
+        $params = [];
+        $params["SignName"] = $SignName;
+        $params["TemplateCode"] = $TemplateCode;
+        $params["PhoneNumbers"] = $PhoneNumbers;
+        $params['TemplateParam'] = $TemplateParam;
+        is_null($OutId) || $params['OutId'] = $OutId;
+        is_null($SmsUpExtendCode) || $params['SmsUpExtendCode'] = $SmsUpExtendCode;
+        if (!empty($params["TemplateParam"]) && is_array($params["TemplateParam"])) {
+            $params["TemplateParam"] = json_encode($params["TemplateParam"], JSON_UNESCAPED_UNICODE);
+        }
+        return self::request("dysmsapi.aliyuncs.com", array_merge($params, [
+            "RegionId" => "cn-hangzhou",
+            "Action"   => "SendSms",
+            "Version"  => "2017-05-25",
+        ]), true);
+    }
+
+    /**
+     * 生成签名并发起请求
+     * @param $domain string API接口所在域名
+     * @param $params array API具体参数
+     * @param $security boolean 使用https
+     * @return bool|array 返回API接口调用结果,当发生错误时返回false
+     */
+    public static function request($domain, $params, $security = false)
+    {
+        $apiParams = array_merge([
+            "SignatureMethod"  => "HMAC-SHA1",
+            "SignatureNonce"   => uniqid(mt_rand(0, 0xffff), true),
+            "SignatureVersion" => "1.0",
+            "AccessKeyId"      => config('aliyun.SmsAppid'),
+            "Timestamp"        => gmdate("Y-m-d\TH:i:s\Z"),
+            "Format"           => "JSON",
+        ], $params);
+        ksort($apiParams);
+        $sortedQueryStringTmp = "";
+        foreach ($apiParams as $key => $value) {
+            $sortedQueryStringTmp .= "&" . self::encode($key) . "=" . self::encode($value);
+        }
+        $stringToSign = "GET&%2F&" . self::encode(substr($sortedQueryStringTmp, 1));
+        $sign = base64_encode(hash_hmac("sha1", $stringToSign, config('aliyun.SmsAppkey') . "&", true));
+        $signature = self::encode($sign);
+        $url = ($security ? 'https' : 'http') . "://{$domain}/?Signature={$signature}{$sortedQueryStringTmp}";
+        try {
+            return json_decode(self::fetchContent($url), true);
+        } catch (\Exception $e) {
+            return false;
+        }
+    }
+
+    /**
+     * 数据编码处理
+     * @param string $str
+     * @return null|string
+     */
+    private static function encode($str)
+    {
+        $res = urlencode($str);
+        $res = preg_replace("/\+/", "%20", $res);
+        $res = preg_replace("/\*/", "%2A", $res);
+        $res = preg_replace("/%7E/", "~", $res);
+        return $res;
+    }
+
+    /**
+     * 网络请求
+     * @param string $url 请求URL
+     * @return mixed
+     */
+    private static function fetchContent($url)
+    {
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+        curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-sdk-client" => "php/2.0.0"]);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+        $rtn = curl_exec($ch);
+        if ($rtn === false) {
+            trigger_error("[CURL_" . curl_errno($ch) . "]: " . curl_error($ch), E_USER_ERROR);
+        }
+        curl_close($ch);
+        return $rtn;
+    }
+}
\ No newline at end of file
diff --git a/vendor/autoload.php b/vendor/autoload.php
index 990cfa033..a3a19ef2b 100644
--- a/vendor/autoload.php
+++ b/vendor/autoload.php
@@ -4,4 +4,4 @@
 
 require_once __DIR__ . '/composer/autoload_real.php';
 
-return ComposerAutoloaderInit33a8bc3c373005edc4cb872b55fab022::getLoader();
+return ComposerAutoloaderInit38d0f6865bffe6f3ec7977ff5e7499f1::getLoader();
diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php
index cd4eb03c9..260e115ee 100644
--- a/vendor/composer/autoload_real.php
+++ b/vendor/composer/autoload_real.php
@@ -2,7 +2,7 @@
 
 // autoload_real.php @generated by Composer
 
-class ComposerAutoloaderInit33a8bc3c373005edc4cb872b55fab022
+class ComposerAutoloaderInit38d0f6865bffe6f3ec7977ff5e7499f1
 {
     private static $loader;
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit33a8bc3c373005edc4cb872b55fab022
             return self::$loader;
         }
 
-        spl_autoload_register(array('ComposerAutoloaderInit33a8bc3c373005edc4cb872b55fab022', 'loadClassLoader'), true, true);
+        spl_autoload_register(array('ComposerAutoloaderInit38d0f6865bffe6f3ec7977ff5e7499f1', 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
-        spl_autoload_unregister(array('ComposerAutoloaderInit33a8bc3c373005edc4cb872b55fab022', 'loadClassLoader'));
+        spl_autoload_unregister(array('ComposerAutoloaderInit38d0f6865bffe6f3ec7977ff5e7499f1', 'loadClassLoader'));
 
         $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
         if ($useStaticLoader) {
             require_once __DIR__ . '/autoload_static.php';
 
-            call_user_func(\Composer\Autoload\ComposerStaticInit33a8bc3c373005edc4cb872b55fab022::getInitializer($loader));
+            call_user_func(\Composer\Autoload\ComposerStaticInit38d0f6865bffe6f3ec7977ff5e7499f1::getInitializer($loader));
         } else {
             $map = require __DIR__ . '/autoload_namespaces.php';
             foreach ($map as $namespace => $path) {
@@ -48,19 +48,19 @@ class ComposerAutoloaderInit33a8bc3c373005edc4cb872b55fab022
         $loader->register(true);
 
         if ($useStaticLoader) {
-            $includeFiles = Composer\Autoload\ComposerStaticInit33a8bc3c373005edc4cb872b55fab022::$files;
+            $includeFiles = Composer\Autoload\ComposerStaticInit38d0f6865bffe6f3ec7977ff5e7499f1::$files;
         } else {
             $includeFiles = require __DIR__ . '/autoload_files.php';
         }
         foreach ($includeFiles as $fileIdentifier => $file) {
-            composerRequire33a8bc3c373005edc4cb872b55fab022($fileIdentifier, $file);
+            composerRequire38d0f6865bffe6f3ec7977ff5e7499f1($fileIdentifier, $file);
         }
 
         return $loader;
     }
 }
 
-function composerRequire33a8bc3c373005edc4cb872b55fab022($fileIdentifier, $file)
+function composerRequire38d0f6865bffe6f3ec7977ff5e7499f1($fileIdentifier, $file)
 {
     if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
         require $file;
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
index 321ba51b4..c216fda63 100644
--- a/vendor/composer/autoload_static.php
+++ b/vendor/composer/autoload_static.php
@@ -4,7 +4,7 @@
 
 namespace Composer\Autoload;
 
-class ComposerStaticInit33a8bc3c373005edc4cb872b55fab022
+class ComposerStaticInit38d0f6865bffe6f3ec7977ff5e7499f1
 {
     public static $files = array (
         '1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php',
@@ -273,9 +273,9 @@ class ComposerStaticInit33a8bc3c373005edc4cb872b55fab022
     public static function getInitializer(ClassLoader $loader)
     {
         return \Closure::bind(function () use ($loader) {
-            $loader->prefixLengthsPsr4 = ComposerStaticInit33a8bc3c373005edc4cb872b55fab022::$prefixLengthsPsr4;
-            $loader->prefixDirsPsr4 = ComposerStaticInit33a8bc3c373005edc4cb872b55fab022::$prefixDirsPsr4;
-            $loader->classMap = ComposerStaticInit33a8bc3c373005edc4cb872b55fab022::$classMap;
+            $loader->prefixLengthsPsr4 = ComposerStaticInit38d0f6865bffe6f3ec7977ff5e7499f1::$prefixLengthsPsr4;
+            $loader->prefixDirsPsr4 = ComposerStaticInit38d0f6865bffe6f3ec7977ff5e7499f1::$prefixDirsPsr4;
+            $loader->classMap = ComposerStaticInit38d0f6865bffe6f3ec7977ff5e7499f1::$classMap;
 
         }, null, ClassLoader::class);
     }