前端效果图:

在这里插入图片描述

文件结构:

在这里插入图片描述

imgup.vue 代码

<template>
	<view>
		<view class='pages'>
		  
			<view class='father_view'> 
				<view class='son_view'> 
				  <view class="title-bg">请描述质量问题(最多120个汉字)</view>
				  <textarea class="textarea-bg" v-model="text1" @blur="inputText"  placeholder="请输入内容" /> 
				</view> 
			</view>
			
			<!-- 图片 -->
			<view class="images_box">
				<block v-for="(item, index) in imglist" :key="index">
				  <view class='img-box'>
					<image class='img' :src='item' mode='aspectFill'></image>
					<view class='img-delete' @click='imgDelete1' :data-delindex="index">
					    <image class='img' src='../../static/delect.png' ></image>  
					</view>
				  </view>
				</block>
				<view class='img-box' @click='addPic1' v-if="imglist.length<9">
					<image class='img' src='../../static/add_image.png'></image>  
				</view>
			</view>
			
			<button @click='uploadimage'>上传图片</button>			
			<button @click='viewmemo'>查看留言</button>
		</view>		
	</view>	
</template>

<script>
	export default {
		data() {
			return {
				imglist:[],//选择图片后生成的临时地址数组
				text1:'',				
			}
		},
		
		onLoad() {
		
		},
		
		methods: {	
			//*获取文本框内容*//
			inputText:function (e) {
				this.text1 = e.detail.value	
			},
			
			//*选择图片*//
			addPic1: async function() {
				let that = this
				uni.chooseImage({
					count: 9,  // 最多可以选择的图片张数,默认9
					sizeType: ['compressed'], // original 原图,compressed 压缩图,默认二者都有
					sourceType: ['album', 'camera'], // album 从相册选图,camera 使用相机,默认二者都有
					success: function (res) {						
						if (that.imglist.length === 0) {
							that.imglist = res.tempFilePaths
						} else if (that.imglist.length < 9) {
							that.imglist = that.imglist.concat(res.tempFilePaths); //concat追加到数组
						}						
					},
				})
			},
			
			//*显示选择后的图片*//
			imgbox: function (e) {
			    this.imglist = e.detail.value
			},
			
			//* 删除已经选择的图片 *//
			imgDelete1: function (e) {				
				let index = e.currentTarget.dataset.delindex; //获取要删除的图片的下标,否则删除的永远是第一张 ,对应 <view class='img-delect' @click='imgDelete1' :data-delindex="index">
				this.imglist.splice(index, 1);			  	
			},
			
			//*上传图片*//
			uploadimage: function () {
				let app = getApp()
				let upimg = require("./upimg.js"); //引用当前目录下的自定义函数
				let that = this;		
				
				if (that.imglist.length != 0) { //数组不为空的时候才执行 				
					upimg.uploadimg({ //调用upimg.js文件的uploadimg函数
						url: app.globalData.url+'/imgup', //全局变量,后端接口地址
						path: that.imglist, //选取图片的临时地址数组 
						text: that.text1,  //文本框内容  
						user: app.globalData.username, 
					});
					uni.showToast({  //显示对话框
						title: "上传中!",
						icon: 'loading',
						duration: 1000,
					});					
					setTimeout(function () { //延迟执行,目的是等待上一步的uploadimg函数执行完成赋值给全局变量后再执行下面的代码
						that.imglist = []  //清空选择的图片
						that.text1 = ''   //清空文本框的内容						
					}, 1000); //延迟时间
				 
				}else{
					uni.showToast({
					  title: "请选择图片!",
					  icon: 'none',
					  duration: 1000,
					})
				}
			},
			
			viewmemo:function (e) {
				uni.navigateTo({  //跳转到指定页面
					url: "../memo/memo",
				})
			}
		},
	}
</script>

<style>
	@import "./imgup.css";
</style>

upimg.js 代码:


//多张图片上传
function uploadimg(data) {
  var app = getApp()
  var imgurln=[]	
  var that = this
  
  i = data.i ? data.i : 0,  //当前上传的哪张图片
  success = data.success ? data.success : 0,  //上传成功的个数
  fail = data.fail ? data.fail : 0;  //上传失败的个数
  uni.uploadFile({
		url: data.url, //从调用页面传入 -- url: 'http://127.0.0.1:3000/' 后端接口地址
		filePath: data.path[i], //从调用页面传入 --path: imgbox, 选取图片的地址数组  
		name: 'img', //文件名称可以自定义,要与后端配对使用:app.post('/',upload.single('img'),function(req,res,next)
		formData: {  //这里是上传图片时一起上传的数据
			user: data.user,
			memo: data.text   //从调用页面传入 -- text:text1 文本框内容  
		},

		success: (resp) => {
			success++;//图片上传成功,图片上传成功的变量+1
			//console.log(resp.data) //在调试窗口显示后端返回的图片名称      
			imgurln = imgurln.concat(app.globalData.url + resp.data); //以图片名称拼接成网址,并追加到数组imgurln
			//console.log(i);
			//这里可能有BUG,失败也会执行这里,所以这里应该是后台返回过来的状态码为成功时,这里的success才+1
		},

		fail: (res) => {  //失败
			fail++;//图片上传失败,图片上传失败的变量+1
			console.log('fail:' + i + "fail:" + fail);
		},

		complete: () => { //不论成功、失败都执行		
			i++; //这个图片执行完上传后,开始上传下一张
			if (i == data.path.length) {   //当图片传完时,停止调用  
				//app.globalData.imgurl =imgurln; //把远程图片的网址数组赋值给全局变量,以便在另一个页面显示远程图片
				console.log('1>'+app.globalData.url);       
				console.log('执行完毕');
				console.log('成功:' + success + " 失败:" + fail);
			} else { //若图片还没有传完,则继续调用函数
				//console.log(i);
				data.i = i;
				data.success = success;
				data.fail = fail;
				that.uploadimg(data);
			}
		}
    });
}

