Refactor(云灵AI):1、使用新模型逻辑对接;2、订单查询
This commit is contained in:
@@ -129,7 +129,7 @@ export default {
|
|||||||
* 想找个像《去有风的地方》那样的治愈县城
|
* 想找个像《去有风的地方》那样的治愈县城
|
||||||
* 云南有哪些小众县城适合旅居?
|
* 云南有哪些小众县城适合旅居?
|
||||||
*/
|
*/
|
||||||
prompt: '',
|
prompt: '查询最近一个月的订单',
|
||||||
recordManager: null,
|
recordManager: null,
|
||||||
// 录音权限是否开通
|
// 录音权限是否开通
|
||||||
recordPermission: false,
|
recordPermission: false,
|
||||||
|
|||||||
@@ -0,0 +1,210 @@
|
|||||||
|
<template>
|
||||||
|
<view
|
||||||
|
class="order-item"
|
||||||
|
>
|
||||||
|
<view class="order-header">
|
||||||
|
<view class="order-shop">
|
||||||
|
<view class="shop-name">
|
||||||
|
<image
|
||||||
|
:src="webUrl + '/aiChat/icon-04.png'"
|
||||||
|
class="icon"
|
||||||
|
mode="widthFix"
|
||||||
|
/>
|
||||||
|
{{ item.shopName }}
|
||||||
|
</view>
|
||||||
|
<view class="order-id">
|
||||||
|
{{ item.orderId }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="status">
|
||||||
|
{{ item.statusName }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="product-info">
|
||||||
|
<view class="good-img">
|
||||||
|
<image
|
||||||
|
:src="item.img"
|
||||||
|
class="img"
|
||||||
|
mode="widthFix"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<view class="name-wrap">
|
||||||
|
<view class="name one-t">
|
||||||
|
{{ item.name }}
|
||||||
|
</view>
|
||||||
|
<view class="attr">
|
||||||
|
{{ item.attr || '' }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="price-num">
|
||||||
|
<view>
|
||||||
|
{{ item.price }}
|
||||||
|
</view>
|
||||||
|
<view class="num">
|
||||||
|
x{{ item.num }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="order-bottom">
|
||||||
|
<view class="time-total">
|
||||||
|
<view class="time">
|
||||||
|
{{ item.createTime }}
|
||||||
|
</view>
|
||||||
|
<view class="total">
|
||||||
|
共{{ item.totalNum }}件商品,
|
||||||
|
<text class="total-txt">
|
||||||
|
总金额<text class="color-red">¥{{ item.totalPrice }}</text>
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="btns">
|
||||||
|
<view class="btn" @click="viewOrderTrack">查看物流</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'AiHistoryList',
|
||||||
|
props: {
|
||||||
|
item: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
webUrl: this.$VUE_APP_RESOURCES_URL
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
viewOrderTrack() {
|
||||||
|
this.$emit('viewOrderTrack', this.item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.order-item {
|
||||||
|
padding: 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0rpx 6rpx 20rpx rgba(101,101,101,0.16);
|
||||||
|
.order-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
.order-shop {
|
||||||
|
flex: 1;
|
||||||
|
width: calc(100% - 120rpx);
|
||||||
|
.shop-name {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: #333;
|
||||||
|
font-size: 28rpx;
|
||||||
|
line-height: 40rpx;
|
||||||
|
.icon {
|
||||||
|
display: block;
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.order-id {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
.status {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 24rpx;
|
||||||
|
line-height: 40rpx;
|
||||||
|
text-align: center;
|
||||||
|
background: rgba(197,39,51,0.39);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.product-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
font-size: 28rpx;
|
||||||
|
.good-img {
|
||||||
|
.img {
|
||||||
|
display: block;
|
||||||
|
width: 120rpx;
|
||||||
|
height: 120rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.name-wrap {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 120rpx;
|
||||||
|
width: calc(100% - 240rpx);
|
||||||
|
.name {
|
||||||
|
line-height: 40rpx;
|
||||||
|
}
|
||||||
|
.attr {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
min-height: 50rpx;
|
||||||
|
padding: 0 25rpx;
|
||||||
|
margin: 20rpx 0 0 0;
|
||||||
|
border-radius: 25rpx;
|
||||||
|
line-height: 40rpx;
|
||||||
|
color: #252525;
|
||||||
|
line-height: 40rpx;
|
||||||
|
background: rgba(239,239,239,0.39);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.price-num {
|
||||||
|
line-height: 40rpx;
|
||||||
|
.price {
|
||||||
|
}
|
||||||
|
.num {
|
||||||
|
font-size: 20rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.order-bottom {
|
||||||
|
.time-total {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
color: #999;
|
||||||
|
font-size: 22rpx;
|
||||||
|
.total-txt {
|
||||||
|
color: #333;
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.color-red {
|
||||||
|
color: #C52733;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.btns {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin: 24rpx 0 0 0;
|
||||||
|
.btn {
|
||||||
|
height: 44rpx;
|
||||||
|
padding: 0 24rpx;
|
||||||
|
border-radius: 22rpx;
|
||||||
|
border: 1rpx solid #C52733;
|
||||||
|
color: #C52733;
|
||||||
|
font-size: 28rpx;
|
||||||
|
line-height: 44rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -18,6 +18,29 @@ export const chatMixins = {
|
|||||||
token: cookie.get('login_status'),
|
token: cookie.get('login_status'),
|
||||||
userInfo: cookie.get('userInfo'),
|
userInfo: cookie.get('userInfo'),
|
||||||
webUrl: this.$VUE_APP_RESOURCES_URL,
|
webUrl: this.$VUE_APP_RESOURCES_URL,
|
||||||
|
bottomTools: Object.freeze([
|
||||||
|
{
|
||||||
|
icon: 'icon-50',
|
||||||
|
text: '我要送礼',
|
||||||
|
type: 'prompt',
|
||||||
|
prompt: '我要送礼,请给我推荐一些平台的礼品',
|
||||||
|
url: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'icon-51',
|
||||||
|
text: '订单查询',
|
||||||
|
type: 'prompt',
|
||||||
|
prompt: '订单查询',
|
||||||
|
url: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'icon-52',
|
||||||
|
text: '拍照识图',
|
||||||
|
type: 'link',
|
||||||
|
prompt: '',
|
||||||
|
url: '/aiChat/views/imageRecognition'
|
||||||
|
}
|
||||||
|
]),
|
||||||
scrollData: {},
|
scrollData: {},
|
||||||
scrollTop: 0,
|
scrollTop: 0,
|
||||||
isScrollToBottom: false,
|
isScrollToBottom: false,
|
||||||
@@ -524,6 +547,19 @@ export const chatMixins = {
|
|||||||
console.log('------------end')
|
console.log('------------end')
|
||||||
this.isPlayAudio = false
|
this.isPlayAudio = false
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
bottomToolClickHandle(item) {
|
||||||
|
if (item.type === 'prompt') {
|
||||||
|
this.streamReq({
|
||||||
|
prompt: item.prompt,
|
||||||
|
init: 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (item.type === 'link') {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: item.url
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,556 @@
|
|||||||
|
import {
|
||||||
|
getSseConfigV1,
|
||||||
|
getCompletionsV3,
|
||||||
|
deleteChatItemByConversationId,
|
||||||
|
// getAnalyzeKeywordsV1,
|
||||||
|
getAnalyzeKeywordsChangeV1
|
||||||
|
} from '@/api/chat/index'
|
||||||
|
import { VUE_APP_API_URL } from '@/config'
|
||||||
|
import settings from '@/config/baseSetting.js'
|
||||||
|
import { formatAiMsgContent } from '../utils/aiChat'
|
||||||
|
import cookie from '@/utils/store/cookie'
|
||||||
|
import { handleLoginFailure } from '@/utils'
|
||||||
|
const plugin = requirePlugin('WechatSI')
|
||||||
|
const removeMarkdown = require('remove-markdown')
|
||||||
|
export const chatMixinsV2 = {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
token: cookie.get('login_status'),
|
||||||
|
userInfo: cookie.get('userInfo'),
|
||||||
|
webUrl: this.$VUE_APP_RESOURCES_URL,
|
||||||
|
bottomTools: Object.freeze([
|
||||||
|
{
|
||||||
|
icon: 'icon-50',
|
||||||
|
text: '我要送礼',
|
||||||
|
type: 'prompt',
|
||||||
|
prompt: '我要送礼,请给我推荐一些平台的礼品',
|
||||||
|
url: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'icon-51',
|
||||||
|
text: '订单查询',
|
||||||
|
type: 'prompt',
|
||||||
|
prompt: '订单查询',
|
||||||
|
url: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'icon-52',
|
||||||
|
text: '拍照识图',
|
||||||
|
type: 'link',
|
||||||
|
prompt: '',
|
||||||
|
url: '/aiChat/views/imageRecognition'
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
scrollData: {},
|
||||||
|
scrollTop: 0,
|
||||||
|
isScrollToBottom: false,
|
||||||
|
// 状态栏高度
|
||||||
|
statusBarHeight: 20,
|
||||||
|
fileHttpStr: Object.freeze(VUE_APP_API_URL + settings.sysPrefix),
|
||||||
|
keyboardHeight: 0,
|
||||||
|
optionsFrom: '',
|
||||||
|
onFocus: false,
|
||||||
|
loading: false,
|
||||||
|
chatNumber: '',
|
||||||
|
infoResData: {},
|
||||||
|
chatMessageList: [
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
type: -2,
|
||||||
|
isError: false,
|
||||||
|
showCursor: false,
|
||||||
|
conversationId: '',
|
||||||
|
prompt: '',
|
||||||
|
nodes: '-------------监听 WebSocket 接受到服务器的消息事件',
|
||||||
|
content: '-------------监听 WebSocket 接受到服务器的消息事件',
|
||||||
|
listQuestion: [
|
||||||
|
'监听 WebSocket 接受到服务器的消息事件',
|
||||||
|
'监听 WebSocket 接受到服务器的消息事件',
|
||||||
|
'监听 WebSocket 接受到服务器的消息事件'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
],
|
||||||
|
errorMsg: Object.freeze('您提的问题未能理解,云灵思想跑偏啦,重新整理一下问题或者重新提问,让云灵再试试!'),
|
||||||
|
audioAyy: [],
|
||||||
|
isPlayAudio: false,
|
||||||
|
audioContext: null,
|
||||||
|
audioPlayId: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
chatMessageListLength() {
|
||||||
|
return this.chatMessageList.length
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onPageScroll(e) {
|
||||||
|
this.scrollData = e
|
||||||
|
const scrollTop = e.scrollTop
|
||||||
|
this.scrollTop = scrollTop
|
||||||
|
const query = wx.createSelectorQuery().in(this)
|
||||||
|
query.select('#fixTbabarBody').boundingClientRect(function(rect) {
|
||||||
|
const contentHeight = rect.height
|
||||||
|
const windowInfo = wx.getWindowInfo()
|
||||||
|
const windowHeight = windowInfo.windowHeight
|
||||||
|
if (scrollTop + windowHeight + 30 >= contentHeight) {
|
||||||
|
this.isScrollToBottom = true
|
||||||
|
} else {
|
||||||
|
this.isScrollToBottom = false
|
||||||
|
}
|
||||||
|
}.bind(this)).exec()
|
||||||
|
},
|
||||||
|
onUnload() {
|
||||||
|
if (this.audioContext) {
|
||||||
|
this.audioContext.stop()
|
||||||
|
}
|
||||||
|
wx.getBackgroundAudioManager().stop()
|
||||||
|
this.closeWsFn()
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
const _this = this
|
||||||
|
uni.getSystemInfo({
|
||||||
|
success: (e) => {
|
||||||
|
let statusBar = 0
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
statusBar = e.statusBarHeight
|
||||||
|
const custom = uni.getMenuButtonBoundingClientRect()
|
||||||
|
_this.rightDistance = e.windowWidth - custom.left + 10
|
||||||
|
// #endif
|
||||||
|
// 状态栏高度
|
||||||
|
_this.statusBarHeight = statusBar
|
||||||
|
}
|
||||||
|
})
|
||||||
|
_this.createdCallbak()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
createdCallbak() {
|
||||||
|
console.log('页面初始话回调')
|
||||||
|
},
|
||||||
|
inputFocusHandle(value) {
|
||||||
|
this.onFocus = value === 1
|
||||||
|
this.scrollToBottomHandle()
|
||||||
|
},
|
||||||
|
historyViewHandle() {
|
||||||
|
console.log(this.$refs.historyView)
|
||||||
|
this.$refs.historyView.showView()
|
||||||
|
},
|
||||||
|
copyContentHandle(data) {
|
||||||
|
uni.setClipboardData({
|
||||||
|
data,
|
||||||
|
success: () => {
|
||||||
|
uni.showToast({
|
||||||
|
title: '已复制'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
copyMoreInfoHandle(item) {
|
||||||
|
uni.setClipboardData({
|
||||||
|
data: JSON.stringify(item.showMoreInfo),
|
||||||
|
success: () => {
|
||||||
|
uni.showToast({
|
||||||
|
title: '已复制'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
shareHandle() {
|
||||||
|
wx.showShareMenu({
|
||||||
|
withShareTicket: true,
|
||||||
|
menus: ['shareAppMessage', 'shareTimeline'],
|
||||||
|
success: (res) => {
|
||||||
|
console.log(res)
|
||||||
|
},
|
||||||
|
fail: err => {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
scrollToBottomHandle() {
|
||||||
|
uni.pageScrollTo({
|
||||||
|
duration: 100,
|
||||||
|
selector: '#bottom_postion'
|
||||||
|
})
|
||||||
|
this.isScrollToBottom = true
|
||||||
|
},
|
||||||
|
// 重新生成
|
||||||
|
regenerateHandle(item) {
|
||||||
|
this.audioStopHandle()
|
||||||
|
deleteChatItemByConversationId(item.conversationId).then(res => {
|
||||||
|
const { success } = res
|
||||||
|
if (success) {
|
||||||
|
this.chatMessageList.splice(this.chatMessageListLength - 1, 1)
|
||||||
|
this.streamReq({
|
||||||
|
prompt: item.prompt,
|
||||||
|
init: 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 建议提问
|
||||||
|
suggestionItemClickHandle(question) {
|
||||||
|
this.streamReq({
|
||||||
|
prompt: question,
|
||||||
|
init: 0
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 大家都在问
|
||||||
|
topicItemClickHandle(question) {
|
||||||
|
this.streamReq({
|
||||||
|
prompt: question,
|
||||||
|
init: 0
|
||||||
|
})
|
||||||
|
},
|
||||||
|
streamReq(params) {
|
||||||
|
const _this = this
|
||||||
|
// 需要校验登录状态
|
||||||
|
if (!_this.token) {
|
||||||
|
handleLoginFailure()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const prompt = params.prompt
|
||||||
|
if (params.init !== 1) {
|
||||||
|
_this.chatMessageList.push({
|
||||||
|
prompt,
|
||||||
|
type: -1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_this.$nextTick(() => {
|
||||||
|
_this.scrollToBottomHandle()
|
||||||
|
})
|
||||||
|
_this.chatMessageList.push({
|
||||||
|
content: '',
|
||||||
|
nodes: '',
|
||||||
|
isError: false,
|
||||||
|
showCursor: false,
|
||||||
|
conversationId: '',
|
||||||
|
prompt,
|
||||||
|
listQuestion: [],
|
||||||
|
orderList: [],
|
||||||
|
type: -2,
|
||||||
|
showMoreInfo: {}
|
||||||
|
})
|
||||||
|
_this.loading = true
|
||||||
|
_this.showCursor = false
|
||||||
|
getSseConfigV1({
|
||||||
|
'chatNumber': _this.chatNumber,
|
||||||
|
prompt
|
||||||
|
}).then(resConfig => {
|
||||||
|
const conversationId = resConfig.data.conversationId
|
||||||
|
_this.chatNumber = resConfig.data.chatNumber || ''
|
||||||
|
_this.chatMessageList[_this.chatMessageListLength - 1].showCursor = true
|
||||||
|
_this.chatMessageList[_this.chatMessageListLength - 1].conversationId = conversationId
|
||||||
|
if (conversationId) {
|
||||||
|
_this.initWebSocket(conversationId, () => {
|
||||||
|
getCompletionsV3({
|
||||||
|
conversationId,
|
||||||
|
ws: true,
|
||||||
|
isNoNeedPublicErrorNotification: 1
|
||||||
|
}).then(sseRes => {
|
||||||
|
console.log(sseRes)
|
||||||
|
// _this.closeWsFn()
|
||||||
|
}).catch(err => {
|
||||||
|
console.log(err)
|
||||||
|
_this.chatErrorSetContent()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
_this.chatErrorSetContent()
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
console.log(err)
|
||||||
|
_this.chatErrorSetContent()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
initWebSocket(conversationId, cb) {
|
||||||
|
const _this = this
|
||||||
|
console.log('------------------创建连接')
|
||||||
|
uni.connectSocket({
|
||||||
|
url: VUE_APP_API_URL.replace('https', 'wss') + settings.sysPrefix + `v1/chat/websocket/${_this.userInfo.unionId}`,
|
||||||
|
header: {
|
||||||
|
'content-type': 'application/json'
|
||||||
|
},
|
||||||
|
timeout: 10 * 1000,
|
||||||
|
success: () => {
|
||||||
|
console.log('------------WebSocket初始化成功')
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
uni.showModal({
|
||||||
|
showCancel: false,
|
||||||
|
content: err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
uni.onSocketMessage(res => {
|
||||||
|
_this.websocketOnmessage(res)
|
||||||
|
})
|
||||||
|
uni.onSocketOpen(() => {
|
||||||
|
cb && cb()
|
||||||
|
_this.websocketOnopen()
|
||||||
|
})
|
||||||
|
uni.onSocketError(err => {
|
||||||
|
_this.websocketOnerror(err)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
websocketOnmessage(res) {
|
||||||
|
console.log('-------------监听 WebSocket 接受到服务器的消息事件')
|
||||||
|
const resData = JSON.parse(res.data)
|
||||||
|
if (resData) {
|
||||||
|
console.log(resData)
|
||||||
|
const message = resData.message
|
||||||
|
if (message && this.chatMessageListLength > 1) {
|
||||||
|
const mesContent = message.content
|
||||||
|
const contentType = message.contentType
|
||||||
|
const finish = message.finish
|
||||||
|
// todo:判断是文本还是列表
|
||||||
|
if (contentType ==='text') {
|
||||||
|
if (!finish && mesContent) {
|
||||||
|
this.chatMessageList[this.chatMessageListLength - 1].nodes = formatAiMsgContent(mesContent)
|
||||||
|
this.chatMessageList[this.chatMessageListLength - 1].content = mesContent
|
||||||
|
this.chatMessageList[this.chatMessageListLength - 1].listQuestion = message.listQuestion || []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (contentType ==='order') {
|
||||||
|
if (!finish && message.listCards) {
|
||||||
|
this.chatMessageList[this.chatMessageListLength - 1].orderList = message.listCards || []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.$forceUpdate()
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scrollToBottomHandle()
|
||||||
|
if (finish) {
|
||||||
|
this.closeWsFn()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
websocketOnopen() {
|
||||||
|
console.log('------------------监听 WebSocket 连接打开事件')
|
||||||
|
// this.websocketSend(JSON.stringify({ msg: '1' }))
|
||||||
|
},
|
||||||
|
websocketOnerror(e) {
|
||||||
|
console.log('-----------------监听 WebSocket 错误事件')
|
||||||
|
console.log(e)
|
||||||
|
},
|
||||||
|
websocketSend(msg) {
|
||||||
|
// 数据发送
|
||||||
|
try {
|
||||||
|
uni.sendSocketMessage({
|
||||||
|
data: msg,
|
||||||
|
success: () => {
|
||||||
|
console.log('-----------发送消息成功了')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
console.log('send failed (' + err.code + ')')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
analyzeKeywordsChangeHandle(conversationId, showMoreInfo) {
|
||||||
|
getAnalyzeKeywordsChangeV1({
|
||||||
|
conversationId,
|
||||||
|
...showMoreInfo
|
||||||
|
}).then(res => {
|
||||||
|
const { success, data } = res
|
||||||
|
if (success) {
|
||||||
|
let resultItems = []
|
||||||
|
let idx = -1
|
||||||
|
this.chatMessageList.map((item, index) => {
|
||||||
|
if (item.conversationId === conversationId) {
|
||||||
|
resultItems = data.resultItems || []
|
||||||
|
idx = index
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (idx > -1) {
|
||||||
|
this.$set(this.chatMessageList[idx].showMoreInfo, 'resultItems', resultItems)
|
||||||
|
this.$forceUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
productItemClickHandle(item) {
|
||||||
|
this.audioStopHandle()
|
||||||
|
this.$yrouter.push({
|
||||||
|
path: '/pages/shop/GoodsCon/index',
|
||||||
|
query: {
|
||||||
|
id: item.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
hotelItemClickHandle(item) {
|
||||||
|
this.audioStopHandle()
|
||||||
|
this.$yrouter.push({
|
||||||
|
path: '/pagesInn/inn/innHome',
|
||||||
|
query: {
|
||||||
|
id: item.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
ichItemClickHandle(item) {
|
||||||
|
this.audioStopHandle()
|
||||||
|
this.$yrouter.push({
|
||||||
|
path: '/pkg_product/views/heritage/details',
|
||||||
|
query: {
|
||||||
|
id: item.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
qianxianItemClickHandle(item) {
|
||||||
|
this.audioStopHandle()
|
||||||
|
this.$yrouter.push({
|
||||||
|
path: '/pkg_product/views/famousQianxianShop',
|
||||||
|
query: {
|
||||||
|
id: item.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
prizeItemClickHandle() {
|
||||||
|
this.audioStopHandle()
|
||||||
|
this.$yrouter.push({ path: '/pkg-video/views/lottery' })
|
||||||
|
},
|
||||||
|
chatErrorSetContent() {
|
||||||
|
this.chatMessageList[this.chatMessageListLength - 1].isError = true
|
||||||
|
this.chatMessageList[this.chatMessageListLength - 1].content = this.errorMsg
|
||||||
|
this.chatMessageList[this.chatMessageListLength - 1].nodes = this.errorMsg
|
||||||
|
this.closeWsFn()
|
||||||
|
},
|
||||||
|
closeWsFn() {
|
||||||
|
this.loading = false
|
||||||
|
if (this.chatMessageListLength) {
|
||||||
|
this.chatMessageList[this.chatMessageListLength - 1].showCursor = false
|
||||||
|
}
|
||||||
|
uni.closeSocket({
|
||||||
|
success: () => {
|
||||||
|
console.log('-----关闭连接')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scrollToBottomHandle()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
audioStopHandle() {
|
||||||
|
// Fix bug#4049
|
||||||
|
this.audioAyy = []
|
||||||
|
if (this.audioContext) {
|
||||||
|
this.audioContext.stop()
|
||||||
|
}
|
||||||
|
this.isPlayAudio = false
|
||||||
|
wx.getBackgroundAudioManager().stop()
|
||||||
|
},
|
||||||
|
ttsHandle(item) {
|
||||||
|
this.audioAyy = []
|
||||||
|
if (this.audioContext) {
|
||||||
|
this.audioContext.stop()
|
||||||
|
// this.audioContext.destroy()
|
||||||
|
}
|
||||||
|
// 如果正在播放,点击当前播放的则认为是暂停
|
||||||
|
if (this.isPlayAudio && item.conversationId === this.audioPlayId) {
|
||||||
|
this.isPlayAudio = false
|
||||||
|
this.audioPlayId = ''
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.isPlayAudio = false
|
||||||
|
this.audioPlayId = item.conversationId
|
||||||
|
const flag = 1
|
||||||
|
if (flag === 1) {
|
||||||
|
console.log(removeMarkdown(item.content).replace(/[\n\t\s]/g, ''))
|
||||||
|
uni.showLoading({
|
||||||
|
title: '合成中...'
|
||||||
|
})
|
||||||
|
this.splitAndSynthesize(removeMarkdown(item.content).replace(/[\n\t\s]/g, ''))
|
||||||
|
} else {
|
||||||
|
// 调试数据
|
||||||
|
this.audioAyy = [
|
||||||
|
'https://ae.weixin.qq.com/cgi-bin/mmasrai-bin/getmedia?filename=1750749075_2f71887cc48d9b3753c39d119862d4bb&filekey=871027724&source=miniapp_plugin',
|
||||||
|
'https://ae.weixin.qq.com/cgi-bin/mmasrai-bin/getmedia?filename=1750749077_0970508786c5e3edc3a68a5eb9de048c&filekey=871027724&source=miniapp_plugin',
|
||||||
|
'https://ae.weixin.qq.com/cgi-bin/mmasrai-bin/getmedia?filename=1750749079_e77cec52cc077ba981892887c3df4cdf&filekey=871027724&source=miniapp_plugin',
|
||||||
|
'https://ae.weixin.qq.com/cgi-bin/mmasrai-bin/getmedia?filename=1750749080_02db4235771f5561cdb73c06d8c67e53&filekey=871027724&source=miniapp_plugin',
|
||||||
|
'https://ae.weixin.qq.com/cgi-bin/mmasrai-bin/getmedia?filename=1750749082_534e455c5d6ac5e9a4192ecf9952851a&filekey=871027724&source=miniapp_plugin',
|
||||||
|
'https://ae.weixin.qq.com/cgi-bin/mmasrai-bin/getmedia?filename=1750749083_78c4a2fecad538561f81c48dc4ecd645&filekey=871027724&source=miniapp_plugin'
|
||||||
|
]
|
||||||
|
this.playNextChunk()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splitAndSynthesize(text) {
|
||||||
|
const _this = this
|
||||||
|
if (text) {
|
||||||
|
const textLength = text.length
|
||||||
|
const chunkSize = 100
|
||||||
|
const chunk = text.slice(0, textLength > chunkSize ? chunkSize : textLength)
|
||||||
|
plugin.textToSpeech({
|
||||||
|
// 语言
|
||||||
|
lang: 'zh_CN',
|
||||||
|
tts: true,
|
||||||
|
// 要转换的文字
|
||||||
|
content: chunk,
|
||||||
|
success: function(res) {
|
||||||
|
console.log("语音文件路径:", res.filename)
|
||||||
|
_this.audioAyy.push(res.filename)
|
||||||
|
// 首次就立即播放,增强体验
|
||||||
|
if (!_this.isPlayAudio) {
|
||||||
|
_this.playNextChunk()
|
||||||
|
}
|
||||||
|
if (textLength > chunkSize) {
|
||||||
|
// 递归调用,播放一定要按照文本分割顺序
|
||||||
|
_this.splitAndSynthesize(text.substr(chunkSize, textLength))
|
||||||
|
} else {
|
||||||
|
// 最后一条合成,没有正在播放则立即播放
|
||||||
|
if (!_this.isPlayAudio) {
|
||||||
|
_this.playNextChunk()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uni.hideLoading()
|
||||||
|
},
|
||||||
|
fail: function(err) {
|
||||||
|
console.log("转换失败:", err)
|
||||||
|
uni.hideLoading()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
if (!_this.isPlayAudio) {
|
||||||
|
_this.playNextChunk()
|
||||||
|
}
|
||||||
|
uni.hideLoading()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
playNextChunk() {
|
||||||
|
if (this.audioAyy.length > 0 && this.audioPlayId) {
|
||||||
|
const src = this.audioAyy.shift()
|
||||||
|
this.isPlayAudio = true
|
||||||
|
const audioContext = uni.createInnerAudioContext({
|
||||||
|
// 是否使用 WebAudio 作为底层音频驱动,默认关闭。对于短音频、播放频繁的音频建议开启此选项,开启后将获得更优的性能表现。由于开启此选项后也会带来一定的内存增长,因此对于长音频建议关闭此选项
|
||||||
|
useWebAudioImplement: false
|
||||||
|
})
|
||||||
|
this.audioContext = audioContext
|
||||||
|
audioContext.src = src
|
||||||
|
audioContext.onEnded(() => {
|
||||||
|
audioContext.destroy()
|
||||||
|
this.playNextChunk()
|
||||||
|
})
|
||||||
|
audioContext.play()
|
||||||
|
console.log('------------src:' + src)
|
||||||
|
} else {
|
||||||
|
console.log('------------end')
|
||||||
|
this.isPlayAudio = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bottomToolClickHandle(item) {
|
||||||
|
if (item.type === 'prompt') {
|
||||||
|
this.streamReq({
|
||||||
|
prompt: item.prompt,
|
||||||
|
init: 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (item.type === 'link') {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: item.url
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
viewOrderTrackHandle(order) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/order/OrderDetails/index?id=' + order.orderId
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+30
-14
@@ -275,24 +275,40 @@
|
|||||||
}"
|
}"
|
||||||
class="page-to-bottom"
|
class="page-to-bottom"
|
||||||
>
|
>
|
||||||
<view
|
<view class="container">
|
||||||
class="new-chat"
|
<view
|
||||||
@click="createNewHandle"
|
v-if="chatNumber"
|
||||||
>
|
class="new-chat"
|
||||||
|
@click="createNewHandle"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
:src="webUrl + '/aiChat/icon-54.png'"
|
||||||
|
class="btn-icon"
|
||||||
|
mode="widthFix"
|
||||||
|
/>
|
||||||
|
开启新对话
|
||||||
|
</view>
|
||||||
<image
|
<image
|
||||||
:src="webUrl + '/aiChat/icon-05.png'"
|
v-if="chatMessageListLength > 0 && !isScrollToBottom && !loading"
|
||||||
class="btn-icon"
|
:src="webUrl + '/aiChat/down.png'"
|
||||||
|
class="icon"
|
||||||
mode="widthFix"
|
mode="widthFix"
|
||||||
|
@click="scrollToBottomHandle"
|
||||||
/>
|
/>
|
||||||
开启新对话
|
<view
|
||||||
|
v-for="(item, index) in bottomTools"
|
||||||
|
:key="index"
|
||||||
|
class="bottom-tool-item"
|
||||||
|
@click="bottomToolClickHandle(item)"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
:src="webUrl + '/aiChat/' + item.icon + '.png'"
|
||||||
|
class="tool-icon"
|
||||||
|
mode="widthFix"
|
||||||
|
/>
|
||||||
|
{{ item.text }}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<image
|
|
||||||
v-if="chatMessageListLength > 0 && !isScrollToBottom && !loading"
|
|
||||||
:src="webUrl + '/aiChat/down.png'"
|
|
||||||
class="icon"
|
|
||||||
mode="widthFix"
|
|
||||||
@click="scrollToBottomHandle"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
<bottom-send
|
<bottom-send
|
||||||
ref="bottomSend"
|
ref="bottomSend"
|
||||||
|
|||||||
@@ -0,0 +1,227 @@
|
|||||||
|
<template>
|
||||||
|
<view
|
||||||
|
:style="{ 'background-image': 'url(' + webUrl + '/aiChat/bg-05.png)' }"
|
||||||
|
class="image-recognition-page"
|
||||||
|
>
|
||||||
|
<hx-navbar
|
||||||
|
:back="true"
|
||||||
|
:fixed="true"
|
||||||
|
:statusBar="true"
|
||||||
|
left-icon="arrowleft"
|
||||||
|
color="#333"
|
||||||
|
transparent="auto"
|
||||||
|
barPlaceholder="hidden"
|
||||||
|
title="云灵"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<view
|
||||||
|
class="main-content"
|
||||||
|
:style="{ 'padding-top': (44 + statusBarHeight) + 'px' }"
|
||||||
|
>
|
||||||
|
<!-- 拍照区域 -->
|
||||||
|
<view class="camera-section" @click="takePhoto">
|
||||||
|
<view class="dashed-border-box">
|
||||||
|
<view class="icon-wrap">
|
||||||
|
<image
|
||||||
|
:src="webUrl + '/aiChat/icon-55.png'"
|
||||||
|
class="camera-icon"
|
||||||
|
mode="widthFix"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<view class="main-title">对准商品拍照</view>
|
||||||
|
<view class="sub-tip">示例:特产/零食/茶叶/纪念品</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部相册上传按钮 -->
|
||||||
|
<view class="bottom-action">
|
||||||
|
<button class="album-btn" @click="chooseImage">
|
||||||
|
<image
|
||||||
|
:src="webUrl + '/aiChat/icon-56.png'"
|
||||||
|
class="upload-icon"
|
||||||
|
mode="widthFix"
|
||||||
|
/>
|
||||||
|
<text>从相册上传图片进行识别</text>
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { chatMixins } from '../mixins/chatMixins.js'
|
||||||
|
import { VUE_APP_API_URL } from '@/config'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AiChatImageRecognitionPage',
|
||||||
|
mixins: [chatMixins],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
createdCallbak() {
|
||||||
|
// 覆盖 mixins 中的 createdCallbak,避免触发默认逻辑
|
||||||
|
},
|
||||||
|
takePhoto() {
|
||||||
|
if (this.loading) return
|
||||||
|
uni.chooseImage({
|
||||||
|
count: 1,
|
||||||
|
sizeType: ['compressed'],
|
||||||
|
sourceType: ['camera'],
|
||||||
|
success: (res) => {
|
||||||
|
this.handleUpload(res.tempFilePaths[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
chooseImage() {
|
||||||
|
if (this.loading) return
|
||||||
|
uni.chooseImage({
|
||||||
|
count: 1,
|
||||||
|
sizeType: ['compressed'],
|
||||||
|
sourceType: ['album'],
|
||||||
|
success: (res) => {
|
||||||
|
this.handleUpload(res.tempFilePaths[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleUpload(filePath) {
|
||||||
|
const _this = this
|
||||||
|
uni.showLoading({ title: '识别中...' })
|
||||||
|
_this.loading = true
|
||||||
|
|
||||||
|
uni.uploadFile({
|
||||||
|
url: `${VUE_APP_API_URL}/api/upload`,
|
||||||
|
filePath: filePath,
|
||||||
|
header: {
|
||||||
|
Authorization: 'Bearer ' + (_this.token || '')
|
||||||
|
},
|
||||||
|
name: 'file',
|
||||||
|
success: (uploadRes) => {
|
||||||
|
const resData = JSON.parse(uploadRes.data)
|
||||||
|
if (resData.link) {
|
||||||
|
_this.performRecognition(resData.link)
|
||||||
|
} else {
|
||||||
|
uni.hideLoading()
|
||||||
|
_this.loading = false
|
||||||
|
_this.$toast('上传失败,请重试')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.log('Upload Error:', err)
|
||||||
|
uni.hideLoading()
|
||||||
|
_this.loading = false
|
||||||
|
_this.$toast('网络异常,请重试')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
performRecognition(imageUrl) {
|
||||||
|
// 存储识别到的图片 URL,并返回上一页
|
||||||
|
uni.setStorageSync('recognitionImage', imageUrl)
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/aiChat/views/imageRecognitionResult'
|
||||||
|
})
|
||||||
|
uni.hideLoading()
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.image-recognition-page {
|
||||||
|
height: 100vh;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 60rpx 40rpx;
|
||||||
|
height: 100vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.camera-section {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 60rpx;
|
||||||
|
|
||||||
|
.dashed-border-box {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 600rpx;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 80rpx;
|
||||||
|
border: 2rpx dashed #DCDFE6;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
background-color: rgba(255, 255, 255, 0.5);
|
||||||
|
|
||||||
|
.icon-wrap {
|
||||||
|
width: 160rpx;
|
||||||
|
height: 160rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 6rpx solid #7A3DF1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
|
||||||
|
.camera-icon {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-tip {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-action {
|
||||||
|
width: 100%;
|
||||||
|
padding-bottom: 60rpx;
|
||||||
|
|
||||||
|
.album-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 100rpx;
|
||||||
|
background: #3D4CF1;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-size: 32rpx;
|
||||||
|
border: none;
|
||||||
|
box-shadow: 0 8rpx 20rpx rgba(61, 76, 241, 0.3);
|
||||||
|
|
||||||
|
.upload-icon {
|
||||||
|
width: 36rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
margin-right: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,348 @@
|
|||||||
|
<template>
|
||||||
|
<view class="image-recognition-result-page">
|
||||||
|
<hx-navbar
|
||||||
|
:back="true"
|
||||||
|
:fixed="true"
|
||||||
|
:statusBar="true"
|
||||||
|
left-icon="arrowleft"
|
||||||
|
color="#333"
|
||||||
|
transparent="auto"
|
||||||
|
barPlaceholder="hidden"
|
||||||
|
title="识别结果"
|
||||||
|
/>
|
||||||
|
<view
|
||||||
|
class="page-body"
|
||||||
|
:style="{ 'padding-top': (44 + statusBarHeight) + 'px' }"
|
||||||
|
>
|
||||||
|
<view class="header">
|
||||||
|
<view
|
||||||
|
class="header-bg"
|
||||||
|
:style="{ 'background-image': imageUrl ? `url(${imageUrl})` : '' }"
|
||||||
|
/>
|
||||||
|
<view class="header-mask" />
|
||||||
|
<view class="scan-wrap">
|
||||||
|
<image
|
||||||
|
v-if="imageUrl"
|
||||||
|
:src="imageUrl"
|
||||||
|
class="scan-image"
|
||||||
|
mode="aspectFill"
|
||||||
|
/>
|
||||||
|
<view class="corner tl" />
|
||||||
|
<view class="corner tr" />
|
||||||
|
<view class="corner bl" />
|
||||||
|
<view class="corner br" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="sheet">
|
||||||
|
<view class="sheet-thumb-row">
|
||||||
|
<image
|
||||||
|
v-if="imageUrl"
|
||||||
|
:src="imageUrl"
|
||||||
|
class="sheet-thumb"
|
||||||
|
mode="aspectFill"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<view class="sheet-divider" />
|
||||||
|
|
||||||
|
<view class="goods-grid">
|
||||||
|
<view
|
||||||
|
v-for="(item, index) in goodsList"
|
||||||
|
:key="index"
|
||||||
|
class="goods-card"
|
||||||
|
@click="goGoods(item)"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
:src="item.img"
|
||||||
|
class="goods-img"
|
||||||
|
mode="aspectFill"
|
||||||
|
/>
|
||||||
|
<view class="goods-title">
|
||||||
|
{{ item.title }}
|
||||||
|
</view>
|
||||||
|
<view class="goods-price-row">
|
||||||
|
<view class="price-left">
|
||||||
|
<text class="price-symbol">¥</text>
|
||||||
|
<text class="price-val">{{ item.price }}</text>
|
||||||
|
<text v-if="item.originPrice" class="origin-price">¥{{ item.originPrice }}</text>
|
||||||
|
</view>
|
||||||
|
<image
|
||||||
|
:src="webUrl + '/home/icon-cart.png'"
|
||||||
|
class="cart-btn"
|
||||||
|
mode="aspectFit"
|
||||||
|
@click.stop="addToCart(item)"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'AiChatImageRecognitionResultPage',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
webUrl: this.$VUE_APP_RESOURCES_URL,
|
||||||
|
statusBarHeight: 20,
|
||||||
|
imageUrl: '',
|
||||||
|
goodsList: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLoad(options) {
|
||||||
|
this.initSystemInfo()
|
||||||
|
const urlFromQuery = options.imageUrl || ''
|
||||||
|
const urlFromStorage = uni.getStorageSync('recognitionImage') || ''
|
||||||
|
this.imageUrl = urlFromQuery || urlFromStorage || ''
|
||||||
|
if (urlFromStorage) {
|
||||||
|
uni.removeStorageSync('recognitionImage')
|
||||||
|
}
|
||||||
|
this.goodsList = this.buildMockGoods(this.imageUrl)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initSystemInfo() {
|
||||||
|
uni.getSystemInfo({
|
||||||
|
success: (e) => {
|
||||||
|
this.statusBarHeight = e.statusBarHeight || 20
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
buildMockGoods(fallbackImg) {
|
||||||
|
const img = fallbackImg || (this.webUrl + '/home/no-data-bg.png')
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: 0,
|
||||||
|
img,
|
||||||
|
title: '西双版纳独有酸蚀蜂种一年一采 不一样的美味',
|
||||||
|
price: '39.8',
|
||||||
|
originPrice: '40.00'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
img,
|
||||||
|
title: '西双版纳独有酸蚀蜂种一年一采 不一样的美味',
|
||||||
|
price: '39.8',
|
||||||
|
originPrice: '40.00'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
img,
|
||||||
|
title: '西双版纳独有酸蚀蜂种一年一采 不一样的美味',
|
||||||
|
price: '39.8',
|
||||||
|
originPrice: '40.00'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
img,
|
||||||
|
title: '西双版纳独有酸蚀蜂种一年一采 不一样的美味',
|
||||||
|
price: '39.8',
|
||||||
|
originPrice: '40.00'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
goGoods(item) {
|
||||||
|
if (!item || !item.productId) return
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/shop/GoodsCon/index?id=${item.productId}`
|
||||||
|
})
|
||||||
|
},
|
||||||
|
addToCart() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.image-recognition-result-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background: #F5F8FF;
|
||||||
|
|
||||||
|
.page-body {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
position: relative;
|
||||||
|
height: 520rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-bg {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: #DDE6FF;
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
filter: blur(18rpx);
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-mask {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scan-wrap {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
width: 320rpx;
|
||||||
|
height: 320rpx;
|
||||||
|
transform: translate(-50%, -52%);
|
||||||
|
border-radius: 24rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 18rpx 48rpx rgba(0, 0, 0, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scan-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.corner {
|
||||||
|
position: absolute;
|
||||||
|
width: 44rpx;
|
||||||
|
height: 44rpx;
|
||||||
|
border: 6rpx solid rgba(255, 255, 255, 0.95);
|
||||||
|
border-radius: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.corner.tl {
|
||||||
|
left: 16rpx;
|
||||||
|
top: 16rpx;
|
||||||
|
border-right: 0;
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
.corner.tr {
|
||||||
|
right: 16rpx;
|
||||||
|
top: 16rpx;
|
||||||
|
border-left: 0;
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
.corner.bl {
|
||||||
|
left: 16rpx;
|
||||||
|
bottom: 16rpx;
|
||||||
|
border-right: 0;
|
||||||
|
border-top: 0;
|
||||||
|
}
|
||||||
|
.corner.br {
|
||||||
|
right: 16rpx;
|
||||||
|
bottom: 16rpx;
|
||||||
|
border-left: 0;
|
||||||
|
border-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet {
|
||||||
|
position: relative;
|
||||||
|
margin-top: -70rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-top-left-radius: 42rpx;
|
||||||
|
border-top-right-radius: 42rpx;
|
||||||
|
padding-bottom: calc(env(safe-area-inset-bottom) + 28rpx);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-thumb-row {
|
||||||
|
padding: 28rpx 0 18rpx 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-thumb {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 100rpx;
|
||||||
|
border-radius: 18rpx;
|
||||||
|
display: block;
|
||||||
|
box-shadow: 0 10rpx 24rpx rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-divider {
|
||||||
|
height: 2rpx;
|
||||||
|
background: #EDEDED;
|
||||||
|
margin: 0 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-grid {
|
||||||
|
padding: 28rpx 24rpx 0 24rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-card {
|
||||||
|
width: 344rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 22rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 22rpx;
|
||||||
|
box-shadow: 0 10rpx 24rpx rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-img {
|
||||||
|
width: 344rpx;
|
||||||
|
height: 344rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-title {
|
||||||
|
padding: 14rpx 14rpx 0 14rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
line-height: 38rpx;
|
||||||
|
color: #333;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 76rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-price-row {
|
||||||
|
padding: 10rpx 14rpx 16rpx 14rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price-symbol {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #C52733;
|
||||||
|
line-height: 1;
|
||||||
|
margin-right: 2rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price-val {
|
||||||
|
font-size: 40rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #C52733;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.origin-price {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
line-height: 1;
|
||||||
|
margin-left: 12rpx;
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cart-btn {
|
||||||
|
width: 52rpx;
|
||||||
|
height: 52rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
+133
-205
@@ -37,131 +37,57 @@
|
|||||||
conversationId: '123'
|
conversationId: '123'
|
||||||
})">播放</button> -->
|
})">播放</button> -->
|
||||||
<block v-if="chatMessageListLength < 1">
|
<block v-if="chatMessageListLength < 1">
|
||||||
<view class="home-focus-wrap">
|
<view class="home-wrap">
|
||||||
<view class="focus-guide-wrap">
|
<view class="home-focus-wrap">
|
||||||
<view class="guide-left">
|
<view class="focus-guide-wrap">
|
||||||
<image
|
<view class="guide-left">
|
||||||
:src="webUrl + '/aiChat/logo-01.gif'"
|
|
||||||
class="avatar"
|
|
||||||
mode="widthFix"
|
|
||||||
/>
|
|
||||||
</view>
|
|
||||||
<view class="guide-right">
|
|
||||||
<view class="trangle" />
|
|
||||||
<view class="title">{{ settingInfo.helloMessageTitle }}</view>
|
|
||||||
<view class="content">{{ settingInfo.helloMessageContent }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view v-if="weatherData.city && holidayData.suit" class="weather-holiday-wrap">
|
|
||||||
<view class="weather-data data-wrap">
|
|
||||||
<block v-if="!weatherDataLoading">
|
|
||||||
<view v-if="weatherIsLoad">
|
|
||||||
<!-- 各种天气对应的图标
|
|
||||||
https://yikeapi.com/help/wea
|
|
||||||
https://yikeapi.com/help/tianqiimg -->
|
|
||||||
<view class="title">
|
|
||||||
<image
|
|
||||||
:src="webUrl + '/aiChat/weather/' + weatherData.wea_img +'.png'"
|
|
||||||
class="icon"
|
|
||||||
mode="widthFix"
|
|
||||||
/>
|
|
||||||
<view class="tem-wrap">
|
|
||||||
<view class="tem">{{ weatherData.tem }}</view>
|
|
||||||
<view class="unit">℃</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="loca">
|
|
||||||
<view class="addr">
|
|
||||||
<image
|
|
||||||
:src="webUrl + '/aiChat/addr.png'"
|
|
||||||
class="icon"
|
|
||||||
mode="widthFix"
|
|
||||||
/>
|
|
||||||
{{ weatherData.city }}
|
|
||||||
</view>
|
|
||||||
<view class="tem-range">
|
|
||||||
{{ weatherData.wea }} {{ weatherData.tem2 }}℃~{{ weatherData.tem1 }}℃
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="content">今日风向:{{ weatherData.win }}</view>
|
|
||||||
<view class="content">紫外线指数:{{ weatherData.uvIndex }} {{ weatherData.uvDescription }}</view>
|
|
||||||
</view>
|
|
||||||
<view v-else class="no-weather">
|
|
||||||
<image
|
<image
|
||||||
:src="webUrl + '/aiChat/weather/no-weather.png'"
|
:src="webUrl + '/aiChat/logo-01.gif'"
|
||||||
class="img"
|
class="avatar"
|
||||||
mode="widthFix"
|
mode="widthFix"
|
||||||
/>
|
/>
|
||||||
<view>无法获取天气信息</view>
|
|
||||||
</view>
|
</view>
|
||||||
</block>
|
<view class="guide-right">
|
||||||
<block v-else>
|
<view class="title">{{ settingInfo.helloMessageTitle }}</view>
|
||||||
<view class="txt-loading">加载中...</view>
|
<view class="content">{{ settingInfo.helloMessageContent }}</view>
|
||||||
</block>
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="holidayData.suit" class="holiday-data data-wrap">
|
<view class="topic-wrap">
|
||||||
<view class="title">
|
<view class="title">
|
||||||
<view class="day">{{ holidayData.lunarCalendar }}</view>
|
<view class="title-left">大家都在问</view>
|
||||||
<view>{{ holidayData.date.substr(5).replace('-', '/') }} {{ weekDayArr[holidayData.weekDay] }}</view>
|
<view class="title-right" @click="loadData">
|
||||||
</view>
|
|
||||||
<view class="desc">{{ holidayData.yearTips }}年/{{ holidayData.chineseZodiac }}</view>
|
|
||||||
<view class="tip">
|
|
||||||
<view class="label">宜</view>
|
|
||||||
<view class="content">
|
|
||||||
{{ holidayData.suit }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="tip">
|
|
||||||
<view class="label label2">忌</view>
|
|
||||||
<view class="content">
|
|
||||||
{{ holidayData.avoid }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="topic-wrap">
|
|
||||||
<view class="title">
|
|
||||||
<image
|
|
||||||
:src="webUrl + '/aiChat/icon-01.png'"
|
|
||||||
class="icon"
|
|
||||||
mode="widthFix"
|
|
||||||
/>
|
|
||||||
<view class="txt">#大家都在问</view>
|
|
||||||
<image
|
|
||||||
:src="webUrl + '/aiChat/icon-01.png'"
|
|
||||||
class="icon"
|
|
||||||
mode="widthFix"
|
|
||||||
/>
|
|
||||||
</view>
|
|
||||||
<view class="list-wrap">
|
|
||||||
<view
|
|
||||||
:style="{
|
|
||||||
'width': animationWidth,
|
|
||||||
'animation': animationStr
|
|
||||||
}"
|
|
||||||
class="list-cont"
|
|
||||||
>
|
|
||||||
<view
|
|
||||||
v-for="(item, index) in topicList"
|
|
||||||
:key="index"
|
|
||||||
class="list-item"
|
|
||||||
@click="topicItemClickHandle(item.title)"
|
|
||||||
>
|
|
||||||
<image
|
<image
|
||||||
v-if="item.isHot"
|
:src="webUrl + '/aiChat/icon-53.png'"
|
||||||
:src="webUrl + '/aiChat/hot.png'"
|
|
||||||
class="icon"
|
class="icon"
|
||||||
mode="widthFix"
|
mode="widthFix"
|
||||||
/>
|
/>
|
||||||
{{ item.title }}
|
换一换
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="list-wrap">
|
||||||
|
<view class="list-cont">
|
||||||
|
<view
|
||||||
|
v-for="(item, index) in topicList"
|
||||||
|
:key="index"
|
||||||
|
class="list-item"
|
||||||
|
@click="topicItemClickHandle(item.title)"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
v-if="item.isHot"
|
||||||
|
:src="webUrl + '/aiChat/hot.png'"
|
||||||
|
class="icon"
|
||||||
|
mode="widthFix"
|
||||||
|
/>
|
||||||
|
{{ item.title }}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
<view class="chat-wrap">
|
<view v-if="chatMessageListLength > 0" class="chat-wrap">
|
||||||
<view v-if="chatMessageListLength > 0" class="chat-list-wrap">
|
<view class="chat-list-wrap">
|
||||||
<view
|
<view
|
||||||
v-for="(item, index) in chatMessageList"
|
v-for="(item, index) in chatMessageList"
|
||||||
:key="index"
|
:key="index"
|
||||||
@@ -267,7 +193,12 @@
|
|||||||
</view>
|
</view>
|
||||||
<!-- 换一换 -->
|
<!-- 换一换 -->
|
||||||
<view
|
<view
|
||||||
v-if="!item.showCursor && item.nodes && item.nodes.length && !item.isError && item.showMoreInfo.show"
|
v-if="!item.showCursor &&
|
||||||
|
item.nodes &&
|
||||||
|
item.nodes.length &&
|
||||||
|
!item.isError &&
|
||||||
|
(item.showMoreInfo.show || item.orderList.length > 0)
|
||||||
|
"
|
||||||
class="change-list-wrap"
|
class="change-list-wrap"
|
||||||
>
|
>
|
||||||
<view v-if="item.showMoreInfo.showType === '特产商品'" class="list-wrap">
|
<view v-if="item.showMoreInfo.showType === '特产商品'" class="list-wrap">
|
||||||
@@ -371,7 +302,19 @@
|
|||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="item.showMoreInfo.showType !== '优惠活动'" class="change-btn">
|
<view v-if="item.orderList.length > 0" class="order-list-wrap">
|
||||||
|
<view
|
||||||
|
v-for="(order, orderIndex) in item.orderList"
|
||||||
|
:key="orderIndex"
|
||||||
|
class="order-item-wrap"
|
||||||
|
>
|
||||||
|
<order-item
|
||||||
|
:item="order"
|
||||||
|
@viewOrderTrack="viewOrderTrackHandle"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="item.showMoreInfo.showType !== '优惠活动' && item.orderList.length === 0" class="change-btn">
|
||||||
<image
|
<image
|
||||||
:src="webUrl + '/aiChat/icon-change.png'"
|
:src="webUrl + '/aiChat/icon-change.png'"
|
||||||
class="icon"
|
class="icon"
|
||||||
@@ -380,6 +323,7 @@
|
|||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<!-- 建议提问 -->
|
||||||
<view
|
<view
|
||||||
v-if="index === (chatMessageListLength - 1) && item.listQuestion.length > 0"
|
v-if="index === (chatMessageListLength - 1) && item.listQuestion.length > 0"
|
||||||
class="suggestion-wrap"
|
class="suggestion-wrap"
|
||||||
@@ -420,25 +364,40 @@
|
|||||||
}"
|
}"
|
||||||
class="page-to-bottom"
|
class="page-to-bottom"
|
||||||
>
|
>
|
||||||
<view
|
<view class="container">
|
||||||
v-if="chatNumber"
|
<view
|
||||||
class="new-chat"
|
v-if="chatNumber"
|
||||||
@click="createNewHandle"
|
class="new-chat"
|
||||||
>
|
@click="createNewHandle"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
:src="webUrl + '/aiChat/icon-54.png'"
|
||||||
|
class="btn-icon"
|
||||||
|
mode="widthFix"
|
||||||
|
/>
|
||||||
|
开启新对话
|
||||||
|
</view>
|
||||||
<image
|
<image
|
||||||
:src="webUrl + '/aiChat/icon-05.png'"
|
v-if="chatMessageListLength > 0 && !isScrollToBottom && !loading"
|
||||||
class="btn-icon"
|
:src="webUrl + '/aiChat/down.png'"
|
||||||
|
class="icon"
|
||||||
mode="widthFix"
|
mode="widthFix"
|
||||||
|
@click="scrollToBottomHandle"
|
||||||
/>
|
/>
|
||||||
开启新对话
|
<view
|
||||||
|
v-for="(item, index) in bottomTools"
|
||||||
|
:key="index"
|
||||||
|
class="bottom-tool-item"
|
||||||
|
@click="bottomToolClickHandle(item)"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
:src="webUrl + '/aiChat/' + item.icon + '.png'"
|
||||||
|
class="tool-icon"
|
||||||
|
mode="widthFix"
|
||||||
|
/>
|
||||||
|
{{ item.text }}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<image
|
|
||||||
v-if="chatMessageListLength > 0 && !isScrollToBottom && !loading"
|
|
||||||
:src="webUrl + '/aiChat/down.png'"
|
|
||||||
class="icon"
|
|
||||||
mode="widthFix"
|
|
||||||
@click="scrollToBottomHandle"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
<bottom-send
|
<bottom-send
|
||||||
ref="bottomSend"
|
ref="bottomSend"
|
||||||
@@ -458,32 +417,25 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { chatMixins } from '../mixins/chatMixins.js'
|
import { chatMixinsV2 } from '../mixins/chatMixinsV2.js'
|
||||||
import {
|
import {
|
||||||
getAiSystemInfoSetting,
|
getAiSystemInfoSetting,
|
||||||
getAiSystemInfoTopic
|
getAiSystemInfoTopic
|
||||||
} from '@/api/public'
|
} from '@/api/public'
|
||||||
import {
|
|
||||||
getWeatherData,
|
|
||||||
getHolidayData
|
|
||||||
} from '@/api/chat/index'
|
|
||||||
import AiHistoryList from '../components/historyList'
|
import AiHistoryList from '../components/historyList'
|
||||||
import BottomSend from '../components/bottomSend.vue'
|
import BottomSend from '../components/bottomSend.vue'
|
||||||
|
import OrderItem from '../components/orderItem.vue'
|
||||||
export default {
|
export default {
|
||||||
name: 'AiChatIndexPage',
|
name: 'AiChatIndexPage',
|
||||||
components: {
|
components: {
|
||||||
AiHistoryList,
|
AiHistoryList,
|
||||||
BottomSend
|
BottomSend,
|
||||||
|
OrderItem
|
||||||
},
|
},
|
||||||
mixins: [chatMixins],
|
mixins: [chatMixinsV2],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
cityName: '',
|
cityName: '',
|
||||||
weatherDataLoading: false,
|
|
||||||
weatherIsLoad: true,
|
|
||||||
weatherData: {},
|
|
||||||
holidayData: {},
|
|
||||||
weekDayArr: Object.freeze(['', '周一', '周二', '周三', '周四', '周五', '周六', '周日']),
|
|
||||||
animationWidth: '150%',
|
animationWidth: '150%',
|
||||||
animationStr: '',
|
animationStr: '',
|
||||||
settingInfo: {},
|
settingInfo: {},
|
||||||
@@ -521,29 +473,7 @@ export default {
|
|||||||
getAiSystemInfoTopic().then(res => {
|
getAiSystemInfoTopic().then(res => {
|
||||||
const { success, data } = res
|
const { success, data } = res
|
||||||
if (success) {
|
if (success) {
|
||||||
this.topicList = data || []
|
this.topicList = (data || []).slice(0, 3)
|
||||||
}
|
|
||||||
})
|
|
||||||
if (this.cityName) {
|
|
||||||
this.weatherDataLoading = true
|
|
||||||
getWeatherData({
|
|
||||||
cityName: this.cityName
|
|
||||||
}).then(res => {
|
|
||||||
const { success, data } = res
|
|
||||||
if (success) {
|
|
||||||
this.weatherData = data
|
|
||||||
}
|
|
||||||
this.weatherIsLoad = true
|
|
||||||
this.weatherDataLoading = false
|
|
||||||
}).catch(() => {
|
|
||||||
this.weatherDataLoading = false
|
|
||||||
this.weatherIsLoad = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
getHolidayData().then(res => {
|
|
||||||
const { success, data } = res
|
|
||||||
if (success) {
|
|
||||||
this.holidayData = data
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -625,43 +555,39 @@ export default {
|
|||||||
opacity: 0.0;
|
opacity: 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.home-wrap {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: calc(100vh - 220rpx);
|
||||||
|
padding: 0 0 220rpx 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
.focus-guide-wrap {
|
.focus-guide-wrap {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 0 40rpx;
|
flex-direction: column;
|
||||||
.guide-left {
|
.guide-left {
|
||||||
.avatar {
|
.avatar {
|
||||||
display: block;
|
display: block;
|
||||||
width: 267rpx;
|
width: 230rpx;
|
||||||
height: 530rpx;
|
height: 404rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.guide-right {
|
.guide-right {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 30rpx;
|
width: 100%;
|
||||||
margin: 0 0 0 40rpx;
|
padding: 30rpx 0;
|
||||||
border-radius: 20rpx;
|
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
background-color: #fff;
|
text-align: center;
|
||||||
box-shadow: 0rpx 12rpx 30rpx rgba(0,0,0,0.1);
|
|
||||||
.trangle {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 120rpx;
|
|
||||||
left: -15rpx;
|
|
||||||
width: 30rpx;
|
|
||||||
height: 30rpx;
|
|
||||||
background-color: #fff;
|
|
||||||
box-shadow: -30rpx 12rpx 30rpx rgba(0,0,0,0.1);
|
|
||||||
transform: rotate(45deg);
|
|
||||||
}
|
|
||||||
.title {
|
.title {
|
||||||
width: 110%;
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
font-size: 34rpx;
|
||||||
}
|
}
|
||||||
.content {
|
.content {
|
||||||
padding: 30rpx 0 0 0;
|
padding: 30rpx 0 0 0;
|
||||||
color: #999;
|
color: #3D4CF0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -670,17 +596,17 @@ export default {
|
|||||||
.title {
|
.title {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: space-between;
|
||||||
.txt {
|
padding: 0 24rpx;
|
||||||
width: 186rpx;
|
color: #3D4CF0;
|
||||||
height: 46rpx;
|
font-size: 28rpx;
|
||||||
margin: 0 20rpx;
|
.title-left {
|
||||||
border-radius: 24rpx;
|
font-size: 32rpx;
|
||||||
text-align: center;
|
font-weight: bold;
|
||||||
line-height: 46rpx;
|
}
|
||||||
color: #fff;
|
.title-right {
|
||||||
font-size: 28rpx;
|
display: flex;
|
||||||
background-color: #3D4CF1;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.icon {
|
.icon {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -690,26 +616,20 @@ export default {
|
|||||||
}
|
}
|
||||||
.list-wrap {
|
.list-wrap {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 60rpx 0 0 0;
|
padding: 40rpx 0 0 0;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
.list-cont {
|
.list-cont {
|
||||||
display: flex;
|
padding: 0 24rpx;
|
||||||
flex-wrap: wrap;
|
|
||||||
width: 750 * 1.5rpx;
|
|
||||||
padding: 0 0 0 24rpx;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
// animation: translateXSwiper 10s infinite linear alternate;
|
|
||||||
.list-item {
|
.list-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 48rpx;
|
padding: 12rpx 18rpx;
|
||||||
padding: 0 18rpx;
|
margin: 0 0 24rpx 0;
|
||||||
margin: 0 30rpx 30rpx 0;
|
border-radius: 12rpx;
|
||||||
border-radius: 24rpx;
|
border: 1rpx solid #ddd;
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
color: #666;
|
color: #666;
|
||||||
background: rgba(255,255,255,0.39);
|
|
||||||
box-shadow: 0rpx 6rpx 12rpx rgba(0,0,0,0.1);
|
|
||||||
.icon {
|
.icon {
|
||||||
display: block;
|
display: block;
|
||||||
width: 24rpx;
|
width: 24rpx;
|
||||||
@@ -720,6 +640,14 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.order-list-wrap {
|
||||||
|
width: 100%;
|
||||||
|
padding: 24rpx 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
.order-item-wrap + .order-item-wrap {
|
||||||
|
margin: 24rpx 0 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@keyframes translateXSwiper {
|
@keyframes translateXSwiper {
|
||||||
0% {
|
0% {
|
||||||
transform: translateX(0);
|
transform: translateX(0);
|
||||||
|
|||||||
@@ -45,3 +45,7 @@ export function getWeatherData(params) {
|
|||||||
export function getHolidayData(params) {
|
export function getHolidayData(params) {
|
||||||
return request.get('/v1/chat/holidayData', params, { login: true })
|
return request.get('/v1/chat/holidayData', params, { login: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getCompletionsV3(params) {
|
||||||
|
return request.get('/v1/chat/intent/recognize', params, { login: true })
|
||||||
|
}
|
||||||
|
|||||||
+49
-15
@@ -94,24 +94,32 @@ page {
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
z-index: 8;
|
z-index: 8;
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-end;
|
|
||||||
padding: 0 24rpx;
|
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
|
overflow-x: auto;
|
||||||
&.focus {
|
&.focus {
|
||||||
transform: translateY(-40rpx);
|
transform: translateY(-40rpx);
|
||||||
}
|
}
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 24rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
.new-chat {
|
.new-chat {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 68rpx;
|
flex-shrink: 0;
|
||||||
|
height: 64rpx;
|
||||||
padding: 0 24rpx;
|
padding: 0 24rpx;
|
||||||
border-radius: 40rpx;
|
margin: 0 20rpx 0 0;
|
||||||
line-height: 68rpx;
|
border-radius: 16rpx;
|
||||||
|
line-height: 64rpx;
|
||||||
font-size: 30rpx;
|
font-size: 30rpx;
|
||||||
background-color: #fff;
|
color: #fff;
|
||||||
box-shadow: 0rpx 6rpx 12rpx rgba(0,0,0,0.16);
|
background-color: #3D4CF1;
|
||||||
|
box-shadow: 0rpx 6rpx 20rpx rgba(74,74,74,0.1);
|
||||||
.btn-icon {
|
.btn-icon {
|
||||||
display: block;
|
display: block;
|
||||||
width: 40rpx;
|
width: 40rpx;
|
||||||
@@ -121,11 +129,35 @@ page {
|
|||||||
}
|
}
|
||||||
.icon {
|
.icon {
|
||||||
display: block;
|
display: block;
|
||||||
width: 68rpx;
|
flex-shrink: 0;
|
||||||
height: 68rpx;
|
width: 64rpx;
|
||||||
margin: 0 0 0 24rpx;
|
height: 64rpx;
|
||||||
border-radius: 50%;
|
margin: 0 20rpx 0 0;
|
||||||
box-shadow: 0rpx 6rpx 12rpx rgba(0,0,0,0.16);
|
border-radius: 16rpx;
|
||||||
|
box-shadow: 0rpx 6rpx 20rpx rgba(74,74,74,0.1);
|
||||||
|
}
|
||||||
|
.bottom-tool-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
height: 64rpx;
|
||||||
|
padding: 0 24rpx;
|
||||||
|
margin: 0 20rpx 0 0;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #333;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0rpx 6rpx 20rpx rgba(74,74,74,0.1);
|
||||||
|
.tool-icon {
|
||||||
|
display: block;
|
||||||
|
width: 32rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0 12rpx 0 0;
|
||||||
|
background-color: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.fix-page-bottom {
|
.fix-page-bottom {
|
||||||
@@ -1191,4 +1223,6 @@ page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.page-to-bottom {
|
||||||
|
}
|
||||||
|
|||||||
+16
@@ -897,6 +897,22 @@
|
|||||||
"navigationStyle": "custom",
|
"navigationStyle": "custom",
|
||||||
"navigationBarTextStyle": "white"
|
"navigationBarTextStyle": "white"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "views/imageRecognition",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "拍照识图",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTextStyle": "white"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "views/imageRecognitionResult",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "识别结果",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTextStyle": "white"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -486,6 +486,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
|
console.time()
|
||||||
// uni.hideTabBar()
|
// uni.hideTabBar()
|
||||||
const _this = this
|
const _this = this
|
||||||
_this.init()
|
_this.init()
|
||||||
@@ -1485,6 +1486,9 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.$nextTick(() => {
|
||||||
|
console.timeEnd()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
uni.hideLoading()
|
uni.hideLoading()
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user