在这次博客中我们为用户增加头像

实现功能

  • 用户头像上传
  • 为每个用户提供三个候选头像,分别是最近两次的头像和系统默认头像

依赖的第三方工具

  • AngularJS前端框架
  • Express后端框架
  • Angular-File-upload插件
  • connect-busboy插件
  • then.js小工具
  • mongoose数据库插件

问题分析

用一个长度为3的栈来保存用户的候选头像,且栈的底部必定是系统默认头像,越新的头像就越靠近栈顶

情况分类

上传新头像

用户上传与之前上传过的同名头像怎么办?

  • 与当前头像名相同,什么都不做
  • 与备用头像名相同,当前头像入栈,删除备用头像名,当前改为上传头像名
  • 都不相同,当前头像入栈,再看长度有没有超,超了删第一号头像(默认后面的那个)
在备用头像里更换
  • 用户选择默认头像,当前也是默认,不做任何事
  • 用户选备用头像,当前是默认头像,当前头像不入栈,栈删除对应备用头像
  • 用户选默认头像,当前头像非默认,当前头像入栈,若栈长超过3,删除1号头像
  • 当前非默认头像,用户选备用头像,当前头像入栈,删除相应备用头像

页面代码

由于在我的博客中前端实战之用户控制台中有详细的页面代码这里只出示一小部分,方便大家阅读

<label class="control-label col-sm-2">
头像
</label>
<div class="avatar col-sm-2">
<img alt="用户头像" class="img-circle" ng-src="{{profile.avatar}}">
</div>
<div class="btn-group change-avatar col-sm-2">
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown">
更换头像
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li class="upload-button">
<div class="btn btn-lg btn-link upload-avatar" type="file" ng-file-select="fileSelect($files)" accept="image/*">
<span class="glyphicon glyphicon-pencil"></span>
上传头像
</div>
</li>
<li class="divider">
</li>
<li class="available-avatar">
<img ng-repeat="pic in picList" ng-src="{{pic}}" ng-click="changeAvatar(pic)">
</li>
</ul>
</div>

前端代码

angular.module('settingAPP',['myApp.Services','angularFileUpload']).controller('profileCtrl',function($rootScope,$scope,$http,$upload){
$scope.count=0;
$scope.$on('userDone',function(){
$scope.profile=document.user.profile;
$scope.picList=$scope.profile.available_avatar;
});
$scope.fileSelect=function($files){
var file=$files[0];
$scope.upload=$upload.upload({
url:'/settings/newAvatar',
file:file
}).success(function(data, status, headers, config){
if(!data.success){
if(!data.err.message) data.err.message="未知错误,稍后再试"
$rootScope.msg=data.err.message;
$rootScope.display=true;
}
else{
$scope.profile.avatar=data.avatar_path;
$scope.picList=data.list;
}
});
};
$scope.changeAvatar=function(pic){
var count,tmp;
for(var i=0;i<3;i++){
if($scope.picList[i]==pic){
count=i;
}
}
$http.post('/settings/changeAvatar',{pic:pic,num:count}).success(function(data){
if(!data.success){
if(!data.err.message) data.err.message="未知错误,稍后再试"
$rootScope.msg=data.err.message;
$rootScope.display=true;
}
else{
$scope.picList=data.list;
$scope.profile.avatar=pic;
}
}).error(function(data){
$rootScope.msg='未知错误,请重试';
$rootScope.display=true;
});
};
});

后端代码

function newAvatar(req,res){//上传新头像
var img_path;
Then(function(cont){
req.pipe(req.busboy);
req.busboy.on('file',cont);
}).fin(function(cont,fieldname,file,filename){
img_path='/img/avatar/'+req.session.uname+'_'+filename;
var fileStream=fs.createWriteStream('public'+img_path);
file.pipe(fileStream);
fileStream.on('close',cont);
}).fin(function(cont){
User.findOne({username:req.session.uname},cont);
}).then(function(cont,doc){
if(!doc) return cont(new Err(msg.USER.userNone));
var tmp=doc.profile.available_avatar;
//与当前头像名相同,什么都不做
if(img_path==doc.profile.avatar) return cont(null,doc);
//与备用头像名相同,当前头像入栈,删除备用头像名,当前改为上传头像名
for(var i in tmp){
if(tmp[i]==img_path){
tmp.splice(i,1);
tmp.push(doc.profile.avatar);
doc.profile.avatar=img_path;
return doc.save(cont);
}
}
//都不相同,当前入栈,再看长度有没有超,超了删1号
tmp.push(doc.profile.avatar);
doc.profile.avatar=img_path;
if(tmp.length>3) tmp.splice(1,1);
return doc.save(cont);
}).then(function(cont,doc){
res.json({
success:true,
err:null,
avatar_path:img_path,
list:doc.profile.available_avatar
});
}).fail(EndHandler);
}
function changeAvatar(req,res){//从候选头像中选择
var tmp=req.body;
Then(function(cont){
User.findOne({username:req.session.uname},cont);
}).then(function(cont,doc){
if(!doc) return cont(new Err(msg.USER.userNone));
//与当前头像名相同,什么都不做
if(tmp.pic==doc.profile.avatar) return cont(null,doc);
//用户选默认,当前入栈,若栈长超过3,删除1号
if(tmp.num==0){
doc.profile.available_avatar.push(doc.profile.avatar);
if(doc.profile.available_avatar.length>3){
doc.profile.available_avatar.splice(1,1);
}
doc.profile.avatar=tmp.pic;
return doc.save(cont);
}
//用户选备用,当前默认,不入栈,删除对应备用
if(doc.profile.avatar==doc.profile.available_avatar[0]){
doc.profile.avatar=tmp.pic;
doc.profile.available_avatar.splice(tmp.num,1);
return doc.save(cont);
}
//当前非默认,用户选备用,当前入栈,删除相应备用
doc.profile.available_avatar.push(doc.profile.avatar);
doc.profile.available_avatar.splice(tmp.num,1);
doc.profile.avatar=tmp.pic;
return doc.save(cont);
}).then(function(cont,doc){
res.json({
success:true,
err:null,
list:doc.profile.available_avatar
});
}).fail(EndHandler);
}

