2 İşlemeler 69e320b640 ... c69178b761

Yazar SHA1 Mesaj Tarih
  fengyu c69178b761 Merge branch 'develop' of ssh://gogs.zlhuiyun.com:8080/szr190/ShenhaiH5 into develop 2 ay önce
  fengyu 180b629091 问卷调查 2 ay önce

+ 1 - 0
.gitignore

@@ -13,6 +13,7 @@ dist
13 13
 *.local
14 14
 unpackage
15 15
 .env.development
16
+.history
16 17
 
17 18
 # Editor directories and files
18 19
 .idea

Dosya farkı çok büyük olduğundan ihmal edildi
+ 7279 - 2682
package-lock.json


BIN
public/images/wenjuan.png


+ 33 - 0
src/api/investigation.ts

@@ -0,0 +1,33 @@
1
+/*
2
+ * @Page: 文件描述
3
+ * @Author: Fengyu
4
+ * @Date: 2025-12-12 14:00:09
5
+ * @LastEditors: Fengyu
6
+ * @LastEditTime: 2025-12-15 17:16:22
7
+ */
8
+import { http } from '@/utils/http'
9
+
10
+/**
11
+ * @description: 问卷调查详情
12
+ * @param {*} data
13
+ * @return {*}
14
+ */
15
+export const getQuestionnaireDetailApi = (id: string) => {
16
+  return http({
17
+    method: 'GET',
18
+    url: '/questionnaire/' + id
19
+  })
20
+}
21
+
22
+/**
23
+ * @description: 问卷调查提交
24
+ * @param {*} data
25
+ * @return {*}
26
+ */
27
+export const submitQuestionnaireApi = (data: any) => {
28
+  return http({
29
+    method: 'POST',
30
+    url: '/questionnaire/answer',
31
+    data
32
+  })
33
+}

+ 7 - 0
src/api/login.ts

@@ -1,4 +1,11 @@
1 1
 /*
2
+ * @Page: 文件描述
3
+ * @Author: Fengyu
4
+ * @Date: 2025-12-11 16:03:49
5
+ * @LastEditors: Fengyu
6
+ * @LastEditTime: 2025-12-12 14:00:41
7
+ */
8
+/*
2 9
  * @Author: wyd
3 10
  * @Date: 2024-02
4 11
  * @LastEditors: wyd

+ 3 - 17
src/manifest.json

@@ -54,31 +54,17 @@
54 54
     "quickapp" : {},
55 55
     "h5" : {
56 56
         "router" : {
57
-            "base" : "./"
58
-        },
59
-        "sdkConfigs" : {
60
-            "maps" : {
61
-                "amap" : {
62
-                    "key" : "b0adb9cb4cae0dd05fae8d444c251492",
63
-                    "securityJsCode" : "337c8dbd6c3e800641d22c85ddb78b9e",
64
-                    "serviceHost" : ""
65
-                }
66
-            }
57
+            "base" : "./",
58
+            "mode" : "history"
67 59
         }
68 60
     },
69 61
     /* 小程序特有相关 */
70 62
     "mp-weixin" : {
71
-        "appid" : "",
63
+        "appid" : "wxa04f62d4bb823b36",
72 64
         "setting" : {
73 65
             "urlCheck" : false,
74 66
             "minified" : true
75 67
         },
76
-        "permission" : {
77
-            "scope.userLocation" : {
78
-                "desc" : "定位信息"
79
-            }
80
-        },
81
-        "requiredPrivateInfos" : [ "getLocation", "chooseLocation", "openLocation" ],
82 68
         "usingComponents" : true
83 69
     },
84 70
     "mp-alipay" : {

+ 9 - 1
src/pages.json

@@ -22,7 +22,15 @@
22 22
         "enablePullDownRefresh": false,
23 23
         "navigationStyle": "custom"
24 24
       }
25
-    }
25
+    },
26
+    {
27
+      "path": "pages/questionnaire",
28
+      "style": {
29
+        "navigationBarTitleText": "问卷调查",
30
+        "enablePullDownRefresh": false,
31
+        "navigationStyle": "custom"
32
+      }
33
+    },
26 34
   ],
