uniapp图片上传 - thinkphp6后台接收 - 填坑日记

107 篇文章 9 订阅
98 篇文章 2 订阅

效果图

多图上传,到自己的腾讯云服务器

主要步骤

踩过的坑

  • 组件uni-file-picker​默认会自动上传图片到项目绑定的云服务器,不符合需求,需要给组件设置
    :auto-upload="false"
    来禁止自动上传
  • 组件uni-file-picker​绑定变量v-model=“list”一点用都没有,图片列表需要手动通过组件绑定事件
    @select="select" @delete=“delete”
    来增减算出 真实的图片列表
  • @select="select"事件每次传值,都只是本次多选中的图片,还要手动去合并原有列表
  • 手册....坑多
  • uniapp上传接口uni.uploadFile官方手册里,没有写头部信息,导致PHP无法获取
    header: {
    	'Content-Type': 'multipart/form-data' 
    },

  • thinkphp6文件上传还好

详细步骤

看下面的完整代码吧,心累了

推荐

手机上无广告的百度绿色版首页 baidu.rudon.cn

完整代码

uniapp页面

<template>
	<view style="background-color: white;">
		
		<view>
			<view>
				<view>
					名称:
				</view>
				<view>
					<uni-easyinput  v-model="formData.name" placeholder="输入名称" :inputBorder="false"/>
				</view>
			</view>
			
			<view>
				<view>
					<uni-file-picker file-mediatype="image" :auto-upload="false" limit="9" @select="whenImagesSelected" @delete="whenImagesDeleted"></uni-file-picker>
				</view>
			</view>
			
			
			
		</view>
		
		<view @click="clickBtn">
			<view>
				打卡
			</view>
		</view>
		
		<view>
			{{noticeMsg}}
		</view>
		
		
		
	</view>
</template>

<script>
	export default {
		data() {
			return {
				
				// 表数据
				formData: {
					// 名称
					name: ''
				},
				
				// 提示文字
				noticeMsg: '',
				
				
				// 图片列表
				imgList: [],
				
				// 图片URL 0 => 'https://xxxx/xx.jpg', 1 => '', ...
				imgListUrl: [],
				
				// 打卡记录ID
				record_id: 0
				
			}
		},
		methods: {
			
			
			// 图片选中时
			whenImagesSelected (e) {
				// 【变化+】 e.tempFilePaths,数组,多张图片
				// JS(ES6)合并数组 
				// https://wenku.baidu.com/view/e329dcda0142a8956bec0975f46527d3240ca679.html
				this.imgList = this.imgList.concat( e.tempFilePaths )
				console.log('whenImagesSelected()', this.imgList)
			},
			
			// 图片删除时
			whenImagesDeleted (e) {
				// 【变化-】 e.tempFilePath,字符串,单张图片
				this.imgList.splice( this.imgList.indexOf(e.tempFilePath), 1 )
				console.log('whenImagesDeleted()', this.imgList)
			},
			
			
			
			
			
			// 按钮点击事件
			clickBtn () {
				
				
				// 检查图片是否已经上传完毕
				if (this.record_id !== 0) {
					// 接着上传图片
					this.upload_image()
					return
				}
				
				
				
				// 检查图片数量
				if (this.imgList.length == 0) {
					this.showError( '请上传图片' )
					return
				}
				
				
				// 初始化图片上传后的路径
				this.imgListUrl = []
				for (var k in this.imgList) {
					this.imgListUrl[k] = ''
				}
				
				
				// 上传资料,获取打卡ID
				uni.request({
					url: 'https://xxxxxxxxxxxxxxx/api/add_record/',
					method: 'POST',
					dataType:'JSON',
					data:{
						name: this.formData.name
					},
					success: (res) => {
						console.log('Success', res)
						
						// 成功
						console.log('[记录添加] 成功', res.data.data.id)
						this.record_id = res.data.data.id
						this.showNotice('打卡记录已保存,准备上传图片')
						
						// 逐个上传图片 (根据打卡ID)
						this.upload_image()
						
					},
					fail: (e) => {
						console.log('Fail', e)
						this.showError('系统出错,请稍后再试')
						return
					}
				})
			},
			
			
			
			
			
			/**
			 * 
			 * 准备逐个上传图片
			 * 参考 https://blog.csdn.net/haoyue1014/article/details/89790247
			 * 
			 */ 
			upload_image () {
				// 判断 - 全部上传完毕
				if (this.index_next_upload() === false) {
					uni.showToast({
						icon: "success",
						title: "打卡成功",
						success: () => {
							setTimeout(()=>{
								uni.navigateBack({})
							}, 2000)
						}
					})
					return
				}
				
				// 获取下一个需要上传的图片下标
				let nextIndex = this.index_next_upload()
				let numberNature = nextIndex + 1
				let imgPath = this.imgList[ nextIndex ]
				console.log('Uploading img #'+nextIndex)
				console.log('Local Path '+imgPath)
				
				
				
				// 开始上传
				uni.uploadFile({
					// 服务器地址
					url: 'https://xxxxxxxxxxxxxxx/api/upload/',
					
					// PHP服务器需要正确的头部信息
					header: {
						'Content-Type': 'multipart/form-data' 
					},
					
					// 传递的参数
					formData: {
						// 目标储存位置
						path: '/images/'+ numberNature +'.jpg'
					},
					
					// 本地图片路径
					filePath: imgPath,
					
					// 服务器端接收下标 $_FILES['file']
					name: 'file', 
					
					success: (res) => {
						
						console.log('[图片上传] ', res)
						
						// 因为uni.uploadFile不能指定dataType="JSON",服务器响应内容需要自行解析
						res.data = JSON.parse(res.data)
						
						// 成功
						this.imgListUrl[ nextIndex ] = res.data.data.url
						let msg = '图片上传成功 (' + numberNature + '/' + this.imgList.length + ')'
						console.log(msg)
						this.showNotice(msg)
						
						console.log('【图片URL】', this.imgListUrl)
						
						// 继续上传,直到全部上传完毕
						this.upload_image()
						
					},
					fail: (e) => {
						console.log('上传失败', e)
						this.showError('上传失败')
					}
				})
			},
			
			
			// 下一个要上传的图片的下标: false 或者 数字下标
			index_next_upload () {
				let res = false
				for (var i in this.imgListUrl) {
					if (res === false && this.imgListUrl[i] == '') {
						res = parseInt(i)
					}
				}
				console.log('[index_next_upload]', res)
				return res
			},
			
			
			// 显示错误
			showError (msg) {
				uni.showToast({
					icon:'error',
					title: msg
				})
			},
			
			// 显示提示
			showNotice (msg) {
				this.noticeMsg = msg
				setTimeout(()=>{
					this.noticeMsg = ''
				}, 1500)
			}

			
		}
	}
