using System;
using System.Web;
using System.Collections;
using System.Data;
using System.Data.SqlClient;
using System.Text.RegularExpressions;

namespace UUN
{
    /// <summary>
    /// 对用户的读取、数据处理。
    /// </summary>
    public class 用户
    {
        public HttpContext HC;
        public SqlConnection 连接;
        public 用户(HttpContext HC,SqlConnection 连接)
        {
            this.HC = HC;
            this.连接 = 连接;
        }

        /// <summary>
        /// 利用标识的方式登录并返回一个用户数据集合，如果登录失败，则返回一个游客用户。
        /// </summary>
        /// <param name="标识">用户的标识</param>
        /// <returns>用户的数据集合</returns>
        public Hashtable 用户登录(String 标识)
        {
            Hashtable 返回值 = null;

            if (标识 != null)
                返回值 = 获取用户(标识);

            if (返回值 == null)
                返回值 = 获取游客_在线();

            if(返回值==null)
                返回值=获取游客_离线();

            if (返回值 == null)
                返回值 = 创建游客();

            return 返回值;
        }

        private Hashtable 获取游客_在线()
        {
            SqlCommand 语句 = new SqlCommand("SELECT [ID],[昵称],[标识],[用户类型],[最后访问时间],[最后登录时间],[最后登录IP],[最后登录地区],[所在位置],[用户组] FROM ["+程序.数据表前缀+"社区_用户_用户] WHERE [最后访问时间]>@最后访问时间 AND [最后登录IP]=@最后登录IP AND [用户类型]='游客'", 连接);
            语句.Parameters.Add("@最后访问时间", SqlDbType.DateTime).Value = DateTime.Now - new TimeSpan(0, Convert.ToInt32(程序.设置["离线时间"]), 0);
            语句.Parameters.Add("@最后登录IP", SqlDbType.NVarChar).Value = HC.Request.UserHostAddress;

            return 常用.SQL_获取(语句);
        }

        private Hashtable 获取游客_离线()
        {
            SqlCommand 语句 = new SqlCommand("SELECT [ID],[昵称],[标识],[用户类型],[最后访问时间],[最后登录时间],[最后登录IP],[最后登录地区],[所在位置],[用户组] FROM [" + 程序.数据表前缀 + "社区_用户_用户] WHERE [最后访问时间]<@最后访问时间 AND [用户类型]='游客'", 连接);
            语句.Parameters.Add("@最后访问时间", SqlDbType.NVarChar).Value = DateTime.Now - new TimeSpan(0, Convert.ToInt32(程序.设置["离线时间"]), 0);

            return 常用.SQL_获取(语句);
        }