module.exports.uploadimg = uploadimg; //把uploadimg函数暴露,才能在其它js文件引用此函数。 

imgup.css 代码:

page{
 background-color: rgba(200, 198, 201, 0.527);
}
.pages{
 width: 98%;
 margin: auto;
 overflow: hidden;
}

/* 图片 */
.images_box{
 width: 98%;
 display: flex;
 flex-direction: row;
 flex-wrap: wrap;
 justify-content: flex-start;
 background-color: white;
 margin: 10rpx;
}
.img-box{ 
 border: 1rpx;
 border-style: solid;
 border-color: rgba(0, 0, 0, 0.452);
 width: 200rpx;
 height: 200rpx;
 margin-left: 25rpx;
 margin-top: 20rpx;
 margin-bottom: 20rpx;
 position: relative;
}
.img{
  width: 100%;
  height:100%;  
}

/* 删除图片 */
.img-delete{
 width:50rpx;
 height:50rpx;
 border-radius:50%;
 position:absolute;
 right:-20rpx;
 top:-20rpx;
}

button{
 width: 98%;	
 margin-top: 20rpx; 
 background-color: #ffaa00;
}

.img1{
 border: 5rpx;
 border-style: solid;
 border-color: rgba(0, 0, 0, 0.452);
 width: 200rpx;
 height: 200rpx;
}

.img2{
  width: 100%;
  height:100%;
}

/* 多行文本 */
textarea {
  width: 700rpx;
  height: 250rpx;
  margin-left: 10rpx;
  margin-right: 10rpx;
  margin-top: 10rpx;
} 
.textarea-bg {
  background-color: #ffffff;
  padding: 10rpx;
  font-size: 32rpx;
} 
.title-bg {
  font-size: 32rpx;
  margin-left: 10rpx;
  margin-right: 10rpx;
  margin-top: 10rpx;
  color: #43c729;
}

后端nodejs代码:

var express=require('express')
var app=express()
var router=express.Router()
var multer=require('multer')
var path=require('path')
var image = require("imageinfo")
var mssql =require("mssql")  //引用mssql
var config = require('../config.js') //引用config.js文件
var request = require("request")
	
var storage = multer.diskStorage({ 
    destination: function (req, file, cb) {
        cb(null, 'public/imgtemp/');  	// 接收到文件后的保存路径,需要手动创建  
    },
    filename: function (req, file, cb) { 
		cb(null, Date.now() + "-" + file.originalname);  // 将保存文件名设置为: 时间戳 + 文件原始名,比如 151342376785-123.jpg
	}
});
var upload = multer({ storage: storage })
var type = upload.single('img')  //与前端的name:'img'对应

//* 上传图片 *//
router.post('/',type,function(req,res,next){
	console.log('01>>',req.file);
	console.log('02>>',req.body);
	//console.log('03>>',req.file.path);
	res.send(req.file.filename); //向前端返回当前上传成功的文件名	
	
	mssql.connect(config, function (err) {  //连接数据库
	    if (err) {
			console.log('数据库连接失败')
			return callback(err);			  
		} else {
			//console.log('数据库连接成功')		    		        
			var user1 = req.body.user ;
			var memo1 = req.body.memo ;  //req.body 解析前端formdata传递过来的数据 //req.query 解析前端data传递过来的数据
			var filename1 = req.file.filename ;
			var request = new mssql.Request();
			request.query("INSERT INTO wx_bbs (username,memo,filename) VALUES ('"+ user1 +"','"+ memo1 +"','"+ filename1 +"')",function (err, recordsets,returnValue) {
				if (err) {
					console.log(err);
					return
				} else {		
					//str = JSON.stringify(recordsets.recordset); //将查询结果转换成json格式
					//res.send(str);  //响应请求,将数据发送到前端
					console.log('执行sql脚本成功');  //在调试窗口显示
				}
			})
		};
		
		mssql.end;  //结束连接数据库
	});
	

	// 压缩图片并删除原图 //
	var images = require("images")
	var fs=require('fs') 
	var name = './public/imgtemp/' + req.file.filename;  	//原图像文件完整路径
	var outName = './public/imgup/' + req.file.filename;	//压缩后的图像文件完整路径
	
	images(name)				   					  //加载原图像文件
	  .size(1000)					  				  //等比缩放图像到1000像素宽
	  .draw(images("./public/png/logo.png"), 10, 10)  //在(10,10)处绘制Logo
	  .save(outName, {quality:60})  				  //保存图片到文件,图片质量为60%
	
	fs.unlink(name,function(err){  	//删除原图
		if(err){								
			console.log('删除失败');
			return;
		}							
		console.log('原图删除成功');
	})	
})

module.exports = router;  //暴露模块,其它地方才能调用此模块
Logo

前往低代码交流专区

更多推荐