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

需求:问卷调查
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>


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

lamda表达式(史上最全)

一、函数式接口 在jdk8中什么是函数式接口&#xff1a; 被FunctionalInterface注解修饰的。接口里边只有一个非default的方法。 满足以上2个条件的即为函数式接口&#xff0c;ps&#xff1a;即使一个接口没有FunctionalInterface修饰&#xff0c;但是满足2&#xff0c;那么这…

国产低成本Wi-Fi SoC解决方案芯片ESP8266与ESP8285对比差异

目录 ESP8266与ESP8285对比差异微信号&#xff1a;dnsj5343ESP8285简介ESP8285 主要特性Wi-Fi特性射频模块CPU特性硬件软件 ES8285 8266通用开发板 ESP8266与ESP8285对比差异 ESP8285相当于在ESP8266基础上多加了1/2MB Flash&#xff0c; ESP8285与ESP8266同用一套SDK&#xf…

异方差与多重共线性对回归问题的影响

异方差的检验 1.异方差的画图观察 2.异方差的假设检验&#xff0c;假设检验有两种&#xff0c;一般用怀特检验使用方法在ppt中&#xff0c;课程中也有实验&#xff0c;是一段代码。 异方差的解决办法 多重共线性 多重共线性可能带来的影响&#xff1a; 多重共线性的检验 多重…

德思特方案 | 德思特毫米波RIS研究测试方案:一站式助力工程师探索高频通信未来

来源&#xff1a;德思特测试测量 德思特方案 | 德思特毫米波RIS研究测试方案&#xff1a;一站式助力工程师探索高频通信未来 原文链接&#xff1a;德思特方案 | 德思特毫米波RIS研究测试方案&#xff1a;一站式助力工程师探索高频通信未来 欢迎关注虹科&#xff0c;为您提供最…

KubeSphere应用【五】发布镜像至Harbor

一、IDEA发布镜像至Docker 1.1IDEA安装Docker插件 1.2配置Docker服务器地址 1.3编写POM.XML文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/20…

Java学习常用实用类2

1 StringTokenizer类 字符串分析器&#xff0c;能够从一个字符串中根据指定的分隔符拆分出若干单词 StringTokenizer(String s) 使用默认分隔符集合&#xff0c;即&#xff1a;空格符、换行符、回车符、Tab符、进纸符 StringTokenizer(String s, String delim) 指定分…

cilium原理之ebpf尾调用与trace

背景 在深入剖析cilium原理之前&#xff0c;有两个关于epbf的基础内容需要先详细介绍一下&#xff1a; 1. ebpf尾调用 尾调用类似于程序之间的相互跳转&#xff0c;但它的功能更加强大。 2. trace 虽然之前使用trace_printk输出日志&#xff0c;但这个函数不能多用&#x…

数据仓库-数据治理小厂实践

一、简介 数据治理贯穿数仓中数据的整个生命周期&#xff0c;从数据的产生、加载、清洗、计算&#xff0c;再到数据展示、应用&#xff0c;每个阶段都需要对数据进行治理&#xff0c;像有些比较大的企业都是有自己的数据治理平台或者会开发一些便捷的平台&#xff0c;对于没有平…

从DevOps状态报告看技术团队的文化建设

本文源自一次内部分享&#xff0c;借由此机会又把历年的DevOps状态报告翻看了一遍&#xff0c;其实大多数时候我们对于DevOps的理解都在于流程&#xff0c;工具&#xff0c;实践这些看得见摸得着的东西&#xff0c;但就像文末的几点思考所说的那样&#xff0c;我们一直相信技术…

轴承故障诊断分类模型全家桶-最全教程

Python轴承故障诊断 (一)短时傅里叶变换STFT-CSDN博客 Python轴承故障诊断 (二)连续小波变换CWT-CSDN博客 Python轴承故障诊断 (三)经验模态分解EMD-CSDN博客 Pytorch-LSTM轴承故障一维信号分类(一)-CSDN博客 Pytorch-CNN轴承故障一维信号分类(二)-CSDN博客 Pytorch-Trans…

VM Group

