Explorar o código

refactor: 重构AI聊天页面路由与冗余代码

1.  合并旧AI页面到ai-chat页面,删除冗余的ai/index.vue和api文件
2.  移除首页和工作页的AI悬浮按钮
3.  更新页面路由配置与登录跳转路径
4.  调整聊天输入框底部间距适配安全区域
huoyi hai 1 semana
pai
achega
d733464c79

+ 0 - 10
src/api/ai/ai.js

@@ -1,10 +0,0 @@
1
-import request from '@/utils/request'
2
-
3
-// AI 对话
4
-export function sendChatMessage(data) {
5
-  return request({
6
-    url: '/ai/chat',
7
-    method: 'post',
8
-    data: data
9
-  })
10
-}

+ 1 - 7
src/pages.json

@@ -262,12 +262,6 @@
262 262
       }
263 263
     },
264 264
     {
265
-      "path": "pages/ai/index",
266
-      "style": {
267
-        "navigationBarTitleText": "AI问答"
268
-      }
269
-    },
270
-    {
271 265
       "path": "pages/announcement/index",
272 266
       "style": {
273 267
         "navigationBarTitleText": "公告"
@@ -398,7 +392,7 @@
398 392
         "text": "消息"
399 393
       },
400 394
       {
401
-        "pagePath": "pages/ai/index",
395
+        "pagePath": "pages/ai-chat/index",
402 396
         "iconPath": "static/images/tabbar/ai.png",
403 397
         "selectedIconPath": "static/images/tabbar/ai_.png",
404 398
         "text": "AI问答"

+ 1 - 0
src/pages/ai-chat/index.vue

@@ -721,6 +721,7 @@ $text-sub: #999;
721 721
   background: #fff;
722 722
   border-top: 1rpx solid #eee;
723 723
   gap: 16rpx;
724
+  margin-bottom: 93rpx;
724 725
 }
725 726
 .input {
726 727
   flex: 1;

+ 0 - 323
src/pages/ai/index.vue

@@ -1,323 +0,0 @@
1
-<template>
2
-  <view class="ai-chat-page">
3
-    <!-- 消息列表 -->
4
-    <scroll-view
5
-      class="message-list"
6
-      scroll-y
7
-      :scroll-into-view="scrollToId"
8
-      @scrolltoupper="loadMore"
9
-      enable-back-to-top
10
-    >
11
-      <view class="messages-wrapper">
12
-        <view
13
-          v-for="(msg, index) in messages"
14
-          :key="msg.id"
15
-          :id="'msg-' + msg.id"
16
-          class="message-item"
17
-          :class="msg.role === 'user' ? 'user-msg' : 'ai-msg'"
18
-        >
19
-          <!-- AI 头像 -->
20
-          <view v-if="msg.role !== 'user'" class="avatar ai-avatar">
21
-            <text class="avatar-text">AI</text>
22
-          </view>
23
-          <view class="bubble-wrapper">
24
-            <view class="bubble" :class="msg.role === 'user' ? 'user-bubble' : 'ai-bubble'">
25
-              <text class="bubble-text">{{ msg.content }}</text>
26
-              <view v-if="msg.role === 'assistant' && index === messages.length - 1 && loading" class="typing-dots">
27
-                <text class="dot">.</text>
28
-                <text class="dot">.</text>
29
-                <text class="dot">.</text>
30
-              </view>
31
-            </view>
32
-          </view>
33
-          <!-- 用户头像 -->
34
-          <view v-if="msg.role === 'user'" class="avatar user-avatar">
35
-            <text class="avatar-text">我</text>
36
-          </view>
37
-        </view>
38
-      </view>
39
-    </scroll-view>
40
-
41
-    <!-- 输入区域 -->
42
-    <view class="input-area">
43
-      <view class="input-wrapper">
44
-        <input
45
-          v-model="inputText"
46
-          class="chat-input"
47
-          type="text"
48
-          placeholder="请输入您的问题..."
49
-          placeholder-class="placeholder-style"
50
-          :disabled="loading"
51
-          @confirm="sendMessage"
52
-          confirm-type="send"
53
-        />
54
-        <view class="send-btn" :class="{ disabled: !inputText.trim() || loading }" @click="sendMessage">
55
-          <text class="send-icon">↑</text>
56
-        </view>
57
-      </view>
58
-    </view>
59
-  </view>
60
-</template>
61
-
62
-<script>
63
-import { sendChatMessage } from '@/api/ai/ai'
64
-
65
-let msgId = 0
66
-
67
-export default {
68
-  data() {
69
-    return {
70
-      inputText: '',
71
-      messages: [],
72
-      loading: false,
73
-      scrollToId: ''
74
-    }
75
-  },
76
-  onLoad() {
77
-    this.addWelcomeMessage()
78
-  },
79
-  methods: {
80
-    addWelcomeMessage() {
81
-      this.messages.push({
82
-        id: ++msgId,
83
-        role: 'assistant',
84
-        content: '您好!我是智慧安检 AI 助手,有什么可以帮助您的吗?'
85
-      })
86
-      this.$nextTick(() => {
87
-        this.scrollToBottom()
88
-      })
89
-    },
90
-    async sendMessage() {
91
-      const text = this.inputText.trim()
92
-      if (!text || this.loading) return
93
-
94
-      // 添加用户消息
95
-      this.messages.push({
96
-        id: ++msgId,
97
-        role: 'user',
98
-        content: text
99
-      })
100
-      this.inputText = ''
101
-      this.scrollToBottom()
102
-
103
-      // 添加占位 AI 消息
104
-      this.loading = true
105
-      const aiMsgId = ++msgId
106
-      this.messages.push({
107
-        id: aiMsgId,
108
-        role: 'assistant',
109
-        content: ''
110
-      })
111
-      this.scrollToBottom()
112
-
113
-      try {
114
-        const res = await sendChatMessage({
115
-          message: text,
116
-          history: this.messages
117
-            .filter(m => m.content)
118
-            .slice(-10)
119
-            .map(m => ({
120
-              role: m.role,
121
-              content: m.content
122
-            }))
123
-        })
124
-        const reply = res?.data?.reply || res?.data?.content || '抱歉,我暂时无法回答这个问题,请稍后再试。'
125
-        // 更新 AI 回复
126
-        const aiMsg = this.messages.find(m => m.id === aiMsgId)
127
-        if (aiMsg) {
128
-          aiMsg.content = reply
129
-        }
130
-      } catch (error) {
131
-        const aiMsg = this.messages.find(m => m.id === aiMsgId)
132
-        if (aiMsg) {
133
-          aiMsg.content = '网络开小差了,请稍后再试。'
134
-        }
135
-      } finally {
136
-        this.loading = false
137
-        this.$nextTick(() => {
138
-          this.scrollToBottom()
139
-        })
140
-      }
141
-    },
142
-    scrollToBottom() {
143
-      if (this.messages.length > 0) {
144
-        this.scrollToId = 'msg-' + this.messages[this.messages.length - 1].id
145
-      }
146
-    },
147
-    loadMore() {
148
-      // 预留加载更多历史消息
149
-    }
150
-  }
151
-}
152
-</script>
153
-
154
-<style lang="scss" scoped>
155
-.ai-chat-page {
156
-  display: flex;
157
-  flex-direction: column;
158
-  height: 100vh;
159
-  background-color: #f5f5f5;
160
-  padding-top: var(--status-bar-height);
161
-}
162
-
163
-.message-list {
164
-  flex: 1;
165
-  overflow-y: auto;
166
-  -webkit-overflow-scrolling: touch;
167
-}
168
-
169
-.messages-wrapper {
170
-  padding: 20rpx 30rpx;
171
-  padding-bottom: 30rpx;
172
-}
173
-
174
-.message-item {
175
-  display: flex;
176
-  align-items: flex-start;
177
-  margin-bottom: 30rpx;
178
-
179
-  &.user-msg {
180
-    justify-content: flex-end;
181
-  }
182
-
183
-  &.ai-msg {
184
-    justify-content: flex-start;
185
-  }
186
-}
187
-
188
-.avatar {
189
-  width: 64rpx;
190
-  height: 64rpx;
191
-  border-radius: 50%;
192
-  display: flex;
193
-  align-items: center;
194
-  justify-content: center;
195
-  flex-shrink: 0;
196
-
197
-  .avatar-text {
198
-    font-size: 24rpx;
199
-    font-weight: bold;
200
-    color: #fff;
201
-  }
202
-}
203
-
204
-.ai-avatar {
205
-  background: linear-gradient(135deg, #409EFF, #36cfc9);
206
-  margin-right: 16rpx;
207
-}
208
-
209
-.user-avatar {
210
-  background: linear-gradient(135deg, #36d399, #409EFF);
211
-  margin-left: 16rpx;
212
-}
213
-
214
-.bubble-wrapper {
215
-  max-width: 70%;
216
-  display: flex;
217
-}
218
-
219
-.bubble {
220
-  padding: 20rpx 24rpx;
221
-  border-radius: 12rpx;
222
-  font-size: 28rpx;
223
-  line-height: 1.6;
224
-  word-break: break-word;
225
-}
226
-
227
-.user-bubble {
228
-  background: linear-gradient(135deg, #409EFF, #36cfc9);
229
-  color: #fff;
230
-  border-bottom-right-radius: 4rpx;
231
-}
232
-
233
-.ai-bubble {
234
-  background: #fff;
235
-  color: #333;
236
-  border-bottom-left-radius: 4rpx;
237
-  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
238
-}
239
-
240
-.bubble-text {
241
-  white-space: pre-wrap;
242
-}
243
-
244
-.typing-dots {
245
-  display: inline-flex;
246
-  align-items: center;
247
-  margin-left: 4rpx;
248
-
249
-  .dot {
250
-    font-size: 40rpx;
251
-    line-height: 1;
252
-    color: #999;
253
-    animation: blink 1.4s infinite both;
254
-
255
-    &:nth-child(2) {
256
-      animation-delay: 0.2s;
257
-    }
258
-
259
-    &:nth-child(3) {
260
-      animation-delay: 0.4s;
261
-    }
262
-  }
263
-}
264
-
265
-@keyframes blink {
266
-  0%, 80%, 100% {
267
-    opacity: 0;
268
-  }
269
-  40% {
270
-    opacity: 1;
271
-  }
272
-}
273
-
274
-/* 输入区域 */
275
-.input-area {
276
-  padding: 16rpx 24rpx;
277
-  padding-bottom: calc(16rpx + env(safe-area-inset-bottom));
278
-  background: #fff;
279
-  border-top: 1rpx solid #eee;
280
-}
281
-
282
-.input-wrapper {
283
-  display: flex;
284
-  align-items: center;
285
-  gap: 16rpx;
286
-}
287
-
288
-.chat-input {
289
-  flex: 1;
290
-  height: 72rpx;
291
-  background: #f5f5f5;
292
-  border-radius: 36rpx;
293
-  padding: 0 30rpx;
294
-  font-size: 28rpx;
295
-  color: #333;
296
-}
297
-
298
-.placeholder-style {
299
-  color: #999;
300
-  font-size: 28rpx;
301
-}
302
-
303
-.send-btn {
304
-  width: 72rpx;
305
-  height: 72rpx;
306
-  border-radius: 50%;
307
-  background: linear-gradient(135deg, #409EFF, #36cfc9);
308
-  display: flex;
309
-  align-items: center;
310
-  justify-content: center;
311
-  flex-shrink: 0;
312
-
313
-  &.disabled {
314
-    opacity: 0.4;
315
-  }
316
-
317
-  .send-icon {
318
-    color: #fff;
319
-    font-size: 36rpx;
320
-    font-weight: bold;
321
-  }
322
-}
323
-</style>

+ 1 - 27
src/pages/home/index.vue

@@ -37,10 +37,6 @@
37 37
       </div>
38 38
     </div>
39 39
 
40
-    <!-- AI助手悬浮按钮 -->
41
-    <view class="ai-float-btn" @click="openAiChat">
42
-      <text class="ai-float-icon">AI</text>
43
-    </view>
44 40
 
45 41
     <Notice ref="notice" />
46 42
     <!--  今日待办  -->
@@ -123,9 +119,7 @@ export default {
123 119
 
124 120
   },
125 121
   methods: {
126
-    openAiChat() {
127
-      uni.navigateTo({ url: '/pages/ai-chat/index' });
128
-    },
122
+
129 123
     goworkDocu() {
130 124
       uni.navigateTo({
131 125
         url: '/pages/workDocu/index'
@@ -376,24 +370,4 @@ img {
376 370
   margin-bottom: 32rpx;
377 371
 }
378 372
 
379
-.ai-float-btn {
380
-  position: fixed;
381
-  right: 40rpx;
382
-  bottom: 180rpx;
383
-  width: 100rpx;
384
-  height: 100rpx;
385
-  border-radius: 50%;
386
-  background: linear-gradient(135deg, #1890ff, #096dd9);
387
-  display: flex;
388
-  align-items: center;
389
-  justify-content: center;
390
-  box-shadow: 0 8rpx 24rpx rgba(24, 144, 255, 0.45);
391
-  z-index: 99;
392
-}
393
-.ai-float-icon {
394
-  color: #fff;
395
-  font-size: 28rpx;
396
-  font-weight: 700;
397
-  letter-spacing: 2rpx;
398
-}
399 373
 </style>

+ 2 - 2
src/pages/login.vue

@@ -78,7 +78,7 @@ export default {
78 78
   onLoad() {
79 79
     //#ifdef H5
80 80
     if (getToken()) {
81
-      this.$tab.reLaunch('/pages/work/index')
81
+      this.$tab.reLaunch('/pages/myToDoList/index')
82 82
     }
83 83
     this.getStorage()
84 84
     //#endif
@@ -164,7 +164,7 @@ export default {
164 164
       this.$store.dispatch('GetInfo').then(res => {
165 165
         // 登录成功后调用showMessageTabRedDot更新消息tab红点状态
166 166
         showMessageTabRedDot()
167
-        this.$tab.reLaunch('/pages/work/index')
167
+        this.$tab.reLaunch('/pages/myToDoList/index')
168 168
       })
169 169
     }
170 170
   }

+ 3 - 27
src/pages/work/index.vue

@@ -34,10 +34,7 @@
34 34
       </view>
35 35
     </div>
36 36
 
37
-    <!-- AI助手悬浮按钮 -->
38
-    <view class="ai-float-btn" @click="openAiChat">
39
-      <text class="ai-float-icon">AI</text>
40
-    </view>
37
+   
41 38
   </home-container>
42 39
 </template>
43 40
 <script>
@@ -98,9 +95,7 @@ export default {
98 95
     updateCurrentDate() {
99 96
       this.currentDate = this.formatDate(new Date());
100 97
     },
101
-    openAiChat() {
102
-      uni.navigateTo({ url: '/pages/ai-chat/index' });
103
-    },
98
+   
104 99
     handleGridClick(url) {
105 100
       console.log('点击了宫格:', url, this.role);
106 101
       uni.navigateTo({
@@ -227,24 +222,5 @@ export default {
227 222
   color: #999;
228 223
 }
229 224
 
230
-.ai-float-btn {
231
-  position: fixed;
232
-  right: 40rpx;
233
-  bottom: 180rpx;
234
-  width: 100rpx;
235
-  height: 100rpx;
236
-  border-radius: 50%;
237
-  background: linear-gradient(135deg, #1890ff, #096dd9);
238
-  display: flex;
239
-  align-items: center;
240
-  justify-content: center;
241
-  box-shadow: 0 8rpx 24rpx rgba(24, 144, 255, 0.45);
242
-  z-index: 99;
243
-}
244
-.ai-float-icon {
245
-  color: #fff;
246
-  font-size: 28rpx;
247
-  font-weight: 700;
248
-  letter-spacing: 2rpx;
249
-}
225
+
250 226
 </style>