JFinal使用技巧-Enjoy巧用在微信公众号消息通知上

最近没有来社区分享东西了,响应波总创业号召回西安创业了~,技术学习懈怠了。。。组建小团队,忙活各种项目累够呛。。。言归正传,上石马!

昨天有个需求,就是微信消息通知 支持跳小程序某页面。
微信文档中给出例子:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Interface.html

//PS:这个官网例子有坑,不要只看这一句,注意后面的是正确使用的
{
           "touser":"OPENID",
           "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
           "url":"http://weixin.qq.com/download",  
           "miniprogram":{
             "appid":"xiaochengxuappid12345",
             "pagepath":"index?foo=bar"
           },          
           "data":{
                   "first": {
                       "value":"恭喜你购买成功!",
                       "color":"#173177"
                   },
                   "keyword1":{
                       "value":"巧克力",
                       "color":"#173177"
                   },
                   "keyword2": {
                       "value":"39.8元",
                       "color":"#173177"
                   },
                   "keyword3": {
                       "value":"2014年9月22日",
                       "color":"#173177"
                   },
                   "remark":{
                       "value":"欢迎再次购买!",
                       "color":"#173177"
                   }
           }
       }

就是增加miniprogram参数,看着很简单啊,但是没有发送出去啊。 去掉miniprogram就能发出去了,检查appid和路径都已经进行管理公众号了,那问题一定就是出现在参数上了。 我们挨个排除, 发现文档中说的pagepath 需要改成 pagepaths 加一个S就能正常发送,然后又发现路径上携带的参数没有被正常挂入,检查发现我们小程序项目是有pages和模块名划分 文件夹 的,被它这个实例给坑了一下。。。

我们正常能发送的例子写法是:

{
           "touser":"OPENID",
           "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
           "url":"http://weixin.qq.com/download",  
           "miniprogram":{
             "appid":"xiaochengxuappid12345",
             "pagepaths":"pages/index/index?foo=bar"
           },        
           "data":{
                   "first": {
                       "value":"恭喜你购买成功!",
                       "color":"#173177"
                   },
                   "keyword1":{
                       "value":"巧克力",
                       "color":"#173177"
                   },
                   "keyword2": {
                       "value":"39.8元",
                       "color":"#173177"
                   },
                   "keyword3": {
                       "value":"2014年9月22日",
                       "color":"#173177"
                   },
                   "remark":{
                       "value":"欢迎再次购买!",
                       "color":"#173177"
                   }
           }
       }


好了,微信的梗说了。
那这个Enjoy怎么巧用在微信消息模板上了?
TemplateData这个类大家都会使用,有时候特别是有些需求消息模板文案经常变更的情况下它就没有那么方便了。
其实很简单,JSON其实就是一个字符串嘛! 字符串拼接都能用Enjoy处理~

大致就是这样一个类, 我们对这个类还有很多业务增强,比如传入用户ID,自动查找对应的openid集合等等业务操作:

public class WxMsgKit {

	public ApiResult send(Kv kv){
	        //这里是示例写法,可以使用自己的Engine对象
		String jsonStr = Engine.use().getTemplate("/weixin/msg.jf").renderToString(kv);
		ApiResult send = TemplateMsgApi.send(jsonStr);
		return send;
	}
	
}

然后模板中大致就是这样写的 :

#call(key)

###消息模板a
#define a()
	#--
	绑定提醒
	{{first.DATA}}
	对方帐号:{{keyword1.DATA}}
	绑定状态:{{keyword2.DATA}}
	{{remark.DATA}}
	--#
	{
	       "touser":"#(openid)",
	       "template_id":"xxxx",
	       "url":"xxxx",
	       "topcolor":"#FF0000",
	       "miniprogram":{
	         "appid":"xxxx",
	         "pagepaths":"pages/login/login?jwName=#(jwName)&jwPassword=#(jwPassword)"
	       },
	       "data":{
	               "first": {
	                   "value":"#(accountName), 您好,请点击进入小程序",
	                   "color":"#173177"
	               },
	               "keyword1": {
	                   "value":"#(jwName)",
	                   "color":"#173177"
	               },
	               "keyword2":{
	                   "value":"待绑定",
	                   "color":"#173177"
	               },
	               "remark":{
	                   "value":"点击进入小程序",
	                   "color":"#FF0000"
	               }
	       }
	}
#end

