苍穹H5集成开发微信小程序原创
金蝶云社区-蔡嘉盛
蔡嘉盛
1人赞赏了该文章 32次浏览 未经作者许可,禁止转载编辑于2024年11月21日 10:17:58
summary-icon摘要由AI智能服务提供

本文介绍了将苍穹开发的H5页面挂载到微信、钉钉等OA应用中心的方法,但无法直接转为不同APP的小程序。解决方案包括使用uni-app和HBuilderX快速搭建小程序,通过web-view挂载H5页面,自定义Filter处理微信登录code,获取用户手机号码后进行用户匹配和session创建,最后重定向到目标页面。文中还提供了小程序创建和Filter开发的代码示例。

# 业务场景

在苍穹开发完成的H5页面已经非常方便的挂载微信、钉钉等OA的应用中心,直接配置相关应用参数即可。

image.png

**但是不能直接转换成对应微信小程序、支付宝小程序等不同APP的小程序** 

# 解决方案

1.  uni-app 和 HBuilderX 快速搭建小程序应用架构,

2. 通过web-view 组件挂载苍穹的H5的URL

3. 自定义Filter接收微信小程序登录code参数,把code转换为session_key。然后在前端引导用户授权获取手机号码,在后端进行解密获取真实手机号码

4. 通过手机号码匹配查找用户,进行创建session,然后页面重定向到需要登录的目标页面


# 开发过程

## 创建小程序

1. 在微信小程序后台创建小程序,获取到appid和secret;安装微信开发者工具,开启服务端口

image.png

image.png

2. 安装HBuilderX 开发工具,创建uniapp,填写微信小程序信息

image.png

image.png


index.vue代码参考

<template>
  <div>
    <!-- Dynamically load the web view -->
    <web-view v-if="webUrl" :src="webUrl"></web-view>
  </div>
</template>

<script>
export default {
  data() {
    return {
      jsCode: '', // Code received from wx.login
      webUrl: '', // Target URL to be loaded in web-view
    };
  },
  mounted() {
    this.loginAndRedirect();
  },
  methods: {
    /**
     * Login and fetch session data, then set the redirect URL.
     */
    loginAndRedirect() {
      uni.login({
        success: (res) => {
          if (res.code) {
            this.jsCode = res.code;
            this.fetchSessionData(res.code);
          } else {
            console.error('登录失败!' + res.errMsg);
          }
        },
        fail: (error) => {
          console.error('wx.login failed:', error);
        },
      });
    },
    /**
     * Fetch session data from the server.
     * @param {string} code - Code from wx.login
     */
    fetchSessionData(code) {
		this.webUrl = "http://127.0.0.1:8881/ierp/wx_uni.do?redirect=http://127.0.0.1:8881/ierp/mobile.html?form=kded_meeting_mob_index&js_code="+code
    },
  },
};
</script>

<style scoped>
/* Center the web-view for better UX */
div {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
}
</style>




获取手机号码逻辑参考https://blog.csdn.net/weixin_58034343/article/details/138784567

## 苍穹过滤器Filter开发

通过Filter方式开发,Filter开发参考 https://developer.kingdee.com/article/318801864630167296?productLineId=29&isKnowledge=2&lang=zh-CN

public class WxUniFilter implements Filter {
    private static final Log logger = LogFactory.getLog(WxUniFilter.class);
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String tenantId = RevProxyUtil.getTenantCode(request);
        LoginUtils.handleGenernal(request, response);
        String accountIdParameter = request.getParameter("accountId");
        Account currentCenter = AccountUtils.getCorrectAccount(accountIdParameter, tenantId);
        Lang lang = LoginLangUtils.getLoginLanguage(request);
        LoginLangUtils.setLang(lang);
        //微信小程序前端code
        String code = request.getParameter("js_code");
        String urlBase = "https://api.weixin.qq.com/sns/jscode2session";
        urlBase += "?appid=wxdd32d5b481a8a7d4&secret=250231d3474a8bc02b3be63e5ca43416&js_code=" + code + "&grant_type=authorization_code";
        String codeResult = HttpUtils.request(urlBase);
        JSONObject jsonObject = JSONObject.parseObject(codeResult);
        //获取用户信息,openid
        String openid = jsonObject.getString("openid");
        //ActionUtil.writeResponseJson(response, "{"session_key":"jQ1TLLeS3R8YVxAUhmtZPw==","openid":"oY7C45U6B6baSuYhJupNSWoSnpzM"}");
        //TODO 正常应该把相关信息返回前端,让用户点击授权获取手机号码,再继续进行完成下面的重定向逻辑
        if (StringUtils.isEmpty(openid)) {
            response.sendRedirect("http://127.0.0.1:8881/ierp/mobile.html?form=kded_meeting_mob_index");
            return;
        }

