请通过浏览器功能收藏网页

微信公众号企业号小程序研发框架搭建 公众号开发

发布时间:2018-08-21 10:02:53  作者:本站编辑  来源:本站原创  浏览次数:
www.javainfo.com.cn 上干货 欢迎收藏


 微信公众企业号在研发的时候,有一些基础通用功能是必须的,为此特地搭建了企业号微信小程序研发框架, 此框架运行图如下: 


企业号公众号开发框架.jpg

    接下来介绍一下各个步骤及各个步骤的代码(java版):

    系统初始化信息:

    导入企业号微信的员工信息  userid为员工编号;  具体如何导入请参考企业号公众号说明。

    新建立小程序 微信小程序 wxoa  小程序的各个系统属性参数  小程序界面会提供。

       参数汇总如下:

         String token = "************";

 String EncodingAESKey = "**************";

// 企业ID

static String CorpID = "***";

// secret 测试小程序的 访问密令

static String Secret = "*************";

String backAuthUri = "http://***.com/dyoa/wx_enter/action/oauth";


    小程序菜单初始化  3个主菜单 从左到右依次编号为 1_x, 2_x , 3_x  二级菜单 从上倒下也按照顺序编码 1_1, 1_2 ,.., 2_1 , 2_2,..等等,二级菜单配置URI: http://xx.com/weixin/xxx.do?menuno=x_x 如此准备条件完毕    


    第一步骤 企业号人员点击菜单进入系统

    第二步骤 首先进入过滤器  过滤器的功能主要描述如下: 

    1当用户第一次进入过滤器 过滤器验证用户是否是企业号的用户获取用户USERID等信息, 

    2 第二次重新进入过滤器 过滤器处理当前登录企业用户的菜单权限 数据权限 判断出是否有权限,是否可以进入某个菜单等

      


    过滤器代码:     

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,

ServletException {

HttpServletRequest hRequest = (HttpServletRequest) request;

// 请求的路径

String contextPath = hRequest.getContextPath();

// 获取前台的 菜单编码

String menuNo = hRequest.getParameter("menu");

hRequest.getSession().setAttribute("menuNo", menuNo);

// 这里读取文件获取 访问权限

String tokenFromFile = this.getTokenFromFile();

// 获取了 token的话, 同步到系统级别的缓存中

if (!"no".equals(tokenFromFile)) {

request.getServletContext().setAttribute("accessToken", tokenFromFile);

// 标记为已经读取

} else {

System.out.println("token from file fail ");

}

// 对ACCTOKEN进行获取并通过系统级参数进行传递 共享整个小应用范围内

String accessToken = (String) request.getServletContext().getAttribute("accessToken");

if (accessToken == null || "".equals(accessToken) || menuNo == null) {

// 若更新 令牌失败,则将URI定位到错误 处理函数 这里测试成功 return 必须存在

((HttpServletResponse) response).sendRedirect(contextPath + "/wx_enter/action/error.do?code=tokenIsNull");

return;

}

HttpSession session = hRequest.getSession();

String userId = (String) session.getAttribute("userId");

if (null == userId || "".equals(userId)) {

String resultUrl = hRequest.getRequestURL().toString();

String param = hRequest.getQueryString();

if (param != null) {

resultUrl += "?" + param;

}

try {

resultUrl = java.net.URLEncoder.encode(resultUrl, "utf-8");

} catch (Exception e) {

e.printStackTrace();

}

((HttpServletResponse) response).sendRedirect(contextPath + "/wx_enter/action/userEnter.do?returnBackUrl="+ resultUrl);

// 避免下面的代码 继续执行

return;

}

// 若 USERID为空 , 则通过微信后台接口 获取当前微信用户信息

else {

// userId 及 OA系统的员工 编号

System.out.println("filter userid =" + userId);

// 第二次登录开始

SessionModel model = (SessionModel) hRequest.getSession().getAttribute("sessionInfo");

Map<String, Map> rightsMap = model.getRightsMap();

MapjspRights = rightsMap.get("menu_jspRights");

MapdataRights = rightsMap.get("menu_dataRights");

if (jspRights != null) {

String jspRight = jspRights.get(menuNo);

String dataRight = dataRights.get(menuNo);

if (null == jspRight) {

System.out.println(userId + "filter 您无权登录菜单" + menuNo);

((HttpServletResponse) response).sendRedirect(contextPath

+ "/wx_enter/action/error.do?code=hasNoRightToEnter_" + menuNo);

return;

} else {

String shenhe = jspRight.split("_")[0];

String caozuo = jspRight.split("_")[1];

System.out.println("菜单=" + menuNo + " ;shenhe=" + shenhe + " ;caozuo=" + caozuo

+ ";this-dataRight:" + dataRight + " ;dataRights=" + dataRights);

/ 针对菜单 的角色配置 做数据权限 转LEVEL处理, 可以同时用于界面与后台的数据处理 现金支领审核菜单

// 进入这里说明 用户的ID不为空

if (userId != null && menuNo != null) {

// 根据用户ID获取审核当前菜单的审核级别

。。。。。。。。

}

request.setAttribute("shenhe", shenhe);

request.setAttribute("caozuo", caozuo);

}

}

}

chain.doFilter(request, response);

}      

       

        /**

* 用户第一次进入系统  转向到微信接口验证用户 , 且获取最初请求URI

*/

