管理中心,文章分类管理,文章管理,文件上传,文章回收站

发布时间 2023-04-22 22:40:12作者: yangphp

前言:

文章分类管理,文章管理,文章回收站

正文:

 分类管理效果:

 添加分类:

 

文章列表效果:

 

添加文章效果:

 

文章回收站效果:

 

控制器代码:admins/controllers/news.go

//文章分类列表
func NewsCateList(c *gin.Context)  {

    list:=modes.NewsCateList(c)

    c.HTML(http.StatusOK,"news/news_cate_list.html", gin.H{
        "list":list,
        "cate_name":c.Query("cate_name"),
        "count":len(list),
    })
}
//文章分类添加/编辑
func NewsCateAdd(c *gin.Context)  {
    var cate modes.SysNewsCate
    news_id,exist := c.GetQuery("news_id");
    if  exist == true{
        //编辑
        news_idd,_ := strconv.Atoi(news_id)
        cate = modes.NewsCateItem(news_idd,c)
    }

    c.HTML(http.StatusOK,"news/news_cate_edit.html", gin.H{
        "cate":cate,
    })
}

//文章分类保存
func NewsCateSave(c *gin.Context)  {
    res,msg := modes.NewsCateSave(c)
    if res != true {
        c.JSON(http.StatusOK, gin.H{ "code": 400, "msg":  msg,})
        return
    }
    c.JSON(http.StatusOK, gin.H{ "code": 0, "msg":  "保存成功",})
}
//文章分类删除
func NewsCateDel(c *gin.Context)  {

    res,msg := modes.NewsCateDel(c)
    if res != true {
        c.JSON(http.StatusOK, gin.H{ "code": 400, "msg":  msg,})
        return
    }
    c.JSON(http.StatusOK, gin.H{ "code": 0, "msg":  "删除成功",})
}

//文章列表
func NewsList(c *gin.Context)  {

    list:=modes.NewsList(c,1)
    cate_list := modes.NewsCateList(c)

    //将cate_id 转换为int
    cate_id,_ := strconv.Atoi(c.Query("cate_id"))

    c.HTML(http.StatusOK,"news/news_list.html", gin.H{
        "list":list,
        "count":len(list),
        "cate_list":cate_list,
        "news_title":c.Query("news_title"),
        "cate_id":cate_id,
        "start_date":c.Query("start_date"),
        "end_date":c.Query("end_date"),
    })
}

//文章添加/编辑
func NewsAdd(c *gin.Context)  {

    news := modes.SysNews{}
    news_id,exist := c.GetQuery("news_id");
    if  exist == true{
        //编辑
        news_idd,_ := strconv.Atoi(news_id)
        news = modes.NewsItem(news_idd,c)
        //content base64解码
        bytes,_ := base64.StdEncoding.DecodeString(news.NewsContent)
        news.NewsContent = string(bytes)
    }
    cate_list := modes.NewsCateList(c)


    c.HTML(http.StatusOK,"news/news_edit.html", gin.H{
        "news":news,
        "cate_list":cate_list,
    })
}

//文章保存
func NewsSave(c *gin.Context)  {
    res,msg := modes.NewsSave(c)
    if res != true {
        c.JSON(http.StatusOK, gin.H{ "code": 400, "msg":  msg,})
        return
    }
    c.JSON(http.StatusOK, gin.H{ "code": 0, "msg":  "保存成功",})
}

//文章删除
func NewsDel(c *gin.Context)  {

    news_id := c.Query("news_id")
    news_idd,_ := strconv.Atoi(news_id)
    res,msg := modes.NewsDel(news_idd,c)
    if res != true {
        c.JSON(http.StatusOK, gin.H{ "code": 400, "msg":  msg,})
        return
    }
    c.JSON(http.StatusOK, gin.H{ "code": 0, "msg":  "保存成功",})
}


//文章列表
func NewsTrashList(c *gin.Context)  {
    list:=modes.NewsList(c,2)
    cate_list := modes.NewsCateList(c)

    //将cate_id 转换为int
    cate_id,_ := strconv.Atoi(c.Query("cate_id"))

    c.HTML(http.StatusOK,"news/news_trash_list.html", gin.H{
        "list":list,
        "count":len(list),
        "cate_list":cate_list,
        "news_title":c.Query("news_title"),
        "cate_id":cate_id,
        "start_date":c.Query("start_date"),
        "end_date":c.Query("end_date"),
    })
}

