瀏覽代碼

添加微信SDKload方法

Anyon 8 年之前
父節點
當前提交
59c15454d8
共有 5 個文件被更改,包括 493 次插入2 次删除
  1. 0 2
      extend/.gitignore
  2. 97 0
      extend/service/ExpressService.php
  3. 175 0
      extend/service/FansService.php
  4. 135 0
      extend/service/PayService.php
  5. 86 0
      extend/service/SmsService.php

+ 0 - 2
extend/.gitignore

@@ -1,2 +0,0 @@
-*
-!.gitignore

+ 97 - 0
extend/service/ExpressService.php

@@ -0,0 +1,97 @@
+<?php
+
+namespace service;
+
+use library\Http;
+
+/**
+ * 快递查询接口
+ * 
+ * @author Anyon <zoujingli@qq.com>
+ * @date 2016/11/28 17:13
+ */
+class ExpressService {
+
+    const APPID = '1232779';
+    const APPKEY = 'ac45f461-8c1a-4518-87b1-bb8e835a2f9d';
+    const APIURI = 'http://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx';
+
+    /**
+     * @brief 获取物流轨迹线路
+     * @param $ShipperCode string 物流公司代号
+     * @param $LogisticCode string 物流单号
+     * @return string array 轨迹数据
+     */
+    public static function line($ShipperCode, $LogisticCode) {
+        $sendData = json_encode(array('ShipperCode' => $ShipperCode, 'LogisticCode' => $LogisticCode), JSON_UNESCAPED_UNICODE);
+        $data = array(
+            'RequestData' => $sendData,
+            'EBusinessID' => self::APPID,
+            'RequestType' => '1002',
+            'DataType'    => 2,
+            'DataSign'    => base64_encode(md5($sendData . self::APPKEY)),
+        );
+        $result = Http::post(self::APIURI, $data);
+        $resultJson = json_decode($result, true);
+        if (!$resultJson) {
+            die(var_export($result));
+        }
+        return self::response($resultJson);
+    }
+
+    /**
+     * 处理返回数据统一数据格式
+     * @param $result 结果处理
+     * @return array 通用的结果集 array('result' => 'success或者fail','data' => array( array('time' => '时间','info' => '地点'),......),'reason' => '失败原因')
+     */
+    public static function response($result) {
+        $status = "fail";
+        $data = array();
+        $message = "此单号无跟踪记录";
+        if (isset($result['Message'])) {
+            $message = $result['Message'];
+        } else if (isset($result['Reason'])) {
+            $message = $result['Reason'];
+        }
+        if (isset($result['Traces']) && $result['Traces']) {
+            foreach ($result['Traces'] as $key => $val) {
+                $data[$key]['time'] = $val['AcceptTime'];
+                $data[$key]['info'] = $val['AcceptStation'];
+            }
+            $status = "success";
+            $message = '此订单号有' . count($data) . '条跟踪记录';
+        }
+
+        return array('result' => $status, 'data' => $data, 'message' => $message);
+    }
+
+    /**
+     * CURL模拟提交数据
+     * @param $url string 提交的url
+     * @param $data array 要发送的数据
+     * @return mixed 返回的数据
+     */
+    private static function curl_post($url, $data) {
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+        curl_setopt($ch, CURLOPT_POST, 1);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, self::_encode_data($data));
+        return curl_exec($ch);
+    }
+
+    /**
+     * 进行数据的string字符串编码
+     * @param type $datas
+     * @return type
+     */
+    private static function _encode_data($datas) {
+        $temps = array();
+        foreach ($datas as $key => $value) {
+            $temps[] = sprintf('%s=%s', $key, $value);
+        }
+        return join('&', $temps);
+    }
+
+}

+ 175 - 0
extend/service/FansService.php