        private Hashtable 创建游客()
        {
            int 最高ID=常用.SQL_最高ID(连接,程序.数据表前缀+"社区_用户_用户");

            Hashtable 返回值=new Hashtable();
            返回值["ID"]=最高ID;
            返回值["昵称"]="游客"+最高ID;
            返回值["密码"]="";
            返回值["标识"] = "U" + 最高ID + 常用.随机字符(30);
            返回值["用户类型"] = "游客";
            返回值["最后访问时间"] = DateTime.Now;
            返回值["最后登录时间"] = DateTime.Now;
            返回值["最后登录IP"] = HC.Request.UserHostAddress;
            返回值["最后登录地区"] = 常用.获取城市(连接, HC.Request.UserHostAddress);

            SqlCommand 语句 = new SqlCommand("INSERT INTO [" + 程序.数据表前缀 + "社区_用户_用户]([ID],[昵称],[手机号],[密码],[标识],[用户类型],[最后访问时间],[最后登录时间],[最后登录IP],[最后登录地区])VALUES(@ID,@昵称,@手机号,@密码,@标识,@用户类型,@最后访问时间,@最后登录时间,@最后登录IP,@最后登录地区)", 连接);
            语句.Parameters.Add("@ID", SqlDbType.Int).Value = 返回值["ID"];
            语句.Parameters.Add("@昵称", SqlDbType.NVarChar).Value = 返回值["昵称"];
            语句.Parameters.Add("@手机号", SqlDbType.NVarChar).Value = "00000000000";
            语句.Parameters.Add("@密码", SqlDbType.NVarChar).Value = 返回值["密码"];
            语句.Parameters.Add("@标识", SqlDbType.NVarChar).Value = 返回值["标识"];
            语句.Parameters.Add("@用户类型", SqlDbType.NVarChar).Value = 返回值["用户类型"];
            语句.Parameters.Add("@最后访问时间", SqlDbType.DateTime).Value = 返回值["最后访问时间"];
            语句.Parameters.Add("@最后登录时间", SqlDbType.DateTime).Value = 返回值["最后登录时间"];
            语句.Parameters.Add("@最后登录IP", SqlDbType.NVarChar).Value = 返回值["最后登录IP"];
            语句.Parameters.Add("@最后登录地区", SqlDbType.NVarChar).Value = 返回值["最后登录地区"];
            语句.ExecuteNonQuery();

            return 返回值;
        }
        /// <summary>
        /// 登录一个管理员并返回新的标识
        /// </summary>
        /// <param name="昵称">管理员的昵称</param>
        /// <param name="密码">管理员的密码</param>
        /// <returns>新的标识</returns>
        public String 管理员登录(String 昵称, String 密码)
        {
            SqlCommand 语句 = new SqlCommand("SELECT [ID] FROM [" + 程序.数据表前缀 + "社区_用户_用户] WHERE [昵称]=@昵称 AND [密码]=@密码 AND [用户类型]='管理员'", 连接);
            语句.Parameters.Add("@昵称", SqlDbType.NVarChar).Value = 昵称;
            语句.Parameters.Add("@密码", SqlDbType.NVarChar).Value = 常用.MD5加密(常用.MD5加密(密码));

            Hashtable 管理员 = 常用.SQL_获取(语句);
            String 所在地区=常用.获取城市(连接,HC.Request.UserHostAddress);

            访问统计_管理员登录日志 管理员登录日志 = new 访问统计_管理员登录日志(HC, 连接);
            if (管理员 == null)
            {
                管理员登录日志.记录(HC.Request.UserHostAddress,
                    所在地区, 昵称, false);
                throw new Exception("管理员登录失败");
            }
            else
            {
                String 新标识 = "U" + 管理员["ID"] + 常用.随机字符(30);
                语句 = new SqlCommand("UPDATE [" + 程序.数据表前缀 + "社区_用户_用户] SET [标识]=@标识,[最后登录时间]=@最后登录时间,[最后登录IP]=@最后登录IP,[最后登录地区]=@最后登录地区 WHERE [ID]=" + 管理员["ID"], 连接);
                语句.Parameters.Add("@标识", SqlDbType.NVarChar).Value =  新标识;
                语句.Parameters.Add("@最后登录时间", SqlDbType.NVarChar).Value = DateTime.Now;
                语句.Parameters.Add("@最后登录IP", SqlDbType.NVarChar).Value = HC.Request.UserHostAddress;
                语句.Parameters.Add("@最后登录地区", SqlDbType.NVarChar).Value = 所在地区;
                语句.ExecuteNonQuery();
                管理员登录日志.记录(HC.Request.UserHostAddress,
                    所在地区, 昵称, true);
                return 新标识;
            }
        }
        /// <summary>
        /// 登录一个会员并返回新的标识
        /// </summary>
        /// <param name="登录类型">会员的登录类型</param>
        /// <param name="用户">会员用户</param>
        /// <param name="密码">会员的密码</param>
        /// <returns>新的标识</returns>
        public String 会员登录(int 登录类型, String 用户, String 密码)
        {
            SqlParameter 参数;
            String SQL = "SELECT [ID] FROM [" + 程序.数据表前缀 + "社区_用户_用户] WHERE [密码]=@密码 AND ";
            String SQLH;
            switch (登录类型)
            {
                case 0:
                    SQLH = "[ID]=@ID";
                    参数 = new SqlParameter("@ID", SqlDbType.Int);
                    参数.Value = Convert.ToInt32(用户);
                    break;
                case 1:
                    SQLH = "[手机号]=@手机号";
                    参数 = new SqlParameter("@手机号", SqlDbType.NVarChar);
                    参数.Value = 用户;
                    break;
                default:
                    SQLH = "[昵称]=@昵称";
                    参数 = new SqlParameter("@昵称", SqlDbType.NVarChar);
                    参数.Value = 用户;
                    break;
            }
            SqlCommand 语句 = new SqlCommand(SQL+SQLH, 连接);
            语句.Parameters.Add("@密码", SqlDbType.NVarChar).Value = 常用.MD5加密(常用.MD5加密(密码));
            语句.Parameters.Add(参数);
            SqlDataReader 读取 = 语句.ExecuteReader();
            int 用户ID;
            if (读取.Read())
                用户ID = Convert.ToInt32(读取["ID"]);
            else
                用户ID = 0;
            读取.Close();

            if (用户ID==0)
                throw new Exception("登录失败，请检查您的用户和密码。");

            String 标识 = "U" + 用户ID + 常用.随机字符(30);
            语句 = new SqlCommand("UPDATE [" + 程序.数据表前缀 + "社区_用户_用户] SET [标识]=@标识," +
                "[最后登录时间]=@最后登录时间,"+
                "[最后登录IP]=@最后登录IP,"+
                "[最后登录地区]=@最后登录地区"+
                " WHERE " + SQLH, 连接);
            语句.Parameters.Add("@标识", SqlDbType.NVarChar).Value = 标识;
            语句.Parameters.Add("@最后登录时间", SqlDbType.DateTime).Value = DateTime.Now;
            语句.Parameters.Add("@最后登录IP", SqlDbType.NVarChar).Value = HC.Request.UserHostAddress;
            语句.Parameters.Add("@最后登录地区", SqlDbType.NVarChar).Value = 常用.获取城市(连接, HC.Request.UserHostAddress);
            语句.Parameters.Add(参数.ParameterName, 参数.SqlDbType).Value = 参数.Value;
            语句.ExecuteNonQuery();

            HttpCookie HCK = new HttpCookie("UUN_UUN3G_BiaoShi", 标识);
            HCK.Expires = DateTime.Now + new TimeSpan(1, 0, 0, 0);
            HC.Response.Cookies.Add(HCK);

            return 标识;
        }

