当我们需要结合企业微信和业务系统的时候,我们需要建立一个企业微信应用,然后在微信管理后台中绑定对应参数,这样可以利用企业微信的服务端API对接相关的功能,包括提交菜单,以及获取对应的企业微信组织机构、发送消息等常规操作;而业务系统则可以把对应的业务流程和企业微信进行对接,包括消息的推送,以及利用JSSDK对相关业务数据的展示和处理等。本篇随笔介绍在利用企业微信前的相关处理步骤,如创建企业应用,绑定企业应用信息,以及相关的业务处理交互等。
1、创建企业微信应用
首先我们需要注册申请一个企业微信的账号,注册申请需要提交相关的企业资质信息,这里就不再赘述。
有了企业微信账号后,我们扫码进入企业微信的管理后台,在【应用与小程序】模块中创建一个应用,这个就是我们对应的业务应用了,企业微信可以创建多个不同场景的业务应用,其本身也自带了很多相关的应用在里面。
创建应用,我们需要录入相关的应用信息和Logo图标信息,如下界面所示。
例如我创建的一个企业微信应用,我们记住它的应用ID和它的秘钥,这个是一个很重要的信息,需要绑定在微信系统里面,我们后面对相关的企业微信服务端API接口调用,都需要利用到这些参数的。
如果我们的企业微信应用设计到支付信息的,需要打开企业支付的应用获得对应的秘钥信息的,如下所示。
打开【企业支付】就可以看到支付对应的密钥了,这个很重要,如我们需要利用企业微信发送红包或者直接付款给员工的时候,这个就需要用到了,如我前面随笔介绍的《企业微信支付的发送红包及相关接口使用》
2、绑定企业微信相关参数
在企业微信后台创建对应的应用,并获得对应的应用ID、密钥等信息后,我们可以在微信后台管理系统里面录入我们获得的应用信息了。
一般来说,微信后台管理系统能够管理不同类型:公众号、企业微信、小程序等类型的账号信息,我们在对应的分类里面录入相关的企业应用信息,如下录入界面所示。
有了这些对应的信息后,我们可以对企业微信应用编辑相关的菜单信息,然后通过接口提交到微信服务端上去,这样我们的应用就具有了我们自定义的业务菜单了,如下是微信管理系统里面对菜单的管理。
菜单列表管理界面如下所示。
这样配置好菜单并设置了相关的处理事件或者对应的JSSDK页面路径后,我们就可以提交到服务端上去,马上就可以看到企业应用的菜单变化了。
以上就是实际应用的菜单界面效果,这样我们企业应用就有了相关的处理入口了,有些是扫码事件,有些是自定义事件,有些则是JSSDK编写的业务入口,如资产录入、盘点任务等。
3、业务处理对接
有了具体的菜单入口,我们需要处理我们入口的处理逻辑了,如果是扫码,我们需要在后台进行一定的事件响应,如在资产查看里面扫码后发送一个文本信息,供跳转到相关的查看资产信息界面上去。
在之前随笔介绍过对这些事件的处理,如《C#开发微信门户及应用(21)-微信企业号的消息和事件的接收处理及解密》,如果需要了解企业微信发送消息的过程,可以参考下《企业微信发送应用消息的实现》随笔的介绍即可。
例如对于扫码入口,企业微信的后台对这些事件进行捕捉,并匹配到对应的处理模块上去处理,如下代码所示。
/// <summary>
/// 扫码推事件且弹出“消息接收中”提示框的事件推送的处理
/// </summary>
/// <param name="info">扫描信息</param>
/// <returns></returns>
public string HandleEventScancodeWaitmsg(RequestEventScancodeWaitmsg info, AccountInfo accountInfo)
{
string result = "";
try
{
var handler = AutoFactory.Instatnce.Container.Resolve<IQRCodeHandler>();
if (handler != null)
{
result = handler.HandleScancodeWaitmsg(info, accountInfo);
}
}
catch (Exception ex)
{
LogHelper.Error(ex);
}
return result;
}
通过 AutoFactory.Instatnce.Container.Resolve<IQRCodeHandler>(); 我们可以看到业务的流程调整到了IOC的一个配置处理模块上去了,这里利用了Autofac的配置信息自动加载对应的处理模块。
对于扫码处理逻辑,我们显示根据资产信息,构建一个文本消息发给企业微信客户端,然后引导用户打开响应的连接就可以跳转到对应的资产信息查看界面上去了,如下所示。
/// <summary>
/// 处理扫码结果
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
private string HandleScanResult(RequestEventScanCode info, AccountInfo accountInfo)
{
ResponseText response = new ResponseText(info);
if (info.ScanCodeInfo != null)
{
response.Content = string.Format("您的信息为:{0},可以结合后台进行数据查询。", info.ScanCodeInfo.ScanResult);
var isUrl = ValidateUtil.IsURL(info.ScanCodeInfo.ScanResult);
if (!isUrl)
{
string assetcode = info.ScanCodeInfo.ScanResult;
if (!string.IsNullOrEmpty(assetcode))
{
response.Content = ConvertAssetInfo(info, accountInfo, assetcode);
}
else
{
response.Content = string.Format("扫码内容为空。");
}
}
}
var result = response.ToXml();
return result;
}
/// <summary>
/// 转换资产信息为文本消息
/// </summary>
/// <returns></returns>
private string ConvertAssetInfo(RequestEventScanCode info, AccountInfo accountInfo, string assetcode)
{
StringBuilder sb = new StringBuilder();
BLLFactory<Asset>.Instance.SetConfigName("workflow");
var assetInfo = BLLFactory<Asset>.Instance.FindByCode(assetcode);
if (assetInfo != null)
{
//~资产代码~、资产名称、管理部门、使用部门、使用人、存放地点、数量、资产动态、在用类型
sb.AppendFormat("资产代码:{0}", assetInfo.Code).Append("\n");
sb.AppendFormat("资产名称:{0}", assetInfo.Name).Append("\n");
sb.AppendFormat("管理部门:{0}", assetInfo.ChargeDept).Append("\n");
sb.AppendFormat("使用部门:{0}", assetInfo.CurrDept).Append("\n");
sb.AppendFormat("使用人:{0}", assetInfo.UsePerson).Append("\n");
sb.AppendFormat("存放地点:{0}", assetInfo.KeepAddr).Append("\n");
sb.AppendFormat("数量:{0}", assetInfo.Qty).Append("\n");
sb.AppendFormat("资产动态:{0}", assetInfo.Status).Append("\n");
sb.AppendFormat("在用类型:{0}", assetInfo.UseType).Append("\n");
sb.AppendFormat("<a href='{0}/QyH5/AssetInfo?code={1}' >点击查看详细信息</a>", WebsiteDomain, assetInfo.Code);
}
else
{
sb.AppendFormat("资产代码【{0}】不存在。", assetcode).Append("\n");
sb.AppendFormat("<a href='{0}/QyH5/Asset?devicecode={1}' >点击添加设备信息</a>", WebsiteDomain, assetcode);
}
return sb.ToString();
}
其他的部分入口是通过编写JSSDK页面的方式实现业务数据的处理的,在JSSDK编写里面,我们有时候需要获取当前登录的用户身份信息,如企业微信的userid,那么我们就可以通过跳转的方式获取code,然后根据对应的code解析为userid即可。
//获取企业微信账号信息
var accountInfo = GetAccount(ConfigData.CorpAccountNo);
//如果传入了userid,使用传入的参数
if (string.IsNullOrEmpty(userid))
{
//通过重定向的code获取对应的UserId
userid = GetUserId(accountInfo.AppID, accountInfo.AppSecret);
}
而为了避免反复的解析code参数导致出错(code只能被用一次,后续再用会出错的),那么我们可以把用户的userid存放在session里面,这样判断如果这个Session不存在了,我们再解析code就没问题了。
/// <summary>
/// 根据当前的Code获取对应的openid(获取获取openid的参数)
/// </summary>
/// <param name="accountInfo">登陆账号信息</param>
/// <returns></returns>
protected virtual string GetUserId(string appid, string appsecret)
{
string userId = Request.QueryString["userid"];
if (string.IsNullOrEmpty(userId))
{
var user_id = Session["user_id"];
if (user_id != null)
{
userId = user_id.ToString();
}
else
{
//如果没有传递userId,那么就根据code参数获取userId
string code = Request.QueryString["code"];
if (!string.IsNullOrEmpty(code))
{
string accessToken = baseApi.GetAccessToken(appid, appsecret);
var result = baseApi.GetUserInfo(accessToken, code);
if (result != null)
{
userId = result.UserId;
Session["user_id"] = userId;//存储在Session
}
}
}
}
return userId;
}
下面是一个资产信息录入的界面效果,利用JSSDK进行编写的页面。
其中的一些选择框,我们可以填写相关的字典数据,或者列表信息供选择。
这些数据最终可以提交到业务管理系统里面,从而实现了企业微信和业务管理系统的数据流对接。
还有一个如盘点任务一样的工作,我们可以交给企业微信端进行处理,通过手机进行移动端的数据处理,更加方便。
以上就是企业微信和业务管理系统的交互过程的一部分,我们具体可以根据自己的业务需要,扩展很多相关的处理页面。
通过整合企业微信和业务系统的数据流,我们可以更加方便的了解企业业务信息,也更加方便的利用手机终端进行一些快捷的查询或者处理业务操作。