Vue + SpringMVC实现像微信朋友圈发动态的功能

Vue + SpringMVC实现像微信朋友圈发动态的功能

平时我们都有玩过微信发朋友圈动态这样的功能吧,你知道它可以写入文字还可以上传一些我们想要发表的图片而且发表的图片还可以是很多张,但是这个时候我们有没有想过这些看起来简单的操作那它们是怎么实现的呢,这就是我要写这篇博客的原因了。由于本人前段时间采用Vue框架做了一个旅游APP而后台则是采用了java的SSM框架。其中这个App中有一个功能模块是用户可以对景点发表一些评论或者攻略的,我就把的这个功能模仿了微信发朋友圈动态的功能。话不多说了,接下来就是直接上代码吧。

  1. 先看前端的代码
//我是引用了蚂金服的前端组件库https://vue.ant.design/docs/vue/use-with-vue-cli-cn/
//所以我们要先下载这些资源

$ npm install ant-design-vue --save

====================================================================================
<template>
  <div class="comment">
	  <div>
	  	<div class="regist_header">
	  		景区评论发表区
	  	</div>
	  </div>
	<div class="comment_desc">
		星级分数:<a-rate :defaultValue="0" @change="starCount" allowHalf />
		<a-comment>
		  <div slot="content">
			<a-form-item>
			  <a-textarea :rows="4" @change="descChange" :value="value" ></a-textarea>
			</a-form-item>
			<div class="img">
				<div class="demo-upload-list" v-for="item in uploadList" :key="item.index">
					<template v-if="item.status === 'finished'">
						<img :src="item.url">
						<div class="demo-upload-list-cover">
							<Icon type="ios-eye-outline" @click.native="handleView(item.url)"></Icon>
							<Icon type="ios-trash-outline" @click.native="handleRemove(item)"></Icon>
						</div>
					</template>
					<template v-else>
						<Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
					</template>
				</div>
				<Upload
					ref="upload"
					:show-upload-list="false"
					:default-file-list="defaultList"
					:on-success="handleSuccess"
					:format="['jpg','jpeg','png']"
					:max-size="2048"
					:on-format-error="handleFormatError"
					:on-exceeded-size="handleMaxSize"
					:before-upload="handleBeforeUpload"
					multiple
					type="drag"
					action="http://192.168.1.100:8200/mavenView_war_exploded/ar/uploadFile.action"
					:data= '{type:"comment", user_id:this.user.id, city:this.information.city, scenery:this.information.scenery_title}'
					style="display: inline-block;width:100px;">
					<div v-if="!(this.uploadList.length >= 6)" style="width: 100px;height:100px;line-height: 100px;">
						<Icon type="ios-camera" size="20"></Icon>
					</div>
				</Upload>
				<Modal title="View Image" v-model="visible">
					<img :src="imgName" v-if="visible" style="width: 100%">
				</Modal>
			</div>
			
			<a-form-item>
			  <a-button
				id="add_comment"
				htmlType="submit"
				:loading="submitting"
				@click="handleSubmit"
				type="primary"
			  >
				发表评论
			  </a-button>
			</a-form-item>
			
      </div>
    </a-comment>
	</div>
  </div>
