From abb66a0e799e7ca613e8967a304e7c5ed00e034e Mon Sep 17 00:00:00 2001
From: chengkun <chengkun@ishangstudy.com>
Date: Fri, 30 May 2025 11:37:48 +0800
Subject: [PATCH] 提交

---
 app/model/notice.model.php |  271 +++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 187 insertions(+), 84 deletions(-)

diff --git a/app/model/notice.model.php b/app/model/notice.model.php
index 3763f07..b12d67a 100644
--- a/app/model/notice.model.php
+++ b/app/model/notice.model.php
@@ -68,18 +68,17 @@
      * 获取邮件、短信模板
      * @param array $data 传入参数
      * @param string $type 模板类型:email邮箱; msg短信
-     * @return mixed
+     * @return array
      */
     public function getTpl($data, $type) {
         $name = $type . $data['type'];
-        
         
         $row = $this->select_once('templates', array('name' => $name));
         
         if ($row) {
             $tpl['title'] = $this->_tpl($row['title'], $data);
             $tpl['content'] = $this->_tpl($row['content'], $data);
-            
+            $tpl['template_id'] = $row['template_id'];
             return $tpl;
         } else {
             return array('status' => -1, 'msg' => '信息模板有误,请联系管理员');
@@ -199,7 +198,7 @@
     /**
      * @desc 根据业务类型,判断后台设置是否开启该类型email提醒,选择设定好的email模板,发送指定类型的邮件
      *
-     * @param string $data ['type'] 发送email的类型:
+     * @param array $data ['type'] 发送email的类型:
      *            reg注册,yqms邀请面试,fkcg付款成功,zzshtg职位审核成功,sqzw申请职位,getpass找回密码,yqmshf回复面试邀请,login登录验证
      *            'birthday',
      *            'webbirthday',
@@ -234,7 +233,13 @@
         return $this->sendEmail($data);
     }
     
-    private function postSMS($type = "msgsend", $data = '') {
+    /**
+     * @desc 发送短信接口
+     * @param $type
+     * @param $data
+     * @return array
+     */
+    private function postSMS($type = "msgsend", $data = []) {
         $sing = $this->config['sy_msg_appsing'];
         $data['content'] = str_replace(array(" ", " ", "\t", "\n", "\r"), array("", "", "", "", ""), $data['content']);
         $url = 'http://api.smsbao.com/sms';
@@ -253,6 +258,11 @@
         return $file_contents;
     }
     
+    /**
+     * 检测手机号
+     * @param $phone
+     * @return mixed
+     */
     private function checkPhone($phone) {
         
         
@@ -274,6 +284,7 @@
     }
     
     /**
+     * @desc 发送短信
      * $data['moblie'] / $data['mobile'] 手机号(必填)
      * $data['content'] 短信内容(必填)
      *
@@ -286,30 +297,29 @@
             return array('status' => -1, 'msg' => '还没有配置短信,请联系管理员!');
         }
         
-        $data['mobile'] = $data['moblie'] ? $data['moblie'] : $data['mobile'];
-        if ($this->_isKey('mobile', $data) == false || CheckMobile($data['mobile']) == false) {
+        if (!$this->_isKey('mobile', $data) || !CheckMobile($data['mobile'])) {
             return array('status' => -1, 'msg' => '手机号错误');
         }
+        
         if ($this->config['sy_web_mobile'] != '') {
             $regnamer = @explode(';', $this->config['sy_web_mobile']);
             if (in_array($data['mobile'], $regnamer)) {
                 return array('status' => -1, 'msg' => '该手机号已被禁止使用');
             }
         }
-        
-        if ($this->_isKey('content', $data) == false || $data['content'] == '') {
+        if (!$this->_isKey('content', $data) || $data['content'] == '') {
             return array('status' => -1, 'msg' => '短信内容为空');
         }
         
         //发送短信
         $row = array(
-            
-            'appsecret' => $this->config['sy_msg_appsecret'],
-            'appkey'    => $this->config['sy_msg_appkey'],
-            'appsing'   => $this->config['sy_msg_appsing'],
-            'phone'     => $data['mobile'],
-            'content'   => $data['content'],
-            'mid'       => isset($data['mid']) ? $data['mid'] : ''
+            'sy_sms_secret_id'  => $this->config['sy_sms_secret_id'],
+            'sy_sms_secret_key' => $this->config['sy_sms_secret_key'],
+            'sy_sms_sdk_app_id' => $this->config['sy_sms_sdk_app_id'],
+            'sy_sms_sign_name'  => $this->config['sy_sms_sign_name'],
+            'template_id'       => $data['template_id'],
+            'phone'             => $data['mobile'],
+            'code'              => $data['code'],
         );
         
         $location = '';
@@ -352,7 +362,9 @@
             }
         }
         if (!isset($re['code'])) {
-            $re = $this->postSMS('msgsend', $row);
+            ///// 发送短信 /////
+//            $re = $this->postSMS('msgsend', $row);
+            $re = $this->sendSmsHttpRequest($row);
         }
         //短信记录保存数据库
         $sql_data = array(
@@ -365,7 +377,7 @@
             'location' => $location
         );
         
-        if (trim($re) == '0') {
+        if ($re['code'] == 1) {
             //检查是否需要发送系统预警
             include_once('warning.model.php');
             
@@ -395,7 +407,7 @@
     }
     
     /**
-     *
+     * 发送短信
      * @param array $data 传入参数
      * @param string $content 短信内容
      * @return number[]|string[]
@@ -414,10 +426,11 @@
                 return $tpl;
             }
             $content = $tpl['content'];
+            $template_id = $tpl['template_id'];
         }
         
         $data['content'] = $content;
-        
+        $data['template_id'] = $template_id;
         return $this->sendSMS($data);
     }
     
@@ -490,19 +503,20 @@
     
     /**
      * @desc    短信验证码时效性
-     * @param array $data
+     * @param string $data
      * @return  boolean
      */
-    public function checkTime($data) {
+    public function checkTime($data = 0) {
         $cert_validity = $this->config['moblie_codetime'] * 60; // 验证码有效时间
+        if (!$data) {
+            return false;
+        }
         $time = time();
-        $ctime = bcsub($time, $data);
-        
+        $data = is_numeric($data) ?: 0;
+        $ctime = round($time - $data, 2);
         if ($ctime <= $cert_validity) {
-            
             return true;
         } else {
-            
             return false;
         }
     }
@@ -519,19 +533,16 @@
      * @return array|number[]|string[]
      */
     public function sendCode($sended, $type, $port = '', $user = array(), $length = 6, $validity = 120, $kind = 'msg') {
-        
         $time = time();
         $overtime = $time - $validity;
         $today = strtotime('today');
-        $ip = fun_ip_get();
         $code = gt_Generate_code($length); //验证码
-        
+        $lastSend = [];
+        $result = [];
         if ($kind == 'msg') {
-            
+            ///// 短信 /////
             if (!checkMsgOpen($this->config)) {
-                
                 return array('error' => 107, 'msg' => '网站没有配置短信,请联系管理员!');
-                
             }
             
             $ip = fun_ip_get();
@@ -539,69 +550,49 @@
             $ipnum = $this->select_num('moblie_msg', array('ip' => $ip, 'ctime' => array('>', strtotime(date('Y-m-d')))));
             
             if ($ipnum >= $this->config['ip_msgnum']) {
-                
                 return array('error' => 107, 'msg' => '当前IP短信发送受限!');
-                
             }
             
             $num = $this->select_num('moblie_msg', array('moblie' => $sended, 'ctime' => array('>', strtotime(date('Y-m-d')))));
             
             if ($num >= $this->config['moblie_msgnum']) {
-                
                 return array('error' => 107, 'msg' => '请不要频繁发送!');
-                
             }
             
-            if (CheckMobile($sended) == false) {
-                
+            if (!CheckMobile($sended)) {
                 return array('error' => 106, 'msg' => '手机号码格式错误');
-                
             }
             
             if ($type == 'getpass') {
-                
+                ///// 找回密码的情况 /////
                 $member = $this->select_once('member', array('moblie' => $sended), '`uid`,`username` as `name`, `usertype`');
-                
                 if (!empty($member)) {
-                    
                     $user = array(
                         'uid'      => $member['uid'],
                         'usertype' => $member['usertype'],
                         'name'     => $member['name']
                     );
-                    
                 } else {
-                    
                     return array('error' => 105, 'msg' => '该手机尚未注册');
-                    
                 }
-                
+                ///// 获取企业认证信息  /////
                 $lastSend = $this->select_once('company_cert', array('check' => $sended, 'type' => 7, 'orderby' => 'id,desc'), '`ctime`,`type`');
-                
             } else {
-                
+                ///// 获取企业认证信息  /////
                 $lastSend = $this->select_once('company_cert', array('check' => $sended, 'type' => 2, 'orderby' => 'id,desc'), '`ctime`,`type`');
             }
             if ($lastSend['ctime'] > $overtime) {
-                
                 return array('error' => 102, 'msg' => '两次发送间隔需超过' . $validity . '秒');
-                
             }
             if ($type == 'cert') {
-                
                 $certover = $time - ($this->config['cert_msgtime'] * 60);
-                
                 if ($lastSend['ctime'] > $certover) {
-                    
                     return array('error' => 102, 'msg' => '手机认证短信发送间隔需超过' . $this->config['cert_msgtime'] . '分钟');
                 }
             }
             $sendToday = $this->select_all('moblie_msg', array('moblie' => $sended, 'ctime' => array('>', $today)), '`ip`');
-            
             if (count($sendToday) >= $this->config['moblie_msgnum']) {
-                
                 return array('error' => 103, 'msg' => '同一手机号一天最多发送' . $this->config['moblie_msgnum'] . '条');
-                
             }
             
             $ipSendNum = 0;
@@ -612,14 +603,12 @@
                 }
             }
             if ($ipSendNum >= $this->config['ip_msgnum']) {
-                
                 return array('error' => 104, 'msg' => '同一IP一天最多发送' . $this->config['ip_msgnum'] . '条');
-                
             }
             $result = $this->sendType($sended, $type, $code, 'msg', $user, $port);
             
         } elseif ($kind == 'email') {
-            if (CheckRegEmail($sended) == false) {
+            if (!CheckRegEmail($sended)) {
                 
                 return array('error' => 101, 'msg' => '邮箱格式错误');
             }
@@ -669,8 +658,6 @@
         }
         
         if ($result['status'] != -1) {
-            
-            
             $sendData = array(
                 'uid'        => intval($user['uid']),
                 'status'     => 0,
@@ -689,29 +676,30 @@
             }
             //只修改短信验证码相关的验证
             if ($lastSend && ($lastSend['type'] == 2 || $lastSend['type'] == 7)) {
-                
                 if ($lastSend['type'] == 2) {
-                    
                     $this->update_once('company_cert', $sendData, array('check' => $sended, 'type' => 2));
-                    
                 } elseif ($lastSend['type'] == 7) {
-                    
                     $this->update_once('company_cert', $sendData, array('check' => $sended, 'type' => 7));
                 }
-                
             } else {
-                
                 $this->insert_into('company_cert', $sendData);
             }
         }
         return array('error' => $result['status'], 'msg' => $result['msg']);
     }
     
-    //按类别发送验证码
+    /**
+     * 按类别发送验证码
+     * @param $sended // 发送对象-手机号
+     * @param $type // 验证码类别
+     * @param $code // 验证码
+     * @param $kind //  发送类别
+     * @param $user // 用户信息
+     * @param $port // 端口
+     * @return array|number[]|string[]
+     */
     private function sendType($sended, $type, $code, $kind = 'msg', $user = array(), $port = null) {
-        
         $finfo = $this->forsend($user);       //用户信息
-        
         $data = array(
             'uid'      => $finfo['uid'],
             'username' => $finfo['name'],
@@ -720,23 +708,23 @@
             'type'     => $type,
             'code'     => $code
         );
+        $result = [];
         if ($kind == 'msg') {
-            
-            $data['moblie'] = $sended;
+            $data['mobile'] = $sended;
             $data['port'] = $port;
-            
             $result = $this->sendSMSType($data);
-            
         } elseif ($kind == 'email') {
-            
             $data['email'] = $sended;
-            
             $result = $this->sendEmailType($data);
         }
         return $result;
     }
     
-    //手机验证码类型
+    /**
+     * 手机验证码类型
+     * @param $type
+     * @return string
+     */
     private function codeType($type) {
         $status = array(
             'login'   => '手机登录验证码',
@@ -744,9 +732,14 @@
             'cert'    => '手机认证',
             'getpass' => '找回密码'
         );
+        return $status[$type] ?: '';
     }
     
-    //查询接收短信、邮件用户信息
+    /**
+     * 查询接收短信、邮件用户信息
+     * @param $user
+     * @return array|mixed|string
+     */
     private function forsend($user) {
         $info = array(
             'uid'   => 0,
@@ -755,16 +748,11 @@
             'cname' => '系统'
         );
         if (!empty($user['uid'])) {
-            
             if (!empty($user['name'])) {
-                
                 $info['uid'] = $user['uid'];
                 $info['name'] = $user['name'];
-                
             } else {
-                
                 $info = $this->select_once('member', array('uid' => $user['uid']), '`uid`, `username` as `name`');
-                
             }
         }
         return $info;
@@ -809,7 +797,122 @@
         }
     }
     
+    /**
+     * 签名-腾讯云
+     * @param $key
+     * @param $msg
+     * @return string
+     */
+    protected function sign($key, $msg) {
+        return hash_hmac("sha256", $msg, $key, true);
+    }
+    
+    /**
+     * 发送短信接口-腾讯云
+     * @param $data
+     * @return array
+     */
+    public function sendSmsHttpRequest($data = []) {
+        // 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
+        // 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
+        // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
+        
+        $secret_id = $data['sy_sms_secret_id'];
+        $secret_key = $data['sy_sms_secret_key'];
+        $token = "";
+        
+        $service = "sms";
+        $host = "sms.tencentcloudapi.com";
+        $req_region = "ap-guangzhou";
+        $version = "2021-01-11";
+        $action = "SendSms";
+        
+        //////数字转字符串 //////
+        $params = [
+            'PhoneNumberSet'   => ['+86' . $data['phone']],
+            'SmsSdkAppId'      => $data['sy_sms_sdk_app_id'],
+            'TemplateId'       => $data['template_id'],
+            'SignName'         => $data['sy_sms_sign_name'],
+            'TemplateParamSet' => [strval($data['code'])]
+        ];
+        $payload = json_encode($params, JSON_UNESCAPED_UNICODE);
+        $endpoint = "https://sms.tencentcloudapi.com";
+        $algorithm = "TC3-HMAC-SHA256";
+        $timestamp = time();
+        $date = gmdate("Y-m-d", $timestamp);
+        
+        // ************* 步骤 1:拼接规范请求串 *************
+        $http_request_method = "POST";
+        $canonical_uri = "/";
+        $canonical_querystring = "";
+        $ct = "application/json; charset=utf-8";
+        $canonical_headers = "content-type:" . $ct . "\nhost:" . $host . "\nx-tc-action:" . strtolower($action) . "\n";
+        $signed_headers = "content-type;host;x-tc-action";
+        $hashed_request_payload = hash("sha256", $payload);
+        $canonical_request = "$http_request_method\n$canonical_uri\n$canonical_querystring\n$canonical_headers\n$signed_headers\n$hashed_request_payload";
+        
+        // ************* 步骤 2:拼接待签名字符串 *************
+        $credential_scope = "$date/$service/tc3_request";
+        $hashed_canonical_request = hash("sha256", $canonical_request);
+        $string_to_sign = "$algorithm\n$timestamp\n$credential_scope\n$hashed_canonical_request";
+        
+        // ************* 步骤 3:计算签名 *************
+        $secret_date = $this->sign("TC3" . $secret_key, $date);
+        $secret_service = $this->sign($secret_date, $service);
+        $secret_signing = $this->sign($secret_service, "tc3_request");
+        $signature = hash_hmac("sha256", $string_to_sign, $secret_signing);
+        
+        // ************* 步骤 4:拼接 Authorization *************
+        $authorization = "$algorithm Credential=$secret_id/$credential_scope, SignedHeaders=$signed_headers, Signature=$signature";
+        
+        // ************* 步骤 5:构造并发起请求 *************
+        $headers = [
+            "Authorization"  => $authorization,
+            "Content-Type"   => "application/json; charset=utf-8",
+            "Host"           => $host,
+            "X-TC-Action"    => $action,
+            "X-TC-Timestamp" => $timestamp,
+            "X-TC-Version"   => $version
+        ];
+        if ($req_region) {
+            $headers["X-TC-Region"] = $req_region;
+        }
+        if ($token) {
+            $headers["X-TC-Token"] = $token;
+        }
+        try {
+            $ch = curl_init();
+            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
+            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
+            curl_setopt($ch, CURLOPT_URL, $endpoint);
+            curl_setopt($ch, CURLOPT_POST, TRUE);
+            curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
+            curl_setopt($ch, CURLOPT_HTTPHEADER, array_map(function ($k, $v) {
+                return "$k: $v";
+            }, array_keys($headers), $headers));
+            curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
+            $response = curl_exec($ch);
+            curl_close($ch);
+            $result = json_decode($response, TRUE);
+            
+            if (!$result['Response']['RequestId']) {
+                throw new Exception("请求失败", 10000);
+            }
+            
+            $result_result = [
+                'code' => 1,
+                'msg'  => 'ok',
+                'data' => $result['Response']
+            ];
+        } catch (Exception $exc) {
+            $result_result = [
+                'code' => $exc->getCode(),
+                'msg'  => $exc->getMessage()
+            ];
+        }
+        return $result_result;
+    }
+    
     
 }
 
-?>
\ No newline at end of file

--
Gitblit v1.9.0