dever 7 years ago
parent
commit
2f15b8f259
8 changed files with 556 additions and 132 deletions
  1. 27 1
      README.md
  2. 16 3
      database/code.php
  3. 256 0
      database/config.php
  4. 13 11
      database/info.php
  5. 94 0
      database/skin.php
  6. 45 0
      lib/Aliyun.php
  7. 88 54
      lib/Base.php
  8. 17 63
      src/Api.php

+ 27 - 1
README.md

@@ -1,2 +1,28 @@
-# sms
+# 短信组件
+
+
+## 发送短信
+```
+# 短信模板标识
+$skin = 'k1';
+# 手机号
+$mobile = Dever::input('mobile');
+# 一些参数
+$param = array
+(
+	'content' => '自定义的内容',
+);
+return Dever::load('sms/api')->send($skin, $mobile, $param);
+
+```
+
+## 发送验证码
+```
+# 短信模板标识
+$skin = 'k1';
+# 手机号
+$mobile = Dever::input('mobile');
+return Dever::load('sms/api')->sendCode($skin, $mobile);
+
+```
 

+ 16 - 3
database/code.php

@@ -51,13 +51,26 @@ return array
 		'day'		=> array
 		(
 			'type' 		=> 'int-11',
-			'name' 		=> '申请时间',
+			'name' 		=> '申请',
 			'default' 	=> '',
-			'desc' 		=> '申请时间',
+			'desc' 		=> '申请',
 			'match' 	=> 'is_numeric',
 			'update'	=> 'text',
+			//'search'	=> 'fulltext',
+			//'list'		=> true,
+		),
+
+		'result'		=> array
+		(
+			'type' 		=> 'text-255',
+			'name' 		=> '返回记录',
+			'default' 	=> '',
+			'desc' 		=> '返回记录',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
 			'search'	=> 'fulltext',
-			'list'		=> true,
+			'list'		=> 'table',
+			'modal'		=> '查看详情',
 		),
 
 		'state'		=> array

+ 256 - 0
database/config.php