</template>
<script>
import 'ant-design-vue/dist/antd.css'//蚂蚁金服组件库
import Antd from 'ant-design-vue'//蚂蚁金服组件库
import moment from 'moment'
import fastClick from 'fastclick'
import { mapState } from "vuex"
import axios from 'axios'
import qs from 'qs'
export default {
	name: 'Criticism',
  data () {
    return {
	  defaultList: [],
	  imgName: '',
	  visible: false,
	  uploadList: [],
      comments: [],
      submitting: false,
      value: '',
      moment,
	  count: 0,
	  number: 0,
	  imgNum: 0
    }
  },
  methods: {
	  handleView (url) {
			this.imgName = url;
			this.visible = true;
		},
		handleRemove (file) {
			const fileList = this.$refs.upload.fileList;
			this.$refs.upload.fileList.splice(fileList.indexOf(file), 1);
			// 往对应路径的发起ajax数据请求
			axios({
				method: 'post',
				url: 'http://localhost/mavenView_war_exploded/ar/deleteUpdate.action',
				data:qs.stringify({fileUrl: file.url})
			}).then(this.getDataSucc)
		},
		handleSuccess (res, file) {
			console.log(res)
			if(res.ret){
				file.url = res.data.url
				file.name = res.data.name
			}
			
		},
		handleFormatError (file) {
			this.$Notice.warning({
				title: 'The file format is incorrect',
				desc: 'File format of ' + file.name + ' is incorrect, please select jpg or png.'
			});
		},
		handleMaxSize (file) {
			this.$Notice.warning({
				title: 'Exceeding file size limit',
				desc: 'File  ' + file.name + ' is too large, no more than 2M.'
			});
		},
		handleBeforeUpload (file) {
			console.log(file)
			const check = this.uploadList.length < 6;
			if (!check) {
				this.$Notice.warning({
					title: '发图存量最大为6张!'
				});
			}
			return check;
		},
	  starCount(value, index) {
		  console.log(index)
		  this.count = value
	  },
	  imgSub(id) {
		  const list = []
		  for(var i=0; i<this.fileList.length; i++) {
			  if(this.fileList[i].id != id) {
				  list.push(this.fileList[i])
			  }
		  }
		  this.fileList = list
		  this.imgNum = list.length
		 console.log(id)
	  },	
	openNotification (res) {//操作提示窗口
		if (res == 'success') {
			this.$notification.open({
			  message: '恭喜您,评论发表成功!',
			  description: '您可以返回到个人页面进行查看评论!',
			  duration: 3,
			})
		}else if(res == 'login') {
			this.$notification.open({
			  message: '跳转失败,可能失败原因!',
			  description: '您还未进行用户登录,请前去登录账户!',
			  duration: 3,
			});
		} else if(res == 'photo') {
			this.$notification.open({
			  message: '选图失败,请重新选择图片!',
			  description: '您选择的图片不得超过6张,请重新输入!',
			  duration: 3,
			})
		} else {
			this.$notification.open({
			  message: '评论发表失败,请重新发表!',
			  description: '请把内容填写完整,请重新输入发表内容!',
			  duration: 3,
			})
		}
	},
    handleSubmit() {
      if (!this.value) {
        return;
      }

	  const values = {}
	  values.city = this.information.city
	  values.scenery_title = this.information.scenery_title
	  values.nickname = this.user.nickname
	  values.comment = this.value
	  values.user_id = this.user.id
	  values.count = this.count
	  values.imgNum = this.fileList.length
		// 往对应路径的发起ajax数据请求
		axios({
			method: 'post',
			url: 'http://localhost:8200/mavenView_war_exploded/insert/Comment.action',
			data:qs.stringify(values)
		}).then(this.getDataSucc)
    },
	getDataSucc (res) {
		 // 获取数据对象
		console.log(res);
		res = res.data
		// 判断数据对象是否存在
		if (res.code == 0) {
			this.openNotification('success')
		} else {
			this.openNotification('error')
		}
	},
    descChange(e) {
      this.value = e.target.value
    },
  },
  mounted() {
	this.uploadList = this.$refs.upload.fileList
  },
  computed: {
  	...mapState(['information','id','user'])
  }
}
  

</script>	
<style lang="stylus" scoped>
	>>> .ant-list-split .ant-list-item {
		float: right
		height: 100%
	}
	>>> .ant-comment-inner{
		max-width: 100%
	}
	.comment {
		width: 100%
		height: 100%
		.regist_header {
			width: 100%
			line-height: 1.5rem
			text-align: center
			font-size: 0.5rem
			background: #00afc7
			color: #fff
		}
		.comment_desc {
			width: 100%
			height: 11rem
			padding: 0.2rem
			.img {
				.demo-upload-list{
					display: inline-block;
					float: left
					margin: 0.06rem 0.1rem
					width: 30%
					height: 2rem
					text-align: center;
					line-height: 2rem;
					border: 1px solid transparent;
					border-radius: 4px;
					overflow: hidden;
					background: #fff;
					position: relative;
					box-shadow: 0 1px 1px rgba(0,0,0,.2);
					// margin-right: 4px;
				}
				.demo-upload-list img{
					width: 100%;
					height: 100%;
				}
				.demo-upload-list-cover{
					display: none;
					position: absolute;
					top: 0;
					bottom: 0;
					left: 0;
					right: 0;
					background: rgba(0,0,0,.6);
				}
				.demo-upload-list:hover .demo-upload-list-cover{
					display: block;
				}
				.demo-upload-list-cover i{
					color: #fff;
					font-size: 20px;
					cursor: pointer;
					margin: 0 2px;
				}
				.img_wipper {
					float: left
					margin: 0.06rem 0.1rem
					width: 30%
					height: 2rem
					// height: 2.14rem
					background:red
					.img_wipper_url {
						position: absolute
						// z-index: 2
						width: 30%
						height:2rem
					}
					.img_wipper_sub {
						z-index: 5
						position: relative
						width: 0.6rem
						line-height: 0.6rem
						text-align: center
						float: right
					}
				}
			}
		}
		>>>.ant-comment-avatar {
			margin-right: 0rem;
		}
	}
