`
webdev2014
  • 浏览: 679401 次
文章分类
社区版块
存档分类
最新评论

CMS之图片管理(5)

 
阅读更多

现在,图片管理就剩上传文件功能没有完成了。这需要用到swfupload,在《CMS之图片管理(1)》中有它的下载地址和加入项目的说明。

使用swfupload最麻烦的地方是要有一个HTML元素让它嵌入加载Flash的HTML代码,而且这个HTML元素必须覆盖住Flash来实现功能,这个有点类似做单按钮的上传按钮。

现在,先为swfupload生成一个HTML元素来实现它的功能。实现方法是在显示图片的视图底部添加一个工具栏,然后将工具栏分成两部分,第一部分显示一个SPAN元素,第二部分显示一个进度条来指示上传进度。

在PicManager.js文件中,找到me.items这句代码,在它上面创建一个进度条,代码如下:

me.progress=Ext.widget("progressbar",{text:"上传进度",flex:1});

因为在swfupload的处理方法中还要直接调用进度条,因而这里将它绑定到progress属性,会方便很多。因为水平工具栏默认是使用HBox布局的,因而在进度条上设置flex为1,就会让它占满整工具栏余下的宽度。

接着在图片文件的面板内添加一个dockedItems配置项,在面板底部放置一个工具栏,并在工具栏上放置一个SPAN元素和进度条,代码如下:

dockedItems: [

{ xtype:"toolbar", dock: "bottom",

items: [

{ xtype: "tbtext", text:"<span></span>", width: 70 },

me.progress

]

}

]

代码中,使用了一个TextItem来显示SPAN元素,宽度为70像素。

现在,要解决的是SPAN的id问题,这也是swfupload的要求,它需要根据该id来获取元素。如果统一一个id,那就会有冲突,因而必须想办法设置成不同的id,这个就需要用Ext的id方法,它看返回一个唯一的id。

在创建进度条的代码下添加以下代码获取一个id:

me.spanid = Ext.id();

修改一下SPAN元素的代码,为它加上id,代码如下:

"<span id='" + me.spanid +"'></span>"

现在要做的是监听扩展的afterrender事件,在callParent代码之前添加以下代码:

me.on("afterrender",me.onAfterRender);

接着要完成的就是onAfterRender方法了,在该方法内,主要工作是完成swfupload的初始化操作,代码如下:

onAfterRender: function(){

var me =this;

me.swfu= new SWFUpload({

upload_url: "/File/Upload",

file_size_limit: "10 MB",

file_types:"*.jpg;*.png;*.gif;*.bmp;",

file_types_description: "图片文件",

file_upload_limit: 100,

file_queue_limit: 0,

file_post_name: "Filedata",

swfupload_preload_handler: me.UploadPreLoad,

swfupload_load_failed_handler: me.UploadLoadFailed,

swfupload_loaded_handler: me.UploadLoaded,

file_queued_handler: me.fileQueued,

file_queue_error_handler: me.fileQueueError,

file_dialog_complete_handler: me.fileDialogComplete,

upload_start_handler: me.uploadStart,

upload_progress_handler: me.uploadProgress,

upload_error_handler: me.uploadError,

upload_success_handler: me.uploadSuccess,

upload_complete_handler: me.uploadComplete,

queue_complete_handler: me.queueComplete,

//Button settings

button_window_mode: SWFUpload.WINDOW_MODE.TRANSPARENT,

button_image_url: '',

button_placeholder_id: me.spanid,

button_width: 60,

button_height: 20,

button_text: '上传图片',

button_text_style: '',

button_text_top_padding: 0,

button_text_left_padding: 0,

//Flash Settings

flash_url: "Scripts/swfupload/swfupload.swf", // Relative tothis file

flash9_url: "Scripts/swfupload/swfupload_FP9.swf", // Relativeto this file

custom_settings: { scope: me },

//Debug Settings

debug: false

});

}

以下是swfupload的配置项的说明:

q upload_url:上传文件的地址,代码中是File控制器的Upload方法。

q file_size_limit:限制上传文件的大小,代码中限制了只能上传小于10M的文件。

q file_types:允许上传的文件类型,代码中允许的类型是jpg、png、gif和bmp格式的文件。

q file_types_description:这个是显示在文件选择对话框中的描述。

q file_upload_limit:一次允许上传的文件数量,这里设置一次最多只能上传100个文件。

q file_queue_limit:文件队列的限制,这里设置为0表示没有限制。

q file_post_name:文件提交后,服务器端可根据该参数获取文件。

q swfupload_preload_handler:监听预加载事件。

q swfupload_load_failed_handler:监听上传失败事件。

q swfupload_loaded_handler:监听上传成功事件。

q file_queued_handler:监听上传队列事件。

q file_queue_error_handler:监听队列错误事件。

q file_dialog_complete_handler:监听文件选择对话框关闭事件。

q upload_start_handler:监听开始上传事件。

q upload_progress_handler:监听上传进度事件。

q upload_error_handler:监听上传错误事件。

q upload_success_handler:监听上传成功事件。

q upload_complete_handler:监听上传完成事件。

q queue_complete_handler:监听上传队列完成事件。

q button_window_mode:按钮的样式,这里设置了窗口系统模式。

q button_image_url:按钮图片的路径,因为没有,所以设置了为空。

q button_placeholder_id:就是SPAN元素的id了。

q button_width:按钮的宽度,要比TextItem小点。

q button_height:按钮的高度。

q button_text:按钮显示的文本,这里要显示的是“上传图片”。

q button_text_style:按钮文本的样式,这里不需要。

q button_text_top_padding:按钮文本的顶部内补丁。

q button_text_left_padding:按钮文本的左边内补丁。

q flash_url:flash文件所在的路径。

q flash9_url:flash 9版本的flash文件所在路径。

q custom_settings:自定义配置,这里一定要添加scope配置项,且值为me,这样就可在swfupload的事件内找到扩展自身,从而使用扩展的属性和方法。

q debug:是否开启调试模式,false表示不开启。

现在要完成的就是swfupload的监听事件了,这个基本可从swfupload包中的示例代码复制过来,具体代码如下:

UploadPreLoad:function(){

},

UploadLoadFailed:function(){

},

UploadLoaded:function(){

},

fileQueued:function(){

},

fileQueueError:function(file,errorCode, message){

try{

vardlg=Ext.Msg.alert;

if(errorCode === SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED) {

dlg("选择的文件太多。\n一次最多上传100个文件,而你选择了" +message + "个文件。");

return;

}

switch(errorCode) {

caseSWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:

dlg("文件超过了10M.");

this.debug("错误代码: File too big, File name: " +file.name + ", File size: " + file.size + ", Message: " +message);

break;

caseSWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:

dlg("不允许上传0字节文件。");

this.debug("ErrorCode: Zero byte file, File name: " + file.name + ", File size: "+ file.size + ", Message: " + message);

break;

caseSWFUpload.QUEUE_ERROR.INVALID_FILETYPE:

dlg("非法的文件类型。");

this.debug("ErrorCode: Invalid File Type, File name: " + file.name + ", File size:" + file.size + ", Message: " + message);

break;

default:

if(file !== null) {

dlg("未知错误。");

}

this.debug("ErrorCode: " + errorCode + ", File name: " + file.name + ", Filesize: " + file.size + ", Message: " + message);

break;

}

}catch (ex) {

this.debug(ex);

}

},

fileDialogComplete:function(numFilesSelected,numFilesQueued){

try {

if(numFilesQueued > 0) {

varme=this.customSettings.scope,sels=me.tree.getSelectionModel().getSelection(),path="/";

if(sels.length>0){

path=sels[0].data.id;

SimpleCMS.postParams.path=path;

this.setPostParams(SimpleCMS.postParams);

this.startUpload();

}

else{

Ext.Msg.alert("请先选择文件夹。");

}

}

}catch (ex) {

this.debug(ex);

}

},

uploadStart:function(file){

try{

varme=this.customSettings.scope;

me.progress.updateProgress(0);

me.progress.updateText("正在上传文件"+file.name+"...");

}

catch(ex) {}

returntrue;

},

uploadProgress:function(file,bytesLoaded, bytesTotal){

try{

varpercent = bytesLoaded / bytesTotal;

varme=this.customSettings.scope;

me.progress.updateProgress(percent);

me.progress.updateText("正在上传文件"+file.name+"...");

}catch (ex) {

this.debug(ex);

}

},

uploadError:function(file,errorCode, message){

try{

varme=this.customSettings.scope;

me.progress.updateText("正在上传文件"+file.name+"...");

switch (errorCode) {

caseSWFUpload.UPLOAD_ERROR.HTTP_ERROR:

me.progress.updateText("上传错误:" + message);

this.debug("ErrorCode: HTTP Error, File name: " + file.name + ", Message: " +message);

break;

caseSWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:

me.progress.updateText("上传失败。");

this.debug("ErrorCode: Upload Failed, File name: " + file.name + ", File size: "+ file.size + ", Message: " + message);

break;

caseSWFUpload.UPLOAD_ERROR.IO_ERROR:

me.progress.updateText("Server(IO) 错误");

this.debug("ErrorCode: IO Error, File name: " + file.name + ", Message: " +message);

break;

caseSWFUpload.UPLOAD_ERROR.SECURITY_ERROR:

me.progress.updateText("安全错误");

this.debug("ErrorCode: Security Error, File name: " + file.name + ", Message: " +message);

break;

caseSWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:

me.progress.updateText("文件大小超出限制。");

this.debug("ErrorCode: Upload Limit Exceeded, File name: " + file.name + ", File size:" + file.size + ", Message: " + message);

break;

caseSWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED:

me.progress.updateText("验证失败。");

this.debug("ErrorCode: File Validation Failed, File name: " + file.name + ", Filesize: " + file.size + ", Message: " + message);

break;

caseSWFUpload.UPLOAD_ERROR.FILE_CANCELLED:

break;

caseSWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:

me.progress.updateText("停止");

break;

default:

me.progress.updateText("未知错误:" + errorCode);

this.debug("ErrorCode: " + errorCode + ", File name: " + file.name + ", Filesize: " + file.size + ", Message: " + message);

break;

}

}catch (ex) {

this.debug(ex);

}

},

uploadSuccess:function(file,serverData){

try{

varme=this.customSettings.scope;

me.progress.updateProgress(1);

me.progress.updateText(serverData);

}catch (ex) {

this.debug(ex);

}

},

uploadComplete:function(file){

try {

if(this.getStats().files_queued > 0) {

this.startUpload();

}else {

varme=this.customSettings.scope;

me.progress.updateProgress(1);

me.progress.updateText("所有文件已上传。");

me.filestore.load();

}

} catch(ex) {

this.debug(ex);

}

},

queueComplete:function(numFilesUploaded){

varme=this.customSettings.scope;

me.progress.updateProgress(1);

me.progress.updateText("已上传"+ numFilesUploaded + "个文件");

if(numFilesUploaded>0){

me.filestore.load();

}

}

代码中UploadPreLoad、UploadLoadFailed、UploadLoaded和fileQueued么有使用到,其实可以在配置中去掉,在这里写出来是为了说明一下。要具体了解清楚这些事件,可仔细阅读一下swfupload的API文档。

先来看看fileQueueError方法,该方法会在队列出现出错时触发。代码中,涉及dlg的代码是提示给用户看的,debug则是在开启了调试模式时使用的。

方法fileDialogComplete会在文件选择对话框关闭后触发,在这里就意味着开始上传文件了,因而,当检测到队列中有文件(numFilesQueued大于0),就从customSettings中获取扩展自身,然后从树中获取选择模型,看是否有选择节点,如果有,就把选择节点(目录)作为上传路径,否则,提示用户选择一个节点(目录)。

在这里一定会很奇怪,为什么会有一个SimpleCMS. postParams的东西,它有什么用?这主要是验证问题,因为Flash上传并不会把当前页面的验证作为其验证,因而要在服务器端验证上传文件的用户是否已经登录且符合权限要求,就要求通过添加验证方式办法来实现,它的具体代码如下:

SimpleCMS.postParams = {

path:null,

"ASPSESSID": "@Session.SessionID",

"AUTHID": "@Request.Cookies[FormsAuthentication.FormsCookieName].Value"

};

代码中,path是用来设置上传路径的,后面两项就是用来填写验证信息用的。笔者在第一次做这个的时候,上传老是不成功,然后在调试模式下(设置debug为true),看到的提示是权限不足,奇怪了,然后google一下,发现原来Flash上传文件的验证信息不能和页面的同步,要加这两个东西来实现。

要完成这个,还要打开Global.asax文件,在里面加入以下代码:

protected void Application_BeginRequest()

{

varRequest = HttpContext.Current.Request;

varResponse = HttpContext.Current.Response;

try

{

string session_param_name = "ASPSESSID";

string session_cookie_name = "ASP.NET_SESSIONID";

if(HttpContext.Current.Request.Form[session_param_name] != null)

{

UpdateCookie(session_cookie_name,HttpContext.Current.Request.Form[session_param_name]);

}

elseif (HttpContext.Current.Request.QueryString[session_param_name] != null)

{

UpdateCookie(session_cookie_name,HttpContext.Current.Request.QueryString[session_param_name]);

}

string auth_param_name = "AUTHID";

string auth_cookie_name = FormsAuthentication.FormsCookieName;

if(HttpContext.Current.Request.Form[auth_param_name] != null)

{

UpdateCookie(auth_cookie_name,HttpContext.Current.Request.Form[auth_param_name]);

}

elseif (HttpContext.Current.Request.QueryString[auth_param_name] != null)

{

UpdateCookie(auth_cookie_name,HttpContext.Current.Request.QueryString[auth_param_name]);

}

}

catch(Exception e)

{

Response.StatusCode = 500;

Response.Write("Error Initializing Session");

}

}

private static void UpdateCookie(stringcookie_name, string cookie_value)

{

HttpCookie cookie =HttpContext.Current.Request.Cookies.Get(cookie_name);

if(cookie == null)

{

cookie = new HttpCookie(cookie_name);

//SWFUpload 的Demo中给的代码有问题,需要加上cookie.Expires 设置才可以

cookie.Expires = DateTime.Now.AddYears(1);

HttpContext.Current.Request.Cookies.Add(cookie);

}

cookie.Value = cookie_value;

HttpContext.Current.Request.Cookies.Set(cookie);

}

其实这代码,在swfupload的示例中也是有的,只是笔者没留意。

回到fileDialogComplete方法,调用swfupload的setPostParams方法就可将参数复制到swfupload中了,然后调用startUpload方法就可以开始上传文件了。

方法uploadStart会在文件开始上传的时候执行,在这里要做的就是更新进度条了。(这里说明一下,swfupload是一个个文件传的,并不是一次把所有文件都传过去的)。

方法uploadProgress就是用来更新进度的,主要功能就是更新进度条了。

方法uploadError是用来显示上传错误的,复制过来根据自己想法修改提示方式就行了。

方法uploadSuccess会在一个文件上传成功后执行,这里要做的就是将进度条显示到100%,并显示服务器端返回的信息。

文件上传完也会执行uploadComplete方法,在这里可检查队列中是是否还有文件,如果有,就调用startUpload继续上传,如果没有,则更新进度条显示,说明文件已经全部上传完毕。

队列中的文件都上传后会执行queueComplete方法,这个和uploadComplete方法检查队列中没有文件后的处理有点重叠,看你怎么取舍了。

最后,别忘了在Index.html加入加载swfupload.js的代码,代码如下:

@if (Request.IsAuthenticated)

{

<script type="text/javascript"src="@Url.Content("Scripts/swfupload/swfupload.js")"></script>

}

这个脚本只有在登录后才会加载。

现在切换到File控制器,完成Upload方法,这个不难,就是接收一个文件,然后保存而已,代码如下:

[AjaxAuthorize(Roles = "普通用户,系统管理员")]

public string Upload()

{

stringpath = Request["path"] ?? "";

string[]filetypes = { "jpg", "gif", "png","bmp" };

stringdir = Server.MapPath(root + path);

if(Directory.Exists(dir))

{

HttpPostedFileBase file = Request.Files["Filedata"];

string filename = file.FileName.ToLower();

string extname = filename.Substring(filename.LastIndexOf(".")+ 1, 3);

if(file.ContentLength <= 0)

{

return "不允许上传0字节文件。";

}

elseif (file.ContentLength > 10485760)

{

return "文件超过了10M。";

}

elseif (!filetypes.Contains(extname))

{

return "文件类型错误。" + extname;

}

else

{

try

{

file.SaveAs(dir + "\\" + filename);

return "文件已上传。" + dir + "\\" + newfilename;

}

catch (Exception e)

{

return e.Message;

}

}

}

else

{

return "保存目录不存在或已被删除。";

}

}

代码没有对重名文件做检查,这个有需要可以自己加上去。

现在可以测试一下了。生成解决方案后,在浏览器打开首页,将看到如图38所示的效果,在视图底部已经有了一个上传图片按钮(实际效果不像按钮,如果想类似按钮,最好是做一下图片)和进度条了。切换到目录1,然后单击上传图片按钮,上传一下图片后将看到如图39所示的效果。

图38 添加了上传图片按钮和进度条的图片管理界面


图39 上传文件后的显示


最后讨论一下扩展的Store问题,如果想所有的扩展都共享一个TreeStore和视图的Store,可以把它们独立出来,写到App的Store目录里,这样就可共享了。这还是个人喜好问题。


至此,图片管理的功能就完成了,余下就是文章管理的功能了。


源代码:http://vdisk.weibo.com/s/hcL2Y

分享到:
评论

相关推荐

    CMS之图片管理

    SimpleCMS-2012-11-3.rar

    图片CMS管理系统_图片动画网站.rar

    图片CMS管理系统_图片动画网站

    PIC CMS图片网站管理系统 v1.2.ZIP

    原PicCMS图片管理系统是原PicCMS开发团队在2012年开发之作(MyPic开发团队三年后回归之作),但是不幸的是原PicCMS开发团队在发布V1.1之后在此销声匿迹,如同当年的MYPIC一样,短暂的璀璨却留下了无限的期盼、遗憾和...

    X6CMS网站内容管理系统 v2.2.rar

    X6CMS:全称小六网站内容管理系统。X6CMS是一个功能完善的营销型网站管理平台,...内容管理:栏目管理、文章管理、单页面管理、图片管理 模块管理:友情链接、碎片管理、导航设置 站点配置:站点配置、伪静态配置

    asp.net奥硕图王CMS管理系统v1.3

    奥硕图王CMS管里系统致力于打造专业级海量图片管理系统,为此专门开发了图王采集器,支持多线程,多图片尺寸,多线程图片下载等。 奥硕图王CMS管里系统功能简介: 1、缩略水印设置2、JS动态菜单3、扩展标签4、扩展...

    CMS 网站管理系统 源码

    5 、支持多级管理权限控制,让网站多人维护更轻松 系统支持设置栏目管理员管理员,同时还可以根据需求分配不同的权限给他们进行管理,帮助用户轻松实现网站多人维护。 6、多重安全机制和权限控制,为网站安全保驾...

    cms内容管理系统V1.0Beta版源码

    cms集文章、图片、分类信息、商城、广告系统、个人/企业空间、友情链接、公告、调查等10多个功能模块于一身,易用、扩展性强的ASP.NET开源网站管理软件,还可以和国内知名论坛及有API接口的各大系统进行完美整合,...

    TUTUCMS图片网站管理系统 v2.3 图片网站源码

    (TUTUCMS)图片管理系统 安装说明: 1. 服务器 Apache、Nginx、IIS 等 2. 推荐:php 5.2----PHP5.3 3. 推荐:MySQL 5.0 及以上 TUTUCMS图片网站管理系统流程操作: 1. 上传 程序文件 目录中的所有文件到服务器 2. ...

    LvyeCms(旅烨cms)内容管理系统 v3.1.zip

    LvyeCms(旅烨cms)是基于ThinkPHP 3.2.x开发的php内容管理系统,从第一版发布(2012/5/17)至今,已经经历了蛮多个版本! LvyeCms(旅烨cms)内容管理系统特性介绍: 基于ThinkPHP最新版本ThinkPHP 3.2.3。 模块化:...

    CMS网站管理系统(Content Management System,简称CMS)

    内容管理系统(Content Management System,简称CMS),是组织和协助共同合作的内容的结果,是指用于管理及发布内容的系统。 CMS系统重点解决的是各种非结构化或半结构化的数字资源的采集、管理、利用、传递和增值,...

    cms内容管理系统

    CMS是Content Management System的缩写,意为"内容管理系统",它具有许多基于模板的优秀设计,可以加快网站开发的速度和减少开发的成本。CMS的功能并不只限于文本处理,它也可以处理图片、Flash动画、声像流、图像...

    CMS网站管理系统 v3.0 beta utf-8

    通过模型管理,您可以基于文章系统克隆出不同的模型,使用标签+模板可扩展图片、新闻、文章、下载、Flash...等多个频道。每个模型可以自定义显示添加选项,更为强大的是,您还可以自定义字段管理,可以随时根据需要...

    CMS 内容管理系统源码

    网站内容管理系统软件(Content Manage System,简称CMS)。 您可以轻松构建从简单企业门户到行业门户的站点, 系统注重美学与人性化交互的理念,开放开源,为专业网站建设人员 或业余网站建设者提供一个真正...

    熊海CMS v1.0.rar

    熊海CMS 是由熊海开发的一款可广泛应用于个人博客,个人网站,企业网站的一套网站综合管理系统。   目前系统已经集成:代码高亮、广告模块、文件图片上传、图片水印、图片缩略图,智能头像,互动邮件通知等。部份...

    baigo CMS 内容管理系统 v2.1 bulid1215.zip

    baigo CMS 内容管理系统 v2.1 bulid1215 更新日志 创建文章时增加重复提交校验功能 增加记住登录状况功能 加强登录安全校验 baigo CMS 内容管理系统简介 baigo CMS是基于php的开源网站内容管理系统。简单、易用...

    CMS (内容管理系统)源码

    5、新闻系统: 集成新闻系统,新闻分类可以显示在树状菜单中。新闻分类管理可以在树管理中完成。您可以在定制表中自定义想要的新闻字段。 6、内容介绍: 可以对某数据表的某个字段进行单独编辑,比如一些...

    简约CMS(网站信息管理系统)

    简约CMS以信息为主题,通过以文字和图片标题为起点,以无限栏目分类为支撑,配合简单模板的灵活使用,以达到简约而不简单的效果! 全站html静态生成,可达到非常不错的seo效果! 特别注意:目前本程序只支持根...

    帝国csm图片管理库插件,后台管理所有图片,编辑文章时可以从图库里面直接选择

    帝国csm图片管理库插件,后台管理所有图片,编辑文章时可以从图库里面直接选择图片,带数据表,和使用说明,个人写的不喜勿喷;

    绵阳虹景CMS网站管理系统 10.0.rar

    绵阳虹景CMS网站管理系统 10.0 更新日志:2015.5.10更新导航二级菜单。界面整体美化。增强SEO能力。基本设置:后台可上传LOGO,修改尺寸,修改联系方式,是否开放、关闭注册。会员注册是否审核、留言是否审核等。...

Global site tag (gtag.js) - Google Analytics