//恢复
func NewsRestore(c *gin.Context)  {
    news_id := c.Query("news_id")
    news_idd,_ := strconv.Atoi(news_id)
    res,msg := modes.NewsRestore(news_idd,c)
    if res != true {
        c.JSON(http.StatusOK, gin.H{ "code": 400, "msg":  msg,})
        return
    }
    c.JSON(http.StatusOK, gin.H{ "code": 0, "msg":  "保存成功",})
}
//永久删除
func NewsDelReal(c *gin.Context)  {
    news_id := c.Query("news_id")
    news_idd,_ := strconv.Atoi(news_id)
    res,msg := modes.NewsDelReal(news_idd,c)
    if res != true {
        c.JSON(http.StatusOK, gin.H{ "code": 400, "msg":  msg,})
        return
    }
    c.JSON(http.StatusOK, gin.H{ "code": 0, "msg":  "保存成功",})
}

模型代码:modes/newsModel.go

type SysNewsCate struct {
   Id int `form:"id"`
   CateName string `form:"cate_name"`
   CateOrders string `form:"cate_orders"`
   IsShow int `form:"is_show"`
}

type SysNews struct {
   Id int `form:"id"`
   NewsTitle string `form:"news_title"`
   NewsDesc string `form:"news_desc"`
   NewsContent string `form:"news_content"`
   NewsPic string `form:"news_pic"`
   IsShow int `form:"is_show"`
   CateId int `form:"cate_id"`
   IsRecommed int `form:"is_recommed"`
   NewsReads int `form:"news_reads"`
   IsDel int `form:"is_del"`
   DelDatetime string `form:"del_datetime"`
   AddDatetime string `form:"add_datetime"`
}
type SysNewsList struct {
   SysNews
   CateName string
}
//获取新闻分类列表
func NewsCateList(c *gin.Context) []SysNewsCate{
    cate_list := []SysNewsCate{}

    NewDb := DB
    if cate_name,isExist := c.GetQuery("cate_name");isExist == true{
        if strings.TrimSpace(cate_name) != ""{
            NewDb = NewDb.Where("cate_name = ?",cate_name)
        }
    }
    res := NewDb.Model(SysNewsCate{}).Order("cate_orders DESC").Find(&cate_list)
    if res.Error != nil {
        return cate_list
    }
    return cate_list
}
//获取新闻分类
func NewsCateItem(news_id int,c *gin.Context) SysNewsCate {
    var news_cate  SysNewsCate
    DB.Model(SysNewsCate{}).Where("id = ?",news_id).First(&news_cate)

    return news_cate
}
//保存分类
func NewsCateSave(c *gin.Context) (bool,string) {
    var cate = SysNewsCate{}
    c.ShouldBind(&cate)

    if cate.Id > 0 {
        //更新
        res := DB.Model(SysNewsCate{}).Where("id=?",cate.Id).Updates(&cate)
        if res.Error != nil {
            return false,"保存失败"
        }

    }else{
        //增加
        res := DB.Model(SysNewsCate{}).Create(&cate)
        if res.Error != nil {
            return false,"保存失败"
        }
    }
    return true,"保存成功"
}
//删除分类
func NewsCateDel(c *gin.Context) (bool,string){
    id := c.Query("id")
    idd,err  := strconv.Atoi(id)
    if err !=nil {
        return false,err.Error()
    }
    var  count int64
    //判断分类下是否有文章
     DB.Model(SysNews{}).Where("cate_id=?",idd).Count(&count)
    if count >0 {
        count_str := strconv.Itoa(int(count))
        return false,"该分类下有"+count_str+"篇文章,请先移除后再删除分类"
    }

    res :=DB.Model(SysNewsCate{}).Where("id=?",idd).Delete(SysNewsCate{})
    if res.Error != nil {
        return false,res.Error.Error()
    }
    return true,"保存成功"
}