@@ -0,0 +1,175 @@
+<?php
+
+namespace service;
+
+use library\Data;
+use think\Cache;
+use think\Db;
+use think\Log;
+
+/**
+ * 微信粉丝数据服务
+ *
+ * @author Anyon <zoujingli@qq.com>
+ * @date 2016/10/24 17:01
+ */
+class FansService {
+
+    /**
+     * 从微信服务器获取所有标签
+     * @param $appid
+     * @return bool
+     */
+    static public function syncTags($appid) {
+        $wechat = &load_wechat("User", $appid);
+        if (($result = $wechat->getTags()) !== FALSE) {
+            $tags = $result['tags'];
+            foreach ($tags as &$tag) {
+                $tag['appid'] = $appid;
+            }
+            Db::table('wechat_fans_tags')->where('appid', $appid)->delete();
+            foreach (array_chunk($tags, 100) as $list) {
+                Db::table('wechat_fans_tags')->insertAll($list);
+            }
+            return true;
+        }
+        return true;
+    }
+
+    /**
+     * 同步粉丝的标签
+     * @param string $appid
+     * @param string $openid
+     * @return bool
+     */
+    static public function syncFansTags($appid, $openid) {
+        $wechat = &load_wechat('User', $appid);
+        $tagsid = $wechat->getUserTags($openid);
+        if ($tagsid === false || !is_array($tagsid)) {
+            return false;
+        }
+        return Data::save('wechat_fans', ['appid' => $appid, 'openid' => $openid, 'tagid_list' => join(',', $tagsid)], 'openid', ['appid' => $appid]);
+    }
+
+    /**
+     * 保存/更新粉丝信息
+     * @param array $userInfo
+     * @param string $appid
+     * @return bool
+     */
+    static public function set($userInfo, $appid = '') {
+        if (!empty($userInfo['subscribe_time'])) {
+            $userInfo['subscribe_at'] = date('Y-m-d H:i:s', $userInfo['subscribe_time']);
+        }
+        if (!empty($userInfo['tagid_list']) && is_array($userInfo['tagid_list'])) {
+            $userInfo['tagid_list'] = join(',', $userInfo['tagid_list']);
+        }
+        $userInfo['appid'] = $appid;
+        return Data::save('wechat_fans', $userInfo, 'openid');
+    }
+
+    /**
+     * 读取粉丝信息
+     * @param string $openid
+     * @return array|false
+     */
+    static public function get($openid) {
+        return Db::table('wechat_fans')->where('openid', $openid)->find();
+    }
+
+    /**
+     * 同步获取粉丝列表
+     * @param string $appid
+     * @param string $next_openid
+     * @return bool
+     */
+    static public function sync($appid, $next_openid = '') {
+        $wechat = &load_wechat('User', $appid);
+        $result = $wechat->getUserList($next_openid);
+        if ($result === FALSE || empty($result['data']['openid'])) {
+            Log::record("获取粉丝列表失败,{$wechat->errMsg} [{$wechat->errCode}]", Log::ERROR);
+            return FALSE;
+        }
+        foreach ($result['data']['openid'] as $openid) {
+            if (FALSE === ($userInfo = $wechat->getUserInfo($openid))) {
+                Log::record("获取用户[{$openid}]信息失败,$wechat->errMsg", Log::ERROR);
+                return FALSE;
+            }
+            if (FALSE === self::set($userInfo, $wechat->appid)) {
+                Log::record('更新粉丝信息更新失败!', Log::ERROR);
+                return FALSE;
+            }
+            if ($result['next_openid'] === $openid) {
+                unset($result['next_openid']);
+            }
+        }
+        return !empty($result['next_openid']) ? self::sync($appid, $result['next_openid']) : TRUE;
+    }
+
+    /**
+     * 同步获取黑名单信息
+     * @param string $appid
+     * @param string $next_openid
+     * @return bool
+     */
+    static public function syncBlacklist($appid, $next_openid = '') {
+        $wechat = &load_wechat('User');
+        $result = $wechat->getBacklist($next_openid);
+
+        if ($result === FALSE || (empty($result['data']['openid']))) {
+            if (empty($result['total'])) {
+                return TRUE;
+            }
+            Log::record("获取粉丝黑名单列表失败,{$wechat->errMsg} [{$wechat->errCode}]", Log::ERROR);
+            return FALSE;
+        }
+        foreach ($result['data']['openid'] as $openid) {
+            if (FALSE === ($userInfo = $wechat->getUserInfo($openid))) {
+                Log::record("获取用户[{$openid}]信息失败,$wechat->errMsg", Log::ERROR);
+                return FALSE;
+            }
+            $userInfo['is_back'] = '1';
+            if (FALSE === self::set($userInfo)) {
+                Log::record('更新粉丝信息更新失败!', Log::ERROR);
+                return FALSE;
+            }
+            if ($result['next_openid'] === $openid) {
+                unset($result['next_openid']);
+            }
+        }
+        return !empty($result['next_openid']) ? self::sync_blacklist($appid, $result['next_openid']) : TRUE;
+    }
+
+    /**
+     * 读取七天的统计数据
+     * @param string $appid
+     * @param int $day
+     * @return array
+     */
+    static public function getTotal($appid, $day = 7) {
+        $result = Cache::get(($cachekey = "wechat_token_{$appid}"));
+        if (!empty($result)) {
+            return $result;
+        }
+        $extends = &load_wechat('Extends', $appid);
+        // 统计总数
+        $data['cumulate'] = (array)$extends->getDatacube('user', 'cumulate', date('Y-m-d', strtotime("-{$day} day")), date('Y-m-d', strtotime('-1 day')));
+        // 统计增量数
+        $data['summary'] = (array)$extends->getDatacube('user', 'summary', date('Y-m-d', strtotime("-{$day} day")), date('Y-m-d', strtotime('-1 day')));
+        // 统计消息数
+        $data['upstreammsg'] = (array)$extends->getDatacube('upstreammsg', 'summary', date('Y-m-d', strtotime("-{$day} day")), date('Y-m-d', strtotime('-1 day')));
+        $temp = array();
+        for ($i = 1; $i <= $day; $i++) {
+            $temp[date('Y-m-d', strtotime("-{$i} day"))] = [];
+        }
+        foreach ($data as $vo) {
+            foreach ($vo as $v) {
+                isset($v['ref_date']) && ($temp[$v['ref_date']] = array_merge($temp[$v['ref_date']], $v));
+            }
+        }
+        ksort($temp);
+        Cache::set($cachekey, $temp, 600);
+        return $temp;
+    }
+
+}

