重写附件功能

pull/39/head
Minho 2017-05-12 19:14:29 +08:00
parent 701121c85e
commit 9d233861ca
12 changed files with 489 additions and 63 deletions

View File

@ -72,3 +72,23 @@ cdnjs=
cdncss=
cdnimg=
################百度地图密钥#################
baidumapkey=

View File

@ -229,7 +229,6 @@ func (c *DocumentController) Edit() {
}else{
c.TplName = "document/" + bookResult.Editor + "_edit_template.tpl"
}
beego.Info(bookResult)
c.Data["Model"] = bookResult
@ -252,6 +251,8 @@ func (c *DocumentController) Edit() {
c.Data["Result"] = template.JS("[]")
}
}
c.Data["BaiDuMapKey"] = beego.AppConfig.DefaultString("baidumapkey","")
}
@ -329,6 +330,7 @@ func (c *DocumentController) Upload() {
identify := c.GetString("identify")
doc_id,_ := c.GetInt("doc_id")
is_attach := true
if identify == "" {
c.JsonResult(6001,"参数错误")
@ -397,7 +399,7 @@ func (c *DocumentController) Upload() {
}
}
fileName := "attachment_" + strconv.FormatInt(time.Now().UnixNano(), 16)
fileName := "attach_" + strconv.FormatInt(time.Now().UnixNano(), 16)
filePath := "uploads/" + time.Now().Format("200601") + "/" + fileName + ext
@ -417,12 +419,18 @@ func (c *DocumentController) Upload() {
attachment.CreateAt = c.Member.MemberId
attachment.FileExt = ext
attachment.FilePath = filePath
attachment.DocumentId = doc_id
if fileInfo, err := os.Stat(filePath); err == nil {
attachment.FileSize = float64(fileInfo.Size())
}
if doc_id > 0{
attachment.DocumentId = doc_id
}
if strings.EqualFold(ext,".jpg") || strings.EqualFold(ext,".jpeg") || strings.EqualFold(ext,"png") || strings.EqualFold(ext,"gif") {
attachment.HttpPath = c.BaseUrl() + "/" + filePath
attachment.HttpPath = "/" + filePath
is_attach = false
}
err = attachment.Insert();
@ -433,7 +441,7 @@ func (c *DocumentController) Upload() {
c.JsonResult(6006,"文件保存失败")
}
if attachment.HttpPath == "" {
attachment.HttpPath = c.BaseUrl() + beego.URLFor("DocumentController.DownloadAttachment",":key", identify, ":attach_id", attachment.AttachmentId)
attachment.HttpPath = beego.URLFor("DocumentController.DownloadAttachment",":key", identify, ":attach_id", attachment.AttachmentId)
if err := attachment.Update();err != nil {
beego.Error("SaveToFile => ",err)
@ -447,6 +455,8 @@ func (c *DocumentController) Upload() {
"message" :"ok",
"url" : attachment.HttpPath,
"alt" : attachment.FileName,
"is_attach" : is_attach,
"attach" : attachment,
}
c.Data["json"] = result
@ -509,6 +519,44 @@ func (c *DocumentController) DownloadAttachment() {
c.StopRun()
}
//删除附件.
func (c *DocumentController) RemoveAttachment() {
c.Prepare()
attach_id ,_ := c.GetInt("attach_id")
if attach_id <= 0 {
c.JsonResult(6001,"参数错误")
}
attach,err := models.NewAttachment().Find(attach_id)
if err != nil {
beego.Error(err)
c.JsonResult(6002,"附件不存在")
}
document,err := models.NewDocument().Find(attach.DocumentId)
if err != nil {
beego.Error(err)
c.JsonResult(6003,"文档不存在")
}
if c.Member.Role != conf.MemberSuperRole {
rel,err := models.NewRelationship().FindByBookIdAndMemberId(document.BookId,c.Member.MemberId)
if err != nil {
beego.Error(err)
c.JsonResult(6004,"权限不足")
}
if rel.RoleId == conf.BookObserver {
c.JsonResult(6004,"权限不足")
}
}
err = attach.Delete()
if err != nil {
beego.Error(err)
c.JsonResult(6005,"删除失败")
}
c.JsonResult(0,"ok",attach)
}
//删除文档.
func (c *DocumentController) Delete() {
c.Prepare()
@ -628,6 +676,10 @@ func (c *DocumentController) Content() {
if err != nil {
c.JsonResult(6003,"文档不存在")
}
attach,err := models.NewAttachment().FindListByDocumentId(doc.DocumentId)
if err == nil {
doc.AttachList = attach
}
c.JsonResult(0,"ok",doc)
}

View File

@ -2,29 +2,32 @@ package models
import (
"time"
"github.com/lifei6671/godoc/conf"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/godoc/conf"
"os"
"github.com/astaxie/beego"
)
// Attachment struct .
type Attachment struct {
AttachmentId int `orm:"column(attachment_id);pk;auto;unique" json:"attachment_id"`
BookId int `orm:"column(book_id);type(int)" json:"book_id"`
DocumentId int `orm:"column(document_id);type(int);null" json:"doc_id"`
FileName string `orm:"column(file_name);size(255)" json:"file_name"`
FilePath string `orm:"column(file_path);size(2000)" json:"file_path"`
FileSize float64 `orm:"column(file_size);type(float)" json:"file_size"`
HttpPath string `orm:"column(http_path);size(2000)" json:"http_path"`
FileExt string `orm:"column(file_ext);size(50)" json:"file_ext"`
CreateTime time.Time `orm:"type(datetime);column(create_time);auto_now_add"`
CreateAt int `orm:"column(create_at);type(int)" json:"create_at"`
AttachmentId int `orm:"column(attachment_id);pk;auto;unique" json:"attachment_id"`
BookId int `orm:"column(book_id);type(int)" json:"book_id"`
DocumentId int `orm:"column(document_id);type(int);null" json:"doc_id"`
FileName string `orm:"column(file_name);size(255)" json:"file_name"`
FilePath string `orm:"column(file_path);size(2000)" json:"file_path"`
FileSize float64 `orm:"column(file_size);type(float)" json:"file_size"`
HttpPath string `orm:"column(http_path);size(2000)" json:"http_path"`
FileExt string `orm:"column(file_ext);size(50)" json:"file_ext"`
CreateTime time.Time `orm:"type(datetime);column(create_time);auto_now_add" json:"create_time"`
CreateAt int `orm:"column(create_at);type(int)" json:"create_at"`
}
// TableName 获取对应数据库表名.
func (m *Attachment) TableName() string {
return "attachment"
}
// TableEngine 获取数据使用的引擎.
func (m *Attachment) TableEngine() string {
return "INNODB"
@ -33,38 +36,51 @@ func (m *Attachment) TableNameWithPrefix() string {
return conf.GetDatabasePrefix() + m.TableName()
}
func NewAttachment() *Attachment {
func NewAttachment() *Attachment {
return &Attachment{}
}
func (m *Attachment) Insert() error {
func (m *Attachment) Insert() error {
o := orm.NewOrm()
_,err := o.Insert(m)
_, err := o.Insert(m)
return err
}
func (m *Attachment) Update() error {
o := orm.NewOrm()
_,err := o.Update(m)
_, err := o.Update(m)
return err
}
func (m *Attachment) Find(id int) (*Attachment,error) {
func (m *Attachment) Delete() error {
o := orm.NewOrm()
_,err := o.Delete(m)
if err == nil {
if err1 := os.Remove(m.FilePath); err1 != nil {
beego.Error(err1)
}
}
return err
}
func (m *Attachment) Find(id int) (*Attachment, error) {
if id <= 0 {
return m,ErrInvalidParameter
return m, ErrInvalidParameter
}
o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("attachment_id",id).One(m)
err := o.QueryTable(m.TableNameWithPrefix()).Filter("attachment_id", id).One(m)
return m,err
return m, err
}
func (m *Attachment) FindListByDocumentId(doc_id int) (attaches []*Attachment, err error) {
o := orm.NewOrm()
_,err = o.QueryTable(m.TableNameWithPrefix()).Filter("document_id",doc_id).OrderBy("-attachment_id").All(&attaches)
return
}

View File

@ -28,6 +28,7 @@ type Document struct {
ModifyTime time.Time `orm:"column(modify_time);type(datetime);auto_now" json:"modify_time"`
ModifyAt int `orm:"column(modify_at);type(int)" json:"-"`
Version int64 `orm:"type(bigint);column(version)" json:"version"`
AttachList []*Attachment `orm:"-" json:"attach"`
}

View File

@ -51,6 +51,7 @@ func init() {
beego.Router("/book/setting/token", &controllers.BookController{},"post:CreateToken")
beego.Router("/book/setting/delete", &controllers.BookController{},"post:Delete")
beego.Router("/api/attach/remove/", &controllers.DocumentController{},"post:RemoveAttachment")
beego.Router("/api/:key/edit/?:id", &controllers.DocumentController{},"*:Edit")
beego.Router("/api/upload",&controllers.DocumentController{},"post:Upload")
beego.Router("/api/:key/create",&controllers.DocumentController{},"post:Create")

View File

@ -195,8 +195,6 @@ body{
font-style: normal;
}
.manual-editor-status{
position: absolute;
left: 0;
@ -208,4 +206,100 @@ body{
color: #555;
background-color: #FAFAFA;
z-index: 1000;
}
line-height: 30px;
}
.manual-editor-status .item{
display: inline-block;
margin-right: 10px;
margin-left: 10px;
cursor: pointer;
}
.attach-drop-panel{
display: block;
position: relative;
width: 100%;
height: 100%;
}
.attach-drop-panel .webuploader-element-invisible{
width: 500px;
height: 100px;
position: absolute;
top: 0;
}
.attach-drop-panel .webuploader-pick{
color: #ccc;
text-align: center;
margin: 20px 20px 15px!important;
padding: 5px!important;
font-size: 65px;
cursor: pointer;
border: 2px dotted #999;
display: block!important;
background: #ffffff;
}
.attach-drop-panel .webuploader-pick:hover{
color: #333;
border-color: #333;
}
.attach-list{
background:#ffffff;
font-size: 12px;
}
.attach-list .attach-item{
padding: 8px 10px;
line-height: 36px;
border: 1px solid #ddd;
border-bottom: none;
border-top-left-radius:3px;
border-top-right-radius:3px;
}
.attach-list .attach-item:last-child{
border-bottom: 1px solid #ddd;
border-bottom-left-radius:3px;
border-bottom-right-radius:3px;
}
.attach-list .attach-item .progress{
margin-top: 10px;
margin-bottom: 10px;
height: 10px;
}
.attach-list .attach-item .form-control{
width: 60%;
float: left;
}
.attach-list .attach-item .text{
display: inline-block;
padding: 0 15px;
}
.attach-list .attach-item .close{
float: right;
display: inline-block;
padding: 8px 0;
color: #586069;
background: #ffffff;
font-size: 16px;
}
.attach-list .attach-item .close:hover {
color: #333;
}

View File

@ -140,6 +140,23 @@ function pushDocumentCategory($node) {
}
window.documentCategory.push($node);
}
/**
* 将数据重置到Vue列表中
* @param $lists
*/
function pushVueLists($lists) {
for(var i in window.vueApp.lists){
var item = window.vueApp.lists[i];
window.vueApp.lists.$remove(item);
}
for(var j in $lists){
var item = $lists[j];
window.vueApp.lists.push(item);
}
console.log(window.vueApp.lists)
$("#attachInfo").text(" " + window.vueApp.lists.length + " 个附件")
}
//实现小提示
$("[data-toggle='tooltip']").hover(function () {

View File

@ -1,16 +1,17 @@
$(function () {
wangEditor.config.mapAk = window.baiduMapKey;
window.addDocumentModalFormHtml = $(this).find("form").html();
wangEditor.config.printLog = false;
window.editor = new wangEditor('htmlEditor');
editor.config.uploadImgUrl = window.imageUploadURL;
editor.config.uploadImgFileName = "editormd-file-file";
editor.config.uploadImgFileName = "editormd-image-file";
editor.config.uploadParams = {
"editor" : "wangEditor"
};
wangEditor.config.menus.splice(0,0,"|");
wangEditor.config.menus.splice(0,0,"save");
wangEditor.config.menus.splice(0,0,"release");
wangEditor.config.menus.splice(29,0,"attach")
//移除地图、背景色
editor.config.menus = $.map(wangEditor.config.menus, function(item, key) {
@ -81,6 +82,8 @@ $(function () {
pushDocumentCategory(node);
window.selectNode = node;
pushVueLists(res.data.attach);
}else{
layer.msg("文档加载失败");
}

View File

@ -0,0 +1,47 @@
(function () {
// 获取 wangEditor 构造函数和 jquery
var E = window.wangEditor;
var $ = window.jQuery;
// 用 createMenu 方法创建菜单
E.createMenu(function (check) {
// 定义菜单id不要和其他菜单id重复。编辑器自带的所有菜单id可通过『参数配置-自定义菜单』一节查看
var menuId = 'attach';
// check将检查菜单配置『参数配置-自定义菜单』一节描述中是否该菜单id如果没有则忽略下面的代码。
if (!check(menuId)) {
return;
}
// this 指向 editor 对象自身
var editor = this;
// 创建 menu 对象
var menu = new E.Menu({
editor: editor, // 编辑器对象
id: menuId, // 菜单id
title: '附件', // 菜单标题
// 正常状态和选中状态下的dom对象样式需要自定义
$domNormal: $('<a href="#" tabindex="-1"><i class="fa fa-paperclip" aria-hidden="true" name="release"></i></a>'),
$domSelected: $('<a href="#" tabindex="-1" class="selected"><i class="fa fa-paperclip" aria-hidden="true" name="release"></i></a>')
});
// 菜单正常状态下,点击将触发该事件
menu.clickEvent = function (e) {
$("#uploadAttachModal").modal("show");
};
// 菜单选中状态下,点击将触发该事件
menu.clickEventSelected = function (e) {
};
// 增加到editor对象中
editor.menus[menuId] = menu;
});
})();

View File

@ -6,6 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>编辑文档 - Powered by MinDoc</title>
<script type="text/javascript">
window.editor = null;
window.imageUploadURL = "{{urlfor "DocumentController.Upload" "identify" .Model.Identify}}";
@ -17,13 +18,18 @@
window.editURL = "{{urlfor "DocumentController.Content" ":key" .Model.Identify ":id" ""}}";
window.releaseURL = "{{urlfor "BookController.Release" ":key" .Model.Identify}}";
window.sortURL = "{{urlfor "BookController.SaveSort" ":key" .Model.Identify}}";
window.baiduMapKey = "{{.BaiDuMapKey}}";
window.vueApp = null;
</script>
<!-- Bootstrap -->
<link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<link href="/static/jstree/3.3.4/themes/default/style.min.css" rel="stylesheet">
<link href="/static/wangEditor/css/wangEditor.min.css" rel="stylesheet">
<link href="/static/highlight/styles/zenburn.css" rel="stylesheet">
<link href="{{cdncss "/static/bootstrap/css/bootstrap.min.css"}}" rel="stylesheet">
<link href="{{cdncss "/static/font-awesome/css/font-awesome.min.css"}}" rel="stylesheet">
<link href="{{cdncss "/static/jstree/3.3.4/themes/default/style.min.css"}}" rel="stylesheet">
<link href="{{cdncss "/static/wangEditor/css/wangEditor.min.css"}}" rel="stylesheet">
<link href="{{cdncss "/static/highlight/styles/zenburn.css"}}" rel="stylesheet">
<link href="{{cdncss "/static/webuploader/webuploader.css"}}" rel="stylesheet">
<link href="/static/css/jstree.css" rel="stylesheet">
<link href="/static/css/markdown.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
@ -36,7 +42,7 @@
<body>
<div class="m-manual manual-editor">
{{/*<div class="manual-head" id="editormd-tools">
<!--{{/*<div class="manual-head" id="editormd-tools">
<div class="editormd-group">
<a href="{{urlfor "BookController.Dashboard" ":key" .Model.Identify}}" data-toggle="tooltip" data-title="返回"><i class="fa fa-chevron-left" aria-hidden="true"></i></a>
</div>
@ -61,7 +67,7 @@
</div>
<div class="clearfix"></div>
</div>*/}}
</div>*/}}-->
<div class="manual-body">
<div class="manual-category" id="manualCategory" style="top: 0;">
<div class="manual-nav">
@ -78,7 +84,7 @@
<div id="htmlEditor" class="manual-editormd-active" style="height: 100%"></div>
</div>
<div class="manual-editor-status">
<div id="attachInfo" class="item"></div>
</div>
</div>
@ -121,16 +127,168 @@
</form>
</div>
</div>
<div class="modal fade" id="uploadAttachModal" tabindex="-1" role="dialog" aria-labelledby="uploadAttachModalLabel">
<div class="modal-dialog" role="document">
<form method="post" action="{{urlfor "DocumentController.Create" ":key" .Model.Identify}}" id="addDocumentForm" class="form-horizontal">
<input type="hidden" name="identify" value="{{.Model.Identify}}">
<input type="hidden" name="doc_id" value="0">
<input type="hidden" name="parent_id" value="0">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">上传附件</h4>
</div>
<div class="modal-body">
<div class="attach-drop-panel">
<div class="upload-container" id="filePicker"><i class="fa fa-upload" aria-hidden="true"></i></div>
</div>
<div class="attach-list" id="attachList">
<template v-for="item in lists">
<div class="attach-item">
<template v-if="item.state == 0">
<div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100">
<span class="sr-only">0% Complete (success)</span>
</div>
</div>
</template>
<template v-else>
<input type="hidden" name="attach_id[0]" :value="item.attach_id">
<input type="text" class="form-control" placeholder="附件名称" :value="item.file_name">
<span class="text">(${(item.file_size/1024/1024).toFixed(4)}MB)</span>
<span class="error-message">${item.message}</span>
<button type="button" class="btn btn-sm close" @click="removeAttach(item.attachment_id)">
<i class="fa fa-remove" aria-hidden="true"></i>
</button>
<div class="clearfix"></div>
</template>
</div>
</template>
</div>
</div>
<div class="modal-footer">
<span id="add-error-message" class="error-message"></span>
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="btnUploadAttachFile">确定</button>
</div>
</div>
</form>
</div>
</div>
<script src="{{cdnjs "/static/jquery/1.12.4/jquery.min.js"}}"></script>
<script src="{{cdnjs "/static/bootstrap/js/bootstrap.min.js"}}"></script>
<script src="{{cdnjs "/static/vuejs/vue.min.js"}}" type="text/javascript"></script>
<script src="{{cdnjs "/static/jstree/3.3.4/jstree.min.js"}}" type="text/javascript"></script>
<script src="{{cdnjs "/static/webuploader/webuploader.min.js"}}" type="text/javascript"></script>
<script src="{{cdnjs "/static/wangEditor/js/wangEditor.min.js"}}" type="text/javascript"></script>
<script src="{{cdnjs "/static/wangEditor/plugins/save-menu.js"}}" type="text/javascript"></script>
<script src="{{cdnjs "/static/wangEditor/plugins/release-menu.js"}}" type="text/javascript"></script>
<script src="{{cdnjs "/static/wangEditor/plugins/attach-menu.js"}}" type="text/javascript"></script>
<script src="{{cdnjs "/static/layer/layer.js"}}" type="text/javascript" ></script>
<script src="{{cdnjs "/static/to-markdown/dist/to-markdown.js"}}" type="text/javascript"></script>
<script src="{{cdnjs "/static/js/jquery.form.js"}}" type="text/javascript"></script>
<script type="text/javascript">
window.vueApp = new Vue({
el : "#attachList",
data : {
lists : []
},
delimiters : ['${','}'],
methods : {
removeAttach : function ($attach_id) {
console.log($attach_id);
var $this = this;
$.ajax({
url : "{{urlfor "DocumentController.RemoveAttachment"}}",
type : "post",
data : { "attach_id" : $attach_id},
success : function (res) {
console.log(res)
if(res.errcode === 0){
for(var i in $this.lists){
var item = $this.lists[i];
if (item.attachment_id == res.data.attachment_id){
$this.lists.$remove(item);
break;
}
}
}else{
layer.msg(res.message);
}
}
});
}
}
});
</script>
<script src="/static/js/editor.js" type="text/javascript"></script>
<script src="/static/js/html-editor.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$("#attachInfo").on("click",function () {
$("#uploadAttachModal").modal("show");
});
window.uploader = null;
$("#uploadAttachModal").on("shown.bs.modal",function () {
if(window.uploader === null){
try {
window.uploader = WebUploader.create({
auto: true,
dnd : true,
swf: '/static/webuploader/Uploader.swf',
server: '{{urlfor "DocumentController.Upload"}}',
formData : { "identify" : {{.Model.Identify}},"doc_id" : window.selectNode.id },
pick: "#filePicker",
fileVal : "editormd-file-file",
fileNumLimit : 1,
compress : false
}).on("beforeFileQueued",function (file) {
uploader.reset();
}).on( 'fileQueued', function( file ) {
var item = {
state : 0,
attachment_id : file.id(),
file_size : file.size,
file_name : file.name,
message : "正在上传"
};
window.vueApp.lists.splice(0,0,item);
}).on("uploadError",function (file,reason) {
$("#error-message").text("上传失败:" + reason);
}).on("uploadSuccess",function (file, res) {
console.log(file);
for(var index in window.vueApp.lists){
var item = window.vueApp.lists[index];
if(item.id === file.id()){
window.vueApp.lists.splice(index,1,res.attach);
break;
}
}
}).on("beforeFileQueued",function (file) {
}).on("uploadComplete",function () {
}).on("uploadProgress",function (file, percentage) {
var $li = $( '#'+file.id ),
$percent = $li.find('.progress .progress-bar');
$percent.css( 'width', percentage * 100 + '%' );
});
}catch(e){
console.log(e);
}
}
});
});
</script>
</body>
</html>

View File

@ -8,8 +8,8 @@
<title>配置管理 - Powered by MinDoc</title>
<!-- Bootstrap -->
<link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<link href="{{cdncss "/static/bootstrap/css/bootstrap.min.css"}}" rel="stylesheet">
<link href="{{cdncss "/static/font-awesome/css/font-awesome.min.css"}}" rel="stylesheet">
<link href="/static/css/main.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
@ -77,10 +77,11 @@
</label>
</div>
</div>
<div class="form-group">
<button type="submit" id="btnSaveBookInfo" class="btn btn-success" data-loading-text="保存中...">保存修改</button>
<span id="form-error-message" class="error-message"></span>
</div>
<div class="form-group">
<button type="submit" id="btnSaveBookInfo" class="btn btn-success" data-loading-text="保存中...">保存修改</button>
<span id="form-error-message" class="error-message"></span>
</div>
</form>
<div class="clearfix"></div>
@ -93,9 +94,9 @@
</div>
<script src="/static/jquery/1.12.4/jquery.min.js" type="text/javascript"></script>
<script src="/static/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="/static/js/jquery.form.js" type="text/javascript"></script>
<script src="{{cdnjs "/static/jquery/1.12.4/jquery.min.js"}}" type="text/javascript"></script>
<script src="{{cdnjs "/static/bootstrap/js/bootstrap.min.js"}}" type="text/javascript"></script>
<script src="{{cdnjs "/static/js/jquery.form.js"}}" type="text/javascript"></script>
<script src="/static/js/main.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {

View File

@ -20,20 +20,36 @@
<div class="btn-group dropdown-menu-right pull-right slidebar visible-xs-inline-block visible-sm-inline-block">
<button class="btn btn-default dropdown-toggle hidden-lg" type="button" data-toggle="dropdown"><i class="fa fa-align-justify"></i></button>
<ul class="dropdown-menu" role="menu">
{{if gt .Member.MemberId 0}}
<li>
<a href="{{urlfor "SettingController.Index"}}" title="个人中心"><i class="fa fa-user" aria-hidden="true"></i> 个人中心</a>
</li>
<li>
<a href="{{urlfor "BookController.Index"}}" title="我的项目"><i class="fa fa-book" aria-hidden="true"></i> 我的项目</a>
</li>
{{if eq .Member.Role 0 }}
<li>
<a href="{{urlfor "ManagerController.Index"}}" title="管理后台"><i class="fa fa-university" aria-hidden="true"></i> 管理后台</a>
<div class="img user-info" data-toggle="dropdown">
<img src="{{cdnimg .Member.Avatar}}" class="img-circle userbar-avatar" alt="{{.Member.Account}}">
<div class="userbar-content">
<span>{{.Member.Account}}</span>
<div>{{.Member.RoleName}}</div>
</div>
<i class="fa fa-chevron-down" aria-hidden="true"></i>
</div>
<ul class="dropdown-menu user-info-dropdown" role="menu">
<li>
<a href="{{urlfor "SettingController.Index"}}" title="个人中心"><i class="fa fa-user" aria-hidden="true"></i> 个人中心</a>
</li>
<li>
<a href="{{urlfor "BookController.Index"}}" title="我的项目"><i class="fa fa-book" aria-hidden="true"></i> 我的项目</a>
</li>
{{if eq .Member.Role 0 }}
<li>
<a href="{{urlfor "ManagerController.Index"}}" title="管理后台"><i class="fa fa-university" aria-hidden="true"></i> 管理后台</a>
</li>
{{end}}
<li>
<a href="{{urlfor "AccountController.Logout"}}" title="退出登录"><i class="fa fa-sign-out"></i> 退出登录</a>
</li>
</ul>
</li>
{{else}}
<li><a href="{{urlfor "AccountController.Login"}}" title="用户登录">登录</a></li>
{{end}}
<li>
<a href="{{urlfor "AccountController.Logout"}}" title="退出登录"><i class="fa fa-sign-out"></i> 退出登录</a>
</li>
</ul>
</div>