前端请求

一开始考虑使用现成的图床api上传,但是图床上传要求必须是file格式的图片对象,不支持uni自带的uploadFile上传,然后考虑在node上发送请求,但是试了很多种方法还是获取不到需要的file格式对象,所以使用node管理图片

1将图片通过uni.uploadFile上传到node上

let imgurl = await this.$http.uploadImg(this.imageList[0]); //发送图片对象console.log(imgurl) //上传图片	


//请求api

uploadImg: function(data) { //上传图片
		console.log(data)
		return new Promise((resolve, reject) => {
			uni.uploadFile({ //上传代码
				url: BASE_URL + '/my/upload', //本地node.js服务器地址
				filePath: data,
				name: "file", //这个东西有点类似与 form表单中的name值 在后面也需要这个
				success: function(res) {
					resolve(res); ///返回!!!!!!
					console.log('res');
					console.log(res);
				},
				fail: function(e) {
					reject(e)
					console.log(e)
				}
			})
		})
	},

node写法

这里使用一个很容易想到的方法,获取上传图片之后随机数重命名并修改图片路径,开放存储路径,达到可以访问的效果

开放图片文件夹

app.use('/img', express.static('public/images'))

修改路径与存储需要预设存储图片的文件夹

const express = require('express')
const router = express.Router()
const my_handler = require('../router_handler/my')
const path = require('path')
const fs = require('fs');
const request = require("request");
const db = require("../db");


//设置临时目录 存放上传的图片
const upload = multer({dest: "tmp/"});
// 接受客户端上传的图片

router.post("/upload", upload.single("file"), (req, res) => {
    let imgFile = req.file;//获取图片上传的资源
    console.log(imgFile)
    let tmp = imgFile.path;//获取临时资源
    let ext = path.extname(imgFile.originalname);//利用path模块获取 用户上传图片的 后缀名
    let newName = "" + (new Date().getTime()) + Math.round(Math.random() * 10000) + ext;  //给用户上传的图片重新命名 防止重名
    let newPath = "../public/images/" + newName; //给图片设置存放目录  提前给当前文件夹下建立一个   images文件夹  !!!!
    let fileData = fs.readFileSync(tmp);//将上传到服务器上的临时资源 读取到 一个变量里面
    fs.writeFileSync(path.join(__dirname, newPath), fileData);//重新书写图片文件  写入到指定的文件夹下
    console.log('http://127.0.0.1:3007/img/' + newName)
    let newurl = 'http://127.0.0.1:3007/img/' + newName;
    res.send(newurl);//上传成功之后  给客户端响应
    // http://127.0.0.1:3007/img/1647057754040334.jpg
})

然后返回得到图片在服务器上的地址,连同其他信息进行最后信息发送,从而在数据库里存储图片地址。

页面完整代码

<template>
	<view class="page">
		<uni-nav-bar color="#FFFFFF" leftIcon="back" backgroundColor="#3088C9" @clickLeft="backToLastPage()"
			title="提交申请信息"></uni-nav-bar>
		<view class="feedback-body feedback-uploader">
			<view class="uni-uploader">
				<view class="uni-uploader-head">
					<view class="uni-uploader-title"></view>
					<view class="uni-uploader-info"></view>
				</view>
				<view class="uni-uploader-body">
					<view class="uni-uploader__files">
						<block v-for="(image,index) in imageList" :key="index">
							<view class="uni-uploader__file" style="position: relative;">
								<image class="uni-uploader__img" :src="image" @tap="previewImage(index)"></image>
								<view class="close-view" @click="close(index)">x</view>
							</view>
						</block>
					</view>
				</view>
				<view class="uni-uploader__input-box" v-if="imageList.length ==0">
					<view class="uni-uploader__input" @tap="chooseImg"></view>
				</view>

			</view>
		</view>
		<view class="btnline">
			<view class="btnlable">时间</view>
			<view class="btnres">
				<view class="uni-input">{{time}}</view>
			</view>
		</view>

		<view class="btnline">
			<view class="btnlable">名字</view>
			<view class="btnres">
				<input class="uni-input" maxlength='4' @blur='nameInput'></input>
			</view>
		</view>


		<view class="btnline">
			<view class="btnlable">地址</view>
			<view class="btnres">
				<input class="uni-input" maxlength="30" @blur='positionInput'></input>

			</view>
		</view>

		<view class="btnline">
			<view class="btnlable">电话</view>
			<view class="btnres">
				<input class="uni-input" type="number" maxlength='12' @blur='phoneInput'></input>
			</view>
		</view>

		<button class="btn" @tap="send">提交</button>

	</view>
</template>