+ 135 - 0
extend/service/PayService.php

@@ -0,0 +1,135 @@
+<?php
+
+namespace service;
+
+use library\Data;
+use PHPQRCode\Constants;
+use PHPQRCode\QRcode;
+use think\Db;
+use think\Exception;
+use think\Log;
+use Wechat\WechatPay;
+
+/**
+ * 支付数据处理
+ *
+ * @author Anyon <zoujingli@qq.com>
+ * @date 2016/10/25 14:49
+ */
+class PayService {
+
+    /**
+     * 查询订单是否已经支付
+     * @param string $order_no
+     * @return bool
+     */
+    static public function isPay($order_no) {
+        return Db::table('wechat_pay_prepayid')->where('order_no', $order_no)->where('is_pay', '1')->count() > 0;
+    }
+
+    /**
+     *  创建微信二维码支付(扫码支付模式二)
+     * @param WechatPay $pay 支付SDK
+     * @param string $order_no 系统订单号
+     * @param int $fee 支付金额
+     * @param string $title 订单标题
+     * @param string $from 订单来源
+     * @return bool
+     */
+    static public function createQrc($pay, $order_no, $fee, $title, $from = 'wechat') {
+        $prepayid = self::_createPrepayid($pay, null, $order_no, $fee, $title, 'NATIVE', $from);
+        if ($prepayid === false) {
+            return false;
+        }
+        $filename = ROOT_PATH . "public/upload/{$pay->appid}/payqrc/" . join('/', str_split(md5($prepayid), 16)) . '.png';
+        !is_dir(dirname($filename)) && mkdir(dirname($filename), 0755, true);
+        !file_exists($filename) && QRcode::png($prepayid, $filename, Constants::QR_ECLEVEL_L, 8);
+        ob_clean();
+        header("Content-type: image/png");
+        exit(readfile($filename));
+    }
+
+    /**
+     * 创建微信预支付码
+     * @param WechatPay $pay 支付SDK
+     * @param string $openid 支付者Openid
+     * @param string $order_no 实际订单号
+     * @param int $fee 实际订单支付费用
+     * @param string $title 订单标题
+     * @param string $trade_type 付款方式
+     * @param string $from 订单来源
+     * @return bool|string
+     */
+    static protected function _createPrepayid($pay, $openid, $order_no, $fee, $title, $trade_type = 'JSAPI', $from = 'shop') {
+        $map = ['order_no' => $order_no, 'is_pay' => '1', 'expires_in' => time(), 'appid' => $pay->appid];
+        $prepayinfo = Db::table('wechat_pay_prepayid')->where('appid=:appid and order_no=:order_no and (is_pay=:is_pay or expires_in>:expires_in)', $map)->find();
+        if (empty($prepayinfo) || empty($prepayinfo['prepayid'])) {
+            $out_trade_no = Data::createSequence(18, 'WXPAY-OUTER-NO');
+            $prepayid = $pay->getPrepayId($openid, $title, $out_trade_no, $fee, url("@push/wechat/notify/{$pay->appid}", '', true, true), $trade_type);
+            if (empty($prepayid)) {
+                Log::error("内部订单号{$order_no}生成预支付失败,{$pay->errMsg}");
+                return false;
+            }
+            $data = [
+                'appid'        => $pay->appid, // 对应公众号APPID
+                'prepayid'     => $prepayid, // 微信支付预支付码
+                'order_no'     => $order_no, // 内部订单号
+                'out_trade_no' => $out_trade_no, // 微信商户订单号
+                'fee'          => $fee, // 需要支付费用(单位为分)
+                'trade_type'   => $trade_type, // 发起支付类型
+                'expires_in'   => time() + 5400, // 微信预支付码有效时间1.5小时(最长为2小时)
+                'from'         => $from // 订单来源
+            ];
+            if (Db::table('wechat_pay_prepayid')->insert($data) > 0) {
+                Log::notice("内部订单号{$order_no}生成预支付成功,{$prepayid}");
+                return $prepayid;
+            }
+        }
+        return $prepayinfo['prepayid'];
+    }
+
+    /**
+     * 创建微信JSAPI支付签名包
+     * @param WechatPay $pay 支付SDK
+     * @param string $openid 微信用户openid
+     * @param string $order_no 系统订单号
+     * @param int $fee 支付金额
+     * @param string $title 订单标题
+     * @return bool|array
+     */
+    static public function createJs($pay, $openid, $order_no, $fee, $title) {
+        if (($prepayid = self::_createPrepayid($pay, $openid, $order_no, $fee, $title, 'JSAPI')) === false) {
+            return false;
+        }
+        return $pay->createMchPay($prepayid);
+    }
+
+    /**
+     * 微信退款操作
+     * @param WechatPay $pay 支付SDK
+     * @param string $order_no 系统订单号
+     * @param int $fee 退款金额
+     * @param string|null $refund_no 退款订单号
+     * @return bool
+     */
+    static public function refund($pay, $order_no, $fee = 0, $refund_no = NULL, $refund_account = '') {
+        $map = array('order_no' => $order_no, 'is_pay' => '1', 'appid' => $pay->appid);
+        $notify = Db::table('wechat_pay_prepayid')->where($map)->find();
+        if (empty($notify)) {
+            Log::error("内部订单号{$order_no}验证退款失败");
+            return false;
+        }
+        if (false !== $pay->refund($notify['out_trade_no'], $notify['transaction_id'], is_null($refund_no) ? "T{$order_no}" : $refund_no, $notify['fee'], empty($fee) ? $notify['fee'] : $fee, '', $refund_account)) {
+            $data = ['out_trade_no' => $notify['out_trade_no'], 'is_refund' => "1", 'refund_at' => date('Y-m-d H:i:s'), 'expires_in' => time() + 7000];
+            if (Data::save('wechat_pay_prepayid', $data, 'out_trade_no')) {
+                return true;
+            }
+            Log::error("内部订单号{$order_no}退款成功,系统更新异常");
+            return false;
+        }
+        Log::error("内部订单号{$order_no}退款失败,{$pay->errMsg}");
+        return false;
+    }
+
+
+}