        /// <summary>
        /// 根据标识获取一个用户
        /// </summary>
        /// <param name="标识">用户的标识</param>
        /// <returns>用户的信息数据集合</returns>
        public Hashtable 获取用户(String 标识)
        {
            String SQL = "SELECT [ID],[昵称],[性别],[标识],[用户类型],[积分],[最后访问时间],[最后登录时间],[最后登录IP],[最后登录地区],[等级],[经验],[累积_秒],[所在位置],[是否加黑],[用户组],[一页显示记录数],[一页显示文字数],[一页显示图片数],[一页显示文件数] FROM [" + 程序.数据表前缀 + "社区_用户_用户] WHERE [标识]=@标识";
            if (!Convert.ToBoolean(程序.设置["离线后重新访问"]))
                SQL += " AND [最后访问时间]>@最后访问时间";
            if (!Convert.ToBoolean(程序.设置["IP变化后"]))
                SQL += " AND [最后登录IP]=@最后登录IP";

            SqlCommand 语句 = new SqlCommand(SQL, 连接);
            语句.Parameters.Add("@标识", SqlDbType.NVarChar).Value = 标识;
            if (!Convert.ToBoolean(程序.设置["离线后重新访问"]))
                语句.Parameters.Add("@最后访问时间", SqlDbType.DateTime).Value = DateTime.Now - new TimeSpan(0, Convert.ToInt32(程序.设置["离线时间"]), 0);
            if (!Convert.ToBoolean(程序.设置["IP变化后"]))
                语句.Parameters.Add("@最后登录IP", SqlDbType.NVarChar).Value = HC.Request.UserHostAddress;

            return 常用.SQL_获取(语句);
        }
        /// <summary>
        /// 更新指定用户的访问信息，一般用户是当前访问的用户
        /// </summary>
        /// <param name="用户">用户的数据集合</param>
        /// <param name="位置">用户现在所在的位置</param>
        public void 更新登录信息(Hashtable 用户,String 位置)
        {
            if (Convert.ToString(用户["用户类型"]) == "游客")
                更新登录信息_游客(用户,位置);
            else
                更新登录信息_会员(用户,位置);
        }

        private void 更新登录信息_游客(Hashtable 用户,String 位置)
        {
            String SQL = "UPDATE [" + 程序.数据表前缀 + "社区_用户_用户] SET [最后访问时间]=@最后访问时间,[所在位置]=@所在位置" +
                (Convert.ToString(用户["最后登录IP"])!=HC.Request.UserHostAddress?",[最后登录IP]=@最后登录IP,[最后登录地区]=@最后登录地区":"")+
                (Convert.ToDateTime(用户["最后访问时间"])<DateTime.Now-new TimeSpan(0,Convert.ToInt32(程序.设置["离线时间"]),0)?",[最后登录时间]=@最后登录时间":"")+
                ",[今日访问次数]=[今日访问次数]+1 WHERE [ID]="+用户["ID"];
            SqlCommand 语句 = new SqlCommand(SQL, 连接);
            语句.Parameters.Add("@最后访问时间", SqlDbType.DateTime).Value = DateTime.Now;
            语句.Parameters.Add("@所在位置", SqlDbType.NVarChar).Value = 位置;

            if (Convert.ToString(用户["最后登录IP"]) != HC.Request.UserHostAddress)
            {
                用户["最后登录IP"] = HC.Request.UserHostAddress;
                用户["最后登录地区"] = 常用.获取城市(连接, HC.Request.UserHostAddress);

                语句.Parameters.Add("@最后登录IP", SqlDbType.NVarChar).Value = 用户["最后登录IP"];
                语句.Parameters.Add("@最后登录地区", SqlDbType.NVarChar).Value = 用户["最后登录地区"];
            }

            if (Convert.ToDateTime(用户["最后访问时间"]) < DateTime.Now - new TimeSpan(0, Convert.ToInt32(程序.设置["离线时间"]), 0))
                语句.Parameters.Add("@最后登录时间", SqlDbType.DateTime).Value = DateTime.Now;

            语句.ExecuteNonQuery();

            if(Convert.ToBoolean(程序.设置["是否启用IP统计"]))
                if (Convert.ToDateTime(用户["最后访问时间"]) < DateTime.Now - new TimeSpan(0, 30, 0)
                    ||Convert.ToString(用户["最后登录IP"])!=HC.Request.UserHostAddress)
                {
                    访问统计_IP记录 IP记录 = new 访问统计_IP记录(HC, 连接);
                    IP记录.记录(Convert.ToString(用户["最后登录IP"]), Convert.ToString(用户["最后登录地区"]));
                    更新在线人数();
                }
        }

