TG.WXCRM.V4/WeChatServerServices/WeiXin/GenHtml/GenHtml.cs

500 lines
22 KiB
C#
Raw 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 Quartz;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using WeChatServerServices.Model;
using WX.CRM.Common;
using WX.CRM.DAL;
namespace WeChatServerServices.WeiXin.GenHtml
{
public class GenHtml
{
//WX.CRM.IBLL.Wx.IWX_MESSAGE bll = new WX.CRM.BLL.Wx.WX_MESSAGE_BL();
WX.CRM.IBLL.Base.IBAS_PARAMETER_Q paraq = new WX.CRM.BLL.Base.BAS_PARAMETER_BL();
WX.CRM.IBLL.Base.IBAS_PARAMETER para = new WX.CRM.BLL.Base.BAS_PARAMETER_BL();
WX.CRM.IBLL.SYQ.ISYQManager syq = new WX.CRM.BLL.SYQ.SYQManager_BL();
//private readonly object _lockObj = new object();
private static string _isMessageMonth;
private static string _shareName;
private static string _isShare;
public GenHtml()
{
_isMessageMonth = Utility.GetSettingOrNullByKey("IsMessageMonth");
_isShare = Utility.GetSettingByKey("IsShare");
if (!string.IsNullOrEmpty(_isShare))
{
//LogHelper.Info(_isShare);
try
{
_shareName = Utility.GetSettingByKey("NetUseShareName") ?? @"\\192.168.1.171\weixin";
string user = Utility.GetSettingByKey("NetUseUser") ?? @"192.168.1.171\admin";
string pwd = Utility.GetSettingByKey("NetUsePwd") ?? "read,./1";
NetUseHelper.Build(_shareName, user, pwd, string.Empty);//不指定盘符,避免引起盘符被占用的错误
}
catch (Exception e)
{
LogHelper.Error(e.ToString());
}
}
}
public void GenHtmlFile()
{
try
{
syq.SYQErro();
string IsCover = Utility.GetSettingByKey("WxGenChatHtmlIsCover"); //生成文后是否覆盖旧文件
string rootPath = Utility.GetSettingByKey("WxGenChatHtmlRootPath"); //html文件生成的根目录
if (!string.IsNullOrEmpty(_shareName))
{
rootPath = _shareName + @"\Message\";
}
string maxCount = Utility.GetSettingByKey("WxGenChatHtmlMaxRecord"); //生成html的最大记录数
int mc = int.Parse(maxCount);
var tableName = string.Empty;
var monthMaxId = 0;
var monthCurId = 0;
string maxPkidStr = paraq.GetModel_Patameter("WxGenHtmlMaxRecordPkid").PARAVALUE;
if (string.IsNullOrEmpty(maxPkidStr))
throw new Exception("没配置WxGenHtmlMaxRecordPkid参数");
int maxPkid = int.Parse(maxPkidStr);
IList<GenMessage> waitGenHtmlList = null;
if ((!string.IsNullOrEmpty(_isMessageMonth) && _isMessageMonth == "1"))
{
//IsMessageMonth配置不是空并且配置值等于1根据月份表来生成聊天记录
var monthTableSql = "select top 1 * from wx_messageconfig where isExe = 0 order by month";
var monthTable = SqlHelper.GetDataSet(SqlHelper.DatabaseType.AYCRM, monthTableSql, CommandType.Text).Tables[0];
tableName = monthTable.Rows[0]["tableMonth"].ToString();
monthMaxId = int.Parse(monthTable.Rows[0]["maxId"].ToString());
monthCurId = int.Parse(monthTable.Rows[0]["curId"].ToString());
waitGenHtmlList = GetMessageByMonth(tableName, monthCurId);
}
else
{
waitGenHtmlList = GetWaitMessage(maxPkid);
}
if (waitGenHtmlList == null || !waitGenHtmlList.Any())
return;
maxPkid = waitGenHtmlList.Select(p => p.Id).Max();
#region
List<string> usernams = waitGenHtmlList.Where(m => m.MsgType != 1).Select(p => p.username).Distinct().ToList();
foreach (string username in usernams)
{
var genLis = waitGenHtmlList.Where(m => m.MsgType != 1).Where(p => p.username == username).OrderBy(o => o.createTime).ToList();
foreach (var genMessage in genLis)
{
try
{
var time = DateTimeTool.GetTimeFromLinuxTime(genMessage.createTime);
var dir = string.Format("{0}/{1}", rootPath, username);
var path = string.Format("{0}_{1}.json", genMessage.talker, time.Year.ToString() + time.Month.ToString());
var content = Utility.ConvertToJSON(genMessage);
if (File.Exists(Path.Combine(dir, path)))
FileUnit.AppendFile(dir, path, "," + content);
else
FileUnit.AppendFile(dir, path, content);
}
catch
{
LogHelper.Error("出错消息记录【id" + genMessage.Id + "msgSvrId" + genMessage.msgSvrId + "rootPath" + rootPath + ",username" + username + ",talker" + genMessage.talker + "】");
}
}
}
#endregion
#region
List<string> talkerList = waitGenHtmlList.Where(m => m.MsgType == 1).Select(p => p.talker).Distinct().ToList();
foreach (string username in talkerList)
{
var genLis = waitGenHtmlList.Where(p => p.talker == username).OrderBy(o => o.createTime).ToList();
foreach (var genMessage in genLis)
{
try
{
var time = DateTimeTool.GetTimeFromLinuxTime(genMessage.createTime);
var dir = string.Format("{0}/{1}", rootPath, username);
var path = string.Format("{0}_{1}.json", genMessage.talker, time.Year.ToString() + time.Month.ToString());
var content = Utility.ConvertToJSON(genMessage);
if (File.Exists(Path.Combine(dir, path)))
FileUnit.AppendFile(dir, path, "," + content);
else
FileUnit.AppendFile(dir, path, content);
}
catch
{
LogHelper.Error("出错消息记录【id" + genMessage.Id + "msgSvrId" + genMessage.msgSvrId + "rootPath" + rootPath + ",username" + username + ",talker" + genMessage.talker + "】");
}
}
}
#endregion
if ((!string.IsNullOrEmpty(_isMessageMonth) && _isMessageMonth == "1"))
{
#region
//IsMessageMonth配置不是空并且配置值等于1根据月份表来更新生成记录配置
var yearMonth = DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString("00");
if (tableName.Equals(yearMonth))
{
//如果是当前月份
var updateSql = "update wx_messageconfig set maxId = " + maxPkid + ", curId = " + maxPkid + " where tableMonth = '" + tableName + "'";
SqlHelper.ExcuteSPOrSql(SqlHelper.DatabaseType.AYCRM, updateSql, CommandType.Text);
}
else
{
var curTableSql = "select max(pkid) from wx_message" + tableName;
var curTableMaxPkid = SqlHelper.ExecuteScalar<int>(SqlHelper.DatabaseType.AYCRM, curTableSql, CommandType.Text);
if (curTableMaxPkid == maxPkid)
{
//如果最大的ID相等说明数据全都执行完了可以更新执行状态
var updateSql = "update wx_messageconfig set maxId = " + curTableMaxPkid + ", curId = " + maxPkid + ", isExe = 1 where tableMonth = '" + tableName + "'";
SqlHelper.ExcuteSPOrSql(SqlHelper.DatabaseType.AYCRM, updateSql, CommandType.Text);
//最新记录是否已经写入配置表,没有就写入
var existsSql = "select count(*) from wx_messageconfig where tableMonth='" + yearMonth + "'";
var isExists = SqlHelper.ExecuteScalar<int>(SqlHelper.DatabaseType.AYCRM, existsSql, CommandType.Text);
if (isExists == 0)
{
var insertSql = "insert into wx_messageconfig(month,maxId,curId,isExe,tableMonth) values('" + DateTime.Now.ToShortDateString() + "',0,0,0,'" + yearMonth + "')";
SqlHelper.ExcuteSPOrSql(SqlHelper.DatabaseType.AYCRM, insertSql, CommandType.Text);
}
}
else if (curTableMaxPkid > maxPkid)
{
var updateSql = "update wx_messageconfig set maxId = " + curTableMaxPkid + ", curId = " + maxPkid + " where tableMonht = '" + tableName + "'";
SqlHelper.ExcuteSPOrSql(SqlHelper.DatabaseType.AYCRM, updateSql, CommandType.Text);
}
else
{
LogHelper.Info("最大ID错误");
}
}
#endregion
}
else
{
para.Update_ParameterValueByKey("WxGenHtmlMaxRecordPkid", maxPkid.ToString());
}
}
catch (Exception ex)
{
LogHelper.Error("【WX.CRM.CRMServices.WeiXin.GenHtml.GenHtml.GenHtmlFile()】" + ex.ToString());
}
}
void GenOneHtmlFile(string IsCover, GenHtmlHelper.WxTemplateModel model, string htmlPath, int maxCount)
{
try
{
//处理模板文件
GenHtmlHelper exc = new GenHtmlHelper();
//循环标签
string foreachtemplate = "";
//获取模版
StringBuilder templatetext = exc.GetTemplate(out foreachtemplate);
if (IsCover == "0" && System.IO.File.Exists(htmlPath))
{
//如果存在追加
StringBuilder htmltext = exc.GetExtHtml(htmlPath);
exc.AppendExt(ref htmltext, model, foreachtemplate);
//保存生成的htm
exc.SaveHtmlFile(htmltext, htmlPath, maxCount);
}
else
{
//处理模板页标签
exc.ReplaceSign(ref templatetext, model, foreachtemplate);
//保存生成的htm
exc.SaveHtmlFile(templatetext, htmlPath, maxCount);
}
}
catch (Exception ex)
{
throw ex;
}
}
#region
private IList<GenMessage> GetWaitMessage(int maxPkid)
{
var tableName = "wx_gen_message";
//var hasBakTable = "wx_gen_message_bak";
//if (!string.IsNullOrEmpty(hasBakTable))
//{
// var sql2 = "select max(id) from " + hasBakTable;
// var maxId = SqlHelper.ExecuteScalar<int>(SqlHelper.DatabaseType.AYCRM, sql2, CommandType.Text);
// if (maxPkid < maxId)
// tableName = hasBakTable;
//}
//LogHelper.Info("生成数据表:" + tableName);
var sql = "select top 50000 * from " + tableName + " where id > @maxPkid order by id asc";
var p = new List<SqlParameter>() { new SqlParameter("@maxPkid", maxPkid) };
var ds = SqlHelper.GetDataSet(SqlHelper.DatabaseType.AYCRM, sql, CommandType.Text, p.ToArray());
var list = new List<GenMessage>();
if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
{
foreach (DataRow dataRow in ds.Tables[0].Rows)
{
int msgtype = 0;
if (dataRow["MsgType"] != DBNull.Value)
{
msgtype = int.Parse(string.Format("{0}", dataRow["MsgType"]));
}
var message = new GenMessage
{
Id = int.Parse(string.Format("{0}", dataRow["Id"])),
msgSvrId = string.Format("{0}", dataRow["msgSvrId"]),
type = int.Parse(string.Format("{0}", dataRow["type"])),
isSend = int.Parse(string.Format("{0}", dataRow["isSend"])),
createTime = long.Parse(string.Format("{0}", dataRow["createTime"])),
talker = dataRow["talker"].ToString(),
content = dataRow["content"].ToString(),
username = dataRow["username"].ToString(),
nickname = dataRow["nickname"].ToString(),
url = dataRow["url"].ToString(),
MsgType = msgtype,
isillegal = int.Parse(string.Format("{0}", dataRow["isillegal"])),
};
list.Add(message);
}
}
return list;
}
private IList<GenMessage> GetMessageByMonth(string tableName, int curPkid)
{
var sql = "select top 50000 * from wx_message" + tableName + " where pkid > @curPkid order by id desc";
var p = new List<SqlParameter>() { new SqlParameter("@curPkid", curPkid) };
var ds = SqlHelper.GetDataSet(SqlHelper.DatabaseType.AYCRM, sql, CommandType.Text, p.ToArray());
var list = new List<GenMessage>();
if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
{
foreach (DataRow dataRow in ds.Tables[0].Rows)
{
int msgtype = 0;
if (dataRow["talker"].ToString().EndsWith("@chatroom"))
{
msgtype = 1;
}
var message = new GenMessage
{
Id = int.Parse(string.Format("{0}", dataRow["pkid"])),
msgSvrId = string.Format("{0}", dataRow["msgSvrId"]),
type = int.Parse(string.Format("{0}", dataRow["msgtype"])),
isSend = int.Parse(string.Format("{0}", dataRow["isSend"])),
createTime = long.Parse(string.Format("{0}", dataRow["createTime"])),
talker = dataRow["talker"].ToString(),
content = dataRow["msgcontent"].ToString(),
username = dataRow["username"].ToString(),
nickname = dataRow["nickname"].ToString(),
url = dataRow["msgurl"].ToString(),
MsgType = msgtype,
isillegal = int.Parse(string.Format("{0}", dataRow["isillegal"])),
};
list.Add(message);
}
}
return list;
}
#endregion
#region html处理
/// <summary>
/// 过滤html
/// </summary>
/// <param name="Htmlstring"></param>
/// <returns></returns>
string RemoveHTML(string Htmlstring)
{
if (string.IsNullOrEmpty(Htmlstring))
return "";
//删除脚本
Htmlstring = Regex.Replace(Htmlstring, @"<script[^>]*?>.*?</script>", "", RegexOptions.IgnoreCase);
//删除HTML
Htmlstring = Regex.Replace(Htmlstring, @"<(.[^>]*)>", "", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"([\r\n])[\s]+", "", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"-->", "", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"<!--.*", "", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(quot|#34);", "\"", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(amp|#38);", "&", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(lt|#60);", "<", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(gt|#62);", ">", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(nbsp|#160);", " ", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(iexcl|#161);", "\xa1", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(cent|#162);", "\xa2", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(pound|#163);", "\xa3", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(copy|#169);", "\xa9", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&#(\d+);", "", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"<img[^>]*>;", "", RegexOptions.IgnoreCase);
Htmlstring.Replace("<", "");
Htmlstring.Replace(">", "");
Htmlstring.Replace("\r\n", "");
return Htmlstring;
}
string ConvertTime(decimal? d)
{
string s = "";
if (d == null)
return s;
try
{
s = WX.CRM.Common.Utility.ConvertStringToDateTime(d.ToString()).ToString();
}
catch { s = ""; }
return s;
}
string MsgTypeName(int typeid)
{
//typeid
//1文字
//3图片
//34语音
//47图片表情
//62小视频
//49微信电脑版文件
//48位置信息
//42名片
//50?
string n = "";
switch (typeid)
{
case 1:
n = "文字";
break;
case 3:
n = "图片";
break;
case 34:
n = "语音";
break;
case 47:
n = "图片表情";
break;
case 62:
n = "小视频";
break;
case 49:
n = "微信电脑版文件";
break;
case 48:
n = "位置信息";
break;
case 42:
n = "名片";
break;
}
return n;
}
bool HasFile(int typeId)
{
bool ret = false;
switch (typeId)
{
case 3:
ret = true;
break;
case 34:
ret = true;
break;
case 47:
ret = true;
break;
case 62:
ret = true;
break;
case 49:
ret = true;
break;
default:
ret = false;
break;
}
return ret;
}
MessageHtml MessageMap(GenMessage info)
{
var messageHtml = new MessageHtml()
{
MSGSVRID = info.msgSvrId.ToString(),
NICKNAME = info.nickname,
USERNAME = info.username,
CREATETIME = ConvertTime(info.createTime),
TALKER = info.talker,
MSG_CONTENT = RemoveHTML(info.content),
MSG_URL = info.url,
MSG_TYPE = MsgTypeName(info.type == null ? 0 : int.Parse(info.type.ToString()))
};
if (string.IsNullOrEmpty(info.url))
{
var hasFile = HasFile(info.type == null ? 0 : Int32.Parse(info.type.ToString()));
if (hasFile)
{
if (info.msgSvrId != null)
{
messageHtml.MSG_URL = "../../go.html?id=" + info.msgSvrId.ToString();
}
}
else
messageHtml.MSG_URL = "";
}
return messageHtml;
}
#endregion
}
public class GenHtmlJob : IJob
{
static bool isRuning = false;
public void Execute(JobExecutionContext context)
{
if (isRuning)
return;
isRuning = true;
try
{
new GenHtml().GenHtmlFile();
}
catch (Exception e)
{
LogHelper.Error("【AY.CRM.CRMServices.CRMJobs.WxGenHtmlJob.Execute()】 " + e);
}
finally
{
isRuning = false;
}
}
}
public class MessageHtml
{
public string MSGSVRID { get; set; }
public string NICKNAME { get; set; }
public string USERNAME { get; set; }
public string CREATETIME { get; set; }
public string TALKER { get; set; }
public string MSG_CONTENT { get; set; }
public string MSG_URL { get; set; }
public string MSG_TYPE { get; set; }
}
}