feat(ai-house): 重构找房聊天交互
This commit is contained in:
@@ -3,6 +3,14 @@ import http from './index.js';
|
|||||||
// AI找房问答
|
// AI找房问答
|
||||||
export const sendHouseAiMessage = (data) => http.post('/house/ai-chat/message', data)
|
export const sendHouseAiMessage = (data) => http.post('/house/ai-chat/message', data)
|
||||||
|
|
||||||
|
// 清空当前AI找房会话
|
||||||
|
export const clearHouseAiSession = (data) => http.post('/house/ai-chat/session/clear', data)
|
||||||
|
|
||||||
|
// 无候选时提交找房咨询线索
|
||||||
|
export const submitHouseAiLead = (data) => http.post('/house/house-message/ai-agent', data)
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
sendHouseAiMessage
|
sendHouseAiMessage,
|
||||||
|
clearHouseAiSession,
|
||||||
|
submitHouseAiLead
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,43 +33,26 @@
|
|||||||
<view class="form-title">您想要找什么样的房型?</view>
|
<view class="form-title">您想要找什么样的房型?</view>
|
||||||
<view class="form-item">
|
<view class="form-item">
|
||||||
<text class="form-label">多少平方</text>
|
<text class="form-label">多少平方</text>
|
||||||
<input
|
<input v-model="form.extent" class="form-input" type="text" placeholder="请输入面积" :disabled="loading" />
|
||||||
v-model="form.extent"
|
|
||||||
class="form-input"
|
|
||||||
type="text"
|
|
||||||
placeholder="请输入面积"
|
|
||||||
:disabled="loading"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="form-item">
|
<view class="form-item">
|
||||||
<text class="form-label">多少楼层</text>
|
<text class="form-label">多少楼层</text>
|
||||||
<input
|
<input v-model="form.floor" class="form-input" type="text" placeholder="请输入楼层" :disabled="loading" />
|
||||||
v-model="form.floor"
|
|
||||||
class="form-input"
|
|
||||||
type="text"
|
|
||||||
placeholder="请输入楼层"
|
|
||||||
:disabled="loading"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="form-item">
|
<view class="form-item">
|
||||||
<text class="form-label">多少租金</text>
|
<text class="form-label">多少租金</text>
|
||||||
<input
|
<input v-model="form.rent" class="form-input" type="text" placeholder="请输入租金" :disabled="loading" />
|
||||||
v-model="form.rent"
|
|
||||||
class="form-input"
|
|
||||||
type="text"
|
|
||||||
placeholder="请输入租金"
|
|
||||||
:disabled="loading"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="form-item">
|
<view class="form-item">
|
||||||
<text class="form-label">什么地段</text>
|
<text class="form-label">什么地段</text>
|
||||||
<input
|
<input v-model="form.location" class="form-input" type="text" placeholder="请输入地段" :disabled="loading" />
|
||||||
v-model="form.location"
|
</view>
|
||||||
class="form-input"
|
<view
|
||||||
type="text"
|
class="finder-submit"
|
||||||
placeholder="请输入地段"
|
:class="{ 'finder-submit-disabled': loading }"
|
||||||
:disabled="loading"
|
@click="submitFinderForm"
|
||||||
/>
|
>
|
||||||
|
{{ loading ? '提交中...' : '提交找房需求' }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-else-if="message.type === 'messageForm'" class="message-form-message">
|
<view v-else-if="message.type === 'messageForm'" class="message-form-message">
|
||||||
@@ -164,13 +147,14 @@
|
|||||||
class="house-card"
|
class="house-card"
|
||||||
@click="goHouseDetail(item)"
|
@click="goHouseDetail(item)"
|
||||||
>
|
>
|
||||||
<image class="house-image" :src="item.files[0].url" mode="aspectFill"></image>
|
<image v-if="item.files && item.files.length" class="house-image" :src="item.files[0].url" mode="aspectFill"></image>
|
||||||
|
<view v-else class="house-image house-image-empty"></view>
|
||||||
<view class="house-info">
|
<view class="house-info">
|
||||||
<view class="house-title">{{ item.houseTitle }}</view>
|
<view class="house-title">{{ item.houseTitle }}</view>
|
||||||
<view v-if="item.matchReason" class="house-match-reason">{{ item.matchReason }}</view>
|
<view v-if="item.matchReason" class="house-match-reason">{{ item.matchReason }}</view>
|
||||||
<view class="house-location">{{ item.address || item.region || item.city || '位置待补充' }}</view>
|
<view class="house-location">{{ item.address || item.region || item.city || '位置待补充' }}</view>
|
||||||
<view class="house-desc">{{ item.extent }}m²|{{ item.toward }}</view>
|
<view class="house-desc">{{ item.extent }}m²|{{ item.toward }}</view>
|
||||||
<view class="house-price">{{ item.monthlyRent }}元/月</view>
|
<view class="house-price">{{ item.monthlyRent ? item.monthlyRent + '元/月' : (item.totalPrice || item.salePrice || '价格待确认') }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -189,6 +173,7 @@
|
|||||||
<view class="typing-dot"></view>
|
<view class="typing-dot"></view>
|
||||||
<view class="typing-dot"></view>
|
<view class="typing-dot"></view>
|
||||||
<view class="typing-dot"></view>
|
<view class="typing-dot"></view>
|
||||||
|
<text class="typing-text">{{ progressText || '正在处理中' }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view id="page-bottom-anchor" class="page-bottom-anchor"></view>
|
<view id="page-bottom-anchor" class="page-bottom-anchor"></view>
|
||||||
@@ -196,15 +181,24 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="input-panel">
|
<view class="input-panel">
|
||||||
<view class="tag-row">
|
<view class="quick-question-row">
|
||||||
<view class="finder-tag" :class="{ active: showFinderForm }" @click="toggleFinderForm">找房</view>
|
<view class="finder-tag" :class="{ active: showFinderForm }" @click="toggleFinderForm">找房</view>
|
||||||
|
<view
|
||||||
|
v-for="item in quickQuestions"
|
||||||
|
:key="item.label"
|
||||||
|
class="quick-question"
|
||||||
|
:class="{ 'quick-question-disabled': loading }"
|
||||||
|
@click="askQuickQuestion(item.question)"
|
||||||
|
>
|
||||||
|
{{ item.label }}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="input-row">
|
<view class="input-row">
|
||||||
<input
|
<input
|
||||||
v-model="inputText"
|
v-model="inputText"
|
||||||
class="chat-input"
|
class="chat-input"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="可补充户型、朝向、电梯等偏好"
|
placeholder="输入找房需求或房源相关问题"
|
||||||
:disabled="loading"
|
:disabled="loading"
|
||||||
confirm-type="send"
|
confirm-type="send"
|
||||||
@confirm="handlePrimaryAction"
|
@confirm="handlePrimaryAction"
|
||||||
@@ -228,10 +222,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as HouseInfoApi from '@/api/house-info.js'
|
|
||||||
import * as HouseAiConfigApi from '@/api/house-ai-config.js'
|
import * as HouseAiConfigApi from '@/api/house-ai-config.js'
|
||||||
import * as HouseAiChatApi from '@/api/house-ai-chat.js'
|
import * as HouseAiChatApi from '@/api/house-ai-chat.js'
|
||||||
import * as HouseMessageApi from '@/api/house-message.js'
|
|
||||||
import storage from '@/utils/storage.js'
|
import storage from '@/utils/storage.js'
|
||||||
import { USER_ID } from '@/store/mutation-types.js'
|
import { USER_ID } from '@/store/mutation-types.js'
|
||||||
import { apiUrl } from '@/config.js'
|
import { apiUrl } from '@/config.js'
|
||||||
@@ -239,19 +231,34 @@
|
|||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
quickQuestions: [
|
||||||
|
{
|
||||||
|
label: '面积和价格',
|
||||||
|
question: '这套房的面积和价格是多少?'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '物业和水电',
|
||||||
|
question: '这套房的物业费和水电怎么收费?'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '空调和停车',
|
||||||
|
question: '这套房有空调和停车位吗?'
|
||||||
|
}
|
||||||
|
],
|
||||||
inputText: '',
|
inputText: '',
|
||||||
loading: false,
|
loading: false,
|
||||||
|
progressText: '',
|
||||||
messages: [],
|
messages: [],
|
||||||
showFinderForm: false,
|
showFinderForm: false,
|
||||||
messageFormOpened: false,
|
|
||||||
messageSubmitting: false,
|
|
||||||
messageSubmitted: false,
|
|
||||||
form: {
|
form: {
|
||||||
extent: '',
|
extent: '',
|
||||||
floor: '',
|
floor: '',
|
||||||
rent: '',
|
rent: '',
|
||||||
location: ''
|
location: ''
|
||||||
},
|
},
|
||||||
|
messageFormOpened: false,
|
||||||
|
messageSubmitting: false,
|
||||||
|
messageSubmitted: false,
|
||||||
messageForm: {
|
messageForm: {
|
||||||
realName: '',
|
realName: '',
|
||||||
phone: '',
|
phone: '',
|
||||||
@@ -267,29 +274,7 @@
|
|||||||
socketConnected: false,
|
socketConnected: false,
|
||||||
heartbeatTimer: null,
|
heartbeatTimer: null,
|
||||||
loginUserId: null,
|
loginUserId: null,
|
||||||
timer: null,
|
nextMessageId: 0
|
||||||
nextMessageId: 0,
|
|
||||||
allHouses: [],
|
|
||||||
fallbackHouses: [
|
|
||||||
{
|
|
||||||
houseId: 'mock-1',
|
|
||||||
houseTitle: '富雅国际金融中心',
|
|
||||||
extent: '75.03',
|
|
||||||
toward: '东',
|
|
||||||
monthlyRent: '3376.35',
|
|
||||||
address: '五象新区总部基地',
|
|
||||||
files: [{ url: 'https://oss.wsdns.cn/20240708/9e1f58e7fc7b4bad92edd852ff34dbcb.png?x-oss-process=image/resize,w_750/quality,Q_90' }]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
houseId: 'mock-2',
|
|
||||||
houseTitle: '五象航洋城3号楼',
|
|
||||||
extent: '180',
|
|
||||||
toward: '西',
|
|
||||||
monthlyRent: '5508',
|
|
||||||
address: '五象新区航洋商圈',
|
|
||||||
files: [{ url: 'https://oss.wsdns.cn/20240708/c95838b78b5746eb934daffb12a2efdc.png?x-oss-process=image/resize,w_750/quality,Q_90' }]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -317,17 +302,59 @@
|
|||||||
}, 300)
|
}, 300)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.conversationId = `house-ai-${this.loginUserId || 'guest'}`
|
this.conversationId = `house-ai-${this.loginUserId}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`
|
||||||
this.connectWebSocket()
|
this.connectWebSocket()
|
||||||
this.loadAiConfig()
|
this.loadAiConfig()
|
||||||
this.loadHouseList()
|
|
||||||
},
|
},
|
||||||
onUnload() {
|
onUnload() {
|
||||||
this.clearMockTimer()
|
if (this.conversationId) {
|
||||||
|
HouseAiChatApi.clearHouseAiSession({
|
||||||
|
conversationId: this.conversationId
|
||||||
|
}).catch(() => {})
|
||||||
|
}
|
||||||
this.closeWebSocket()
|
this.closeWebSocket()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
createMessage(role, type, extra = {}) {
|
askQuickQuestion(question) {
|
||||||
|
if (this.loading) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.showFinderForm = false
|
||||||
|
this.inputText = question
|
||||||
|
this.sendMessage()
|
||||||
|
},
|
||||||
|
toggleFinderForm() {
|
||||||
|
if (this.loading) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.showFinderForm = !this.showFinderForm
|
||||||
|
if (this.showFinderForm) {
|
||||||
|
this.messages = [
|
||||||
|
this.createMessage('ai', 'text', {
|
||||||
|
content: this.aiConfig.welcomeMessage || '您好,我是AI找房助手,请告诉我您的找房需求。'
|
||||||
|
}),
|
||||||
|
this.createMessage('ai', 'form')
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
this.appendWelcomeMessage()
|
||||||
|
}
|
||||||
|
this.scrollToBottom()
|
||||||
|
},
|
||||||
|
submitFinderForm() {
|
||||||
|
if (this.loading) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const question = this.buildFormQuestion()
|
||||||
|
if (!question) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请完整填写找房条件',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.sendMessage(question)
|
||||||
|
},
|
||||||
|
createMessage(role, type, extra = {}) {
|
||||||
const id = `msg-${this.nextMessageId++}`
|
const id = `msg-${this.nextMessageId++}`
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
@@ -338,8 +365,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
startNewChat() {
|
startNewChat() {
|
||||||
this.clearMockTimer()
|
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
this.progressText = ''
|
||||||
this.showFinderForm = false
|
this.showFinderForm = false
|
||||||
this.messageFormOpened = false
|
this.messageFormOpened = false
|
||||||
this.messageSubmitting = false
|
this.messageSubmitting = false
|
||||||
@@ -367,9 +394,6 @@
|
|||||||
})
|
})
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
appendMessageFormCard() {
|
|
||||||
// this.messages.push(this.createMessage('ai', 'messageForm'))
|
|
||||||
},
|
|
||||||
async loadAiConfig() {
|
async loadAiConfig() {
|
||||||
this.aiConfigLoaded = false
|
this.aiConfigLoaded = false
|
||||||
try {
|
try {
|
||||||
@@ -388,26 +412,6 @@
|
|||||||
this.aiConfigLoaded = true
|
this.aiConfigLoaded = true
|
||||||
this.startNewChat()
|
this.startNewChat()
|
||||||
this.appendWelcomeMessage()
|
this.appendWelcomeMessage()
|
||||||
this.appendMessageFormCard()
|
|
||||||
this.scrollToBottom()
|
|
||||||
},
|
|
||||||
toggleFinderForm() {
|
|
||||||
if (this.loading) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.showFinderForm = !this.showFinderForm
|
|
||||||
if (this.showFinderForm) {
|
|
||||||
this.messages = [
|
|
||||||
this.createMessage('ai', 'text', {
|
|
||||||
content: this.aiConfig.welcomeMessage || '您好,我是AI找房助手,请告诉我您的找房需求。'
|
|
||||||
}),
|
|
||||||
this.createMessage('ai', 'messageForm'),
|
|
||||||
this.createMessage('ai', 'form')
|
|
||||||
]
|
|
||||||
} else {
|
|
||||||
this.appendWelcomeMessage()
|
|
||||||
this.appendMessageFormCard()
|
|
||||||
}
|
|
||||||
this.scrollToBottom()
|
this.scrollToBottom()
|
||||||
},
|
},
|
||||||
openMessageForm() {
|
openMessageForm() {
|
||||||
@@ -455,11 +459,11 @@
|
|||||||
}
|
}
|
||||||
this.messageSubmitting = true
|
this.messageSubmitting = true
|
||||||
try {
|
try {
|
||||||
await HouseMessageApi.addHouseMessage({
|
await HouseAiChatApi.submitHouseAiLead({
|
||||||
|
conversationId: this.conversationId,
|
||||||
realName: this.messageForm.realName.trim(),
|
realName: this.messageForm.realName.trim(),
|
||||||
phone: (this.messageForm.phone || '').trim(),
|
phone: (this.messageForm.phone || '').trim(),
|
||||||
wechat: (this.messageForm.wechat || '').trim(),
|
wechat: (this.messageForm.wechat || '').trim()
|
||||||
source: 'ai_house'
|
|
||||||
})
|
})
|
||||||
this.messageSubmitted = true
|
this.messageSubmitted = true
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
@@ -475,30 +479,6 @@
|
|||||||
this.messageSubmitting = false
|
this.messageSubmitting = false
|
||||||
this.scrollToBottom()
|
this.scrollToBottom()
|
||||||
},
|
},
|
||||||
async loadHouseList() {
|
|
||||||
try {
|
|
||||||
const result = await HouseInfoApi.pageHouseInfo({
|
|
||||||
page: 1,
|
|
||||||
recommend: 1,
|
|
||||||
status: 0
|
|
||||||
})
|
|
||||||
const list = (result.data.list || []).map(item => {
|
|
||||||
let files = []
|
|
||||||
try {
|
|
||||||
files = JSON.parse(item.files) || []
|
|
||||||
} catch (error) {
|
|
||||||
files = []
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
files: files.length ? files : this.fallbackHouses[0].files
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.allHouses = list.length ? list : this.fallbackHouses
|
|
||||||
} catch (error) {
|
|
||||||
this.allHouses = this.fallbackHouses
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handlePrimaryAction() {
|
handlePrimaryAction() {
|
||||||
if (this.loading) {
|
if (this.loading) {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
@@ -506,11 +486,10 @@
|
|||||||
}
|
}
|
||||||
this.sendMessage()
|
this.sendMessage()
|
||||||
},
|
},
|
||||||
async sendMessage() {
|
async sendMessage(question = this.buildQuestion()) {
|
||||||
const question = this.buildQuestion()
|
|
||||||
if (!question) {
|
if (!question) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: this.showFinderForm ? '请输入问题或填写找房条件' : '请输入您的找房需求',
|
title: '请输入您的找房需求',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@@ -522,26 +501,23 @@
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
this.inputText = ''
|
this.inputText = ''
|
||||||
if (question.indexOf('人工') !== -1) {
|
|
||||||
this.loading = false
|
|
||||||
this.messages.push(
|
|
||||||
this.createMessage('ai', 'contact', {
|
|
||||||
content: '联系客服'
|
|
||||||
})
|
|
||||||
)
|
|
||||||
this.scrollToBottom()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.loading = true
|
this.loading = true
|
||||||
|
this.progressText = '正在分析您的需求'
|
||||||
this.scrollToBottom()
|
this.scrollToBottom()
|
||||||
try {
|
try {
|
||||||
await HouseAiChatApi.sendHouseAiMessage({
|
const result = await HouseAiChatApi.sendHouseAiMessage({
|
||||||
conversationId: this.conversationId,
|
conversationId: this.conversationId,
|
||||||
userId: this.loginUserId,
|
|
||||||
question
|
question
|
||||||
})
|
})
|
||||||
|
const fallbackResponse = result && result.data
|
||||||
|
? result.data
|
||||||
|
: null
|
||||||
|
if (fallbackResponse && fallbackResponse.type === 'house_ai_result') {
|
||||||
|
this.handleSocketMessage(JSON.stringify(fallbackResponse))
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
this.progressText = ''
|
||||||
this.messages.push(
|
this.messages.push(
|
||||||
this.createMessage('ai', 'text', {
|
this.createMessage('ai', 'text', {
|
||||||
content: error.message || 'AI服务暂时不可用,请稍后再试。'
|
content: error.message || 'AI服务暂时不可用,请稍后再试。'
|
||||||
@@ -551,26 +527,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
buildQuestion() {
|
buildQuestion() {
|
||||||
const inputQuestion = (this.inputText || '').trim()
|
return (this.inputText || '').trim()
|
||||||
const formQuestion = this.buildFormQuestion()
|
|
||||||
|
|
||||||
if (this.showFinderForm && formQuestion) {
|
|
||||||
if (inputQuestion) {
|
|
||||||
return `${formQuestion},补充要求:${inputQuestion}`
|
|
||||||
}
|
|
||||||
return formQuestion
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inputQuestion) {
|
|
||||||
return inputQuestion
|
|
||||||
}
|
|
||||||
|
|
||||||
return ''
|
|
||||||
},
|
},
|
||||||
buildFormQuestion() {
|
buildFormQuestion() {
|
||||||
if (!this.showFinderForm) {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
if (!this.form.extent || !this.form.floor || !this.form.rent || !this.form.location) {
|
if (!this.form.extent || !this.form.floor || !this.form.rent || !this.form.location) {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
@@ -597,25 +556,19 @@
|
|||||||
copyInputText() {
|
copyInputText() {
|
||||||
this.copyText((this.inputText || '').trim())
|
this.copyText((this.inputText || '').trim())
|
||||||
},
|
},
|
||||||
clearMockTimer() {
|
|
||||||
if (this.timer) {
|
|
||||||
clearTimeout(this.timer)
|
|
||||||
this.timer = null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
normalizeHouseFiles(item) {
|
normalizeHouseFiles(item) {
|
||||||
if (item.files && Array.isArray(item.files)) {
|
if (item.files && Array.isArray(item.files)) {
|
||||||
return item.files.length ? item.files : this.fallbackHouses[0].files
|
return item.files
|
||||||
}
|
}
|
||||||
if (item.files && typeof item.files === 'string') {
|
if (item.files && typeof item.files === 'string') {
|
||||||
try {
|
try {
|
||||||
const files = JSON.parse(item.files)
|
const files = JSON.parse(item.files)
|
||||||
return files.length ? files : this.fallbackHouses[0].files
|
return Array.isArray(files) ? files : []
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return this.fallbackHouses[0].files
|
return []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.fallbackHouses[0].files
|
return []
|
||||||
},
|
},
|
||||||
connectWebSocket() {
|
connectWebSocket() {
|
||||||
if (!this.loginUserId) {
|
if (!this.loginUserId) {
|
||||||
@@ -682,6 +635,7 @@
|
|||||||
data = JSON.parse(raw)
|
data = JSON.parse(raw)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
this.progressText = ''
|
||||||
this.messages.push(
|
this.messages.push(
|
||||||
this.createMessage('ai', 'text', {
|
this.createMessage('ai', 'text', {
|
||||||
content: raw
|
content: raw
|
||||||
@@ -690,10 +644,15 @@
|
|||||||
this.scrollToBottom()
|
this.scrollToBottom()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (data.type === 'house_ai_progress') {
|
||||||
|
this.progressText = data.message || '正在处理中'
|
||||||
|
return
|
||||||
|
}
|
||||||
if (data.type !== 'house_ai_result') {
|
if (data.type !== 'house_ai_result') {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
this.progressText = ''
|
||||||
if (data.answer) {
|
if (data.answer) {
|
||||||
this.messages.push(
|
this.messages.push(
|
||||||
this.createMessage('ai', 'text', {
|
this.createMessage('ai', 'text', {
|
||||||
@@ -725,6 +684,9 @@
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if (data.showContactForm) {
|
||||||
|
this.messages.push(this.createMessage('ai', 'messageForm'))
|
||||||
|
}
|
||||||
this.scrollToBottom()
|
this.scrollToBottom()
|
||||||
},
|
},
|
||||||
goHouseDetail(item) {
|
goHouseDetail(item) {
|
||||||
@@ -983,6 +945,23 @@
|
|||||||
color: #1f2937;
|
color: #1f2937;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.finder-submit {
|
||||||
|
margin-top: 24rpx;
|
||||||
|
height: 76rpx;
|
||||||
|
line-height: 76rpx;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 999rpx;
|
||||||
|
background: linear-gradient(to right, #3f72f4, #7a9cf3);
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
box-shadow: 0 12rpx 24rpx rgba(63, 114, 244, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.finder-submit-disabled {
|
||||||
|
opacity: 0.65;
|
||||||
|
}
|
||||||
|
|
||||||
.message-form-message {
|
.message-form-message {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
@@ -1071,6 +1050,10 @@
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.house-image-empty {
|
||||||
|
background: #eef2f6;
|
||||||
|
}
|
||||||
|
|
||||||
.house-info {
|
.house-info {
|
||||||
padding: 22rpx 22rpx 24rpx;
|
padding: 22rpx 22rpx 24rpx;
|
||||||
}
|
}
|
||||||
@@ -1129,6 +1112,12 @@
|
|||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.typing-text {
|
||||||
|
margin-left: 12rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #667085;
|
||||||
|
}
|
||||||
|
|
||||||
.typing-dot:nth-child(2) {
|
.typing-dot:nth-child(2) {
|
||||||
animation-delay: 0.15s;
|
animation-delay: 0.15s;
|
||||||
}
|
}
|
||||||
@@ -1148,6 +1137,31 @@
|
|||||||
box-shadow: 0 -8rpx 24rpx rgba(15, 23, 42, 0.06);
|
box-shadow: 0 -8rpx 24rpx rgba(15, 23, 42, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.quick-question-row {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 12rpx;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-question {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 56rpx;
|
||||||
|
padding: 0 18rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1rpx solid #d6e2f7;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
background: #f7faff;
|
||||||
|
color: #3557d6;
|
||||||
|
font-size: 23rpx;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-question-disabled {
|
||||||
|
opacity: 0.55;
|
||||||
|
}
|
||||||
|
|
||||||
.tag-row {
|
.tag-row {
|
||||||
margin-bottom: 16rpx;
|
margin-bottom: 16rpx;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,19 @@
|
|||||||
</view>
|
</view>
|
||||||
<view v-if="isManager" class="item col-2" @click="makePhoneCall">业主电话:{{ form.phone || '' }}</view>
|
<view v-if="isManager" class="item col-2" @click="makePhoneCall">业主电话:{{ form.phone || '' }}</view>
|
||||||
<view class="item col-2">物业费(元/m²):{{ form.propertyFees || '' }}</view>
|
<view class="item col-2">物业费(元/m²):{{ form.propertyFees || '' }}</view>
|
||||||
|
<view v-if="form.propertyCompany" class="item col-2">物业公司:{{ form.propertyCompany }}</view>
|
||||||
|
<view v-if="form.waterBillingType || form.waterUnitPrice" class="item col-2">
|
||||||
|
水费:{{ form.waterBillingType || '未提供' }}{{ form.waterUnitPrice ? ',' + form.waterUnitPrice + ' 元/单位' : '' }}
|
||||||
|
</view>
|
||||||
|
<view v-if="form.electricityBillingType || form.electricityUnitPrice" class="item col-2">
|
||||||
|
电费:{{ form.electricityBillingType || '未提供' }}{{ form.electricityUnitPrice ? ',' + form.electricityUnitPrice + ' 元/单位' : '' }}
|
||||||
|
</view>
|
||||||
|
<view v-if="form.airConditioningAvailable !== null && form.airConditioningAvailable !== undefined" class="item col-2">
|
||||||
|
空调:{{ form.airConditioningAvailable ? '提供' : '不提供' }}{{ form.airConditioningFee ? ',' + form.airConditioningFee : '' }}
|
||||||
|
</view>
|
||||||
|
<view v-if="form.parkingAvailable !== null && form.parkingAvailable !== undefined" class="item col-2">
|
||||||
|
停车:{{ form.parkingAvailable ? '可停车' : '不可停车' }}{{ form.parkingFee ? ',' + form.parkingFee : '' }}
|
||||||
|
</view>
|
||||||
<!-- <view v-if="isManager" class="item col-2">租期:{{ form.tenancy || '' }}</view> -->
|
<!-- <view v-if="isManager" class="item col-2">租期:{{ form.tenancy || '' }}</view> -->
|
||||||
<view class="item col-2" v-if="isManager">
|
<view class="item col-2" v-if="isManager">
|
||||||
佣金:{{ form.commission || '' }}
|
佣金:{{ form.commission || '' }}
|
||||||
|
|||||||
Reference in New Issue
Block a user