###消息模板b
#define b()
xxx
#end

渲染json时如果"#(name)" name中有双引号会破坏了json 结构,有需要时,
注意使用替换双引号#(name.replace('"', '\"')??)
或增加模板公共处理函数处理#(EscapeKit.escapeJSON(name)) @chcode 提供:
https://jfinal.com/doc/6-8

public class EscapeKit {
public static String escapeJSON(String text) {
if (text == null) {
return null;
}
int len = text.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char ch = text.charAt(i);
switch (ch) {
case '"':
sb.append("\\\"");
break;
case '\\':
sb.append("\\\\");
break;
case '\b':
sb.append("\\b");
break;
case '\f':
sb.append("\\f");
break;
case '\n':
sb.append("\\n");
break;
case '\r':
sb.append("\\r");
break;
case '\t':
sb.append("\\t");
break;
default:
sb.append(ch);
}
}
return sb.toString();
}
}


调用就不用说了

WxMsgKit.send(Kv.by("key", "a").set("openid", openid)) 如果再对业务数据封装一下,调用就更简洁了

对了, 如果想修改模板后 ,立刻生效记得配置 engine.setDevMode(true);https://www.jfinal.com/doc/6-2


分享完了,又水一篇~ 路过记得顺便点个赞~

评论区

凉凉凉凉凉

2019-10-15 17:49

不明觉厉

不要香菜

2019-10-15 17:52

说好的扶墙,却偷偷的扶了你

杜福忠

2019-10-15 17:55

@凉凉凉凉凉 简单来说,就是把 JSON对象的层级关系用Enjoy模板换成了 平级关系,这样配置起来非常的灵活直观,易修改!没有层级关系不烧脑~

山东小木

2019-10-15 18:37

一个模板ID,对应一个模板文件,模板文件可以后台编辑,模板ID也可以配置切换,这样就能做到,当腾讯蛋疼把原申请模板给下架后,能快速使用别的模板替换

山东小木

2019-10-15 18:37

做到数据库配置里更灵活

杜福忠

2019-10-15 18:49

@山东小木 是的木老师,我们其中项目有用自定义Engine里的文件源为数据库的,ID为键直接取模板源,通过页面配置最后的业务JSON字符串,非常方便

JFinal

2019-10-15 20:15

@杜福忠 很美妙的用法

我找了找 jfinal.com 支付成功后的模板消息发送源码,用的是 Kv.set(...).set(...).set(...), 然后生成 json,不如你的用法爽

enjoy 生成 json 内容这个确实不容易想到,涉及到 json 通常想到的是 json 转的换的 API

JFinal

2019-10-15 20:16

jfinal.com 支付成功后的模板消息生成 json 用的 Kv 辅助生成, 可读性远不如你用的模板来表达 json 结构

你这个用法太清晰了,超赞

JFinal

2019-10-15 21:32

谈到创业,我在 2011 年第一次创业,思维方式是相对普遍的那种:想法/团队/产品原型 + 融资 + 发展/融资 + 上市

最终目标是冲着上市去的,但另一种模式我更加建议,那就是做小而美、小而强的创业公司,团队最小可以是两三个人,甚至最初是一个人。团队相当长时间内人数不要超过 10 个人, 6 到 7 个人也能做很大的事情了

前几天我还在俱乐部群里分享过一篇文章,当 Instagram 融了 5750 万美元并被 Facebook 以 10 亿美元收购时,他们只有 13 名员工——而且并非所有人都是工程师:
https://mp.weixin.qq.com/s/AuC6yCm9XWI7oChWmhtauw

WhatsApp 被 facebook 190 多亿美金收购的时候也才几十个人,当今世界,一个小型工程团队甚至一个人创造一些有意义的东西比以往任何时候都有可能

这个时代变化越来越快,小而美、小而强意味着更灵活,适应性更好,加上可以利用的开源项目无限之多,小型创业公司可以活得很快乐

小型团队管理成本、沟通成本更低,有利于专注做产品,自主性也更强

我在 2011 年的创业思维所要付出的东西很多,有些是无法承受的,例如健康透支,将公司做到上市的高强度工作不是常人所能忍受,透支健康几乎是必须的,那几年经常工作到早上八九点才睡

杜福忠

2019-10-15 22:09

