/// <summary>
        /// 生日提醒任务
        /// </summary>
        /// <param name="state"></param>
        private void BirthdayRemind(object state)
        {
            if ((DateTime.Now - lastRemindTime).TotalSeconds >= 60) //1分钟提醒一次
            {
                var dtUser = Tmo_FakeEntityManager.Instance.GetData("tmo_userinfo",
                                                                    new[] { "user_id", "name", "plan_birthday", "doc_id" },
                                                                    string.Format(
                                                                        "(birthday_remid_year is null or birthday_remid_year<{0}) and plan_birthday is not null and doc_id is not null",
                                                                        DateTime.Now.Year));
                if (TmoShare.DataTableIsNotEmpty(dtUser))
                {
                    foreach (DataRow dr in dtUser.Rows)
                    {
                        DateTime birthday = dr.GetDataRowDateTimeValue("plan_birthday");
                        if (birthday.Month == DateTime.Now.Month && birthday.Day == DateTime.Now.Day) //过生日
                        {
                            string userid = dr.GetDataRowStringValue("user_id");
                            string name   = dr.GetDataRowStringValue("name");
                            string docid  = dr.GetDataRowStringValue("doc_id");
                            PushInvoke.SendDocInvoke(docid, 102, userid + ";" + name);
                        }
                    }
                }

                lastRemindTime = DateTime.Now;
            }

            ((ManualResetEvent)((object[])state)[0]).Set();
        }
        /// <summary>
        /// 消息推送任务
        /// </summary>
        /// <param name="state"></param>
        private void PushMessage(object state)
        {
            if ((DateTime.Now - lastPushMsgTime).TotalSeconds >= 30) //30秒检查一次
            {
                var dtMsg = Tmo_FakeEntityManager.Instance.GetData("tmo_pushmsg", new[] { "id", "doc_code", "doc_department", "doc_group", "read_user" },
                                                                   "isRead='1' and input_time>=date_sub(NOW(),INTERVAL 1 MONTH);");
                if (TmoShare.DataTableIsNotEmpty(dtMsg))
                {
                    foreach (TCPServerClient client in TCPServer.Instance.Clients.ToArray())
                    {
                        if (client.DocInfo != null)
                        {
                            DataRow[] rows = dtMsg.Select(
                                string.Format(
                                    "doc_code='{0}' or (doc_department LIKE '%,{1},%' and (read_user not like '%,{0},%' or read_user is null)) or (doc_group='{2}' and (read_user not like '%,{0},%' or read_user is null))",
                                    client.DocInfo.doc_loginid, client.DocInfo.doc_department, client.DocInfo.doc_group));
                            if (rows.Length > 0)
                            {
                                //有消息推送
                                PushInvoke.SendDocInvoke(client.DocInfo.doc_id.ToString(), 103, rows.Length.ToString());
                            }
                        }
                    }
                }

                lastPushMsgTime = DateTime.Now;
            }

            ((ManualResetEvent)((object[])state)[0]).Set();
        }
        private DateTime lastMianTime   = DateTime.MinValue; //面访上次提醒日期

        /// <summary>
        /// 定时执行干预任务
        /// </summary>
        /// <param name="state"></param>
        private void ExecIntervene(object state)
        {
            FE_GetDataParam param = new FE_GetDataParam()
            {
                Sources        = "tmo_intervene",
                PrimaryKey     = "inte_id",
                Columns        = { "tmo_userinfo.name", "tmo_userinfo.gender", "tmo_userinfo.age", "tmo_userinfo.phone", "tmo_intervene.*" },
                JoinConditions = { new JoinCondition()
                                   {
                                       JoinType = EmJoinType.LeftJoin, Table = "tmo_userinfo", OnCol = "user_id"
                                   } }
            };

            param.AddWhere("inte_status in (1,2)");

            var ds = Tmo_FakeEntityManager.Instance.GetData(param); //获取未执行的干预

            if (TmoShare.DataSetIsNotEmpty(ds))
            {
                bool canNotice = (DateTime.Now - lastNoticeTime).TotalSeconds >= 30;
                var  dt        = ds.Tables["tmo_data"];
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    var    dr      = dt.Rows[i];
                    string inte_id = dr.GetDataRowStringValue("inte_id");
                    try
                    {
                        string   inte_content  = dr.GetDataRowStringValue("inte_content");
                        int      inte_way      = dr.GetDataRowIntValue("inte_way"); //干预方式 1-邮件 2-短信  3-电话 4-面访
                        int      doc_id        = dr.GetDataRowIntValue("doc_id");
                        string   inte_addr     = dr.GetDataRowStringValue("inte_addr");
                        DateTime inte_plantime = dr.GetDataRowDateTimeValue("inte_plantime");
                        TimeSpan diffSpan      = DateTime.Now - inte_plantime; //现在时间距离计划时间的时间差
                        int      failMin       = 30;                           //过期时间 单位:分钟
                        if (Debugger.IsAttached)
                        {
                            failMin = 60 * 24 * 3;
                        }
                        if (inte_way == 3)
                        {
                            failMin = 60 * 12;                //电话12小时过期
                        }
                        if (inte_way == 4)
                        {
                            failMin = 60 * 24;                                                 //面访24小时过期
                            if (diffSpan.TotalMinutes > -failMin && diffSpan.TotalMinutes < 0) //提前24小时提醒
                            {
                                if ((DateTime.Now - lastMianTime).TotalMinutes >= 30)
                                {
                                    string str =
                                        string.Format("面访任务提醒\n时间 [{0}]\n客户信息 [{1},{2},{3}岁]\n手机号码 {4}\n面访地址 {5}\n请提前做好准备!",
                                                      inte_plantime.ToString("yyyy年MM月dd日HH点mm分"), dr.GetDataRowStringValue("name"),
                                                      dr.GetDataRowIntValue("gender") == 1 ? "男" : "女",
                                                      dr.GetDataRowStringValue("age"), dr.GetDataRowStringValue("phone"), inte_addr);
                                    bool sendsuc = PushInvoke.SendDocInvoke(doc_id.ToString(), 0, str);
                                    if (sendsuc)
                                    {
                                        lastMianTime = DateTime.Now;
                                    }
                                }

                                continue;
                            }
                        }

                        if (diffSpan.Ticks < 0)
                        {
                            continue;                        //未到执行时间
                        }
                        if (diffSpan.TotalMinutes > failMin) //干预过期
                        {
                            tmo_interveneManager.Instance.SetInterveneFailed(inte_id, "干预过期");
                            continue;
                        }

                        int inte_status = dr.GetDataRowIntValue("inte_status"); //更改执行状态
                        if (inte_status == 1)
                        {
                            tmo_interveneManager.Instance.SetInterveneExecing(inte_id);
                            continue;
                        }

                        PushType pushtype = PushType.doc_wechat; //默认类型 此类型无效
                        switch (inte_way)
                        {
                        case 1:
                            pushtype = PushType.user_mail;
                            break;

                        case 2:
                            pushtype = PushType.user_sms;
                            break;

                        case 3:     //电话干预
                            if (canNotice)
                            {
                                string title = "请执行电话干预";
                                string msg   = string.Format("有一个电话干预需要执行:\n时间 [{0}]\n客户信息 [{1},{2},{3}岁]\n电话号码 [{4}]\n点击查看详情并填写执行结果!",
                                                             inte_plantime.ToString("yyyy年MM月dd日HH点mm分"), dr.GetDataRowStringValue("name"),
                                                             dr.GetDataRowIntValue("gender") == 1 ? "男" : "女",
                                                             dr.GetDataRowStringValue("age"), inte_addr);
                                string sendStr = title + ";" + msg + ";" + inte_id;
                                bool   sendsuc = PushInvoke.SendDocInvoke(doc_id.ToString(), 100, sendStr);
                                if (sendsuc)
                                {
                                    lastNoticeTime = DateTime.Now;
                                }
                            }

                            break;

                        case 4:     //面访干预
                            if (canNotice)
                            {
                                string title = "请执行面访干预";
                                string msg   = string.Format("有一个面访干预需要执行:\n时间 [{0}]\n客户信息 [{1},{2},{3}岁]\n手机号码 [{4}]\n面访地址 {5}\n点击查看详情并填写执行结果!",
                                                             inte_plantime.ToString("yyyy年MM月dd日HH点mm分"), dr.GetDataRowStringValue("name"),
                                                             dr.GetDataRowIntValue("gender") == 1 ? "男" : "女",
                                                             dr.GetDataRowStringValue("age"), dr.GetDataRowStringValue("phone"), inte_addr);
                                string sendStr = title + ";" + msg + ";" + inte_id;
                                bool   sendsuc = PushInvoke.SendDocInvoke(doc_id.ToString(), 101, sendStr);
                                if (sendsuc)
                                {
                                    lastNoticeTime = DateTime.Now;
                                }
                            }

                            break;

                        default:
                            throw new Exception("干预方式参数无效");
                        }

                        if (pushtype == PushType.doc_wechat || pushtype == PushType.None)
                        {
                            continue;                                                               //未知方式取消推送
                        }
                        string inte_reason = dr.GetDataRowStringValue("inte_reason");
                        if (inte_reason == "sending")
                        {
                            continue;                           //发送中跳过
                        }
                        string inte_title = dr.GetDataRowStringValue("inte_title");
                        if (string.IsNullOrWhiteSpace(inte_title))
                        {
                            inte_title = "健康干预";
                        }
                        string user_id = dr.GetDataRowStringValue("user_id");

                        Dictionary <string, object> dicVals = new Dictionary <string, object>();
                        dicVals.Add("push_id", inte_id);
                        dicVals.Add("user_code", user_id);
                        dicVals.Add("push_type", (int)pushtype);
                        dicVals.Add("push_address", inte_addr);
                        dicVals.Add("content_type", "1");
                        dicVals.Add("content_title", inte_title);
                        dicVals.Add("content_value", inte_content);
                        dicVals.Add("push_status", 1);
                        dicVals.Add("doc_code", doc_id);

                        bool suc = tmo_push_listManager.Instance.AddToPushList(dicVals);
                        if (suc)
                        {
                            dicVals.Clear();
                            dicVals.Add("inte_reason", "sending");
                            Tmo_FakeEntityManager.Instance.SubmitData(DBOperateType.Update, "tmo_intervene", "inte_id", inte_id, dicVals);
                        }
                    }
                    catch (Exception ex)
                    {
                        LogHelper.Log.Error("干预任务解析失败!", ex);
                        tmo_interveneManager.Instance.SetInterveneFailed(inte_id, "干预任务解析失败:" + ex.Message);
                    }
                }
            }

            ((ManualResetEvent)((object[])state)[0]).Set();
        }