//文章列表
func NewsList(c *gin.Context,flag int) ([]SysNewsList)  {

    news_list := []SysNewsList{}

    NewDb := DB
    if title,isExist := c.GetQuery("news_title");isExist == true{
        if strings.TrimSpace(title) != ""{
            NewDb = NewDb.Where("news_title like ?","%"+title+"%")
        }
    }
    if is_show,isExist := c.GetQuery("is_show");isExist == true{
        if strings.TrimSpace(is_show) != ""{
            NewDb = NewDb.Where("is_show = ?",is_show)
        }
    }

    if cate_id,isExist := c.GetQuery("cate_id");isExist == true{
        if strings.TrimSpace(cate_id) != ""{
            NewDb = NewDb.Where("cate_id = ?",cate_id)
        }
    }

    if start_date,isExist := c.GetQuery("start_date");isExist == true{
        if strings.TrimSpace(start_date) != "" {
            start_date = start_date + " 00:00:00"
            NewDb = NewDb.Where("add_datetime > ?", start_date)
        }
    }
    if end_date,isExist := c.GetQuery("end_date");isExist == true{
        if strings.TrimSpace(end_date) != "" {
            end_date = end_date+" 23:59:59"
            NewDb = NewDb.Where("add_datetime <= ?",end_date)
        }
    }
    if flag == 1 {
        //只查询未删除的
        NewDb = NewDb.Where("is_del  = ?",1)
    }else{
        //只查询未删除的
        NewDb = NewDb.Where("is_del  = ?",2)
    }

    res := NewDb.Model(SysNews{}).Select("sys_news.*","sys_news_cate.cate_name").
        Order("sys_news.id DESC").
        Joins("join sys_news_cate on sys_news.cate_id = sys_news_cate.id").Find(&news_list)

    if res.Error != nil {
        return news_list
    }
    return news_list

}

//文章详情
func NewsItem(news_id int,c *gin.Context) SysNews  {
    var news  SysNews
    DB.Model(SysNews{}).Where("id = ?",news_id).First(&news)

    return news
}

//文章保存
func NewsSave(c *gin.Context) (bool,string) {
    var news = SysNews{}
    c.ShouldBind(&news)

    if news.Id > 0 {
        //更新

        //对内容进行base64编码一下
        content := []byte(news.NewsContent)
        news.NewsContent = base64.StdEncoding.EncodeToString(content)

        ////解编码
        //bytes,_ := base64.StdEncoding.DecodeString(news.NewsContent)
        //news.NewsContent = string(bytes)

        res := DB.Model(SysNews{}).Where("id=?",news.Id).Updates(&news)
        if res.Error != nil {
            return false,"保存失败"
        }

    }else{
        //增加

        //对内容进行base64编码一下,方便保存
        content := []byte(news.NewsContent)
        news.NewsContent = base64.StdEncoding.EncodeToString(content)
        news.AddDatetime = time.Now().Format(common.TimeTem)
        news.DelDatetime = "1999-01-01 00:00:00"

        res := DB.Model(SysNews{}).Create(&news)
        if res.Error != nil {
            return false,"保存失败"
        }
    }
    return true,"保存成功"
}

//文章删除
func NewsDel(news_id int,c *gin.Context) (bool,string) {
    var news = SysNews{
        IsDel: 2,
        DelDatetime: time.Now().Format(common.TimeTem),
    }

    res := DB.Model(SysNews{}).Where("id=?",news_id).Updates(&news)
    if res.Error != nil {
        return false,"保存失败"
    }
    return true,"删除成功"
}

//文章恢复
func NewsRestore(news_id int,c *gin.Context) (bool,string) {
    var news = SysNews{
        IsDel: 1,
        DelDatetime: "1999-01-01 00:00:00",
    }

    res := DB.Model(SysNews{}).Where("id=?",news_id).Updates(&news)
    if res.Error != nil {
        return false,"保存失败"
    }
    return true,"删除成功"
}

//文章彻底删除
func NewsDelReal(news_id int,c *gin.Context) (bool,string) {

    var news = SysNews{}

    res := DB.Model(SysNews{}).Where("id=?",news_id).Delete(&news)
    if res.Error != nil {
        return false,"保存失败"
    }
    return true,"删除成功"
}

文件上传:common/upload.go

// 定义上传路径
const UPLOAD_DIR = "./static/uploads"

//文件上传 ,文章封面图
func FileUpload(c *gin.Context)  {

    file, err := c.FormFile("file")
    if err != nil {
        c.JSON(http.StatusForbidden, gin.H{
            "code":  400,
            "error": err.Error(),
        })
        return
    }

    arr := strings.Split(file.Filename, ".")
    filepath, ok := checkExtAndgetFilePath(arr[1])
    if ok != true {
        c.JSON(http.StatusForbidden, gin.H{
            "code":  400,
            "error": "invalid ext",
        })
        return
    }
    if err = c.SaveUploadedFile(file, filepath); err != nil {
        c.JSON(http.StatusForbidden, gin.H{
            "code":  400,
            "error": "upload failed",
        })
        return
    }

    file_url :=strings.Replace(filepath,"./static/uploads","/uploads",1)

    c.JSON(http.StatusOK, gin.H{
        "code":    200,
        "error":   "upload success",
        "img_url": file_url,
    })
    return
}


