<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>微信 on 分享技术带来的喜悦</title><link>https://bridgeli.cn/categories/%E5%BE%AE%E4%BF%A1/</link><description>Recent content in 微信 on 分享技术带来的喜悦</description><generator>Hugo -- 0.156.0</generator><language>zh-cn</language><lastBuildDate>Sun, 15 Mar 2015 14:17:09 +0000</lastBuildDate><atom:link href="https://bridgeli.cn/categories/%E5%BE%AE%E4%BF%A1/index.xml" rel="self" type="application/rss+xml"/><item><title>微信JS SDK Demo（Java版）</title><link>https://bridgeli.cn/posts/2015-03-15-%E5%BE%AE%E4%BF%A1js-sdkdemojava%E7%89%88/</link><pubDate>Sun, 15 Mar 2015 14:17:09 +0000</pubDate><guid>https://bridgeli.cn/posts/2015-03-15-%E5%BE%AE%E4%BF%A1js-sdkdemojava%E7%89%88/</guid><description>&lt;p&gt;前几天在公司开发一个功能：微信分享，要求是分享的不是用户当前看到的这个页面，大家知道这在以前其实很简单的，但去年的最后一天，微信大力打击诱导分享、关注之后，以前的分享就不能用了，好在后来微信开放了JS SDK接口，可以满足这个需求，由于网上的例子写的都很简单，而且大多都是php，今天老夫就记录一下自己用Java如何实现的这个功能，窃以为比网上的很多Demo更具有实用性，大家在使用中如果有什么疑问，欢迎留言交流。废话到此为止，下面看看如何实现，当然了首先肯定要参考微信的文档：http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html，其实这个文档上面说的已经比较详细了，但是距离真正使用当然还是有一定的距离的，在说老夫的代码之前，再多说一句，想调用微信的JS SDK，请确保你有一个经过微信认证的服务号，否则你是调用不了的，好，下面就看代码了：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$(&amp;amp;#8216;.share&amp;amp;#8217;).tap(function(){
var urlCurrery = window.location.href.split(&amp;amp;#8216;#&amp;amp;#8217;)[0];
$.ajax({
type : &amp;#34;post&amp;#34;,
url : &amp;amp;#8216;share.do&amp;amp;#8217;,
data : {&amp;amp;#8216;urlCurrery&amp;amp;#8217;:urlCurrery},
success : function(data) {
var dataObj = eval(data)[0];
var url =dataObj.url;
var jsapi_ticket =dataObj.jsapi_ticket;
var nonce_str =dataObj.nonceStr;
var timestamp =dataObj.timestamp;
var signature =dataObj.signature;
wx.config({
debug: true,
appId: appId;,
timestamp: timestamp,
nonceStr: nonce_str,
signature: signature,
jsApiList: [
&amp;amp;#8216;checkJsApi&amp;amp;#8217;,
&amp;amp;#8216;onMenuShareTimeline&amp;amp;#8217;,
&amp;amp;#8216;onMenuShareAppMessage&amp;amp;#8217;
]
});
wx.ready(function () {
wx.onMenuShareAppMessage({
title: &amp;amp;#8216;分享测试&amp;amp;#8217;,
desc: &amp;amp;#8216;分享测试&amp;amp;#8217;,
link: &amp;amp;#8216;https://bridgeli.cn&amp;amp;#8217;,
imgUrl: &amp;amp;#8221;,
success: function (res) {
alert(&amp;amp;#8216;已分享&amp;amp;#8217;);
}
});
wx.onMenuShareTimeline({
title: &amp;amp;#8216;分享测试&amp;amp;#8217;,
link: &amp;amp;#8216;https://bridgeli.cn&amp;amp;#8217;,
imgUrl: &amp;amp;#8221;,
success: function (res) {
alert(&amp;amp;#8216;已分享&amp;amp;#8217;);
}
});
alert(&amp;amp;#8216;已注册获取“发送给朋友”状态事件&amp;amp;#8217;);
alert(&amp;amp;#8216;已注册获取“分享到朋友圈”状态事件&amp;amp;#8217;);
});
}
});
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;经过分析微信的文档我们知道：如果想使用分享功能，那么请给分享注册事件，所以我们这里给文本中一个class为：share 的dom，绑定了分享事件，也就是说，我们想改变分享url，必须先点击一下该button，否则是不行的；另外通过文档里面的常见错误，我们可以知道，参与签名的url必须是动态获取的，如果不是，请通过ajax传到后台，为了强调这一点，微信专门用红色标注了，所以老夫在给class为share的button绑定事件的同时，将当前页面的 url （文中用：urlCurrery表示的）通用ajax传到后台 share.do 参与签名，我们一会再说后台怎么实现，接着分析前台代码，在经过后台签名之后，后台会传给前台一些数据，封装在data里面，这些就是我们需要的数据，相信通过微信的文档，所有人都能看得明白，就不多做解释了，在 wx.ready()方法里，老夫举了两个例子分别是分享给朋友和分享到朋友圈，其中的参数 link 就是你要分享的 url ，这一点很重要，这样就实现了我们分析的不是当前页面的 url 的需求，好了前台的说完了，下面就要看后台是怎么实现的了，这个其实很简单&lt;/p&gt;</description></item><item><title>别人抢红包，程序猿来探讨微信红包的算法实现</title><link>https://bridgeli.cn/posts/2015-02-25-%E5%88%AB%E4%BA%BA%E6%8A%A2%E7%BA%A2%E5%8C%85%E7%A8%8B%E5%BA%8F%E7%8C%BF%E6%9D%A5%E6%8E%A2%E8%AE%A8%E5%BE%AE%E4%BF%A1%E7%BA%A2%E5%8C%85%E7%9A%84%E7%AE%97%E6%B3%95%E5%AE%9E%E7%8E%B0/</link><pubDate>Wed, 25 Feb 2015 09:24:43 +0000</pubDate><guid>https://bridgeli.cn/posts/2015-02-25-%E5%88%AB%E4%BA%BA%E6%8A%A2%E7%BA%A2%E5%8C%85%E7%A8%8B%E5%BA%8F%E7%8C%BF%E6%9D%A5%E6%8E%A2%E8%AE%A8%E5%BE%AE%E4%BF%A1%E7%BA%A2%E5%8C%85%E7%9A%84%E7%AE%97%E6%B3%95%E5%AE%9E%E7%8E%B0/</guid><description>&lt;p&gt;曾经在公司写过一个类似于微信抢红包的功能，当时由于不会写，各种纠结，虽然最终实现了功能，但也仅仅是实现功能而已，像腾讯这么牛的公司肯定不是那样的，那么腾讯是怎么实现的呢？一直很好奇，但一直不得要领，今天偶然发现一篇文章，作者用很简单的算法，算是比较完美的解决了这个问题，说是完美，因为该算法满足了：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1、每个人都要能够领取到红包；&lt;br&gt;
2、每个人领取到的红包金额总和=总金额；&lt;br&gt;
3、每个人领取到的红包金额不等，但也不能差的太离谱，不然就没趣味；&lt;br&gt;
4、算法一定要简单，不然对不起腾讯这个招牌；&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;但由于原文是Python写的（老夫的推测，因为老夫并不会Python，本文底部注有链接，感兴趣的可以看看），老夫改为由Java实现，当然介于水平，实现的可能并不好，写在这里算是抛砖引玉，如果有牛人写出来更好的，欢迎留言交流&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;package cn.bridgeli.hongbao;
public class HongBao {
public static void fenPei(double totalMoney, int totalPerson) {
double min = 0.01;
for (int i = 1; i &amp;lt; totalPerson; i++) {
// 随机安全上限，同时扩大 100 倍
double safeTotal = ((totalMoney &amp;amp;#8211; (totalPerson &amp;amp;#8211; i) \* min) / (totalPerson &amp;amp;#8211; i)) \* 100;
// 生成随机钱数
double money = Math.floor(Math.random() * safeTotal + 1.0) / 100;
totalMoney -= money;
System.out.println(&amp;#34;第&amp;#34; + i + &amp;#34;个红包：&amp;#34; + money + &amp;#34; 元&amp;#34;);
}
System.out.println(&amp;#34;第&amp;#34; + totalPerson + &amp;#34;个红包：&amp;#34; + roundDouble(totalMoney) + &amp;#34; 元&amp;#34;);
}
// 四舍五入
private static Double roundDouble(double val) {
Double ret = null;
try {
// 2 表示保留两位小数
double factor = Math.pow(10, 2);
ret = Math.floor(val * factor + 0.5) / factor;
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;参考资料：http://mp.weixin.qq.com/s?__biz=MjM5OTA1MDUyMA==&amp;amp;mid=204349860&amp;amp;idx=2&amp;amp;sn=0a3433ff34c08dca5c47f7d97301e118#rd&lt;/p&gt;</description></item><item><title>反射的简单应用：解决微信开发中if-else过多的问题</title><link>https://bridgeli.cn/posts/2014-09-15-%E5%8F%8D%E5%B0%84%E7%9A%84%E7%AE%80%E5%8D%95%E5%BA%94%E7%94%A8%E8%A7%A3%E5%86%B3%E5%BE%AE%E4%BF%A1%E5%BC%80%E5%8F%91%E4%B8%ADif-else%E8%BF%87%E5%A4%9A%E7%9A%84%E9%97%AE%E9%A2%98/</link><pubDate>Mon, 15 Sep 2014 14:44:38 +0000</pubDate><guid>https://bridgeli.cn/posts/2014-09-15-%E5%8F%8D%E5%B0%84%E7%9A%84%E7%AE%80%E5%8D%95%E5%BA%94%E7%94%A8%E8%A7%A3%E5%86%B3%E5%BE%AE%E4%BF%A1%E5%BC%80%E5%8F%91%E4%B8%ADif-else%E8%BF%87%E5%A4%9A%E7%9A%84%E9%97%AE%E9%A2%98/</guid><description>&lt;p&gt;前一段时间，闲着无聊玩微信开发，遇到一个问题：当关注者向公众号发送消息，请求一些服务时，由于是文本消息，所以当公众号拿到消息内容时，必须判断消息以什么打头，即：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;
String content = requestMap.get(&amp;#34;Content&amp;#34;).trim();
if (&amp;#34;?&amp;#34;.equals(content) || &amp;#34;？&amp;#34;.equals(content)) {
respContent = &amp;#34;您好，我是生活小助手，请根据提示，回复内容选择服务：nn1 回复“天气”获取天气帮助n2 回复“歌曲”获取歌曲帮助n3 回复“公交”获取歌曲帮助n4 回复“火车”获取歌曲帮助&amp;#34;;
} else if (content.startsWith(&amp;#34;歌曲&amp;#34;)) {
//TODO
} else if (content.startsWith(&amp;#34;天气&amp;#34;)) {
//TODO
} else if (content.startsWith(&amp;#34;物流&amp;#34;)) {
//TODO
} else if (content.startsWith(&amp;#34;公交&amp;#34;)) {
//TODO
} else if (content.startsWith(&amp;#34;火车&amp;#34;)) {
//TODO
} else {
respContent = &amp;#34;亲，很抱歉，由于功能还不够完善，尚不能处理您回复的信息，请回复“？”显示主菜单，获取帮助，有此给您带来的不便，还请见谅！&amp;#34;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;来判断何种服务，调用具体的接口来处理，当你的功能越来越完善时，会导致if-else越来越多，多的会自己都搞不清了，另外这个方法也会越来越大，显然不是非常符合面向对象的单一职责原则。那么有没用一个比较好的方法来解决这个问题呢？我曾经的项目经理Zack曾经说过，上天不会这么惩罚一个后期维护代码的人，所以答案是勘定有，今天老夫就给大家带来一个解决方法，需要说明的是：这不是老夫的原创，是老夫研究捷微源码的找到的方法，老夫在捷微方法的基础上做了一些修改，所以先感谢捷微，感谢捷微的开发人员。最后需要说明的是，这个方法也不是很完善，如果有人参考的话，老样子，请做具体修改，但逻辑老夫保证不会有错。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;
@Override
public BaseMessage handleText(String content, String fromUsername, String toUsername) {
String respContent = null;
BaseMessage baseMessage = null;
if (&amp;#34;?&amp;#34;.equals(content) || &amp;#34;？&amp;#34;.equals(content)) {
respContent = &amp;#34;您好，我是生活小助手，请根据提示，回复内容选择服务：nn1 回复“天气”获取天气帮助n2 回复“歌曲”获取歌曲帮助n3 回复“公交”获取公交帮助n4 回复“火车”获取火车帮助&amp;#34;;
} else {
List&amp;lt;WeixinExpandconfigEntity&amp;gt; weixinExpandconfigEntities = new ArrayList&amp;lt;WeixinExpandconfigEntity&amp;gt;();
boolean isFind = false;// 是否找到关键字信息
for (WeixinExpandconfigEntity weixinExpandconfigEntity : weixinExpandconfigEntities) {
// 如果已经找到关键字并处理业务，结束循环。
if (isFind) {
break;// 如果找到结束循环
}
String[] keys = weixinExpandconfigEntity.getKeyword().split(&amp;#34;,&amp;#34;);
for (String k : keys) {
if (content.indexOf(k) != -1) {
String className = weixinExpandconfigEntity.getClassname();
String returnType = weixinExpandconfigEntity.getReturnType();
KeyService keyService = null;
try {
keyService = (KeyService) Class.forName(className).newInstance();
baseMessage = (BaseMessage) Class.forName(returnType).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
keyService.excute(baseMessage, content.substring(2));
isFind = true;
break;
}
}
}
}
if (baseMessage == null) {
TextMessage textMessage = new TextMessage();
textMessage.setContent(respContent);
baseMessage = textMessage;
}
baseMessage.setToUserName(fromUsername);
baseMessage.setFromUserName(toUsername);
baseMessage.setCreateTime(new Date().getTime());
baseMessage.setFuncFlag(0);
return baseMessage;
}
&lt;/code&gt;&lt;/pre&gt;</description></item></channel></rss>