Grails 显示每个内容片段的库链接

Grails 显示每个内容片段的库链接,grails,Grails,我有两个不同的域名:媒体和画廊: 它们的定义如下: 媒体 package com.twentyonecceducation class Media { String displayName String description String url Document thumbnail Document banner Document file MediaType type Date dateCreated = new Dat

我有两个不同的域名:媒体和画廊: 它们的定义如下: 媒体

package com.twentyonecceducation


class Media {

    String displayName
    String description
    String url
    Document thumbnail
    Document banner
    Document file
    MediaType type
    Date dateCreated = new Date()

    @Deprecated
    byte[] thumbnailData
    @Deprecated
    String thumbnailContentType
    @Deprecated
    String thumbnailFileName
    @Deprecated
    byte[] bannerData
    @Deprecated
    String bannerContentType
    @Deprecated
    String bannerFileName
    @Deprecated
    String fileName
    @Deprecated
    byte[] files
    @Deprecated
    String filesContentType

    static constraints = {

        files nullable: true
        filesContentType nullable: true
        displayName nullable: false
        description nullable: true
        fileName nullable: true
        url nullable: true

        thumbnailData nullable: true, display: false
        thumbnailContentType nullable: true, display: false
        thumbnailFileName nullable: true, display: false

        bannerData nullable: true, display: false
        bannerContentType nullable: true, display: false
        bannerFileName nullable: true, display: false
        type nullable: true

        file nullable: true
        thumbnail nullable: true
        banner nullable: true
    }

    static mapping = {
        files column: 'file', type: 'image'
        description type: "text"
        thumbnailData column: 'thumbnail', type: 'image'
        bannerData column: 'banner', type: 'image'
        dateCreated defaultValue: "now()"
    }

    enum MediaType {
        DOCUMENT,
        VIDEO;
    }
}
画廊

package com.twentyonecceducation


import com.twentyonecceducation.lms.moodle.Module

class Gallery {

    String name
    Double mapX
    Double mapY
    List<Game> games
    List<Media> medias
    List<Module> modules
    static hasMany = [games: Game, medias: Media, modules: Module]
    Industry fantasyMap
    Boolean isDefault = false
    String description
    String displayName

    @Deprecated
    byte[] coverImage

    @Deprecated
    String coverImageContentType
    Document coverImageFile


    static constraints = {
        name nullable: false, unique:  true
        mapX nullable: false
        mapY nullable: false
        fantasyMap nullable: true
        games display: false
        medias display: false
        modules display: false
        isDefault nullable: true
        coverImage nullable: true
        coverImageContentType nullable: true
        description nullable: true
        coverImageFile nullable: true
        displayName nullable: true
    }

    static mapping = {
        description type: "text"
        coverImage column: 'coverImage', type: "image"
    }
}
package com.twentyaneceducation
导入com.twentyonecceducation.lms.moodle.Module
班级画廊{
字符串名
双mapX
双mapY
列表游戏
列表媒体
列出模块
static hasMany=[游戏:游戏,媒体:媒体,模块:模块]
工业幻想图
布尔值isDefault=false
字符串描述
字符串显示名
@不赞成
字节[]封面图像
@不赞成
字符串coverImageContentType
文档封面图像文件
静态约束={
名称可为空:false,唯一:true
mapX可为空:false
mapY-nullable:false
fantasyMap可为空:真
游戏显示:错误
媒体显示:错误
模块显示:false
isDefault可为空:true
coverImage可为空:true
coverImageContentType可为空:true
description可为空:true
coverImageFile可为空:true
displayName可为空:true
}
静态映射={
描述类型:“文本”
封面图像列:“封面图像”,类型:“图像”
}
}
媒体控制器

package com.twentyonecceducation

import com.twentyonecceducation.security.SecRole
import grails.plugin.springsecurity.annotation.Secured
import org.springframework.core.io.Resource

@Secured([SecRole.ROLE_ADMIN])
class MediaController {


    def assetResourceLocator
    MediaService mediaService
    StorageService storageService

    static scaffold = Media

    def index(){
        log.warn("Preparing to render media")
        def mediaList = Media.list(sort:"dateCreated",order:"desc")
        def count = Media.count()
        log.warn("retrive media to render, and the total count is " + count)
        [mediaList: mediaList, mediaCount: count]
    }

    def create() {
        [media: new Media()]
    }

    def save(MediaCommand cmd) {
        if (cmd.hasErrors()) {
            render(view: 'create', model: [media: cmd])
        }
        else {
            String type = params.type
            mediaService.addNewMedia(cmd, type)
            redirect(action: 'index')
        }
    }

    @Secured([SecRole.ANONYMOUS])
    def icon(Long id) {
        Media media = Media.get(id)
        if(!media || media.file == null) {
            Resource myResource = assetResourceLocator.findResourceForURI('img_avatar.png')
            render file: myResource.inputStream?.bytes, contentType: 'image/png'
        }
        else {
            File file = storageService.getFile(media.file)
            render file: file.getBytes(), contentType: media.file.contentType
        }
    }

    @Secured([SecRole.ANONYMOUS])
    def thumbnail(Long id) {
        Media media = Media.get(id)
        if(!media || media.thumbnail == null) {
            if(media?.type?.equals(Media.MediaType.VIDEO)){
                Resource myResource = assetResourceLocator.findResourceForURI('video.png')
                render file: myResource.inputStream?.bytes, contentType: 'image/png'
            } else if(media?.type?.equals(Media.MediaType.DOCUMENT)){
                Resource myResource = assetResourceLocator.findResourceForURI('pdf.png')
                render file: myResource.inputStream?.bytes, contentType: 'image/png'
            }
        }
        else {
            File thumbnail = storageService.getFile(media.thumbnail)
            render file: thumbnail.getBytes(), contentType: media.thumbnail.contentType
        }
    }

    @Secured([SecRole.ANONYMOUS])
    def banner(Long id) {
        Media media = Media.get(id)
        if(!media || media.banner == null) {
                if(media?.type?.equals(Media.MediaType.VIDEO)) {
                    Resource myResource = assetResourceLocator.findResourceForURI('video.png')
                    render file: myResource.inputStream?.bytes, contentType: 'image/png'
                } else if(media?.type?.equals(Media.MediaType.DOCUMENT)) {
                    Resource myResource = assetResourceLocator.findResourceForURI('pdf.png')
                    render file: myResource.inputStream?.bytes, contentType: 'image/png'
                }
        }
        else {
            File banner = storageService.getFile(media.banner)
            render file: banner.getBytes(), contentType: media.bannerContentType
        }
    }

    @Secured([SecRole.ANONYMOUS])
    def downloadFile() {
        def id = params.id as Long
        if(id){
            Media media = Media.get(params.id as long)
            if(media){
                response.setContentType("application/octet-stream")
                response.setHeader("Content-disposition", "filename=${media.file.name}")
                File file = storageService.getFile(media.file)
                response.outputStream << file.getBytes()
            }
        }
    }


    @Secured([SecRole.ANONYMOUS])
    def downloadThumbnailFile() {
        def id = params.id as Long
        if(id){
            Media media = Media.get(params.id as long)
            if(media){
                response.setContentType("application/octet-stream")
                response.setHeader("Content-disposition", "filename=${media.thumbnail.name}")
                File thumbnail = storageService.getFile(media.thumbnail)
                response.outputStream << thumbnail.getBytes()
            }
        }
    }

    @Secured([SecRole.ANONYMOUS])
    def downloadBannerFile() {
        def id = params.id as Long
        if(id){
            Media media = Media.get(params.id as long)
            if(media){
                response.setContentType("application/octet-stream")
                response.setHeader("Content-disposition", "filename=${media.banner.name}")
                File thumbnail = storageService.getFile(media.banner)
                response.outputStream << thumbnail.getBytes()
            }
        }
    }

    def edit(Long id) {
        Media media = Media.get(id)
        [media: media]
    }

    def update(Long id, MediaCommand cmd) {
        if(id){
            if (cmd.hasErrors()) {
                render(view: 'edit', model: [media: cmd])
            }
            else {
                String type = params.type
                Media media = Media.get(id)
                mediaService.updateMedia(media, cmd, type)
                redirect(action: 'index')
            }
        }
    }

    def delete(Long id) {
        Media media = Media.get(id)
        mediaService.delete(media)
        redirect(action: 'show', id: id)
    }

}

package com.twentyonecceducation


import com.twentyonecceducation.lms.moodle.Module
import com.twentyonecceducation.security.SecRole
import grails.plugin.springsecurity.annotation.Secured
import org.springframework.core.io.Resource

@Secured([SecRole.ROLE_ADMIN])

class GalleryController {

    static scaffold = Gallery

    GalleryService galleryService
    StorageService storageService
    def assetResourceLocator

    def index() {
        List<Gallery> galleries = galleryService.list()
        Integer galleryCount = galleryService.count()
        respond galleries, model: [galleries: galleries,galleryCount:galleryCount]
    }
    def setAsDefaultGallery(Long id) {
        Gallery gallery = Gallery.get(id)
        galleryService.makeDefault(gallery)
        redirect action: 'index'
    }
    def create() {
        [gallery: new Gallery() ,games: Game.list()]
    }
    def show(Long id) {
        Gallery gallery = Gallery.get(id)

        [gallery: gallery]
    }

    @Secured(SecRole.ANONYMOUS)
    def image(Long id) {
        println("IMAGE")
        Gallery gallery = Gallery.get(id)
        //Cache-Control: private, max-age=<seconds>
        response.setHeader("Cache-Control", "private, max-age=86400")
        if(!gallery || gallery.coverImageFile == null) {
            Resource myResource = assetResourceLocator.findResourceForURI('placeholder_map.png')
            render file: myResource.inputStream?.bytes, contentType: 'image/png'
        } else {
            File image = storageService.getFile(gallery.coverImageFile)
            render file: image.bytes, contentType: gallery.coverImageFile.contentType
        }
    }

    def edit(Long id) {
        Gallery gallery = Gallery.get(id)

        def modules = []
        Module.list().each() { Module m ->
            if(!gallery.modules.contains(m)) {
                modules << m
            }
        }
        def games = []
        Game.list().each() { Game g ->
            if(!gallery.games.contains(g)) {
                games << g
            }
        }
        def medias = []
        Media.list().each() { Media m ->
            if(!gallery.medias.contains(m)) {
                medias << m
            }
        }
        def fantasyMaps = Industry.list()

        [gallery: gallery, modules: modules, games: games, medias:medias, fantasyMaps: fantasyMaps]
    }
    def oldedit(Long id) { //I am refactoring back to the original as this should work now that db files are being off loaded - keeping this here for now.
        //TODO - it seems that the gallery object alone is simply too big and will also need to be proxied
        def g = Gallery.executeQuery("select g.id, g.name, g.mapX, g.mapY, g.description, g.fantasyMap.id, g.coverImage, g.coverImageFile.id from Gallery g where g.id = :id", [id: id])
        def gallery = [
                id:g[0][0],
                name: g[0][1],
                mapX: g[0][2],
                mapY: g[0][3],
                description: g[0][4],
                fantasyMap: [id: g[0][5]],
                coverImage: g[0][6],
                coverImageFile: [id: g[0][7]]
            ]
        //Games in gallery
        def h = Gallery.executeQuery("select g.games from Gallery g where g.id = :id", [id: id])
        def currentGames = []
        h.each {
            currentGames << [id:it.id, name:it.name]
        }
        gallery.put('games', currentGames)
        //Media in gallery
        def m = Gallery.executeQuery("select g.medias from Gallery g where g.id = :id", [id: id])
        def currentMedia = []
        m.each {
            currentMedia << [id:it.id, displayName:it.displayName]
        }
        gallery.put('medias', currentMedia)
        //Modules in gallery
        def s = Gallery.executeQuery("select g.modules from Gallery g where g.id = :id", [id: id])
        def currentModules = []
        s.each {
            currentModules << [id:it.id, name:it.name, moodleId: it.moodleId, fullName: it.fullName]
        }
        gallery.put('modules', currentModules)

        //Building (memory)efficient list of games
        def games = []
        def x = Game.executeQuery("select g.id, g.name from Game g")
        x.each {
            games << [id:it[0], name:it[1]]
        }
        gallery.games.each() {
            games.remove([id:it.id, name:it.name])
        }

        //building (memory) efficient list of media
        def medias = []
        def y = Media.executeQuery("select m.id, m.displayName from Media m")
        y.each {
            medias << [id:it[0], name:it[1]]
        }
        gallery.medias.each() {
            medias.remove([id:it.id, name:it.displayName])
        }

        //building (memory) efficient list of media
        /*def modules = []
        def z = Module.executeQuery("select m.id, m.name, m.moodleId from Module m")
        z.each {
            modules << [id:it[0], name:it[1], nameWithId: " ${it[2]} - ${it[1]}"]
        }
        gallery.modules.each() {
            log.debug("$it")
            modules.remove([id:it.id, name:it.name, moodleId: it.moodleId])
        }*/
        def modules = []
        Module.list().each() { Module mod ->
            if(!gallery.modules.contains(mod)) {
                modules << mod
            }
        }

        def fantasyMaps = []
        def a = Industry.executeQuery("select i.id, i.fantasyMapName, i.parent.id from Industry i")
        a.each {
            String name = getFullName(it[0], a)
            fantasyMaps << [id:it[0], name:name]
        }
        [gallery: gallery, games: games, medias: medias, modules:modules, fantasyMaps: fantasyMaps]
    }

    private String getFullName(long id, List list) {
        String l = null
        list.each {
            if(it[0]==id) { //this is the correct record
                if(it[2]==null) { //it has no parents
                    l = it[1]
                } else {
                    String pops = getFullName(it[2], list)
                    l = "${pops} >> ${it[1]}"
                }
            }
        }
        return l
    }

    def update(Long id, GalleryCommand cmd) {
        log.debug("Updating gallery ${id} with ${cmd}")
        Gallery gallery = Gallery.get(id)
        galleryService.updateGallery(gallery, cmd)
        redirect(action: "show", id: gallery.id)
    }

    def save(GalleryCommand cmd) {
        println "Trying to save ${cmd} - ${cmd.errors}"
        if (cmd.hasErrors()) {
            render(view: 'create', model: [gallery: cmd])
        }
        else {
            galleryService.addNewGallery(cmd)

            redirect(action: 'index')
        }
    }

    def addGame() {
        Gallery gallery = Gallery.get(params.id as long)
        Game game = Game.get(params.game.id as long)
        galleryService.updateGameToGallery(gallery, game)
        redirect(action: "edit", id: gallery.id)
    }

    def removeGame() {
        Game game = Game.get(params.gameId as Long)
        Gallery gallery = Gallery.get(params.id as Long)
        if(game && gallery){
            galleryService.removeGame(gallery, game)
        }
        redirect(action:'edit', id:gallery.id)
    }

    def addMedia() {
        Gallery gallery = Gallery.get(params.id as long)
        Media media = Media.get(params.media.id as long)
        galleryService.updateMediaToGallery(gallery, media)
        redirect(action: "edit", id: gallery.id)
    }

    def removeMedia() {
        Media media = Media.get(params.mediaId as Long)
        Gallery gallery = Gallery.get(params.id as Long)
        if(media && gallery){
            galleryService.removeMedia(gallery, media)
        }
        redirect(action:'edit', id:gallery.id)
    }

    def moveGameDown() {
        def gameId = params.gameId as Long
        log.debug("move game down has been called with gameid : ${gameId}")

        Gallery gallery = Gallery.get(params.id as Long)
        log.debug("move game down has been called for Gallery Name : ${gallery.name}")

        Integer idx = gallery.games.indexOf(Game.findById(gameId))
        log.debug("index of game in gallery is : ${idx}")

        galleryService.moveGameDown(gallery, gameId, idx)
        log.debug("Moving game down has been done for gameid ${gameId}")
        redirect(action:'edit', id:gallery.id)
    }

    def moveGameUp() {
        def gameId = params.gameId as Long
        log.debug("move game up has been called with gameid : ${gameId}")

        Gallery gallery = Gallery.get(params.id as Long)
        log.debug("move game up has been called for Gallery Name : ${gallery.name}")

        Integer idx = gallery.games.indexOf(Game.findById(gameId))
        log.debug("index of game in gallery is : ${idx}")

        galleryService.moveGameUp(gallery, gameId, idx)
        log.debug("Moving game up has been done for gameid ${gameId}")
        redirect(action:'edit', id:gallery.id)
    }

    def moveMediaDown() {
        def mediaId = params.mediaId as Long
        log.debug("move media down has been called with mediaId : ${mediaId}")

        Gallery gallery = Gallery.get(params.id as Long)
        log.debug("move media down has been called for Gallery Name : ${gallery.name}")

        Integer idx = gallery.medias.indexOf(Media.findById(mediaId))
        log.debug("index of media in gallery is : ${idx}")

        galleryService.moveMediaDown(gallery, mediaId, idx)
        log.debug("Moving media down has been done for mediaId ${mediaId}")

        redirect(action:'edit', id:gallery.id)
    }

    def moveMediaUp() {
        def mediaId = params.mediaId as Long
        log.debug("move media up has been called with mediaId : ${mediaId}")

        Gallery gallery = Gallery.get(params.id as Long)
        log.debug("move media up has been called for Gallery Name : ${gallery.name}")

        Integer idx = gallery.medias.indexOf(Media.findById(mediaId))
        log.debug("index of media in gallery is : ${idx}")

        galleryService.moveMediaUp(gallery, mediaId, idx)
        log.debug("Moving media up has been done for mediaId ${mediaId}")

        redirect(action:'edit', id:gallery.id)
    }

    def addModule() {
        Gallery gallery = Gallery.get(params.id as long)
        Module course = Module.get(params.module.id as long)
        galleryService.updateModuleToGallery(gallery, course)
        redirect(action: "edit", id: gallery.id)
    }

    def removeModule() {
        Module course = Module.get(params.moduleId as long)
        Gallery gallery = Gallery.get(params.id as Long)
        if(course && gallery){
            galleryService.removeModule(gallery, course)
        }
        redirect(action:'edit', id:gallery.id)
    }

    def moveModuleDown() {
        def moduleId = params.moduleId as Long
        Gallery gallery = Gallery.get(params.id as Long)
        Integer idx = gallery.modules.indexOf(Module.findById(moduleId))
        galleryService.moveModuleDown(gallery, moduleId, idx)
        redirect(action:'edit', id:gallery.id)
    }

    def moveModuleUp() {
        def moduleId = params.moduleId as Long
        Gallery gallery = Gallery.get(params.id as Long)
        Integer idx = gallery.modules.indexOf(Module.findById(moduleId))
        galleryService.moveModuleUp(gallery, moduleId, idx)
        redirect(action:'edit', id:gallery.id)
    }

}

package com.twentyaneceducation
导入com.twentyonecceducation.security.SecRole
导入grails.plugin.springsecurity.annotation.securied
导入org.springframework.core.io.Resource
@安全([SecRole.ROLE\u ADMIN])
类媒体控制器{
def资源定位器
媒体服务媒体服务
存储服务存储服务
静态脚手架=介质
def索引(){
log.warn(“准备呈现媒体”)
def mediaList=Media.list(排序:“dateCreated”,顺序:“desc”)
def count=Media.count()
log.warn(“检索要渲染的媒体,总计数为”+count)
[媒体列表:媒体列表,媒体计数:计数]
}
def create(){
[媒体:新媒体()]
}
def保存(MediaCommand cmd){
if(cmd.hasErrors()){
渲染(视图:“创建”,模型:[媒体:cmd])
}
否则{
字符串类型=params.type
mediaService.addNewMedia(cmd,类型)
重定向(操作:“索引”)
}
}
@安全([SecRole.ANONYMOUS])
def图标(长id){
媒体=媒体。获取(id)
如果(!media | | media.file==null){
Resource myResource=assetResourceLocator.findResourceForURI('img_avatar.png'))
渲染文件:myResource.inputStream?.bytes,contentType:'image/png'
}
否则{
File File=storageService.getFile(media.File)
呈现文件:file.getBytes(),contentType:media.file.contentType
}
}
@安全([SecRole.ANONYMOUS])
def缩略图(长id){
媒体=媒体。获取(id)
如果(!media | | media.缩略图==null){
if(媒体?类型?等于(媒体.媒体类型.视频)){
Resource myResource=assetResourceLocator.findResourceForURI('video.png'))
渲染文件:myResource.inputStream?.bytes,contentType:'image/png'
}else if(media?type?等于(media.MediaType.DOCUMENT)){
Resource myResource=assetResourceLocator.findResourceForURI('pdf.png'))
渲染文件:myResource.inputStream?.bytes,contentType:'image/png'
}
}
否则{
文件缩略图=storageService.getFile(media.缩略图)
呈现文件:缩略图.getBytes(),contentType:media.thumbnail.contentType
}
}
@安全([SecRole.ANONYMOUS])
def横幅(长id){
媒体=媒体。获取(id)
如果(!media | | media.banner==null){
if(媒体?类型?等于(媒体.媒体类型.视频)){
Resource myResource=assetResourceLocator.findResourceForURI('video.png'))
渲染文件:myResource.inputStream?.bytes,contentType:'image/png'
}else if(media?type?等于(media.MediaType.DOCUMENT)){
Resource myResource=assetResourceLocator.findResourceForURI('pdf.png'))
渲染文件:myResource.inputStream?.bytes,contentType:'image/png'
}
}
否则{
File banner=storageService.getFile(media.banner)
呈现文件:banner.getBytes(),contentType:media.bannerContentType
}
}
@安全([SecRole.ANONYMOUS])
def下载文件(){
def id=参数id,长度为
如果(id){
Media Media=Media.get(params.id尽可能长)
if(媒体){
response.setContentType(“应用程序/八位字节流”)
response.setHeader(“内容处置”,“文件名=${media.file.name}”)
File File=storageService.getFile(media.File)
response.outputStream