随机问卷调查数据的处理(uniapp)

news2025/1/23 7:13:31

需求:问卷调查
1.返回的数据中包含单选、多选、多项文本框、单文本框、图片上传
2.需要对必填的选项进行校验
3.非必填的多项文本框内容 如果不填写 不提交
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

表单数据格式
res={
    "code": 0,
    "msg": null,
    "data": [
        {
            "executeDay": "2023-12-18",
            "infoList": [ //表单数据
                {
                    "id": "",
                    "recordId": "",
                    "taskId": "",
                    "itemId": "",
                    "itemName": "",
                    "subtype": 1,//根据这个数值区分 表单的类型 1单选 2多选 3多填空 4 文本框 5上传文件 6基本信息
                    "executeDate": "",
                    "states": "0",// 是否为必填项目 0表示必填 1表示非必填
                    "times": 1,
                    "timing": "8:00",
                    "executeTimes": 0,
                    "delFlag": "0",
                    "content": "{}",
                    "executeDay": "2023-12-18"
                }
            ]
        }
    ]
}

<view class="reportData" v-for="(val, index) in obj" :key="index">
				<view class="reportData-title"><text class='red'
						v-if='val.requiredFlag==0'>*</text>{{index+1+'.'}}{{ val.questionContent }}</view>
				<view v-if="val.questionType ==1" class="chbox">
					<u-radio-group v-model="submitData[index].optionValue" placement="column"
						@change="(e)=>groupChange(e, val)" :key="index">
						
						<block v-for="(item, i) in val.optionInfoList">
							<!-- 其它选项 -->
							<view v-if="item.optionType=='1'" style="display:flex"  >
								<u-radio :customStyle="{marginBottom: '20rpx'}" :label="item.optionName"
									:name="item.optionName" @change="e=>radioChange(e,item,index)">
									
								</u-radio>
	
								<u--input placeholder="其他-具体描述" v-model="submitData[index].remark" class="cc_input"
									style="height:24rpx;font-size: 30rpx;margin-left:20rpx ;" v-if="submitData[index].optionValue.indexOf('其他')!= -1"
									></u--input>
							</view>
							<u-radio :customStyle="{marginBottom: '20rpx'}" v-else :label="item.optionName"
								:name="item.optionName" @change="e=>radioChange(e,item,index)">
							</u-radio>
						</block>
					</u-radio-group>

				</view>

				<!-- 多选 -->
				<view v-if="val.questionType ==2" class="chbox">
					
					<u-checkbox-group v-model="submitData[index].optionValue" placement="column"
						@change="(e) =>checkboxChange(e, val)">
						<block v-for="(item, i) in val.optionInfoList" :key="index" >
							<view v-if="item.optionType=='1'" style="display:flex"  >
								<u-checkbox :customStyle="{marginBottom: '20rpx'}" 
									:label="item.optionName" :name="item.optionName">
								</u-checkbox>
								<u--input placeholder="其他具体描述" v-model="submitData[index].remark" class="cc_input"
									style="height:24rpx;font-size: 30rpx;margin-left:20rpx ;" v-if="submitData[index].optionValue.indexOf('其他')!= -1"
									></u--input>
							</view>
							<u-checkbox :customStyle="{marginBottom: '20rpx'}" v-else :label="item.optionName" :name="item.optionName">
							</u-checkbox>
						</block>
					</u-checkbox-group>
					
				</view>

				<!-- 文本上传 -->
				<view v-else-if="val.questionType ==4" class="chbox">
					<up-load @afterRead='val=>afterRead(val,index)' @deletePic='val=>deletePic(val,index)'></up-load>
				</view>
				<!--  文本框-->
				<view v-else-if="val.questionType ==5" class="chbox">
					<textarea class="investigate-propose" placeholder="请输入" v-model="submitData[index].optionValue"
						name="propose" id="" cols="30" rows="10"></textarea>
				</view>
				<!-- 6.个人的基本信息 -->
				<view v-if="val.questionType ==6 || val.questionType ==3" class="chbox">
					<view class="item" v-for="(item,i) in submitData[index].info">
						<view class="name">{{item.optionTitle}}:</view>
						<!-- 数值 -->
						<view class="c_name" v-if="item.optionType==2">
							<u--input placeholder="请输入数值" type='number' v-model="item.cname"
								class="cc_input"></u--input>
						</view>
						<!-- 时间 -->
						<view class="c_name" @click="item.showState = true" v-else-if="item.optionType==3">
							<u--input placeholder="请输入时间" v-model="item.cname" class="cc_input"></u--input>
							<u-calendar :closeOnClickOverlay='true' :show="item.showState"
								@confirm="e=>confirm(e,i,index)" @close='item.showState = false'>
							</u-calendar>
						</view>
						<!-- 文本 -->
						<view class="c_name" v-else>

							<u--input placeholder="请输入数值" type='number' v-model="item.cname"
								class="cc_input"></u--input>
						</view>
					</view>
				</view>