</style>
  1. 然后是SpringMVC的后台代码

/**
* 功能分析:完成对前端文件上传的请求,接收图像,修改图像,存储图片的功能
* 
* @param request //接收请求体
* @param file //上传的文件
* @return
*/
//多图片上传控制器
@RequestMapping("/uploadFile")
@ResponseBody
public JSONObject uploadFile(HttpServletRequest request, @RequestParam("file") MultipartFile file){
    JSONObject json = new JSONObject();
    //设置同步代码块
    synchronized (this) {
        Map<String, Object> map = new HashMap<>();
        Boolean flag=false;
        //判断是否有图片上
        if(file.isEmpty()){
            json.put("ret", false);
            json.put("code", 2);
            return json;
        }

        try{
            //获取上传文件的名称
            String fileName = file.getOriginalFilename();
            //获取文件上传的时间戳
            DateFormat format1 = new SimpleDateFormat("yyyyMMddhhmmss");
            String dateStr = format1.format(new Date()) + Math.floor(Math.random()*10000);
            //设置上传文件在服务器端的存储路径
            String path = request.getServletContext().getRealPath("/static/")+dateStr;
            //存储路径和上传文件名生成一个文件
            File dest = new File(path, fileName);
            //判断文件父目录是否存在
            if(!dest.getParentFile().exists()){
                //不存在就创建一个文件夹出来存储上传文件
                dest.getParentFile().mkdir();
                //将上传文件保存到一个目标文件中
//                file.transferTo(new File(path + File.separator + fileName));
                //通过图片的IO流读取上传的图片资源
                BufferedImage image = ImageIO.read(file.getInputStream());
                //获取一个操作图像资源的镀锡
                BufferedImage   images = null;
                //定义上传图片的高、宽值的变量
                int img_width = 610,img_height = 400;
                if (image != null) {//如果image=null 表示上传的不是图片格式
                    //创建一个存放图片区域的对象
                    images = new BufferedImage(img_width, img_height, BufferedImage.TYPE_INT_BGR);
                    //创建一个 Graphics2D,可以将它绘制到此 BufferedImage 中。
                    Graphics garphics = images.createGraphics();
                    /**
                     * 绘制当前可用的指定图像的指定区域,动态地缩放图像使其符合目标绘制表面的指定区域。
                     * 简单点说就是对上传的图像进行宽度和高度的修改从而达到符合我们前端的展示的需要
                     */
                    garphics.drawImage(image, 0, 0, img_width, img_height, null);
                    //创建一个文件输出流
                    OutputStream outputStream = new FileOutputStream(dest);
                    //把修改好的图片按指定输出流的路径存储
                    JPEGImageEncoder j = JPEGCodec.createJPEGEncoder(outputStream);
                    j.encode(images);
                    outputStream.close();
                }
            }
            
            if(dest.exists()){
                map.put("name", fileName);
                map.put("url", dataUrl);
                json.put("ret",true);
                json.put("data", map);
                json.put("code", 0);
            } else {
                json.put("ret", false);
                json.put("code", 2);
            }
            System.out.println("数据库路径:"+dataUrl);
        }catch(Exception e){
            e.printStackTrace();
            json.put("ret", false);
            json.put("code", 2);
        }
        return json;
    }
 }




/**
 * 功能分析:可以完成对一些失去价值的图像资源进行回收内存操作
 * 
 * @param request
 * @return
 */
//清除用户取消的图片
@RequestMapping("/deleteUpdate")
@ResponseBody
public JSONObject deleteImg(HttpServletRequest request) {
    JSONObject json = new JSONObject();
    String url = request.getParameter("fileUrl");
    if (url == null) {
        return json;
    }
    //删除数据库中的记录
    CityImg cityImg = urdi.findCityImgByUrl(url);
    if (cityImg != null) {
        int number = urdi.DeleteCityImg(cityImg.getId());
    }
    String[] fileArr=url.split("/");
    String fileName = fileArr[fileArr.length-1];
    String path = request.getServletContext().getRealPath("/static/")+fileArr[fileArr.length-2];
    File dest = new File(path, fileName);
    //删除磁盘目录下的记录
    if (dest.exists()){
        //如果该目录的文件存在,执行删除操作
        dest.delete();
    }
    return json;
}

好了这就是一个完整的类似微信发朋友圈动态功能模块了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值