// 检查扩展名,并返回文件路径
func checkExtAndgetFilePath(fileExt string) (string, bool) {
    allowExt := map[string]bool{
        "jpg":  true,
        "png":  true,
        "jpeg": true,
    }
    if _, ok := allowExt[fileExt]; !ok {
        return "", false
    }

    year := strconv.Itoa(time.Now().Year())
    month := strconv.Itoa(int(time.Now().Month()))
    file_dir := UPLOAD_DIR + "/"+year+month+"/"
    //创建文件夹
    _, ok := os.Stat(file_dir)
    if  ok != nil {
        os.Mkdir(UPLOAD_DIR, os.ModePerm)
    }

    filePath := file_dir + strconv.FormatInt(time.Now().UnixNano(), 10) + "." + fileExt
    return filePath, true
}


//UEeditor 文件上传
func ImgUpload(c *gin.Context)  {


    action := c.Query("action")

    json_str := `/* 前后端通信相关的配置,注释只允许使用多行方式 */
{
    /* 上传图片配置项 */
    "imageActionName": "uploadimage", /* 执行上传图片的action名称 */
    "imageFieldName": "upfile", /* 提交的图片表单名称 */
    "imageMaxSize": 2048000, /* 上传大小限制,单位B */
    "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
    "imageCompressEnable": true, /* 是否压缩图片,默认是true */
    "imageCompressBorder": 1600, /* 图片压缩最长边限制 */
    "imageInsertAlign": "none", /* 插入的图片浮动方式 */
    "imageUrlPrefix": "", /* 图片访问路径前缀 */
    "imagePathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
                                /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
                                /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
                                /* {time} 会替换成时间戳 */
                                /* {yyyy} 会替换成四位年份 */
                                /* {yy} 会替换成两位年份 */
                                /* {mm} 会替换成两位月份 */
                                /* {dd} 会替换成两位日期 */
                                /* {hh} 会替换成两位小时 */
                                /* {ii} 会替换成两位分钟 */
                                /* {ss} 会替换成两位秒 */
                                /* 非法字符 \ : * ? " < > | */
                                /* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */

    /* 涂鸦图片上传配置项 */
    "scrawlActionName": "uploadscrawl", /* 执行上传涂鸦的action名称 */
    "scrawlFieldName": "upfile", /* 提交的图片表单名称 */
    "scrawlPathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "scrawlMaxSize": 2048000, /* 上传大小限制,单位B */
    "scrawlUrlPrefix": "", /* 图片访问路径前缀 */
    "scrawlInsertAlign": "none",

    /* 截图工具上传 */
    "snapscreenActionName": "uploadimage", /* 执行上传截图的action名称 */
    "snapscreenPathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "snapscreenUrlPrefix": "", /* 图片访问路径前缀 */
    "snapscreenInsertAlign": "none", /* 插入的图片浮动方式 */

    /* 抓取远程图片配置 */
    "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
    "catcherActionName": "catchimage", /* 执行抓取远程图片的action名称 */
    "catcherFieldName": "source", /* 提交的图片列表表单名称 */
    "catcherPathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "catcherUrlPrefix": "", /* 图片访问路径前缀 */
    "catcherMaxSize": 2048000, /* 上传大小限制,单位B */
    "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */

    /* 上传视频配置 */
    "videoActionName": "uploadvideo", /* 执行上传视频的action名称 */
    "videoFieldName": "upfile", /* 提交的视频表单名称 */
    "videoPathFormat": "/ueditor/php/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "videoUrlPrefix": "", /* 视频访问路径前缀 */
    "videoMaxSize": 102400000, /* 上传大小限制,单位B,默认100MB */
    "videoAllowFiles": [
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"], /* 上传视频格式显示 */

    /* 上传文件配置 */
    "fileActionName": "uploadfile", /* controller里,执行上传视频的action名称 */
    "fileFieldName": "upfile", /* 提交的文件表单名称 */
    "filePathFormat": "/ueditor/php/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "fileUrlPrefix": "", /* 文件访问路径前缀 */
    "fileMaxSize": 51200000, /* 上传大小限制,单位B,默认50MB */
    "fileAllowFiles": [
        ".png", ".jpg", ".jpeg", ".gif", ".bmp",
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
        ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
        ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
    ], /* 上传文件格式显示 */

    /* 列出指定目录下的图片 */
    "imageManagerActionName": "listimage", /* 执行图片管理的action名称 */
    "imageManagerListPath": "/ueditor/php/upload/image/", /* 指定要列出图片的目录 */
    "imageManagerListSize": 20, /* 每次列出文件数量 */
    "imageManagerUrlPrefix": "", /* 图片访问路径前缀 */
    "imageManagerInsertAlign": "none", /* 插入的图片浮动方式 */
    "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件类型 */

    /* 列出指定目录下的文件 */
    "fileManagerActionName": "listfile", /* 执行文件管理的action名称 */
    "fileManagerListPath": "/ueditor/php/upload/file/", /* 指定要列出文件的目录 */
    "fileManagerUrlPrefix": "", /* 文件访问路径前缀 */
    "fileManagerListSize": 20, /* 每次列出文件数量 */
    "fileManagerAllowFiles": [
        ".png", ".jpg", ".jpeg", ".gif", ".bmp",
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
        ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
        ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
    ] /* 列出的文件类型 */

}`


    if action == "config" {
        //返回配置信息
        c.String(http.StatusOK,json_str);
        return

    }else if action == "uploadimage"{

        file, err := c.FormFile("upfile")
        if err != nil {
            c.JSON(http.StatusForbidden, gin.H{
                "code":  400,
                "error": err.Error(),
            })
            return
        }

        arr := strings.Split(file.Filename, ".")
        filepath, ok := checkExtAndgetFilePath(arr[1])
        if ok != true {
            c.JSON(http.StatusForbidden, gin.H{
                "code":  400,
                "error": "invalid ext",
            })
            return
        }
        if err = c.SaveUploadedFile(file, filepath); err != nil {
            c.JSON(http.StatusForbidden, gin.H{
                "code":  400,
                "error": "upload failed",
            })
            return
        }
        file_url :=strings.Replace(filepath,"./static/uploads","/uploads",1)

        c.JSON(http.StatusOK, gin.H{
            "state":    "SUCCESS",
            "url": file_url,
            "title":   file.Filename,
            "original":file.Filename,
            "type":arr[1],
            "size":file.Size,
        })
        return
    }

}