<script>
<script>
	import http from '@/untils/http'//请求接口的封装
	import upLoad from '@/pages/components/upLoad.vue'//图片上传的封装
	export default {
		components: {
			upLoad
		},
		data() {
			return {
				id:"",
				formData: {
					itemId: '',
					subtype: ''
				},
				obj: {},
				infoList: '',
				subtype: '',
				submitData: [], // submitData[{info:[{item:1}]}]
				optionsObj: { //需要提交给后台的数据
					"userId": '',
					"taskId": '', //问卷的id taskId"1736623815192743937"
					"taskNmae": "",
					"surveyId": "1", // itemId
					"surveyName": "", //
					"totalScore": "",
					"taskInfoId": "12", // id
				}
			}
		},
		onLoad(options) {
			this.optionsObj = {
						"userId": this.$store.state.userInfo.userId,
						"taskId": options.taskId, //问卷的id taskId"1736623815192743937"
						"taskNmae": "",
						"surveyId": options.itemId, // itemId
						"surveyName": options.surveyName, //
						"totalScore": "",
						"taskInfoId": options.id, // id
					}
					this.initData()
		},
		methods: {
			// 回显数据
			async showData(){
				let {data}=await http.savefindByTaskInfoId(this.id)
				console.log(res)
				this.obj=data.infoList

			},
			// 时间下拉框 确认按钮
			confirm(e, i, index) {
				this.obj[index].info[i].cname = e.toString()
				this.obj[index].info[i].showState = false
			},
			// 提交按钮
			submitFn() {
				let sendFrom = JSON.parse(JSON.stringify(this.submitData))
				sendFrom = sendFrom.map((item, index) => {
					// 将字符串转化为数组
					if (typeof(item.optionValue) == 'string') {
						item.optionValue = item.optionValue.length == 0 ? [] : item.optionValue.split();
					}
					if (item.info && item.info.length > 0) {
						// 过滤掉 空的数组
						for (let i = 0; i < item.info.length; i++) {
							if (item.info[i].cname != '') {
								item.optionValue.push(item.info[i].cname)
								item.optionTitle.push(item.info[i].optionTitle)
							}
						}
					}

					return item
				})
				// 校验部分 是否需要必填
				for (let i = 0; i < sendFrom.length; i++) {
					if (sendFrom[i].requiredFlag == 0) {
						if (sendFrom[i].optionValue.length == 0) {
							this.$refs.uToast.show({
								message: `${i+1}题未填写`
							});

							break
						}
						if (sendFrom[i].optionValue.indexOf('') != -1) {
							this.$refs.uToast.show({
								message: `${i+1}题未填写`
							});
							break
						}
					}

				}
				
				// console.log(sendFrom)
				this.sendFrom(sendFrom)
			},
			async sendFrom(val) {
				let sendFrom = {
					...this.optionsObj,
					"infoList": val
				}
				let {
					data,
					code,
					msg
				} = await http.saveUserQuestionnaire(sendFrom)
				if (code == 0) {
					this.$refs.uToast.show({
						message: data
					})
					uni.navigateTo({
						url: '/pages/Option/sucess/sucess'
					})
				} else {

					this.$refs.uToast.show({
						message: msg
					})

				}





			},
			// afterRead 上传图片
			afterRead(val, index) {
				this.submitData[index].optionValue = val.map(item => {
					return item.url.filePath
				})

			},
			// 删除图片
			deletePic(val, index) {
				this.submitData[index].optionValue = []
				this.submitData[index].optionValue = val

			},
			// 单选框按钮处理
			groupChange(e, val) {
				console.log(e,val,'dyd')
				this.submitData = this.submitData.map(item => {
					if (val.id == item.itemId) {

						item.optionValue = e

					}

					return item
				})

			},
			// 复选框
			checkboxChange(e, val) {
				this.submitData = this.submitData.map(item => {
					if (val.id == item.itemId) {
						item.optionValue = e
					}
					return item
				})
			},

			async initData() {
				let res = await http.getFindByInfo(this.formData)
				this.obj = res.data.questionInfoList.map(item => {

					if (item.questionType == 2 || item.questionType == 4) {
						this.submitData.push({
							itemId: item.id, //题目的id
							optionValue: [],
							fraction: item.fraction,
							questionNumber: item.questionNumber,
							questionContent: item.questionContent, //问题
							requiredFlag: item.requiredFlag,
							questionId: item.questionId,
							optionTitle: item.optionTitle,
							remark:'',
							questionType:item.questionType

						})

						// 基本信息部分
					} else if (item.questionType == 6 || item.questionType == 3) {
						this.submitData.push({
							itemId: item.id, //题目的id
							optionValue: [],
							info: [],
							fraction: item.fraction,
							questionNumber: item.questionNumber,
							questionContent: item.questionContent, //问题
							requiredFlag: item.requiredFlag,
							questionId: item.questionId,
							optionTitle: [],
							remark:'',
							questionType:item.questionType
						})
						item.optionInfoList.map(item2 => {
							this.submitData = this.submitData.map(item3 => {
								if (item.id == item3.itemId) {
									let cname = 'cid' + item2.id
									item3.info.push({
										id: item2.id,
										cname: '',
										fraction: item2.fraction,
										optionTitle: item2.optionTitle,
										showState: false, //是否可以打开时间的下拉框
									})
								}
								return item3
							})

						})
					} else {
						this.submitData.push({
							itemId: item.id, //题目的id
							optionValue: '',
							fraction: item.fraction,
							questionNumber: item.questionNumber,
							questionContent: item.questionContent, //问题
							requiredFlag: item.requiredFlag,
							questionId: item.questionId,
							optionTitle: item.optionTitle,
							questionType:item.questionType
						})
					}

					item.optionInfoList.map(item2 => {
						item2.disabled = false

					})

					return item
				})



			},


			// 单选按钮切换
			radioChange(e, item,index) {
				if(e=='其他') {
					
				}else {
					this.submitData[index].remark=''
				}
			},
			

			
		}
	}
