1 Commits
Author SHA1 Message Date
lifizer 5f835afd8b Feat(AI):关键词搜索匹配相关模块列表 2025-05-12 15:48:02 +08:00
6 changed files with 428 additions and 5 deletions
+8
View File
@@ -120,6 +120,14 @@ export default {
webUrl: this.$VUE_APP_RESOURCES_URL,
// 输入模式:input-键盘,sound-语音
inputModel: 'input',
/**
* 端午节送礼攻略
* 丽江逛吃攻略
* 云南非遗有哪些?
* 怎么申请地理标志保护产品?
* 想找个像《去有风的地方》那样的治愈县城
* 云南有哪些小众县城适合旅居?
*/
prompt: '',
recordManager: null,
// 录音权限是否开通
+97 -3
View File
@@ -1,7 +1,9 @@
import {
getSseConfigV1,
getCompletionsV2,
deleteChatItemByConversationId
deleteChatItemByConversationId,
getAnalyzeKeywordsV1,
getAnalyzeKeywordsChangeV1
} from '@/api/chat/index'
import { VUE_APP_API_URL } from '@/config'
import settings from '@/config/baseSetting.js'
@@ -104,10 +106,21 @@ export const chatMixins = {
copyContentHandle(data) {
uni.setClipboardData({
data,
success: () =>
success: () => {
uni.showToast({
title: '已复制'
})
}
})
},
copyMoreInfoHandle(item) {
uni.setClipboardData({
data: JSON.stringify(item.showMoreInfo),
success: () => {
uni.showToast({
title: '已复制'
})
}
})
},
shareHandle() {
@@ -181,7 +194,8 @@ export const chatMixins = {
conversationId: '',
prompt,
listQuestion: [],
type: -2
type: -2,
showMoreInfo: {}
})
_this.loading = true
_this.showCursor = false
@@ -207,6 +221,32 @@ export const chatMixins = {
_this.chatErrorSetContent()
})
})
getAnalyzeKeywordsV1({
'chatNumber': _this.chatNumber,
conversationId,
prompt
}).then(keywordRes => {
if (keywordRes.success) {
const keywordResData = keywordRes.data
const show = (keywordResData.searchArtworks ||
keywordResData.searchDiscount ||
keywordResData.searchGoods ||
keywordResData.searchLandmark ||
keywordResData.searchTowns ||
keywordResData.searchTravelGuide
) && (keywordResData.resultItems && keywordResData.resultItems.length > 0)
_this.chatMessageList[_this.chatMessageListLength - 1].showMoreInfo = keywordResData
_this.chatMessageList[_this.chatMessageListLength - 1].showMoreInfo.show = show
// 展示类型
_this.chatMessageList[_this.chatMessageListLength - 1].showMoreInfo.showType = ''
if (show && keywordResData.resultItems) {
keywordResData.resultItems.map(resItem => {
_this.chatMessageList[_this.chatMessageListLength - 1].showMoreInfo.showType = resItem.type
})
}
console.log(_this.chatMessageList[_this.chatMessageListLength - 1])
}
})
} else {
_this.chatErrorSetContent()
}
@@ -215,6 +255,60 @@ export const chatMixins = {
_this.chatErrorSetContent()
})
},
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.$yrouter.push({
path: '/pages/shop/GoodsCon/index',
query: {
id: item.id
}
})
},
hotelItemClickHandle(item) {
this.$yrouter.push({
path: '/pagesInn/inn/innHome',
query: {
id: item.id
}
})
},
ichItemClickHandle(item) {
this.$yrouter.push({
path: '/pkg_product/views/heritage/details',
query: {
id: item.id
}
})
},
qianxianItemClickHandle(item) {
this.$yrouter.push({
path: '/pkg_product/views/famousQianxianShop',
query: {
id: item.id
}
})
},
chatErrorSetContent() {
this.chatMessageList[this.chatMessageListLength - 1].isError = true
this.chatMessageList[this.chatMessageListLength - 1].content = this.errorMsg
+101
View File
@@ -100,6 +100,107 @@
</view>
</view>
</view>
<!-- 换一换 -->
<view
v-if="item.showMoreInfo.show"
class="change-list-wrap"
>
<view v-if="item.showMoreInfo.showType === '特产商品'" class="list-wrap">
<view
v-for="(productItem, productIndex) in item.showMoreInfo.resultItems"
:key="productIndex"
class="product-item"
@click="productItemClickHandle(productItem)"
>
<image
:src="productItem.img"
class="img"
/>
<view class="product-info">
<view class="name one-t">
{{ productItem.name }}
</view>
<view class="price-wrap">
<view class="price">
<text class="txt"></text>{{ productItem.price }}
</view>
<view class="btn">立即查看</view>
</view>
</view>
</view>
</view>
<view v-if="item.showMoreInfo.showType === '店铺'" class="list-wrap">
<view
v-for="(hotel, hotelIndex) in item.showMoreInfo.resultItems"
:key="hotelIndex"
class="product-item"
@click="hotelItemClickHandle(hotel)"
>
<view class="hotel-type">
手工体验
</view>
<image
:src="hotel.img"
class="img"
/>
<view class="product-info">
<view class="name one-t">
{{ hotel.name }}
</view>
<view class="desc-wrap one-t">
{{ hotel.description || '' }}
</view>
</view>
</view>
</view>
<view v-if="item.showMoreInfo.showType === '非遗文化'" class="list-wrap">
<view
v-for="(ich, ichIndex) in item.showMoreInfo.resultItems"
:key="ichIndex"
class="product-item"
@click="ichItemClickHandle(ich)"
>
<image
:src="ich.img"
class="img"
/>
<view class="product-info">
<view class="name one-t">
{{ ich.name }}
</view>
<view class="desc-wrap one-t">
{{ ich.description || '' }}
</view>
</view>
</view>
</view>
<view v-if="item.showMoreInfo.showType === '千县名品'" class="list-wrap">
<view
v-for="(qianxian, qianxianIndex) in item.showMoreInfo.resultItems"
:key="qianxianIndex"
class="product-item"
@click="qianxianItemClickHandle(qianxian)"
>
<image
:src="qianxian.img"
class="img"
/>
<view class="product-info">
<view class="name name2 one-t">
{{ qianxian.name }}
</view>
</view>
</view>
</view>
<view class="change-btn">
<image
:src="webUrl + '/aiChat/icon-change.png'"
class="icon"
mode="widthFix"
@click="analyzeKeywordsChangeHandle(item.conversationId, item.showMoreInfo)"
/>
</view>
</view>
<view
v-if="index === (chatMessageListLength - 1) && item.listQuestion.length > 0"
class="suggestion-wrap"
+105 -2
View File
@@ -21,8 +21,9 @@
:z-index="1"
@beforeleave="pageContainerBeforeleave"
>
<view style="opacity: 0;"></view>
遮罩层用于监听实体键返回
<view style="opacity: 0;">
遮罩层用于监听实体键返回
</view>
</page-container>
<view
id="fixTbabarBody"
@@ -165,9 +166,111 @@
/>
重新生成
</view>
<view class="item item2" @click="copyMoreInfoHandle(item)">拷贝</view>
</view>
</view>
</view>
<!-- 换一换 -->
<view
v-if="item.showMoreInfo.show"
class="change-list-wrap"
>
<view v-if="item.showMoreInfo.showType === '特产商品'" class="list-wrap">
<view
v-for="(productItem, productIndex) in item.showMoreInfo.resultItems"
:key="productIndex"
class="product-item"
@click="productItemClickHandle(productItem)"
>
<image
:src="productItem.img"
class="img"
/>
<view class="product-info">
<view class="name one-t">
{{ productItem.name }}
</view>
<view class="price-wrap">
<view class="price">
<text class="txt"></text>{{ productItem.price }}
</view>
<view class="btn">立即查看</view>
</view>
</view>
</view>
</view>
<view v-if="item.showMoreInfo.showType === '店铺'" class="list-wrap">
<view
v-for="(hotel, hotelIndex) in item.showMoreInfo.resultItems"
:key="hotelIndex"
class="product-item"
@click="hotelItemClickHandle(hotel)"
>
<view class="hotel-type">
手工体验
</view>
<image
:src="hotel.img"
class="img"
/>
<view class="product-info">
<view class="name one-t">
{{ hotel.name }}
</view>
<view class="desc-wrap one-t">
{{ hotel.description || '' }}
</view>
</view>
</view>
</view>
<view v-if="item.showMoreInfo.showType === '非遗文化'" class="list-wrap">
<view
v-for="(ich, ichIndex) in item.showMoreInfo.resultItems"
:key="ichIndex"
class="product-item"
@click="ichItemClickHandle(ich)"
>
<image
:src="ich.img"
class="img"
/>
<view class="product-info">
<view class="name one-t">
{{ ich.name }}
</view>
<view class="desc-wrap one-t">
{{ ich.description || '' }}
</view>
</view>
</view>
</view>
<view v-if="item.showMoreInfo.showType === '千县名品'" class="list-wrap">
<view
v-for="(qianxian, qianxianIndex) in item.showMoreInfo.resultItems"
:key="qianxianIndex"
class="product-item"
@click="qianxianItemClickHandle(qianxian)"
>
<image
:src="qianxian.img"
class="img"
/>
<view class="product-info">
<view class="name name2 one-t">
{{ qianxian.name }}
</view>
</view>
</view>
</view>
<view class="change-btn">
<image
:src="webUrl + '/aiChat/icon-change.png'"
class="icon"
mode="widthFix"
@click="analyzeKeywordsChangeHandle(item.conversationId, item.showMoreInfo)"
/>
</view>
</view>
<view
v-if="index === (chatMessageListLength - 1) && item.listQuestion.length > 0"
class="suggestion-wrap"
+10
View File
@@ -12,6 +12,16 @@ export function getCompletionsV2(params) {
return request.get('/v1/chat/sse/completions2', params, { login: true })
}
// 通过关键字-搜索列表
export function getAnalyzeKeywordsV1(data) {
return request.post('/v1/chat/analyzeKeywords', data, { login: true })
}
// 通过关键字-搜索列表-换一换
export function getAnalyzeKeywordsChangeV1(data) {
return request.post('/v1/chat/aiSearch', data, { login: true })
}
export function deleteChatItemByConversationId(id) {
return request.delete('/v1/chat/message/' + id, {}, { login: true })
}
+107
View File
@@ -488,6 +488,7 @@ page {
}
}
.bottom-btns {
position: relative;
display: flex;
justify-content: flex-start;
padding: 20rpx 0 0 0;
@@ -510,6 +511,13 @@ page {
margin: 0 6rpx 0 0;
}
}
.item2 {
position: absolute;
bottom: 0;
right: 0;
margin: 0;
color: transparent;
}
}
}
}
@@ -919,4 +927,103 @@ page {
100% {
height: 20rpx;
}
}
.change-list-wrap {
.list-wrap {
display: flex;
flex-wrap: nowrap;
width: 100%;
flex-shrink: 0;
padding: 40rpx 0;
overflow-x: auto;
.product-item {
position: relative;
width: 240rpx;
margin: 0 24rpx 0 0;
border-radius: 20rpx;
background-color: #fff;
box-shadow: 0rpx 6rpx 12rpx rgba(0,0,0,0.16);
&:last-child {
margin: 0;
}
.img {
position: relative;
z-index: 2;
display: block;
width: 240rpx;
height: 240rpx;
border-radius: 20rpx;
}
.product-info {
padding: 12rpx;
.name {
height: 34rpx;
font-size: 24rpx;
color: #333;
line-height: 34rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
transition: all linear 0.2s;
}
.name2 {
font-weight: bold;
}
.price-wrap {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 12rpx;
.price {
color: #C52733;
font-size: 24rpx;
font-weight: bold;
.txt {
font-size: 16rpx;
}
}
.btn {
height: 30rpx;
padding: 0 12rpx;
border-radius: 16rpx;
color: #fff;
font-size: 22rpx;
background-color: #C52733;
}
}
.desc-wrap {
font-size: 24rpx;
color: #999;
line-height: 34rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.hotel-type {
position: absolute;
top: 0;
left: 0;
z-index: 5;
height: 40rpx;
padding: 0 24rpx;
border-top-left-radius: 20rpx;
border-bottom-right-radius: 20rpx;
color: #fff;
font-size: 24rpx;
background-color: rgba(0, 0, 0, 0.5);
}
}
}
.change-btn {
display: flex;
align-items: center;
justify-content: center;
padding: 0 0 20rpx 0;
.icon {
display: block;
width: 124rpx;
height: 38rpx;
}
}
}