DIV CSS display (block,none,inline) - lyqandgdp - 博客园

mikel阅读(1318)

来源: DIV CSS display (block,none,inline) – lyqandgdp – 博客园

DIV CSS display (block,none,inline)

DIV CSS display (block none inline)属性的用法

在一般的CSS布局制作时候,我们常常会用到display对应值有block、none、inline这三个值。下面我们来分别来认识和学习什么 时候用什么值。这里通过CSS display知识加实例、图演示讲解方法来学习和了解DIV CSS display。

目录

CSS display使用

display的值有哪些

css display block

css display none

css display inline

1、CSS display使用

以下为DIV CSS运用dispaly

CSS代码:

.divcss{display:none}

Html对应运用:

<div class=”divcss”>我是测试内容</div>

2、display的值有哪些

Css display值与解释

参数:

block :块对象的默认值。用该值为对象之后添加新行。之前也添加一行。

none :隐藏对象。与visibility属性的hidden值不同,其不为被隐藏的对象保留其物理空间

inline :内联对象的默认值。用该值将从对象中删除行。如果其前后都是inline的则在同一行

compact :分配对象为块对象或基于内容之上的内联对象

marker :指定内容在容器对象之前或之后。要使用此参数,对象必须和:after及:before 伪元素一起使用

inline-table :将表格显示为无前后换行的内联对象或内联容器
list-item :将块对象指定为列表项目。并可以添加可选项目标志
run-in :分配对象为块对象或基于内容之上的内联对象
table :将对象作为块元素级的表格显示
table-caption :将对象作为表格标题显示
table-cell :将对象作为表格单元格显示
table-column :将对象作为表格列显示
table-column-group :将对象作为表格列组显示
table-header-group :将对象作为表格标题组显示
table-footer-group :将对象作为表格脚注组显示
table-row :将对象作为表格行显示
table-row-group :将对象作为表格行组显示

3、css display:block

Display:block是我们常用的,block也是Display默认的值。

block元素(即默认display:block)的特点是: 

· 总是在新行上开始;

· 该对象随后的内容自动换行;

· 高度,行高以及顶和底边距都可控制;

· 宽度缺省是它的容器的100%,除非设定一个宽度

<div>, <p>, <h1>, <form>, <ul> 和 <li>是块元素的例子。(意思是他们默认显示方式是block)

实例1.

CSS代码:

.divcss{display:block}

Html对应运用代码:

<span class="divcss">我的后面文字会换行</span>我是被前面的divcss对应CSS属性换行。
<span>不会被换行,因为我没有被设置display:block</span>

对应结果截图:

clip_image002[8]_thumb[2]

实例2.

<div style="width:200px;margin:0;background-color:#CCCCCC">
<p style="display:block;margin:0;">the first line</p>
<p style="display:block;margin:0;width:40%">the second line</p>
<div style="margin-top:2px;margin-bottom:2px;margin-left:10px;margin-right:10px;height:20px;">test div</div>
</div>

clip_image004[8]_thumb

可以看出这就是三行,可以看出宽度默认设置成其容器的100%,也可以设置成其他百分比。

4、css display:none

此display的none值,我们也常常使用,用于隐藏对象内容,被隐藏的对象也不会占用自身固有宽度高度空间。

例如在导航条的二级菜单中就会使用此属性显示和隐藏二级菜单。

5、css display:inline

Display:inline,我们常常在li中使用它。功能是让li排成一排(称:删除行)。

接下来我们以一个未设置li列表与一个设置css Display inline样式对比实例演示演示。

CSS代码

ul.divcss li{display:inline}

解释:ul.divcss对应li CSS样式属性为display:inline

inline元素(即默认display:inline)的特点是:

· 和其他元素都在一行上;

· 高,行高及顶和底边距不可改变;

· 宽度就是它的文字或图片的宽度,不可改变。

<span>, <a>, <label>, <input>, <img>, <strong> 和<em>是inline元素的例子

Html对应代码:

<ul>
<li>我父级ul没有divcss5样式</li>
<li>我是独行</li>
<li>我是独行</li>
</ul>
<ul class="divcss5">
<li>我父级ul有divcss5样式</li>
<li>我站成一排</li>
<li>我在divcss5下li站成一排</li>
</ul>

演示结果图:

clip_image006_thumb[1]

说明:设置css为display:inline的li对象,li被排成一排,而未设置的li列表对象仍然继承原来自身独占一行的CSS样式.

inline和block可以控制一个元素的行宽高等特性,需要切换的情况如下:

1. 让一个inline元素从新行开始;

将需要新开一行的元素的display设置成block.

2. 让块元素和其他元素保持在一行上;

将块元素的display的属性设置成inline.

3. 控制inline元素的宽度(对导航条特别有用);

4. 控制inline元素的高度;

HoloLens开发手记-开发概述Development overview - msp的昌伟哥哥 - 博客园

mikel阅读(1254)

来源: HoloLens开发手记-开发概述Development overview – msp的昌伟哥哥 – 博客园

开发概述

 

开发HoloLens全息应用将使用UWP平台(Universal Windows Platform),所有的HoloLens应用都是Win10通用应用,所有UWP通用应用都可以在HoloLens上运行。通过Windows 10和Unity这样的中间工具,我们可以现在开始构建全息应用的体验。

 

 

全息开发基础 Basics of a holographic development

 

为了尽可能实现全息场景,Windows暴露了一系列全新的特性给开发者。对混合现实全息应用来说,涉及到6个基础构建领域。

 

 

与HoloLens的交互被设计成凝视、手势和声音。这有时被联想到GGV。例如坐标、空间声音和空间匹配的这样的环境感知特性提供了用户与周围环境全息交互的能力。

 

全息场景是由依赖渲染的光和声音构成的。理解做为HoloLens Shell示范操作中的物体放置和持续存在的体验是一个能让你融入用户体验的好方式。

 

用于开发HoloLens的工具 Tools for developing on HoloLens

 

你将用于创建应用的工具取决于应用的类型。

 

  • 2D应用可以使用任何可以开发UWP应用的工具开发,例如用来开发PC、平板和Windows Phoned通用应用的工具。这种应用将被表现为2D投影,并且能够跨设备运行。
  • 全息应用需要使用基于Windows 全息API(Windows Holographic APIs)设计的工具来开发。特别说一下,如果你想开发全息应用,我们推荐使用Unity。对于那些想要构建自己引擎的开发者来说,可以使用DirectX和其它Windows API。

 

考虑到你要开发应用的类型,这些工具将会提高你的开发体验:

 

开始开发 Getting started

 

安装了这些工具后,我们推荐下面这些在HoloLens Academy中的教程。在你完成应用开发后,Windows应用商店就是你发布应用的地方,使得其它HoloLens用户也能使用。

 

HoloLens

 

 

PS:下月跳槽到北京做HoloLens开发,今后我会陆续翻译HoloLens的官方开发文档,希望能有所帮助。去年11月份作为MVP在西雅图试用了半小时HoloLens,虽未能有宣传视频那么震撼,但是完成度相当高,核心的特性也都具备了。

HoloLens开发手记 - 入门学习阶段总结 - msp的昌伟哥哥 - 博客园

mikel阅读(818)

来源: HoloLens开发手记 – 入门学习阶段总结 – msp的昌伟哥哥 – 博客园

伴随着数月的期 待,终于拿到了预订的HoloLens开发者版本套件。随着VR/AR/MR技术的热潮,国内外均对它们的应用与盈利前景持有积极的预期,这也直接导致了 国内外当前投资VR/AR/MR技术的热潮。无论是融资数十亿美元的Magic Leap,还是Facebook、微软等科技巨头布局VR/AR市场,这股热潮不仅出现在风险投资领域,还席卷了消费者市场和智能硬件市场,这无疑引领了 下一波互联网产业的爆发,而我们作为技术核心的开发者更不能落下。正如乔帮主所说:“Stay foolish,Stay Hungry”,今天我们就来了解下AR/MR技术的开发特性,本文以微软出品的HoloLens为目标设备。

 

AR/MR是什么?

 

VR大家都已经 很清楚了,VR即是虚拟现实技术,这意味着沉浸式全虚拟的使用体验。全虚拟沉浸式的体验带了独特的视觉效果,但是由于遮盖现实内容,仍导致了头晕、运动不 友好等难以解决的问题。与之相对的则是AR/MR技术,这意味虚拟世界与真实世界交织的视觉体验。从用户使用体验来看,AR/MR无疑是更符合人类自然交 互模式,代表了未来更伟大的发展方向。同时在笔者看来,由Magic Leap提出的MR(Mixed Reality)技术其本质与AR(Augmented Reality)技术并无区别,微软目前也在HoloLens文档中大量使用MR技术的说法,故此本文将AR/MR技术视为一体。

 

 

 

AR核心特性

 

正如上面所 说,AR具备与VR截然不同的视觉体验,所以其开发体验也与VR区别较大,下面我们来一起探讨HoloLens的部分核心开发特性。本文使用的开发环境为 Unity HoloLens preview beta 14以及Unity Universal Windows Platform Runtime组件,具体的配置细节可看:http://www.cnblogs.com/mantgh/p/5352703.html;

 

摄像机 Camera

 

根据沉浸式全虚拟的VR体验要求,所以我们见到VR独特的摄像机视角,包括两个一模一样内容的视口。

 

 

VR摄像机视图

 

然而,AR追求 的是自然的用户体验,所以不会遮挡任何真实世界的内容。所以我们并不需要创造两个同样视图内容的摄像头,仍然和传统的桌面、移动端没有太大区别。主要需要 适配的内容是背景和视角范围。对于HoloLens,将主摄像机渲染背景设为纯色,颜色设为RGBA(0,0,0,0)。因为任何纯黑的颜色将会被 HoloLens渲染为透明,以达到不遮挡现实世界的目的。此外,HoloLens建议摄像机视角近距离为0.85,这个距离最符合真实人眼的体验。同时 主摄像机位置必须重置为世界零点,即xyz(0,0,0),任何全息图像将会以此为原点在周边世界中绘制出来。

 

 

主摄像机推荐设置

 

Gaze凝视射线

 

与VR头戴设备一样,HoloLens同样依赖于设备发出的凝视射线来选中目标。Gaze凝视的作用和PC上的光标一样,配合语音和手势能够实现对全息对象的操纵。作为一个全息应用开发者,你可以使用凝视做到很多事情:

  • 应用可以通过判断凝视射线与全息物体的交叉来判断用户当前在关注什么。
  • 应用可以借助基于凝视射线的手势来实现选中、激活、拖拽或其他对全息物体的交互。
  • 通过凝视射线与空间匹配网格的交叉,应用可以让用户放置全息物体到真实世界的表面。
  • 应用可以知道何时用户没有注视在重要物体的方向,这使得你可以通过图形或者声音提醒将用户带回到正确的方向上。

Unity自带了对射线的支持,能够很好的集成为凝视射线,只需要简单的代码即可:

 