模板文件:news_list.html

 <article class="cl pd-20">
            <div class="text-c">
                <form name="postform" method="get" action="/admin/news_list">
                <span class="select-box inline">
                <select name="cate_id" class="select">
                    <option value="">全部分类</option>
                    {{range $k,$v := .cate_list}}
                        <option value="{{$v.Id}}" {{if eq $v.Id $.cate_id}}selected{{end}}>{{$v.CateName}}</option>
                    {{end}}
                </select>
                </span>
                日期范围:
                <input type="text" onfocus="WdatePicker({maxDate:'#F{$dp.$D(\'logmax\')||\'%y-%M-%d\'}'})" id="logmin" name="start_date" value="{{.start_date}}" class="input-text Wdate" style="width:120px;">
                -
                <input type="text" onfocus="WdatePicker({minDate:'#F{$dp.$D(\'logmin\')}',maxDate:'%y-%M-%d'})" id="logmax" name="end_date" value="{{.end_date}}" class="input-text Wdate" style="width:120px;">
                <input type="text" name="news_title" id="news_title" value="{{.news_title}}" placeholder="文章标题" style="width:250px" class="input-text">
                <button name="" id="" class="btn btn-success" type="submit"><i class="Hui-iconfont">&#xe665;</i> 搜文章</button>
                </form>
            </div>
            <div class="cl pd-5 bg-1 bk-gray mt-20">
                <span class="l">
                {{ $admin_uid := GetAdminId}}

                <a class="btn btn-primary radius" data-title="添加文章" {{if has_powa $admin_uid "/admin/news_add"}} style="display:none" {{end}}  onclick="article_add('添加文章','/admin/news_add')" href="javascript:;"><i class="Hui-iconfont">&#xe600;</i> 添加文章</a>
                </span>
                <span class="r">共有数据:<strong>{{.count}}</strong> 条</span>
            </div>
            <div class="mt-20">
                <table class="table table-border table-bordered table-bg table-hover table-sort">
                    <thead>
                    <tr class="text-c">
                        <th width="25"><input type="checkbox" name="" value=""></th>
                        <th width="80">ID</th>
                        <th>标题</th>
                        <th width="120">封面图</th>
                        <th width="100">文章分类</th>
                        <th width="100">是否显示</th>
                        <th width="75">浏览次数</th>
                        <th width="120">添加时间</th>
                        <th width="120">操作</th>
                    </tr>
                    </thead>
                    <tbody>
                    {{range $k,$v := .list }}
                    <tr class="text-c">
                        <td><input type="checkbox" value="" name=""></td>
                        <td>{{$v.Id}}</td>
                        <td class="text-l"><u style="cursor:pointer" class="text-primary" onClick="article_edit('查看','/admin/news_add','{{$v.Id}}')" title="查看">{{$v.NewsTitle}}</u></td>
                        <td><img src="{{$v.NewsPic}}" width="110"></td>
                        <td>{{$v.CateName}}</td>
                        <td class="td-status">
                            {{if eq $v.IsShow 1}}
                            <span class="label label-success radius">显示</span>
                            {{else}}
                            <span class="label label-info radius">隐藏</span>
                            {{end}}

                        </td>
                        <td>{{$v.NewsReads}}</td>
                        <td>{{$v.AddDatetime}}</td>
                        <td class="f-14 td-manage">
                            <a  class="ml-5"   {{if has_powa $admin_uid "/admin/news_add"}} style="display:none" {{end}} onClick="article_edit('资讯编辑','/admin/news_add','{{$v.Id}}')" href="javascript:;" title="编辑"><i class="Hui-iconfont">&#xe6df;</i></a>
                            <a  class="ml-5"  {{if has_powa $admin_uid "/admin/news_del"}} style="display:none" {{end}} onClick="article_del(this,'{{$v.Id}}')" href="javascript:;" title="删除"><i class="Hui-iconfont">&#xe6e2;</i></a></td>
                    </tr>
                    {{end}}

                    </tbody>
                </table>
            </div>
        </article>

