图片上传

图片上传概述

ux-editor 在生成内容时,用户通过点击图片图标,调用 uni.chooseImage() 接口,从用户相册或者相机选择一张图片,然后生成一个图片类型的内容项目。在项目生成时图片项目保存的是图片文件临时文件地址,所以在提交时候,我们需要先对图片文件进行上传,上传完成后再提交给我们的 api 接口进行保存。

图片项目完整流程

1. 选择图片生成临时文件地址;
2. 提交时通过 getContent() 函数获取内容项目数组;
3. 通过 getNeedUploadImages() 函数筛选出所有图片类型数据;
4. 循环上传所有图片,获得对应的已经上传到服务器或者云服务的图片路径;
5. 替换临时图片数据为实际图片数据,提交给数据收集者( 如 : 后端保存数据 API )。

说明

1. 我们已经为您写好了完整的提交逻辑,包含图片上传逻辑,见下面的演示代码;
2. 我们为您提供了基于 GO 和 PHP 的后端源码包,源码已经经过测试,请参考源码继续改进。
3. 请加入 uXui 交流 QQ 群 : 527580758 ,在群文件中获取后端源码。

完整提交逻辑源码

<template>
	<!-- 组件内部使用 scroll-view 此处请使用 view 作为根节点 -->
	<view class="page">
		<view class="demo-header">
			<text class="demo-header-text">uxEditor 演示</text>
			<text 
			class="demo-button" 
			@tap="submit">提交</text>
		</view>
		<view style="margin-top:0rpx; flex:1;">
			<ux-editor ref="editor"></ux-editor>
		</view>
		<view style="height:20rpx;"></view>
	</view>
</template>
<script lang="uts">
import { 
	UXEditorItem, 
	UXEditorNeedUploadItem, 
	UXEditorItemForSubmit ,
	UXEditorResponse
} from "@/uni_modules/ux-editor/ux-editor.uts";
export default {
	data() {
		return {}
	},
	onReady() {
		// 此处演示为编辑器设置默认值
		var editor = this.$refs['editor'] as UxEditorComponentPublicInstance;
		var items = [
			{content:"标题文本", type:"h", uploadStatus:2},
			{content:"段落文本", type:"text", uploadStatus:2}
		] as UXEditorItem[];
		editor.setContent(items);
	},
	methods: {
		// 提交按钮触发的直接函数
		submit : function(){
			var editor = this.$refs['editor'] as UxEditorComponentPublicInstance;
			// 编辑器内容数据
			var contentItems = editor.getContent();
			// 获取需要上传的图片数组
			var needUploadImages = editor.getNeedUploadImages();
			if(needUploadImages.length > 0){
				uni.showLoading({
					title:"图片上传中..."
				});
				// 循环上传图片直至完成
				this.uploadImage(contentItems, needUploadImages, 0);
			}else{
				this.submitData(contentItems);
			}
		},
		// 图片上传函数
		uploadImage : function(contentItems:UXEditorItem[], needUploadImages:UXEditorNeedUploadItem[], step:number){
			// 上传完毕
			if(step > needUploadImages.length - 1){
				this.submitData(contentItems);
				return ;
			}
			// 上传图片
			uni.uploadFile({
				// 图片上传接口地址 php
				url: 'http://192.168.1.101/uploadImage.php', 
				// // 图片上传接口地址 GO
				// url: 'http://192.168.1.101:8080/upload', 
				filePath: needUploadImages[step].tmpPath,
				name: 'file',
				formData: {},
				// 上传成功
				success: (res) => {
					var response = JSON.parse<UXEditorResponse>(res.data);
					var errcode:number = response?.errcode == null ? 0 : response.errcode;
					// 上传过程错误
					if(errcode > 0){
						contentItems[needUploadImages[step].index].uploadStatus = 3;
						uni.hideLoading();
						uni.showToast({
							icon:"none",
							title:"图片上传失败,请重试"
						});
						var editor = this.$refs['editor'] as UxEditorComponentPublicInstance;
						editor.setContent(contentItems);
					}else{
						var imageUrl:string = response?.data == null ? "":response.data;
						// 修改内容项目的上传状态
						contentItems[needUploadImages[step].index].uploadStatus = 2;
						contentItems[needUploadImages[step].index].content = imageUrl;
						this.uploadImage(contentItems, needUploadImages, step+1)
					}					
				}, 
				// 上传失败
				fail: () => {
					contentItems[needUploadImages[step].index].uploadStatus = 3;
					uni.hideLoading();
					uni.showToast({
						icon:"none",
						title:"图片上传失败,请重试"
					});
					var editor = this.$refs['editor'] as UxEditorComponentPublicInstance;
					editor.setContent(contentItems);
				},
			});
		},
		// 数据提交函数
		submitData:function(contentItems:UXEditorItem[]){
			var contentForSubmit = [] as UXEditorItemForSubmit[];
			// 整理最终提交的数据
			contentItems.forEach((item:UXEditorItem)=>{
				var itemIn = {
					type:item.type,
					content:item.content
				} as UXEditorItemForSubmit;
				contentForSubmit.push(itemIn)
			});
			// 连接 api 接口进行真正的数据提交即可
			uni.hideLoading();
			uni.showToast({
				icon:"none",
				title:"数据收集成功,请观察控制台"
			});
			console.log(contentForSubmit);
			console.log(JSON.stringify(contentForSubmit));
		}
	}
}
</script>
<style scoped>
.page{flex:1; background-color:#FFFFFF; display:flex; flex-direction:column;}
.demo-header{display:flex; flex-direction:row; align-items:center; justify-content:space-between; padding:25rpx 17rpx}
.demo-header-text{font-size:28rpx; color:#888888;}
.demo-button{padding:15rpx; font-size:26rpx; border:1px solid #3688FF; color:#3688FF; border-radius:12rpx;}
</style>