AdminEAP框架-头像上传功能实现
AdminEAP为本人基于AdminLTE改造的后台管理框架,包含了基本的系统管理功能和各种交互demo,项目已经开源到Github,并部署到阿里云。Github : https://github.com/bill1012/AdminEAPAdminEAP DEMO: http://www.admineap.com本文介绍在AdminEAP框架中使用fullAvatarEditor实现用户头像上传
AdminEAP框架
1、概述
AdminEAP为本人基于AdminLTE改造的后台管理框架,包含了基本的系统管理功能和各种交互demo,项目已经开源到Github,并部署到阿里云。
Github : https://github.com/bill1012/AdminEAP
AdminEAP DEMO: http://www.admineap.com
本文介绍在AdminEAP框架中使用fullAvatarEditor实现用户头像上传的功能,代码已经在Github上。
2、实现思路
新增用户时,保存图片的id,保存用户时,将头像和用户绑定,并修改头像名称
修改时,直接绑定用户和头像,如果以前有头像,将之前的头像文件删除
3、实现代码
用户编辑界面(新增和修改共用) user_page_edit.html
<section class="content-header">
<h1>
<span>用户管理</span>
<small>新增</small>
</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-dashboard"></i> 首页</a></li>
<li><a href="#">系统管理</a></li>
<li class="active">用户管理</li>
</ol>
</section>
<section class="content">
<div class="row">
<div class="col-xs-12">
<div class="box box-info">
<form id="user-form" name="user-form" class="form-horizontal">
<input type="hidden" name="id">
<input type="hidden" name="version">
<input type="hidden" name="isSuperAdmin">
<input type="hidden" name="createDateTime" data-flag="date" data-format="yyyy-MM-dd HH:mm:ss">
<input type="hidden" name="deleted">
<input type='hidden' value='${CSRFToken}' id='csrftoken'>
<input type="hidden" id="avatarId" name="avatarId">
<div class="box-header">
<div class="col-xs-12 text-center">
<div class="avatar-container text-center">
<img src="${basePath}/resources/common/images/avatar.jpg" id="avatarImg" class="avatar-img"/>
</div>
<div>
<button type="button" class="btn btn-sm btn-camera" data-btn-type="upload" ><i class="fa fa-camera"> 上传/更改头像</i></button>
</div>
</div>
</div>
<div class="box-body">
<div class="col-md-6">
<div class="form-group">
<label for="name" class="col-sm-3 control-label">姓名</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="name" name="name" placeholder="姓名">
</div>
</div>
<div class="form-group">
<label for="birthday" class="col-sm-3 control-label">出生日期</label>
<div class="input-group date col-sm-8">
<div class="input-group-addon">
<i class="fa fa-calendar"></i>
</div>
<input type="text" class="form-control" data-flag="datepicker" data-format="yyyy-MM-dd"
id="birthday" name="birthday"
placeholder="出生日期">
</div>
</div>
<div class="form-group">
<label for="telphone" class="col-sm-3 control-label">座机</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="telphone" name="telphone" placeholder="座机">
</div>
</div>
<div class="form-group">
<label for="email" class="col-sm-3 control-label">Email</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="email" name="email" placeholder="Email">
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="col-sm-3 control-label">性别</label>
<div class="col-sm-8">
<label class="control-label"> <input type="radio" name="sex" data-flag="icheck"
class="flat-red" value="1"> 男
</label> <label class="control-label"> <input type="radio" name="sex"
data-flag="icheck" class="flat-red"
value="0"> 女
</label>
</div>
</div>
<div class="form-group">
<label for="loginName" class="col-sm-3 control-label">登录名</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="loginName" name="loginName"
placeholder="登录名">
</div>
</div>
<div class="form-group">
<label for="mobile" class="col-sm-3 control-label">手机</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="mobile" name="mobile" placeholder="手机">
</div>
</div>
<div class="form-group">
<label for="qq" class="col-sm-3 control-label">QQ</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="qq" name="qq" placeholder="QQ">
</div>
</div>
</div>
</div>
<!-- /.box-body -->
<div class="box-footer text-right">
<!--以下两种方式提交验证,根据所需选择-->
<button type="button" class="btn btn-default" data-btn-type="cancel" >取消 </button>
<button type="submit" class="btn btn-primary" data-btn-type="save">提交</button>
</div>
<!-- /.box-footer -->
</form>
</div>
</div>
</div>
</section>
</div>
<script>
//tableId,queryId,conditionContainer
var form = null;
var id = "${id?default(0)}";
$(function () {
//数据校验
$("#user-form").bootstrapValidator({
message: '请输入有效值',
feedbackIcons: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
submitHandler: function (validator, userform, submitButton) {
modals.confirm('确认保存?', function () {
//Save Data,对应'submit-提交'
var params = form.getFormSimpleData();
ajaxPost(basePath + '/user/save', params, function (data, status) {
if (data.success) {
if (id != "0") {//更新
gotolist(id);
} else {//新增
//modals.info("数据保存成功");
gotolist();
}
}
});
});
},
fields: {
name: {
validators: {
notEmpty: {
message: '请输入姓名'
}
}
},
sex: {
validators: {
notEmpty: {
message: '请选择性别'
}
}
},
birthday: {
validators: {
notEmpty: {
message: '请输入出生日期'
},
date: {
format: $(this).data("format"),
message: '请输入有效日期'
}
}
},
loginName: {
validators: {
notEmpty: {
message: '请输入登录名'
}
}
},
email: {
validators: {
notEmpty: {
message: '请输入邮件',
},
emailAddress: {
message: '非法的邮件格式',
}
}
}
}
});
//初始化控件
form = $("#user-form").form();
//回填id
if (id != "0") {
ajaxPost(basePath + "/user/get", {id: id}, function (data) {
form.initFormData(data);
$(".content-header h1 small").html("编辑用户【"+data.name+"】");
//头像回填
ajaxPost(basePath+"/user/getAvatar",{userId:id},function(result){
setAvatar(result.id,result.src,false);
})
})
}
//cancel
$("[data-btn-type='cancel']").click(function () {
gotolist();
})
$("[data-btn-type='upload']").click(function(){
uploadAvatar();
})
});
function gotolist(id){
window.loadPage(basePath+"/user/page/list?id="+id);
}
var avatarWin="avatarWin";
function uploadAvatar(){
modals.openWin({
winId:avatarWin,
title:'上传头像',
width:'700px',
url:basePath+"/user/avatar?userId="+id
});
}
function resetForm() {
form.clearForm();
$("#user-form").data('bootstrapValidator').resetForm();
}
function setAvatar(avatar_id,avatar_url,isAdd){
$("#avatarImg").attr("src",basePath+avatar_url);
//如果是新增 绑定用户
if(isAdd){
$("#avatarId").val(avatar_id);
}else{
$("#avatarId").val(null);
}
}
</script>
头像上传界面 user_avatar.html
<script type="text/javascript" src="${basePath}/resources/common/libs/avatar/swfobject.js"></script>
<script type="text/javascript" src="${basePath}/resources/common/libs/avatar/fullAvatarEditor.js"></script>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><li class="fa fa-remove"></li></button>
<h5 class="modal-title">新增用户</h5>
</div>
<div class="modal-body">
<div class="box-body">
<input type="hidden" value="${userId?default('')}" name="userId" id="userId"/>
<div style="width: 680px;height:360px;margin: 0 auto;">
<div>
<p id="swfContainer">
本组件需要安装Flash Player后才可使用,请从
<a href="http://www.adobe.com/go/getflashplayer">这里</a>下载安装。
</p>
</div>
</div>
</div>
<div class="box-footer text-right">
<button type="button" class="btn btn-info btn-sm" data-btn-type="cancel" data-dismiss="modal"><i class="fa fa-remove"> 取消</i> </button>
</div>
</div>
<script>
if (navigator.userAgent.indexOf('Firefox') >= 0){
avatarPath='';
}
swfobject.addDomLoadEvent(function () {
var swf = new fullAvatarEditor("swfContainer", {
id: 'swfUploader',
upload_url: basePath+'/file/avatarUpload?userId='+$("#userId").val(),
src_url:avatarPath,
src_upload:0,
src_size:"5MB",
avatar_sizes:"160*160",
avatar_sizes_desc:"160*160像素",
browse_tip:"仅支持JPG、JPEG、GIF、PNG格式的图片文件\n文件不能大于5MB",
src_size_over_limit:'文件大小({0})超出限制(5MB)\n请重新上传'
}, function (msg) {
switch(msg.code)
{
/**
case 1 : alert("页面成功加载了组件!");break;
case 2 : alert("已成功加载默认指定的图片到编辑面板。");break;
case 3 :
if(msg.type == 0)
{
alert("摄像头已准备就绪且用户已允许使用。");
}
else if(msg.type == 1)
{
alert("摄像头已准备就绪但用户未允许使用!");
}
else
{
alert("摄像头被占用!");
}
break;
**/
case 5 :
if(msg.type == 0)
{
var isAdd=true;
if($("#userId").val()!=''&&$("#userId").val()!='0'){
isAdd=false;
}
if(msg.content.sourceUrl)
{
modals.correct("头像已成功保存");
setAvatar(msg.content.msg,msg.content.avatarUrls[i],isAdd);
}
for(var i=0;i<msg.content.avatarUrls.length;i++){
setAvatar(msg.content.msg,msg.content.avatarUrls[i],isAdd);
}
}
else if(msg.type==1){
modals.error('头像上传失败,原因:' + msg.content.msg);
}
else if(msg.type==2){
modals.error('头像上传失败,原因:指定的上传地址不存在或有问题!');
}
else if(msg.type==3){
modals.error('头像上传失败,原因:发生了安全性错误!请联系站长添加crossdomain.xml到网站根目录。');
}
modals.hideWin("avatarWin");
break;
}
}
);
});
</script>
头像上传后台处理
@RequestMapping("/avatarUpload")
@ResponseBody
public AvatarResult avatarUpload(String userId, HttpServletRequest httpRequest, HttpSession session) throws Exception {
MultipartHttpServletRequest request = (MultipartHttpServletRequest) httpRequest;
Map<String, MultipartFile> fileMap = request.getFileMap();
String contentType = request.getContentType();
if (contentType.indexOf("multipart/form-data") >= 0) {
AvatarResult result = new AvatarResult();
result.setAvatarUrls(new ArrayList());
result.setSuccess(false);
result.setMsg("Failure!");
// 定义一个变量用以储存当前头像的序号
int avatarNumber = 1;
User user = uploaderService.get(User.class, userId);
if (user == null) {
user = new User();
user.setName("new");
}
// 文件名
String fileName = user.getName() + "_" + (new Date()).getTime() + ".jpg";
String relPath = PropertiesUtil.getValue("avatarPath");
String dirPath = request.getRealPath("/");
String initParams = "";
BufferedInputStream inputStream;
BufferedOutputStream outputStream;
for (Iterator<Map.Entry<String, MultipartFile>> it = fileMap.entrySet().iterator(); it.hasNext(); avatarNumber++) {
Map.Entry<String, MultipartFile> entry = it.next();
MultipartFile mFile = entry.getValue();
String fieldName = entry.getKey();
Boolean isSourcePic = fieldName.equals("__source"); // 是否是原始图片域名称
// 文件名,如果是本地或网络图片为原始文件名(不含扩展名)、如果是摄像头拍照则为 *FromWebcam
// String name = fileItem.getName();
// 当前头像基于原图的初始化参数(即只有上传原图时才会发送该数据),用于修改头像时保证界面的视图跟保存头像时一致,提升用户体验度。
// 修改头像时设置默认加载的原图url为当前原图url+该参数即可,可直接附加到原图url中储存,不影响图片呈现。
if (fieldName.equals("__initParams")) {
inputStream = new BufferedInputStream(mFile.getInputStream());
byte[] bytes = new byte[mFile.getInputStream().available()];
inputStream.read(bytes);
initParams = new String(bytes, "UTF-8");
inputStream.close();
} else if (isSourcePic || fieldName.startsWith("__avatar")) {
String virtualPath = dirPath + relPath + "\\" + fileName;
if (avatarNumber > 1) {
fileName = avatarNumber + fileName;
virtualPath = dirPath + relPath + "\\" + fileName;
}
// 原始图片(file 域的名称:__source,如果客户端定义可以上传的话,可在此处理)。
if (isSourcePic) {
fileName = "source" + fileName;
virtualPath = dirPath + relPath + "\\" + fileName;
result.setSourceUrl(relPath + "/" + fileName);
}
// 头像图片(file 域的名称:__avatar1,2,3...)。
else {
result.getAvatarUrls().add(relPath + "/" + fileName);
}
inputStream = new BufferedInputStream(mFile.getInputStream());
outputStream = new BufferedOutputStream(new FileOutputStream(virtualPath.replace("/", "\\")));
Streams.copy(inputStream, outputStream, true);
inputStream.close();
outputStream.flush();
outputStream.close();
// 保存图片信息
result.setMsg(uploaderService.saveAvatar(userId, fileName, relPath + File.separator + fileName, dirPath));
}
}
if (result.getSourceUrl() != null) {
result.setSourceUrl(result.getSourceUrl() + initParams);
}
result.setSuccess(true);
return result;
}
return null;
}
头像上传处理结果实体 AvatarResult.java
package com.cnpc.framework.base.pojo;
import java.util.ArrayList;
/**
* Created by billJiang on 2016/12/6.
* e-mail:jrn1012@petrochina.com.cn qq:475572229
*/
public class AvatarResult {
/**
* 表示图片是否已上传成功。
*/
private Boolean success;
/**
* 自定义的附加消息。
*/
private String msg;
/**
* 表示原始图片的保存地址。
*/
private String sourceUrl;
/**
* 表示所有头像图片的保存地址,该变量为一个数组。
*/
private ArrayList avatarUrls;
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getSourceUrl() {
return sourceUrl;
}
public void setSourceUrl(String sourceUrl) {
this.sourceUrl = sourceUrl;
}
public ArrayList getAvatarUrls() {
return avatarUrls;
}
public void setAvatarUrls(ArrayList avatarUrls) {
this.avatarUrls = avatarUrls;
}
}
头像保存 uploaderService–>saveAvatar方法
public String saveAvatar(String userId, String fileName, String filePath, String dirPath) {
UserAvatar avatar = null;
if(!StrUtil.isEmpty(userId)&&!userId.equals("0"))
avatar=userService.getAvatarByUserId(userId);
String avatar_id=avatar==null?null:avatar.getId();
//图片替换
if (avatar != null) {
File file = new File(dirPath + avatar.getSrc());
if (file.exists())
file.delete();
avatar.setName(fileName);
avatar.setSrc(filePath);
avatar.setUpdateDateTime(new Date());
this.update(avatar);
}
// 新增图片
else {
avatar = new UserAvatar();
avatar.setName(fileName);
avatar.setSrc(filePath);
avatar.setCreateDateTime(new Date());
avatar.setUserId(userId);
avatar_id=this.save(avatar).toString();
}
return avatar_id;
}
用户新增关联头像 userService–>updateUserAvatar方法
@Override
public void updateUserAvatar(User user,String dirPath) {
if(StrUtil.isEmpty(user.getAvatarId()))
return;
UserAvatar userAvatar=this.get(UserAvatar.class,user.getAvatarId());
userAvatar.setUserId(user.getId());
String src=userAvatar.getSrc();
File file = new File(dirPath +src);
String newPath=src.replaceAll("new",user.getName());
if (file.exists()) {
file.renameTo(new File(dirPath+newPath));
}
userAvatar.setSrc(newPath);
userAvatar.setName(userAvatar.getName().replaceAll("new",user.getName()));
this.update(userAvatar);
}
实现结果
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)