Explorar o código

Merge branch 'develop' of http://gogs.zlhuiyun.com/szr190/ShenhaiH5 into develop

szr190 hai 2 meses
pai
achega
102884184b
Modificáronse 1 ficheiros con 273 adicións e 29 borrados
  1. 273 29
      src/pages/questionnaire.vue

+ 273 - 29
src/pages/questionnaire.vue

@@ -3,7 +3,7 @@
3 3
  * @Author: Fengyu
4 4
  * @Date: 2025-12-12 10:12:59
5 5
  * @LastEditors: Fengyu
6
- * @LastEditTime: 2025-12-17 10:26:23
6
+ * @LastEditTime: 2025-12-17 17:32:29
7 7
 -->
8 8
 <template>
9 9
   <view class="questionnaire-container">
@@ -33,18 +33,29 @@
33 33
     <!-- 网格选择区域 -->
34 34
     <view class="grid-section">
35 35
       <view class="grid-container">
36
+
36 37
         <view class="grid-item">
37 38
           <view class="grid-content flex j-sb a-center">
38
-            <view class="grid-title">1.您所在的服务区</view>
39
+            <view class="grid-title">1.您的身份是:</view>
40
+            <view class="grid-desc">
41
+              <u-select v-model="userTypeShow" :list="userTypeList" @confirm="userTypeconfirm"></u-select>
42
+              <span @click="userTypeShow = true">{{ userTypeName || '请选择' }}&nbsp;<span style="position: relative; top: -2px;">⌵</span></span>
43
+            </view>
44
+          </view>
45
+        </view>
46
+
47
+        <view class="grid-item">
48
+          <view class="grid-content flex j-sb a-center">
49
+            <view class="grid-title">2.您所在的服务区</view>
39 50
             <view class="grid-desc">
40 51
               <u-select v-model="parkSelectShow" :list="parkList" @confirm="confirm"></u-select>
41
-              <span @click="parkSelectShow = true">{{ parkName || '请选择' }}</span>
52
+              <span @click="parkSelectShow = true">{{ parkName || '请选择' }}&nbsp;<span style="position: relative; top: -2px;">⌵</span></span>
42 53
             </view>
43 54
           </view>
44 55
         </view>
45 56
         <view v-for="(item, index) in dataFilledIn" :key="item.id" class="grid-item">
46 57
           <view class="grid-content">
47
-            <view class="grid-title">{{ index + 2 }}. {{ item.name }}</view>
58
+            <view class="grid-title">{{ index + 3 }}. {{ item.name }}</view>
48 59
             <view class="grid-desc">
49 60
               <u-radio-group v-model="item.value">
50 61
                 <u-radio
@@ -61,27 +72,65 @@
61 72
         <!-- 最好的高速 -->
62 73
         <view class="grid-item">
63 74
           <view class="grid-content">
64
-            <view class="grid-title">{{ dataFilledIn.length + 2 }}. 您认为本服务区的最好的高速是?</view>
75
+            <view class="grid-title">{{ dataFilledIn.length + 3 }}. 您认为途经最好的高速是?</view>
65 76
             <view class="grid-desc">
66
-              <u-input v-model="bestWay" type="textarea" :border="false" :height="100" :auto-height="true" placeholder="请输入您的评价" />
77
+              <u-input v-model="bestWay" type="textarea" :border="false" :height="100" :auto-height="true" placeholder="请输入您认为途经最好的高速" />
67 78
             </view>
68 79
           </view>
69 80
         </view>
70 81
         <!-- 最好的服务区 -->
71 82
         <view class="grid-item">
72 83
           <view class="grid-content">
73
-            <view class="grid-title">{{ dataFilledIn.length + 3 }}. 您认为本服务区的最好的服务区是?</view>
84
+            <view class="grid-title">{{ dataFilledIn.length + 4 }}. 您认为途经最好的服务区是?</view>
74 85
             <view class="grid-desc">
75
-              <u-input v-model="bestService" type="textarea" :border="false" :height="100" :auto-height="true" placeholder="请输入您的评价" />
86
+              <u-input v-model="bestService" type="textarea" :border="false" :height="100" :auto-height="true" placeholder="请输入您认为途经最好的服务区" />
76 87
             </view>
77 88
           </view>
78 89
         </view>
79 90
 