</script>

//对uviews上传组件进行了二次封装

<template>
	<u-upload :fileList="fileList6" @afterRead="afterRead" @delete="deletePic" name="6" multiple :maxCount="10"
		:width="wWidth" :height="hHeight"  >

	</u-upload>
</template>

<script>
	export default {
		props: {
			wWidth:{ //图片的宽度
				type: Number,
				default: 58,
			},
			hHeight:{// 图片的高度
				type: Number,
				default: 58,
			},
		},
		data() {
			return {
				fileList6: [],
			}
		},
		methods: {
			// 添加图片时间
			async afterRead(event) {
				// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
				let lists = [].concat(event.file)
				let fileListLen = this[`fileList${event.name}`].length
				lists.map((item) => {
					this[`fileList${event.name}`].push({
						...item,
						status: 'uploading',
						message: '上传中'
					})
				})
				for (let i = 0; i < lists.length; i++) {
					const result = await this.uploadFilePromise(lists[i].url)
					let item = this[`fileList${event.name}`][fileListLen]
					this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
						status: 'success',
						message: '',
						url: result
					}))
					fileListLen++
				
				}
				this.$emit('afterRead',this.fileList6)
			
			},
			uploadFilePromise(url) {
				return new Promise((resolve, reject) => {
					let a = uni.uploadFile({
						url:  '/sapi/file/uploadImageMobile', // 仅为示例,非真实的接口地址
						filePath: url,
						name: 'file',
						formData: {
							bizType: "patient",
							
						},
						success: (res) => {
							setTimeout(() => {
								let data=JSON.parse(res.data)
								resolve(data.data)
							}, 1000)
						}
					});
				})
				
			},
			// 删除图片
			deletePic(event) {
				this[`fileList${event.name}`].splice(event.index, 1);
				this.$emit('deletePic',this.fileList6)
			},
		}
	}