<script type="text/javascript">
    $('.table-sort').dataTable({
        "aaSorting": [[ 1, "desc" ]],//默认第几个排序
        "bStateSave": true,//状态保存
        "aoColumnDefs": [
            //{"bVisible": true, "aTargets": [ 3,4,5 ]} ,//控制列的隐藏显示
            {"orderable":false,"aTargets":[0,8]}// 不参与排序的列
        ]
    });

    /*资讯-添加*/
    function article_add(title,url,w,h){
        var index = layer.open({
            type: 2,
            title: title,
            content: url
        });
        layer.full(index);
    }
    /*资讯-编辑*/
    function article_edit(title,url,id,w,h){
        var index = layer.open({
            type: 2,
            title: title,
            content: url+"?news_id="+id
        });
        layer.full(index);
    }
    /*资讯-删除*/
    function article_del(obj,id){
        layer.confirm('确认要删除吗?',function(index){
            $.ajax({
                type: 'GET',
                url: '/admin/news_del?news_id='+id,
                dataType: 'json',
                success: function(data){
                    if (data.code == 0){
                        $(obj).parents("tr").remove();
                        layer.msg('已删除!',{icon:1,time:1000});
                    }else{
                        layer.msg(data.msg);
                    }
                },
                error:function(data) {
                    console.log(data.msg);
                },
            });
        });
    }

</script>

模板文件:news_edit.html

