/// <summary>
        /// 条件是否为true
        /// </summary>
        /// <param name="condition"></param>
        /// <param name="node"></param>
        /// <returns></returns>
        private static bool IsTrue_StatUsers(TableTemplate.NodeCondition nCondition, XmlNode node)
        {
            NodeCondition_StatUsers condition = (NodeCondition_StatUsers)nCondition;

            return(TableTemplate.IncludeString(node.Attributes["reportType"], condition.ReportType) &&
                   TableTemplate.IncludeInt(node.Attributes["period"], (int)condition.Period) &&
                   TableTemplate.CompareBool(node.Attributes["byChannel"], condition.ByChannel) &&
                   TableTemplate.CompareBool(node.Attributes["isInternalSoft"], condition.IsInternalSoft) &&
                   TableTemplate.CompareBool(node.Attributes["onlyOldUser"], condition.OnlyOldUser) &&
                   TableTemplate.IncludeInt(node.Attributes["platform"], (int)condition.Platform) &&
                   TableTemplate.IncludeInt(node.Attributes["softId"], (int)condition.SoftID) &&
                   TableTemplate.ExcludeInt(node.Attributes["excludeSoftId"], (int)condition.SoftID));
        }
        /// <summary>
        /// 构建用户量表格
        /// </summary>
        /// <param name="softId"></param>
        /// <param name="platform"></param>
        /// <param name="isInternalSoft">是否是内部软件</param>
        /// <param name="byChannel">按渠道查询</param>
        /// <param name="period">统计周期</param>
        /// <param name="reportType"></param>
        /// <param name="onlyOldUser"></param>
        /// <param name="users"></param>
        /// <param name="forDown">是否用于下载(EXCEL)</param>
        /// <param name="tableIndex">多个表格时,用于指明第几张表格</param>
        /// <param name="tableName">表格名称</param>
        /// <returns></returns>
        public static string BuildStatUsersTable(int softId, MobileOption platform, bool isInternalSoft, bool byChannel, net91com.Stat.Core.PeriodOptions period, string reportType, bool onlyOldUser, List <SoftUser> users, bool forDown, int tableIndex, string tableName)
        {
            #region 表头开始

            StringBuilder htmlBuilder = new StringBuilder();
            if (forDown)
            {
                htmlBuilder.Append("<table border=\"1\">");
            }
            else
            {
                htmlBuilder.AppendFormat("<table id=\"tab{0}\" class=\"tablesorter\" name=\"{1}\" {2} cellspacing=\"1\">", tableIndex, tableName, tableIndex != 0 ? "style=\"display:none\"" : "");
            }

            if (statUsersXmlDoc == null)
            {
                statUsersXmlDoc = new XmlDocument();
                statUsersXmlDoc.Load(HttpContext.Current.Server.MapPath("~/DataTables/StatUsers.xml"));
            }
            TableTemplate.IsTrueHandler IsTrue    = new TableTemplate.IsTrueHandler(IsTrue_StatUsers);
            NodeCondition_StatUsers     nCodition = new NodeCondition_StatUsers
            {
                ByChannel      = byChannel,
                SoftID         = softId,
                Platform       = platform,
                IsInternalSoft = isInternalSoft,
                Period         = period,
                OnlyOldUser    = onlyOldUser,
                ReportType     = reportType
            };
            TableTemplate.ColumnNode rootNode = new TableTemplate.ColumnNode {
                CorrespondXmlNode = statUsersXmlDoc.DocumentElement
            };
            //生成表头,并返回数据绑定列
            List <TableTemplate.ColumnNode> dataColumns;
            htmlBuilder.Append(TableTemplate.BuildTableHead(rootNode, IsTrue, nCodition, out dataColumns));

            #endregion

            #region 表体开始

            htmlBuilder.Append("<tbody>");
            StringBuilder averageBuilder = new StringBuilder();
            StringBuilder sumBuilder     = new StringBuilder();
            for (int i = 0; i < users.Count; i++)
            {
                bool red = period == net91com.Stat.Core.PeriodOptions.Daily && (users[i].StatDate.DayOfWeek == DayOfWeek.Sunday || users[i].StatDate.DayOfWeek == DayOfWeek.Saturday);
                htmlBuilder.Append("<tr style=\"text-align:right;\">");
                foreach (TableTemplate.ColumnNode col in dataColumns)
                {
                    htmlBuilder.Append(red ? "<td style=\"color:red;\">" : "<td>");
                    switch (col.Name)
                    {
                    case "StatDate":
                        htmlBuilder.AppendFormat("{0:yyyy-MM-dd}", users[i].StatDate);
                        if (i == 0)
                        {
                            averageBuilder.Append("<td>平均</td>");
                            sumBuilder.Append("<td>总计</td>");
                        }
                        break;

                    case "Hour":
                        htmlBuilder.Append(users[i].Hour);
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0}</td>", averageBuilder.Length == 0 ? "平均" : "--");
                            sumBuilder.AppendFormat("<td>{0}</td>", sumBuilder.Length == 0 ? "总计" : "--");
                        }
                        break;

                    case "NewUserCount":
                        htmlBuilder.AppendFormat("{0:N0}", users[i].NewNum);
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0:N0}</td>", (int)users.Average(a => a.NewNum));
                            sumBuilder.AppendFormat("<td>{0:N0}</td>", users.Sum(a => a.NewNum));
                        }
                        break;

                    case "NewUserCount_NotFromCache":
                        htmlBuilder.AppendFormat("{0:N0}", users[i].FirstNewUserCount);
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0:N0}</td>", (int)users.Average(a => a.FirstNewUserCount));
                            sumBuilder.AppendFormat("<td>{0:N0}</td>", users.Sum(a => a.FirstNewUserCount));
                        }
                        break;

                    case "NewUserCount_Shanzhai":
                        htmlBuilder.AppendFormat("{0:N0}", users[i].NewUserCount_Shanzhai);
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0:N0}</td>", (int)users.Average(a => a.NewUserCount_Shanzhai));
                            sumBuilder.AppendFormat("<td>{0:N0}</td>", users.Sum(a => a.NewUserCount_Shanzhai));
                        }
                        break;

                    case "NewUserCount_SecAct":
                        htmlBuilder.AppendFormat("{0:N0}", users[i].NewUserCount_SecAct);
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0:N0}</td>", (int)users.Average(a => a.NewUserCount_SecAct));
                            sumBuilder.AppendFormat("<td>{0:N0}</td>", users.Sum(a => a.NewUserCount_SecAct));
                        }
                        break;

                    case "NewUserCount_SecAct2":
                        htmlBuilder.AppendFormat("{0:N0}", users[i].NewUserCount_SecAct2);
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0:N0}</td>", (int)users.Average(a => a.NewUserCount_SecAct2));
                            sumBuilder.AppendFormat("<td>{0:N0}</td>", users.Sum(a => a.NewUserCount_SecAct2));
                        }
                        break;

                    case "NewUserCount_Broken":
                        htmlBuilder.AppendFormat("{0:N0}", users[i].NewNum_Broken);
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0:N0}</td>", (int)users.Average(a => a.NewNum_Broken));
                            sumBuilder.AppendFormat("<td>{0:N0}</td>", users.Sum(a => a.NewNum_Broken));
                        }
                        break;

                    case "NewUserCount_NotBroken":
                        htmlBuilder.AppendFormat("{0:N0}", users[i].NewNum_NotBroken);
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0:N0}</td>", (int)users.Average(a => a.NewNum_NotBroken));
                            sumBuilder.AppendFormat("<td>{0:N0}</td>", users.Sum(a => a.NewNum_NotBroken));
                        }
                        break;

                    case "NewUserCount_ZJS":
                        htmlBuilder.AppendFormat("{0:N0}", users[i].NewNum_ZJS);
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0:N0}</td>", (int)users.Average(a => a.NewNum_ZJS));
                            sumBuilder.AppendFormat("<td>{0:N0}</td>", users.Sum(a => a.NewNum_ZJS));
                        }
                        break;

                    case "NewUserCount_ValuedUsers":
                        htmlBuilder.AppendFormat("{0:N0}", Math.Max(users[i].FuncValueUsersForNew, users[i].DownValueUsersForNew));
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0:N0}</td>", (int)users.Average(a => Math.Max(a.FuncValueUsersForNew, a.DownValueUsersForNew)));
                            sumBuilder.AppendFormat("<td>{0:N0}</td>", users.Sum(a => Math.Max(a.FuncValueUsersForNew, a.DownValueUsersForNew)));
                        }
                        break;

                    case "ActiveUserCount":
                        htmlBuilder.AppendFormat("{0:N0}", onlyOldUser ? users[i].ActiveNum : users[i].ActiveNum + users[i].NewNum);
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0:N0}</td>", onlyOldUser ? (int)users.Average(a => a.ActiveNum) : (int)users.Average(a => a.ActiveNum + a.NewNum));
                            sumBuilder.Append("<td>--</td>");
                        }
                        break;

                    case "OldUserCount":
                        htmlBuilder.AppendFormat("{0:N0}", users[i].ActiveNum);
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0:N0}</td>", (int)users.Average(a => a.ActiveNum));
                            sumBuilder.Append("<td>--</td>");
                        }
                        break;

                    case "OldPercent":
                        htmlBuilder.Append((((double)users[i].ActiveNum) * 100 / (users[i].ActiveNum + users[i].NewNum)).ToString("0.00") + "%");
                        if (i == 0)
                        {
                            averageBuilder.Append("<td>--</td>");
                            sumBuilder.Append("<td>--</td>");
                        }
                        break;

                    case "ActiveUserCount_NotFromCache":
                        htmlBuilder.AppendFormat("{0:N0}", onlyOldUser ? users[i].FirstActiveUserCount : users[i].FirstActiveUserCount + users[i].FirstNewUserCount);
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0:N0}</td>", onlyOldUser ? (int)users.Average(a => a.FirstActiveUserCount) : (int)users.Average(a => a.FirstActiveUserCount + a.FirstNewUserCount));
                            sumBuilder.Append("<td>--</td>");
                        }
                        break;

                    case "ActiveUserCount_Shanzhai":
                        htmlBuilder.AppendFormat("{0:N0}", onlyOldUser ? users[i].ActiveUserCount_Shanzhai : users[i].ActiveUserCount_Shanzhai + users[i].NewUserCount_Shanzhai);
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0:N0}</td>", onlyOldUser ? (int)users.Average(a => a.ActiveUserCount_Shanzhai) : (int)users.Average(a => a.ActiveUserCount_Shanzhai + a.NewUserCount_Shanzhai));
                            sumBuilder.Append("<td>--</td>");
                        }
                        break;

                    case "ActiveUserCount_Broken":
                        htmlBuilder.AppendFormat("{0:N0}", onlyOldUser ? users[i].ActiveNum_Broken : users[i].ActiveNum_Broken + users[i].NewNum_Broken);
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0:N0}</td>", onlyOldUser ? (int)users.Average(a => a.ActiveNum_Broken) : (int)users.Average(a => a.ActiveNum_Broken + a.NewNum_Broken));
                            sumBuilder.Append("<td>--</td>");
                        }
                        break;

                    case "ActiveUserCount_NotBroken":
                        htmlBuilder.AppendFormat("{0:N0}", onlyOldUser ? users[i].ActiveNum_NotBroken : users[i].ActiveNum_NotBroken + users[i].NewNum_NotBroken);
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0:N0}</td>", onlyOldUser ? (int)users.Average(a => a.ActiveNum_NotBroken) : (int)users.Average(a => a.ActiveNum_NotBroken + a.NewNum_NotBroken));
                            sumBuilder.Append("<td>--</td>");
                        }
                        break;

                    case "ActiveUserCount_ZJS":
                        htmlBuilder.AppendFormat("{0:N0}", onlyOldUser ? users[i].ActiveNum_ZJS : users[i].ActiveNum_ZJS + users[i].NewNum_ZJS);
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0:N0}</td>", onlyOldUser ? (int)users.Average(a => a.ActiveNum_ZJS) : (int)users.Average(a => a.ActiveNum_ZJS + a.NewNum_ZJS));
                            sumBuilder.Append("<td>--</td>");
                        }
                        break;

                    case "ActiveUserCount_ValuedUsers":
                        htmlBuilder.AppendFormat("{0:N0}", onlyOldUser ? Math.Max(users[i].FuncValueUsersForAct, users[i].DownValueUsersForAct) : Math.Max(users[i].FuncValueUsersForAct + users[i].FuncValueUsersForNew, users[i].DownValueUsersForAct + users[i].DownValueUsersForNew));
                        if (i == 0)
                        {
                            averageBuilder.AppendFormat("<td>{0:N0}</td>", onlyOldUser ? (int)users.Average(a => Math.Max(a.FuncValueUsersForAct, a.DownValueUsersForAct)) : (int)users.Average(a => Math.Max(a.FuncValueUsersForAct + a.FuncValueUsersForNew, a.DownValueUsersForAct + a.DownValueUsersForNew)));
                            sumBuilder.Append("<td>--</td>");
                        }
                        break;

                    case "TotalUserCount":
                        htmlBuilder.AppendFormat("{0:N0}", users[i].TotalNum);
                        if (i == 0)
                        {
                            averageBuilder.Append("<td>--</td>");
                            sumBuilder.AppendFormat("<td>{0:N0}</td>", users.Max(a => a.TotalNum));
                        }
                        break;

                    case "TotalUserCount_Shanzhai":
                        htmlBuilder.AppendFormat("{0:N0}", users[i].TotalUserCount_Shanzhai);
                        if (i == 0)
                        {
                            averageBuilder.Append("<td>--</td>");
                            sumBuilder.AppendFormat("<td>{0:N0}</td>", users.Max(a => a.TotalUserCount_Shanzhai));
                        }
                        break;

                    case "Growth":
                        htmlBuilder.Append(users[i].Growth);
                        if (i == 0)
                        {
                            averageBuilder.Append("<td>--</td>");
                            sumBuilder.Append("<td>--</td>");
                        }
                        break;

                    case "ActivePercent":
                        htmlBuilder.Append(onlyOldUser ? users[i].ActivityPercent : users[i].UsePercent);
                        if (i == 0)
                        {
                            averageBuilder.Append("<td>--</td>");
                            sumBuilder.Append("<td>--</td>");
                        }
                        break;
                    }
                    htmlBuilder.Append("</td>");
                }
                htmlBuilder.Append("</tr>");
            }

            #endregion

            #region 表尾开始

            htmlBuilder.Append("</tbody><tr style=\"text-align:right;\">");
            htmlBuilder.Append(averageBuilder.ToString());
            htmlBuilder.Append("</tr>");
            if (period != net91com.Stat.Core.PeriodOptions.LatestOneMonth)
            {
                htmlBuilder.Append("<tr style=\"text-align:right;\">");
                htmlBuilder.Append(sumBuilder.ToString());
                htmlBuilder.Append("</tr>");
            }
            htmlBuilder.Append("</tr></table>");

            #endregion

            return(htmlBuilder.ToString());
        }