php版微信api制作多客服插件例子
其实多客服插件很简单,就是简单的HTML结构。当然结合异步AJAX来获取数据。至于微信后台怎么设置插件的URL这里不多说了,看看API,别告诉我你不懂?做个插件代码中只需要调用微信官方给出的window.external.PutMsg(JSON)就可以选定的三种内容(文本、图片、图文)调到多客服软件的发送框!下面以发送图片为例。过程中是AJAX后台取图片,然后显示出来,再鼠标单击点选发送。(注意微信发图片有大小限制,请看官方API)
效果图:
client
一、我们要组织的JSON格式:
{
msg:{
head:{
random:(new Date()).valueOf().toString()
},
body:[{
type:1,
content:{
picUrl:imageUrl
}
}]
}
}
二、插件my_plugin.html排版布局的HTML(即插件窗口)最好是响应式,不过写固定宽度也行,官方给出的推荐宽度是420px
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
<meta http-equiv="Content-Language" content="zh-cn" />
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<title></title>
</head>
<style>
body {
font-family: "Microsoft Yahei", Arial, sans-serif;
font-size: 14px;
background: #FFF;
overflow-x:hidden;
}
.title{font-size: 15px;margin-bottom:5px;}
.content{margin-bottom:10px;}
.textarea{background-color: #FFFCEC;}
.module{background: #eee;border: 1px solid #DDDDDD; padding:5px; margin-bottom:10px;}
.button {
margin-top: 8px;
padding: 0 20px;
text-align: center;
text-decoration: none;
font: 12px/25px Arial, sans-serif;
border-radius: 5px;
}
.green {color: #3e5706; background: #a5cd4e;}
.img {width:170px;height:120px;}
li.left{float:left;margin:8px 0 0 5px;padding:0;border:1px solid #0088d0;}
.gallery{
list-style: none;
margin: 0; padding: 0;
width: 100%;
font-size: 0; /* fix inline-block spacing */
}
.gallery li{
display: inline-block;
*display: inline;
zoom:1;
width: 170px; height: 120px;
margin: 2px;
border: 5px solid #fff;
-moz-box-shadow: 0 2px 2px rgba(0,0,0,.1);
-webkit-box-shadow: 0 2px 2px rgba(0,0,0,.1);
box-shadow: 0 2px 2px rgba(0,0,0,.1);
-webkit-transition: all .3s ease;
-moz-transition: all .3s ease;
-ms-transition: all .3s ease;
-o-transition: all .3s ease;
transition: all .3s ease;
}
.gallery:hover li:not(:hover){
-webkit-filter: blur(2px) grayscale(1);
-moz-filter: blur(2px) grayscale(1);
-o-filter: blur(2px) grayscale(1);
-ms-filter: blur(2px) grayscale(1);
filter: blur(2px) grayscale(1);
opacity: .7; /* fallback */
}
</style>
<body style="">
<div>
<div class="module">
<div class="title">
<span style="margin-left:39%;color:#C62A2A;">最新产品图</span>
</div>
<div class="content">
<ul class="gallery">
</ul>
</div>
<div style="text-align: center;clear:both;">
<input type="button" class="button" id="add" onclick="get()" value="重取"/>
</div>
<div>
<span id="putmsgret" style="color:red;font-size: 11px"></span>
</div>
</div>
</div>
<script type="text/javascript" src="http://static.paipaiimg.com/js/victor/lib/jquery.min.js"></script>
<script type="text/javascript" src="json2.min.js"></script>
<script>
var ul = $("ul");
get();
function get() {
$("li").remove();
$.getJSON('http://www.wp83.net/getImages.php',null,function(data){
$.each(data,function(index, url){
var li = '<li class="left">';
li += '<img class="img" src="thumb.php?src='+url+'&w=165&h=130" /></li>';
$("ul").append(li);
});
});
}
function MCS_ClientNotify(EventData) {
EventData = strToJson(EventData);
switch(EventData['event']){
case 'OnUserChange':{
OnUserChange(EventData);
break;
}
}
}
ul.on('click', ".img",function() {
var $img = $(this);
var thumbUrl = $img.attr('src');
var imageUrl = thumbUrl.substring(thumbUrl.indexOf('=')+1,thumbUrl.indexOf('&'));
var json = setmsg(imageUrl);
var strReturn = window.external.PutMsg(json);
document.getElementById('putmsgret').innerHTML= 'Status: ' + strReturn;
setTimeout(close_tips,3000);
});
/*ul.on('mouseenter mouseout', ".img",function(event) {
var $li = $(this).parents("li");
if (event.type == 'mouseenter') {
$li.css({background:'#EDED00'});
} else {
$li.css({background:'#FFF'});
}
});*/
function close_tips(){
document.getElementById('putmsgret').innerHTML = '';
}
function setmsg(imageUrl) {
var json = {
msg:{
head:{
random:(new Date()).valueOf().toString()
},
body:[{
type:1,
content:{
picUrl:imageUrl
}
}]
}
};
return JSON.stringify(json);
}
function OnUserChange(data) {
document.getElementById('toUser').innerHTML = data['userid'];
}
function strToJson(str){
var json = (new Function("return " + str))();
return json;
}
</script>
</body>
</html>
三、后台PHP要处理的获取图片目录的代码:(这个自由发挥了)
<?php
class GetImage {
const
HOST = 'http://www.wp83.net/',
JPG = 'jpg';
public
$files = array();
protected static
$allow_types = array(self::JPG);
public function __construct($dir){
$this->get_allfiles($dir, $this->files);
}
private function get_allfiles($path,&$files) {
if(is_dir($path)){
$dp = dir($path);
while ($file = $dp ->read()){
if($file !="." && $file !=".."){
$this->get_allfiles($path."/".$file, $files);
}
}
$dp ->close();
}
if(is_file($path)){
$type = substr($path,-3);
if(in_array($type, self::$allow_types))
$files[] = self::HOST.$path;
}
}
}
$dir = 'wp-content/uploads';
$images = new GetImage($dir);
echo json_encode($images->files);
然后我们可以直接用浏览器调试运行没问题,再去微信后台设置插件的url。因为它只是个html
在浏览器调试效果:
点选图片后发送效果:
微信在1月6日时放出了新的数据分析接口传送门:
请注意:
1、接口侧的公众号数据的数据库中仅存储了2014年12月1日之后的数据,将查询不到在此之前的日期,即使有查到,也是不可信的脏数据;
2、请开发者在调用接口获取数据后,将数据保存在自身数据库中,即加快下次用户的访问速度,也降低了微信侧接口调用的不必要损耗。
用户分析数据接口指的是用于获得公众平台官网数据统计模块中用户分析数据的接口,具体接口列表如下(暂无用户属性数据接口):
最大时间跨度是指一次接口调用时最大可获取数据的时间范围,如最大时间跨度为7是指最多一次性获取7天的数据。access_token的实际值请通过“获取access_token”来获取。
接口调用请求说明
用户分析数据接口(包括接口列表中的所有接口)需要向相应接口调用地址POST以下示例数据包:
{
"begin_date": "2014-12-02",
"end_date": "2014-12-07"
}
调用参数说明
粗略看了下,暂时还是内测阶段,不过因为是新接口,所以要改进下本站所用的微信高级接口的类。修改如下:
在类里加上新接口常量:
API_DATA_CUBE_URL = 'https://api.weixin.qq.com/datacube',
API_TYPE_DATA = 'datacube',
修改call方法:因为它要求URL参数只是access token所以跟以前JSON时一样,不过要在判断里加入datacube的判断(注:注释已经说明):
public function call($api_name, $params = array(), $type = self::GET, $api_type = self::API_TYPE_CGI) {
//加入datacube后,用switch来组接口URL
switch(true) {
case $api_type == self::API_TYPE_PAY :
$url = self::PAY_URL.$api_name;
break;
case $api_type == self::API_TYPE_DATA:
$url = self::API_DATA_CUBE_URL.$api_name;
break;
default :
$url = self::API_URL_PREFIX.$api_name;
}
if (in_array($api_name, self::$_no_need_token_apis)) {
$res = $this->request($url, $params, $type);
if ($res) {
return $res;
}
}
$this->_access_token = $this->getAccessToken();
if ($this->_access_token) {
//加多个or判断带上access_token
if ($type == self::JSON || $api_type == self::API_TYPE_DATA) {
$url = $url.'?access_token='.$this->_access_token;
} else {
$params['access_token'] = $this->_access_token;
}
$res = $this->request($url, $params, $type);
if ($res) {
return $res;
}
}
return false;
}
最后CLI方式call文档中一个getinterfacesummary接口调试(注意:是POST方式给接口):
if (isset($argc) && $argc >= 1 && $argv[0] == __FILE__) {
$client = new WechatJSON(array(
WechatJSON::APP_ID => 'wx78sfsd023744d51',
WechatJSON::APP_SECRET => '9ba3476db1fsfsff512esf2f630fb9',
));
$res = $client->call('/getinterfacesummary', array(
'begin_date' => '2014-12-01',
'end_date' => '2014-12-31'
), WechatJSON::POST, WechatJSON::API_TYPE_DATA);
if (!$res) {
var_dump($client->_error);
}
var_dump($res);
}
运行结果,虽然是API 未授权(毕竟还是内测有条件的合作伙伴有资料,公众号的就等吧):
后记,以后再做个linux任务让后台自己每隔一段时间(一周或30天)因为数据统计接口有的是7天,有的是30天。这样执行取到数据再写进库表,生成图报表,省下自己log一些官方已经给你log的统计!
测试地址为:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的appid&redirect_uri=http://www.111cn.net /wx_agentAdd.php?response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect
我们直接在浏览器中打开此地址你会看到
Oops! Something went wrong:(
这个问题包括所有浏览器打开都会这样只能从微信中打开才会正常,包括我们pc版微信登录也是一样的。
这个支付类是根据官方的文档修改而来!主要实现生成JS API 、Native的package签名包和Native响应的XML格式数据。注释都标上了各方法的用意。由于package包签名,略复杂,这个要自己多花时间去对应去看和log出文件来一一对比!当然只要你用上教程的类,设置好对应的参数就可以正确的生成package参数等
<?php
if (isset($argc) && $argc >= 1 && $argv[0] == __FILE__) {
//初始化pay的必要信息
$pay = new WechatPay(array(
WechatPay::APPID => 'wx99dabzpiuq83985b8',
WechatPay::APPSERCER => 'ac12e7e4abaer63hkoa0cc36a9663fa',
WechatPay::PARTNERKEY => 'bae4sfa3562rsfaq23s2045',
WechatPay::PARTNERID => '1268969802',
WechatPay::PAYSIGNKEY => '9Fqsxb3PK4IVOCEc4yCquy5zecS9LeeMjF2Nn4B4YKoOxPwaQdFwMezKT8oNlBYaWcuT',
WechatPay::SIGNTYPE => 'sha1',
));
//设置package 必要的参数 jsapi native都通用
$pay->setParams(WechatPay::BANK_TYPE, "WX");
$pay->setParams(WechatPay::BODY, "test");
$pay->setParams(WechatPay::PARTNER, $pay->partnerid);
$pay->setParams(WechatPay::OUT_TRADE_NO, commonUtil::createNoncestr());
$pay->setParams(WechatPay::TOTAL_FEE, "1");
$pay->setParams(WechatPay::FEE_TYPE, "1");
$pay->setParams(WechatPay::TIMESTAMP, time());
$pay->setParams(WechatPay::NOTIFY_URL, "http://www.demo.com/notify");
$pay->setParams(WechatPay::SPBILL_CREATE_IP, "127.0.0.1");
$pay->setParams(WechatPay::INPUT_CHARSET, "UTF-8");
//JSAPI的签名json
print_r($pay->createJsApiPackage());
//生成native XML
print_r($pay->createNativePackage());
//生成native URL
print_r($pay->createNativeUrl("9701"));
}
JS API生成的package签名包参数:
{
"appId":"wx9998ff5f4dede5b7",
"package":"bank_type=WX&body=test&fee_type=1&input_charset=UTF-8¬ify_url=http%3A%2F%2Fwww.demo.com%2Fnotify&out_trade_no=Vf5qsSwtu0hc2loH&partner=wx9998ff5f4dede5b7&spbill_create_ip=127.0.0.1×tamp=1409295711&total_fee=1&sign=FEE0167BD0D89A88BF6850590EA889B6",
"timeStamp":1409295711,
"nonceStr":"Vf5qsSwtu0hc2loH",
"paySign":"f816264c750923863c370a1739640244b0c2d39c",
"signType":"sha1"
}
Native 响应的XML格式:
<xml>
<AppId><![CDATA[wx9998ff5f4dede5b7]]></AppId>
<Package>
<![CDATA[bank_type=WX&body=test&fee_type=1&input_charset=UTF-8¬ify_url=http%3A%2F%2Fwww.demo.com%2Fnotify&out_trade_no=GDl3what4sALDEAd&partner=wx9998ff5f4dede5b7&spbill_create_ip=127.0.0.1×tamp=1409296124&total_fee=1&sign=BF949B85570644B939B369FD44B0C4A9]]>
</Package>
<TimeStamp>1409296124</TimeStamp>
<NonceStr><![CDATA[GDl3what4sALDEAd]]></NonceStr>
<RetCode>0</RetCode>
<RetErrMsg><![CDATA[ok]]></RetErrMsg>
<AppSignature><![CDATA[ca4a2467b817a62c38a9801fcf451f51692027bf]]></AppSignature>
<SignMethod><![CDATA[sha1]]></SignMethod>
</xml>
Native的URL链接:
weixin://wxpay/bizpayurl?appid=wx9998ff5f4dede5b7&noncestr=VY7cVA6mtVrc1BVq&productid=9701&sign=43508b65b50e1d7e1089be66d55a709469155d73×tamp=1409296323
无论哪一种方式,我们都要通过setParams来设置必要初始化参数和商品价格和状态等!
WechatPay class:
<?php
class WechatPay {
const
BANK_TYPE = 'bank_type',
BODY = 'body',
PARTNER = 'partner',
OUT_TRADE_NO = 'out_trade_no',
TIMESTAMP = 'timestamp',
TOTAL_FEE = 'total_fee',
FEE_TYPE = 'fee_type',
NOTIFY_URL = 'notify_url',
SPBILL_CREATE_IP = 'spbill_create_ip',
INPUT_CHARSET = 'input_charset',
APPID = 'appid',
APPSERCER = 'appsercer',
PAYSIGNKEY = 'appkey',
PARTNERID = 'partnerid',
PARTNERKEY = 'partnerkey',
SIGNTYPE = 'signtype';
public
$params = array(), $partnerid = '';
static protected
$_instance;
protected
$_appid, $_appkey, $_signtype, $_partnerkey, $_appsercer;
static public function getInstance(array $options = array()) {
if (empty(self::$_instance)) {
self::$_instance = new self ($options);
}
return self::$_instance;
}
public function __construct(array $options = array()){
$this->_appid = $options[self::APPID];
$this->_appkey = $options[self::PAYSIGNKEY];
$this->_signtype = $options[self::SIGNTYPE];
$this->_partnerkey = $options[self::PARTNERKEY];
$this->_appsercer = $options[self::APPSERCER];
$this->partnerid = $options[self::APPID];
}
public function setParams($param, $paramValue) {
$this->params[CommonUtil::trimString($param)] = CommonUtil::trimString($paramValue);
}
public function getParams($param) {
return $this->params[$param];
}
protected function createNoncestr( $length = 16 ) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$str ="";
for ( $i = 0; $i < $length; $i++ ) {
$str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}
public function checkParams(){
//必要的9个参与签名的参数
if($this->params[self::BANK_TYPE] == null || $this->params[self::BODY] == null || $this->params[self::PARTNER] == null ||
$this->params[self::OUT_TRADE_NO] == null || $this->params[self::TOTAL_FEE] == null || $this->params[self::FEE_TYPE] == null ||
$this->params[self::NOTIFY_URL] == null || $this->params[self::SPBILL_CREATE_IP] == null || $this->params[self::INPUT_CHARSET] == null
) {
return false;
}
return true;
}
/*
* 生成package包
* @params 初始化类时用setParams方法定义必要的9个参数
* 排序后格式化url query形式 再md5SignUtil类签名,再给合URL
*/
protected function getPackageSign(){
try {
if (null == $this->_partnerkey || "" == $this->_partnerkey ) {
throw new Exception("密钥不能为空!" . "<br>");
}
$commonUtil = new CommonUtil();
ksort($this->params);
$unSignParaString = $commonUtil->formatUrlQuery($this->params, false);
$paraString = $commonUtil->formatUrlQuery($this->params, true);
$md5SignUtil = new MD5SignUtil();
return $paraString . "&sign=" . $md5SignUtil->sign($unSignParaString,commonUtil::trimString($this->_partnerkey));
} catch (Exception $e) {
echo ($e->getMessage());
}
}
/*
* 生成签名方法
* @params appid appkey package timestamp noncestr 等参数而native事例代码中加上retcode reterrmsg两个参数
*/
public function getPaySign($signObj){
foreach ($signObj as $k => $v){
$signParams[strtolower($k)] = $v;
}
try {
if ($this->_appkey == "") {
throw new Exception("APPKEY为空!" . "<br>");
}
$signParams["appkey"] = $this->_appkey;
ksort($signParams, SORT_STRING);
$commonUtil = new CommonUtil();
$signString = $commonUtil->formatPayUrlQuery($signParams, false);
return sha1($signString);
} catch (Exception $e) {
echo ($e->getMessage());
}
}
//JS API 签名 其中nonceStr是作为订单号 灌穿整个支付流程
public function createJsApiPackage(){
try {
if($this->checkParams() == false) {
throw new Exception("生成package参数缺失!" . "<br>");
}
$payObj["appId"] = $this->_appid;
$payObj["package"] = $this->getPackageSign();
$payObj["timeStamp"] = $this->getParams(self::TIMESTAMP);
$payObj["nonceStr"] = $this->getParams(self::OUT_TRADE_NO);
$payObj["paySign"] = $this->getPaySign($payObj);
$payObj["signType"] = $this->_signtype;
return json_encode($payObj);
} catch (Exception $e) {
die($e->getMessage());
}
}
/*
* 构建发货状态数组 主要三个参数openid transid orderid
*/
public function createDeliverPost(Array $params) {
$deliver = array();
$deliver['appid'] = $this->_appid;
$deliver['openid'] = $params['openid'];
$deliver['transid'] = $params['transid'];
$deliver['out_trade_no'] = $params['out_trade_no'];
$deliver['deliver_timestamp'] = current_time('timestamp');
$deliver['deliver_status'] = 1;
$deliver['deliver_msg'] = 'OK';
$deliver['app_signature'] = $this->getPaySign($deliver);
$deliver['sign_method'] = 'sha1';
return $deliver;
}
/*
* 生成扫描或者点击原生URL后,响应的XML格式
* @params $retcode $reterrmsg 定义该商品的状态
*/
public function createNativePackage($retcode = 0, $reterrmsg = "ok") {
try {
if ($this->checkParams() == false && $retcode == 0) { //如果是正常的返回, 检查财付通的参数
throw new Exception("生成package参数缺失!" . "<br>");
}
$nativeObj["AppId"] = $this->_appid;
$nativeObj["Package"] = $this->getPackageSign();
$nativeObj["TimeStamp"] = $this->getParams(self::TIMESTAMP);
$nativeObj["NonceStr"] = $this->getParams(self::OUT_TRADE_NO);
$nativeObj["RetCode"] = $retcode;
$nativeObj["RetErrMsg"] = $reterrmsg;
$nativeObj["AppSignature"] = $this->getPaySign($nativeObj);
$nativeObj["SignMethod"] = $this->_signtype;
$commonUtil = new CommonUtil();
$xml = $commonUtil->arrayToXml($nativeObj);
exit($xml);
}catch (Exception $e) {
echo ($e->getMessage());
}
}
/*
* 生成原生URL 以订单号为参数 这是灌穿整个支付流程
*/
public function createNativeUrl($productid) {
$commonUtil = new CommonUtil();
$nativeObj["appid"] = $this->_appid;
$nativeObj["productid"] = urlencode($productid);
$nativeObj["timestamp"] = time();
$nativeObj["nonceStr"] = commonUtil::createNoncestr();
$nativeObj["sign"] = $this->getPaySign($nativeObj);
$nativeString = $commonUtil->formatPayUrlQuery($nativeObj, false);
return "weixin://wxpay/bizpayurl?".$nativeString;
}
/*
* 取IP地址
*/
public function getIp(){
switch(true) {
case !empty($_SERVER["HTTP_CLIENT_IP"]):
$ip = $_SERVER["HTTP_CLIENT_IP"];
break;
case !empty($_SERVER["HTTP_X_FORWARDED_FOR"]):
$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
break;
case !empty($_SERVER["REMOTE_ADDR"]):
$ip = $_SERVER["REMOTE_ADDR"];
break;
default:
$ip = "127.0.0.1";
}
return $ip;
}
}
class MD5SignUtil {
public function sign($content, $key) {
try {
if (null == $key) {
throw new Exception("财付通签名key不能为空!" . "<br>");
}
if (null == $content) {
throw new Exception("财付通签名内容不能为空" . "<br>");
}
$signStr = $content . "&key=" . $key;
return strtoupper(md5($signStr));
} catch (Exception $e) {
echo ($e->getMessage());
}
}
public static function verifySignature($content, $sign, $md5Key) {
$signStr = $content . "&key=" . $md5Key;
$calculateSign = strtolower(md5($signStr));
$tenpaySign = strtolower($sign);
return $calculateSign == $tenpaySign;
}
}
class CommonUtil {
public function genAllUrl($toURL, $paras) {
$allUrl = null;
if (null == $toURL) {
die("toURL is null");
}
if (strripos($toURL,"?") =="") {
$allUrl = $toURL . "?" . $paras;
} else {
$allUrl = $toURL . "&" . $paras;
}
return $allUrl;
}
//订单号,可根据实际自定义
static public function createOrderNo() {
$nonce = CommonUtil::createNoncestr(4);
return strtoupper(date('ymds').substr(microtime(),2,4).$nonce);
}
//随机字符串
static public function createNoncestr( $length = 16 ) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$str ="";
for ( $i = 0; $i < $length; $i++ ) {
$str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}
public function splitParaStr($src, $token) {
$resMap = array();
$items = explode($token,$src);
foreach ($items as $item){
$paraAndValue = explode("=",$item);
if ($paraAndValue != "") {
$resMap[$paraAndValue[0]] = $paraAndValue[1];
}
}
return $resMap;
}
static function trimString($value) {
$ret = null;
if (null != $value) {
$ret = $value;
if (strlen($ret) == 0) {
$ret = null;
}
}
return $ret;
}
public function formatUrlQuery($paraMap, $urlencode) {
$buff = "";
ksort($paraMap, SORT_STRING);
foreach ($paraMap as $k => $v) {
if (null != $v && "null" != $v && "sign" != $k) {
if($urlencode) {
$v = urlencode($v);
}
$buff .= $k . "=" . $v . "&";
}
}
$reqPar = '';
if (strlen($buff) > 0) {
$reqPar = substr($buff, 0, strlen($buff)-1);
}
return $reqPar;
}
public function formatPayUrlQuery($paraMap, $urlencode) {
$buff = "";
ksort($paraMap, SORT_STRING);
foreach ($paraMap as $k => $v) {
if($urlencode){
$v = urlencode($v);
}
$buff .= strtolower($k) . "=" . $v . "&";
}
$reqPar = '';
if (strlen($buff) > 0) {
$reqPar = substr($buff, 0, strlen($buff)-1);
}
return $reqPar;
}
/*
* 输出一级数组的xml格式
*/
public function arrayToXml($arr) {
$xml = "<xml>";
foreach ($arr as $key=>$val) {
if ($key == 'TimeStamp' || $key == 'RetCode') {
$xml.="<".$key.">".$val."</".$key.">";
} else
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
$xml .= "</xml>";
return $xml;
}
}
微信JSSDK的图片接口,能让我们轻松实现上传功能。继续做例子,我们先更新下wx.config的jsApiList数组加入四个’chooseImage’, ‘uploadImage’, ‘downloadImage’, ‘previewImage’。
继续用thinkphp做框架,首先们们新建Layout/image.phtml:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<link href="__PUBLIC__/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
{__CONTENT__}
</body>
<script type="text/javascript">
window.jQuery || document.write("<script src='__PUBLIC__/js/jquery-1.10.2.min.js'>"+"<"+"/script>");
</script>
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script>
wx.config({
debug: false,
appId: '{$signPackage["appId"]}',
timestamp: {$signPackage["timestamp"]},
nonceStr: '{$signPackage["nonceStr"]}',
signature: '{$signPackage["signature"]}',
jsApiList: [
'checkJsApi',
'chooseImage',
'uploadImage',
'downloadImage',
'previewImage'
]
});
wx.ready(function () {
var images = {
localId: [],
serverId: [],
downloadId: []
};
document.querySelector('#selectImage').onclick = function () {
wx.chooseImage({
success: function (res) {
images.localId = res.localIds;
jQuery(function(){
$.each( res.localIds, function(i, n){
$("#img").append('<img src="'+n+'" /> <br />');
});
});
}
});
};
document.querySelector('#uploadImage').onclick = function () {
if (images.localId.length == 0) {
alert('请先使用选择图片按钮');
return;
}
images.serverId = [];
jQuery(function(){
$.each(images.localId, function(i,n) {
wx.uploadImage({
localId: n,
success: function (res) {
images.serverId.push(res.serverId);
},
fail: function (res) {
alert(JSON.stringify(res));
}
});
});
});
};
document.querySelector('#downloadImage').onclick = function () {
if (images.serverId.length == 0) {
alert('请先按上传图片按钮');
return;
}
jQuery(function() {
$.each(images.serverId, function (i, n) {
wx.downloadImage({
serverId: n,
success: function (res) {
images.downloadId.push(res.localId);
}
});
});
$.each( images.downloadId, function(i, n){
$("#img2").append('<img src="'+n+'" /> <br />');
});
});
};
document.querySelector('#previewImage').onclick = function () {
var imgList = [
'__PUBLIC__/images/gallery/image-1.jpg',
'__PUBLIC__/images/gallery/image-2.jpg'
];
wx.previewImage({
current: imgList[0],
urls: imgList
});
};
});
wx.error(function(res){
var str = res.errMsg;
var reg = /invalid signature$/;
var r = str.match(reg);
if(r !== null) {
jQuery(function(){
$.getJSON('http://www.demo.com/tp/home/index/ticket', function(data) {
if(data) {
alert('ticket update');
location = location;
window.navigate(location);
}
});
});
}
});
</script>
</html>
新建视图views/Index/image.phtml:
<style>
.text-center {text-align: center;}
.btn-hight {height:100px;width:230px;}
#img img{width:200px;}
</style>
<div class="col-lg-12 col-sm-12" style="margin: 12px auto 10px;">
<div class="form-group text-center">
<button id="selectImage" type="button" class="btn btn-primary btn-hight"><h2>选择图片</h2></button>
</div>
<div class="form-group text-center">
<div id="img"></div>
</div>
<div class="form-group text-center">
<button id="uploadImage" type="button" class="btn btn-primary btn-hight"><h2>上传图片</h2></button>
</div>
<div class="form-group text-center">
<button id="downloadImage" type="button" class="btn btn-primary btn-hight"><h2>下载图片</h2></button>
</div>
<div class="form-group text-center">
<div id="img2"></div>
</div>
<div class="form-group text-center">
<button id="previewImage" type="button" class="btn btn-primary btn-hight"><h2>预览图片</h2></button>
</div>
</div>
Controller就加入一个imageAction:
public function imageAction() {
layout('Layout/image');
$this->display();
}
选择图片接口效果图:
上传和下载接口的效果图:(注 这里是先上传接口取到media_id再调下载图片接口显示出来,请看layout的js代码)
预览图片接口效果图:
相关文章
- 这篇文章主要为大家详细介绍了C#微信开发之发送模板消息的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
jQuery Mobile开发中日期插件Mobiscroll使用说明
这篇文章主要介绍了jQuery Mobile开发中日期插件Mobiscroll使用说明,需要的朋友可以参考下...2016-03-03- 在页面开发中,经常遇到需要用户输入日期的操作。通常的做法是,提供一个文本框(text),让用户输入,然后,编写代码验证输入的数据,检测其是否是日期类型。这样比较麻烦,同时,用户输入日期的操作也不是很方便,影响用户体验。如果使...2015-10-30
- 这篇文章主要介绍了iOS新版微信底部返回横条问题的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-30
- 一个简单的jQuery分页插件,兼容AMD规范和requireJS./** * jQuery分页插件 * */;(function (factory) { if (typeof define === "function" && define.amd) { // AMD模式 define([ "jquery" ], factory); } els...2015-11-08
vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件
这篇文章主要介绍了vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下...2021-02-20- 为公司系统业务需要,这几天了解了一下微信和支付宝扫码支付的接口,并用c#实现了微信和支付宝扫码支付的功能。需要的朋友跟随小编一起看看吧...2020-06-25
- 这篇文章主要为大家分享了Bootstrap教程JS插件滚动监听学习笔记,内容很详细,感兴趣的小伙伴们可以参考一下...2016-05-20
- 这篇文章主要介绍了Python爬取微信小程序通用方法代码实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-29
- 这篇文章主要介绍了C#实现的微信网页授权操作逻辑封装,分析了微信网页授权操作的原理、步骤并给出了C#实现的网页授权操作逻辑封装类,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了iOS新版微信底部工具栏遮挡问题完美解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-30
- 这篇文章主要为大家详细介绍了C#图像识别,微信跳一跳机器人,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要为大家详细介绍了jquery插表单件form使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2017-01-23
- 这篇文章主要介绍了jquery自定义插件开发之window的实现过程的相关资料,需要的朋友可以参考下...2016-05-09
- 这篇文章主要介绍了vue中使用swiper 插件出错问题及解决办法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-08-22
- Query架构的开发人员能够创建一个插件代码来扩展其功能,从而能够产生一些最好的插件,让你的网站或任何给定的项目达到一个全新的水平。 ...2016-04-27
解决jquery插件:TypeError:$.browser is undefined报错的方法
首先先说一说$.browser browser就是用来获取浏览器基本信息的。 jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version , 取而代之的是 $.support 。 在更新的 2.0 版本中,将不再支持 IE 6/7/8。 以后,如果用户需...2015-11-24IntelliJ IDEA 刷题利器 LeetCode 插件详解
这篇文章主要介绍了IntelliJ IDEA 刷题利器 LeetCode 插件,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-08-21- 通过jquery.cookie.js插件可以快速实现“点击获取验证码后60秒内禁止重新获取(防刷新)”的功能效果图:先到官网(http://plugins.jquery.com/cookie/)下载cookie插件,放到相应文件夹,代码如下:复制代码 代码如下: <!DOCTYPE ht...2015-03-15
JS基于ocanvas插件实现的简单画板效果代码(附demo源码下载)
这篇文章主要介绍了JS基于ocanvas插件实现的简单画板效果,结合实例形式分析了ocanvas插件实现画板的相关技巧,并附代码demo源码供读者下载参考,需要的朋友可以参考下...2016-04-06