</script>

<style>
	
</style>

thinkphp6文件上传接收API


    /**
     * 提交-图片上传
     * 
     */
    public function upload () {
        // 默认返回具体数据
        $res = array();

        // 默认参数
        $fileupload_key = 'file'; // 在uniapp中的 uni.uploadFile({name:'file'}) 设置
        $folder_name_tmp = 'topic'; // 随意、非空,作为接收文件夹名字
        $folder_root = dirname(dirname(dirname(__FILE__))).'/';
        $folder_path_tmp_storage = $folder_root . 'runtime/storage/';
        $folder_public = $folder_root . 'public/';
        $url_root = 'https://xxxxxxxxxxxxxxx/';

        
        // 获取参数
        $targetPath_key = 'path'; // 在uniapp中的 uni.uploadFile({ formData:{path: '/path/to/image/in/server/'} }) 设置
        if (!input('?post.'.$targetPath_key)) {
            return json('缺少参数'.$targetPath_key);
        }
        $subPath = input('post.'.$targetPath_key.'/s');
        $subPath = ltrim($subPath, '/\\');
        
        
        // 获取目标存放路径 - 原始
        // https://www.kancloud.cn/manual/thinkphp6_0/1037639 TP6手册 - 文件上传
        $tmp_file = request()->file( $fileupload_key ); 
        $tmp_savename = Filesystem::putFile( $folder_name_tmp, $tmp_file);

        
        // 获取目标存放路径 - 绝对路径
        $tmp_file_path = realpath($folder_path_tmp_storage . $tmp_savename);
        
        

        // 移动到最终路径
        $target_path = $folder_public . $subPath;
        $target_path_dir = dirname($target_path);
        if (!is_dir( $target_path_dir )) {
            mkdir( $target_path_dir, 0755, true );
        }
        rename($tmp_file_path, $target_path);
        $url = $url_root . $subPath;


        
        // 返回成功信息
        $res['url'] = $url;
        return json($res);
    }

封面

 

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rudon滨海渔村

花的越多,赚得越多...

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值