From 4be2904f3688c07e0e9793414bda33ae1f85f565 Mon Sep 17 00:00:00 2001 From: chengkun <chengkun@ishangstudy.com> Date: Wed, 28 May 2025 18:41:16 +0800 Subject: [PATCH] 提交 --- app/model/notice.model.php | 214 ++++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 153 insertions(+), 61 deletions(-) diff --git a/app/model/notice.model.php b/app/model/notice.model.php index 3763f07..23122e5 100644 --- a/app/model/notice.model.php +++ b/app/model/notice.model.php @@ -199,7 +199,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,6 +234,12 @@ return $this->sendEmail($data); } + /** + * @desc 发送短信 + * @param $type + * @param $data + * @return bool|string + */ private function postSMS($type = "msgsend", $data = '') { $sing = $this->config['sy_msg_appsing']; $data['content'] = str_replace(array(" ", " ", "\t", "\n", "\r"), array("", "", "", "", ""), $data['content']); @@ -253,6 +259,11 @@ return $file_contents; } + /** + * 检测手机号 + * @param $phone + * @return mixed + */ private function checkPhone($phone) { @@ -287,7 +298,7 @@ } $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'] != '') { @@ -297,7 +308,7 @@ } } - if ($this->_isKey('content', $data) == false || $data['content'] == '') { + if (!$this->_isKey('content', $data) || $data['content'] == '') { return array('status' => -1, 'msg' => '短信内容为空'); } @@ -395,7 +406,7 @@ } /** - * + * 发送短信 * @param array $data 传入参数 * @param string $content 短信内容 * @return number[]|string[] @@ -519,19 +530,15 @@ * @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 = []; if ($kind == 'msg') { - + ///// 短信 ///// if (!checkMsgOpen($this->config)) { - return array('error' => 107, 'msg' => '网站没有配置短信,请联系管理员!'); - } $ip = fun_ip_get(); @@ -539,69 +546,48 @@ $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 +598,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 +653,6 @@ } if ($result['status'] != -1) { - - $sendData = array( 'uid' => intval($user['uid']), 'status' => 0, @@ -689,29 +671,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|mixed|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 +703,23 @@ 'type' => $type, 'code' => $code ); + $result = []; if ($kind == 'msg') { - $data['moblie'] = $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 +727,14 @@ 'cert' => '手机认证', 'getpass' => '找回密码' ); + return $status[$type] ?: ''; } - //查询接收短信、邮件用户信息 + /** + * 查询接收短信、邮件用户信息 + * @param $user + * @return array|mixed|string + */ private function forsend($user) { $info = array( 'uid' => 0, @@ -755,16 +743,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 +792,116 @@ } } + /** + * 签名-腾讯云 + * @param $key + * @param $msg + * @return string + */ + function sign($key, $msg) { + return hash_hmac("sha256", $msg, $key, true); + } + + /** + * 发送短信接口-腾讯云 + * @param $params + * @return array + */ + public function sendSmsHttpRequest($params = []) { + // 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密 + // 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305 + // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取 + + try { + $secret_id = "SecretId"; + $secret_key = "SecretKey"; + $token = ""; + + $service = "sms"; + $host = "sms.tencentcloudapi.com"; + $req_region = "ap-guangzhou"; + $version = "2021-01-11"; + $action = "SendSms"; +// $params = [ +// 'PhoneNumberSet' => '18019261992', +// 'SmsSdkAppId' => '2343224242', +// 'TemplateId' => '54645454' +// ]; + $payload = json_encode($params); + $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 = sign("TC3" . $secret_key, $date); + $secret_service = sign($secret_date, $service); + $secret_signing = 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; + } + + $ch = curl_init(); + 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