@@ -0,0 +1,256 @@
+<?php
+
+$sdk = array
+(
+	'url' => '不使用',
+	'aliyun' => '阿里云',
+);
+
+$method = array
+(
+	'get' => 'GET',
+	'post' => 'POST',
+);
+
+$json = array
+(
+	1 => '是',
+	2 => '否',
+);
+
+$code_type = array
+(
+	1 => '全数字',
+	2 => '小写字母',
+	3 => '大写字母',
+	4 => '大小写字母',
+	5 => '数字+大小写字母',
+);
+
+return array
+(
+	# 表名
+	'name' => 'config',
+	# 显示给用户看的名称
+	'lang' => '基本配置',
+	'order' => 20,
+	'check' => 'key',
+	# 数据结构
+	'struct' => array
+	(
+	
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			'search'	=> 'order',
+			//'list'		=> true,
+		),
+
+		'name'		=> array
+		(
+			'type' 		=> 'varchar-32',
+			'name' 		=> '配置名称',
+			'default' 	=> '',
+			'desc' 		=> '配置名称',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'key'		=> array
+		(
+			'type' 		=> 'varchar-32',
+			'name' 		=> '短信标识-发送短信时,使用该标识来读取短信基本配置',
+			'default' 	=> '',
+			'desc' 		=> '短信标识',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'sign'		=> array
+		(
+			'type' 		=> 'varchar-60',
+			'name' 		=> '短信签名',
+			'default' 	=> '',
+			'desc' 		=> '短信签名',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+		),
+
+		'sdk'		=> array
+		(
+			'type' 		=> 'varchar-32',
+			'name' 		=> '是否调取sdk',
+			'default' 	=> 'url',
+			'desc' 		=> '是否调取sdk',
+			'match' 	=> 'is_string',
+			'update'	=> 'radio',
+			'option'	=> $sdk,
+			'control'	=> 'sdk',
+		),
+
+		'appid'		=> array
+		(
+			'type' 		=> 'varchar-50',
+			'name' 		=> 'appid',
+			'default' 	=> '',
+			'desc' 		=> 'appid',
+			'match' 	=> 'option',
+			'update'	=> 'text',
+			'show'		=> 'sdk=aliyun',
+		),
+
+		'appsecret'		=> array
+		(
+			'type' 		=> 'varchar-80',
+			'name' 		=> 'appsecret',
+			'default' 	=> '',
+			'desc' 		=> 'appsecret',
+			'match' 	=> 'option',
+			'update'	=> 'text',
+			'show'		=> 'sdk=aliyun',
+		),
+
+		'url'		=> array
+		(
+			'type' 		=> 'varchar-300',
+			'name' 		=> '接口地址',
+			'default' 	=> '',
+			'desc' 		=> '接口地址',
+			'match' 	=> 'option',
+			'update'	=> 'text',
+			'show'		=> 'sdk=url',
+		),
+
+		'method'		=> array
+		(
+			'type' 		=> 'varchar-32',
+			'name' 		=> '请求方式',
+			'default' 	=> 'get',
+			'desc' 		=> '请求方式',
+			'match' 	=> 'is_string',
+			'update'	=> 'select',
+			'option'	=> $method,
+		),
+
+		'json'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '是否进行json编码',
+			'default' 	=> '2',
+			'desc' 		=> '是否进行json编码',
+			'match' 	=> 'is_numeric',
+			'update'	=> 'radio',
+			'option'	=> $json,
+		),
+
+		'header'		=> array
+		(
+			'type' 		=> 'varchar-500',
+			'name' 		=> 'header信息-如Authorization:APPCODE e7183e44ba8e4ccaa3d690510923d3fa',
+			'default' 	=> '',
+			'desc' 		=> 'header信息',
+			'match' 	=> 'option',
+			'update'	=> 'textarea',
+		),
+
+		'body'		=> array
+		(
+			'type' 		=> 'varchar-500',
+			'name' 		=> 'body信息-如param={code}&phone={mobile}&sign={sign}&skin={skin}',
+			'default' 	=> '',
+			'desc' 		=> 'body信息',
+			'match' 	=> 'option',
+			'update'	=> 'textarea',
+		),
+
+		'code_timeout'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '验证码有效期-以秒为单位',
+			'default' 	=> '600',
+			'desc' 		=> '验证码有效期',
+			'match' 	=> 'option',
+			'update'	=> 'text',
+		),
+
+		'code_length'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '验证码长度',
+			'default' 	=> '4',
+			'desc' 		=> '验证码长度',
+			'match' 	=> 'option',
+			'update'	=> 'text',
+		),
+
+		'code_type'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '验证码类型',
+			'default' 	=> '4',
+			'desc' 		=> '验证码类型',
+			'match' 	=> 'option',
+			'update'	=> 'select',
+			'option'	=> $code_type,
+		),
+
+		'code_total'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '一天之内的最大发送次数',
+			'default' 	=> '10',
+			'desc' 		=> '一天之内的最大发送次数',
+			'match' 	=> 'option',
+			'update'	=> 'text',
+		),
+
+		'code_time'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '不允许多久之内重复发送-以秒为单位',
+			'default' 	=> '60',
+			'desc' 		=> '不允许多久之内重复发送',
+			'match' 	=> 'option',
+			'update'	=> 'text',
+		),
+
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '录入时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'insert'	=> true,
+			'search'	=> 'date',
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+
+	# 管理功能
+	'manage' => array
+	(
+		# 列表
+		'list_button' => array
+		(
+			'list' => array('模板', '"skin&project=sms&search_option_config_id={id}&oper_parent=config&oper_project=sms"'),
+		),
+	),
+);

+ 13 - 11
database/info.php

@@ -36,28 +36,30 @@ return array
 			'list'		=> true,
 		),
 
-		'msg'		=> array
+		'param'		=> array
 		(
-			'type' 		=> 'varchar-500',
-			'name' 		=> '短信内容',
+			'type' 		=> 'text-255',
+			'name' 		=> '请求记录',
 			'default' 	=> '',
-			'desc' 		=> '短信内容',
+			'desc' 		=> '请求记录',
 			'match' 	=> 'is_string',
 			'update'	=> 'text',
 			'search'	=> 'fulltext',
-			'list'		=> true,
+			//'list'		=> 'table',
+			//'modal'		=> '查看详情',
 		),
 