@RequestMapping(value = "/wx_enter/action/userEnter", method = RequestMethod.GET)

public void userEnter(HttpServletRequest request, HttpServletResponse response) {

try {

// 获取回调界面的URI //此URI 已经 encode

String returnBackUrl = request.getParameter("returnBackUrl");

String uri = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=CORPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";

// 赋值

uri = uri.replace("CORPID", CorpID);

uri = uri.replace("REDIRECT_URI", WeixinUtil.urlEncode(backAuthUri + "?returnBackUrl=") + returnBackUrl); // 需要encoder

uri = uri.replace("SCOPE", "snsapi_base"); // 用户基础信息

uri = uri.replace("STATE", "123456");

// 重定向

response.sendRedirect(uri);

} catch (IOException e) {

e.printStackTrace();

}

}   

   

        /**

* 获取微信用户的 信息 , 只有第一次登录的时候 才会走此验证

* @企业成员授权时返回示例如下: { "UserId":"USERID", "DeviceId":"DEVICEID" "user_ticket":

*                 "USER_TICKET", "expires_in":7200 }

* @非企业成员授权时返回示例如下: { "OpenId":"OPENID", "DeviceId":"DEVICEID" }

* @info 重定向的URI 为 redirect_uri?code=CODE&state=STATE

*/

@RequestMapping(value = "/wx_enter/action/oauth", method = RequestMethod.GET)