        //根据关键信息匹配查找用户手机号码
        QFilter filter = new QFilter("kded_wx_openid", QFilter.equals, openid);
        DynamicObject bosUser = BusinessDataServiceHelper.loadSingle("bos_user", "phone", filter.toArray());
        Map&lt;String, String&gt; userInfo = LoginUserService.getErpUserInfoByPhone(null, bosUser.getString("phone"), lang.getLangTag());
        String randomCode = this.loginFromDefaultTenant(request, response, lang, currentCenter, userInfo);
        JSONObject jsonObject1 = JSONObject.parseObject(randomCode);
        if (jsonObject1.getInteger("errorcode") == 0){
            response.sendRedirect(jsonObject1.getString("RedirectURL"));
        }else {
            response.sendRedirect("http://127.0.0.1:8881/ierp/mobile.html?form=kded_meeting_mob_index");
        }

    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }

    /**
     * 用户重定向处理
     */
    private String loginFromDefaultTenant(HttpServletRequest request, HttpServletResponse response, Lang lang, Account currentCenter, Map&lt;String, String&gt; userInfo) throws IOException {
        String user = userInfo.get("ftruename");
        logger.info(String.format("用户%s登录默认租户。", user));

        if (!"0".equalsIgnoreCase(userInfo.get("success"))) {
            String userName = userInfo.get("ftruename");
            String userorgId = userInfo.getOrDefault("forgid", "0");
            userInfo.put("ftruename", userName);
            userInfo.put("forgid", userorgId);
            Map&lt;String, Object&gt; map = new HashMap&lt;&gt;(8);
            String redirect;
            //创建用户session
            SessionUtils.createNewSession(request, response, currentCenter, lang, NetAddressUtils.getRemoteHost(request), userInfo, LoginClientEnum.MOBILE);
//            if (StringUtils.isNotEmpty(request.getParameter("isMobile"))) {
//
//            } else {
//                redirect = SessionUtils.createNewSession(request, response, currentCenter, lang, NetAddressUtils.getRemoteHost(request), userInfo, LoginClientEnum.WEB);
//            }
            logger.info("客户 端类型  :" + AgentUtil.getClienyId(request) + ",用户名:" + request.getRemoteHost() + ",访问地址:" + request.getRemoteAddr());
            LoginUtils.setCachkeyData(currentCenter);
            LoginUtils.clearSmsSendTimes(currentCenter.getAccountId(), user);
            redirect = request.getParameter("redirect");
            if (StringUtils.isEmpty(redirect)) {
                redirect = UrlService.getDomainContextUrl() + "/index.html";
            } else if (LoginUtils.isSelfEnvironment(redirect, request, response) && !SecurityUtils.checkXss(redirect)) {
                String qs = request.getQueryString();
                if (qs != null) {
                    redirect = qs.replace("redirect=", "");
                }
            } else if (StringUtils.isNotEmpty(request.getParameter("isMobile"))) {
                redirect = "mobile.html";
            } else {
                redirect = "index.html";
            }
            map.put("errorcode", 0);
            String randomCode;
            redirect = URLUtils.securityFilterRedirectUrl(redirect);
            map.put("RedirectURL", redirect);
            map.put("username", userName);
            map.put("userId", userInfo.get("fid"));
            return JSONUtils.toString(map);
        } else {
            throw new KDException(LoginErrorCode.loginBizException, ResManager.loadKDString("您的账号在系统中不存在!", "LoginAction_11", "bos-login"));
        }
    }
}

通过Java代码解密微信加密过的用户手机号码信息 参考 https://blog.csdn.net/m0_72958694/article/details/139890088


# 实现效果

本地代码调试效果

image.png

图标赞 1
1人点赞
还没有人点赞,快来当第一个点赞的人吧!
图标打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!