        private void 获取等级信息(Hashtable 用户,out int 等级, out int 经验, out int 累积_秒, out int 积分)
        {
            累积_秒 = Convert.ToInt32(用户["累积_秒"]);
            经验 = Convert.ToInt32(用户["经验"]);
            等级 = Convert.ToInt32(用户["等级"]);
            积分 = Convert.ToInt32(用户["积分"]);

            if (Convert.ToDateTime(用户["最后访问时间"]) > DateTime.Now - new TimeSpan(0, Convert.ToInt32(程序.设置["离线时间"]), 0))
            {
                int 产生秒数 = Convert.ToInt32((DateTime.Now - Convert.ToDateTime(用户["最后访问时间"])).TotalSeconds);
                if (产生秒数 > 300)
                    产生秒数 = 300;
                累积_秒 += 产生秒数;
                int 增加一经验需积累秒数=Convert.ToInt32(程序.设置["增加一经验需积累秒数"]);
                if (累积_秒 >= 增加一经验需积累秒数)
                {
                    经验 += 累积_秒 / 增加一经验需积累秒数;
                    累积_秒 = 累积_秒 % 增加一经验需积累秒数;
                }

                int 需要经验 =Convert.ToInt32(字符串计算.计算结果(Convert.ToString(程序.设置["升级规则"]).Replace("$等级$",等级.ToString())));
                if (经验 >= 需要经验)
                {
                    int 增加积分 = Convert.ToInt32(字符串计算.计算结果(Convert.ToString(程序.设置["每升一级赠送积分"]).Replace("$等级$", 等级.ToString())));
                    if (Convert.ToBoolean(程序.设置["升级是否消息提醒"]) && Convert.ToString(用户["用户类型"]) == "会员")
                    {
                        消息 消息 = new 消息(HC, 连接);
                        消息.发送系统消息(Convert.ToInt32(用户["ID"]),
                            Convert.ToString(用户["昵称"]),
                            Convert.ToString(程序.设置["升级信息提示"]).Replace("$等级$", (等级 + 1).ToString())
                            .Replace("$积分$", (积分 + 增加积分).ToString())
                            .Replace("$增加积分$", 增加积分.ToString()));
                    }
                    积分 += 增加积分;
                    等级++;
                    经验 -= 需要经验;
                }
            }
        }

        private void 更新登录信息_会员(Hashtable 用户,String 位置)
        {
            int 等级, 经验, 累积_秒, 积分;
            获取等级信息(用户, out 等级, out 经验, out 累积_秒, out 积分);

            String SQL = "UPDATE [" + 程序.数据表前缀 + "社区_用户_用户] SET " +
                "[最后访问时间]=@最后访问时间," +
                "[等级]=@等级," +
                "[经验]=@经验,"+
                "[积分]=@积分," +
                "[累积_秒]=@累积_秒," +
                "[所在位置]=@所在位置"+
                (Convert.ToString(用户["最后登录IP"]) != HC.Request.UserHostAddress ? ",[最后登录IP]=@最后登录IP,[最后登录地区]=@最后登录地区" : "") +
                (Convert.ToDateTime(用户["最后访问时间"])<DateTime.Now-new TimeSpan(0,Convert.ToInt32(程序.设置["离线时间"]),0)?",[最后登录时间]=@最后登录时间":"")+
                ",[今日访问次数]=[今日访问次数]+1 WHERE [ID]=" + 用户["ID"];

            SqlCommand 语句 = new SqlCommand(SQL, 连接);
            语句.Parameters.Add("@最后访问时间", SqlDbType.DateTime).Value = DateTime.Now;
            语句.Parameters.Add("@等级", SqlDbType.Int).Value = 等级;
            语句.Parameters.Add("@经验", SqlDbType.Int).Value = 经验;
            语句.Parameters.Add("@积分", SqlDbType.Int).Value = 积分;
            语句.Parameters.Add("@累积_秒", SqlDbType.Int).Value = 累积_秒;
            语句.Parameters.Add("@所在位置", SqlDbType.NVarChar).Value = 位置;
            if (Convert.ToString(用户["最后登录IP"]) != HC.Request.UserHostAddress)
            {
                用户["最后登录IP"] = HC.Request.UserHostAddress;
                用户["最后登录地区"] = 常用.获取城市(连接, HC.Request.UserHostAddress);

                语句.Parameters.Add("@最后登录IP", SqlDbType.NVarChar).Value = 用户["最后登录IP"];
                语句.Parameters.Add("@最后登录地区", SqlDbType.NVarChar).Value = 用户["最后登录地区"];
            }
            if (Convert.ToDateTime(用户["最后访问时间"]) < DateTime.Now - new TimeSpan(0, Convert.ToInt32(程序.设置["离线时间"]), 0))
                语句.Parameters.Add("@最后登录时间", SqlDbType.NVarChar).Value = DateTime.Now;
            语句.ExecuteNonQuery();
            if(Convert.ToBoolean(程序.设置["是否启用IP统计"]))
                if (Convert.ToDateTime(用户["最后访问时间"]) < DateTime.Now - new TimeSpan(0, Convert.ToInt32(程序.设置["离线时间"]), 0)
                    ||
                    Convert.ToString(用户["最后登录IP"])==HC.Request.UserHostAddress
                    )
                {
                    访问统计_IP记录 IP记录 = new 访问统计_IP记录(HC, 连接);
                    IP记录.记录(Convert.ToString(用户["最后登录IP"]), Convert.ToString(用户["最后登录地区"]));
                    更新在线人数();
                }
        }
        /// <summary>
        /// 更新在线人数的缓存
        /// </summary>
        public void 更新在线人数()
        {
            int 在线用户数 = 0;
            int 在线会员数 = 0;

            SqlCommand 语句 = new SqlCommand("SELECT COUNT(ID) FROM [" + 程序.数据表前缀 + "社区_用户_用户] WHERE [最后访问时间]>@最后访问时间", 连接);
            语句.Parameters.Add("@最后访问时间", SqlDbType.DateTime).Value = DateTime.Now - new TimeSpan(0, Convert.ToInt32(程序.设置["离线时间"]), 0);
            在线用户数 = Convert.ToInt32(语句.ExecuteScalar());

            语句 = new SqlCommand("SELECT COUNT(ID) FROM [" + 程序.数据表前缀 + "社区_用户_用户] WHERE [用户类型]='会员' AND [最后访问时间]>@最后访问时间", 连接);
            语句.Parameters.Add("@最后访问时间", SqlDbType.DateTime).Value = DateTime.Now - new TimeSpan(0, Convert.ToInt32(程序.设置["离线时间"]), 0);
            在线会员数 = Convert.ToInt32(语句.ExecuteScalar());

            HC.Application["UUN_UUN3G_ZaiXianYongHuShu"] = 在线用户数;
            HC.Application["UUN_UUN3G_ZaiXianHuiYuanShu"] = 在线会员数;
        }
        /// <summary>
        /// 将今日访问次数重置为0
        /// </summary>
        public void 重置访问次数()
        {
            SqlCommand 语句 = new SqlCommand("UPDATE [" + 程序.数据表前缀 + "社区_用户_用户] SET [今日访问次数]=0", 连接);
            语句.ExecuteNonQuery();
        }
        /// <summary>
        /// 验证用户是否包含某个权限
        /// </summary>
        /// <param name="用户组">用户所在的用户组</param>
        /// <param name="权限">验证的权限</param>
        public static void 验证权限(String 用户组, String 权限)
        {
            if (!是否包含权限(用户组, 权限))
                throw new Exception("您没有权限执行此操作");
        }