<article class="page-container">
  <form class="form form-horizontal" id="form-article-add" method="post" action="/admin/news_save">
    <div class="row cl">
      <label class="form-label col-xs-4 col-sm-2"><span class="c-red">*</span>文章标题:</label>
      <div class="formControls col-xs-8 col-sm-9">
        <input type="text" class="input-text" value="{{.news.NewsTitle}}" placeholder="" id="news_title" name="news_title">
      </div>
    </div>

    <div class="row cl">
      <label class="form-label col-xs-4 col-sm-2"><span class="c-red">*</span>文章栏目:</label>
      <div class="formControls col-xs-8 col-sm-9"> <span class="select-box">
                <select name="cate_id" class="select">
                    <option value="0">全部栏目</option>
                    {{range $k,$v := .cate_list}}
                        <option value="{{$v.Id}}" {{if eq $v.Id $.news.CateId}}selected{{end}}>{{$v.CateName}}</option>
                    {{end}}
                </select>
                </span> </div>
    </div>

    <div class="row cl">
      <label class="form-label col-xs-4 col-sm-2">浏览量:</label>
      <div class="formControls col-xs-8 col-sm-9">
        <input type="text" class="input-text" value="{{.news.NewsReads}}" placeholder="" id="news_reads" name="news_reads">
      </div>
    </div>

    <div class="row cl">
      <label class="form-label col-xs-4 col-sm-2">文章摘要:</label>
      <div class="formControls col-xs-8 col-sm-9">
        <textarea name="news_desc" cols="" rows="" class="textarea"  placeholder="说点什么...最少输入10个字符" datatype="*10-100" dragonfly="true" nullmsg="备注不能为空!" onKeyUp="textarealength(this,200)">{{.news.NewsDesc}}</textarea>
        <p class="textarea-numberbar"><em class="textarea-length">0</em>/200</p>
      </div>
    </div>

    <div class="row cl">
      <label class="form-label col-xs-4 col-sm-2">是否显示:</label>
      <div class="formControls col-xs-8 col-sm-9 skin-minimal">
        <div class="radio-box">
          <input name="is_show" type="radio" id="is_show-1" value="1" {{if eq .news.IsShow 1 }}checked{{end}} {{if not .news.IsShow}}checked{{end}}>
          <label for="is_show-1">显示</label>
        </div>
        <div class="radio-box">
          <input type="radio" id="is_show-2" name="is_show" value="2" {{if eq .news.IsShow 2 }}checked{{end}}>
          <label for="is_show-2">隐藏</label>
        </div>
      </div>
    </div>
    <div class="row cl">
      <label class="form-label col-xs-4 col-sm-2">是否推荐:</label>
      <div class="formControls col-xs-8 col-sm-9 skin-minimal">
        <div class="radio-box">
          <input name="is_recommed" type="radio" id="is_recommed-1" value="1" {{if eq .news.IsRecommed 1 }}checked{{end}} {{if not .news.IsRecommed}}checked{{end}}>
          <label for="is_recommed-1">正常</label>
        </div>
        <div class="radio-box">
          <input type="radio" id="is_recommed-2" name="is_recommed" value="2" {{if eq .news.IsRecommed 2 }}checked{{end}}>
          <label for="is_recommed-2">推荐</label>
        </div>
      </div>
    </div>
    <div class="row cl">
      <label class="form-label col-xs-4 col-sm-2">是否删除:</label>
      <div class="formControls col-xs-8 col-sm-9 skin-minimal">
        <div class="radio-box">
          <input name="is_del" type="radio" id="is_del-1" value="1" {{if eq .news.IsDel 1 }}checked{{end}} {{if not .news.IsDel}}checked{{end}}>
          <label for="is_del-1">正常</label>
        </div>
        <div class="radio-box">
          <input type="radio" id="is_del-2" name="is_del" value="2" {{if eq .news.IsDel 2 }}checked{{end}}>
          <label for="is_del-2">删除</label>
        </div>
      </div>
    </div>


    <div class="row cl">
      <label class="form-label col-xs-4 col-sm-2">缩略图:</label>
      <div class="formControls col-xs-8 col-sm-9">
        <div class="uploader-thum-container">
          <div id="fileList" class="uploader-list">
            {{if .news.NewsPic}}
            <div id="WU_FILE_0" class="item upload-state-success"><div class="pic-box"><img src="{{.news.NewsPic}}" style="height: 100px"></div><div class="info">{{.news.NewsPic}}</div><p class="state">已上传</p><div class="progress-box" style="display: none;"><span class="progress-bar radius"><span class="sr-only" style="width: 100%;"></span></span></div></div>
            {{end}}

          </div>
          <div id="filePicker">选择图片</div>
          <button id="btn-star" class="btn btn-default btn-uploadstar radius ml-10">开始上传</button>
          <input type="hidden" name="news_pic" id="news_pic" value="{{.news.NewsPic}}">
        </div>
      </div>
    </div>
    <div class="row cl">
      <label class="form-label col-xs-4 col-sm-2">文章内容:</label>
      <div class="formControls col-xs-8 col-sm-9">
        <script id="editor" type="text/plain" style="width:100%;height:400px;"></script>
        <input type="hidden" name="news_content" id="news_content">
        <input type="hidden" name="id" id="id" value="{{.news.Id}}">

      </div>
    </div>
    <div class="row cl">
      <div class="col-xs-8 col-sm-9 col-xs-offset-4 col-sm-offset-2">
        <button  class="btn btn-primary radius" type="submit"><i class="Hui-iconfont">&#xe632;</i> 提交</button>
        <button onClick="removeIframe();" class="btn btn-default radius" type="button">&nbsp;&nbsp;取消&nbsp;&nbsp;</button>
      </div>
    </div>
  </form>
</article>