+ 86 - 0
extend/service/SmsService.php

@@ -0,0 +1,86 @@
+<?php
+
+namespace service;
+
+use library\Sms;
+use think\Cache;
+
+/**
+ * 短信服务
+ *
+ * @package service
+ * @author Anyon <zoujingli@qq.com>
+ * @date 2016/12/14 16:50
+ */
+class SmsService extends BasicService {
+
+    /**
+     * 给手机发送短信
+     * @param string $phone 手机号码
+     * @param string $content 短信内容
+     * @param array $data 短信内容模板数据
+     * @return bool
+     */
+    static public function send($phone, $content, $data = []) {
+        $sms = new Sms();
+        return $sms->render($content, $data)->send($phone);
+    }
+
+    /**
+     * 给指定手机号码发送验证码
+     * @param string $phone 手机号码
+     * @param int $length 验证码长度
+     * @param string $string 验证码可选字符
+     * @param string $code
+     * @return array
+     */
+    static public function verify($phone, $length = 4, $string = "0123456789", $code = '') {
+        $max = strlen($string) - 1;
+        for ($i = 0; $i < $length; $i++) {
+            $code .= $string[rand(0, $max)];
+        }
+        $cache_key = "sms_verify_{$phone}";
+        $cache = Cache::get($cache_key);
+        if ($cache && !empty($cache['time']) && $cache['time'] + 60 > time()) {
+            return self::_data('同一手机号码60秒内只能发送一条短信哦!', 'SMS_60S_ONLY_SEND_A_SMS');
+        }
+        $result = self::send($phone, 'sms_tpl_register', ['code' => $code]);
+        if ($result) {
+            $cache = ['phone' => $phone, 'code' => $code, 'time' => time()];
+            Cache::set($cache_key, $cache, 180);
+            return self::_data('验证码发送成功,请查看手机短信!', 'SUCCESS');
+        }
+        return self::_data('验证码发送失败,请稍候再试!', 'ERROR');
+    }
+
+    /**
+     * 获取再次发送短信的等待时间
+     * @param string $phone
+     * @return int
+     */
+    static public function getVerifyWaitTime($phone) {
+        $cache_key = "sms_verify_{$phone}";
+        $cache = Cache::get($cache_key);
+        if (empty($cache) || empty($cache['time']) || $cache['time'] + 60 < time()) {
+            return 0;
+        }
+        return time() - $cache['time'] - 60;
+    }
+
+    /**
+     * 统一验证码验证
+     * @param string $phone
+     * @param string $code
+     * @return array
+     */
+    static public function checkVerify($phone, $code) {
+        $cache_key = "sms_verify_{$phone}";
+        $cache = Cache::get($cache_key);
+        if (empty($cache) || empty($cache['code']) || $cache['code'] !== $code) {
+            return self::_data('验证码验证失败,请输入正确的验证码!', 'SMS_VERIFY_FAILD');
+        }
+        Cache::rm($cache_key);
+        return self::_data('验证码验证成功!', 'SUCCESS');
+    }
+
+}