500 lines
22 KiB
C#
500 lines
22 KiB
C#
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; }
|
||
}
|
||
}
|