public void weixinOAuth(HttpServletRequest request, HttpServletResponse response) {

String menuNo = (String) request.getSession().getAttribute("menuNo");

// 获取传递过来的 回调界面的URI

String returnBackUrl = request.getParameter("returnBackUrl");

String access_token = (String) request.getServletContext().getAttribute("accessToken");

// 获取重定向传递的CODE与STATE

String code = request.getParameter("code");

String state = request.getParameter("state");

// 根据CODE与ACCESS_TOKEN 获取用户的信息 重点为 userid

if (code != null && !"".equals(code) && !"".equals(access_token)) {

// 获取的用户信息JSON

// ={"UserId":"N1","DeviceId":"545445353453453453455434534",

// "errcode":0,"errmsg":"ok"}

WxUser user = WeixinUtil.getLoginUserInfo(access_token, code);

// 这里代表 系统获取了 当前微信用户的 userid ,微信验证为 当前用户为 员工

if (null != user.getUserId() && !"".equals(user.getUserId())) {

System.out.println("微信登录成功" + user.getUserId());

// 这里需要触发同步登录函数

try {

SessionModel a = this.wxService.wxLogin(user);

if (a == null) {

System.out.println(user.getUserId() + "后台登录失败");

response.sendRedirect(request.getContextPath() + "/wx_enter/action/error.do?code=errorUserNull");

// return;

} else {

// 对菜单进行验证过滤

   。。。。。。。。。。。

}

request.getSession().setAttribute("userId", user.getUserId());

// 此字段为 核心字段 用于同步手机段与服务器之间数据

request.getSession().setAttribute("sessionInfo", a);

try {

// 重定向到页面回调URI 路径是正确的 已经确认

response.sendRedirect(returnBackUrl);

// request.getRequestDispatcher(returnBackUrl).forward(request,

// response);

} catch (IOException e) {

e.printStackTrace();

}

}

} catch (Exception e1) {

e1.printStackTrace();

}

} else {

try {

System.out.println("您无权登录系统");

response.getWriter().write("您无权登录系统,请确认");

response.getWriter().flush();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}   

       微信重新回来的时候, 会调用上面的函数, 函数的操作是 对用户进行后台隐式登录到系统,并将请求重新定向到过滤器上(第二次进入过滤器)  对其能否进入系统某个菜单及 对某个界面 的操作按钮权限进行控制。


   企业号 accessToken控制模块如何设计 请参考下一篇文章



        下面是两个工具函数   获取用户基础信息    获取令牌信息

        /**

* 获取企业号登录用户信息

* @param corpid

* @param corpsecret

*         https://qyapi.weixin.qq.com/cgi-bin/

*         user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE

*/

public static WxUser getLoginUserInfo(String access_token, String auth_code) {

String token_url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE";

token_url = token_url.replace("ACCESS_TOKEN", access_token);

token_url = token_url.replace("CODE", auth_code);

// System.out.println("new userInfoURI = " + token_url);

WxUser wu = null;

try {

URL url = new URL(token_url);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setDoInput(true);

conn.setRequestMethod("GET");

InputStream inputStream = conn.getInputStream();

Reader in = new InputStreamReader(inputStream);

BufferedReader reader = new BufferedReader(in);

StringBuffer buffer = new StringBuffer();

String str = null;

while ((str = reader.readLine()) != null) {

buffer.append(str);

}

inputStream.close();

in.close();

reader.close();

conn.disconnect();

JSONObject json = JSONObject.fromObject(buffer.toString());

System.out.println("获取的用户信息JSON =" + json);

// {"UserId":"N33","DeviceId":"34343434343434343434322","errcode":0,"errmsg":"ok"}

String errcode = json.getString("errcode");

String errmsg = json.getString("errmsg");


if ("0".equals(errcode) || "ok".equals(errmsg)) {

wu = new WxUser();

wu.setDeviceId(json.getString("DeviceId"));

wu.setUserId(json.getString("UserId"));

wu.setErrcode(errcode);

wu.setErrmsg(json.getString("errmsg"));

}

} catch (Exception e) {

e.printStackTrace();

}

return wu;

}

    

        

        /**

* 获取AccessToken; 每个secret代表了对应用、通讯录的不同权限;不同的管理组拥有不同的secret。

* @param corpid

*            企业Id

* @param corpsecret

*            管理组的凭证密钥

*/

public static String getAccessToken(String corpid, String corpsecret) throws Exception {

String token_url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpid + "&corpsecret="

+ corpsecret;

String access_token = null;


URL url = new URL(token_url);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setDoInput(true);

conn.setRequestMethod("GET");

InputStream inputStream = conn.getInputStream();

Reader in = new InputStreamReader(inputStream);

BufferedReader reader = new BufferedReader(in);

StringBuffer buffer = new StringBuffer();

String str = null;

while ((str = reader.readLine()) != null) {

buffer.append(str);

}

inputStream.close();

in.close();

reader.close();

conn.disconnect();

JSONObject json = JSONObject.fromObject(buffer.toString());

access_token = json.getString("access_token");

if (access_token != null) {

// System.out.println("访问令牌:" + access_token);

} else {

System.out.println("token获取失败!");

}

return access_token;


/*注:企业号融合过程中该接口输出参数可能略有不同,以下情况均视作获取token成功:

1、能获取到access_token,接口无返回errcode

2、能获取到access_token,接口返回errcode为0, errmsg为空或者"ok"

正确的Json返回结果:

{

  "access_token": "accesstoken000001",

  "expires_in": 7200

}

b)错误的Json返回示例:

{

  "errcode": 43003,

  "errmsg": "require https"

}*/

}

   


如有疑问 请留言 欢迎提供建议

评论已有 0