</script>


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1330257.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS overflow-anchor

overflow-anchor 为了认识这个属性, 我们需要先看一种常见的现象. 即在网页加载中, 图片常常比文字加载更慢, 这样图片加载完成后可能会将文字向下顶. 比如下图演示 <div class"overflow"><img id"bg" src"" height"150" al…

前端页面资源放入oss 对象存储问题

1.需求 当我们做的是微信公众号的时候 需要微信重定向登录 在此时 我们需要在微信后台配置重定向域名 但是微信后台只能配置三个 如果有很多H5 公众号重定向登录的需求 我们该怎么做呢 2.解决 肯定我们需要配置 首页的 一般前端打包项目 都是由index.html 当然 我们实现 都是…

Linux:sudo给予账户特定的权限

我们某些用户权限比较低&#xff0c;如果我们他们的权限提高&#xff0c;或者假如搞权限的组&#xff0c;那么会大大减少安全性&#xff0c;我们可以使用sudo对他们开放指定的命令 我这里有 a1—3 3个用户&#xff0c;现在我切换到a1执行一下重启的命令 发现我们这个用户并无…

DSC2803X,DSP Pin2Pin with Ti Parts

一&#xff0c;产品特性 高能效 32 位处理器(H28x 内核)  主频 120MHz&#xff08;周期 8.33ns&#xff09;  哈佛(Harvard) 总线架构  硬件乘法/除法单元  4/6 通道高速 DMA  快速中断响应和处理  统一存储器编程模型  高效代码&#xff08;使用 C/C和汇编语言&…

docker容器内 获取宿主机ip

可以使用命令 --add-host jargatewayip:192.168.0.47 \ 需要注意,这里不能是 127.0.0.1 ,所以要找到服务器局域网的ip 命令示例 docker run -it \-p 80:80 \-p 443:443 \--name nginx \--network app --hostname nginx \-e TZAsia/Shanghai \--add-host jargatewayip:192.16…

基于JAVA的厦门旅游电子商务预订系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 景点类型模块2.2 景点档案模块2.3 酒店管理模块2.4 美食管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 学生表3.2.2 学生表3.2.3 学生表3.2.4 学生表 四、系统展示五、核心代码5.1 新增景点类型5.2 查询推荐的…

16、Qt线程(一):继承QThread,重写run

一、说明 Qt提供了3个类4种方式创建线程&#xff1a; 1、QThread ①继承QThread类&#xff0c;重写run()函数 ②继承QObject类&#xff0c;使用moveToThread()函数 2、使用QtConCurrent并发模块的run()函数 3、继承QRunnable类 二、功能说明 1、通过继承QThread&#xff0c;重…

FATFS文件系统

文件系统是为了存储和管理数据&#xff0c;而在存储设备上建立的一种组织结构。 Windows常用的文件系统&#xff1a; 1、FAT12 2、FAT16 3、FAT32 4、exFAT 5、NTFS FAT&#xff1a;File Alloction Table 文件分配表 在小型的嵌入式存储设备大多…

大模型托管平台Replicate,获2.9元B轮融资

大模型开源平台Replicate在官网宣布&#xff0c;获得4000万美元&#xff08;近2.9亿元&#xff09;B轮融资。本次由a16z领投&#xff0c;英伟达、Y Combinator等跟投。 Replicate的开源平台提供了超过25,000个模型&#xff0c;涵盖文本、图片、视频、音频、3D模型等领域。典型…

60.乐理基础-打拍子-V字打拍法

前置内容&#xff1a; 文字版 https://note.youdao.com/s/6FSSvGBf &#xff08;顺序参考&#xff1a;下方的视频版里面目录顺序&#xff09; 视频版 【四川音乐学院作曲硕士】教你零基础自学乐理保姆级教学-学习视频教程-腾讯课堂 文字版还有下图红框中三个专栏里的内容&a…