void Update() { RaycastHit hitInfo; if (Physics.Raycast( Camera.main.transform.position, Camera.main.transform.forward, out hitInfo, 20.0f, Physics.DefaultRaycastLayers)) { // 如果射线成功击中一个全息对象 // hitInfo的point属性代表了射线击中的位置 // hitInfo.collider.GameObject代表了射线集中地全息对象 } }

 

对于凝视射线,笔者建议使用单例来进行管理,这样可以避免功能混乱。同时为凝视设置可视化的指针,可以提高用户的交互体验和效率。

 

 

 

手势识别Gesture

 

手势是 HoloLens三大基本输入方式之一,其余是语音和凝视。Windows Holographic支持的基本手势为Air-Tap(点击),Hold(长按)和Bloom(绽开)。Air-Tap手势用于选中物体,而Hold手 势用于唤出二级菜单,Bloom手势用于唤出开始菜单。

 

 

开始菜单

 

同时我们可以为应用自定义手势,通过GestureRecognizer来识别。下面是基本的手势识别用法:

 

//初始化手势识别器 GestureRecognizer recognizer = new GestureRecognizer(); recognizer.SetRecognizableGestures(GestureSettings.Tap | GestureSettings.Hold); recognizer.TappedEvent += MyTapEventHandler; recognizer.HoldEvent += MyHoldEventHandler; //开始识别 recognizer.StartCapturingGestures();

 

 

语音识别Voice Command

 

语音识别同样是HoloLens重要组成部分,包括我们很熟悉的Cortana,同样能够为我们带来更自然高效的输入体验。

HoloLens的语音识别分为三个部分:

 

  • 语音命令 KeywordRecognizer:通过关键词来执行动作
  • 语法识别GrammarRecognizer:通过预设的语法来模糊匹配动作
  • 听写 Diction:即语音转文字,用于输入

 

三个组件中语音命令特性最为常用,配合凝视能够完成绝大部分场景的需求。为了使用语音命令,首先要启用KeywordRecognizer实例,同时要预设好<keyword,action>来源。

 

KeywordRecognizer keywordRecognizer; Dictionary<string, System.Action> keywords = new Dictionary<string, System.Action>();

 

 

通过<keyword,action>数组来初始化关键词识别器:

 

keywords.Add(“activate”, () => { // 关键词动作 }); keywordRecognizer = new KeywordRecognizer(keywords.Keys.ToArray()); keywordRecognizer.OnPhraseRecognized += KeywordRecognizer_OnPhraseRecognized; //开始识别 keywordRecognizer.Start();

 

在响应事件中做处理,调用识别到的关键词事件。

 

private void KeywordRecognizer_OnPhraseRecognized(PhraseRecognizedEventArgs args) { System.Action keywordAction; //如果关键词在预设列表中,即执行其2动作 if (keywords.TryGetValue(args.text, out keywordAction)) { keywordAction.Invoke(); } }

 

 

空间映射 Spatial Mapping

 

AR技术能实现的关键就是能够识别映射周边世界,这是全息对象与真实表面交互的基础,是AR技术的核心组件。HoloLens借助于微软特殊研发的全息处理单元(HPU 1.0)才能实现空间映射特性,幸运的是我们可以使用空间映射API来对真实世界做交互。

 

 

全息处理单元

 

我们可以利用SurfaceObserver组件来获取控件表面映射信息,下面是基本的操作:

 

SurfaceObserver surfaceObserver; void Start () { //初始化 surfaceObserver = new SurfaceObserver(); StartCoroutine(UpdateLoop()); } IEnumerator UpdateLoop() { var wait = new WaitForSeconds(2.5f); while(true) { surfaceObserver.Update(OnSurfaceChanged); yield return wait; } }

 

 

每一个空间表面都需要注册其Handle事件,用于实时调整空间映射信息和交互。

 

private void OnSurfaceChanged(SurfaceId surfaceId, SurfaceChange changeType, Bounds bounds, System.DateTime updateTime) { //处理空间表面变化 }

 

 

结语

 

AR/MR技术 独特的交互体验与开发特性,代表了未来自然交互的发展方向,相较于目前成熟的VR技术,它们具有更光明的发展前景和更广阔的用途。无论是微软还是 Magic Leap,他们无疑会是未来市场的引领者,而目前也是我们学习的黄金阶段,能够迎头赶上这波浪潮,对于相关从业者具有重要的意义。

HoloLens开发手记 - Unity之Spatial mapping 空间映射 - msp的昌伟哥哥 - 博客园

mikel阅读(1472)

来源: HoloLens开发手记 – Unity之Spatial mapping 空间映射 – msp的昌伟哥哥 – 博客园

 

本文主要讨论如何在Unity项目中集成空间映射功能。Unity内置了对空间映射功能的支持,通过以下两种方式提供给开发者:

  1. HoloToolkit项目中你可以找到空间映射组件,这可以让你便捷快速地开始使用空间映射特性。
  2. Unity还提供更多底层的空间映射API,以便开发者能够完全控制空间映射特性,满足定制复杂的应用需求

 

为了在应用使用空间映射特性,你必须在应用权限清单中启用SpatialPerception能力。

 

 

Setting the SpatialPerception capability 设置SpatialPerception能力


为了使应用能够使用空间映射数据,SpatialPerception能力必须被启用。

使用以下步骤启用此能力:

  1. 在Unity编辑器中,进入Player Settings选项(Edit > Project Settings > Player)
  2. 点击Window Store选项卡
  3. 展开Publish Settings选项,并在Capabilities列表勾选SpatialPerception选项

 

注意:如果你已经把Unity项目导出为Visual Studio项目,你需要重新导出修改后的项目到新文件夹或者手动在VS中修改AppxManifest应用清单

空间映射特性也要求项目MaxVersionTested版本最低为10.0.10586.0

  1. 在VS项目解决方案中,双击Package.appxmanifest文件,并右键选中查看源码方式打开
  2. 找到TargetDeviceFamily这一行,并将MaxVersionTested=”10.0.10240.0″ 修改为 MaxVersionTested=”10.0.10586.0″
  3. 保存Package.appmanifest文件

 

Spatial mapping components 空间映射组件


HoloToolkit项目提供了几个方案帮助你简单快速集成空间映射特性。

对于默认的空间映射需求,我们推荐使用SpatialMappingComponent目录下的 SpatialMappingCollider.csSpatialMapppingRenderer.cs脚本。如果你需要从网络或者文件载入空间网格,可以使用SpatialMapping目录下的脚本。

额外的信息可以在HoloToolkit项目Github主页上找到。

 

How to use the API 如何使用底层API


命名空间UnityEngine.VR.WSA

类型: SurfaceObserverSurfaceChangeSurfaceDataSurfaceId

SurfaceObserver是主要使用到的API对象,下面是应用使用空间映射特性推荐的大致流程。

 

Set up the SurfaceObserver(s) 设定SurfaceObserver对象

 

你要为每一个需要空间映射数据的空间区域在应用中初始化一个SurfaceObserver对象。

 

SurfaceObserver surfaceObserver;

 void Start () {
     surfaceObserver = new SurfaceObserver();
 }

 

通过调用SetVolumeAsSphere、SetVolumeAsAxisAlignedBox、 SetVolumeAsOrientedBox、 或 SetVolumeAsFrustum方法可以为每个SurfaceObserver对象指定它们需要获取数据的空间范围。以后你还可以通过再次调用它们 来重新设定检测的空间范围。

 

void Start () {
    ...
     surfaceObserver.SetVolumeAsAxisAlignedBox(Vector3.zero, new Vector3(3, 3, 3));
}

 

当你调用SurfaceObserver.Update()方法时,需要每一个SurfaceObserver对象检测区域中的空间表面(spatial surface)指定事件处理方法。

 

private void OnSurfaceChanged(SurfaceId surfaceId, SurfaceChange changeType, Bounds bounds, System.DateTime updateTime)
 {
    //处理空间表面变化
 }

 

Handling Surface Changes 处理空间表面变化

 

关于空间表面变化,有几个典型情形需要处理。Added状态和Updated状态可以使用相同的代码处理,Removed状态则使用另一种代码来处理。

  • 在Added和Updated情形下,我们从字典中添加或者获取代码当前网格的对象,使用必要的组件来创建一个SurfaceData结构体,然后调用RequestMeshDataAsync方法在场景中使用网格数据和位置来填充对象。
  • 在Removed情形下,我们从字典中移除当前网格代表的对象并销毁它。

 

复制代码
System.Collections.Generic.Dictionary<SurfaceId, GameObject> spatialMeshObjects = new System.Collections.Generic.Dictionary<SurfaceId, GameObject>();

   private void OnSurfaceChanged(SurfaceId surfaceId, SurfaceChange changeType, Bounds bounds, System.DateTime updateTime)
   {
       switch (changeType)
       {
           case SurfaceChange.Added:
           case SurfaceChange.Updated:
               if (!spatialMeshObjects.ContainsKey(surfaceId))
               {
                   spatialMeshObjects[surfaceId] = new GameObject("spatial-mapping-" + surfaceId);
                   spatialMeshObjects[surfaceId].transform.parent = this.transform;
                   spatialMeshObjects[surfaceId].AddComponent<MeshRenderer>();
               }
               GameObject target = spatialMeshObjects[surfaceId];
               SurfaceData sd = new SurfaceData(
                   //系统返回的surface id,
                   //当前对象的MeshFilter组件
                   target.GetComponent<MeshFilter>() ?? target.AddComponent<MeshFilter>(),
                   //用于在空间中定位对象的空间锚
                   target.GetComponent<WorldAnchor>() ?? target.AddComponent<WorldAnchor>(),
                   //当前网格对象的MeshCollider组件
                   target.GetComponent<MeshCollider>() ?? target.AddComponent<MeshCollider>(),
                   //每立方米网格三角形的数量
                   1000,
                   //bakeMeshes -如果是true,MeshCollider会被数据填充,反之MeshCollider为空
                   true
                   );

               SurfaceObserver.RequestMeshAsync(sd, OnDataReady);
               break;
           case SurfaceChange.Removed:
               var obj = spatialMeshObjects[surfaceId];
               spatialMeshObjects.Remove(surfaceId);
               if (obj != null)
               {
                   GameObject.Destroy(obj);
               }
               break;
           default:
               break;
       }
   }
复制代码

 

Handing Data Ready 处理DataReady事件

 

OnDataReady事件方法会接收到一个SurfaceData对象,它包含了WorldAnchor、MeshFilter和 MeshCollider对象数据,表示了当前关联的空间表面最新状态。通过访问Mesh Filter对象的Mesh数据可以进行性能分析或者处理网格。使用最新的Mesh数据来渲染空间表面并将它用于物理碰撞或者射线击中对象。确认 SurfaceData内容不为空很重要。

 

Start processing on updates 处理更新操作

 

SurfaceObserver.Update()方法只能延时调用,可以每帧更新都调用。

 

复制代码
void Start () {
    ...
     StartCoroutine(UpdateLoop());
}

 IEnumerator UpdateLoop()
    {
        var wait = new WaitForSeconds(2.5f);
        while(true)
        {
            surfaceObserver.Update(OnSurfaceChanged);
            yield return wait;
        }
    }
复制代码

 

HoloToolKit


HoloToolkit项目是基于Unity API封装的一系列很有用的全息开发代码工具集合,能帮助开发者快速集成HoloLens特性。

 

Troubleshooting 问题诊断


  • 确保你启用了 SpatialPreception能力
  • 当追踪焦点丢失时,在接下来的OnSurfaceChanged事件处理中将会移除现有所有的网格。

用最基本的EF+MVC+JQ+AJAX+bootstrap实现权限管理的简单实例 之登陆和操作权限 - 随机哥丶 - 博客园

mikel阅读(1476)

来源: 用最基本的EF+MVC+JQ+AJAX+bootstrap实现权限管理的简单实例 之登陆和操作权限 – 随机哥丶 – 博客园

搞清流程和职责,代码实现喜欢怎么搞就怎么搞

到目前为止,开发人员这块我感觉差不多了。开发人员的职责无非就是按业务需要和逻辑开发一个MVC控制器和控制器下的方法,这跟平常的没有权限管理 是一样一样的,如果要加权限管理,你只需要把它逻辑分类,保存到数据库,加上一些验证标签然后扔给前前端设计和管理员去管理分配。

模型都是最基本的属性,全部用的贫血的,如果用充血模型,API逻辑应该更清晰。比如用户隐藏字段的权限,可以写到用户类中去的。调用仓储接口来持久化,你可以用user.HideFiledToxx。

不多说了。我是把上篇文章的EF操作和水货RBAC生成DLL引用到这是测试项目来的。

后端就两个项目,非常简单。Domain层就一个服务是对上篇的进行二次封装,以持久化到数据库,另外一个是登陆用户服务类这两个类比较特别。其它都是一般的服务。这两个点是根据业务和数据库变化的。

复制代码
namespace Domain.DataModels
{
    public class User:YZY_RBAC.Core.YZYUser<int>
    {
        public User() : base(0) { }
        public string Name { get; set; }
        public string Telphone { get; set; }
    }
}
复制代码

复制代码
using System.Collections.Generic;
using YZY_RBAC.Core;

namespace Domain.DataModels
{
    public class Role:YZYRole<int>
    {
        public Role() : base(0) { }

        /// <summary>
        /// 指定角色可操作的门
        /// </summary>
        public virtual ICollection<Dep_Role> ManageDeps { get; set; } = new List<Dep_Role>();        
    }
}
复制代码

复制代码
using YZY_RBAC.Core;

namespace Domain.DataModels
{
    public class Relevance:BaseRelevance<int>
    {
        public Relevance() : base(0) { }
    }
}
复制代码

复制代码
using System.Collections.Generic;
using YZY_RBAC.Core;

namespace Domain.DataModels
{
    public class Module:BaseEntity<int>
    {
        public Module() : base(0) { }
        public string Name { get; set; }
        public virtual ICollection<Menu> Menus { get; set; }
        public string Type { get; set; }
        public bool IsAdminModule { get; set; }
        public string Url { get; set; }
    }
}
复制代码

复制代码
using System.Collections.Generic;
using YZY_RBAC.Core;

namespace Domain.DataModels
{
    public class Menu:BaseEntity<int>
    {
        public Menu() : base(0) { }
        public string Url { get; set; }
        public string RoleType { get; set; }
        public virtual ICollection<ActionButton> Buttons { get; set; } = new List<ActionButton>();
        public string Name { get; set; }
        public virtual Module Module { get; set; }
        public int? ModuleId { get; set; }
    }
}
复制代码

复制代码
using YZY_RBAC.Core;

namespace Domain.DataModels
{
    public class HideFiled:BaseHideFiled<int>
    {
        public HideFiled() : base(0) { }
    }
}
复制代码

复制代码
using System.Collections.Generic;

namespace Domain.DataModels
{
    public class Employee:User
    {     
        public virtual ICollection<Dep_Emp> Depatments { get; set; } = new List<Dep_Emp>();

        /// <summary>
        /// 姓名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 性别
        /// </summary>
        public string Gender { get; set; }

        /// <summary>
        /// 年龄
        /// </summary>
        public int Age { get; set; }

        /// <summary>
        /// 工资
        /// </summary>
        public double Salary { get; set; }

    }
}
复制代码

复制代码
using System.Collections.Generic;
using YZY_RBAC.Core;

namespace Domain.DataModels
{
    public class Deparentment:BaseEntity<int>
    {
        public Deparentment() : base(0) { }
        public string Name { get; set; }
        public string Number { get; set; }
        public int? ParentId { get; set; }
        public virtual Deparentment Parent { get; set; }
        public virtual ICollection<Dep_Emp> Employees { get; set; } = new List<Dep_Emp>();
        public virtual ICollection<Dep_Role> Roles { get; set; } = new List<Dep_Role>();     
        public virtual ICollection<Deparentment> Childs { get; set; } = new List<Deparentment>();
        public bool IsTop { get; set; }
    }
}
复制代码

复制代码
using YZY_RBAC.Core;

namespace Domain.DataModels
{
    public class Dep_Role:BaseEntity<int>
    {
        public Dep_Role() : base(0) { }
        public int DepId { get; set; }
        public virtual Deparentment Dep { get; set; }
        public int RoleId { get; set; }
        public virtual Role Role { get; set; }
    }
}
复制代码

复制代码
using YZY_RBAC.Core;

namespace Domain.DataModels
{
    public class Dep_Emp:BaseEntity<int>
    {
        public Dep_Emp() : base(0) { }
        public Deparentment Dep { get; set; }
        public int DepId { get; set; }
        public Employee Emp { get; set; }
        public int EmpId { get; set; }
    }
}
复制代码

复制代码
using YZY_RBAC.Core;

namespace Domain.DataModels
{
    public class ActionButton:BaseEntity<int>
    {
        public ActionButton() : base(0) { }
        public int? MenuId { get; set; }
        public virtual Menu Menu { get; set; }
        public string Url { get; set; }
        public string Icon { get; set; }
        public string RoleType { get; set; }
        public string Name { get; set; }
    }
}
复制代码

上面这些代码这真心是蛮不好意思贴出来的。服务类就是些CURD我就不贴出来了,把两个特别点的贴出来。AuthorizeService就是个 授权服务,将两个实体间的权限通过权限类型进行关联。LoginUserService是根据当前登陆用户的身份加载用户的所有权限集合,供前端用。但是 我没有写测试代码,功能现在还不知道有没有问题。

复制代码
using Domain.DataModels;
using System;
using System.Collections.Generic;
using System.Linq;
using YZY_RBAC.Core;

namespace Domain.Service
{
    public class AuthorizeService<TEntity>where TEntity:BaseEntity<int>
    {
        
        public static RBACManage<TEntity, int> rbac { get; set; } = new RBACManage<TEntity, int>();

        private static RelevanceService releService;
        
        private static HideFiledService hideService;

        /// <summary>
        /// 初始化RBAC
        /// </summary>
        public static void InitiaRbac()
        {
            releService = new RelevanceService();
            hideService = new HideFiledService();
            rbac.RelevanceQuery = releService.Find();
            rbac.HideFiledQuery = hideService.Find();
        }        

        /// <summary>
        /// 为当前实体授权指定的权限
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="per"></param>
        /// <param name="type"></param>
        public static void Authorize<TPer>(TEntity entity,TPer per,PermissionType type)where TPer:BaseEntity<int>
        {
            var rel = rbac.GetBindRelevance(entity, new Relevance(), per, type) as Relevance;
            if (!releService.Find().Any(o => o.EntityId == entity.Id && o.PermisId == per.Id))
                releService.Add(rel);
            releService.Commit();
            InitiaRbac();
        }

        /// <summary>
        /// 为当前实体授权指定的权限
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="pers"></param>
        /// <param name="type"></param>
        public static void Authorize<TPer>(TEntity entity,IEnumerable<TPer>pers,PermissionType type) where TPer : BaseEntity<int>
        {
            if(pers!=null&&pers.Count()>0)
            {
                foreach(var p in pers)
                {
                    var rel = rbac.GetBindRelevance(entity, new Relevance(), p, type) as Relevance;
                    if (!releService.Find().Any(o => o.EntityId == entity.Id && o.PermisId == p.Id))
                        releService.Add(rel);
                }
                releService.Commit();
                InitiaRbac();
            }
        }

        /// <summary>
        /// 设置当前实体对其它实体隐藏指定的权限
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="per"></param>
        /// <param name="filedName"></param>
        public static void SetHideFiledToOther<T>(TEntity entity, T per, string filedName)
            where T:BaseEntity<int>
        {
            //保存申请的隐藏字段权限
            var hide = rbac.GetRegisteHideFiled(entity, filedName, new HideFiled()) as HideFiled;
            if (!hideService.Find().Any(o => o.EntityId == entity.Id && o.HidePropertyName == filedName))
            {
                hideService.Add(hide);
                hideService.Commit();
                InitiaRbac();
            }            
            var rel = rbac.GetBindHideFiledToOtherEntityRelevance(entity, new Relevance(), per, filedName);
            //如数据库中不存在这个关联,则添加
            if (!releService.Find().Any(o => o.EntityId == per.Id &&
            o.PermissionType == PermissionType.Propety.ToString() && o.PermisId == hide.Id))
            {
                releService.Add(rel as Relevance);
            }                
            releService.Commit();
            InitiaRbac();            
        }

        /// <summary>
        /// 设置当前实体对其它实体隐藏指定的权限
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="filedName"></param>
        /// <param name="others"></param>
        public static void SetHideFiledToOther<T>(TEntity entity,string filedName,IEnumerable<T>others)where T:BaseEntity<int>
        {
            if(others!=null&&others.Count()>0)
            {
                foreach(var o in others)
                {
                    SetHideFiledToOther(entity, o, filedName);
                }
            }
        }
        
        /// <summary>
        /// 取消隐藏字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="filedName"></param>
        public static void ClearHideFiled(TEntity entity, string filedName)
        {
            if (hideService.Find().Any(o => o.EntityId == entity.Id && o.HidePropertyName == filedName))
            {
                var hide =hideService.Find().Where(o => o.EntityId == entity.Id && o.HidePropertyName == filedName).FirstOrDefault();
                hideService.Remove(hide);
                if (releService.Find().Any(o => o.PermisId == hide.Id && o.PermissionType == PermissionType.Propety.ToString()))
                {
                    var rels = releService.Find().Where(o => o.PermisId == hide.Id && o.PermissionType == "Porpety").ToList();
                    foreach (var r in rels)
                    {
                        releService.Remove(r);
                    }
                    releService.Commit();
                    hideService.Commit();
                    InitiaRbac();
                    return;
                }
            }
            throw new Exception("没有找到指定的字段");
        }

        /// <summary>
        /// 取消对指的其它实体的隐藏字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="filedName"></param>
        /// <param name="other"></param>
        public static void ClearHideFiledToOther<T>(TEntity entity,string filedName,T other)where T:BaseEntity<int>
        {
            if(hideService.Find().Any(o=>o.EntityId==entity.Id&&o.HidePropertyName==filedName))
            {
                var hide = hideService.Find().Where(o => o.EntityId == entity.Id && o.HidePropertyName == filedName).FirstOrDefault();
                hideService.Remove(hide);
                if(releService.Find().Any(o=>o.EntityId==other.Id&&o.PermisId==hide.Id&&o.PermissionType==PermissionType.Propety.ToString()))
                {
                    var rel = releService.Find(o => o.EntityId == other.Id && o.PermissionType == "Propety" && o.PermisId == hide.Id).FirstOrDefault();
                    releService.Remove(rel);
                    releService.Commit();
                }
                hideService.Commit();
                InitiaRbac();
                return;
            }
            throw new Exception("没有找到指定的字段");
        }

        /// <summary>
        /// 取消对指的其它实体的隐藏字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="filedName"></param>
        /// <param name="others"></param>
        public static void ClearHideFiledToOther<T>(TEntity entity, string filedName, IEnumerable<T>others)
            where T : BaseEntity<int>
        {
            if(others!=null&&others.Count()>0)
            {
                foreach (var o in others)
                    ClearHideFiledToOther(entity, filedName, o);
            }
        }

        /// <summary>
        /// 取消当前实体的指定授权
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="other"></param>
        /// <param name="relFilter"></param>
        public static void ClearAuthorizetion<T>
            (TEntity entity,T other,Func<Relevance,bool>relFilter=null)
            where T:BaseEntity<int>
        {
            Relevance rel = null;
            if(relFilter==null)
            {
                if(releService.Find(o=>o.EntityId==entity.Id&&o.PermisId==other.Id).Any())
                {
                    rel = releService.Find(o => o.EntityId == entity.Id && o.PermisId == other.Id).FirstOrDefault();
                    releService.Remove(rel);
                    releService.Commit();
                    InitiaRbac();
                    return;
                }
            }
            if(releService.Find(o=>o.EntityId==entity.Id&&o.PermisId==other.Id).AsEnumerable().Where(relFilter).Any())
            {
                rel = releService.Find(o => o.EntityId == entity.Id && o.PermisId == other.Id).AsEnumerable().Where(relFilter).FirstOrDefault();
                releService.Remove(rel);
                releService.Commit();
                InitiaRbac();
                return;
            }
            throw new Exception("没有找到指定的关联");
        }

        /// <summary>
        /// 取消当前实体的指定授权
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="others"></param>
        /// <param name="relFilter"></param>
        public static void ClearAuthorizetion<T>
            (TEntity entity, IEnumerable<T> others, Func<Relevance, bool> relFilter = null)
            where T : BaseEntity<int>
        {
            if(others!=null&&others.Count()>0)
            {
                foreach (var o in others)
                    ClearAuthorizetion(entity, o, relFilter);
            }
        }

    }
}
复制代码

复制代码
using Domain.DataModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YZY.Domain;
using YZY_RBAC.Core;

namespace Domain.Service
{
    public class LoginUserService
    {
        public LoginUserService(User loginUser)
        {  
            mage = new LoginUserMagage<int>(user);
            mage.HideFiledQuery = new HideFiledService().Find();
            mage.RelevanceQuery = new RelevanceService().Find();
            mage.RoleQuery = new RoleService().Find();
        }
        private User user = UserManage<int>.GetCacheUser() as User;

        private Pager pager;
        private LoginUserMagage<int> mage;
        private List<ActionButton> btns = new List<ActionButton>();
        private List<Deparentment> deps = new List<Deparentment>();
        private List<Employee> ems = new List<Employee>();
        private List<Menu> menus = new List<Menu>();
        private List<Role> roles = new List<Role>();
        private List<Module> modules = new List<Module>();
        private List<User> users = new List<User>();

        #region 属性

        /// <summary>
        /// 当前登陆用户
        /// </summary>
        public User LoginUser { get { return user; } }

        /// <summary>
        /// 当前登陆用户可访问或操作的按钮
        /// </summary>
        public IEnumerable<ActionButton> Buttons { get { return btns; } }

        /// <summary>
        /// 登陆用户可访问的模块
        /// </summary>
        public IEnumerable<Module> Modules { get { return modules; } }

        /// <summary>
        /// 当前登陆用户可访问或操作部门
        /// </summary>
        public IEnumerable<Deparentment> Departs { get { return deps; } }

        /// <summary>
        /// 当前登陆用户可访问或操作员工
        /// </summary>
        public IEnumerable<Employee> Employees { get { return ems; } }

        /// <summary>
        /// 当前登陆用户可访问或操作的菜单
        /// </summary>
        public IEnumerable<Menu> Menus { get { return menus; } }

        /// <summary>
        /// 当前登陆用户可访问或操作的角色
        /// </summary>
        public IEnumerable<Role> Roles { get { return roles; } }

        /// <summary>
        /// 登陆用户可访问的用户
        /// </summary>
        public IEnumerable<User> Users { get { return users; } }
        //分页数据
        public int EmpPageIndex { get; set; }
        public int EmpPageSize { get; set; }
                
        #endregion

        /// <summary>
        /// 加载当前登陆用户的权限资源和数据
        /// </summary>
        public void LoadLoginUserResouces()
        {
            if (user != null)
            {

                #region 系统管理员登陆

                if (user.IsSysAdmin)
                {
                    
                    deps = new DepartmentService().Find().ToList();
                    btns = new ButtonService().Find().ToList();
                    ems = new EmpService().FindPage(EmpPageIndex, EmpPageSize).ToList();
                    menus = new MenuService().Find().ToList();
                    roles = new RoleService().Find().ToList();
                    modules = new ModuleService().Find().ToList();
                    users = new UserService().Find().ToList();
                    return;
                }
                #endregion

                #region 以员工身份登陆的用户

                string tel = user.Telphone;
                if (new EmpService().Find(o => o.Telphone == tel).Any())
                {
                    Employee em = new EmpService().Find(o => o.Telphone == tel).Single();
                    mage = new LoginUserMagage<int>(em);
                    mage.HideFiledQuery = new HideFiledService().Find();
                    mage.RelevanceQuery = new RelevanceService().Find();
                    mage.RoleQuery = new RoleService().Find();

                    //获取后台已授权的数据
                    btns = mage.GetInPermissionResouces(new ButtonService().Find(), null).ToList();
                    menus = mage.GetInPermissionResouces(new MenuService().Find(), null).ToList();
                    roles = mage.GetInPermissionResouces(new RoleService().Find(), null).ToList();
                    modules = mage.GetInPermissionResouces(new ModuleService().Find(), null).ToList();
                    users = mage.GetInPermissionResouces(new UserService().Find(), null).Where(o => o.IsSysAdmin == false).ToList();

                    //默认的数据规则:用户只能访问自己部门和同部门的员工                
                    deps = new Dep_EmpService().Find(o => o.Emp == em).Select(o => o.Dep).ToList();

                    //如果当前用户有角色权限,并集角色的部门
                    if (roles != null && roles.Count > 0)
                    {
                        foreach (var r in roles)
                        {
                            deps = new Dep_RoleService().Find(o => o.Role == r).ToList().Select(o => o.Dep).Union(deps).ToList();
                        }
                        deps = deps.Distinct(new DistinctEntityId<Deparentment, int>()).ToList();
                    }
                    //找出所有部门下的员工
                    foreach (var d in deps)
                    {
                        ems = ems.Union(new Dep_EmpService().Find(o => o.DepId == d.Id).ToList().Select(o => o.Emp)).ToList();
                        pager = new Pager(ems.Count);
                        pager.Initia(EmpPageIndex, EmpPageSize);
                        ems = ems.OrderBy(o => o.Id).Skip(pager.Skip).Take(pager.Take).ToList();
                    }
                    //如果其中有隐藏字段的员工,替换掉
                    var hides = mage.GetHideFiledResouces(new EmpService().Find());
                    if (hides != null && hides.Count() > 0)
                    {
                        ems = ems.Except(hides, new DistinctEntityId<Employee, int>()).Union(hides).ToList();
                    }
                    return;
                }
                #endregion

                #region 以角色或其它身份登陆
                //获取后台已授权的数据
                btns = mage.GetInPermissionResouces(new ButtonService().Find(), null).ToList();
                menus = mage.GetInPermissionResouces(new MenuService().Find(), null).ToList();
                roles = mage.GetInPermissionResouces(new RoleService().Find(), null).ToList();
                modules = mage.GetInPermissionResouces(new ModuleService().Find(), null).ToList();
                users = mage.GetInPermissionResouces(new UserService().Find(), null).Where(o => o.IsSysAdmin == false).ToList();
                //如果当前用户有角色权限,并集角色的部门
                if (roles != null && roles.Count > 0)
                {
                    var drs = new Dep_RoleService();
                    foreach (var r in roles)
                    {
                        if (drs.Find(o => o.RoleId == r.Id).Any())
                        {
                            deps.Add(drs.Find(o => o.RoleId == r.Id).Select(o => o.Dep).Single());
                        }
                        //deps = new Dep_RoleService().Find(o => o.Role == r).ToList().Select(o => o.Dep).Union(deps).ToList();
                    }
                    deps = deps.Distinct(new DistinctEntityId<Deparentment, int>()).ToList();
                }
                //找出所有部门下的员工
                foreach (var d in deps)
                {
                    ems = ems.Union(new Dep_EmpService().Find(o => o.DepId == d.Id).ToList().Select(o => o.Emp)).ToList();
                }
                //如果其中有隐藏字段的员工,替换掉
                var hids = mage.GetHideFiledResouces(new EmpService().Find());
                if (hids != null && hids.Count() > 0)
                {
                    ems = ems.Except(hids, new DistinctEntityId<Employee, int>()).Union(hids).ToList();
                }
                #endregion

            }
        }

        /// <summary>
        /// 根据地址和权限类型判断当前登陆用户是否有该操作权限
        /// </summary>
        /// <param name="url"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public bool CheckActionAuthorize(string url,PermissionType type)
        {  
            
            if (type == PermissionType.Button)
            {
                ButtonService service = new ButtonService();
                ActionButton action = null;
                if (service.Find(o => o.Url == url).Any())
                    action = service.Find(o => o.Url == url).First();
                if (action == null) throw (new Exception("没有找到指定URL的操作,请确定URL和TYPE正确"));
                return mage.CheckPermission(action);
            }
            if (type == PermissionType.Menu)
            {
                MenuService service = new MenuService();
                Menu action = null;
                if (service.Find(o => o.Url == url).Any())
                    action = service.Find(o => o.Url == url).First();
                if (action == null) throw (new Exception("没有找到指定URL的操作,请确定URL和TYPE正确"));
                return mage.CheckPermission(action);
            }
            if(type== PermissionType.Module)
            {
                ModuleService service = new ModuleService();
                Module action = null;
                if (service.Find(o => o.Url == url).Any())
                    action = service.Find(o => o.Url == url).First();
                if (action == null) throw (new Exception("没有找到指定URL的操作,请确定URL和TYPE正确"));
                return mage.CheckPermission(action);
            }
            return false;
        }
    }
}
复制代码

EF上下文

关健是实体之间的关联关系配置,relevance实体的关联是通过代码逻辑来实现的,其它的是上下文配置的。好像都有注释的。是的,用的正是CodeFirst

复制代码
using System.Data.Entity;
using YZY.Datas.EF;
using System.Data.Entity.ModelConfiguration.Conventions;
using Domain.DataModels;

namespace EFDbcontext
{
    public class RBACDemoContext:EFUnitOfWork
    {
        public RBACDemoContext() : base("RBACDemoContext") { }
        public virtual DbSet<User> Users { get; set; }
        public virtual DbSet<Module> Modules { get; set; }
        public virtual DbSet<Role> Roles { get; set; }
        public virtual DbSet<Relevance> Relevance { get; set; }
        public virtual DbSet<HideFiled> HideFiled { get; set; }
        public virtual DbSet<ActionButton> Buttons { get; set; }
        public virtual DbSet<Deparentment> Departments { get; set; }
        public virtual DbSet<Employee> Employees { get; set; }
        public virtual DbSet<Menu> Menus { get; set; }
        public virtual DbSet<Dep_Emp> Dep_Emp { get; set; }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            
           
            //配置按钮和菜单的1:N关系
            modelBuilder.Entity<ActionButton>()
                .HasOptional(o => o.Menu)
                .WithMany(o => o.Buttons)
                .HasForeignKey(o => o.MenuId);         

            //配置部门的层级关系
            modelBuilder.Entity<Deparentment>()
                .HasOptional(o => o.Parent).WithMany(o => o.Childs).HasForeignKey(o => o.ParentId);

            //配置部门和员工的N:N关系
            modelBuilder.Entity<Dep_Emp>().HasKey(o => new { o.DepId, o.EmpId });
            modelBuilder.Entity<Dep_Emp>()
                .HasRequired(o => o.Dep).WithMany(o => o.Employees).HasForeignKey(o => o.DepId);
            modelBuilder.Entity<Dep_Emp>()
                .HasRequired(o => o.Emp).WithMany(o => o.Depatments).HasForeignKey(o => o.EmpId);

            //配置部门和角色的N:N关系
            modelBuilder.Entity<Dep_Role>().HasKey(o => new { o.DepId, o.RoleId });
            modelBuilder.Entity<Dep_Role>()
                .HasRequired(o => o.Dep).WithMany(o => o.Roles).HasForeignKey(o => o.DepId);
            modelBuilder.Entity<Dep_Role>()
                .HasRequired(o => o.Role).WithMany(o => o.ManageDeps).HasForeignKey(o => o.RoleId);


            //配置模块和菜单的1:N关系
            modelBuilder.Entity<Menu>()
                .HasOptional(o => o.Module).WithMany(o => o.Menus).HasForeignKey(o => o.ModuleId);

        }

    }
}
复制代码

 

MVC部分:视图模型和登陆鉴权

是的,没有用到DTO。小例子,没必要用上DTO,也没用到json,因为我并没有把后端做成WebApi或是WebService,前端用的也正是.net MVC。

复制代码
using Domain.DataModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MVCDemo.Models
{
    public class LoginUserResouces
    {
        public List<Menu> Menus { get; set; }
        public List<ActionButton> Buttons { get; set; }
        public List<Deparentment> Departs { get; set; }
        public List<Employee> Employees { get; set; }
        public List<Role> Roles { get; set; }
        public List<Module> Modules { get; set; }
        public List<User> Users { get; set; }
    }
}
复制代码

我的用户与服务器交互用的是cookie和缓存,没有用session,本来是想用memcached缓存的,但是我的mem装在虚拟机在,开个VS,IIS基本机器要炸了,根本开不了其它的了。无奈之下才用的MS的缓存。

复制代码
using Domain.DataModels;
using Domain.Service;
using MVCDemo.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using YZY.Domain;

namespace MVCDemo.Controllers
{
    public class BaseController:Controller
    {
        public BaseController()
        {
            if (new LoginUserService(UserManage<int>.GetCacheUser() as User) != null)
            {
                lus = new LoginUserService(UserManage<int>.GetCacheUser() as User);
                LoadResouce();
            }
        }

        /// <summary>
        /// 当前登陆用户
        /// </summary>
        public User LoginUser { get { return lus.LoginUser; } }
        private LoginUserService lus ;

        /// <summary>
        /// 是否启用登陆检测
        /// </summary>
        public bool IsCheckLogin { get; set; } = true;

        /// <summary>
        /// 跳转登陆页前的url
        /// </summary>
        public string LastUrl { get { return lastUrl; } }
        private string lastUrl;

        /// <summary>
        /// 缓存
        /// </summary>
        public ICache Cache { get { return DependencyContext.Resolve<ICache>(); } }    
        

        public LoginUserResouces Resouces { get { return resouces; } }

        private LoginUserResouces resouces = new LoginUserResouces();

        /// <summary>
        /// 加载用户的所有权限供控制器
        /// </summary>
        private void LoadResouce()
        {
            if (lus != null)
            {
                lus.LoadLoginUserResouces();
                resouces.Buttons = lus.Buttons.ToList();
                resouces.Departs = lus.Departs.ToList();
                resouces.Employees = lus.Employees.ToList();
                resouces.Menus = lus.Menus.ToList();
                resouces.Roles = lus.Roles.ToList();
                resouces.Modules = lus.Modules.ToList();
                resouces.Users = lus.Users.ToList();
            }
        }
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (IsCheckLogin)
            {                              
                //如果没有登陆跳转到登陆页面
                if (LoginUser == null)
                {

                    lastUrl = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName + "/"
                        + filterContext.ActionDescriptor.ActionName;
                    //将跳转前的url保存到缓存中
                    if (Cache.GetCache("LastUrl") == null) Cache.AddCache("LastUrl", lastUrl);
                    else
                    {
                        Cache.DelCache("LastUrl");
                        Cache.AddCache("LastUrl", lastUrl);
                    }
                    filterContext.HttpContext.Response.Redirect("/Login/Index");                    
                }
            }
        }
        
    }
}
复制代码

基类控制器目前还没有写错误处理和日志记录,又是一个未成品,主要是没写测试,很多功能可能还有错误。下面是鉴权标签类和登陆控制器代码

复制代码
using Domain.DataModels;
using Domain.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using YZY.Domain;
using YZY_RBAC.Core;

namespace MVCDemo.Controllers
{
    //指示当前标签类可用于类或者方法,每个类或者方法只能有一个当前标签
    [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method,AllowMultiple =false)]
    public class UserAuthorizeAttribute:AuthorizeAttribute
    {
        public PermissionType Type { get; set; }
        public override void OnAuthorization(AuthorizationContext filterContext)
        {   
            //此处可以通过修改身份认证的provide来获取当前的用户:通过filterContext.HttpContext.User;
            //User u = service.LoginUser;
            LoginUserService service = null;
            if (UserManage<int>.GetCacheUser() != null)
            {
                service = new LoginUserService(UserManage<int>.GetCacheUser() as User);
            }
            if (service != null)
            {
                if (service.LoginUser != null)
                {
                    string conUrl = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower();
                    string actUrl = conUrl + "/" + filterContext.ActionDescriptor.ActionName;
                    string checkUrl = "";
                    if (Type == PermissionType.Module)
                    {
                        checkUrl = conUrl;
                    }
                    else
                    {
                        checkUrl = actUrl;
                    }
                    if (service.LoginUser.IsSysAdmin) return;
                    bool yn = false;
                    try { yn = service.CheckActionAuthorize(checkUrl, Type); }

                    //错误应该不要紧,用户没登陆会自动跳转到登陆页面,直到有用户,所以没有处理catch
                    catch { }
                    if (!yn)
                    {
                        filterContext.Result = new ContentResult { Content = "你没有权限,不是通过界面搞进来的?" };

                        /*此处应跳转至错误页面
                        filterContext.HttpContext.Response.Redirect("url");
                        或者filterContext.Result = new RedirectToRouteResult(
                        new RouteValueDictionary {
                             { "action", url },
                             { "controller", url } });*/

                    }
                }
            }
        }
    }
}
复制代码

复制代码
using Domain.DataModels;
using Domain.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using YZY.Domain;

namespace MVCDemo.Controllers
{
    public class LoginController : BaseController 
    {
        public LoginController() { IsCheckLogin = false; }
        
        private UserService service = new UserService();
        private EmpService emService = new EmpService();
        // GET: Login
        public ActionResult Index()
        {            
            return View();
        }
        [HttpPost]
        public ActionResult Account()
        {
            IsCheckLogin = false;
            string acc = Request["Account"];
            string pwd = Request["Password"];
            string rem = Request["Rember"];
            User u = null;
            if( !service.Find(o=>o.Account==acc).Any()&& !emService.Find(o => o.Account == acc).Any())
            {
                 return Content("no:帐户不存在");
            }
            if (service.Find(o => o.Account == acc).Any())
                u = service.Find(o => o.Account == acc).First();
            else if(emService.Find(o=>o.Account==acc).Any())
            {
                u = emService.Find(o => o.Account == acc).First();
            }
            if (u != null)
            {
                string depwd = UserManage<int>.GetDeCryptPwd(u.Password);

                if (depwd == pwd)
                {
                    if (rem == "true" && u != null)
                    {
                        UserManage<int>.CookieExpiresTime = 24 * 30 * 60;
                        UserManage<int>.CacheExpiresTime = 24 * 30 * 60;
                        UserManage<int>.AddCacheUser(u);
                    }
                    UserManage<int>.AddCacheUser(u);
                    if (Cache.GetCache("LastUrl")==null) return Content("ok:/Home/Index");
                    return Content("ok:/" + Cache.GetCache("LastUrl").ToString());
                }
            }
            return Content("no:密码不正确");
        }
    }
}
复制代码

本来是为了方便我扩展了控制器的一些方法,结果发现用处不是很大

复制代码
using Domain.DataModels;
using Domain.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using YZY.Domain;
using YZY_RBAC.Core;

namespace MVCDemo.Controllers
{
    public static class ExtController
    {  
        public static ButtonService btnService { get; set; } = new ButtonService();
        public static MenuService menuService { get; set; } = new MenuService();
        public static ModuleService modService { get; set; } = new ModuleService();

        private static ILogger logger = DependencyContext.Resolve<ILogger>();

        /// <summary>
        /// 将当前控制器注册到数据库
        /// </summary>
        /// <param name="controller"></param>
        /// <param name="perType"></param>
        /// <param name="name"></param>
        public static void RegiterToDb
            (this Controller controller,PermissionType perType,string name)
        {
            
            string controlUrl = controller.RouteData.Values["controller"].ToString().ToLower();
            string url = controlUrl + "/" + controller.RouteData.Values["action"].ToString().ToLower();

            
            if(perType== PermissionType.Button)
            {
                var btn = new ActionButton();
                btn.Name = name;
                btn.Url = url;
                try
                {
                    btnService.Add(btn);
                }
                catch (Exception ex)
                {
                    throw new CustomWarring("没有添加成功", "UI", logger.LogLevel, ex);
                }
                return;
            }
            if(perType== PermissionType.Module)
            {
                var module = new Module();
                module.Name = name;
                module.Url = controlUrl;
                modService.Add(module);
                return;
            }
            if(perType== PermissionType.Menu)
            {
                var menu = new Menu();
                menu.Name = name;
                menu.Url = url;
                menuService.Add(menu);
                return;
            }
            throw new CustomWarring("当前权限类型不能用于注册MVC控制器或控制器方法", "UI", logger.LogLevel);
        }
        
        public static void BindingButtonToMenu(this Controller controller, string menuName)
        {
            string url = controller.RouteData.Values["controller"].ToString().ToLower();
            url += "/" + controller.RouteData.Values["action"].ToString().ToLower();
            var btn = btnService.GetForUrl(url);
            var menu = menuService.GetForName(menuName);
            btnService.SetToMenu(btn.Name, menuName);
        }
        public static void BindingMenuToModule(this Controller controller,string moduleName)
        {
            string url = controller.RouteData.Values["controller"].ToString().ToLower();
            url += "/" + controller.RouteData.Values["action"].ToString().ToLower();
            var menu = menuService.GetForUrl(url);
            menuService.SetIntoModule(menu.Name, moduleName);
        }
        
    }
}
复制代码

 

MVC部分:控制器

不想写字了,直接上代码吧,有问题的欢迎评论,我会积极参与

复制代码
using Domain.DataModels;
using Domain.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using YZY.Domain;
using YZY_RBAC.Core;
using Newtonsoft.Json;

namespace MVCDemo.Controllers
{
    //整个打成控制器级别的权限,除非被分配了权限,除了开发者其它都进不来
    //对于模块,菜单,按钮的添加修改等开发者工作,没有存入数据库中
    [UserAuthorize(Type= PermissionType.Module)]
    public class AdminController : BaseController
    {
        private ILogger logger = DependencyContext.Resolve<ILogger>();
        private ModuleService modService=new ModuleService();
        private MenuService menService=new MenuService();
        // GET: Admian    

        /// <summary>
        /// 模块管理菜单
        /// </summary>
        /// <returns></returns>
        [UserAuthorize(Type=PermissionType.Menu)]    
        public ActionResult ModuleManage()
        {
            if(!menService.Find(o=>o.Name=="模块管理").Any())
            {
                this.RegiterToDb(PermissionType.Menu, "模块管理");
            }
            this.BindingMenuToModule("开发人员模块");
            return Content(PermissionType.Module.ToString());
        }

        /// <summary>
        /// 菜单管理菜单
        /// </summary>
        /// <returns></returns>
        [UserAuthorize(Type = PermissionType.Menu)]
        public ActionResult MenuManage()
        {
            if (!menService.Find(o => o.Name == "菜单管理").Any())
            {
                this.RegiterToDb(PermissionType.Menu, "菜单管理");
            }
            this.BindingMenuToModule("开发人员模块");
            return Content(PermissionType.Menu.ToString());
        }

        /// <summary>
        /// 按钮管理菜单
        /// </summary>
        /// <returns></returns>        
        [UserAuthorize(Type = PermissionType.Menu)]
        public ActionResult ButtonManage()
        {
            if (!menService.Find(o => o.Name == "按钮管理").Any())
            {
                this.RegiterToDb(PermissionType.Menu, "按钮管理");
            }
            this.BindingMenuToModule("开发人员模块");
            return Content(PermissionType.Button.ToString());
        }

        /// <summary>
        /// 添加模块
        /// </summary>
        /// <param name="moduleName"></param>
        /// <returns></returns>  
        [UserAuthorize(Type=PermissionType.Button)]      
        public ActionResult AddModule()
        {
            

            if (Request["Name"]==null||Request["Url"]==null)
            {
                throw new CustomWarring("请求参数配置有误");
            }
            string moduleName = Request["Name"];
            string url = Request["Url"];

            if (string.IsNullOrEmpty(moduleName)) return Content("no:模块称不能为空");

            var module = new Module { Name = moduleName, Url = url, Type=PermissionType.Module.ToString() };

            
            try
            {
                modService.Add(module);                
            }
            catch (CustomWarring cw)
            {
                if (cw.Code == "UI") return Content("no:" + cw.Message);
                throw cw;
            }
            catch (Exception) { throw; }
            return Content("ok:添加加成功");
        }

        [UserAuthorize(Type=PermissionType.Button)]
        public ActionResult EditModule()
        {
            string controlName = Request["controlName"];
            string name = Request["moduleName"];
            string type = Request["type"];
            if (string.IsNullOrEmpty(controlName)||string.IsNullOrEmpty(name))
                throw new CustomWarring("名称或控制器地址不能为空", "UI", logger.LogLevel);
            try
            {
                var module = modService.GetForName(name);
                module.Name = name;
                module.Url = controlName;
                module.Type = type;
                modService.Update(module);
                modService.Commit();   
            }
            catch (CustomWarring cw)
            {
                if (cw.Code == "UI") return Content("no:" + cw.Message);
                throw cw;
            }
            //这部分错误日志应在基类和配置文件完成
            catch (Exception ex) { logger.Log("", ex); throw; }
            return Content("ok:修改成功");
        }

        /// <summary>
        /// 添加按钮
        /// </summary>
        /// <returns></returns>
        [UserAuthorize(Type=PermissionType.Button)]
        public ActionResult AddButton()
        {
            if (Request["Name"]==null
                || Request["Url"] == null
                || Request["MenuName"] == null)
            {
                throw new Exception("请求参数配置有误");
            }

            string name = Request["Name"];
            string url = Request["Url"];
            string menuName = Request["MenuName"];

            if (name == string.Empty || url == null) return Content("no:名称或地址不能为空");
             
            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(url)) return Content("no:名称或地址不能空");
            try
            {
                ButtonService btnService = new ButtonService();
                ActionButton btn = new ActionButton
                { Name = name, Url = url, RoleType = PermissionType.Button.ToString() };
                btnService.Add(btn);
                if (!string.IsNullOrEmpty(menuName)) btnService.SetToMenu(name, menuName);
            }
            catch (CustomWarring cw)
            {
                if (cw.Code == "UI") return Content("no:" + cw.Message);
                throw cw;
            }
            catch (Exception) { throw; }
            return Content("ok:添加加成功");
        }

        /// <summary>
        /// 修改按钮
        /// </summary>
        /// <returns></returns>
        public ActionResult EditBtn()
        {
            try
            {
                string json = Request["btnJson"];
                int n;int id;
                if (!int.TryParse(Request["btnId"], out n)) throw new Exception();
                id = n;
                ActionButton btn = JsonConvert.DeserializeObject<ActionButton>(Request["btnJson"]);
                if (string.IsNullOrEmpty(btn.Name)) return Content("no:名称不能为空");
                if (string.IsNullOrEmpty(btn.Url)) return Content("no:地址不能为空");
                var service = new ButtonService();
                var change = service.Find().Single(o => o.Id == id);
                if (service.Find(o => o.Name == btn.Name&&o.Name!=change.Name).Any()) return Content("no:数据库中已有该名称的按钮");
                if (service.Find(o => o.Url == btn.Url&&o.Url!=change.Url).Any()) return Content("数据库中已有该地址的按钮");
                change.Icon = btn.Icon;
                change.Name = btn.Name;
                change.RoleType = btn.RoleType;
                change.Url = btn.Url;
                service.Update(change);
                service.Commit();
            }
            catch (CustomWarring cw)
            {
                if (cw.Code == "UI") return Content("no:" + cw.Message);
                throw cw;
            }
            //这部分错误日志应在基类和配置文件完成
            catch (Exception ex) { logger.Log("",ex); throw; }
            return Content("ok:添加加成功");
        }

        /// <summary>
        /// 添加菜单
        /// </summary>
        /// <returns></returns>
        [UserAuthorize(Type = PermissionType.Button)]
        public ActionResult AddMenu()
        {
            if (Request["Name"] == null
                || Request["Url"] == null
                || Request["ModuleName"] == null)
            {
                throw new Exception("请求参数配置有误");
            }

            string name = Request["Name"];
            string url = Request["Url"];
            string moduleName = Request["ModuleName"];

            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(url)) return Content("no:名称或地址不能空");
            try
            {                
                Menu menu = new Menu { Name = name, Url = url,RoleType=PermissionType.Menu.ToString() };
                menService.Add(menu);
                if (!string.IsNullOrEmpty(moduleName)) menService.SetIntoModule(name, moduleName);
            }
            catch (CustomWarring cw)
            {
                if (cw.Code == "UI") return Content("no:" + cw.Message);
                throw cw;
            }
            catch (Exception) { throw; }
            return Content("ok:添加加成功");
        }

        [UserAuthorize(Type = PermissionType.Button)]
        public ActionResult AuthorizeAppManager()
        {
            string userid = Request["UserId"];
            if (userid == null) throw new Exception();
            try
            {
                int id = int.Parse(userid);
                var manager = new UserService().FindById(id);

                AuthorizeService<User>.InitiaRbac();

                AuthorizeService<User>.Authorize
                    (manager,modService.Find().Where(o => o.Name != "开发人员模块").AsEnumerable(), PermissionType.Module);

                
                AuthorizeService<User>.Authorize
                    (manager, menService.Find()
                    .Where(o => o.Name != "模块管理"
                    &&o.Name!= "菜单管理" && o.Name!= "按钮管理").AsEnumerable(), PermissionType.Menu);
                
                AuthorizeService<User>.Authorize
                    (manager, new ButtonService().Find().AsEnumerable(), PermissionType.Button);

                AuthorizeService<User>.Authorize
                    (manager, new UserService().Find()
                    .Where(o => o.IsSysAdmin ==false).AsEnumerable(), PermissionType.User);

                AuthorizeService<User>.Authorize
                    (manager, new DepartmentService().Find().AsEnumerable(), PermissionType.Group);

                AuthorizeService<User>.Authorize
                    (manager, new RoleService().Find().AsEnumerable(), PermissionType.Role);

                AuthorizeService<User>.Authorize
                    (manager, new EmpService().Find().AsEnumerable(), PermissionType.Data);
            }
            catch (CustomWarring cw)
            {
                if (cw.Code == "UI") return Content("no:" + cw.Message);
                throw cw;
            }
            catch (Exception) { throw; }
            return Content("ok:已成功添加网站管理员");
        }
    }
}
复制代码

复制代码
using Domain.DataModels;
using Domain.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using YZY.Domain;
using YZY_RBAC.Core;

namespace MVCDemo.Controllers
{
    [UserAuthorize(Type = PermissionType.Module)]
    public class RoleModuleController : BaseController
    {
        // GET: Role

        public ActionResult RoleManage()
        {
            try
            {
                if (!new MenuService().Find(o => o.Name == "角色管理").Any())
                {
                    this.RegiterToDb(PermissionType.Menu, "角色管理");
                    this.BindingMenuToModule("管理员操作模块");
                }
            }
            catch (CustomWarring cw)
            {
                if (cw.Code == "UI") return Content("no:" + cw.Message);
                throw cw;
            }
            return Content("ok:角色管理菜单添加成功");
        }

        /// <summary>
        /// 添加角色
        /// </summary>
        /// <param name="role"></param>
        /// <returns></returns>
        [UserAuthorize(Type=PermissionType.Button)]       
        public ActionResult AddRole()
        {
            string roleName = Request["Name"];
            string roleType = Request["Type"];
            Role role = new Role { RoleName = roleName, RoleType = roleType };
            try
            {                
                new RoleService().Add(role);
            }
            catch (CustomWarring cw)
            {
                if (cw.Code == "UI") return Content("no:" + cw.Message);
                throw cw;
            }
            return Content("ok:角色" + role.RoleName + "添加成功");
        }

        /// <summary>
        /// 为角色添加权限
        /// </summary>
        /// <returns></returns>
        [UserAuthorize(Type=PermissionType.Button)]
        public ActionResult AuthorizeForRole()
        {
            string roleName = Request["RoleName"];
            string type = Request["Type"];
            string targetName = Request["TargetName"];
            if (roleName == null || string.IsNullOrEmpty(roleName)) return Content("no:角色不能为空");

            try
            {
                Role role = new RoleService().GetForName(roleName);
                Helper.AuthorizeMenyForType(role, targetName, type);
            }
            catch (CustomWarring cw)
            {
                if (cw.Code == "UI") return Content("no:" + cw.Message);
                throw cw;
            }
            string successMsg = string.Format("ok:已成功为角色{0}添加{1}权限", roleName, targetName);
            return Content(successMsg);
        }

        /// <summary>
        /// 取消角色的权限
        /// </summary>
        /// <returns></returns>
        [UserAuthorize(Type = PermissionType.Button)]
        public ActionResult CancelAuthorize()
        {
            string roleName = Request["RoleName"];
            string type = Request["Type"];
            string targetName = Request["TargetName"];
            if (roleName == null || string.IsNullOrEmpty(roleName)) return Content("no:角色不能为空");

            try
            {
                Role role = new RoleService().GetForName(roleName);
                Helper.CancelAuthorizeMenyForType(role, targetName, type);
            }
            catch (CustomWarring cw)
            {
                if (cw.Code == "UI") return Content("no:" + cw.Message);
                throw cw;
            }
            string successMsg = string.Format("ok:已成功为角色{0}添加{1}权限", roleName, targetName);
            return Content(successMsg);
        }

        /// <summary>
        /// 为角色分配可管理的部门
        /// </summary>
        /// <returns></returns>
        [UserAuthorize(Type=PermissionType.Button)]
        public ActionResult AllotDepartment()
        {
            
            string roleName = Request["RoleName"];
            if (roleName == null || string.IsNullOrEmpty(roleName)) return Content("no:角色名称不能为空");
            if (Request["DepNames"]==null||Request["DepNames"]==string.Empty) return Content("no:目权限名称不能空");
            try
            {
                var depNames = Helper.GetNamesArray(Request["DepNames"]);
                var role = new RoleService().GetForName(roleName);
                var service = new Dep_RoleService();
                var depService = new DepartmentService();
                foreach (var name in depNames)
                {
                    var dep = depService.GetForName(name);
                    service.Add(new Dep_Role { RoleId = role.Id, DepId = dep.Id });
                }
                service.Commit();
            }

            catch (Exception)
            {
                return Content("no:添加失败");
                throw ;
            }
            string successMsg = "ok:角色已成功分配到部门" ;
            return Content(successMsg);
        }
    }
}
复制代码

复制代码
using Domain.DataModels;
using Domain.Service;
using MVCDemo.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using YZY.Domain;

namespace MVCDemo.Controllers
{
    public class HomeController :BaseController
    {
        // GET: Home
        
        public ActionResult Index()
        {
            //测试插入一个用户
            if (!new UserService().Find(o => o.Name == "test").Any())
            {
                new UserService().Add(new User
                {
                    Name = "test",
                    Account = "test",
                    Password = "123",
                    Telphone = "15011111111"
                });
            }
            ViewBag.IsAdmin = false;

            ViewBag.PerTypes = Helper.GetUITypes();

            if (LoginUser != null)
            {
                ViewBag.UserName = LoginUser.Name;
                ViewBag.IsAdmin = LoginUser.IsSysAdmin;
            }
            
            else { ViewBag.UserName = "游客"; }
            LoginUserResouces lr = new LoginUserResouces();
            lr = Resouces;
            return View(lr);
        }
        public ActionResult LogOut()
        {
            if (Cache.GetCache("LastUrl") == null) Cache.AddCache("LastUrl", "Home/Index");
            Cache.DelCache("LastUrl"); Cache.AddCache("LastUrl", "Home/Index");
            return new EmptyResult();
        }
    }
}
复制代码

 

MVC部分:视图

复制代码
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <link href="~/Content/bootstrap.min.css" rel="stylesheet" />

    <script src="~/scripts/jquery-1.9.1.min.js"></script>
    <script src="~/scripts/bootstrap.min.js"></script>
    <title>登陆</title>
    <style type="text/css">
        body{
            background-color:#2F4051;
        }
        .login-holder {
            -webkit-border-radius: 6px;
            -moz-border-radius: 6px;
            -ms-border-radius: 6px;
            -o-border-radius: 6px;
            border-radius: 6px;
            position: absolute;
            top: 50%;
            left: 50%;
            display: block;
            margin-top: -185px;
            margin-left: -205px;
            width: 420px;
            height: auto;
            background: white;
            padding: 10px;
        }
        .login-holder .form-footer {
            padding: 20px;
        }

    </style>
    <script type="text/javascript">
        $(function () {
            $("#btn").click(function () {
                $.post("/Login/Account",
                    {
                        "Account": $("#Account").val(),
                        "Password": $("#Password").val(),
                        "Rember": $("#Rember").is(":checked")
                    },
                    function (data) {
                        var yn = data.split(':');
                        if (yn[0] == "ok") {
                            window.location.href = yn[1];
                        }
                        else {
                            alert(yn[1]);
                        }
                })
            });
        });
    </script>
</head>

<body>
    <div>
        <div class="login-holder col-md-6 col-md-offset-3">
            <h2 class="page-header text-center text-primary"> 欢迎!请登陆 </h2>
            <form role="form" method="post">
                <div class="form-group">
                    <input class="form-control" id="Account" type="text" placeholder="输入帐号">
                </div>
                <div class="form-group">
                    <input class="form-control" id="Password" type="password" placeholder="输入密码">
                </div>
                <div class="form-footer">
                    <label>
                        <input id="Rember" type="checkbox" value="0"> 一个月免登陆
                    </label><br />
                    <button class="btn btn-info btn-submit" id="btn" type="button">登陆</button>
                </div>

            </form>
        </div>
    </div>
</body>
</html>
复制代码

现在只做出来两个视图,完成前面展示效果,Home视图抠的一个模板,所以有很多的JS和CSS文件,自己尝试写过,太痛苦了,所以干脆全扒下来算了,时间都浪费在上面划不来

复制代码
@{
    Layout = null;
}
@model MVCDemo.Models.LoginUserResouces
<!DOCTYPE html>

<html>
<head>
    <meta charset="utf-8">
    <title>首页</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <!-- Loading Bootstrap -->
    <link href="~/aaaa/css/bootstrap.min.css" rel="stylesheet" />

    <!-- Loading Stylesheets -->
    <link href="~/aaaa/css/font-awesome.css" rel="stylesheet">
    <link href="~/aaaa/css/style.css" rel="stylesheet" type="text/css">

    <link href="~/aaaa/less/style.less" rel="stylesheet" title="lessCss" id="lessCss">

    <!-- Loading Custom Stylesheets -->
    <link href="~/aaaa/css/custom.css" rel="stylesheet">

    <link rel="shortcut icon" href="~/aaaa/images/favicon.ico">
    <!-- Load JS here for Faster site load =============================-->
    <script src="~/aaaa/js/jquery-1.10.2.min.js"></script>
    <script src="~/aaaa/js/jquery-ui-1.10.3.custom.min.js"></script>
    <script src="~/aaaa/js/less-1.5.0.min.js"></script>
    <script src="~/aaaa/js/jquery.ui.touch-punch.min.js"></script>
    <script src="~/aaaa/js/bootstrap.min.js"></script>
    <script src="~/aaaa/js/bootstrap-select.js"></script>
    <script src="~/aaaa/js/bootstrap-switch.js"></script>
    <script src="~/aaaa/js/jquery.tagsinput.js"></script>
    <script src="~/aaaa/js/jquery.placeholder.js"></script>
    <script src="~/aaaa/js/bootstrap-typeahead.js"></script>
    <script src="~/aaaa/js/application.js"></script>
    <script src="~/aaaa/js/moment.min.js"></script>
    <script src="~/aaaa/js/jquery.dataTables.min.js"></script>
    <script src="~/aaaa/js/jquery.sortable.js"></script>
    <script src="~/aaaa/js/jquery.gritter.js" type="text/javascript"></script>
    <script src="~/aaaa/js/jquery.nicescroll.min.js"></script>
    <script src="~/aaaa/js/skylo.js"></script>
    <script src="~/aaaa/js/prettify.min.js"></script>
    <script src="~/aaaa/js/jquery.noty.js"></script>
    <script src="~/aaaa/js/bic_calendar.js"></script>
    <script src="~/aaaa/js/jquery.accordion.js"></script>
    <script src="~/aaaa/js/theme-options.js"></script>

    <script src="~/aaaa/js/bootstrap-progressbar.js"></script>
    <script src="~/aaaa/js/bootstrap-progressbar-custom.js"></script>
    <script src="~/aaaa/js/bootstrap-colorpicker.min.js"></script>
    <script src="~/aaaa/js/bootstrap-colorpicker-custom.js"></script>


    <!-- Core JS =============================-->
    <script src="~/aaaa/js/core.js"></script>
    <style type="text/css">
        .yuandian{
            margin-right:20px;
        }
    </style>
    <script type="text/javascript">
        
        $(function () {           
            

            //设置全局初始变量
            var selectMenu = $("#menulist").children("li").eq(0).find("span[class='hidden']")
            var leftMenuName = $(selectMenu).attr("menuname");
            var leftMenuUrl = $(selectMenu).attr("url");
            var leftMenuId = $(selectMenu).attr("menuid");
            var btns = $('#actionbtnlist').children("a");
            
            //对非开发人员隐藏按钮
            function hiddenBtn(){
                if (leftMenuName == "按钮管理") {
                    if ($("#authorize").hasClass("hidden")) {
                        $("#authorize").removeClass("hidden")
                    }
                    if ($("#add").hasClass("hidden")) {
                        $("#add").removeClass("hidden")
                    }
                }
                else if (leftMenuName == "模块管理") {
                    if ($("#authorize").hasClass("hidden")) {
                        $("#authorize").removeClass("hidden")
                    }
                    if ($("#add").hasClass("hidden")) {
                        $("#add").removeClass("hidden")
                    }
                }
                else  if (leftMenuName == "菜单管理") {
                    if ($("#authorize").hasClass("hidden")) {
                        $("#authorize").removeClass("hidden")
                    }
                    if ($("#add").hasClass("hidden")) {
                        $("#add").removeClass("hidden")
                    }
              }
                else {
                    $("#authorize").addClass("hidden")
                    $("#add").addClass("hidden")
                }
            }
            hiddenBtn()

            //清除模态框
            function clear() {
                $('#addModal').find("input").addClass("hidden").attr("placeholder", "")
                $('#addModal').find("input").val('')
                $('#addModal').find('textarea').val('')
                $("#modalTitle").html("");
            }
            clear();

            //界面转换
            function change() {
                clear()
                //菜单界面
                var menu = document.getElementById(leftMenuUrl);
                $("#head").find("span[class='menu-title']").html(leftMenuName);
                if ($(menu).hasClass("hidden")) {
                    $(menu).removeClass("hidden");
                    $(menu).siblings().addClass("hidden");
                }
                //按钮界面
                $(btns).each(function () {
                    if ($(this).attr("menuid") == leftMenuId) {
                        if ($(this).hasClass('hidden')) {
                            $(this).removeClass("hidden")                            
                        }                        
                    }
                    else {
                        if ($(this).not(":hidden")) {
                            $(this).addClass('hidden')
                        }
                    }
                })
            }
            change()

            //模态框设置
            $('.modal').on('show.bs.modal', function () {
                $(".modal").css("display", "blocl").css("margin-top", -350);
            })
            $('.modal').on('hidden.bs.modal', clear())

            //重新登陆
            $("#Logout").click(function () {
                $.post("/Home/LogOut", {}, function () {
                    window.location.href = "/Login/Index";
                })
            })

            //菜单点击界面响应
            $(".menu").click(function () {
                leftMenuId=$(this).children("span[class='hidden']").attr("menuid")
                leftMenuUrl = $(this).children("span[class='hidden']").attr("url")
                leftMenuName = $(this).children("span[class='hidden']").attr("menuname")
                change()
                hiddenBtn()
            })

            //添加按钮点击事件
            $("#add").click(function () {
                clear()
                var modalele = $('#addModal')
                var name = $(modalele).find("input[id='name']")
                var url = $(modalele).find("input[id='url']")
                var account = $(modalele).find("input[id='account']")
                var password = $(modalele).find("input[id='password']")
                var telphone = $(modalele).find("input[id='telphone']")
                var targetname = $(modalele).find("input[id='targetname']")

                if (leftMenuName == "模块管理") {
                    addModule(name, url, modalele)
                }
                else if (leftMenuName == "菜单管理") {
                    addMenu(name, url, targetname, modalele)                    
                }
                else if (leftMenuName == "按钮管理") {
                    addBtn(name, url, targetname, modalele)                    
                }
                $(modalele).find("attr[data-dismiss='modal']").click(clear)
            })
            //添加模块
            function addModule(name, url,modalele) {

                $("#modalTitle").html("添加模块");

                name.removeClass("hidden").attr("placeholder", "输入要添加的模块名称");
                
                url.removeClass("hidden").attr("placeholder", "输入要添加的模块控制器地址");
                
                $(modalele).modal("show");
                
                var submit = $(modalele).find("button[id='modalSubmit']")

                $(submit).click(function () {

                    $.post("/admin/addmodule",
                        {
                            "Name": name.val(),
                            "Url":url.val()
                        },
                        function (data) {
                            var datas = data.split(':');
                            if (datas[0] == "ok") {
                                window.location.reload();
                                
                            }
                            else
                            {
                                alert(datas[1])
                                clear()
                            }
                        })

                })
            }
            //添加菜单
            function addMenu(name, url, modulename,modalele) {

                $("#modalTitle").html("添加菜单");

                name.removeClass("hidden").attr("placeholder", "输入要添加的菜单名称");

                url.removeClass("hidden").attr("placeholder", "输入要添加的菜单地址");

                modulename.removeClass("hidden").attr("placeholder", "输入要添加到的模块名称")

                modalele.modal("show");

                var submit = $(modalele).find("button[id='modalSubmit']")

                $(submit).click(function () {

                    $.post("/admin/addmenu",
                        {
                            "Name": name.val(),
                            "Url": url.val(),
                            "ModuleName": modulename.val()
                        },
                        function (data) {
                            var datas = data.split(':');
                            if (datas[0] == "ok") {
                                window.location.reload();
                                clear()
                            }
                            else {
                                alert(datas[1])
                            }
                        })
                })
            }
            //添加按钮
            function addBtn(name, url, menuname, modalele) {

                $("#modalTitle").html("添加按钮");

                name.removeClass("hidden").attr("placeholder", "输入要添加的按钮名称")

                url.removeClass("hidden").attr("placeholder", "输入按钮访问地址")

                menuname.removeClass("hidden").attr("placeholder", "输入要添加到的菜单名称")

                modalele.modal("show");

                var submit = $(modalele).find("button[id='modalSubmit']")

                $(submit).click(function () {

                    $.post("/admin/addbutton",
                        {
                            "Name": name.val(),
                            "Url": url.val(),
                            "MenuName": menuname.val()
                        },
                        function (data) {
                            var datas = data.split(':');
                            if (datas[0] == "ok") {
                                window.location.reload();
                                clear()
                            }
                            else {
                                alert(datas[1])
                            }
                        })
                })
            }

            //查看,修改模态框
            $("#ManageEditModal").on('show.bs.modal', function (event) {
                var button = $(event.relatedTarget)
                var name = button.data('name')
                var url = button.data('url')
                var type = button.data('type')
                var action = button.data('action')
                var btnId = button.data('btnid')

                if (action == "btnEdit") {
                    
                    $(this).find('.modal-title').text('编辑' + name+'按钮')
                    $(this).find('input').attr("readonly", null)
                    $(this).find("input[id='name']").val(name)
                    $(this).find("input[id='url']").val(url)
                    $(this).find("textarea[id='type']").val(type).attr("readonly",null)
                    $(this).find('button[id="editSubmit"]').removeClass("hidden")
                        .click(function () {

                        name = $('#ManageEditModal').find("input[id='name']").val()
                        url = $('#ManageEditModal').find("input[id='url']").val()
                        type = $('#ManageEditModal').find("textarea[id='type']").val()

                        $.post("/admin/editbtn",
                            {
                                "btnJson": '{"Name":"' + name + '","Url":"'
                                    + url + '","RoleType":"' +
                                    type + '"}',
                                "btnId":btnId

                            },
                            function (data) {
                                var input = data.split(':');
                                if (input[0] == "ok") {
                                    $('#ManageEditModal').on("hidden")
                                    window.location.reload()
                                    
                                }
                                else if(input[0]=="no") {
                                    alert(input[1])
                                }
                            })
                    })
                }

                if (action == "btnLook") {
                    $(this).find('.modal-title').text('查看' + name + '按钮')
                    $(this).find('input').attr("readonly","")
                    $(this).find("input[id='name']").val(name)
                    $(this).find("input[id='url']").val(url)
                    $(this).find("textarea[id='type']").val(type).attr("readonly","")
                    $(this).find('button[id="editSubmit"]').addClass("hidden")
                }
            })

            var authorUser = $("#admin-authouser-tbody").children('tr').children('td').children('div').children('a')
            authorUser.click(function () {
                $.post("/admin/AuthorizeAppManager", {
                    "UserId":$(this).attr("userid")
                },
                function (data) {
                    var query = data.split(':')
                    alert(query[1])
                    window.location.reload(query[0] == "ok")
                })
            })

            //按钮集合点击事件
            $(btns).click(function () {

                if ($(this).text().indexOf('添加角色') > 0) {
                    //找出模态框
                    var modalele = $('#addModal')
                    //找出需要的控件
                    var name = $(modalele).find("input[id='name']")
                    var roletype = $(modalele).find("input[id='url']")
                    //显示模态框和相关控件  
                    $("#modalTitle").html("添加按钮");
                    name.removeClass("hidden").attr("placeholder", "输入要添加的角色名称")
                    roletype.removeClass("hidden").attr("placeholder", "输入角色的类型")
                    modalele.modal("show");
                    //设置访问地址
                    var url = "/" + $(this).attr("url")
                    var submit = $(modalele).find("button[id='modalSubmit']")
                    $(submit).click(function () {
                        $.post(url,
                            {
                                "Name": $(name).val(),
                                "Type": $(roletype).val()
                            },
                            function (data) {
                                var serverdatas = data.split(':')
                                alert(serverdatas[1])
                                $(modalele).on('hidden')
                                
                                if (serverdatas[0] == "ok") {
                                    window.location.reload()
                                }
                            })
                    })
                }
                    
            })
        })
    </script>

</head>
<body>  
    
    
    <div class="site-holder">

        <!--横向导航 -->
        <nav class="navbar" role="navigation">

            <!-- Logo -->
            <div class="navbar-header">
                <a class="navbar-brand" >
                    <i class="fa fa-list btn-nav-toggle-responsive text-white"></i>
                    <span class="logo">
                        RBAC<strong>Test</strong>Demo <i class="fa fa-bookmark"></i>
                    </span>
                </a>
            </div>

            <!-- 右侧图标 -->
            <div class="collapse navbar-collapse">
                <ul class="nav navbar-nav user-menu navbar-right ">
                    <!--用户图标-->
                    <li>
                        <a href="#" class="settings dropdown-toggle" data-toggle="dropdown">
                            <i class="fa fa-user"></i>
                        </a>
                        <ul class="dropdown-menu">
                            <li><a><i class="fa fa-user"></i> @ViewBag.UserName</a></li>

                            <li class="divider"></li>
                            <li><a id="Logout" class="text-danger"><i class="fa fa-lock"></i>重新登陆</a></li>
                        </ul>
                    </li>

                    <!--样式颜色设置开关-->
                    <li>
                        <a href="#" class="settings">
                            <i class="fa fa-cogs settings-toggle"></i><span class="badge bg-info">20</span>
                        </a>
                    </li>
                </ul>
            </div>
        </nav>

        <!--主体部分 -->
        <div class="box-holder">

            <!-- 左侧竖向导航 -->
            <div class="left-sidebar">
                <div class="sidebar-holder">
                    <ul class="nav  nav-list">

                        <!-- 左侧导航开头 -->
                        <li class="nav-toggle">
                            <button class="btn  btn-nav-toggle text-primary"><i class="fa fa-angle-double-left toggle-left"></i> </button>
                        </li>

                        <!--模块-->
                        @foreach (var item in Model.Modules)
                        {
                            <li>
                                <a class="dropdown" data-original-title=@item.Name>
                                    <i class="fa fa-paperclip"></i>
                                    <span class="hidden-minibar"><strong> @item.Name</strong> </span>
                                </a>
                                @if (Model.Menus.Where(o => o.ModuleId == item.Id).Any())
                                {
                                    <ul id="menulist">
                                        <!--菜单-->
                                        @foreach (var menu in Model.Menus.Where(o => o.ModuleId == item.Id))
                                        {
                                            if (menu.ModuleId == item.Id)
                                            {
                                                <li class="menu">
                                                    <a data-original-title=@menu.Name>
                                                        <i class="fa fa-pencil"></i>
                                                        <span class="hidden-minibar"> @menu.Name</span>
                                                    </a>
                                                    <span menuname="@menu.Name" url="@menu.Url" menuid="@menu.Id"class="hidden" ></span>
                                                    
                                                </li>
                                            }
                                        }
                                    </ul>
                                }

                            </li>
                        }

                    </ul>
                </div>
            </div>

            <!-- 开发者或管理员界面 -->
            <div class="content" id="managerView">

                <div class="row">
                    <div class="col-mod-12">
                        <!--面包屑导航-->
                        @*<ul class="breadcrumb">
                                <li><a >Dashboard</a></li>
                                <li><a >Tables</a></li>
                                <li class="active">Dynamic Tables</li>
                            </ul>*@

                        <!--搜索框-->
                        @*<div class="form-group hiddn-minibar pull-right">
                                <input type="text" class="form-control form-cascade-control nav-input-search"
                                       size="20" placeholder="Search through site" />
                                <span class="input-icon fui-search"></span>
                            </div>*@

                        <!--标题-->
                        <h3 id="head" class="page-header">
                            <span class="menu-title"></span>
                            <i class="fa fa-info-circle animated bounceInDown show-info"></i>
                        </h3>

                        <!--横块-->
                        <blockquote class="page-information hidden ">
                            <p>

                            </p>
                        </blockquote>
                    </div>
                </div>

                <div  class="row inbox">

                    <!--操作集合-->                                        
                    <div id="manageActionContaner" class="col-md-2 mail-left-box">                       

                        <div class="panel panel-cascade">
                            <div class="panel-heading ">
                                <h3 class="text-primary panel-title">
                                    <i class="fa fa-align-justify"></i> 操作按钮
                                    <span class="pull-right">
                                        <a class="panel-minimize"><i class="fa fa-chevron-up"></i></a>
                                    </span>
                                </h3>
                            </div>
                            <div class="panel-body buttons-demo">
                                <div class="row">
                                    <div id="actionbtnlist" class="col-md-12">                                       
                                        @{ 
                                            var colors = new List<string>
                                            {
                                                "btn btn-success btn-block",
                                                "btn btn-info btn-block",
                                                "btn btn-warning btn-block"
                                            };
                                            int n = 0;
                                        }


                                        @foreach (var item in Model.Buttons)
                                        {
                                            
                                            if (n > 2) { n = 0; }
                                            var color = colors[n];
                                            <a class="@color hidden" url="@item.Url" menuid="@item.MenuId"> @item.Name</a>
                                                                                    
                                            n++;
                                        }
                                        <br />

                                           
                                        
                                        
                                    </div>
                                </div> <!-- Large Buttons -->
                            </div>
                        </div>                        

                       <div class="panel panel-cascade">
                            <div class="panel-heading ">
                                <h3 class="panel-title text-primary">
                                    <i class="fa fa-align-justify"></i> 其他数据
                                    <span class="pull-right">
                                        <a class="panel-minimize"><i class="fa fa-chevron-up"></i></a>
                                    </span>
                                </h3>
                            </div>

                            <div class="panel-body list-group inbox-options">
                                <a class="list-group-item"><i class="fa fa-inbox"></i> 其他数据  </a>
                                <a class="list-group-item"><i class="fa fa-bolt"></i> 其他数据  </a>
                                <a class="list-group-item"><i class="fa fa-magic"></i> 其他数据  </a>
                                <a class="list-group-item"><i class="fa fa-bookmark-o"></i> 其他数据  </a>
                                <a class="list-group-item"><i class="fa fa-check-square-o"></i> 其他数据 </a>
                                <a class="list-group-item"><i class="fa fa-ban"></i> 其他数据  </a>
                                <a class="list-group-item"><i class="fa fa-trash-o"></i> 其他数据  </a>
                                <a class="list-group-item"><i class="fa fa-archive"></i> 其他数据  </a>
                            </div>
                        </div>
                        
                    </div>

                    <!--菜单对应视图数据-->
                    <div id="manageMenuContainer"  class="col-md-10 mail-right-box">
                        <!--头部-->
                        <div class="mail-options-nav">

                            <div class="mail-pagination btn-group yuandian">
                                <h4 class="text-primary">
                                    <i class="fa fa-align-justify"></i> 列表展示
                                </h4>
                            </div>
                            
                            <div class="btn-group mail-options popover-options">

                                <a id="add" class="btn btn-success"><i class="fa fa-archive"></i> 添加</a>
                                
                                <a id="authorize" class="btn btn-warning" >
                                    <i class="fa fa-ban"></i>
                                    删除
                                </a>    
                                
                            </div>

                            <div class="mail-pagination pull-right ">
                                <label class="label text-primary">1-60 of 500</label>
                                <a class="btn btn-default"><i class="fa fa-angle-double-left"></i></a>
                                <a class="btn btn-default"><i class="fa fa-angle-double-right"></i></a>
                                <a class="btn btn-info"><i class="fa fa-cogs"></i></a>
                            </div>
                        </div>

                        <div class="mails">

                            <!----------------- 模块管理------------->
                            <div id="admin/modulemanage" class="hidden">
                                <table class="table table-bordered table-hover table-striped display">
                                    <thead>
                                        <tr>
                                            <th class="text-center">
                                                <input type="checkbox" />
                                            </th>
                                            <th class="text-center">模块名称</th>
                                            <th class="text-center">地址</th>
                                            <th class="text-center">操作</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        @foreach (var item in Model.Modules)
                                        {
                                            var edit = "edit-" + item.Id;
                                            var del = "del-" + item.Id;
                                            var see = "see-" + item.Id;
                                            <tr class="odd gradeX">
                                                <td class="text-center">
                                                    <input type="checkbox" />
                                                </td>
                                                <td class="text-center "> @item.Name</td>
                                                <td class="text-center "> @item.Url </td>
                                                <td class="text-center ">
                                                    <div class="btn-group mail-options">
                                                        <a id="@edit" class="btn btn-success btn-sm">
                                                            <i class="fa fa-edit"></i> 编辑
                                                        </a>
                                                        <a id="@see" class="btn btn-warning btn-sm">
                                                            <i class="fa fa-trash-o"></i> 查看
                                                        </a>                                                        
                                                    </div>
                                                </td>
                                            </tr>
                                        }

                                    </tbody>

                                </table>
                            </div>

                            <!------------------菜单管理------------>
                            <div id="admin/menumanage" class="hidden">
                                <table class="table table-bordered table-hover table-striped display">
                                    <thead>
                                        <tr>
                                            <th class="text-center">
                                                <input type="checkbox" />
                                            </th>
                                            <th class="text-center">名称</th>
                                            <th class="text-center">地址</th>
                                            <th class="text-center">操作</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        @foreach (var item in Model.Menus)
                                        {
                                            var edit = "edit-" + item.Id;
                                            var del = "del-" + item.Id;
                                            var see = "see-" + item.Id;
                                            <tr class="odd gradeX">
                                                <td class="text-center">
                                                    <input type="checkbox" />
                                                </td>
                                                <td class="text-center "> @item.Name</td>
                                                <td class="text-center "> @item.Url </td>
                                                <td class="text-center ">
                                                    <div class="btn-group mail-options">
                                                        
                                                        <a id="@see" class="btn btn-warning btn-sm">
                                                            <i class="fa fa-trash-o"></i> 查看
                                                        </a>
                                                    </div>
                                                </td>
                                            </tr>
                                        }
                                    </tbody>

                                </table>
                            </div>

                            <!-------------------按钮管理------------>
                            <div id="admin/buttonmanage" class="hidden">
                                <table id="btnManageTable" class="table table-bordered table-hover table-striped display">
                                    <thead>
                                        <tr>
                                            <th class="text-center">
                                                <input type="checkbox" />
                                            </th>
                                            <th class="text-center">名称</th>
                                            <th class="text-center">地址</th>
                                            <th class="text-center">操作</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        @foreach (var item in Model.Buttons)
                                        {
                                            <tr class="odd gradeX">
                                                <td class="text-center">
                                                    <input type="checkbox" />
                                                </td>
                                                <td class="text-center "> @item.Name</td>
                                                <td class="text-center "> @item.Url </td>
                                                <td class="text-center ">
                                                    <div class="btn-group mail-options">
                                                        <a class="btn btn-success btn-sm"
                                                           data-toggle="modal"
                                                           data-target="#ManageEditModal"
                                                           data-name="@item.Name"
                                                           data-url="@item.Url"
                                                           data-type="@item.RoleType"
                                                           data-action="btnEdit"
                                                           data-btnid="@item.Id">

                                                            <i class="fa fa-edit"></i> 编辑
                                                        </a>
                                                        <a class="btn btn-warning btn-sm"
                                                           data-toggle="modal"
                                                           data-target="#ManageEditModal"
                                                           data-name="@item.Name"
                                                           data-url="@item.Url"
                                                           data-type="@item.RoleType"
                                                           data-action="btnLook"
                                                           data-btnid="@item.Id">
                                                            <i class="fa fa-trash-o"></i> 查看
                                                        </a>                                                        
                                                    </div>
                                                </td>
                                            </tr>
                                        }


                                    </tbody>

                                </table>
                            </div>

                            <!-------------------开发人员授权管理------------>
                            <div id="admin/menu" class="hidden">
                                <table id="admin-authouser-table" class="table table-bordered table-hover table-striped display">
                                    <thead>
                                        <tr>
                                            <th class="text-center">
                                                <input type="checkbox" />
                                            </th>
                                            <th class="text-center">用户名称</th>
                                            <th class="text-center">帐号</th>
                                            <th class="text-center">电话</th>
                                        </tr>
                                    </thead>
                                    <tbody id="admin-authouser-tbody">
                                        @foreach (var item in Model.Users)
                                        {
                                            if (!item.IsSysAdmin)
                                            {
                                                <tr class="odd gradeX">
                                                    <td class="text-center">
                                                        <input type="checkbox" />
                                                    </td>
                                                    <td class="text-center "> @item.Name</td>
                                                    <td class="text-center "> @item.Account </td>
                                                    <td class="text-center"> @item.Telphone</td>
                                                    <td class="text-center ">
                                                        <div class="btn-group mail-options">
                                                            <a userid="@item.Id" class="btn btn-success btn-sm">
                                                                <i class="fa fa-edit"></i> 授权为网站管理员
                                                            </a>

                                                        </div>
                                                    </td>
                                                </tr>
                                            }
                                        }

                                    </tbody>

                                </table>
                            </div>

                            <!-------------------角色管理------------>
                            <div id="rolemodule/rolemanage" class="hidden">
                                <table class="table table-bordered table-hover table-striped display">
                                    <thead>
                                        <tr>
                                            <th class="text-center">
                                                <input type="checkbox" />
                                            </th>
                                            <th class="text-center">角色名称</th>
                                            <th class="text-center">角色类型</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        @foreach (var item in Model.Roles)
                                        {
                                            var edit = "edit-" + item.Id;
                                            var del = "del-" + item.Id;
                                            var see = "see-" + item.Id;
                                            <tr class="odd gradeX">
                                                <td class="text-center">
                                                    <input type="checkbox" />
                                                </td>
                                                <td class="text-center "> @item.RoleName</td>
                                                <td class="text-center "> @item.RoleType </td>                                                
                                            </tr>
                                        }


                                    </tbody>

                                </table>
                            </div>

                        </div>
                    </div>   
                                     
                </div>

                <!-----------------------------模态框----------------------------------------------->

                <!--添加框-->
                <div class="modal fade" id="addModal" tabindex="-1"
                     role="dialog" aria-labelledby="addModuleModalLabel" aria-hidden="true">
                    <div class="modal-dialog">
                        <div class="modal-content">
                            <div class="modal-header bg-primary text-white">
                                <button type="button" class="close text-white"
                                        data-dismiss="modal" aria-hidden="true">
                                    &times;
                                </button>
                                <h3 id="modalTitle" class="modal-title">Subject</h3>
                            </div>
                            <div class="modal-body">
                                <div class="icon-show">
                                    <form id="addForm" role="form">
                                        <div class="form-group">
                                            <input class="form-control" id="name" type="text" placeholder="">
                                        </div>
                                        <div class="form-group">
                                            <input class="form-control" id="url" type="text" placeholder="">
                                        </div>
                                        <div class="form-group">
                                            <input class="form-control" id="account" type="text" placeholder="">
                                        </div>
                                        <div class="form-group">
                                            <input class="form-control" id="password" type="password" placeholder="">
                                        </div>
                                        <div class="form-group">
                                            <input class="form-control" id="telphone" type="text" placeholder="">
                                        </div>
                                        <div class="form-group">
                                            <input class="form-control" id="targetname" type="text" placeholder="">
                                        </div>
                                    </form>
                                </div>
                            </div>
                            <div class="modal-footer">
                                <button id="close" data-dismiss="modal" type="button" class="btn bg-primary text-white">退出</button>
                                <button id="modalSubmit" type="button" class="btn bg-primary text-white">提交</button>
                            </div>
                        </div>
                    </div>
                </div>

                <!--修改框-->
                <div class="modal fade" id="ManageEditModal" tabindex="-1"
                     role="dialog" aria-labelledby="ManageEditModalLabel" aria-hidden="true">
                    <div class="modal-dialog">
                        <div class="modal-content">
                            <div class="modal-header bg-primary text-white">
                                <button type="button" class="close text-white"
                                        data-dismiss="modal" aria-hidden="true">
                                    &times;
                                </button>
                                <h3 id="modalTitle" class="modal-title">编辑</h3>
                            </div>
                            <div class="modal-body">
                                <div class="icon-show">
                                    <form id="ManageEditForm" role="form" class="form-horizontal">
                                        
                                        <div class="form-group">
                                                <label id="labelName" for="name" class="control-label col-md-2">按钮名称</label>                                            
                                            <div class="col-md-10">
                                                <input class="form-control" id="name" type="text" placeholder="">
                                            </div>
                                        </div>
                                        <div class="form-group">
                                            <label id="labelUrl" for="url" class="control-label col-md-2">地址</label>
                                            <div class="col-md-10">
                                                <input class="form-control" id="url" type="text" placeholder="">
                                            </div>
                                        </div>
                                        <div class="form-group">
                                            <label id="labelType" for="type" class="control-label col-md-2">属性</label>
                                            <div class="col-md-10">
                                                <textarea rows="3" class="form-control" id="type" type="text" ></textarea>                                                   
                                            </div>
                                        </div>
                                    </form>
                                </div>
                            </div>
                            <div class="modal-footer">
                                <button id="close" data-dismiss="modal" type="button" class="btn bg-primary text-white">退出</button>
                                <button id="editSubmit" type="button" class="btn bg-primary text-white">提交修改</button>
                            </div>
                        </div>
                    </div>
                </div>

                
            </div>

            <!--用户界面-->
            <div id="userView" class="content hidden">

            </div>
            
            <!-- 右侧页面编辑模块 -->
            <div class="right-sidebar right-sidebar-hidden">
                <div class="right-sidebar-holder">
                    <h4 class="page-header text-primary text-center">
                        页面样式颜色选项
                    </h4>

                    <ul class="list-group theme-options">

                        <!---样式-->
                        <li class="list-group-item" href="#">

                            <div class="checkbox">
                                <label>
                                    <input type="checkbox" id="fixedNavbar" value=""> 顶部导航栏
                                </label>
                            </div>
                            <div class="checkbox">
                                <label>
                                    <input type="checkbox" id="fixedNavbarBottom" value=""> 底部导航栏
                                </label>
                            </div>
                            <div class="checkbox">
                                <label>
                                    <input type="checkbox" id="boxed" value=""> 缩小居中
                                </label>
                            </div>

                            <div class="form-group backgroundImage hidden">
                                <label class="control-label">Paste Image Url and then hit enter</label>
                                <input type="text" class="form-control" id="backgroundImageUrl" />
                            </div>

                        </li>

                        <!--颜色-->
                        <li class="list-group-item" href="#">
                            颜色搭配选项
                            <ul class="list-inline predefined-themes">
                                <li><a class="badge" style="background-color:#54b5df" data-color-primary="#54b5df" data-color-secondary="#2f4051" data-color-link="#FFFFFF"> &nbsp; </a></li>
                                <li><a class="badge" style="background-color:#d85f5c" data-color-primary="#d85f5c" data-color-secondary="#f0f0f0" data-color-link="#474747"> &nbsp; </a></li>
                                <li><a class="badge" style="background-color:#3d4a5d" data-color-primary="#3d4a5d" data-color-secondary="#edf0f1" data-color-link="#777e88"> &nbsp; </a></li>
                                <li><a class="badge" style="background-color:#A0B448" data-color-primary="#A0B448" data-color-secondary="#485257" data-color-link="#AFB5AA"> &nbsp; </a></li>
                                <li><a class="badge" style="background-color:#2FA2D1" data-color-primary="#2FA2D1" data-color-secondary="#484D51" data-color-link="#A5B1B7"> &nbsp; </a></li>
                                <li><a class="badge" style="background-color:#2f343b" data-color-primary="#2f343b" data-color-secondary="#525a65" data-color-link="#FFFFFF"> &nbsp; </a></li>
                            </ul>
                        </li>
                        <li class="list-group-item">
                            主体颜色
                            <div class="input-group colorpicker-component bscp" data-color="#54728c" data-color-format="hex" id="colr">
                                <span class="input-group-addon"><i style="background-color: #54728c"></i></span>
                                <input type="text" value="#54728c" id="primaryColor" readonly class="form-control" />

                            </div>
                        </li>
                        <li class="list-group-item" href="#">
                            左侧导航背景颜色
                            <div class="input-group colorpicker-component bscp" data-color="#f9f9f9" data-color-format="hex" id="Scolr">
                                <span class="input-group-addon"><i style="background-color: #f9f9f9"></i></span>
                                <input type="text" value="#f9f9f9" id="secondaryColor" readonly class="form-control" />

                            </div>
                        </li>
                        <li class="list-group-item" href="#">
                            左侧导航字体颜色
                            <div class="input-group colorpicker-component bscp" data-color="#54728c" data-color-format="hex" id="Lcolr">
                                <span class="input-group-addon"><i style="background-color: #54728c"></i></span>
                                <input type="text" value="#54728c" id="linkColor" readonly class="form-control" />

                            </div>
                        </li>
                        <li class="list-group-item" href="#">
                            右侧导航背景色
                            <div class="input-group colorpicker-component bscp" data-color="#f9f9f9" data-color-format="hex" id="Rcolr">
                                <span class="input-group-addon"><i style="background-color: #f9f9f9"></i></span>
                                <input type="text" value="#f9f9f9" id="rightsidebarColor" readonly class="form-control" />

                            </div>
                        </li>
                    </ul>


                </div>


            </div>            

        </div>
    </div>
    
</body>
</html>
复制代码

做前端界面真的好痛苦啊,不知道有没调试的工具。我都不想干这种义务劳动了。

ECShop出现Strict Standards: Only variables should be passed by reference in的解决方法 - 双魂人生 - 博客园

mikel阅读(827)

来源: ECShop出现Strict Standards: Only variables should be passed by reference in的解决方法 – 双魂人生 – 博客园

今天安装ecshop的时候最上面出现了一个错误提示:Strict Standards: Only variables should be passed by reference in F:\www.xxxx.com\cls_template.php on line 418

解决办法:

打开cls_template.php文件中发现下面这段代码:
$tag_sel = array_shift(explode(‘ ‘, $tag));
忘记说了,我的PHP版本是5.4.19,PHP5.3以上默认只能传递具体的变量,而不能通过函数返回值传递,所以这段代码中的explode就得移出来重新赋值了

$tagArr = explode(‘ ‘, $tag);
$tag_sel = array_shift($tagArr);
这样之后顶部的报错没掉了,左侧和底部的报错还需要去ecshop的后台点击清除缓存才能去除。

SuperSocket源码解析之开篇

mikel阅读(1319)

一 简介

官方介绍:SuperSocket 是一个轻量级, 跨平台而且可扩展的 .Net/Mono Socket 服务器程序框架。你无须了解如何使用 Socket, 如何维护 Socket 连接和 Socket 如何工作,但是你却可以使用 SuperSocket 很容易的开发出一款 Socket 服务器端软件,例如游戏服务器,GPS 服务器, 工业控制服务和数据采集服务器等等。

地址:http://www.supersocket.net/

目前所阅读的版本是:1.6.4.0

本笔记的基本思路为:Supersocket是什么,主要功能,组成结构,启动过程,工作机制,如何高性能,如何高并发,以及如何可扩展等方面进行

二  基础知识

1 Net4.0以上编程基础,熟悉lamada表达式,Tpl多核并行异步编程,泛型编程(非常重要),多线程(线程池),反射,特性等基础知识;

2 熟悉常见的设计模式,工厂模式,命令模式,代理模式,其中工厂模式在SuperSocket配置系统中大量使用,也是具有高扩展性重要基础之一;

3 Tcp/ip基本概念,通信过程;

4 IOCP(完成端口)相关概念;

5 Log4Net日志组件;

6 常见的服务器会话机制;

 

三 主要功能

如官方介绍所言,可以作为轻量级的服务器程序框架,其核心在于进程之间通过Socket进行通信达到数据交换的目的,当然也可以作为一款三方通信组件,其 主要作用在于建立服务端与客户端或者其他端点的通信,管理,维护,并提供常见的通信协议,解析等,也可以自定义协议和协议处理相关接口,所以说 SuperSocket在首先满足通信前提下同时提供常见的协议处理,也提供直接作为应用程序的服务器应用程序框架。

 

四  组成结构

援引官方的对象模型示意图可以知道,SuperSocket主要分为SocketServer,AppServer以及与之对应的SocketSession、AppSession组成

1 其中SocketServer是SocketSession的容器,负责SocketSession的管理(创建,初始化,启动,关闭等);

 

2 SocketSession则是一个最小的通信单元也就是客户端与服务端一个Socket一条通信信道封装,负责消息发送,接收;

 

3 AppServer则是服务器的一个工作单元,一个服务器可以有多个AppServer共同组成,实现对不同端口进行Tcp或者Udp链接监听,并作为 AppSession的容器和管理者,负责AppSession创建,初始化,启动,关闭等管理,向外界提供配置接口,日志接口,命令接口,连接过滤接 口,接收过滤接口等等;

 

4 相应的AppSession则是工作在SocketSession上层的服务器会话单元,其主要职能在于负责将接收到的数据进行过滤,解析,以及路由到命令并执行,如上图所示

 

五 工作机制

 

个人觉得上图从左至右第一个Session应细化成SocketSession更合适。

其工作机制也就是服务器何时开始工作,怎样工作,怎样处理接收和发送消息,这里可以参考官方给出的请求处理模型示意图,其具体步骤如下所述

1 SocketSession会话阶段

服务器启动监听器,进入监听状态等待客户端连接,当接收到一个客户端请求,验证并创建一个SocketSession会话;

2 AppSession会话阶段

当接收到客户端一个Socket请求,封装成一个SocketSession时该会话已具备收发消息的能力,但是要处理数据还得有AppSession来处理,所以由AppServer根据SocketSeeion创建AppSession,并让该会话启动开始工作

3 消息处理阶段

当SocketSession接收到一个消息时,将交由AppSession进行处理,首先进行原始数据完整性和过滤特性进行处理,主要过滤掉一 些不合法的消息或者被特性标记的,并将消息交由IReciveFilter进行协议解析封装成RequestInfo一类的结构,再路由给具体的命令执行 单元进行具体处理执行

 

以上三步骤将客户端发送一条消息或者说一个数据包,在经历接收,检查,解析,命令处理过程,这些步骤经由SocketSession和 AppSession工作在一个由AppServer负责启动的一个线程单元中,也就是说每一个 会话都将是一个线程在负责,而这些线程是交由ThreadPool负责管理,所以通篇都看不到一个显式的Thread创建并启动代码

 

六  示例

在官方源码QuickStart文件夹中给出了一些列完整示例,可以直接启动并接收简单消息的处理,这些示例可以参考到文档中结合起来理解和使用

20款优秀的Notepad++插件推荐 - PHPERZ中文资讯站

mikel阅读(1747)

来源: 20款优秀的Notepad++插件推荐 – PHPERZ中文资讯站

Notepad++编辑器

Notepad++ 是一款Windows环境下免费开源的代码编辑器,支持的语言:C, C++ , Java , C#, XML, HTML, PHP, JavaScript

Notepad++是一款Windows环 境下免费开源的代码编辑器,支持的语言: C, C++ , Java , C#, XML,SQL,Ada, HTML, PHP, ASP, AutoIt, 汇编, DOS批处理, Caml, COBOL, Cmake, CSS, D, Diff, ActionScript, Fortran, Gui4Cli, HTML, Haskell, INNO, JSP, KIXtart, LISP, Lua, Make处理(Makefile), Matlab, INI文件, MS-DOS Style, NSIS, Normal text, Objective-C, Pascal,Python, JavaScript

Notepad++从3.4版本开始支持插件机制,让用户可选择的为本身已经优秀的Notepad++添加更多强大的功能。本文搜集了20款非常优秀好用的Notepad++插件推荐给大家。

20款Notepad++插件

Insertion

这是一个主要用于演示的插件,适合初次开发者用于实例学习。它的功能是插入当前文档的名称和日期时间,以及自动关闭HTML/XML标签。

XML Tools

这个插件是包含了很多XML编辑方面的实用工具。比如XML语法规则检查,XML Schema和DTD确认,XML标签自动关闭,当前XML路径,XML和Text转换,注释和非注释切换等等。

TextFX

TextFx是预装在Notepad++中的一个插件,功能非常强大,包括各种代码的转换、插入、优化、格式化和验证等等,能很方便的提高你的工作效率。
你可以查看Text FX 官方网站 了解更多细节。

Doc Updater

每三秒自动更新你Notepad++中打开的文档。

QuickText

一个非常出色的代码片段管理器,支持Notepad++所支持的所有语言类型。

SearchInFiles

一个友好的Notepad++文件搜索工具。

NppExec

使用NppExec插件,你可以不需要离开Notepad++即可扫行你的命令行或保存脚本,大大提高你的效率。

Spell-checker

拼写检查工具. 需要先安装Aspell

DBGP plugin

你可以使用这个插件把你的 Notepad++ 变成一个php IDE.

Compare Plugin

一个非常实用的工具,可以用来比较两个文件不同之处.

FTP_synchronize

一个集成于Notepad++的FTP客户端。

MultiClipboard

Notepad的剪贴板功能增强插件。

SpeechPlugin

文本转语音朗诵插件。

Gmod 10 Lua Syntax Highlighter

Notepad++的一个语法高亮插件。

Log plugin

这个插件可以让Notepad++实现Windows内置记本事的一个功能 : 当文件为.log,每次打开后可以附加日期和时间。

更多的就不一一介绍了,大家根据自己的需求各取所需:

Light Explorer

Colour Picker

SecurePad

HTMLTag

NppExport

Simple script

Notepad的使用方法

把插件(.dll文件)放到notepad++/plugins目录里,重启Notepad++后,即可提示安装,安装成功后,在菜单栏的插件里能找到。需要注意的是,Notepad的ANSI版和Unicode版本,有的插件只支持其中某个版本。

PHP的时间戳与具体时间转化 - 沈金强 - 博客园

mikel阅读(1043)

来源: PHP的时间戳与具体时间转化 – 沈金强 – 博客园

三个内置函数:

time()     //获取UNIX系统时间戳

mktime(hour,minute,second,month,day,year)   //将指定时间转化为时间戳

date(时间格式,时间戳)     //将时间戳转化为方便阅读的时间

 

time -> date:

复制代码
$now = time();
echo "时间戳是 " .$now;
echo "创建日期是 " . date("Y-m-d h:i:s", $now);

输出:

时间戳是 1404610907
创建日期是 2014-07-06 09:41:47
复制代码

 

mktime -> date:

复制代码
$d=mktime(9, 41, 47, 7, 6, 2014);
echo "时间戳是 " .$d;
echo "创建日期是 " . date("Y-m-d h:i:s", $d);

输出:
时间戳是 1404610907
创建日期是 2014-07-06 09:41:47
复制代码

 

注:

一般注册或是登录的时候默认用time函数获得当前时间戳,当有需要指定特定时间的业务时可以根据具体时间用mktime函数转化为特定时间戳,而date函数则可以对时间戳进行逆转化为方便查看的具体时间。

在NotePad++中安装DBGP debugger调试PHP程序 - 上善若水 - 博客频道 - CSDN.NET

mikel阅读(1430)

来源: 在NotePad++中安装DBGP debugger调试PHP程序 – 上善若水 – 博客频道 – CSDN.NET

本文章涵盖了NotePad++ 的安装、Xdebug 的安装、DBGP插件 的安装以及简单的调试Php 的示例。

DBGP插件(PlugIn)如何工作

1、Web浏览器(例如:FireFox )通过Http端口(80)请求Url来访问Apache Server。

2、XDebug 是Apache的一个扩展(DLL In Windows),类似于GD库。

3、XDebug 是Web Server(Apache)与远程调试客户端(例如:NotePad++的DBGP插件 )的一个接口,他们之间通过9000端口通信。

Wire Flow:

Web browser <==> Port 80 <==> Apache + PHP + Xdebug extension <==> Port 9000

<==> DBGp Plugin-notepad++

1、开启NotePad++,BDGP插件打开9000端口。

2、Web browser向Apache 请求一个php页面,请求的Url中包含一个指定的参数

(即:XDebug_SESSION_START)以便激活远程调试。

3、Apache 调用Php 解释器(Interpreter)。

4、Php解释器加载XDebug 模块。

5、XDebug 模块检测到第2步发送的XDebug_SESSION_START参数,开启远程调试。

6、XDebug 连接到远程调试客户端(依赖于XDebug 的配置项,在php.ini中)。

7、XDebug 和调试客户端建立连接以后,通过9000端口进行对话。

8、当调试客户端向XDebug 发送执行Php语句的指令后,Php 解释器执行Php语句,相应的输出由Apache通过80端口发送出去到Web Browser。

9、当所有的php代码执行完后,XDebug 断开与调试客户端的连接。

10、Apache 断开与Web Browser的Http连接。

安装步骤

首先,你先安装好Apache和Php的运行环境,这个我就不说了,不会安装的话,看这里 ,也可以跟我一样,使用xampp ,还有WinLamp 也推荐一下,反正是开发环境,不是生产环境。

我用的xampp,php模块安装在c:/xampp/php目录下(这个因人而异)。

1、安装NotePad++,注意,不要选择exe安装包,选择zip 包,使用包中的ansi版本即可(新建一个文件夹notepad++到c:/Program Files,将ansi下面的所有文件拷贝进去),否则在你安装DBGP插件的时候会报错 (This ANSI plugin is not compatible with your Unicode
Notepad++)。

notepad++.jpg

2、下载NotePad++ 的中文xml文件 ,将其重新命名为nativeLang.xml,放到notepad++的根目录下(c:/Program Files/notepad++)。

3、下载DBGP插件 ,一个Zipped文件,解压以后,将dbgpPlugin.dll和Readme.txt文件复制到Notepad++的plugins目录下(c:/Program Files/notepad++/plugins)。

4、创建一个php文件phpinfo.php,打印php的配置信息。
<?php phpinfo(); ?>

5、 新建一文件夹supplier到apache的htdocs目录下,执行phpinfo.php,即:http://localhost /supplier/phpinfo.php  检查你的php版本,我的php版本是5.1.4,确认你的php.ini文件的位置,以及php扩展库extensions文件夹的路径。比如:

PhpInfo.JPG 图中表明:
php.ini文件在C:/WebServer/Apache2/modules/php/ 文件夹下

扩展库的路径是C:/WebServer/Apache2/modules/php/ext/

6、到XDebug官方网站 上下载XDebug For Php的Module,注意要与你的php的版本相匹配,对我来说,就是 PHP 5.1.2 – 5.1.6 ,对应的扩展库为php_xdebug-2.0.0-5.1.6.dll

Xdebug.JPG 7、拷贝php_xdebug-2.0.0-5.1.6.dll 文件到你的php扩展库文件夹,比如:C:/WebServer/Apache2/modules/php/ext/ (php.ini中的extension_dir 项)

8、用Windows记事本软件打开php.ini,增加下面的几行到php.ini的最后

[xdebug]

zend_extension_ts="C:/WebServer/Apache2/modules/php/ext/php_xdebug-2.0.0-5.1.6.dll"
xdebug.remote_enable=1
xdebug.remote_handler=dbgp
xdebug.remote_host=127.0.0.1
xdebug.remote_mode=req
xdebug.idekey=default
xdebug.remote_log="D:/www/ourcommunity.dev/log/xdebug.log"
xdebug.remote_port=9000
xdebug.show_exception_trace=0
xdebug.show_local_vars=9
xdebug.show_mem_delta=0
xdebug.trace_format=0

根据你自己的情况设置zend_extension_ts和xdebug.remote_log两项。

9、重新启动apache,如果apache启动失败,试着将php.ini中关于zend的配置项注释掉。

比如:

;zend_extension_manager.optimizer_ts = "C:/xampp/php/zendOptimizer/lib/Optimizer"

10、重新执行phpinfo.php文件,有没有看到其中的xdebug区域?

PhpInfo_Xdebug.JPG

配置Notepad++


1、打开Notepad++,进入插件菜单,弹出DbGp下拉菜单列表。

DBGp_Plugin.JPG

2、点击"Config...
"菜单项,如下图一样配置DbGp调试器(Remote Path 和 Local Path是你的php文件所在的文件夹)

DBGp_Config.JPG

简单示例