在复杂方案中模块过多可能造成查看或修改方案时存在视觉混乱&#xff0c;不够直观。此时可利用Group模块进行模块整合&#xff0c;同时Group模式也兼容循环的功能&#xff0c;如下图所示。 双击Group模块可进入Group内部&#xff0c;如下图所示。 在Group模块单击 可设置输入、…

Spring Cloud+SpringBoot b2b2c:Java商城实现一件代发设置及多商家直播带货商城 免 费 搭 建

【saas云平台】打造全行业全渠道全场景的saas产品&#xff0c;为经营场景提供一体化解决方案&#xff1b;门店经营区域化、网店经营一体化&#xff0c;本地化、全方位、一站式服务&#xff0c;为多门店提供统一运营解决方案&#xff1b;提供丰富多样的营销玩法覆盖所有经营场景…

北斗卫星时钟同步服务器对电力系统有多重要?

随着计算机和网络通信技术的飞速发展&#xff0c;火电厂热工自动化系统数字化、网络化的时代已经到来。一方面它为控制和信息系统之间的数据交换、分析和应用提供了更好的平台&#xff0c;另一方面对各种实时和历史数据时间标签的准确性提出了更高的要求。 通过卫星时钟来统一全…

Tomcat报404问题解决方案大全(包括tomcat可以正常运行但是报404)

文章目录 Tomcat报404问题解决方案大全(包括tomcat可以正常运行但是报404)1、正确的运行页面2、报错404问题分类解决2.1、Tomcat未配置环境变量2.2、IIs访问权限问题2.3、端口占用问题2.4、文件缺少问题解决办法&#xff1a; Tomcat报404问题解决方案大全(包括tomcat可以正常运…

uniapp如何原生app-云打包

首先第一步&#xff0c;需要大家在HBuilder X中找到一个项目&#xff0c;然后呢在找到上面的发行选项 发行->原生App-云打包 选择完该选中的直接大包就ok。 大包完毕后呢&#xff0c;会出现一个apk包&#xff0c;这是后将这个包拖动发给随便一个人就行了。 然后接收到的那…

【Java 并发】CyclicBarrier 介绍

1 简介 在多线程编程中, 协调和同步线程的执行是至关重要的。Java 提供了许多并发工具来帮助开发人员有效地管理多线程应用程序。 其中之一是 CyclicBarrier, 它是一个强大的同步辅助类, 可用于在多个线程之间创建同步点, 以便它们可以在同一时间点协调执行某个任务。 Cyclic…

Flink系列之:Checkpoints 与 Savepoints

Flink系列之&#xff1a;Checkpoints 与 Savepoints 一、概述二、功能和限制 一、概述 从概念上讲&#xff0c;Flink 的 savepoints 与 checkpoints 的不同之处类似于传统数据库系统中的备份与恢复日志之间的差异。 Checkpoints 的主要目的是为意外失败的作业提供恢复机制。 …

12、Qt:用QProcess类启动外部程序:简单使用

一、说明 简单使用&#xff1a;在一个函数中&#xff0c;使用QProcess类的临时对象调用可执行文件exe&#xff0c;只有这个exe执行完了&#xff0c;这个函数才往下执行&#xff0c;一次性打印出exe所有输出信息&#xff1b;复杂使用&#xff1a;创建QProcess类的全局对象&…

蛮力法之背包问题

问题: 有 n 个重量分别是 w1,w2....,wn 的物品&#xff08;物品编号为 1-n&#xff09;它们的价值分别为 v1,v2,...,vn 给定一个容量为 W 的背包。设计从这些物品中选取一部分放入该背包的方案。 每个物品要么选中要么不选中【其实每个物品只有 1 件】&#xff0c;要求选中…

CSS:盒子模型

CSS&#xff1a;盒子模型 盒子模型盒子模型的组成盒子内容边框 border内边距 padding盒子实际大小计算CSS3的盒子类型content-boxborder-box 外边距 margin外边距合并相邻块元素垂直外边距合并嵌套块元素垂直外边距塌陷 行内元素的内外边距 盒子相关属性圆角边框盒子阴影 盒子模…