        public static bool 是否包含权限(String 用户组, String 权限)
        {
            String 所有权限 = "";
            DataSet 数据 = (DataSet)HttpContext.Current.Application["UUN_UUN3G_YongHuZu"];
            for (int i = 0; i < 数据.Tables[0].Rows.Count; i++)
            {
                DataRow 行 = 数据.Tables[0].Rows[i];
                if (Convert.ToString(行["组名称"]) == 用户组)
                    所有权限 = Convert.ToString(行["组权限"]);
            }

            if (所有权限 == "0")
                return true;

            if (权限 == "")
                return true;

            String[] 权限数组 = 权限.Split(',');
            for (int i = 0; i < 权限数组.Length; i++)
                if (所有权限.IndexOf(权限数组[i] + ",") == -1)
                    return false;
            return true;
        }
        /// <summary>
        /// 设置用户的勋章
        /// </summary>
        /// <param name="用户">勋章设置到的用户。</param>
        /// <param name="图片地址">勋章图片的地址</param>
        public void 设置勋章(int 用户,String 图片地址)
        {
            String 勋章;
            SqlCommand 语句 = new SqlCommand("SELECT [勋章] FROM [" + 程序.数据表前缀 + "社区_用户_用户] WHERE [ID]=" + 用户, 连接);
            SqlDataReader 读取 = 语句.ExecuteReader();
            if (读取.Read())
            {
                勋章 = Convert.ToString(读取["勋章"]);
                读取.Close();
            }
            else
            {
                读取.Close();
                throw new Exception("用户不存在");
            }

            勋章 += 勋章 == "" ? "" : ",";
            勋章 += 图片地址;

            语句 = new SqlCommand("UPDATE [" + 程序.数据表前缀 + "社区_用户_用户] SET [勋章]=@勋章 WHERE [ID]=" + 用户, 连接);
            语句.Parameters.Add("@勋章", SqlDbType.NVarChar).Value = 勋章;
            语句.ExecuteNonQuery();
        }
        /// <summary>
        /// 将指定用户删除
        /// </summary>
        /// <param name="ID">用户的ID</param>
        public void 删除用户(int ID)
        {
            SqlCommand 语句 = new SqlCommand("DELETE FROM [" + 程序.数据表前缀 + "社区_用户_用户] WHERE [ID]=" + ID, 连接);
            语句.ExecuteNonQuery();
        }
        /// <summary>
        /// 将用户性别的布尔值转换成相应的字符串值
        /// </summary>
        /// <param name="性别">用户的性别</param>
        /// <returns></returns>
        public static String 用户性别(bool 性别)
        {
            return 性别 ? 程序.设置["单位名词_男性名词"].ToString() : 程序.设置["单位名词_女性名词"].ToString();
        }
        /// <summary>
        /// 奖励积分给某位会员
        /// </summary>
        /// <param name="ID">会员的ID</param>
        /// <param name="积分数">奖励的积分数</param>
        /// <param name="是否消息提醒">是否消息提醒该会员</param>
        /// <param name="消息提醒内容">提醒的消息内容</param>
        public void 奖励积分(int ID, int 积分数, bool 是否消息提醒, String 消息提醒内容)
        {
            SqlCommand 语句 = new SqlCommand("UPDATE [" + 程序.数据表前缀 + "社区_用户_用户] SET [积分]=[积分]+" + 积分数 + " WHERE [ID]=" + ID, 连接);
            语句.ExecuteNonQuery();

            if (是否消息提醒)
                new 消息(HC, 连接).发送系统消息(ID, 消息提醒内容.Replace("$积分数$", 积分数.ToString() + 程序.设置["单位名称_积分单位"] + 程序.设置["单位名称_积分名词"]));
        }
        /// <summary>
        /// 扣除指定会员的积分
        /// </summary>
        /// <param name="ID">会员的ID</param>
        /// <param name="积分数">扣除的积分数</param>
        /// <param name="是否消息提醒">是否发送系统消息提醒该会员</param>
        /// <param name="消息提醒内容">提醒的消息内容</param>
        public void 扣除积分(int ID, int 积分数, bool 是否消息提醒, String 消息提醒内容)
        {
            int 会员积分数;
            SqlCommand 语句 = new SqlCommand("SELECT [积分] FROM [" + 程序.数据表前缀 + "社区_用户_用户] WHERE [ID]=" + ID, 连接);
            SqlDataReader 读取 = 语句.ExecuteReader();
            if (读取.Read())
                会员积分数 = Convert.ToInt32(读取["积分"]);
            else
            {
                读取.Close();
                throw new Exception("会员不存在");
            }
            读取.Close();

            if (积分数 > 会员积分数)
                throw new Exception("您的积分不足扣取。");

            语句 = new SqlCommand("UPDATE [" + 程序.数据表前缀 + "社区_用户_用户] SET [积分]=[积分]-" + 积分数 + " WHERE [ID]=" + ID, 连接);
            语句.ExecuteNonQuery();

            if (是否消息提醒)
                new 消息(HC, 连接).发送系统消息(ID, 消息提醒内容.Replace("$积分数$", 积分数.ToString() + 程序.设置["单位名称_积分单位"] + 程序.设置["单位名称_积分名词"]));
        }
        /// <summary>
        /// 注册一个新的用户
        /// </summary>
        /// <param name="HC"></param>
        public String 增加用户(out int ID)
        {
            int ZGID = 常用.SQL_最高ID(连接, 程序.数据表前缀 + "社区_用户_用户");
            String 标识 = "U"+ZGID+常用.随机字符(30);
            String 昵称 = HC.Request.Form["NiChen"];
            String 手机号 = HC.Request.Form["ShouJiHao"];
            bool 性别 = Convert.ToBoolean(HC.Request.Form["XingBie"]);
            String 密码 = HC.Request.Form["MiMa"];
            String 确认密码 = HC.Request.Form["QueRenMiMa"];
            if (昵称.Length < 1 || 昵称.Length > 16)
                throw new Exception("昵称只能由1至16位字符组成");
            Regex 表达式 = new Regex("^\\d{11}$");
            if (!表达式.IsMatch(手机号))
                throw new Exception("手机号只能是11位的数字组成");
            if (密码.Length < 6 || 密码.Length > 20)
                throw new Exception("密码只能是6至20位字符组成");
            if (密码 != 确认密码)
                throw new Exception("密码与确认密码不相同");
            SqlCommand 语句 = new SqlCommand("SELECT [ID] FROM [" + 程序.数据表前缀 + "社区_用户_用户] WHERE [昵称]=@昵称 OR [手机号]=@手机号", 连接);
            语句.Parameters.Add("@昵称", SqlDbType.NVarChar).Value = 昵称;
            语句.Parameters.Add("@手机号", SqlDbType.NVarChar).Value = 手机号;
            SqlDataReader 读取 = 语句.ExecuteReader();
            if (读取.HasRows)
            {
                读取.Close();
                throw new Exception("用户的昵称或手机号已存在");
            }
            else
                读取.Close();

            String XML数据 = 生成XML();

            语句 = new SqlCommand("INSERT INTO [" + 程序.数据表前缀 + "社区_用户_用户]([ID],[昵称],[性别],[头像],[手机号],[密码],[标识],[用户类型],[最后登录IP],[最后登录地区],[用户组],[个人资料])" +
                "VALUES(@ID,@昵称,@性别,@头像,@手机号,@密码,@标识,@用户类型,@最后登录IP,@最后登录地区,@用户组,@个人资料)", 连接);
            语句.Parameters.Add("@ID", SqlDbType.Int).Value = ZGID;
            语句.Parameters.Add("@昵称", SqlDbType.NVarChar).Value = 昵称;
            语句.Parameters.Add("@性别", SqlDbType.Bit).Value = 性别;
            语句.Parameters.Add("@头像", SqlDbType.NVarChar).Value = 性别 ? "/Data/TouXiang/0/2.gif" : "/Data/TouXiang/0/1.gif";
            语句.Parameters.Add("@手机号", SqlDbType.NVarChar).Value = 手机号;
            语句.Parameters.Add("@密码", SqlDbType.NVarChar).Value = 常用.MD5加密(常用.MD5加密(密码));
            语句.Parameters.Add("@标识", SqlDbType.NVarChar).Value = 标识;
            语句.Parameters.Add("@用户类型", SqlDbType.NVarChar).Value = "会员";
            语句.Parameters.Add("@最后登录IP", SqlDbType.NVarChar).Value = HC.Request.UserHostAddress;
            语句.Parameters.Add("@最后登录地区", SqlDbType.NVarChar).Value = 常用.获取城市(连接, HC.Request.UserHostAddress);
            语句.Parameters.Add("@用户组", SqlDbType.NVarChar).Value = "普通会员";
            语句.Parameters.Add("@个人资料", SqlDbType.NVarChar).Value = XML数据;
            语句.ExecuteNonQuery();

            new 会员活动信息(HC, 连接).记录(ZGID, 昵称, "加入了社区", 程序.安装位置+"Club/User.aspx?ID=" + ZGID);

            ID = ZGID;
            return 标识;
        }
        public void 修改用户资料(Hashtable 用户)
        {
            String 昵称 = HC.Request.Form["NiChen"];
            bool 性别 = Convert.ToBoolean(HC.Request.Form["XingBie"]);
            String 个人资料 = null;
            SqlCommand 语句 = new SqlCommand("SELECT [个人资料] FROM [" + 程序.数据表前缀 + "社区_用户_用户] WHERE [ID]=" + 用户["ID"], 连接);
            SqlDataReader 读取 = 语句.ExecuteReader();
            if (读取.Read())
                个人资料 = Convert.ToString(读取["个人资料"]);
            读取.Close();

            if (昵称.Length < 1 || 昵称.Length > 16)
                throw new Exception("昵称只能是1至16位的数字。");

            语句 = new SqlCommand("SELECT [ID] FROM [" + 程序.数据表前缀 + "社区_用户_用户] WHERE [昵称]=@昵称 AND [ID]<>" + 用户["ID"], 连接);
            语句.Parameters.Add("@昵称", SqlDbType.NVarChar).Value = 昵称;
            读取 = 语句.ExecuteReader();
            bool 是否存在 = 读取.HasRows;
            读取.Close();

            if (是否存在)
                throw new Exception("昵称不存在");

            语句 = new SqlCommand("UPDATE [" + 程序.数据表前缀 + "社区_用户_用户] SET [昵称]=@昵称,[性别]=@性别,[个人资料]=@个人资料 WHERE [ID]=" + 用户["ID"], 连接);
            语句.Parameters.Add("@昵称", SqlDbType.NVarChar).Value = 昵称;
            语句.Parameters.Add("@性别", SqlDbType.Bit).Value = 性别;
            语句.Parameters.Add("@个人资料", SqlDbType.NVarChar).Value = 生成XML_修改资料(个人资料);
            语句.ExecuteNonQuery();
        }
        private String 生成XML_修改资料(String 资料数据)
        {
            DataSet 数据 = new DataSet();
            SqlCommand 语句 = new SqlCommand("SELECT [数据名称],[数据类型],[是否允许重复],[是否修改资料项],[最小大小(长度)],[最大大小(长度)],[值列表],[表单名称],[默认值] FROM [" + 程序.数据表前缀 + "社区_用户_资料结构] WHERE [是否修改资料项]=@是否修改资料项 ORDER BY [ID]", 连接);
            语句.Parameters.Add("@是否修改资料项", SqlDbType.Bit).Value = true;
            SqlDataAdapter 填充 = new SqlDataAdapter(语句);
            填充.Fill(数据, "用户资料结构");

            return 生成XML(数据, new 设置(资料数据),false);
        }
        private String 生成XML(DataSet 数据,设置 其它资料,bool 注册_修改)
        {
            SqlCommand 语句;
            for (int i = 0; i < 数据.Tables[0].Rows.Count; i++)
            {
                DataRow 行 = 数据.Tables[0].Rows[i];
                String 数据值;
                if (Convert.ToBoolean(行[注册_修改?"是否注册项":"是否修改资料项"]))
                    数据值 = HC.Request.Form[行["表单名称"].ToString()];
                else
                    数据值 = 行["默认值"].ToString();
                switch (Convert.ToInt32(行["数据类型"]))
                {
                    case 0:
                        {
                            if (数据值.Length < Convert.ToInt32(行["最小大小(长度)"]) || 数据值.Length > Convert.ToInt32(行["最大大小(长度)"]))
                                throw new Exception(HC.Server.HtmlEncode(行["数据名称"].ToString()) + "的长度必须在" + 行["最小大小(长度)"] + "到" + 行["最大大小(长度)"] + "之间。");
                        }
                        break;
                    case 1:
                        {
                            if (Convert.ToInt64(数据值) < Convert.ToInt64(行["最小大小(长度)"]) || Convert.ToInt64(数据值) > Convert.ToInt64(行["最大大小(长度)"]))
                                throw new Exception(HC.Server.HtmlEncode(行["数据名称"].ToString()) + "的大小必须在" + 行["最小大小(长度)"] + "到" + 行["最大大小(长度)"] + "之间。");
                        }
                        break;
                    default:
                        {
                            String[] 值数组 = Convert.ToString(行["值列表"]).Split(new String[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                            bool 是否存在 = false;
                            for (int i1 = 0; i1 < 值数组.Length; i1++)
                                if (值数组[i1] == 数据值)
                                    是否存在 = true;
                            if (!是否存在)
                                throw new Exception(HC.Server.HtmlEncode(行["数据名称"].ToString()) + "的值不存在");
                        }
                        break;
                }
                其它资料[行["数据名称"].ToString()] = 数据值;
                if (!Convert.ToBoolean(行["是否允许重复"]))
                {
                    语句 = new SqlCommand("SELECT [ID] FROM [" + 程序.数据表前缀 + "社区_用户_资料结构] WHERE CHARINDEX(@个人资料,[个人资料])>0", 连接);
                    语句.Parameters.Add("@个人资料", SqlDbType.NVarChar).Value = "<set name=\"" + HC.Server.HtmlEncode(行["数据名称"].ToString()) + "\" value=\"" + HC.Server.HtmlEncode(数据值) + "\" />";
                    SqlDataReader 读取 = 语句.ExecuteReader();
                    if (读取.HasRows)
                    {
                        读取.Close();
                        throw new Exception(行["数据名称"] + "不允许重复，请输入其它的值。");
                    }
                    else
                        读取.Close();
                }
            }
            return 其它资料.生成XML();
        }
        private String 生成XML()
        {
            DataSet 数据 = new DataSet();
            SqlCommand 语句 = new SqlCommand("SELECT [数据名称],[数据类型],[是否允许重复],[是否注册项],[最小大小(长度)],[最大大小(长度)],[值列表],[表单名称],[默认值] FROM [" + 程序.数据表前缀 + "社区_用户_资料结构] ORDER BY [ID]", 连接);
            SqlDataAdapter 填充 = new SqlDataAdapter(语句);
            填充.Fill(数据, "用户资料结构");

            return 生成XML(数据,new 设置(""),true);
        }
        public String 获取手机号(int ID)
        {
            String 返回值="";
            SqlCommand 语句 = new SqlCommand("SELECT [手机号] FROM [" + 程序.数据表前缀 + "社区_用户_用户] WHERE [ID]=" + ID, 连接);
            SqlDataReader 读取 = 语句.ExecuteReader();
            if (读取.Read())
                返回值 = 读取["手机号"].ToString();
            else
            {
                读取.Close();
                throw new Exception("用户不存在");
            }
            读取.Close();
            return 返回值;
        }
        public String 获取昵称(int ID)
        {
            String 返回值 = "";
            SqlCommand 语句 = new SqlCommand("SELECT [昵称] FROM [" + 程序.数据表前缀 + "社区_用户_用户] WHERE [ID]=" + ID, 连接);
            SqlDataReader 读取 = 语句.ExecuteReader();
            if (读取.Read())
                返回值 = 读取["昵称"].ToString();
            else
            {
                读取.Close();
                throw new Exception("用户不存在");
            }
            读取.Close();
            return 返回值;
        }
        public String 获取用户其它资料(String XML)
        {
            设置 _用户 = new 设置(XML);
            DataSet 数据 = new DataSet();
            SqlCommand 语句 = new SqlCommand("SELECT [ID],[数据名称],[资料显示格式],[默认值] FROM [" + 程序.数据表前缀 + "社区_用户_资料结构] ORDER BY [ID]", 连接);
            SqlDataAdapter 填充 = new SqlDataAdapter(语句);
            填充.Fill(数据, "用户资料结构");

            String 返回值 = "";
            for (int i = 0; i < 数据.Tables[0].Rows.Count; i++)
            {
                DataRow 行 = 数据.Tables[0].Rows[i];
                String _值=_用户[行["数据名称"].ToString()].ToString();
                返回值 += 行["资料显示格式"].ToString()
                    .Replace("$项名称$", HC.Server.HtmlEncode(行["数据名称"].ToString()))
                    .Replace("$项值$", HC.Server.HtmlEncode(_值 == null ? 行["默认值"].ToString() : _值));
            }
            return 返回值;
        }
        /// <summary>
        /// 获取等级相应的等级称呼
        /// </summary>
        /// <param name="等级">用户的等级</param>
        /// <returns>等级称呼</returns>
        public static String 获取等级称呼(int 等级)
        {
            String 默认值 = null;
            DataSet 数据 = (DataSet)HttpContext.Current.Application["UUN_UUN3G_DenJiChenHu"];
            for (int i = 0; i < 数据.Tables[0].Rows.Count; i++)
            {
                DataRow 行 = 数据.Tables[0].Rows[i];
                if (Convert.ToInt32(行["等级"]) == 0)
                    默认值 = 行["称呼"].ToString();
                if (Convert.ToInt32(行["等级"]) == 等级)
                    return 行["称呼"].ToString();
            }
            return 默认值;
        }
    }
}