Files
property-resident-side/property-uniapp-project/pages/service-list/questionnaireFillout.vue
2026-04-18 17:29:15 +08:00

498 lines
10 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="contentStyle" style="">
<view class="status-bar"></view>
<uni-nav-bar title="问卷调查" backgroundColor="transparent" :border="false" left-icon="left" @clickLeft="goBack">
</uni-nav-bar>
<!-- 表单区域 -->
<scroll-view class="page" scroll-y="true">
<view class="content-wrap">
<!-- 问卷标题 -->
<view class="survey-title">关于用户体验反馈的调查</view>
<!-- 问卷说明 -->
<view class="survey-desc">
为了给您提供更好的服务希望您能抽出几分钟时间将进的感受和建议告诉我们我们非常重视每位用户的宝贵意见期待您的参与
</view>
<!-- 问题1单选 -->
<view class="question-item">
<view class="question-title">
<text class="required">*</text>1.您社区的大门数量
</view>
<view class="radio-group">
<view class="radio-item" v-for="(item, index) in q1Options" :key="index"
@click="selectRadio(1, index)">
<view class="radio-circle" :class="{ checked: q1Selected === index }">
<text v-if="q1Selected === index" class="check-icon"></text>
</view>
<text class="radio-label">{{ item }}</text>
</view>
</view>
</view>
<!-- 问题2单选 -->
<view class="question-item">
<view class="question-title">
<text class="required">*</text>2.您所在的社区关于消防演练下列符合几项
</view>
<view class="radio-group">
<view class="radio-item" v-for="(item, index) in q2Options" :key="index"
@click="selectRadio(2, index)">
<view class="radio-circle" :class="{ checked: q2Selected === index }">
<text v-if="q2Selected === index" class="check-icon"></text>
</view>
<text class="radio-label">{{ item }}</text>
</view>
</view>
</view>
<!-- 问题3自定义 Select (核心部分不使用 picker) -->
<view class="question-item">
<view class="question-title">
<text class="required">*</text>3.您所在的社区是否有健康医疗服务
</view>
<!-- 模拟输入框点击展开下拉 -->
<view class="select-wrapper" @click="toggleDropdown">
<text class="select-text" v-if="q3Selected">
{{ q3Selected }}
</text>
<text class="select-placeholder" v-else>
请选择是否有该项服务
</text>
<text class="select-arrow"></text>
</view>
<!-- 下拉面板 (遮罩 + 列表) -->
<view class="dropdown-mask" v-if="showDropdown" @click="hideDropdown"></view>
<view class="dropdown-panel" v-if="showDropdown">
<view class="dropdown-item" v-for="(item, index) in q3Options" :key="index"
@click="selectQ3(index)" :class="{ active: index === q3Index }">
{{ item }}
</view>
</view>
</view>
<!-- 问题4星级评分 -->
<view class="question-item">
<view class="question-title">
<text class="required">*</text>4.您对所在社区的综合评分
</view>
<view class="star-group">
<view class="star-item" v-for="(item, index) in 5" :key="index" @click="selectStar(index + 1)">
<text class="star-icon" :class="{ active: index < q4Score }"></text>
</view>
</view>
</view>
<!-- 问题5文本输入 -->
<view class="question-item">
<view class="question-title">
<text class="required">*</text>5.您还有哪些建议
</view>
<textarea class="textarea-input" v-model="q5Content" placeholder="请输入您还有哪些建议" maxlength="500" />
</view>
</view>
</scroll-view>
<!-- 固定底部提交按钮 -->
<view class="submit-btn-wrap">
<button class="submit-btn" @click="handleSubmit">提交</button>
</view>
</view>
</template>
<script>
export default {
onReady: function(e) {},
components: {
},
computed: {
},
created() {
},
onShow() {
},
mounted() {},
onReady() {
this.$nextTick(() => {
})
},
data() {
return {
/* 设定状态栏默认高度 */
statusBarHeight: 20,
// 问题1
q1Options: ['1', '2', '3', '4'],
q1Selected: -1,
// 问题2
q2Options: ['一周2~3次', '一月2~3次', '一年2~3次', '基本不买'],
q2Selected: -1,
// 问题3 (自定义Select)
q3Options: ['有', '无'], // 选项列表
q3Selected: '', // 绑定显示值
q3Index: -1, // 绑定索引
showDropdown: false, // 控制下拉面板显示
// 问题4
q4Score: -1,
// 问题5
q5Content: ''
}
},
methods: {
selectRadio(type, index) {
if (type === 1) this.q1Selected = index
else this.q2Selected = index
},
// 问题3切换下拉显示
toggleDropdown() {
this.showDropdown = !this.showDropdown
},
// 问题3隐藏下拉
hideDropdown() {
this.showDropdown = false
},
// 问题3选择选项
selectQ3(index) {
this.q3Index = index
this.q3Selected = this.q3Options[index]
this.hideDropdown() // 选择后自动关闭
},
// 问题4
selectStar(score) {
this.q4Score = score
},
// 提交
handleSubmit() {
if (this.q1Selected === -1) {
uni.showToast({
title: '请选择社区大门数量',
icon: 'none'
})
return
}
if (this.q2Selected === -1) {
uni.showToast({
title: '请选择社区消防演练频率',
icon: 'none'
})
return
}
if (this.q3Index === -1) {
uni.showToast({
title: '请选择社区是否有健康医疗服务',
icon: 'none'
})
return
}
if (this.q4Score === -1) {
uni.showToast({
title: '请选择对社区的综合评分',
icon: 'none'
})
return
}
if (!this.q5Content.trim()) {
uni.showToast({
title: '请输入建议',
icon: 'none'
})
return
}
uni.showLoading({
title: '提交中...',
mask: true
});
setTimeout(() => {
uni.showToast({
title: '提交成功',
icon: 'success'
});
}, 1000);
setTimeout(() => {
// 提交成功后跳转列表页
uni.hideLoading();
this.goBack();
}, 2500);
},
goBack() {
uni.redirectTo({
url: '/pages/service-list/questionnaireSurveyIndex',
success: res => {},
fail: () => {},
complete: () => {}
});
},
},
}
</script>
<style lang="scss">
page {
background: #f2f1f6;
}
</style>
<style scoped lang="scss">
.contentStyle {
display: flex;
flex-direction: column;
height: 100vh;
/* 关键:占满屏幕高度 */
background: linear-gradient(to left bottom, #e2efff 0%, #f9f9f9 50%);
}
.page {
flex: 1;
overflow-y: auto;
padding: 0px 40rpx;
box-sizing: border-box;
/* background-color: #fff; */
}
/* 滚动内容区 */
.content-scroll {}
.content-wrap {
// padding-bottom: 40rpx;
}
/* 标题与描述 */
.survey-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
text-align: center;
margin: 0px 0 20rpx 0;
;
}
.survey-desc {
font-size: 24rpx;
color: #4A4A4A;
line-height: 1.6;
margin-bottom: 20rpx;
text-align: justify;
}
/* 问题项 */
.question-item {
margin-bottom: 30rpx;
.question-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom:10rpx;
line-height: 1.4;
.required {
color: #ff3b30;
font-size: 36rpx;
margin-right: 8rpx;
}
}
}
/* 单选按钮 */
.radio-group {
display: flex;
flex-direction: column;
gap: 30rpx;
padding-left: 30rpx;
}
.radio-item {
display: flex;
align-items: center;
gap: 20rpx;
.radio-circle {
width: 40rpx;
height: 40rpx;
border-radius: 50%;
border: 2rpx solid #ccc;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
&.checked {
background-color: #007aff;
border-color: #007aff;
.check-icon {
color: #fff;
font-size: 24rpx;
font-weight: bold;
}
}
}
.radio-label {
font-size: 34rpx;
color: #333;
}
}
/* 核心:自定义 Select 样式 (模拟输入框) */
.select-wrapper {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
height: 80rpx;
padding: 0 20rpx;
border: 2rpx solid #e5e5e5;
border-radius: 8rpx;
background-color: #fff;
font-size: 32rpx;
color: #333;
margin-left: 30rpx;
}
.select-placeholder {
color: #999;
}
.select-arrow {
font-size: 24rpx;
color: #999;
margin-left: 10rpx;
}
/* 下拉遮罩层 */
.dropdown-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.1);
z-index: 99;
}
/* 下拉面板 */
.dropdown-panel {
position: absolute;
left: 0;
right: 0;
max-height: 400rpx;
background-color: #fff;
border: 2rpx solid #e5e5e5;
border-radius: 8rpx;
z-index: 100;
margin-top: 10rpx;
overflow: hidden;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
}
.dropdown-item {
height: 80rpx;
line-height: 80rpx;
padding: 0 20rpx;
font-size: 32rpx;
color: #333;
&:active {
background-color: #f5f5f5;
}
&.active {
color: #007aff;
font-weight: 500;
}
}
/* 星级评分 */
.star-group {
display: flex;
align-items: center;
gap: 16rpx;
margin-left: 30rpx;
.star-icon {
font-size: 56rpx;
color: #e5e5e5;
transition: all 0.2s ease;
&.active {
color: #007aff;
}
}
}
/* 文本输入框 */
.textarea-input {
width: calc(100% - 30rpx);
min-height: 240rpx;
padding: 20rpx;
border: 2rpx solid #e5e5e5;
border-radius: 8rpx;
background-color: #fff;
font-size: 32rpx;
color: #333;
box-sizing: border-box;
margin-left: 30rpx;
}
/* 底部占位 & 提交按钮 */
.bottom-placeholder {
height: 120rpx; // 高度要大于等于按钮高度
}
.submit-btn-wrap {
padding: 20rpx 30rpx 40rpx;
display: flex;
gap: 20rpx;
// background-color: #fff;
.submit-btn {
width: 100%;
height: 96rpx;
line-height: 96rpx;
background-color: #007aff;
color: #fff;
font-size: 36rpx;
font-weight: 500;
border-radius: 12rpx;
border: none;
padding: 0;
margin: 0;
&::after {
border: none;
}
}
}
.status-bar {
width: 100vw;
height: 46px;
}
</style>