今天在项目开发中,遇到某个功能需要移动端上传多张图片,看了uview官方的组件使用方法后,发现比较鸡肋,需要挨个编写组件并渲染对应点的文件列表和上传函数,于是就有了接下来的封装,在此记录。


首先在设计好该功能的数据表字段后,通过后端接口返回要渲染的上传图片的组件数组列表


public $configArray = [];

    /**
     * 构造方法
     * Custom constructor.
     * @param Request|null $request
     */
    public function __construct(Request $request=null)
    {
        parent::__construct($request);
        if($this->request->isPost()){
            $post = $this->request->post();
            if(!isset($post['data'])) $this->error('参数格式异常~','',0);
            $this->param = $post['data'];
        }

        $this->configArray = [
            ['label'=>'退宿整体照','name'=>'whole_image'],
            ['label'=>'退宿床位照','name'=>'bed_image'],
            ['label'=>'退宿阳台照','name'=>'balcony_image'],
            ['label'=>'退宿卫生间照','name'=>'toilet_image'],
            ['label'=>'退宿衣柜照','name'=>'wardrobe_image'],
            ['label'=>'其他照片','name'=>'other_image'],
        ];

    }

    /**
     *获取退宿上传图片项
     */
    public function getExampleImageList()
    {
        try {
            $configList = [];
            foreach ($this->configArray as $key => $item){
                $configList[] = [
                    'label'=>$item['label'],
                    'name'=>$item['name'],
                    'examoleImage'=>trim(Config::get('site.'.$item['name'])),
                    'fileList'=>[],
                    'fileListName'=>$item['name'].'_filelist'
                ];
            }
        }catch (\Exception $e){
            $this->error($e->getMessage());
        }
        $this->success('获取成功',['exampleImageList'=>$configList]);

其次是前端代码



<template>
	<view class="padding-sm">
		<view class="radius15 hidden" >
			<view class="border-bottom">
				<view class="cu-bar justify-center bg-white" style="justify-content: start;">
					<view class="action sub-title">
						<text class="text-xl text-bold text-blue">退宿资料</text>
						<text class="text-ABC text-blue">information</text>
					</view>
				</view>
			</view>
			<view class="shadow bg-white radius10">
				<view class="cu-form-group">
					<view class="title fpc">退宿原因:</view>
					<textarea class="text-right" maxlength="-1" v-model="dormitoryRefundData.reason" placeholder-style="font-size:30rpx" style="height:170rpx;width: 100%;" confirm-type="我写完了" :auto-focus="false" placeholder="请填写退宿原因"></textarea>
				</view>
				<view class="cu-form-group">
					<view class="title fpc">备注:</view>
					<textarea class="text-right" maxlength="-1" v-model="dormitoryRefundData.remark" placeholder-style="font-size:30rpx" style="height:170rpx;width: 100%;" confirm-type="我写完了" :auto-focus="false" placeholder="如有备注请填写"></textarea>
				</view>
				
				<view class="cu-form-group" v-for="(item,index) in exampleImageList">
					<view class="title fpc">{{item.label}}:</view>
					<view class="flex">
						<view>
							<u-upload :fileList="filelist[index][`${item.name}`]" :name="item.name" :data-index="index" :maxCount="1" @afterRead="afterRead" @delete="deletePic"></u-upload>
						</view>
						<view class="padding-top-sm margin-left-sm" v-if="item.examoleImage">
							<u-tag text="示例图" plain size="mini" shape="circle" @click="prevExampleImage(config.localUrl+item.examoleImage)"></u-tag>
						</view>
					</view>
				</view>
			</view>
		</view>
		
		<view class="radius15 hidden margin-top-sm">
			<view class="border-bottom">
				<view class="cu-bar justify-center bg-white" style="justify-content: start;">
					<view class="action sub-title">
						<text class="text-xl text-bold text-blue">注意事项</text>
						<text class="text-ABC text-blue">ordinance</text>
					</view>
				</view>
			</view>
			<view class="bg-white">
				<view class="padding-tb-sm">
					<view class="text-gray text-sm padding-lr-sm" style="line-height: 2em;">
						<view>1、请确保所有填写的信息准确无误,以避免后续的管理问题。</view>
						<view>2、所有必填字段必须完成填写,否则无法提交登记。</view>
						<view>3、任何虚假信息将会影响您的宿舍分配和后续管理</view>
					</view>
				</view>
			</view>
		</view>
		<view class="padding-sm margin-top-df">
			<button class="response cu-btn bg-blue margin-tb-sm lg round" @click="validateData">确认提交</button>
		</view>
	</view>
</template>

<script>
	import {getExampleImageList,setDormitoryRefundData} from '@/api/dormitory.js'
	import common from '../../../utils/common';
	import config from '../../../utils/config';
	import validate from '../../../utils/validate.js';
	export default {
		data() {
			return {
				config:config,
				
				//入住数据
				dormitoryRefundData:{
					dormitory_move_id:null,
					reason:'',
					remark:'',
				},
				filelist:[],//上传图片绑定fileList
				
				exampleImageList:[],//渲染上传图片表单
				exampleImageNameArray:[],//配置名称数组用于获取index
			}
		},
		onLoad(option) {
			if(!option.dormitory_move_id){
				common.toast('参数错误,请刷新后重试');
				setTimeout(function(){
					uni.navigateBack();
				},1500)
				return false;
			}
			this.dormitoryRefundData.dormitory_move_id = option.dormitory_move_id;
			this.getExampleImageList();//获取上传图片项
		},
		onShow() {
		},
		methods: {
			//提交退宿申请
			setDormitoryRefundData(){
				const that = this;
				common.toast('提交中');
				setDormitoryRefundData(that.dormitoryRefundData).then(res=>{
					uni.hideLoading();
					common.toast(res.data.msg);
					if(res.data.code){
						setTimeout(function(){
							uni.navigateTo({
								url:'/pages/index/index'
							})
						},1500)
					}
				})
			},
			
			
			//获取上传图片项
			getExampleImageList(){
				const that = this;
				common.loading();
				getExampleImageList({}).then(res=>{
					uni.hideLoading();
					if(res.data.code){
						that.exampleImageList = res.data.data.exampleImageList;
						
						that.exampleImageList.map(item=>{
							that.filelist.push({
								[`${item.name}`]:[],
								name:item.name,
								label:item.label
							})
							that.exampleImageNameArray.push(item.name);
						})
					}else{
						common.toast('暂未获取到上传表单项');
						setTimeout(function(){
							uni.navigateBack();
						},1500)
						return false;
					}
				})
			},
			
			// 删除图片
			deletePic(event) {
				const that = this;
				let eventName = event.name;
				let eventIndex = that.exampleImageNameArray.indexOf(eventName);
				that.filelist[eventIndex][`${event.name}`].splice(event.index, 1);
			},
			
			// 新增图片
			async afterRead(event) {
				const that = this;
				let eventName = event.name;
				let eventIndex = that.exampleImageNameArray.indexOf(eventName);
				let lists = [].concat(event.file);
				let fileList = that.filelist[eventIndex][`${event.name}`];
				
				let fileListLen = that.filelist[eventIndex][`${event.name}`].length
				lists.map((item) => {
					that.filelist[eventIndex][`${event.name}`].push({
						...item,
						status: 'uploading',
						message: '上传中'
					})
				})
				for (let i = 0; i < lists.length; i++) {
					const result = await common.uploadFile(lists[i].url);
					let item = that.filelist[eventIndex][`${event.name}`][fileListLen]
					that.filelist[eventIndex][`${event.name}`].splice(fileListLen, 1, Object.assign(item, {
						status: 'success',
						message: '',
						url: result.fullurl,
						image:result.url
					}))
					fileListLen++
				}
			},
			
			//查看大图
			prevExampleImage(image){
				const that = this;
				console.log([image]);
				uni.previewImage({
					urls:[image],
					showmenu:true,
				})
			},
			
			//提交登记入住数据
			setDormitoryMoveData(){
				const that = this;
				
			},
			
			//验证提交数据
			validateData(){
				const that = this;
				if(!that.dormitoryRefundData.reason){
					common.toast('请填写退宿原因');
					return false;
				}
				
				try{
					that.filelist.map((item,index)=>{
						let data = item[`${item.name}`];
						if(!data.length){
							throw new Error('请上传'+item.label);
						}
						that.dormitoryRefundData[`${item.name}`] = data[0].image;
						console.log(JSON.stringify(that.dormitoryRefundData));
					})
				}catch(error){
					common.toast(error.message);
					return false;
				}
				
				uni.showModal({
					title:'提醒',
					content:'是否确认退宿',
					success(res) {
						if(res.confirm){
							that.setDormitoryRefundData();
						}
					}
				})
			},
			
		}
	}
</script>
<style>
	.u-upload__button{
		margin: 16rpx !important;
	}
</style>



点赞(4) 打赏

评论列表 共有 0 条评论

暂无评论

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部