<script 
type="text/javascript" src="/static/h-ui.lib/webuploader/0.1.5/webuploader.min.js"></script>
<script type="text/javascript" src="/static/h-ui.lib/ueditor/1.4.3/ueditor.config.js"></script>
<script type="text/javascript" src="/static/h-ui.lib/ueditor/1.4.3/ueditor.all.min.js"> </script>
<script type="text/javascript" src="/static/h-ui.lib/ueditor/1.4.3/lang/zh-cn/zh-cn.js"></script>
<script type="text/javascript">

  var ue = UE.getEditor('editor');
  ue.ready(function (){
    //设置内容
    UE.getEditor('editor').setContent({{.news.NewsContent}})
  })
  $(function(){
    $('.skin-minimal input').iCheck({
      checkboxClass: 'icheckbox-blue',
      radioClass: 'iradio-blue',
      increaseArea: '20%'
    });


    $list = $("#fileList"),
            $btn = $("#btn-star"),
            state = "pending",
            uploader;

    var uploader = WebUploader.create({
      auto: true,
      swf: '/static/h-ui.lib/webuploader/0.1.5/Uploader.swf',

      // 文件接收服务端。
      server: '/admin/fileupload',

      // 选择文件的按钮。可选。
      // 内部根据当前运行是创建,可能是input元素,也可能是flash.
      pick: '#filePicker',

      // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
      resize: false,
      // 只允许选择图片文件。
      accept: {
        title: 'Images',
        extensions: 'gif,jpg,jpeg,bmp,png',
        mimeTypes: 'image/*'
      }
    });
    uploader.on( 'fileQueued', function( file ) {
      var $li = $(
                      '<div id="' + file.id + '" class="item">' +
                      '<div class="pic-box"><img></div>'+
                      '<div class="info">' + file.name + '</div>' +
                      '<p class="state">等待上传...</p>'+
                      '</div>'
              ),
              $img = $li.find('img');
      $list.append( $li );

      // 创建缩略图
      // 如果为非图片文件,可以不用调用此方法。
      //thumbnailWidth x thumbnailHeight 为 100 x 100

      uploader.makeThumb( file, function( error, src ) {
        if ( error ) {
          $img.replaceWith('<span>不能预览</span>');
          return;
        }
        //缩略图尺寸
        $img.attr( 'src', src );
      }, 100, 100 );
    });
    // 文件上传过程中创建进度条实时显示。
    uploader.on( 'uploadProgress', function( file, percentage ) {
      var $li = $( '#'+file.id ),
              $percent = $li.find('.progress-box .sr-only');

      // 避免重复创建
      if ( !$percent.length ) {
        $percent = $('<div class="progress-box"><span class="progress-bar radius"><span class="sr-only" style="width:0%"></span></span></div>').appendTo( $li ).find('.sr-only');
      }
      $li.find(".state").text("上传中");
      $percent.css( 'width', percentage * 100 + '%' );
    });

    // 文件上传成功,给item添加成功class, 用样式标记上传成功。
    uploader.on( 'uploadSuccess', function( file ,res) {

      $("#news_pic").val(res.img_url)

      $( '#'+file.id ).addClass('upload-state-success').find(".state").text("已上传");
    });

    // 文件上传失败,显示上传出错。
    uploader.on( 'uploadError', function( file ) {
      $( '#'+file.id ).addClass('upload-state-error').find(".state").text("上传出错");
    });

    // 完成上传完了,成功或者失败,先删除进度条。
    uploader.on( 'uploadComplete', function( file ) {
      $( '#'+file.id ).find('.progress-box').fadeOut();
    });
    uploader.on('all', function (type) {
      if (type === 'startUpload') {
        state = 'uploading';
      } else if (type === 'stopUpload') {
        state = 'paused';
      } else if (type === 'uploadFinished') {
        state = 'done';
      }

      if (state === 'uploading') {
        $btn.text('暂停上传');
      } else {
        $btn.text('开始上传');
      }
    });

    $btn.on('click', function () {
      if (state === 'uploading') {
        uploader.stop();
      } else {
        uploader.upload();
      }
    });

    $("#form-article-add").validate({
      rules:{
        menu_name:{
          required:true,
          minlength:2,
          maxlength:16
        },
      },
      onkeyup:false,
      focusCleanup:true,
      success:"valid",
      submitHandler:function(form){

        $("#news_content").val(ue.getContent())

        $(form).ajaxSubmit(function (data){
          if(data.code == 0){
            var index = parent.layer.getFrameIndex(window.name);
            parent.window.location.reload();
            parent.layer.close(index);
          }else{
            layer.alert(data.msg)
          }
        });
      }
    });

  });
</script>