27 35
   "subPackages": [
28 36
     {

+ 424 - 0
src/pages/questionnaire.vue

@@ -0,0 +1,424 @@
1
+<!--
2
+ * @Page: 问卷调查
3
+ * @Author: Fengyu
4
+ * @Date: 2025-12-12 10:12:59
5
+ * @LastEditors: Fengyu
6
+ * @LastEditTime: 2025-12-15 17:14:50
7
+-->
8
+<template>
9
+  <view class="questionnaire-container">
10
+    <!-- 顶部导航栏 -->
11
+    <!-- <view class="nav-bar">
12
+      <view class="nav-left">
13
+        <uni-icons type="left" size="32" color="#333" @click="goBack"></uni-icons>
14
+      </view>
15
+      <view class="nav-title">调查问卷</view>
16
+      <view class="nav-right">
17
+        <uni-icons type="ellipsis" size="32" color="#333"></uni-icons>
18
+        <uni-icons type="eye" size="32" color="#333" class="ml10"></uni-icons>
19
+      </view>
20
+    </view> -->
21
+
22
+    <!-- 问卷引导区域 -->
23
+    <view class="guide-section">
24
+      <view class="guide-content">
25
+        <view class="guide-text">
26
+          <view class="guide-title">问卷引导</view>
27
+          <view class="guide-desc">欢迎您对我们服务区提出建议反馈,我们会对您的问题进行全程跟踪</view>
28
+        </view>
29
+        <view class="guide-image"></view>
30
+      </view>
31
+    </view>
32
+
33
+    <!-- 网格选择区域 -->
34
+    <view class="grid-section">
35
+      <view class="grid-container">
36
+        <view v-for="(item, index) in dataFilledIn" :key="item.id" class="grid-item">
37
+          <view class="grid-content">
38
+            <view class="grid-title">{{ index + 1 }}. {{ item.name }}</view>
39
+            <view class="grid-desc">
40
+              <u-radio-group v-model="item.value">
41
+                <u-radio
42
+                  v-for="(t, i) in options" :key="i" 
43
+                  :name="t.value"
44
+                  :disabled="t.disabled"
45
+                >
46
+                  {{t.name}}
47
+                </u-radio>
48
+              </u-radio-group>
49
+            </view>
50
+          </view>
51
+        </view>
52
+        <!-- 最好的高速 -->
53
+        <view class="grid-item">
54
+          <view class="grid-content">
55
+            <view class="grid-title">{{ dataFilledIn.length + 1 }}. 您认为本服务区的最好的高速是?</view>
56
+            <view class="grid-desc">
57
+              <u-input v-model="bestWay" type="textarea" :border="false" :height="100" :auto-height="true" placeholder="请输入您的评价" />
58
+            </view>
59
+          </view>
60
+        </view>
61
+        <!-- 最好的服务区 -->
62
+        <view class="grid-item">
63
+          <view class="grid-content">
64
+            <view class="grid-title">{{ dataFilledIn.length + 2 }}. 您认为本服务区的最好的服务区是?</view>
65
+            <view class="grid-desc">
66
+              <u-input v-model="bestService" type="textarea" :border="false" :height="100" :auto-height="true" placeholder="请输入您的评价" />
67
+            </view>
68
+          </view>
69
+        </view>
70
+
71
+        <view class="submit-btn" @click="submitForm">
72
+          提 交
73
+        </view>
74
+      </view>
75
+    </view>
76
+  </view>
77
+</template>
78
+
79
+<script setup>
80
+  import { ref, onMounted } from 'vue'
81
+  import { getQuestionnaireDetailApi, submitQuestionnaireApi } from '@/api/investigation'
82
+
83
+  const dataList = ref([
84
+    {
85
+      id: 1,
86
+      name: '公共卫生间',
87
+      value: ''
88
+    },
89
+    {
90
+      id: 2,
91
+      name: '公共区域',
92
+      value: ''
93
+    },
94
+    {
95
+      id: 3,
96
+      name: '餐饮',
97
+      value: ''
98
+    },
99
+    {
100
+      id: 4,
101
+      name: '便利店',
102
+      value: ''
103
+    },
104
+    {
105
+      id: 5,
106
+      name: '加油(加气、充电)站',
107
+      value: ''
108
+    },
109
+    {
110
+      id: 6,
111
+      name: '车辆维修站',
112
+      value: ''
113
+    },
114
+    {
115
+      id: 7,
116
+      name: '对本服务区总体评价',
117
+      value: ''
118
+    }
119
+  ])
120
+
121
+  const options = ref([
122
+    {
123
+      name: '满意',
124
+      value: 1
125
+    },
126
+    {
127
+      name: '比较满意',
128
+      value: 2
129
+    },
130
+    {
131
+      name: '一般',
132
+      value: 3
133
+    },
134
+    {
135
+      name: '不满意',
136
+      value: 4
137
+    }
138
+  ])
139
+
140
+  // 最好的高速
141
+  const bestWay = ref('')
142
+
143
+  // 最好的服务区
144
+  const bestService = ref('')
145
+
146
+  // 动态的判断是否需要显示‘车辆维修站’
147
+  const dataFilledIn = ref([])
148
+
149
+  // 问卷信息
150
+  const questionnaireInfo = ref({
151
+    id: '',
152
+    name: '',
153
+    endAt: '',
154
+    fileId: 0,
155
+    type: 0
156
+  })
157
+
158
+  // 根据页面参数获取问卷详情
159
+  onMounted(() => {
160
+    // 使用URLSearchParams正确解析URL参数
161
+    const urlParams = new URLSearchParams(window.location.search);
162
+    const questionnaireId = urlParams.get('id');
163
+    
164
+    if (!questionnaireId) {
165
+      uni.showToast({
166
+        title: '问卷ID参数缺失',
167
+        icon: 'none'
168
+      });
169
+      return;
170
+    }
171
+    
172
+    getQuestionnaireDetailApi(questionnaireId).then(res => {
173
+      if (res.code === 200) {
174
+        questionnaireInfo.value = res.data
175
+        // 如果questionnaireInfo.value.type == 2,不显示‘车辆维修站’
176
+        if (questionnaireInfo.value.type == 2) {
177
+          dataFilledIn.value = dataList.value.filter(item => item.id != 6)
178
+        } else {
179
+          dataFilledIn.value = dataList.value
180
+        }
181
+      } else {
182
+        uni.showToast({
183
+          title: res.message || '获取问卷详情失败',
184
+          icon: 'none'
185
+        });
186
+      }
187
+    }).catch(err => {
188
+      console.error('获取问卷详情失败:', err);
189
+      uni.showToast({
190
+        title: '网络错误,请重试',
191
+        icon: 'none'
192
+      });
193
+    });
194
+  });
195
+  
196
+    // 提交表单
197
+    const submitForm = () => {
198
+      // 检查是否所有项都有选择
199
+      const isComplete = dataFilledIn.value.every(item => item.value !== '');
200
+      if (!isComplete) {
201
+        uni.showToast({
202
+          title: '请完成所有项',
203
+          icon: 'none'
204
+        });
205
+        return;
206
+      }
207
+      
208
+      // 解析URL参数
209
+      const urlParams = new URLSearchParams(window.location.search);
210
+      const questionnaireId = parseInt(questionnaireInfo.value.id) || 0;
211
+      // const parkid = parseInt(urlParams.get('parkid')) || 0; // 与API参数名保持一致
212
+      const mobile = urlParams.get('m') || '';
213
+      
214
+      // 验证必需参数
215
+      if (!questionnaireId || !mobile) {
216
+        uni.showToast({
217
+          title: '参数错误,请重新进入页面',
218
+          icon: 'none'
219
+        });
220
+        return;
221
+      }
222
+      
223
+      // 验证手机号格式
224
+      // const mobileRegex = /^1[3-9]\d{9}$/;
225
+      // if (!mobileRegex.test(mobile)) {
226
+      //   uni.showToast({
227
+      //     title: '手机号格式不正确',
228
+      //     icon: 'none'
229
+      //   });
230
+      //   return;
231
+      // }
232
+      
233
+      // 转换评分数据为targetA-G格式,确保为整数类型
234
+      const scoreData = {
235
+        targetA: parseInt(dataFilledIn.value.find(item => item.id === 1)?.value) || 0, // 公共卫生间
236
+        targetB: parseInt(dataFilledIn.value.find(item => item.id === 2)?.value) || 0, // 公共区域
237
+        targetC: parseInt(dataFilledIn.value.find(item => item.id === 3)?.value) || 0, // 餐饮
238
+        targetD: parseInt(dataFilledIn.value.find(item => item.id === 4)?.value) || 0, // 便利店
239
+        targetE: parseInt(dataFilledIn.value.find(item => item.id === 5)?.value) || 0, // 加油(加气、充电)站
240
+        targetF: parseInt(dataFilledIn.value.find(item => item.id === 6)?.value) || 0, // 车辆维修站
241
+        targetG: parseInt(dataFilledIn.value.find(item => item.id === 7)?.value) || 0, // 总体评价
242
+        bestWay: bestWay.value, // 最好的高速
243
+        bestService: bestService.value // 最好的服务区
244
+      };
245
+      
246
+      // 构建完整参数对象,确保与API要求一致
247
+      let params = {
248
+        questionnaireId,
249
+        // parkid, // 使用API要求的参数名
250
+        mobile,
251
+        ...scoreData
252
+      };
253
+
254
+      console.log('提交参数:', params);
255
+      
256
+      // 调用API提交表单
257
+      submitQuestionnaireApi(params).then(res => {
258
+        if (res.code === 200) {
259
+          uni.showToast({
260
+            title: '感谢您的反馈!',
261
+            icon: 'success'
262
+          });
263
+        } else {
264
+          uni.showToast({
265
+            title: res.message || '提交失败,请重试',
266
+            icon: 'none'
267
+          });
268
+        }
269
+      }).catch(err => {
270
+        console.error('提交失败:', err);
271
+        uni.showToast({
272
+          title: err.data.msg || '操作失败',
273
+          icon: 'none'
274
+        });
275
+      });
276
+    }
277
+</script>
278
+
279
+<style lang="scss" scoped>
280
+  .questionnaire-container {
281
+    width: 100%;
282
+    min-height: 100vh;
283
+    background-color: #f5f7fa;
284
+  }
285
+
286
+  /* 导航栏 */
287
+  .nav-bar {
288
+    display: flex;
289
+    align-items: center;
290
+    justify-content: space-between;
291
+    padding: 20rpx 30rpx;
292
+    background-color: #fff;
293
+  }
294
+
295
+  .nav-left,
296
+  .nav-right {
297
+    display: flex;
298
+    align-items: center;
299
+  }
300
+
301
+  .nav-title {
302
+    font-size: 32rpx;
303
+    font-weight: 600;
304
+    color: #333;
305
+  }
306
+
307
+  /* 问卷引导区域 */
308
+  .guide-section {
309
+    width: 100%;
310
+    height: 100vh;
311
+    /* 从上到下渐变样式 */
312
+    background: linear-gradient(to bottom, #9ED9FC, #F0F8FB 40%);
313
+    padding: 40rpx 30rpx;
314
+    position: absolute;
315
+    top: 0;
316
+    left: 0;
317
+    z-index: 2;
318
+    margin-bottom: 40rpx;
319
+  }
320
+  
321
+  .guide-content {
322
+    display: flex;
323
+    align-items: center;
324
+    justify-content: space-between;
325
+  }
326
+  
327
+  .guide-text {
328
+    flex: 1;
329
+    /* color: #fff; */
330
+  }
331
+  
332
+  .guide-title {
333
+    font-size: 32rpx;
334
+    font-weight: 600;
335
+    margin-bottom: 20rpx;
336
+  }
337
+
338
+  .guide-desc {
339
+    font-size: 24rpx;
340
+    line-height: 36rpx;
341
+  }
342
+  
343
+  .guide-image {
344
+    width: 300rpx;
345
+    height: 300rpx;
346
+    background: url('@/static/images/wenjuan.png') no-repeat center center;
347
+    background-size: 100%;
348
+  }
349
+  
350
+  .guide-image image {
351
+    width: 100%;
352
+    height: 100%;
353
+  }
354
+
355
+  /* 网格选择区域 */
356
+  .grid-section {
357
+    width: 90%;
358
+    /* height: 80vh; */
359
+    margin: 0 auto;
360
+    background-color: #fff;
361
+    position: relative;
362
+    top: 24vh;
363
+    z-index: 3;
364
+    border-radius: 20rpx;
365
+  }
366
+
367
+  .grid-container {
368
+    /* display: grid;
369
+    grid-template-columns: repeat(5, 1fr);
370
+    gap: 30rpx; */
371
+    display: flex;
372
+    flex-direction: column;
373
+    margin-bottom: 40rpx;
374
+
375
+    .grid-content {
376
+
377
+      .grid-title {
378
+        font-size: 28rpx;
379
+        font-weight: 600;
380
+        margin-bottom: 20rpx;
381
+      }
382
+    }
383
+
384
+    // 提交按钮
385
+    .submit-btn {
386
+      width: 100%;
387
+      height: 80rpx;
388
+      line-height: 80rpx;
389
+      text-align: center;
390
+      font-size: 32rpx;
391
+      font-weight: 600;
392
+      color: #fff;
393
+      background: linear-gradient(to bottom, #7EBBF5, #4B9EF6);
394
+      border-radius: 10rpx;
395
+      margin-top: 40rpx;
396
+      // position: absolute;
397
+      // bottom: 0;
398
+      // left: 0;
399
+      // z-index: 3;
400
+    }
401
+  }
402
+
403
+  .grid-item {
404
+    width: 100%;
405
+    background-color: #fff;
406
+    padding: 10px;
407
+    /* border: 2rpx solid #e4e7ed; */
408
+    border-radius: 10rpx;
409
+    box-sizing: border-box;
410
+    position: relative;
411
+    transition: all 0.3s ease;
412
+  }
413
+
414
+  .grid-item-selected {
415
+    background-color: #479bfa;
416
+    border-color: #479bfa;
417
+  }
418
+
419
+  /* 换一换按钮 */
420
+  .refresh-btn {
421
+    display: flex;
422
+    justify-content: center;
423
+  }
424
+</style>

BIN
src/static/images/wenjuan.png


+ 1 - 0
vite.config.ts

@@ -8,6 +8,7 @@ export default defineConfig(({ command, mode }) => {
8 8
   if (mode === 'development' || mode === 'sandbox') {
9 9
     // 测试环境配置
10 10
     return {
11
+      base: '/',
11 12
       plugins: [uni()],
12 13
       // envDir: resolve(__dirname, 'env'),
13 14
       define: {