80
-        <view class="submit-btn" @click="submitForm">
81
-          提 交
91
+        <!-- 宝贵意见 -->
92
+        <view class="grid-item">
93
+          <view class="grid-content">
94
+            <view class="grid-title">{{ dataFilledIn.length + 5 }}. 宝贵意见</view>
95
+            <view class="grid-desc">
96
+              <u-input v-model="opinion" type="textarea" :border="false" :height="100" :auto-height="true" placeholder="请输入宝贵意见" />
97
+            </view>
98
+          </view>
99
+        </view>
100
+
101
+        <view class="grid-item">
102
+          <view class="grid-content">
103
+            <view class="grid-title">您的手机号:</view>
104
+            <view class="grid-desc">
105
+              <u-input v-model="phone" type="number" :border="false" :height="100" :maxlength="11" :auto-height="true" placeholder="请输入您的手机号" />
106
+            </view>
107
+          </view>
108
+        </view>
109
+
110
+        <view 
111
+          class="submit-btn" 
112
+          @click="submitForm" 
113
+          :class="{ 'disabled': !isFormAvailable || isSubmitting || submitCountdown > 0 }" 
114
+          :disabled="!isFormAvailable || isSubmitting || submitCountdown > 0"
115
+        >
116
+          <span v-if="!isSubmitting && submitCountdown === 0">提 交</span>
117
+          <span v-else-if="isSubmitting">提交中...</span>
118
+          <span v-else>稍后提交({{ submitCountdown }}s)</span>
82 119
         </view>
83 120
       </view>
84 121
     </view>
122
+    <!-- 过了填报日期,弹窗提醒 -->
123
+    <u-mask :show="!isFormAvailable" :mask-click-able="false">
124
+      <view class="warp">
125
+        <view class="rect" @tap.stop>
126
+          <view class="rect-content">
127
+            <view class="rect-title">提示</view>
128
+            <view class="rect-desc">{{ msg || '当前时间已超过截止时间,无法填写' }}</view>
129
+            <view class="rect-btn" @click="goHome">去首页</view>
130
+          </view>
131
+        </view>
132
+      </view>
133
+	  </u-mask>
85 134
   </view>
86 135
 </template>
87 136
 
@@ -155,6 +204,36 @@
155 204
   const parkId = ref('')
156 205
   const parkName = ref('')
157 206
 
207
+  const phone = ref('')
208
+
209
+  const userTypeShow = ref(false)
210
+  const userTypeList = ref([
211
+    {
212
+      label: '大客司机',
213
+      value: 1
214
+    },
215
+    {
216
+      label: '大客乘客',
217
+      value: 2
218
+    },
219
+    {
220
+      label: '小客司乘人员',
221
+      value: 3
222
+    },
223
+    {
224
+      label: '货车司机',
225
+      value: 4
226
+    },
227
+    {
228
+      label: '其他',
229
+      value: 5
230
+    }
231
+  ])
232
+  const userTypeName = ref('')
233
+  const userType = ref('')
234
+
235
+  const opinion = ref('')
236
+
158 237
   // 获取服务区列表
159 238
   const getParkListApi = () => {
160 239
     getParkList().then(res => {
@@ -178,6 +257,13 @@
178 257
     });
179 258
   }
180 259
 
260
+  // 选择用户身份
261
+  const userTypeconfirm = (e) => {
262
+    console.log(e[0].value, e[0].label)
263
+    userTypeName.value = e[0].label
264
+    userType.value = e[0].value
265
+  }
266
+
181 267
   // 选择服务区
182 268
   const confirm = (e) => {
183 269
     console.log(e[0].value, e[0].label)
@@ -204,6 +290,63 @@
204 290
     type: 0
205 291
   })
206 292
 
