using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Xml.Serialization;
using NewLife.Configuration;
using NewLife.Log;
using NewLife.Reflection;
using XCode;
#if NET4
using System.Linq;
#else
using NewLife.Linq;
using NewLife.Collections;
#endif
namespace NewLife.CommonEntity
{
/// <summary>菜单</summary>
public partial class Menu<TEntity> : EntityTree<TEntity>, IMenu where TEntity : Menu<TEntity>, new()
{
#region 对象操作
/// <summary>首次连接数据库时初始化数据,仅用于实体类重载,用户不应该调用该方法</summary>
[EditorBrowsable(EditorBrowsableState.Never)]
protected override void InitData()
{
base.InitData();
if (Meta.Count > 0) return;
if (XTrace.Debug) XTrace.WriteLine("开始初始化{0}菜单数据……", typeof(TEntity).Name);
Meta.BeginTrans();
try
{
//Int32 sort = 1000;
//TEntity top = Root.AddChild("管理平台", null, sort -= 10, "Admin");
//TEntity entity = top.AddChild("系统管理", null, sort -= 10, "System");
//entity.AddChild("菜单管理", "../../Admin/System/Menu.aspx", sort -= 10, "菜单管理");
//entity.AddChild("管理员管理", "../../Admin/System/Admin.aspx", sort -= 10, "管理员管理");
//entity.AddChild("角色管理", "../../Admin/System/Role.aspx", sort -= 10, "角色管理");
//entity.AddChild("权限管理", "../../Admin/System/RoleMenu.aspx", sort -= 10, "权限管理");
//entity.AddChild("日志查看", "../../Admin/System/Log.aspx", sort -= 10, "日志查看");
// 准备增加Admin目录下的所有页面
//ScanAndAdd(top);
ScanAndAdd();
Meta.Commit();
if (XTrace.Debug) XTrace.WriteLine("完成初始化{0}菜单数据!", typeof(TEntity).Name);
}
catch { Meta.Rollback(); throw; }
}
/// <summary>已重载。调用Save时写日志,而调用Insert和Update时不写日志</summary>
/// <returns></returns>
public override int Save()
{
if (!String.IsNullOrEmpty(Url))
{
// 删除两端空白
if (Url != Url.Trim()) Url = Url.Trim();
}
if (ID == 0)
WriteLog("添加", Name);
else
WriteLog("修改", Name);
return base.Save();
}
/// <summary>已重载。</summary>
/// <returns></returns>
public override int Delete()
{
String name = Name;
if (String.IsNullOrEmpty(name))
{
TEntity entity = FindByID(ID);
if (entity != null) name = entity.Name;
}
WriteLog("删除", name);
return base.Delete();
}
#endregion
#region 扩展属性
/// <summary>父菜单名</summary>
[XmlIgnore]
public virtual String ParentMenuName { get { return Parent == null ? null : Parent.Name; } set { } }
/// <summary>当前页所对应的菜单项</summary>
public static TEntity Current
{
get
{
if (HttpContext.Current == null || HttpContext.Current.Request == null) return null;
String key = "CurrentMenu";
TEntity entity = HttpContext.Current.Items[key] as TEntity;
if (entity == null)
{
entity = GetCurrentMenu();
if (entity != null)
{
// 根据页面标题,修正菜单名
Page page = HttpContext.Current.Handler as Page;
if (page != null && !String.IsNullOrEmpty(page.Title)) entity.ResetName(page.Title);
}
HttpContext.Current.Items[key] = entity;
}
return entity;
}
}
/// <summary>当前页所对应的菜单项。通过实体资格提供者,保证取得正确的菜单项</summary>
[Obsolete("该成员在后续版本中讲不再被支持!")]
public static IMenu CurrentMenu
{
get
{
//return TypeResolver.GetPropertyValue(typeof(IMenu), "Current") as IMenu;
ICommonManageProvider provider = CommonManageProvider.Provider;
if (provider == null) return null;
Type type = provider.MenuType;
return PropertyInfoX.Create(type, "Current").GetValue() as IMenu;
}
}
static TEntity GetCurrentMenu()
{
if (HttpContext.Current == null || HttpContext.Current.Request == null) return null;
// 计算当前文件路径
String p = HttpContext.Current.Request.PhysicalPath;
DirectoryInfo di = new DirectoryInfo(Path.GetDirectoryName(p));
String fileName = Path.GetFileName(p);
// 查找所有以该文件名结尾的菜单
EntityList<TEntity> list = Meta.Cache.Entities;
list = list.FindAll(delegate(TEntity item)
{
return !String.IsNullOrEmpty(item.Url) && item.Url.Trim().EndsWith(fileName, StringComparison.OrdinalIgnoreCase);
});
if ((list == null || list.Count < 1) && Path.GetFileNameWithoutExtension(p).EndsWith("Form", StringComparison.OrdinalIgnoreCase))
{
fileName = Path.GetFileNameWithoutExtension(p);
fileName = fileName.Substring(0, fileName.Length - "Form".Length);
fileName += Path.GetExtension(p);
// 有可能是表单
list = Meta.Cache.Entities.FindAll(delegate(TEntity item)
{
return !String.IsNullOrEmpty(item.Url) && item.Url.Trim().EndsWith(fileName, StringComparison.OrdinalIgnoreCase);
});
}
if (list == null || list.Count < 1) return null;
if (list.Count == 1) return list[0];
// 查找所有以该文件名结尾的菜单
var list2 = list.FindAll(delegate(TEntity item)
{
return !String.IsNullOrEmpty(item.Url) && item.Url.Trim().EndsWith(@"/" + fileName, StringComparison.OrdinalIgnoreCase);
});
if (list2 == null || list2.Count < 1) return list[0];
if (list2.Count == 1) return list2[0];
// 优先全路径
var url = String.Format(@"../../{0}/{1}/{2}", di.Parent.Name, di.Name, fileName);
var entity = FindByUrl(url);
if (entity != null) return entity;
// 兼容旧版本
url = String.Format(@"../{0}/{1}", di.Name, fileName);
return FindByUrl(url);
}
#endregion
#region 扩展查询
/// <summary>根据编号查找</summary>
/// <param name="id"></param>
/// <returns></returns>
public static TEntity FindByID(Int32 id)
{
if (id <= 0) return null;
return Meta.Cache.Entities.Find(_.ID, id);
}
/// <summary>根据名字查找</summary>
/// <param name="name"></param>
/// <returns></returns>
public static TEntity FindByName(String name) { return Meta.Cache.Entities.Find(_.Name, name); }
/// <summary>根据Url查找</summary>
/// <param name="url"></param>
/// <returns></returns>
public static TEntity FindByUrl(String url) { return Meta.Cache.Entities.FindIgnoreCase(_.Url, url); }
/// <summary>根据名字查找,支持路径查找</summary>
/// <param name="name"></param>
/// <returns></returns>
public static TEntity FindForName(String name)
{
TEntity entity = FindByName(name);
if (entity != null) return entity;
//return FindByPath(Meta.Cache.Entities, name, _.Name);
return Root.FindByPath(name, _.Name, _.Permission, _.Remark);
}
/// <summary>根据权限名查找</summary>
/// <param name="name"></param>
/// <returns></returns>
public static TEntity FindByPerssion(String name) { return Meta.Cache.Entities.Find(_.Permission, name); }
/// <summary>为了权限而查找,支持路径查找</summary>
/// <param name="name"></param>
/// <returns></returns>
public static TEntity FindForPerssion(String name)
{
// 计算集合,为了处理同名的菜单
EntityList<TEntity> list = Meta.Cache.Entities.FindAll(_.Permission, name);
if (list != null && list.Count == 1) return list[0];
// 如果菜单同名,则使用当前页
TEntity current = null;
// 看来以后要把list != null && list.Count > 0判断作为常态,养成好习惯呀
if (list != null && list.Count > 0)
{
if (current == null) current = Current;
if (current != null)
{
foreach (TEntity item in list)
{
if (current.ID == item.ID) return item;
}
}
if (XTrace.Debug) XTrace.WriteLine("存在多个名为" + name + "的菜单,系统无法区分,请修改为不同的权限名,以免发生授权干扰!");
return list[0];
}
//TEntity entity = FindByPerssion(name);
//if (entity != null) return entity;
//TEntity entity = FindByPath(Meta.Cache.Entities, name, _.Permission);
TEntity entity = Root.FindByPath(name, _.Permission);
// 找不到的时候,修改当前页面
if (entity == null)
{
if (current == null) current = Current;
if (current != null)
{
if (current.ResetName(name)) entity = current;
}
}
return entity;
}
///// <summary>
///// 路径查找
///// </summary>
///// <param name="list"></param>
///// <param name="path"></param>
///// <param name="name"></param>
///// <returns></returns>
//public static TEntity FindByPath(EntityList<TEntity> list, String path, String name)
//{
// if (list == null || list.Count < 1) return null;
// if (String.IsNullOrEmpty(path) || String.IsNullOrEmpty(name)) return null;
// // 尝试一次性查找
// TEntity entity = list.Find(name, path);
// if (entity != null) return entity;
// String[] ss = path.Split(new Char[] { '.', '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
// if (ss == null || ss.Length < 1) return null;
// // 找第一级
// entity = list.Find(name, ss[0]);
// if (entity == null) entity = list.Find(_.Remark, ss[0]);
// if (entity == null) return null;
// // 是否还有下级
// if (ss.Length == 1) return entity;
// // 递归找下级
// return FindByPath(entity.Childs, String.Join("\\", ss, 1, ss.Length - 1), name);
// //EntityList<TEntity> list3 = new EntityList<TEntity>();
// //for (int i = 0; i < ss.Length; i++)
// //{
// // // 找到符合当前级别的所有节点
// // EntityList<TEntity> list2 = list.FindAll(name, ss[i]);
// // if (list2 == null || list2.Count < 1) return null;
// // // 是否到了最后
// // if (i == ss.Length - 1)
// // {
// // list3 = list2;
// // break;
// // }
// // // 找到它们的子节点
// // list3.Clear();
// // foreach (TEntity item in list2)
// // {
// // if (item.Childs != null && item.Childs.Count > 0) list3.AddRange(item.Childs);
// // }
// // if (list3 == null || list3.Count < 1) return null;
// //}
// //if (list3 != null && list3.Count > 0)
// // return list[0];
// //else
// // return null;
//}
/// <summary>查找指定菜单的子菜单</summary>
/// <param name="id"></param>
/// <returns></returns>
public static EntityList<TEntity> FindAllByParentID(Int32 id)
{
EntityList<TEntity> list = Meta.Cache.Entities.FindAll(_.ParentID, id);
if (list != null && list.Count > 0) list.Sort(new String[] { _.Sort, _.ID }, new Boolean[] { true, false });
return list;
}
#endregion
#region 扩展操作
/// <summary>检查并重新设置名称和权限项</summary>
/// <param name="name"></param>
/// <returns></returns>
public Boolean ResetName(String name)
{
if (name.Contains(@".") || name.Contains(@"/") || name.Contains(@"\")) return false;
// 没有设置权限项或者权限项和名字相同时
// 注意比较添加权限名称是否跟页面上所写Title相同(包括中文,英文)
// 如果权限名称与页面中的Title不相同时修改权限名称为页面Title名称,疏漏可能造成日志重复写入
if (String.IsNullOrEmpty(Permission) || IsEnglish(Permission) || !String.Equals(Permission, name, StringComparison.OrdinalIgnoreCase)) Permission = name;
if (String.IsNullOrEmpty(Name) || IsEnglish(Name)) Name = name;
//检查是否有菜单名称或权限是否有变动如无变动不做记录
if (Dirtys[_.Permission] || Dirtys[_.Name])
return Save() > 0;
return false;
}
/// <summary>是否全英文</summary>
/// <param name="str"></param>
/// <returns></returns>
private static Boolean IsEnglish(String str)
{
if (String.IsNullOrEmpty(str)) return false;
return Encoding.UTF8.GetByteCount(str) == str.Length;
}
/// <summary>已重载。</summary>
/// <returns></returns>
public override string ToString()
{
var path = FullPath;
if (!String.IsNullOrEmpty(path))
return path;
return base.ToString();
}
#endregion
#region 业务
/// <summary>导入</summary>
public virtual void Import()
{
Meta.BeginTrans();
try
{
//顶级节点根据名字合并
if (ParentID == 0)
{
TEntity m = Find(_.Name, Name);
if (m != null)
{
this.ID = m.ID;
this.Name = m.Name;
this.ParentID = 0;
this.Url = m.Url;
this.Remark = m.Remark;
this.Update();
}
else
this.Insert();
}
else
{
this.Insert();
}
//更新编号
var list = Childs;
if (list != null && list.Count > 0)
{
foreach (TEntity item in list)
{
item.ParentID = ID;
item.Import();
}
}
Meta.Commit();
}
catch
{
Meta.Rollback();
throw;
}
}
/// <summary>添加子菜单</summary>
/// <param name="name"></param>
/// <param name="url"></param>
/// <param name="sort"></param>
/// <param name="reamark"></param>
/// <returns></returns>
public virtual TEntity Create(String name, String url, Int32 sort = 0, String reamark = null)
{
var entity = new TEntity();
entity.ParentID = ID;
entity.Name = name;
entity.Permission = name;
entity.Url = url;
entity.Sort = sort;
entity.IsShow = true;
entity.Remark = reamark ?? name;
//entity.Save();
return entity;
}
/// <summary>扫描配置文件中指定的目录</summary>
/// <returns></returns>
public static Int32 ScanAndAdd()
{
TEntity top = null;
//扫描目录
String[] AppDirs = Config.GetConfigSplit<String>("NewLife.CommonEntity.AppDirs", null);
//过滤文件
String[] AppDirsFileFilter = Config.GetConfigSplit<String>("NewLife.CommonEntity.AppDirsFileFilter", null);
//是否在子目中过滤
Boolean AppDirsIsAllFilter = Config.GetConfig<Boolean>("NewLife.CommonEntity.AppDirsIsAllDirs", false);
//List<String> AppDirsFileFilterList = AppDirsFileFilter == null ? null : new List<String>(AppDirsFileFilter);
var filters = new HashSet<String>(AppDirsFileFilter, StringComparer.OrdinalIgnoreCase);
if (AppDirs == null || AppDirs.Length == 0)
AppDirs = new String[] { "Admin" };
else if (AppDirs.Length > 0)
{
List<String> list = new List<string>(AppDirs);
if (!list.Contains("Admin")) list.Add("Admin");
AppDirs = list.ToArray();
}
Int32 total = 0;
foreach (String item in AppDirs)
{
// 如果目录不存在,就没必要扫描了
String p = item;
if (!Path.IsPathRooted(p)) p = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, p);
if (!Directory.Exists(p))
{
p = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Path.Combine("Admin", item));
if (!Directory.Exists(p)) continue;
}
// 根据目录找菜单,它将作为顶级菜单
top = FindForName(item);
if (top == null) top = Meta.Cache.Entities.Find(_.Remark, item);
if (top == null)
{
top = Root.Create(item, null, 0, item);
top.Save();
}
//total += ScanAndAdd(item, top);
total += ScanAndAdd(item, top, filters, AppDirsIsAllFilter);
}
return total;
}
static TEntity GetTopForDir(String dir)
{
// 根据目录找菜单,它将作为顶级菜单
TEntity top = FindForName(dir);
if (top == null) top = Meta.Cache.Entities.Find(_.Remark, dir);
// 如果找不到,就取第一个作为顶级
if (top == null)
{
var childs = Root.Childs;
if (childs != null && childs.Count > 0)
top = childs[0];
else
{
//var list = FindAllByName(_.ParentID, 0, _.ID.Desc(), 0, 1);
//if (list != null && list.Count > 1) top = list[0];
return Meta.Cache.Entities.ToList().OrderByDescending(e => e.Sort).FirstOrDefault(e => e.ParentID == 0);
}
}
return top;
}
/// <summary>扫描指定目录并添加文件到第一个顶级菜单之下</summary>
/// <param name="dir"></param>
/// <returns></returns>
public static Int32 ScanAndAdd(String dir) { return ScanAndAdd(dir, GetTopForDir(dir)); }
/// <summary>获取目录层级</summary>
/// <param name="dir"></param>
/// <param name="isTop">是否顶级目录</param>
/// <returns></returns>
public static String GetPathForScan(String dir, Boolean isTop)
{
if (String.IsNullOrEmpty(dir)) throw new ArgumentNullException("dir");
// 要扫描的目录
String p = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, dir);
if (!Directory.Exists(p)) return "";
//获取层级
var currentPath = isTop ? "../" : "../../";
currentPath = Path.Combine(currentPath, p.Replace(AppDomain.CurrentDomain.BaseDirectory, null)).Replace("\\", "/");
if (!currentPath.EndsWith("/"))
currentPath += "/";
return currentPath;
}
/// <summary>扫描指定目录并添加文件到顶级菜单之下</summary>
/// <param name="dir">扫描目录</param>
/// <param name="top">父级</param>
/// <param name="fileFilter">过滤文件名</param>
/// <param name="isFilterChildDir">是否在子目录中过滤</param>
/// <returns></returns>
static Int32 ScanAndAdd(String dir, TEntity top, ICollection<String> fileFilter = null, Boolean isFilterChildDir = false)
{
if (String.IsNullOrEmpty(dir)) throw new ArgumentNullException("dir");
if (top == null) throw new ArgumentNullException("top");
// 添加
Int32 num = 0;
//目录是否做为新菜单
Boolean isAddDir = false;
// 要扫描的目录
String p = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, dir);
if (!Directory.Exists(p)) return num;
//本意,获取目录名
String dirName = new DirectoryInfo(p).Name;
if (dirName.Equals("Frame", StringComparison.OrdinalIgnoreCase)) return num;
if (dirName.Equals("Asc", StringComparison.OrdinalIgnoreCase)) return num;
if (dirName.Equals("images", StringComparison.OrdinalIgnoreCase)) return num;
if (dirName.StartsWith("img", StringComparison.OrdinalIgnoreCase)) return num;
//本目录aspx页面
String[] fs = Directory.GetFiles(p, "*.aspx", SearchOption.TopDirectoryOnly);
//本目录子子录
String[] dis = Directory.GetDirectories(p);
//如没有页面和子目录
if ((fs == null || fs.Length < 1) && (dis == null || dis.Length < 1))
return num;
//本目录菜单
//TEntity parent = Find(_.Name, dirName);
//if (parent == null) parent = Find(_.Remark, dirName);
var parent = FindByName(dirName);
if (parent == null) parent = Meta.Cache.Entities.Find(_.Remark, dirName);
if (parent == null)
{
parent = top.Create(dirName, null, 0, dirName);
parent.Save();
num++;
//目录为新增菜单
isAddDir = true;
}
//aspx
if (fs != null && fs.Length > 0)
{
String currentPath = GetPathForScan(p, !dir.Contains("/") && !dir.Contains("\\"));
var files = new List<String>();
foreach (var elm in fs)
{
var file = Path.GetFileName(elm);
if (file.EqualIgnoreCase("Default.aspx"))
{
parent.Url = Path.Combine(currentPath, "Default.aspx");
String title = GetPageTitle(elm);
if (!String.IsNullOrEmpty(title)) parent.Name = parent.Permission = title;
parent.Save();
}
//过滤特定文件名文件
//if (fileFilter != null && fileFilter.Count() > 0 && null != fileFilter.Find(delegate(String item)
//{
// return item.Equals(Path.GetFileName(elm), StringComparison.CurrentCultureIgnoreCase);
//}))
// continue;
// 采用哈希集合查询字符串更快
if (fileFilter != null && fileFilter.Contains(file)) continue;
// 过滤掉表单页面
if (Path.GetFileNameWithoutExtension(elm).EndsWith("Form", StringComparison.OrdinalIgnoreCase)) continue;
// 过滤掉选择页面
if (Path.GetFileNameWithoutExtension(elm).StartsWith("Select", StringComparison.OrdinalIgnoreCase)) continue;
//if (elm.EndsWith("Default.aspx", StringComparison.OrdinalIgnoreCase)) continue;
files.Add(elm);
}
if (files.Count > 0)
{
//aspx页面
foreach (String elm in files)
{
var file = Path.GetFileName(elm);
String url = null;
// 全部使用全路径
//if (String.Equals(dir, "Admin", StringComparison.OrdinalIgnoreCase))
// url = String.Format(@"../{0}/{1}", dirName, Path.GetFileName(elm));
//else
url = Path.Combine(currentPath, Path.GetFileName(elm));
//TEntity entity = Find(_.Url, url);
var entity = FindByUrl(url);
if (entity != null) continue;
entity = parent.Create(Path.GetFileNameWithoutExtension(elm), url);
String elmTitle = GetPageTitle(elm);
if (!String.IsNullOrEmpty(elmTitle)) entity.Name = entity.Permission = elmTitle;
entity.Save();
num++;
}
}
}
// 子级目录
if (dis == null || dis.Length > 0)
foreach (String item in dis)
{
num += isFilterChildDir ? ScanAndAdd(item, parent, fileFilter, true) : ScanAndAdd(item, parent, null, false);
}
//如果目录中没有菜单,移除目录
//if (parent != null && parent.ID > 0 && FindCount(_.ParentID, parent.ID) == 0)
//目录为新增加菜单且本级以下num为1则认为只增加了目录,并无子级
if (isAddDir && num == 1)
{
var remove = top.Childs.Find(_.ID, parent.ID);
if (remove != null) top.Childs.Remove(remove);
parent.Delete();
num = num - 1;
}
return num;
}
///// <summary>
///// 扫描指定目录并添加文件到顶级菜单之下
///// </summary>
///// <param name="dir"></param>
///// <param name="top"></param>
///// <returns></returns>
//public static Int32 ScanAndAdd(String dir, TEntity top)
//{
// if (String.IsNullOrEmpty(dir)) throw new ArgumentNullException("dir");
// if (top == null) throw new ArgumentNullException("top");
// // 要扫描的目录
// String p = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, dir);
// if (!Directory.Exists(p)) return 0;
// // 处理Default.aspx,该顶级目录下的首页,一般是工作台
// String defFile = Path.Combine(p, "Default.aspx");
// if (File.Exists(defFile))
// {
// if (String.IsNullOrEmpty(top.Url))
// {
// top.Url = String.Format(@"../{0}/{1}", dir, Path.GetFileName(defFile));
// String title = GetPageTitle(defFile);
// if (!String.IsNullOrEmpty(title)) top.Name = top.Permission = title;
// top.Save();
// }
// }
// // 找到子级目录
// String[] dis = Directory.GetDirectories(p);
// if (dis == null || dis.Length <= 0)
// //return 0;
// //没有子目录时,将自身设置为扫述目录
// dis = new String[] { p };
// Int32 num = 0;
// foreach (String item in dis)
// {
// String dirName = new DirectoryInfo(item).Name;
// if (dirName.Equals("Frame", StringComparison.OrdinalIgnoreCase)) continue;
// //if (dirName.Equals("System", StringComparison.OrdinalIgnoreCase)) continue;
// if (dirName.StartsWith("img", StringComparison.OrdinalIgnoreCase)) continue;
// String[] fs = Directory.GetFiles(item, "*.aspx", SearchOption.TopDirectoryOnly);
// if (fs == null || fs.Length < 1) continue;
// List<String> files = new List<String>();
// foreach (String elm in fs)
// {
// // 过滤掉表单页面
// if (Path.GetFileNameWithoutExtension(elm).EndsWith("Form", StringComparison.OrdinalIgnoreCase)) continue;
// // 过滤掉选择页面
// if (Path.GetFileNameWithoutExtension(elm).StartsWith("Select", StringComparison.OrdinalIgnoreCase)) continue;
// //if (elm.EndsWith("Default.aspx", StringComparison.OrdinalIgnoreCase)) continue;
// files.Add(elm);
// }
// if (files.Count < 1) continue;
// // 添加
// TEntity parent = Find(_.Name, dirName);
// if (parent == null) parent = Find(_.Remark, dirName);
// if (parent == null)
// {
// parent = top.AddChild(dirName, null, 0, dirName);
// num++;
// }
// // 处理Default.aspx
// defFile = Path.Combine(item, "Default.aspx");
// if (File.Exists(defFile))
// {
// if (String.IsNullOrEmpty(parent.Url))
// {
// parent.Url = String.Format(@"../../{0}/{1}/{2}", dir, item, Path.GetFileName(defFile));
// String title = GetPageTitle(defFile);
// if (!String.IsNullOrEmpty(title)) parent.Name = parent.Permission = title;
// parent.Save();
// }
// continue;
// }
// foreach (String elm in files)
// {
// String url = null;
// if (elm.EndsWith("Default.aspx", StringComparison.OrdinalIgnoreCase))
// {
// }
// // 全部使用全路径
// //if (String.Equals(dir, "Admin", StringComparison.OrdinalIgnoreCase))
// // url = String.Format(@"../{0}/{1}", dirName, Path.GetFileName(elm));
// //else
// url = String.Format(@"../{0}/{1}", dirName, Path.GetFileName(elm));
// TEntity entity = Find(_.Url, url);
// if (entity != null) continue;
// url = String.Format(@"../../{2}/{0}/{1}", dirName, Path.GetFileName(elm), dir);
// entity = Find(_.Url, url);
// if (entity != null) continue;
// entity = parent.AddChild(Path.GetFileNameWithoutExtension(elm), url);
// String title = GetPageTitle(elm);
// if (!String.IsNullOrEmpty(title)) entity.Name = entity.Permission = title;
// entity.Save();
// num++;
// }
// }
// return num;
//}
static Regex reg_PageTitle = new Regex("\\bTitle=\"([^\"]*)\"", RegexOptions.IgnoreCase | RegexOptions.Compiled);
static Regex reg_PageTitle2 = new Regex("<title>([^<]*)</title>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
static String GetPageTitle(String pagefile)
{
if (String.IsNullOrEmpty(pagefile) || !".aspx".EqualIgnoreCase(Path.GetExtension(pagefile)) || !File.Exists(pagefile)) return null;
// 读取aspx的第一行,里面有Title=""
String line = null;
using (StreamReader reader = new StreamReader(pagefile))
{
while (!reader.EndOfStream && line.IsNullOrWhiteSpace()) line = reader.ReadLine();
// 有时候Title跑到第二第三行去了
if (!reader.EndOfStream) line += Environment.NewLine + reader.ReadLine();
if (!reader.EndOfStream) line += Environment.NewLine + reader.ReadLine();
}
if (!String.IsNullOrEmpty(line))
{
// 正则
Match m = reg_PageTitle.Match(line);
if (m != null && m.Success) return m.Groups[1].Value;
}
// 第二正则
String content = File.ReadAllText(pagefile);
Match m2 = reg_PageTitle2.Match(content);
if (m2 != null && m2.Success) return m2.Groups[1].Value;
return null;
}
#endregion
#region 日志
/// <summary>写日志</summary>
/// <param name="action">操作</param>
/// <param name="remark">备注</param>
public static void WriteLog(String action, String remark)
{
var admin = ManageProvider.Provider.Current as IAdministrator;
if (admin != null) admin.WriteLog(typeof(TEntity), action, remark);
}
#endregion
#region 导入导出
/// <summary>导出</summary>
/// <param name="list"></param>
/// <returns></returns>
public static String Export(IList<IMenu> list)
{
return Export(new EntityList<TEntity>(list));
}
/// <summary>导出</summary>
/// <param name="list"></param>
/// <returns></returns>
public static String Export(EntityList<TEntity> list)
{
return list.ToXml();
}
/// <summary>导入</summary>
/// <param name="xml"></param>
public static void Import(String xml)
{
var list = new EntityList<TEntity>();
list.FromXml(xml);
foreach (var item in list)
{
item.Import();
}
}
#endregion
#region IMenu 成员
/// <summary>取得全路径的实体,由上向下排序</summary>
/// <param name="includeSelf">是否包含自己</param>
/// <param name="separator">分隔符</param>
/// <param name="func">回调</param>
/// <returns></returns>
string IMenu.GetFullPath(bool includeSelf, string separator, Func<IMenu, string> func)
{
Func<TEntity, String> d = null;
if (func != null) d = item => func(item);
return GetFullPath(includeSelf, separator, d);
}
/// <summary>检查菜单名称,修改为新名称。返回自身,支持链式写法</summary>
/// <param name="oldName"></param>
/// <param name="newName"></param>
IMenu IMenu.CheckMenuName(String oldName, String newName)
{
//IMenu menu = FindByPath(AllChilds, oldName, _.Name);
IMenu menu = FindByPath(oldName, _.Name, _.Permission, _.Remark);
if (menu != null && menu.Name != newName)
{
menu.Name = menu.Permission = newName;
menu.Save();
}
return this;
}
/// <summary>父菜单</summary>
IMenu IMenu.Parent { get { return Parent; } }
/// <summary>子菜单</summary>
IList<IMenu> IMenu.Childs { get { return Childs.OfType<IMenu>().ToList(); } }
/// <summary>子孙菜单</summary>
IList<IMenu> IMenu.AllChilds { get { return AllChilds.OfType<IMenu>().ToList(); } }
/// <summary>根据层次路径查找</summary>
/// <param name="path">层次路径</param>
/// <returns></returns>
IMenu IMenu.FindByPath(String path) { return FindByPath(path, _.Name, _.Permission, _.Remark); }
#endregion
}
public partial interface IMenu
{
/// <summary>取得全路径的实体,由上向下排序</summary>
/// <param name="includeSelf">是否包含自己</param>
/// <param name="separator">分隔符</param>
/// <param name="func">回调</param>
/// <returns></returns>
String GetFullPath(Boolean includeSelf, String separator, Func<IMenu, String> func);
/// <summary>检查菜单名称,修改为新名称。返回自身,支持链式写法</summary>
/// <param name="oldName"></param>
/// <param name="newName"></param>
IMenu CheckMenuName(String oldName, String newName);
/// <summary>父菜单</summary>
IMenu Parent { get; }
/// <summary>子菜单</summary>
IList<IMenu> Childs { get; }
/// <summary>子孙菜单</summary>
IList<IMenu> AllChilds { get; }
/// <summary>深度</summary>
Int32 Deepth { get; }
/// <summary>根据层次路径查找</summary>
/// <param name="path">层次路径</param>
/// <returns></returns>
IMenu FindByPath(String path);
/// <summary>排序上升</summary>
void Up();
/// <summary>排序下降</summary>
void Down();
/// <summary>保存</summary>
/// <returns></returns>
Int32 Save();
}
}
|