freemarkEngine文件ftl的可视化编辑

在做导出word文件功能时&#xff0c;需要准备ftl模板&#xff0c;设置一些通配符&#xff0c;之后通过相关编码&#xff0c;即可以实现业务数据渲染后导出word的功能。但是ftl文件一般我们看不太懂&#xff0c;所以可视化创建和修改就非常合适。 1、安装office2016版本&#x…

【Linux】权限篇(二)

权限目录 1. 前言2. 权限2.1 修改权限2.2 有无权限的对比2.3 另外一个修改权限的方法2.3.1 更改用户角色2.3.2 修改文件权限属性 3. 第一个属性列4. 目录权限5. 默认权限 1. 前言 在之前的一篇博客中分享了关于权限的一些知识&#xff0c;这次紧接上次的进行&#xff0c;有需要…

中国数字化进程简史(1980-2022)之二基础网络雏形

20世纪80年代数字化政策扶持信息化技术基础研究&#xff0c;一大批科研成果在90年代开始市场转化&#xff0c;随着中国大陆向外向型经济转型&#xff0c;1993年3月12日朱镕基副总理主持会议部署建设国家公用经济信息网为起点&#xff0c;拉开了一系列“金”字号工程规划建设的序…

LLM漫谈(一)| LLM可以取代数据分析师吗?

我想&#xff0c;在过去的一年里&#xff0c;我们每个人都不止一次想知道ChatGPT是否&#xff08;或者更确切地说&#xff0c;何时&#xff09;能够取代你的工作。 我们有一个共识&#xff0c;即Generative AI最近的突破将极大地影响我们每个人生活和工作。然而&#xff0c;我们…

使用OpenCV4实现工业缺陷检测的六种方法

目录 1 机器视觉2 缺陷检测3 工业上常见缺陷检测方法 1 机器视觉 机器视觉是使用各种工业相机&#xff0c;结合传感器跟电气信号实现替代传统人工&#xff0c;完成对象识别、计数、测量、缺陷检测、引导定位与抓取等任务。其中工业品的缺陷检测极大的依赖人工完成&#xff0c;…

DPDK单步跟踪(3)-如何利用visual studio 2019和visual gdb来单步调试dpdk

准备工作 因为时间的关系&#xff0c;我想到哪说到哪&#xff0c;可能没那么高的完成度。 但其实有心的人&#xff0c;看到这个标题&#xff0c;就关了本文自己能做了。 why和how to build debug version DPDK,见前两篇。这里我们准备开始。 首先&#xff0c;你有一台linux机…

【游戏篇】Scratch之饥饿的鱼

【作品展示】饥饿的鱼 操作&#xff1a;点击小绿旗&#xff0c;按下键盘方向或者利用鼠标移动&#xff0c;躲避大鱼的同时还要想办法吃到小鱼。

SecureCRT连接vmware虚拟机的centos系统配置

软件版本&#xff1a;VMware10.0.3&#xff0c;centos 7&#xff0c;securecrt 8.7.2 1&#xff0c;虚拟网络编辑器选择桥接模式&#xff0c; 2&#xff0c;如果不小心删除网络&#xff0c;centos关机状态下&#xff0c;选择恢复默认设置。 3&#xff0c;进入linux系统&#…

DRF之引入

目录 一、web应用模式 【1】前后端混合开发 【2】前后端分离 二、API接口 三、接口测试工具&#xff1a;Postman 四、RESTful API规范 【1】什么是RESTful 【2】RESTful API的规范 2.1 数据的安全保障 2.2 接口特征表现 2.3 多数据版本共存 2.4 数据即是资源&#…

助力硬件测试工程师之EMC项目测试。

1&#xff1a;更新该系列的目的 接下来的一个月内&#xff0c;将更新硬件测试工程师的其中测试项目--EMC项目&#xff0c;后续将会出安规等项目&#xff0c;助力测试工程师的学习。 2&#xff1a;如何高效率的展现项目的基础以及一些细节知识点 通过思维导图以及标准的规定进行…