@JFinal 开森O(∩_∩)O~~ 谢老大叮嘱!
业务不是从0开始,老东家还在全力支持着我
就年初组建的时候累点,同事几乎都新手,事情多他们不能抗
现在好了, 大家都能独当一面了,产品设计前端后端测试实施都齐全着,我周末再去报班进修一下管理知识,一步一步前进~

JFinal

2019-10-15 22:29

@杜福忠 技术起家创业,一定要注意抛弃技术思维

要以用户/客户价值为中心,技术当成工具、手段

我身边那些技术好的朋友创业都失败了,相反技术很差的创业却赚了不少钱。因为技术差的往往不会有技术思维,而更容易将目标专注于实现用户价值

希望你不要在创业过程中掉入技术思维的坑

当然,在创业过程中选择可以提升效率、降低成本的技术是很重要的,技术是工具不是目标,但好用的工具可以让工作事半功倍

杜福忠

2019-10-15 22:51

@JFinal 谨记! 业务功能以用户为中心,这个在16年我做第一个项目的时候,就被一个使用者深深的教诲了,当时那个老师说,这个功能不是给老板用的,最终是我们这些人在使用系统的。当时顿悟,一直谨记,从后交流沟通业务的时候,避免自己是一个开发者视角,从而说服自己想办法实现一些看似很扯蛋的业务需求。就在上周这个老客户又准备签新期功能了,相互信任,和客户们一起成长~

JFinal

2019-10-16 00:01

@杜福忠 同理心是做出好产品的基本素质

凉凉凉凉凉

2019-10-16 09:20

@JFinal 大佬们的留言,受用无穷呀

阿帕奇

2019-10-16 09:45

@JFinal @杜福忠 看了你们的创业分享,然后回想了一下自身的想法;感触颇深,有时候总站在技术的角度上去考虑了;总觉得一个很奇葩的功能,做出来对项目本身没有好处,反而会让后期难扩展,难维护,不易读懂;等很多问题;到现在都还有一种是否要权衡一下中间的利益的想法?是否真的就以产品是上帝的心里去实现功能?

chcode

2019-10-16 09:47

佩服你创业的勇气

杜福忠

2019-10-16 11:14

@阿帕奇 还是得根据情况权衡一下的,如果真有特别坑的业务需求,我们会和客户一起商量出一种双方友好的方案,因为项目如果出现难以维护和未知问题的功能时,会是更大灾难,恶性循环拖垮团队了

happyboy

2019-10-16 11:20

给小杜点个赞

快乐的蹦豆子

2019-10-17 10:11

不错哦

北流家园网

2019-10-20 19:51

@JFinal 波总,我打工10年,现在也准备出来了,希望多多关照

JFinal

2019-10-20 20:26

@北流家园网 俱乐部群里面多交流,俱乐部越来越多的人会选择 jfinal 做自己的产品

未来公司会选择能长期加班、工资低的 00 后,趁早出来做自己的事情才是大势

canca

2020-04-20 14:54

6年前都这么用!用的不是Enjoy,是freemarker.

杜福忠

2020-04-20 15:09

@canca 活捉大佬一只~ 囧6年前我还在大二玩LOL。。。

JFinal

2020-04-20 15:58

@杜福忠 今天发现有个同学使用 enjoy 有了创新的用法:enjoy 用于实现动态配置 + 动态规则

具体是该同学有个业务系统,经常要搞些促销活动,不同的会员要有不同的折扣之类的逻辑,大致演示如下:

### 下面的代码设计默认折扣,该配置可根据活动策划动态调整
#( configObject.setDefaultDiscount("" ) )

### 下面代码代替 java 代码的功能,实现打哲规则制定
#if ( 用户是 xxx 类型)
#set( returnDiscount = ...)
#else if (....)
#set( returnDiscount = ...)
#else
#set( returnDiscount = ...)
#end

上面两段代码,分别存放在两个不同的模板文件中,第一个相当于实现了动态配置文件,配置完成后利用 enjoy 的 devMode 实时加载生效

第二个相当于将部分业务规则动态化

以上用法的好处是,经常变动的配置与逻辑规则可以不用改 java 代码,更不用打包、部署,也不用重启项目就可以实现需求的变化

人民群众的智慧是无限的 ^_^

JFinal

2020-04-20 16:00

回看你分享的这个用法, 用模板来生成 json ,核心妙处在于模板表达出来的信息可读性极度清晰,妙不可言

热门分享

扫码入社