TG.WXCRM.V4/AppletMvcService/Hanlder/MessageHandler.cs

645 lines
27 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using AppletMvcService.Common;
using AppletMvcService.Models;
using Newtonsoft.Json;
using Ninject;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Net;
using System.Text;
using WX.CRM.Common;
using WX.CRM.IBLL.weapp;
using WX.CRM.Model.weapp;
using WX.CRM.WebHelper.Infrastructure;
namespace AppletMvcService.Hanlder
{
public class MessageHandler
{
public static IAppletMsg appletmsg = NinjectControllerFactory.ninjectKernel.Get<IAppletMsg>();
public static IWX_UserInfo userinfo = NinjectControllerFactory.ninjectKernel.Get<IWX_UserInfo>();
private static Dictionary<string, WxAccount> wxaccount = null;
public static Dictionary<string, WxAccount> GetWxAccount()
{
if (wxaccount != null && wxaccount.Count > 0)
return wxaccount;
wxaccount = new Dictionary<string, WxAccount>();
DataTable tab = userinfo.GetWxAccount();
if (tab != null && tab.Rows.Count > 0)
{
LogHelper.Error("wxaccount为空需要进行初始化");
foreach (DataRow item in tab.Rows)
{
WxAccount account = new WxAccount();
account.accountName = item["ACCOUNTNAME"].ToString();
account.pkid = Convert.ToDecimal(item["PKID"]);
account.accountNum = item["ACCOUNTNUM"].ToString();
account.appId = item["APPID"].ToString();
account.appSecret = item["APPSECRET"].ToString();
account.fenPeiPoc = item["FENPEIPOC"].ToString();
if (!wxaccount.ContainsKey(account.accountNum))
wxaccount.Add(account.accountNum, account);
account.tokenhttp = item["TOKENHTTP"].ToString();
account.isonline = Convert.ToInt32(item["ISONLINE"]);
}
}
return wxaccount;
}
#region 线
public static Dictionary<string, List<UserDetail>> GetConnectedByRedis()
{
Dictionary<string, List<UserDetail>> nn = new Dictionary<string, List<UserDetail>>();
try
{
LogHelper.Error("客服数据获取");
//Dictionary<string, WxAccount> naccount = GetWxAccount();
DataTable tab = userinfo.GetOnlineUser();
if (tab != null && tab.Rows.Count > 0)
{
foreach (DataRow item in tab.Rows)
{
UserDetail detial = new UserDetail();
detial.ConnectionId = item["connectionid"].ToString();
detial.DeptName = item["deptname"].ToString();
detial.LoginTime = Convert.ToDateTime(item["logintime"]);
detial.UserID = item["userid"].ToString();
detial.UserName = item["username"].ToString();
string accountnum = item["accountnum"].ToString();
if (!nn.ContainsKey(accountnum))
nn.Add(accountnum, new List<UserDetail>());
nn[accountnum].Add(detial);
}
}
}
catch (Exception x)
{
LogHelper.Error(x.ToString());
}
return nn;
}
public static void AddConnectedToRedis(UserDetail connected, string accountnum)
{
try
{
userinfo.Logon(connected.ConnectionId, connected.UserID, connected.UserName, connected.DeptName, connected.LoginTime, accountnum);
}
catch (Exception ex)
{
LogHelper.Error(ex.ToString());
}
}
public static void RemoveConnectedToRedis(UserDetail connected, string accountnum)
{
try
{
userinfo.UnLogon(connected.UserID, accountnum);
}
catch (Exception ex)
{
LogHelper.Error(ex.ToString());
}
}
#endregion
public static void UpdateSendTime(string v_openid, DateTime v_ctime, string v_AccountNum, decimal eid)
{
userinfo.UpdateSendTime(v_openid, v_ctime, v_AccountNum, eid);
}
public static CustoemrDetail GetCustomerHeadInfo(CustoemrDetail info)
{
DataTable table = userinfo.GetUserHeadInfo(info.OpenId);
if (table != null && table.Rows.Count > 0)
{
info.NickName = table.Rows[0]["nickname"].ToString();
info.HeaderUrl = table.Rows[0]["avatarurl"].ToString();
}
return info;
}
public static void weapp_update_subscribe(string v_openid, string v_subType, DateTime v_time, string v_AccountNum)
{
userinfo.weapp_update_subscribe(v_openid, v_subType, v_time, v_AccountNum);
}
/// <summary>
/// 获取分配信息
/// </summary>
/// <param name="openId"></param>
/// <param name="onlineUser">在线人员</param>
/// <param name="accountnum">公众号</param>
/// <returns></returns>
public static string GetFenPeiEID(int type, string openId, string onlineUser, string accountnum, string fenpei, ref int isNew)
{
//LogHelper.Error("1");
if (string.IsNullOrEmpty(fenpei))
return "1";
//LogHelper.Error("2");
DataTable table = userinfo.GetFenPeiCustomerService(type, openId, onlineUser, accountnum, fenpei);
//LogHelper.Error("3");
string eid = "1";
isNew = 0;
if (table != null && table.Rows.Count > 0)
{
eid = table.Rows[0]["eid"].ToString();
isNew = Convert.ToInt32(table.Rows[0]["isNew"]);
}
//LogHelper.Error("4");
//LogHelper.Error("eid:" + eid + ",isNew:" + isNew + ",ChatHub.ConnectedUsers:" + (ChatHub.ConnectedUsers == null));
//if (ChatHub.ConnectedUsers == null)
//{
// LogHelper.Error("ChatHub.ConnectedUsers被销毁" + eid);
// return "1";
//}
//LogHelper.Error("ChatHub.ConnectedUsers.Count" + ChatHub.ConnectedUsers.Count);
//if (ChatHub.ConnectedUsers[accountnum].Count == 0)//没有售后客服在线
//{
// eid = "1";//系统工号
//}
//else if (!string.IsNullOrEmpty(eid) && ChatHub.ConnectedUsers[accountnum].Count > 0)//检测目标售后是否在线
//{
// LogHelper.Error("count:" + ChatHub.ConnectedUsers[accountnum].Count);
// UserDetail detail = ChatHub.ConnectedUsers[accountnum].FirstOrDefault(m => m.UserID == eid);
// if (detail == null)
// {
// Random rd = new Random();
// eid = ChatHub.ConnectedUsers[accountnum][rd.Next(ChatHub.ConnectedUsers.Count)].UserID;
// }
//}
return eid;
}
/// <summary>
/// 获取好友列表
/// </summary>
/// <param name="eid"></param>
/// <param name="accountnum"></param>
/// <returns></returns>
public static List<CustoemrDetail> GetFriends(decimal eid, string accountnum)
{
List<CustoemrDetail> friends = new List<CustoemrDetail>();
DataTable table = userinfo.GetFriends(eid, accountnum);
if (table == null || table.Rows.Count == 0)
return friends;
CustoemrDetail fd = null;
foreach (DataRow item in table.Rows)
{
fd = new CustoemrDetail();
fd.ConnectionId = item["openid"].ToString();
fd.HeaderUrl = item["avatarurl"].ToString();
fd.LoginTime = DateTime.Now;
fd.NickName = item["nickname"].ToString();
fd.OpenId = item["openid"].ToString();
fd.Remarks = item["remarks"].ToString();
if (item["subscribe"] == DBNull.Value)
fd.subscribe = 0;
else
fd.subscribe = Convert.ToInt32(item["subscribe"]);
if (item["ChatTime"] == DBNull.Value)
fd.ChatTime = new DateTime(2017, 1, 1);
else
fd.ChatTime = Convert.ToDateTime(item["ChatTime"]);
fd.Hours = Convert.ToInt32(item["hours"]);
if (string.IsNullOrEmpty(fd.HeaderUrl))
fd.HeaderUrl = "/Content/Images/defaulthead.jpg";
fd.resid = string.Format("{0}", item["resid"]);
friends.Add(fd);
}
return friends;
}
public static void SendNoLineMsg(string toUserId, string accountnum)
{
string message = "无客服在线请在上班9:00~11:30 13:00~18:00进行咨询";
SendMsg(toUserId, message, 1, accountnum);
}
private static string GetToken(string accountnum, bool GetNew = false)
{
string url = GetWxAccount()[accountnum].tokenhttp + accountnum + (GetNew == true ? "&isForce=true" : "");
string result = RequestHelper.CreateGetString(url, null, "", null);
AccessToken imgmsg = JsonConvert.DeserializeObject<AccessToken>(result);
return imgmsg.access_token;
}
/// <summary>
/// 发送消息
/// </summary>
/// <param name="toUserId"></param>
/// <param name="message"></param>
public static void SendMsg(string toUserId, string message, int eid, string accountnum)
{
string token = GetToken(accountnum);
SendMsg msg = new SendMsg();
string resultJson = string.Empty;
for (int i = 0; i < 2; i++)
{
string url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + token;
//LogHelper.Info(string.Format("userid:{0},token:{1}", toUserId, token));
msg.touser = toUserId.Replace("userid-", "");
msg.text = new MsgContent() { content = message };
msg.msgtype = "text";
resultJson = RequestHelper.CreatePostGetString(url, JsonConvert.SerializeObject(msg), null, "", Encoding.UTF8, null);
//LogHelper.Info("返回值:" + resultJson);
if (resultJson.IndexOf("\"errcode\":40001") > -1)
token = GetToken(accountnum, true);
else
break;
}
ResultModel rest = JsonConvert.DeserializeObject<ResultModel>(resultJson);
if (rest.errmsg != "ok")//发送失败
{
LogHelper.Error("发送文本错误:" + resultJson);
}
else
{
AppletMsgModel appletMsg = new AppletMsgModel();
appletMsg.Content = message;
DateTime time1 = System.DateTime.Now;
appletMsg.CreateTime = DateTimeTool.ConvertDateTimeInt(time1);
appletMsg.MsgId = 0;
appletMsg.MsgType = "text";
appletMsg.ToUserName = msg.touser;
appletMsg.FromUserName = accountnum;
appletmsg.WeapAddMessage(appletMsg, eid, 1, 1);
UpdateSendTime(msg.touser, time1, accountnum, eid);
}
}
public static string GetSuCaiUrl(string mediaId, string accountnum, ref string erroMsg)
{
string token = GetToken(accountnum);
string resultJson = string.Empty;
HttpWebResponse response = null;
Stream stream = null;
StreamReader sr = null;
string filePath = string.Empty;
byte[] mbyte = null;
int startmbyte = 0;
try
{
for (int i = 0; i < 2; i++)
{
string url = "https://api.weixin.qq.com/cgi-bin/media/get?access_token=" + token + "&media_id=" + mediaId;
WebClient client = new WebClient();
stream = client.OpenRead(url);
sr = new StreamReader(stream);
mbyte = new byte[1000000];
int allmybyte = (int)mbyte.Length;
while (allmybyte > 0)
{
int m = stream.Read(mbyte, startmbyte, allmybyte);
if (m == 0)
break;
startmbyte += m;
allmybyte -= m;
}
resultJson = sr.ReadToEnd();
if (resultJson.IndexOf("\"errcode\":40001") > -1)
token = GetToken(accountnum, true);
else
break;
}
if (resultJson.IndexOf("errcode") > -1)//发送失败
{
LogHelper.Error("素材获取失败:" + resultJson);
return "";
}
else
{
#region
// 把 byte[] 写入文件
var yearMonth = DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString();
string fileNameWithoutExt = yearMonth + "/" + mediaId;
string vpath = ConfigurationManager.AppSettings["weappfile"] + fileNameWithoutExt + ".amr";
FileStream fstr = new FileStream(vpath, FileMode.OpenOrCreate, FileAccess.Write);
fstr.Write(mbyte, 0, startmbyte);
fstr.Flush();
fstr.Close();
#endregion
#region MP3
var webPath = FileUnit.GetBaseDirectory();
var exePath = webPath + "silk2mp3";
//var fileNameWithoutExt = Path.GetFileNameWithoutExtension(vpath);
var basePath = Utility.GetSettingByKey("weappfile");
var path = basePath + "audio/" + yearMonth;
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
if (!System.IO.File.Exists(vpath))
{
erroMsg = "未能找到文件!";
}
var targetFileNameMp3 = Path.Combine(path, mediaId + ".mp3");
if (!System.IO.File.Exists(targetFileNameMp3))
{
SilkConvertToMp3 amr = new SilkConvertToMp3();
amr.ConvertToMp3(exePath, vpath, targetFileNameMp3);
}
#endregion
filePath = "/audio/" + yearMonth + "/" + mediaId + ".mp3";
}
}
catch (Exception ex) { LogHelper.Error(ex.ToString()); }
finally
{
if (sr != null) { sr.Close(); }
if (stream != null) { stream.Close(); }
if (response != null) { response.Close(); }
}
return filePath;
}
/// <summary>
/// 新增一个图片文件
/// </summary>
public static ImageMsg SendImg(string type, string accountnum, string filename, string nfile)
{
string token = GetToken(accountnum);
string resultJson = string.Empty;
for (int i = 0; i < 2; i++)
{
string url = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=" + token + "&type=" + type;
resultJson = HttpUploadFile(url, filename);
if (resultJson.IndexOf("\"errcode\":40001") > -1)
token = GetToken(accountnum, true);
else
break;
}
if (resultJson.IndexOf("errcode") > -1)//发送失败
{
LogHelper.Error("新增素材失败:" + resultJson);
return null;
}
else
{
ImageMsg imgmsg = JsonConvert.DeserializeObject<ImageMsg>(resultJson);
MessageHandler.appletmsg.WeapAddFilePath(0, imgmsg.media_id, nfile);
return imgmsg;
}
}
/// <summary>
/// 发送图片素材
/// </summary>
/// <param name="imgmsg"></param>
/// <param name="toUser"></param>
/// <param name="accountnum"></param>
public static void SendImgMsg(ImageMsg imgmsg, string sucaitype, string toUser, string accountnum, int eid, string name, ref string content)
{
if (imgmsg == null)
return;
string token = GetToken(accountnum);
string resultJson = string.Empty;
content = string.Empty;
for (int i = 0; i < 2; i++)
{
string url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + token;
var ojb = new object();
if (sucaitype == "image")
{
ojb = new { touser = toUser, msgtype = sucaitype, image = new { media_id = imgmsg.media_id } };
content = "图片素材【" + (string.IsNullOrEmpty(name) ? "本地图片" : name) + "】";
}
else if (sucaitype == "voice")
{
ojb = new { touser = toUser, msgtype = sucaitype, voice = new { media_id = imgmsg.media_id } };
content = "语音素材【" + name + "】";
}
else if (sucaitype == "video")
{
ojb = new { touser = toUser, msgtype = sucaitype, video = new { media_id = imgmsg.media_id } };
content = "视频素材【" + name + "】";
}
else if (sucaitype == "mpnews")
{
ojb = new { touser = toUser, msgtype = "mpnews", mpnews = new { media_id = imgmsg.media_id } };
content = "图文素材【" + name + "】";
}
resultJson = RequestHelper.CreatePostGetString(url, JsonConvert.SerializeObject(ojb), null, "", Encoding.UTF8, null);
if (resultJson.IndexOf("\"errcode\":40001") > -1)
token = GetToken(accountnum, true);
else
break;
}
ResultModel rest = JsonConvert.DeserializeObject<ResultModel>(resultJson);
if (rest.errmsg != "ok")//发送失败
{
LogHelper.Error("发送" + content + "素材错误:" + resultJson);
}
else
{
AppletMsgModel appletMsg = new AppletMsgModel();
appletMsg.CreateTime = DateTimeTool.ConvertDateTimeInt(System.DateTime.Now);
appletMsg.MsgId = 0;
appletMsg.MsgType = sucaitype;
appletMsg.ToUserName = toUser;
appletMsg.FromUserName = accountnum;
appletMsg.MediaId = imgmsg.media_id;
appletMsg.Content = content;
appletmsg.WeapAddMessage(appletMsg, eid, 1, 1);
}
}
public static DataTable IsNeedDownLoadSuCai(string media_id)
{
return appletmsg.IsHasMediaId(media_id);
}
/// <summary>
/// 下载文件素材
/// </summary>
/// <param name="URLAddress"></param>
/// <returns></returns>
public static string DownLoadSuCaiPath(string media_id, string URLAddress)
{
string filepath = string.Empty;
try
{
string fix = ".jpg";
LogHelper.Error("fix:" + fix);
WebClient client = new WebClient();
Stream str = client.OpenRead(URLAddress);
StreamReader reader = new StreamReader(str);
byte[] mbyte = new byte[1000000];
int allmybyte = (int)mbyte.Length;
int startmbyte = 0;
while (allmybyte > 0)
{
int m = str.Read(mbyte, startmbyte, allmybyte);
if (m == 0)
break;
startmbyte += m;
allmybyte -= m;
}
reader.Dispose();
str.Dispose();
var yearMonth = DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString();
string uploadFolder = (ConfigurationManager.AppSettings["weappfile"] ?? "weappfile") + "/" + yearMonth;
if (!Directory.Exists(uploadFolder))
{
Directory.CreateDirectory(uploadFolder);
}
string imgname = "G" + DateTime.Now.ToString("yyyyMMddHHmmssffff") + fix;
string path = Path.Combine(uploadFolder, imgname);
filepath = "/" + yearMonth + "/" + imgname;
FileStream fstr = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
fstr.Write(mbyte, 0, startmbyte);
fstr.Flush();
fstr.Close();
}
catch (Exception ex)
{
LogHelper.Error("download erro:" + ex.ToString());
filepath = "";
}
return filepath;
}
public static string HttpUploadFile(string url, string path)//这个方法是两个URL第一个url是条到微信的第二个是本地图片路径
{
// 设置参数
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
CookieContainer cookieContainer = new CookieContainer();
request.CookieContainer = cookieContainer;
request.AllowAutoRedirect = true;
request.Method = "POST";
string boundary = DateTime.Now.Ticks.ToString("X"); // 随机分隔线
request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary;
byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
int pos = path.LastIndexOf("\\");
string fileName = path.Substring(pos + 1);
//请求头部信息
StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name=\"file\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n", fileName));
byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString());
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
byte[] bArr = new byte[fs.Length];
fs.Read(bArr, 0, bArr.Length);
fs.Close();
Stream postStream = request.GetRequestStream();
postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
postStream.Write(bArr, 0, bArr.Length);
postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
postStream.Close();
//发送请求并获取相应回应数据
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
//直到request.GetResponse()程序才开始向目标网页发送Post请求
Stream instream = response.GetResponseStream();
StreamReader sr = new StreamReader(instream, Encoding.UTF8);
//返回结果网页html代码
string content = sr.ReadToEnd();
return content;
}
#region
public static object GetSucaiModel(string type, int count, int offset, string accountnum)
{
string token = GetToken(accountnum);
string resultJson = string.Empty;
for (int i = 0; i < 2; i++)
{
string url = "https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=" + token;
SuCaiSendModel model = new SuCaiSendModel();
model.count = count;
model.offset = offset;
model.type = type;
resultJson = RequestHelper.CreatePostGetString(url, JsonConvert.SerializeObject(model), null, "", Encoding.UTF8, null);
if (resultJson.IndexOf("\"errcode\":40001") > -1)
token = GetToken(accountnum, true);
else
break;
}
if (resultJson.IndexOf("errcode") > -1)
{
//ResultModel result = JsonConvert.DeserializeObject<ResultModel>(resultJson);
return new { result = false, msg = resultJson };
}
if (type == "news")
{
//LogHelper.Info(resultJson);
//NewsModel newsmodel = JsonConvert.DeserializeObject<NewsModel>(resultJson);
//newsmodel.result = true;
//return newsmodel;
NewsModel2 newmodel = new NewsModel2();
newmodel.result = true;
newmodel.dataResult = resultJson;
return newmodel;
}
else
{
SuCaiModel newsmodel = JsonConvert.DeserializeObject<SuCaiModel>(resultJson);
newsmodel.result = true;
return newsmodel;
}
}
#endregion
}
public class SilkConvertToMp3
{
public void ConvertToPcm(string applicationPath, string fileName, string targetFileName)
{
string para = applicationPath + @"\silk_v3_decoder.exe " + fileName + " " + targetFileName + "&exit";
Cmd(para);
}
public void ConvertToMp3(string applicationPath, string fileName, string targetFilName)
{
string c = applicationPath + @"\ffmpeg.exe -i " + fileName + " " + targetFilName + "&exit"; ;
Cmd(c);
}
private void Cmd(string c)
{
try
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;
process.Start();
process.StandardInput.WriteLine(c);
process.StandardInput.AutoFlush = true;
//process.StandardInput.WriteLine("exit");
var reader = process.StandardOutput.ReadToEnd(); //截取输出流
process.WaitForExit();
process.Close();
}
catch (Exception ex)
{
LogHelper.Error("转换录音文件失败:" + ex.ToString());
}
}
}
}