293
+  // 是否超时,超时显示弹窗
294
+  const isFormAvailable = ref(true)
295
+
296
+  // 提交按钮相关状态
297
+  const isSubmitting = ref(false) // 是否正在提交
298
+  const submitCountdown = ref(0) // 提交倒计时(秒)
299
+
300
+  /**
301
+   * 验证问卷截止时间
302
+   * @param {string} endAt 截止时间字符串,格式为"YYYY-MM-DD HH:MM:SS"
303
+   */
304
+  const validateEndTime = (endAt) => {
305
+    try {
306
+      // 将字符串转换为日期对象(兼容不同浏览器)
307
+      const endDate = new Date(endAt.replace(/-/g, '/'))
308
+      const currentDate = new Date()
309
+      
310
+      // 比较当前时间与截止时间
311
+      if (currentDate <= endDate) {
312
+        isFormAvailable.value = true
313
+      } else {
314
+        isFormAvailable.value = false
315
+      }
316
+    } catch (error) {
317
+      console.error('时间验证失败:', error)
318
+      // 如果时间格式解析失败,默认允许填写
319
+      isFormAvailable.value = true
320
+    }
321
+  }
322
+
323
+  const goHome = () => {
324
+    uni.switchTab({
325
+      url: '/pages/index'
326
+    })
327
+  }
328
+
329
+  const msg = ref('')
330
+
331
+  /**
332
+   * 开始提交倒计时,限制5秒内只能提交一次
333
+   */
334
+  const startSubmitCountdown = () => {
335
+    const countdownTime = 5; // 倒计时时间(秒)
336
+    submitCountdown.value = countdownTime;
337
+    
338
+    // 创建倒计时定时器
339
+    const timer = setInterval(() => {
340
+      submitCountdown.value--;
341
+      
342
+      // 倒计时结束
343
+      if (submitCountdown.value <= 0) {
344
+        clearInterval(timer);
345
+        submitCountdown.value = 0;
346
+      }
347
+    }, 1000);
348
+  }
349
+
207 350
   // 根据页面参数获取问卷详情
208 351
   onMounted(() => {
209 352
     getParkListApi()
@@ -222,6 +365,7 @@
222 365
     getQuestionnaireDetailApi(questionnaireId).then(res => {
223 366
       if (res.code === 200) {
224 367
         questionnaireInfo.value = res.data
368
+        validateEndTime(questionnaireInfo.value.endAt)
225 369
         // 如果questionnaireInfo.value.type == 2,不显示‘车辆维修站’
226 370
         if (questionnaireInfo.value.type == 2) {
227 371
           dataFilledIn.value = dataList.value.filter(item => item.id != 6)
@@ -229,24 +373,60 @@
229 373
           dataFilledIn.value = dataList.value
230 374
         }
231 375
       } else {
232
-        uni.showToast({
233
-          title: res.message || '获取问卷详情失败',
234
-          icon: 'none'
235
-        });
376
+        msg.value = res.msg || '获取问卷详情失败'
377
+        isFormAvailable.value = false
378
+        // uni.showToast({
379
+        //   title: res.message || '获取问卷详情失败',
380
+        //   icon: 'none'
381
+        // });
236 382
       }
237 383
     }).catch(err => {
238
-      console.error('获取问卷详情失败:', err);
239
-      uni.showToast({
240
-        title: '网络错误,请重试',
241
-        icon: 'none'
242
-      });
384
+      // console.error('获取问卷详情失败:', err);
385
+      uni.hideToast()
386
+      msg.value = err.data.msg || '获取问卷详情失败'
387
+      isFormAvailable.value = false
388
+      // uni.showToast({
389
+      //   title: '网络错误,请重试',
390
+      //   icon: 'none'
391
+      // });
243 392
     });
244 393
   });
245 394
   
246 395
     // 提交表单