Web实战之用户头像相关推荐

  1. php文件 用户头像上传代码,网页web上传用户头像代码实现(美图秀秀开放)

    网页web上传用户头像代码实现(美图秀秀开放) 在制作论坛或者一些门户社交网站的时候,经常要获取用户的头像.之前我们一般都是自己制作flash插件头像上传.或者用js来自己开发一个头像上传功能.比如有 ...

  2. SpringBoot OSS实战之用户头像上传

    文章目录 前言 OSS整合 前端 获取授权 上传图片 上传URL到服务端 完整代码 后端 图片URL接收 补充 效果演示 前言 已经开始对写接口产生厌烦了,毫无技术含量,不过也是最近把用户的比较核心的 ...

  3. 亲测简单易懂可用:阿里云OSS入门实战2(集成到SpringBoot项目中存放用户头像)

    亲测简单易懂可用:阿里云OSS入门实战2(集成到SpringBoot项目中存放用户头像) 大噶好,我们继续延续上一章,学习如何使用OSS存放用户头像代码示例; 在application.propert ...

  4. web应用用户头像处理

    所有的上传,都应该将文件存储到服务器的硬盘中,另外,在数据库中记录下文件的存储路径,当需要使用文件时,可以查询数据库获取指定文件的路径,再对文件进行访问. 当用户登录成功后应当将用户头像数据(地址)保 ...

  5. 跟安全技术大师学习黑客攻防技术 ——《黑客攻防技术宝典:web实战篇》

    跟安全技术大师学习黑客攻防技术 --<黑客攻防技术宝典: web 实战篇> 随着网络技术的快速发展以及网络带宽的不断扩张, Web 应用程序几乎无处不在,渗透到社会的经济.文化.娱乐等各个 ...

  6. 《黑客攻防技术宝典Web实战篇@第2版》读书笔记1:了解Web应用程序

    读书笔记第一部分对应原书的第一章,主要介绍了Web应用程序的发展,功能,安全状况. Web应用程序的发展历程 早期的万维网仅由Web站点构成,只是包含静态文档的信息库,随后人们发明了Web浏览器用来检 ...

  7. Django2 Web 实战03-文件上传

    作者:Hubery 时间:2018.10.31 接上文:接上文:Django2 Web 实战02-用户注册登录退出 视频是一种可视化媒介,因此视频数据库至少应该存储图像.让用户上传文件是个很大的隐患, ...

  8. 统一管理MOSS2010用户头像

    我们都知道MOSS 2010里面的"我的网站"里面有一个上传照片功能,通过那里用户可以方便的上传自己的照片.也可以通过在AD里面上传用户的头像,通过MOSS的 User Profi ...

  9. python读mongodb很慢_Python3.5+Mongodb+Flask Web实战坑点小结【Dog Plus】

    我不是程序员,也不是设计师,我只是碰巧有一些想法和一台电脑. I am not a designer nor a coder. I'm just a guy with a point-of-view ...

最新文章

  1. 硬件常见问题及排错思路。
  2. P5007-DDOSvoid的疑惑【树形dp】
  3. 链栈的入栈和出栈代码_代码简介:全栈开发仍然有效
  4. 性能之巅:Linux网络性能分析工具
  5. Spring4.3.10 集成 Apache CXF 3.3 详细说明
  6. ARM 汇编详解 -- 体系结构与编程
  7. 百度云同盘在计算机显示不出来的,电脑打不开百度网盘里面的视频如何解决
  8. 微信公众号支付报错:当前页面的url未注册
  9. oracle insert提高速度,如何提高oracle的insert速度
  10. C++17 结构化绑定
  11. [CTSC2016]时空旅行(斜率优化+线段树分治)
  12. python 爬取知网url
  13. c语言背景音乐,背景图,背景字体
  14. Smith数问题C++代码实现
  15. #父与子的编程之旅#第八章
  16. 计算机科学与技术的专业概论论文,计算机科学与技术专业概论论文.docx
  17. Shader编程之地标特效
  18. 越努力越幸运!(2017年终总结)
  19. 字符串java_字符串的常用方法(内建函数)
  20. 微信小程序网悦新闻开发--小程序配置(二)

热门文章

  1. 深度挖掘 从苹果云计算窥探云端产业发展
  2. html点击文字选中单选框
  3. 自定义View-仿微信群组头像
  4. Unity实现 双指触摸放大缩小镜头 单指平移镜头
  5. 电脑网络连接正常 QQ、微信、钉钉网络正常,但是浏览器打不开网页?
  6. 匿名浏览器是什么?为什么联盟营销需要借助匿名浏览器?
  7. [Python]*词云图生成——默认和图片蒙版词云图
  8. 超高频RFID手持终端在仓储盘点中的应用
  9. 没学c语言可以学python_不学C语言直接零基础学Python怎么样?
  10. Oracle 表关联、半关联、反关联