<script>
	import {
		formatTime
	} from "../../utils/formatedate.js";

	var _self; //this
	export default {
		mounted() {
			this.time = formatTime(new Date())
			console.log(this.time); //时间
		},
		data() {
			return {
				imageList: [],
				time: '',
				nameStr: '',
				phoneStr: '',
				positionStr: '',
				nameStrValid: '必填',
				index: 0,
				sendDate: {
					score: 0,
					content: "",
					contact: ""
				}
			}
		},
		created() {
			_self = this; //全局的this
		},
		onLoad: function(option) {},
		methods: {
			nameInput: function(event) {
				this.nameStr = event.target.value;
				if (this.nameStr.length <= 0) {
					this.nameStrValid = '姓名不能为空';
				} else {
					this.nameStrValid = '验证通过';
				}

			},
			phoneInput: function(event) {
				this.phoneStr = event.target.value;
			},

			positionInput: function(event) {
				this.positionStr = event.target.value;
			},

			close(e) {
				this.imageList.splice(e, 1);
			},

			chooseMsg() { //快速输入
				uni.showActionSheet({
					itemList: this.msgContents,
					success: (res) => { //从底部向上弹出操作菜单
						this.sendDate.content = this.msgContents[res.tapIndex];
					}
				})
			},
			backToLastPage() {
				uni.navigateBack();
			},

			chooseImg(index) { //选择图片
				uni.chooseImage({
					sourceType: ["camera", 'album'],
					count: 1 - this.imageList.length,
					sizeType: "compressed",
					success: function(res) {
						_self.imageList = res.tempFilePaths //一张图片
					}
				})
			},

			previewImage(index) { //预览图片
				uni.previewImage({
					urls: this.imageList,
					current: this.imageList[index]
				});
			},

			async send() { //发送申请
				console.log('开始发现');
				if (this.imageList.length === 0) {
					uni.showModal({ //弹窗提示
						content: '至少选择一张图片',
						showCancel: false
					})
					return
				}
				if (this.nameStr.replace(/\s*/g, "") === '') {
					uni.showModal({ //弹窗提示
						content: '姓名不为空',
						showCancel: false
					})
				}
				let imgurl = await this.$http.uploadImg(this.imageList[0]); //发送图片对象
				console.log(imgurl) //上传图片
				let data = {
					owner_id: getApp().globalData.id,
					phone: this.phoneStr,
					pos: this.positionStr,
					owner_img: imgurl.data,
					time: this.time,
					name: this.nameStr,
				}
				console.log('data:')
				console.log(data)
				let result = await this.$http.addmaster(data)
				uni.showToast({
					title: '已发送申请',
					duration: 2000
				});
				if (result.data.status === 0) {
					uni.showToast({
						title: '申请成功',
						duration: 2000
					});
					getApp().globalData.ismaster = true
				}
			},
		}
	}
</script>

<style>
	page {
		background-color: #EFEFF4;
	}

	.input-view {
		font-size: 28rpx;
	}

	.close-view {
		text-align: center;
		line-height: 14px;
		height: 16px;
		width: 16px;
		border-radius: 50%;
		background: #FF5053;
		color: #FFFFFF;
		position: absolute;
		top: -6px;
		right: -4px;
		font-size: 12px;
	}

	.feedback-body {
		background: #fff;

	}

	.feedback-uploader {
		padding: 22rpx 20rpx;
	}

	.uni-uploader {
		flex: 1;
		flex-direction: column;
	}

	.uni-uploader-head {
		display: flex;
		flex-direction: row;
		justify-content: space-between;
	}

	.uni-uploader-info {
		color: #B2B2B2;
	}

	.uni-uploader-body {
		margin-top: 16rpx;
	}

	.uni-uploader__files {
		margin-top: 30px;
		display: flex;
		flex-direction: row;
		flex-wrap: wrap;

	}

	.uni-uploader__file {
		margin-left: 100px;
		width: 300rpx;
		height: 300rpx;

	}

	.uni-uploader__img {
		display: block;
		width: 300rpx;
		height: 300rpx;

	}

	.uni-uploader__input-box {
		position: relative;
		margin-left: 100px;
		width: 300rpx;
		height: 300rpx;
		border: 2rpx solid #D9D9D9;
	}

	.uni-uploader__input-box:before,
	.uni-uploader__input-box:after {
		/* 内部线条 */
		content: " ";
		position: absolute;
		top: 50%;
		left: 50%;
		-webkit-transform: translate(-50%, -50%);
		transform: translate(-50%, -50%);
		background-color: #D9D9D9;
	}

	.uni-uploader__input-box:before {
		width: 4rpx;
		height: 79rpx;
	}

	.uni-uploader__input-box:after {
		width: 79rpx;
		height: 4rpx;
	}

	.uni-uploader__input-box:active {
		border-color: #999999;
	}

	.uni-uploader__input-box:active:before,
	.uni-uploader__input-box:active:after {
		background-color: #999999;
	}

	.uni-uploader__input {
		position: absolute;
		z-index: 1;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		opacity: 0;
	}

	.btnline {
		margin-top: 20rpx;
		height: 80rpx;
		width: 100%;

	}

	.btnline2 {
		margin-top: 10rpx;
		height: 870rpx;
		width: 100%;

	}

	.btnlable {
		margin-left: 10rpx;
		height: 80rpx;
		font-size: 30rpx;
		width: 26%;
		text-align: center;
		line-height: 80rpx;
		background: #FFFFFF;
		border: solid 1px #F0F0F0;
		border-radius: 6px;
		float: left;
	}

	.btnres {
		margin-left: 10rpx;
		height: 80rpx;
		font-size: 30rpx;
		width: 68%;
		text-align: center;
		line-height: 80rpx;
		background: #FFFFFF;
		border: solid 1px #F0F0F0;
		border-radius: 6px;
		float: left;
	}

	.btndate {
		margin-left: 10rpx;
		height: 80rpx;
		font-size: 30rpx;
		width: 40%;
		text-align: center;
		line-height: 80rpx;
		background: #FFFFFF;
		border: solid 1px #F0F0F0;
		border-radius: 6px;
		float: left;
	}

	.btn {
		margin-top: 100rpx;
		margin-left: 8%;
		height: 80rpx;
		font-size: 30rpx;
		width: 84%;
		text-align: center;
		line-height: 80rpx;
		color: #FFFFFF;
		background: #f9624f;
		border: solid 1px #F0F0F0;
		border-radius: 6px;
		float: left;
	}
</style>

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