247 396
     const submitForm = () => {
397
+      // 检查表单是否可用
398
+      if (!isFormAvailable.value) {
399
+        uni.showToast({
400
+          title: '当前时间已超过截止时间,无法提交',
401
+          icon: 'none'
402
+        });
403
+        return;
404
+      }
405
+      
406
+      // 检查是否正在提交或处于倒计时状态
407
+      if (isSubmitting.value || submitCountdown.value > 0) {
408
+        return;
409
+      }
410
+      
248 411
       // 检查是否所有项都有选择
249 412
       const isComplete = dataFilledIn.value.every(item => item.value !== '');
413
+
414
+      if (!userType.value) {
415
+        uni.showToast({
416
+          title: '请选择身份',
417
+          icon: 'none'
418
+        });
419
+        return;
420
+      }
421
+      
422
+      if (!parkId.value) {
423
+        uni.showToast({
424
+          title: '请选择服务区',
425
+          icon: 'none'
426
+        });
427
+        return;
428
+      }
429
+
250 430
       if (!isComplete) {
251 431
         uni.showToast({
252 432
           title: '请完成所有项',
@@ -254,10 +434,26 @@
254 434
         });
255 435
         return;
256 436
       }
437
+      
438
+      if (!phone.value) {
439
+        uni.showToast({
440
+          title: '请输入手机号',
441
+          icon: 'none'
442
+        });
443
+        return;
444
+      }
257 445
 
258
-      if (!parkId.value) {
446
+      if (!bestWay.value) {
259 447
         uni.showToast({
260
-          title: '请选择服务区',
448
+          title: '请输入最好的高速',
449
+          icon: 'none'
450
+        });
451
+        return;
452
+      }
453
+
454
+      if (!bestService.value) {
455
+        uni.showToast({
456
+          title: '请输入最好的服务区',
261 457
           icon: 'none'
262 458
         });
263 459
         return;
@@ -308,12 +504,17 @@
308 504
       let params = {
309 505
         questionnaireId,
310 506
         // parkid, // 使用API要求的参数名
311
-        mobile,
507
+        mobile: phone.value,
508
+        userType: userType.value,
509
+        opinion: opinion.value,
312 510
         ...scoreData
313 511
       };
314 512
 
315 513
       console.log('提交参数:', params);
316 514
       
515
+      // 设置提交状态
516
+      isSubmitting.value = true;
517
+      
317 518
       // 调用API提交表单
318 519
       submitQuestionnaireApi(params).then(res => {
319 520
         if (res.code === 200) {
@@ -321,8 +522,10 @@
321 522
             title: '感谢您的反馈!',
322 523
             icon: 'success'
323 524
           });
525
+          // 提交成功后开始5秒倒计时
526
+          startSubmitCountdown();
324 527
           setTimeout(() => {
325
-            uni.redirectTo({
528
+            uni.switchTab({
326 529
               url: '/pages/index'
327 530
             })
328 531
           }, 2000);
@@ -338,6 +541,9 @@
338 541
           title: err.data.msg || '操作失败',
339 542
           icon: 'none'
340 543
         });
544
+      }).finally(() => {
545
+        // 无论成功失败,都恢复提交状态
546
+        isSubmitting.value = false;
341 547
       });
342 548
     }
343 549
 </script>
@@ -437,6 +643,7 @@
437 643
     display: flex;
438 644
     flex-direction: column;
439 645
     margin-bottom: 40rpx;
646
+    padding-bottom: 10px;
440 647
 
441 648
     .grid-content {
442 649
 
@@ -449,16 +656,18 @@
449 656
 
450 657
     // 提交按钮
451 658
     .submit-btn {
452
-      width: 100%;
453
-      height: 80rpx;
454
-      line-height: 80rpx;
659
+      width: calc(100% - 20px);
660
+      margin: auto;
661
+      height: 2.5rem;
662
+      line-height: 2.5rem;
455 663
       text-align: center;
456
-      font-size: 32rpx;
664
+      font-size: 1rem;
457 665
       font-weight: 600;
458 666
       color: #fff;
459 667
       background: linear-gradient(to bottom, #7EBBF5, #4B9EF6);
460
-      border-radius: 10rpx;
461
-      margin-top: 40rpx;
668
+      border-radius: 0.3125rem;
669
+      margin-top: 1.25rem;
670
+      padding: 0 10px;
462 671
       // position: absolute;
463 672
       // bottom: 0;
464 673
       // left: 0;
@@ -487,4 +696,39 @@
487 696
     display: flex;
488 697
     justify-content: center;
489 698
   }
699
+  .warp {
700
+		display: flex;
701
+		align-items: center;
702
+		justify-content: center;
703
+		height: 100%;
704
+	}
705
+
706
+	.rect {
707
+		width: 60vw;
708
+    max-width: 400px;
709
+    background-color: #fff;
710
+    border-radius: 12rpx;
711
+    padding: 30rpx 30rpx;
712
+
713
+    .rect-title {
714
+      font-size: 32rpx;
715
+      font-weight: 600;
716
+      color: #333;
717
+      margin-bottom: 20rpx;
718
+      text-align: center;
719
+    }
720
+
721
+    .rect-btn {
722
+      width: 100%;
723
+      height: 80rpx;
724
+      line-height: 80rpx;
725
+      text-align: center;
726
+      font-size: 32rpx;
727
+      font-weight: 600;
728
+      color: #fff;
729
+      background: linear-gradient(to bottom, #7EBBF5, #4B9EF6);
730
+      border-radius: 10rpx;
731
+      margin-top: 40rpx;
732
+    }
733
+	}
490 734
 </style>