refactor: 重构移动端页面布局与资源路径,优化打包配置
1. 新增layout.uts统一管理页面尺寸与安全区计算 2. 修正图片资源路径到static/mobile目录 3. 调整App.vue与AppIcon组件样式适配多端 4. 为微信小程序配置打包忽略规则减少包体积 5. 修复API请求错误抛出类型,完善类型定义 6. 补充README文档说明项目运行与维护规范 7. 优化多个页面的样式与生命周期逻辑
This commit is contained in:
@@ -1,24 +1,26 @@
|
||||
<template>
|
||||
<view class="assistant-page page">
|
||||
<view class="assistant-page page" :style="pageStyle()">
|
||||
<AppHeader title="AI融资助手" />
|
||||
<scroll-view scroll-y class="chat-scroll" :scroll-into-view="lastMessageId">
|
||||
<scroll-view scroll-y class="chat-scroll" :scroll-into-view="lastMessageId" :style="contentStyle(210, false)">
|
||||
<view class="chat-content">
|
||||
<view class="assistant-intro"><image src="/static/images/robot.png" mode="aspectFit"></image><view class="assistant-bubble"><text>您好!我是AI融资助手,可以帮您解答融资相关问题。</text></view></view>
|
||||
<view class="assistant-intro"><image src="/static/mobile/images/robot.png" mode="aspectFit" class="assistant-intro-image"></image><view class="assistant-bubble"><text>您好!我是AI融资助手,可以帮您解答融资相关问题。</text></view></view>
|
||||
<view class="quick-questions">
|
||||
<view class="question" v-for="item in questions" :key="item" @click="ask(item)"><text>{{ item }}</text><AppIcon name="chevron-right" :size="28" muted /></view>
|
||||
</view>
|
||||
<view v-for="(item,index) in messages" :key="index" :id="'message-' + index" :class="item.role == 'user' ? 'message-row user-row' : 'message-row'">
|
||||
<image v-if="item.role == 'assistant'" class="message-avatar" src="/static/images/robot.png" mode="aspectFit"></image>
|
||||
<image v-if="item.role == 'assistant'" class="message-avatar" src="/static/mobile/images/robot.png" mode="aspectFit"></image>
|
||||
<view :class="item.role == 'user' ? 'message-bubble user-bubble' : 'message-bubble'"><text>{{ item.text }}</text></view>
|
||||
</view>
|
||||
<view v-if="errorMessage.length > 0" class="assistant-error"><text>{{ errorMessage }}</text><text @click="retry">重试</text></view>
|
||||
<view v-if="errorMessage.length > 0" class="assistant-error"><text>{{ errorMessage }}</text><text @click="retry" class="assistant-error-text-last-child">重试</text></view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="chat-input"><input v-model="draft" confirm-type="send" @confirm="send" placeholder="请输入您的问题..." /><button @click="send"><AppIcon name="send" :size="34" /></button></view>
|
||||
<view class="chat-input" :style="bottomStyle(17)"><input v-model="draft" confirm-type="send" @confirm="send" placeholder="请输入您的问题..." class="chat-input-input" /><button @click="send" class="chat-input-button"><AppIcon name="send" :size="34" /></button></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { usePageLayout } from '@/services/layout.uts'
|
||||
const { bottomStyle, contentStyle, pageStyle } = usePageLayout()
|
||||
import AppHeader from '@/components/AppHeader.uvue'
|
||||
import AppIcon from '@/components/AppIcon.uvue'
|
||||
import { sendAssistantMessage } from '@/services/api.uts'
|
||||
@@ -29,7 +31,6 @@
|
||||
const lastQuestion = ref('')
|
||||
const sending = ref(false)
|
||||
const errorMessage = ref('')
|
||||
const ask = (text: string) => { draft.value = text; send() }
|
||||
const send = async () => {
|
||||
const text = draft.value.trim()
|
||||
if (text.length == 0 || sending.value) return
|
||||
@@ -41,12 +42,26 @@
|
||||
try { const answer = await sendAssistantMessage(text); messages.value.push({ role: 'assistant', text: answer }); lastMessageId.value = 'message-' + (messages.value.length - 1) } catch (error) { errorMessage.value = '消息发送失败,请稍后重试' }
|
||||
sending.value = false
|
||||
}
|
||||
const ask = (text: string) => { draft.value = text; send() }
|
||||
const retry = () => { draft.value = lastQuestion.value; errorMessage.value = ''; send() }
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.assistant-page { background-color: #f4f7fb; }.chat-scroll { height: calc(100vh - var(--status-bar-height) - 210rpx); }.chat-content { padding: 28rpx 26rpx 50rpx; }.assistant-intro { flex-direction: row; align-items: flex-start; }.assistant-intro image, .message-avatar { width: 78rpx; height: 78rpx; border-radius: 24rpx; background-color: #e7f2ff; margin-right: 16rpx; }.assistant-bubble, .message-bubble { max-width: 530rpx; padding: 24rpx; border-radius: 8rpx 22rpx 22rpx 22rpx; background-color: #fff; color: #344259; font-size: 25rpx; line-height: 42rpx; border: 1rpx solid #e4ebf5; }
|
||||
.quick-questions { margin: 25rpx 0 36rpx 94rpx; }.question { min-height: 72rpx; margin-top: 13rpx; padding: 14rpx 18rpx; border-radius: 16rpx; border: 2rpx solid #bcd9ff; background-color: #eef6ff; color: #0868f7; font-size: 23rpx; flex-direction: row; align-items: center; justify-content: space-between; }.question-arrow { font-size: 34rpx; }.message-row { margin-top: 22rpx; flex-direction: row; align-items: flex-start; }.user-row { justify-content: flex-end; }.user-bubble { color: #fff; background-color: #0868f7; border-color: #0868f7; border-radius: 22rpx 8rpx 22rpx 22rpx; }
|
||||
.chat-input { position: fixed; left: 0; right: 0; bottom: 0; min-height: 114rpx; padding: 17rpx 24rpx calc(17rpx + env(safe-area-inset-bottom)); background-color: #fff; border-top: 1rpx solid #e3eaf4; flex-direction: row; align-items: center; }.chat-input input { flex: 1; height: 78rpx; border-radius: 39rpx; background-color: #f2f5f9; padding: 0 28rpx; font-size: 25rpx; }.chat-input button { width: 76rpx; height: 76rpx; line-height: 76rpx; border-radius: 50%; margin-left: 15rpx; padding: 0; background-color: #0868f7; color: #fff; font-size: 29rpx; }
|
||||
.assistant-error { margin: 18rpx 0 0 94rpx; color: #e05a5a; font-size: 21rpx; flex-direction: row; justify-content: space-between; }.assistant-error text:last-child { color: #0868f7; margin-left: 18rpx; }
|
||||
.assistant-page { background-color: #f4f7fb; }
|
||||
.chat-scroll { }
|
||||
.chat-content { padding: 28rpx 26rpx 50rpx; }
|
||||
.assistant-intro { flex-direction: row; align-items: flex-start; }
|
||||
.assistant-intro-image, .message-avatar { width: 78rpx; height: 78rpx; border-radius: 24rpx; background-color: #e7f2ff; margin-right: 16rpx; }
|
||||
.assistant-bubble, .message-bubble { max-width: 530rpx; padding: 24rpx; border-radius: 8rpx 22rpx 22rpx 22rpx; background-color: #fff; color: #344259; font-size: 25rpx; line-height: 42rpx; border: 1rpx solid #e4ebf5; }
|
||||
.quick-questions { margin: 25rpx 0 36rpx 94rpx; }
|
||||
.question { min-height: 72rpx; margin-top: 13rpx; padding: 14rpx 18rpx; border-radius: 16rpx; border: 2rpx solid #bcd9ff; background-color: #eef6ff; color: #0868f7; font-size: 23rpx; flex-direction: row; align-items: center; justify-content: space-between; }
|
||||
.question-arrow { font-size: 34rpx; }
|
||||
.message-row { margin-top: 22rpx; flex-direction: row; align-items: flex-start; }
|
||||
.user-row { justify-content: flex-end; }
|
||||
.user-bubble { color: #fff; background-color: #0868f7; border-color: #0868f7; border-radius: 22rpx 8rpx 22rpx 22rpx; }
|
||||
.chat-input { position: fixed; left: 0; right: 0; bottom: 0; min-height: 114rpx; padding: 17rpx 24rpx; background-color: #fff; border-top: 1rpx solid #e3eaf4; flex-direction: row; align-items: center; }
|
||||
.chat-input-input { flex: 1; height: 78rpx; border-radius: 39rpx; background-color: #f2f5f9; padding: 0 28rpx; font-size: 25rpx; }
|
||||
.chat-input-button { width: 76rpx; height: 76rpx; line-height: 76rpx; border-radius: 50%; margin-left: 15rpx; padding: 0; background-color: #0868f7; color: #fff; font-size: 29rpx; }
|
||||
.assistant-error { margin: 18rpx 0 0 94rpx; color: #e05a5a; font-size: 21rpx; flex-direction: row; justify-content: space-between; }
|
||||
.assistant-error-text-last-child { color: #0868f7; margin-left: 18rpx; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user