本人的毕业设计是做一个日程安排的软件或网站,提醒要求发送到用户手机。第一感觉是做成B/S结构要方便一些,所以选用了ASP.NET做,目前发现移动邮箱的页面挺符合我要求,但因本人暂无项目开发经验,很难下手,途中遇到很多关于日历绘制js技术问题和数据库查询提取用户提醒的频率问题。希望各位高手能给我技术上的帮助,最好是能有相关的源代码参考,好像一些OA系统的日程安排有类似的功能。
        现将移动邮箱中移动助理的模板截图如下,希望能在高手的帮助下做出类似的设计,谢谢!在线提醒系统设计样例:

解决方案 »

  1.   

    o,ding i wish you can do it best
      

  2.   

    我写的一个windows服务,定时查询数据库记录,有新的消息就发出去.用的诺亚短信猫,
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Data;
    using System.Diagnostics;
    using System.ServiceProcess;
    using System.Threading;
    using System.IO;
    using System.Globalization;namespace GSM_WindowsService
    {
    //==========================================================================================================================================================================================
    // 本服务用到的环境变量,需要在系统环境变量中手动输入
    // Gsm_TimeSpanMicSecond -----> 检查数据库的时间间隔(如果有新记录,则发送) 单位:毫秒 默认值:10000 推荐值:10000
    // Gsm_LogDir -----> 日志目录 单位: 默认值: 推荐值:c:\
    // Gsm_LogSizeKb -----> 日志限额,最大大小 单位:Kb 默认值:500 推荐值:500
    // Gsm_Port -----> 设备端口号 单位: 默认值: 推荐值:COM1
    // Gsm_Baud -----> 设备波特率 单位: 默认值: 推荐值:9600
    // Gsm_Key -----> 设备授权码 单位: 默认值: 推荐值:EPQP-TPDF-HDGQ-PFQE
    // Gsm_Len -----> 短信分块长度 单位: 默认值:70 推荐值:70
    // Gsm_SqlServerConn -----> 连接到短信数据库 连接字符串 单位: 默认值: 推荐值:server=127.0.0.1;uid=sa;pwd=123;DataBase=GsmMessage
    // Gsm_TimeAreaMinute 暂时不用 发送时间区间 (检索数据库中与当前日期相差 Gsm_TimeAreaMinute 分钟的所有记录)  则恢复
    //==========================================================================================================================================================================================
    public class GSM_WindowsService : System.ServiceProcess.ServiceBase
    {
    /// <summary> 
    /// 必需的设计器变量。
    /// </summary>
    private System.ComponentModel.Container components = null;
    private bool blnStopThread = false;//是否停止线程
    private string sqlstr = "";//sql查询字符串 //(与当前日期相差 指定 分钟的所有记录)  则恢复下面的语句
    //private string TimeArea = System.Environment.GetEnvironmentVariable("Gsm_TimeAreaMinute").ToString();//发送时间区间 private string TimeSpan = System.Environment.GetEnvironmentVariable("Gsm_TimeSpanMicSecond").ToString();//检查数据库的时间间隔
    private string LogDir = System.Environment.GetEnvironmentVariable("Gsm_LogDir").ToString();//日志目录
    private string LogSizeKb = System.Environment.GetEnvironmentVariable("Gsm_LogSizeKb").ToString();//日志限制大小
    private Thread thdMain; public GSM_WindowsService()
    {
    // 该调用是 Windows.Forms 组件设计器所必需的。
    InitializeComponent(); // TODO: 在 InitComponent 调用后添加任何初始化
    } // 进程的主入口点
    static void Main()
    {
    System.ServiceProcess.ServiceBase[] ServicesToRun;

    // 同一进程中可以运行多个用户服务。若要将
    //另一个服务添加到此进程,请更改下行
    // 以创建另一个服务对象。例如,
    //
    //   ServicesToRun = New System.ServiceProcess.ServiceBase[] {new Service1(), new MySecondUserService()};
    //
    ServicesToRun = new System.ServiceProcess.ServiceBase[] { new GSM_WindowsService() };
    System.ServiceProcess.ServiceBase.Run(ServicesToRun);
    } /// <summary> 
    /// 设计器支持所需的方法 - 不要使用代码编辑器 
    /// 修改此方法的内容。
    /// </summary>
    private void InitializeComponent()
    {
    // 
    // GSM_WindowsService
    // 
    //可以停止,继续
    this.CanPauseAndContinue = true;
    this.ServiceName = "GSM_WindowsService";
    } /// <summary>
    /// 清理所有正在使用的资源。
    /// </summary>
    protected override void Dispose( bool disposing )
    {
    if( disposing )
    {
    if (components != null) 
    {
    components.Dispose();
    }
    }
    base.Dispose( disposing );
    } /// <summary>
    /// 设置具体的操作,以便服务可以执行它的工作。
    /// </summary>
    protected override void OnStart(string[] args)
    {
    // TODO: 在此处添加代码以启动服务。
    blnStopThread = false;
    thdMain=new Thread(new ThreadStart(SendMessage));
    thdMain.Start();
    }
     
    /// <summary>
    /// 停止此服务。
    /// </summary>
    protected override void OnStop()
    {
    // TODO: 在此处添加代码以执行停止服务所需的关闭操作。

    blnStopThread=true;
    thdMain.Join();
    WriteLog("线程停止:" + "\t" + "停止成功");
    } protected override void OnPause()
    {
    if (thdMain.ThreadState == System.Threading.ThreadState.Running) 


    thdMain.Suspend(); 
    WriteLog("线程暂停:" + "\t" + "暂停成功");

    } protected override void OnContinue()
    {
    if (thdMain.ThreadState == System.Threading.ThreadState.Suspended) 
    {

    thdMain.Resume();
    WriteLog("线程继续:" + "\t" + "启动成功");
    }
    }
      

  3.   


    /// <summary>
    /// 主要的执行部分
    /// </summary>
    protected void SendMessage()
    {      
    DataSet ds = null;
    ArrayList SqlTran = null;//发送之前,将准备发送的信息加 逻辑锁
    WriteLog("线程启动:" + "\t" + "启动成功,Gsm_TimeSpanMinSecond=" + TimeSpan); while(blnStopThread == false)
    { //=====================================================================================================
    // 发送信息
    //查询所有没有发送的信息  
    //(与当前日期相差 指定 分钟的所有记录)  则恢复下面的语句
    //sqlstr = "select * from Tb_MessageQueue where Tag = 0 and DATEDIFF(minute, SendTime, getdate()) < " + TimeArea + "   order by PRI desc";
    sqlstr = "select * from Tb_MessageQueue where Tag = 0 and  SendTime <= getdate() order by PRI desc";

    try
    {
    ds = new DataSet();
    DbHelperSQL.Query(sqlstr,ref ds);

    if (ds != null && ds.Tables[0].Rows.Count != 0)
    {
    //如果有还没有发送的短信,则加入到发送队列,全部的状态改成  1 即 “正在处理”
    SqlTran = new ArrayList();
    for (int i = 0 ; i <= ds.Tables[0].Rows.Count -1 ; i++)
    {
    sqlstr = "update Tb_MessageQueue set Tag = 1 where ID =" + ds.Tables[0].Rows[i]["ID"].ToString();
    SqlTran.Add(sqlstr);
    }
    //执行sql事务,
    DbHelperSQL.ExecuteSqlTran(SqlTran);
    //开始循环发送
    for (int i = 0 ; i <= ds.Tables[0].Rows.Count -1 ; i++)
    { if (this.FastSendMessages(ds.Tables[0].Rows[i]["SendTo"].ToString(),ds.Tables[0].Rows[i]["Content"].ToString()) == true)
    {
    //如果发送成功,则置为 发送成功状态
    sqlstr = "update Tb_MessageQueue set Tag = 10 ,OverTime = '" + DateTime.Now + "' where ID =" + ds.Tables[0].Rows[i]["ID"].ToString();
    DbHelperSQL.ExecuteSql(sqlstr);
    }
    else
    {
    //如果发送失败,则置为 发送失败状态
    sqlstr = "update Tb_MessageQueue set Tag = -1 ,OverTime = '" + DateTime.Now + "' where ID =" + ds.Tables[0].Rows[i]["ID"].ToString();
    DbHelperSQL.ExecuteSql(sqlstr);
    }
    }
    }
    }
    catch(Exception ex)
    {
    WriteLog("严重错误:" + "\t" + ex.ToString());
    }
    finally
    {
    if (ds != null)
    {
    ds.Dispose();
    ds = null;
    //WriteLog("释放资源DataSet");
    }
    if (SqlTran != null)
    {
    SqlTran = null;
    //WriteLog("释放资源SqlTran");
    }
    } //=====================================================================================================
    //=====================================================================================================
    // 接收信息
    this.ReceiveMsgToDataBase(true);
    //===================================================================================================== //如果设定值不是数字,则默认进程睡眠时间  5秒钟
    try
    {
    Thread.Sleep(Convert.ToInt32(TimeSpan));
    }
    catch
    {
    WriteLog("线程休眠:" + "\t" + "休眠失败,环境变量Gsm_TimeSpanMinSecond设置错误,以10秒默认时间休眠,Gsm_TimeSpanMinSecond=" + TimeSpan);
    Thread.Sleep(10000);
    }
    // finally
    // {
    // WriteLog("线程休眠:" + "\t" + "休眠成功");
    // } }
    } #region 写日志
    protected void WriteLog(string Info)
    {
    //=============================
    //写入错误日志
    StreamWriter myWriter=null;
    try
    {
    string Dir = "";
    int FileLength = 500;//默认是500k的日志大小 if (LogDir.LastIndexOf('\\') == LogDir.Length -1)
    {
    //如果最后一个字符是\ 
    Dir = LogDir + "GSM_MyLog.txt";
    }
    else
    {
    //如果最后一个字符不是  \
    Dir = LogDir + "\\GSM_MyLog.txt";
    } try
    {
    FileLength = Convert.ToInt32(this.LogSizeKb);
    }
    catch
    {} //判断是否日志文件太大,如果超过限制,则清空
    FileInfo fi = new FileInfo(Dir);
    if (fi.Length >= (FileLength * 1024))
    {
    fi.Delete();
    } myWriter=new StreamWriter(Dir,true);
    myWriter.WriteLine(DateTime.Now.ToString() + "\t" + Info + "\r");
    myWriter.Close();
    }
    catch{}
    finally
    {
    if (myWriter != null)
    {
    myWriter = null;
    }

    } //=============================
    }
    #endregion  #region 发送函数
    /// <summary>
    /// 直接群发信息,无返回信息
    /// </summary>
    /// <param name="_phoneNumber">发送手机号,可以用;区分,也可以一个手机号码</param>
    /// <param name="_content">发送内容</param>
    /// <returns>是否全部发送成功  是=true 否=false</returns>
    protected bool FastSendMessages(string _phoneNumber,string _content)
    {
    string ErrMsg = "初始化";//失败信息

    bool _fail = false;//发送是否失败

    CommonClass cmu = new CommonClass();
    //连接设备
    try
    {
    cmu.InitDevice(out ErrMsg);
    }
    catch
    {}
                WriteLog("连接设备:" + "\t" + ErrMsg);

    //发送信息
    if (cmu.DeviceIsConn(out ErrMsg) == true)
    {
    //初始化设备成功
    string[] phoneList = _phoneNumber.Split(';');

    //循环检查手机号码合法性------------------
    WriteLog("↓--------------------------------");
    for (int i = 0 ; i <= phoneList.Length -1 ; i++)
    {
    //WriteLog("发送信息:" + "\t" + _content);
    if (cmu.Send(phoneList[i].ToString(),_content,false,out ErrMsg) == false)
    {
    _fail = true;
    }
    WriteLog(" 发送信息:" + "\t" + ErrMsg);
    }
    WriteLog("↑--------------------------------");
    }
    else
    {
    //WriteLog("设备状态检查:" + "\t" + ErrMsg);
    //设备没有连接上
    return false;
    }
    //发送完毕,释放设备 if (cmu.DeviceIsConn(out ErrMsg) == true)
    {
    //如果设备已经连接,则释放
    cmu.ReleaseDevice(out ErrMsg);
    WriteLog("释放设备:" + "\t" + ErrMsg);
    } if (_fail == true)
    {
    return false;
    }
    else
    {
    return true;
    }
    }
    #endregion
      

  4.   

    #region 接收函数
    /// <summary>
    /// 接收信息
    /// </summary>
    /// <param name="_clear">是否清除sim卡中的信息, 是=true(推荐)  否=false</param>
    /// <returns>是否接收成功 是=true  否=false</returns>
    public bool  ReceiveMsgToDataBase(bool _clear)
    {
    string _returnMsg = "";//程序运行信息
    try
    {
    CommonClass cmu = new CommonClass();
    string SMS_String = "";//短信接收所有的字符串

    //连接设备
    try
    {
    cmu.InitDevice(out _returnMsg);
    }
    catch
    {}
    if (cmu.DeviceIsConn(out _returnMsg) == true)
    {//如果设备连接成功
    SMS_String = cmu.Read(_clear, out _returnMsg);
    if (SMS_String != null && SMS_String != "")
    {//如果有信息
    SMS_String = SMS_String.Replace("||","■");
    //替换非法字符
    SMS_String.Replace("'","''");
    //删掉最后一个■
    SMS_String = SMS_String.Remove(SMS_String.Length -1,1);
    //将所有的字符串按照信息,一条一条的拆分成字符串数组
    string[] SMS_OneString = SMS_String.Split('■'); WriteLog("↓--------------------------------");
    //循环信息字符串数组,再一点一点的拆分内部的具体信息
    for (int i = 0 ; i <= SMS_OneString.Length - 1 ; i++)
    {
    try
    {
    string _temp = SMS_OneString[i].ToString();
    string[] _tempDetail = _temp.Split('|');
    string _SMS_TypeCode = _tempDetail[0].ToString();//短信编码
    string _SMS_Storage = _tempDetail[1].ToString();//短信存储位置
    string _SendTime = _tempDetail[2].ToString();//短信发送时间
    string _Sender = _tempDetail[3].ToString();//短信发送人的号码
    string _SMS_Code = _tempDetail[4].ToString();//短信编码
    string _SMS_Len = _tempDetail[5].ToString();//短信长度
    string _Content = _tempDetail[6].ToString();//短信内容

    //需要对发送日期进行处理,因为短信的发送日期为 07/24/07 10:00:51 (+0800) 的形式
    string _tempTime = _SendTime.Substring(0,17);
    DateTime dt = new DateTime();
    CultureInfo culture = new CultureInfo( "en-US" );
    try
    {
    dt = Convert.ToDateTime( _tempTime, culture );
    dt = Convert.ToDateTime(dt.ToString("{yyyy-MM-dd HH:mm:ss}"));
    }
    catch
    {
    WriteLog("写入数据:" + "\t" + "日期转换错误,供应商日期=" + _tempTime);
    dt = DateTime.Now;
    }


    string sqlstr = "insert into Tb_Receive (Sender,Content,SendTime,SMS_Code,SMS_Len,SMS_TypeCode,SMS_Storage) "
    +" values('" +_Sender + "','"
    + _Content.Replace("'","''") + "','"
    + dt.ToString() + "','"
    + _SMS_Code + "',"
    + _SMS_Len + ",'"
    + _SMS_TypeCode + "','"
    + _SMS_Storage + "'"
    +")";
    DbHelperSQL.ExecuteSql(sqlstr);
    WriteLog(" 接收信息:" + "\t" + "信息来自" + _Sender); }
    catch(Exception ex)
    {
    WriteLog("接收错误:" + "\t" + ex.ToString());
    }
    }
    WriteLog("↑--------------------------------");
    }
    }
    else
    {
    //设备连接失败
    return false;
    } if (cmu.DeviceIsConn(out _returnMsg) == true)
    {
    //如果设备已经连接,则释放
    cmu.ReleaseDevice(out _returnMsg);
    }

    return true;
    }
    catch(Exception ex)
    {
    WriteLog("严重错误:" + "\t" + ex.ToString());
    return false;
    }

    }
    #endregion }
    }
      

  5.   

    下面是公共类文件using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.Text.RegularExpressions;
    namespace GSM_WindowsService
    {
    /// <summary>
    /// CommonClass 的摘要说明。
    /// </summary>
    public class CommonClass
    {
    public static string _port = "";//端口号
    public static string _baud = "";//波特率
    public static string _key = "";//授权码
    public static int _len = 70;//短信拆分长度 public CommonClass()
    {
    _port =  System.Environment.GetEnvironmentVariable("Gsm_Port").ToString();//设备端口号
    _baud =  System.Environment.GetEnvironmentVariable("Gsm_Baud").ToString();//设备波特率
    _key =  System.Environment.GetEnvironmentVariable("Gsm_Key").ToString();//设备授权码 try
    {
    _len = Convert.ToInt32(System.Environment.GetEnvironmentVariable("Gsm_Len").ToString());//短信拆分长度
    }
    catch
    {
    _len = 70;
    }
    }
    #region 合法性检查函数

    /// <summary>
    /// 替换非法字符
    /// </summary>
    /// <param name="Temp">传入字符串</param>
    /// <returns>返回替换之后的字符串</returns>
    public static string ReplaceDangerCode (string Temp)
    {
    Temp = Temp.Replace("'","''"); 
    Temp = Temp.Replace("\"","");
    Temp = Temp.Replace("or","");
    Temp = Temp.Replace("&","");
    Temp = Temp.Replace("*","");
    Temp = Temp.Replace("select ","");
    Temp = Temp.Replace("insert ","");
    Temp = Temp.Replace("delete ","");
    Temp = Temp.Replace("count(","");
    Temp = Temp.Replace("drop table ","");
    Temp = Temp.Replace("update ","");
    Temp = Temp.Replace("truncate ","");
    Temp = Temp.Replace("asc(","");
    Temp = Temp.Replace("mid(","");
    Temp = Temp.Replace("char(","");
    Temp = Temp.Replace("xp_cmdshell","");
    Temp = Temp.Replace("exec master","");
    Temp = Temp.Replace("net localgroup administrators","");
    Temp = Temp.Replace(" and ","");
    Temp = Temp.Replace("net user","");
    Temp = Temp.Replace(" or ","");
    return Temp;
    } #region 初始化modem
    /// <summary>
    /// 初始化短信猫并返回是否连接成功
    /// </summary>
    /// <param name="_returnMsg">out返回参数,具体的错误信息或者连接成功信息</param>
    /// <returns>bool  连接成功=true   连接失败=false</returns>
    public bool InitDevice(out string _returnMsg)
    {
    try
    {
    if (_port == "" || _baud == "" || _key == "")
    {
    _returnMsg = "读取配置文件失败,请检查环境变量配置";
    return false;
    } if(GSMModem.GSMModemInit(_port, _baud, null, null, false, _key)==true)
    {
    //连接成功
    _returnMsg = "连接成功";
    return true;
    }
    else
    {
    _returnMsg = "连接失败!" + GSMModem.GSMModemGetErrorMsg(_port);
    }
    return false;
    }
    catch(Exception ex)
    {
    _returnMsg = ex.ToString();
    return false;
    }
    }
    #endregion #region 释放modem
    /// <summary>
    /// 释放短信猫并返回是否释放成功
    /// </summary>
    /// <param name="_returnMsg">out返回参数,具体的错误信息或者连接成功信息</param>
    /// <returns>bool  释放成功=true   释放失败=false</returns>
    public bool ReleaseDevice(out string _returnMsg)
    {
    try
    {
    if (_port == "")
    {
    _returnMsg = "读取配置文件失败,请检查环境变量配置";
    return false;
    } GSMModem.GSMModemRelease(_port);
    _returnMsg = "释放成功";
    return true;
    }
    catch(Exception ex)
    {
    _returnMsg = ex.ToString();
    return false;
    }
    }
    #endregion #region modem当前连接状态
    /// <summary>
    /// modem当前连接状态
    /// </summary>
    /// <param name="_returnMsg">out返回参数,具体的程序运行信息</param>
    /// <returns>bool  已经连接=true   没有连接=false</returns>
    public bool DeviceIsConn(out string _returnMsg)
    {
    try
    {
    if (_port == "" )
    {
    _returnMsg = "读取配置文件失败,请检查环境变量配置";
    return false;
    }
    //判断是否连接
    if (GSMModem.GSMModemIsConn(_port) == true)
    {
    //如果已经连接
    _returnMsg = "设备已经被连接。";
    return true;
    }
    else
    {
    //如果没有连接
    _returnMsg = "设备没有被连接。";
    return false;
    }
    }
    catch(Exception ex)
    {
    _returnMsg = ex.ToString();
    return true;
    }
    }
    #endregion #region 发送一条信息
    /// <summary>
    /// 发送一条信息
    /// </summary>
    /// <param name="_phoneNumber">发送给那个手机号码</param>
    /// <param name="_content">发送内容</param>
    /// <param name="_report">是否需要返回发送报告.   需要=true   不需要=false</param>
    /// <param name="_returnMsg">out返回参数,具体的返回程序运行信息</param>
    /// <returns>信息是否发送成功   成功=true  失败=false</returns>
    public bool Send( string _phoneNumber,string _content,bool _report, out string _returnMsg)
    {
    try
    {
    int _smslen = 0;//信息单字节长度
    bool Result;//发送结果
    string _SendText = ""; //发送的字符串,必须在指定长度 _len 的范围内
     
    _smslen = System.Text.Encoding.Default.GetByteCount(_content);
    //只发送前指定的 _len 个字符  移动默认是70 //-----------------------------
    //长度处理
    if (_content.Length > _len)
    {
    //如果准备发送的内容大于指定的最大长度,则发送前 _len 个字符,剩下的递归调用
    _SendText = _content.Substring(0,_len);
    }
    else
    {
    //如果准备发送的内容小于规定的 _len 长度 ,则直接发送就可以
    _SendText = _content;
    }
    //-----------------------------
    if(GSMModem.GSMModemSMSsend(_port,null, 8,_SendText, _smslen, _phoneNumber, _report) == true)
    {
    _returnMsg = _phoneNumber + "短信发送成功!";
    Result = true;
    }
    else
    {
    _returnMsg = _phoneNumber + "短信发送失败!" + GSMModem.GSMModemGetErrorMsg(_port);
    Result = false;
    } if (Result == true && _content.Length > _len )
    {//如果发送成功,信息内容大于指定字符个数,现在移动的是70个字符
    //如果大于,则调用递归
    Send( _phoneNumber,_content.Substring(_len,(_content.Length - _len)), _report, out  _returnMsg);
    }
    return Result;

    }
    catch(Exception ex)
    {
    _returnMsg = ex.ToString();
    return false;
    }
    }
    #endregion #region 接收信息串 /// <summary>
    /// 接收信息串
    /// </summary>
    /// <param name="_clear">是否清空sim卡存储的短信   是=true  否=false</param>
    /// <param name="_returnMsg">out返回参数,程序运行信息</param>
    /// <returns>返回信息串</returns>
    public string Read( bool _clear,out string _returnMsg)
    {
    string _returnSMS = "";//返回短信字符串 if (_clear == true)
    {
    //清除信息
    _returnSMS = GSMModem.GSMModemSMSReadAll(_port,0);
    _returnMsg = GSMModem.GSMModemGetErrorMsg(_port);
    }
    else
    {
    //保留信息
    _returnSMS = GSMModem.GSMModemSMSReadAll(_port,1);
    _returnMsg = GSMModem.GSMModemGetErrorMsg(_port);
    }
    return _returnSMS;
    } #endregion }
    }