-		'day'		=> array
+		'result'		=> array
 		(
-			'type' 		=> 'int-11',
-			'name' 		=> '申请时间',
+			'type' 		=> 'text-255',
+			'name' 		=> '发送记录',
 			'default' 	=> '',
-			'desc' 		=> '申请时间',
-			'match' 	=> 'is_numeric',
+			'desc' 		=> '发送记录',
+			'match' 	=> 'is_string',
 			'update'	=> 'text',
 			'search'	=> 'fulltext',
-			'list'		=> true,
+			'list'		=> 'table',
+			'modal'		=> '查看详情',
 		),
 
 		'state'		=> array

+ 94 - 0
database/skin.php

@@ -0,0 +1,94 @@
+<?php
+
+return array
+(
+	# 表名
+	'name' => 'skin',
+	# 显示给用户看的名称
+	'lang' => '模板设置',
+	'menu' => false,
+	'check' => 'config_id,key',
+	# 数据结构
+	'struct' => array
+	(
+	
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			'search'	=> 'order',
+			//'list'		=> true,
+		),
+
+		'config_id'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '所属配置',
+			'default' 	=> '1',
+			'desc' 		=> '请选择所属配置',
+			'match' 	=> 'is_numeric',
+			'update'	=> 'hidden',
+			'value'		=> Dever::input('search_option_config_id')
+		),
+
+		'name'		=> array
+		(
+			'type' 		=> 'varchar-32',
+			'name' 		=> '模板名称',
+			'default' 	=> '',
+			'desc' 		=> '模板名称',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'key'		=> array
+		(
+			'type' 		=> 'varchar-32',
+			'name' 		=> '模板标识',
+			'default' 	=> '',
+			'desc' 		=> '模板标识',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'content'		=> array
+		(
+			'type' 		=> 'varchar-800',
+			'name' 		=> '模板内容-如果短信接口已提供模板,请在此输入模板id',
+			'default' 	=> '',
+			'desc' 		=> '模板内容',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '录入时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'insert'	=> true,
+			'search'	=> 'date',
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+);

+ 45 - 0
lib/Aliyun.php

@@ -0,0 +1,45 @@
+<?php
+namespace Sms\Lib;
+
+use Dever;
+Dever::apply('sdk/aliyun/SignatureHelper');
+use Aliyun\DySDKLite\SignatureHelper;
+
+class Aliyun
+{
+	public function send($param, $config)
+	{
+		$send = array ();
+
+		$send['PhoneNumbers'] = $param['mobile'];
+		$send['SignName'] = $param['sign'];
+		$send['TemplateCode'] = $param['skin'];
+		$send['TemplateParam'] = $param;
+
+		if (isset($param['id'])) {
+			$send['OutId'] = $param['id'];
+		}
+
+		// *** 需用户填写部分结束, 以下代码若无必要无需更改 ***
+		if(!empty($send['TemplateParam']) && is_array($send['TemplateParam'])) {
+			$send['TemplateParam'] = json_encode($send['TemplateParam'], JSON_UNESCAPED_UNICODE);
+		}
+
+		// 初始化SignatureHelper实例用于设置参数,签名以及发送请求
+		$helper = new SignatureHelper();
+
+		// 此处可能会抛出异常,注意catch
+		$content = $helper->request(
+			$config['appid'],
+			$config['appsecret'],
+			'dysmsapi.aliyuncs.com',
+			array_merge($send, array(
+				'RegionId' => 'cn-hangzhou',
+				'Action' => 'SendSms',
+				'Version' => date('Y-m-d'),
+			))
+		);
+
+		return $content;
+	}
+}

+ 88 - 54
lib/Base.php

@@ -5,100 +5,134 @@ use Dever;
 
 class Base
 {
-    const NAME = 'dever_passport';
+    protected $config;
 
-    const CODE = 'dever_code';
+    private function config($skin)
+    {
+        if (!$this->config) {
+            $this->config['skin'] = Dever::db('sms/skin')->one(array('key' => $skin));
+            if ($this->config['skin']) {
+                $this->config += Dever::db('sms/config')->one($this->config['skin']['id']);
+            } else {
+                Dever::alert('错误的短信模板');
+            }
+            if (!$this->config) {
+                Dever::alert('错误的短信配置');
+            }
+        }
+        
+        return $this;
+    }
 
-    const MCODE = 'dever_mcode';
+    private function mobile($mobile)
+    {
+        # 验证手机号是否有效
 
-    protected $config;
+    }
 
-    public function __construct()
+    public function send($skin, $mobile, $param = array())
     {
-        $this->config = Dever::config('base', 'project')->sms;
+        $this->config($skin)->mobile($mobile);
+
+        $content = $this->config['body'];
+        $skin = $this->config['skin']['content'];
+
+        $param['skin'] = $skin;
+        $param['mobile'] = $mobile;
+        $param['sign'] = $this->config['sign'];
+
+        if ($content) {
+            $content = $this->replace($content, $param);
+            parse_str($content, $param);
+        }
+
+        if ($this->config['sdk'] != 'url') {
+            $result = Dever::load('sms/lib/' . $this->config['sdk'] . '.send', $param, $this->config);
+        } else {
+            if (!$this->config['url']) {
+                $result = 'url error';
+            } else {
+                $result = Dever::curl($this->config['url'], $param, $this->config['method'], $this->config['json'], $this->config['header']);
+            }
+        }
+
+        # 记录当前的短信信息
+        $insert = array();
+        $insert['mobile'] = $mobile;
+        $insert['param'] = Dever::json_encode($this->config + $param);
+        $insert['result'] = Dever::json_encode($result);
+        Dever::db('sms/info')->insert($insert);
+
+        return $result;
     }
 
-    protected function code($mobile, $code = false)
+    public function sendCode($skin, $mobile, $code = false)
     {
+        $this->config($skin)->mobile($mobile);
+
         if ($code) {
-            $save = $this->save->get($this->config['code']);
+            $save = Dever::session($this->config['key']);
             return $mobile . '_' . $code == $save;
         }
 
         $day = date('Ymd', time());
 
         # 检测当前手机号最新一次发送时间,不允许一分钟之内发送
-        $param['option_day'] = $day;
-        $param['option_mobile'] = $mobile;
+        $param['day'] = $day;
+        $param['mobile'] = $mobile;
 
         # 检测当前手机号今天已经发送多少验证码了
-        $info = Dever::load('sms/code-total', $param);
+        $info = Dever::db('sms/code')->total($param);
 
         if ($info >= 1) {
-            $check = Dever::load('sms/code-one', $param);
+            $check = Dever::db('sms/code')->one($param);
 
             if ($check) {
-                if (time() - $check['cdate'] < $this->config['time']) {
+                if (time() - $check['cdate'] < $this->config['code_time']) {
                     Dever::alert('请不要在一分钟之内申请多次验证码,请您稍后再试');
                 }
             }
         }
 
-        $total = $this->config['total'];
+        $total = $this->config['code_total'];
         if ($info >= $total) {
             Dever::alert('很抱歉,您已经申请获取验证码超过' . $total . '次,今天您已经无法获取验证码了,请您明天再来');
         }
 
-        $code = new Code();
-        $code->createM();
-
-        # 记录当前的验证码
-        $insert['add_mobile'] = $mobile;
-        $insert['add_day'] = $day;
-        $insert['add_code'] = $code->mcode;
-        $id = Dever::load('passport/code-insert', $insert);
+        $code = $this->createCode();
 
         # 启动发送
-        $this->send($mobile, $insert['add_code'], $id);
+        $result = $this->send($skin, $mobile, array('code' => $code));
 
-        $this->save->add($this->config['code'], $mobile . '_' . $code->mcode, $this->config['timeout']);
+        # 记录当前的验证码
+        $insert = array();
+        $insert['mobile'] = $mobile;
+        $insert['day'] = $day;
+        $insert['code'] = $code;
+        $insert['result'] = Dever::json_encode($result);
+        $id = Dever::db('sms/code')->insert($insert);
+
+        Dever::session($this->config['key'], $mobile . '_' . $code, $this->config['code_timeout']);
 
-        return $code->mcode;
+        return $code;
     }
+   
 
-    protected function send($mobile, $code, $id = false)
+    private function replace($content, $param)
     {
-        $url = $this->config['url'];
-
-        if (!$url) {
-            return;
+        foreach ($param as $k => $v) {
+            $string = '{'.$k.'}';
+            if (strstr($content, $string)) {
+                $content = str_replace($string, $v, $content);
+            }
         }
-
-        $content = $this->config['body'];
-
-        $content = $this->replace($content, $mobile, $code);
-
-        parse_str($content, $param);
-
-        $type = $this->config['method'];
-        $json = $this->config['json'];
-        $header = $this->config['header'];
-
-        return Dever::curl($url, $param, $type, $json, $header);
+        return $content;
     }
 
-    private function replace($content, $mobile = '', $code = '')
+    private function createCode()
     {
-        $skin = $this->config['skin'];
-        $skin_key = Dever::input('skin', 1);
-        if (isset($skin[$skin_key])) {
-            $skin = $skin[$skin_key];
-        } else {
-            $skin = array_shift($skin);
-        }
-
-        $config = array('{code}', '{mobile}', '{sign}', '{skin}', '{param}');
-        $replace = array($code, $mobile, $this->config['sign'], $skin);
-        return str_replace($config, $replace, $content);
+        $len = isset($this->config['code_length']) ? $this->config['code_length'] : 4;
+        $type = isset($this->config['code_type']) ? $this->config['code_type'] : 4;
+        return Dever::rand($len, $type);
     }
 }

+ 17 - 63
src/Api.php

@@ -2,75 +2,29 @@
 namespace Sms\Src;
 
 use Dever;
-use Passport\Lib\Base;
+use Sms\Lib\Base;
 
 class Api extends Base
 {
     public function test()
     {
-        return Dever::login(-1);
+    	# 短信模板标识
+    	$skin = 'k1';
+		# 手机号
+		$mobile = Dever::input('mobile');
+		$param = array
+		(
+			'content' => '自定义的内容',
+		);
+		return Dever::load('sms/api')->send($skin, $mobile, $param);
     }
 
-    public function quit()
+    public function testCode()
     {
-        if ($this->info()) {
-            $this->save->un(self::NAME);
-        }
-
-        $refer = isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] ? $_SERVER['HTTP_REFERER'] : Dever::url('home', 'main');
-
-        Dever::location($refer);
-    }
-
-    public function action()
-    {
-        $account = Dever::config('base', 'project')->account;
-
-        $param['option_' . $account] = Dever::input($account);
-
-        $password = sha1(Dever::input('password'));
-
-        $user = Dever::load('passport/user-login', $param);
-
-        if ($user && $password == $user['password']) {
-            $this->save($user);
-
-            $this->refer();
-        } else {
-            Dever::alert('您的账号或密码错误');
-        }
-    }
-
-    public function check()
-    {
-        if ($this->info()) {
-            $url = $this->refer(true);
-            return Dever::location($url);
-        }
-    }
-
-    public function get()
-    {
-        return $this->info();
-    }
-
-    public function url()
-    {
-        return Dever::url('login?' . $this->createRefer(), 'main');
-    }
-
-    public function location()
-    {
-        return Dever::location($this->url());
-    }
-
-    public function oauth($url = false)
-    {
-        if (!$url) {
-            $url = Dever::url();
-        }
-        $link = Dever::url('get.request?refer=' . urlencode($url), 'oauth');
-
-        return $link;
+    	# 短信模板标识
+    	$skin = 'k1';
+		# 手机号
+		$mobile = Dever::input('mobile');
+		return Dever::load('sms/api')->sendCode($skin, $mobile);
     }
-}
+}