fix:更新聊天优化
This commit is contained in:
parent
4765dad143
commit
55f2e26b8c
@ -1,3 +1,3 @@
|
||||
{
|
||||
"version": "0.0.80"
|
||||
"version": "0.0.83"
|
||||
}
|
||||
3
dist/build/mp-weixin/app.json
vendored
3
dist/build/mp-weixin/app.json
vendored
@ -6,6 +6,7 @@
|
||||
"pages/forward/index",
|
||||
"pages/me/index",
|
||||
"pages/ai/chat",
|
||||
"pages/ai/index",
|
||||
"pages/web_view/index"
|
||||
],
|
||||
"subPackages": [
|
||||
@ -95,7 +96,7 @@
|
||||
"selectedIconPath": "/static/tabbar/home_active.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/ai/chat",
|
||||
"pagePath": "pages/ai/index",
|
||||
"text": "管家在线",
|
||||
"iconPath": "/static/tabbar/news_active.png",
|
||||
"selectedIconPath": "/static/tabbar/news_active.png"
|
||||
|
||||
@ -1 +1 @@
|
||||
"use strict";const e=require("../vendor.js"),r=require("../store/useWeAppAuthStore.js"),t=new e.Request;t.setConfig((e=>(e.baseURL="https://weapp-api.linyikj.com.cn/api/",e.header={...e.header},e))),t.interceptors.request.use((r=>(r.header={...r.header,Authorization:"Bearer "+e.index.getStorageSync("NCHL_TEST_ACCESS_TOKEN_CUSTOMER")},r)),(e=>Promise.reject(e))),t.interceptors.response.use((t=>{const o=t.data;if(e.index.hideLoading(),!0!==o.success){if(10001===o.errorCode){r.useWeAppAuthStore().loading=!1,e.index.showToast({title:o.errorMessage,icon:"none"})}else e.index.showToast({title:o.errorMessage,icon:"none"});return Promise.reject(t.data)}return t.data}),(e=>{console.log("error",e);return r.useWeAppAuthStore().loading=!1,Promise.reject(e)})),exports.request=function(e,r){return t.post(e,r.data)};
|
||||
"use strict";const e=require("../vendor.js"),r=require("../store/useWeAppAuthStore.js"),t=new e.Request;t.setConfig((e=>(e.baseURL="https://weapp-api.linyikj.com.cn/api/",e.header={...e.header},e))),t.interceptors.request.use((r=>(r.header={...r.header,Authorization:"Bearer "+e.index.getStorageSync("NCHL_PROD_ACCESS_TOKEN_CUSTOMER")},r)),(e=>Promise.reject(e))),t.interceptors.response.use((t=>{const o=t.data;if(e.index.hideLoading(),!0!==o.success){if(10001===o.errorCode){r.useWeAppAuthStore().loading=!1,e.index.showToast({title:o.errorMessage,icon:"none"})}else e.index.showToast({title:o.errorMessage,icon:"none"});return Promise.reject(t.data)}return t.data}),(e=>{console.log("error",e);return r.useWeAppAuthStore().loading=!1,Promise.reject(e)})),exports.request=function(e,r){return t.post(e,r.data)};
|
||||
|
||||
@ -1 +1 @@
|
||||
"use strict";let t=[{pagePath:"/pages/index/index",iconPath:"/static/tabbar/home_icon.png",selectedIconPath:"/static/tabbar/home_active.png",text:"首页"},{pagePath:"/pages/ai/chat",iconPath:"/static/tabbar/news_icon.png",selectedIconPath:"/static/tabbar/news_active.png",text:"管家在线"},{pagePath:"/pages/me/index",iconPath:"/static/tabbar/news_icon.png",selectedIconPath:"/static/tabbar/news_active.png",text:"我的"}];exports.setTabBar=function(a){var e,n,l,o,c,i,s,u;const g=getCurrentPages(),p=g[g.length-1];if(p){const s=(null==p?void 0:p.getTabBar)?null==p?void 0:p.getTabBar():null;let u=null==(l=null==(n=null==(e=null==a?void 0:a.companyConfig)?void 0:e.config_value)?void 0:n.menu)?void 0:l.map((t=>{var a,e,n,l;return{...t,iconPath:null==(e=null==(a=t.iconPath)?void 0:a[0])?void 0:e.url,selectedIconPath:null==(l=null==(n=t.selectedIconPath)?void 0:n[0])?void 0:l.url}}));u.splice((null==(i=null==(c=null==(o=null==a?void 0:a.companyConfig)?void 0:o.config_value)?void 0:c.menu)?void 0:i.length)/2,0,{pagePath:"/pages/ai/chat",iconPath:"https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN63WTGSX2T5X8N233CJ5K0Q.png",selectedIconPath:"https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN63WTGSX2T5X8N233CJ5K0Q.png",text:"管家在线"}),getApp().globalData.menuList=u||t,s&&s.setData({list:u||t})}console.log("App.globalData.selectedOrg",null==(u=null==(s=null==a?void 0:a.companyConfig)?void 0:s.config_value)?void 0:u.menu)};
|
||||
"use strict";let t=[{pagePath:"/pages/index/index",iconPath:"/static/tabbar/home_icon.png",selectedIconPath:"/static/tabbar/home_active.png",text:"首页"},{pagePath:"/pages/ai/chat",iconPath:"/static/tabbar/news_icon.png",selectedIconPath:"/static/tabbar/news_active.png",text:"管家在线"},{pagePath:"/pages/me/index",iconPath:"/static/tabbar/news_icon.png",selectedIconPath:"/static/tabbar/news_active.png",text:"我的"}];exports.setTabBar=function(a){var e,n,l,o,c,i,s,g;const p=getCurrentPages(),u=p[p.length-1];if(u){const s=(null==u?void 0:u.getTabBar)?null==u?void 0:u.getTabBar():null;let g=null==(l=null==(n=null==(e=null==a?void 0:a.companyConfig)?void 0:e.config_value)?void 0:n.menu)?void 0:l.map((t=>{var a,e,n,l;return{...t,iconPath:null==(e=null==(a=t.iconPath)?void 0:a[0])?void 0:e.url,selectedIconPath:null==(l=null==(n=t.selectedIconPath)?void 0:n[0])?void 0:l.url}}));g.splice((null==(i=null==(c=null==(o=null==a?void 0:a.companyConfig)?void 0:o.config_value)?void 0:c.menu)?void 0:i.length)/2,0,{pagePath:"/pages/ai/index",iconPath:"https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN63WTGSX2T5X8N233CJ5K0Q.png",selectedIconPath:"https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN63WTGSX2T5X8N233CJ5K0Q.png",text:"管家在线"}),getApp().globalData.menuList=g||t,console.log("getApp().globalData",getApp().globalData,g),s&&s.setData({list:g||t})}console.log("App.globalData.selectedOrg",null==(g=null==(s=null==a?void 0:a.companyConfig)?void 0:s.config_value)?void 0:g.menu)};
|
||||
|
||||
@ -1 +1 @@
|
||||
"use strict";const e=require("../vendor.js");require("./request.js");const o=require("../store/useWeAppAuthStore.js");require("../store/useWorkStore.js");const n=o.useWeAppAuthStore(),r={onBindPhone(){var o;return console.log("auth?.userInfo:",null==n?void 0:n.data),!!(null==(o=null==n?void 0:n.data)?void 0:o.user)||(e.index.showModal({title:"登录",content:"请先登录体验更多功能!",success:function(o){o.confirm?(e.index.navigateTo({url:"/pages/login"}),console.log("用户点击确定")):o.cancel&&console.log("用户点击取消")}}),!1)},getLoginStatus(){var e;return!!(null==(e=null==n?void 0:n.data)?void 0:e.user)}};exports.getUserLogin=r;
|
||||
"use strict";const e=require("../vendor.js");require("./request.js");const o=require("../store/useWeAppAuthStore.js");require("../store/useWorkStore.js");const n=o.useWeAppAuthStore(),t={onBindPhone(){var o;return console.log("auth?.userInfo:",null==n?void 0:n.data),!!(null==(o=null==n?void 0:n.data)?void 0:o.user)||(e.index.showModal({title:"登录",content:"请先登录体验更多功能!",success:function(o){o.confirm?(e.index.navigateTo({url:"/pages/login"}),console.log("用户点击确定")):o.cancel&&console.log("用户点击取消")}}),!1)},getLoginStatus(){var e,o;return console.log("auth?.data?.user:",null==(e=null==n?void 0:n.data)?void 0:e.user),!!(null==(o=null==n?void 0:n.data)?void 0:o.user)}};exports.getUserLogin=t;
|
||||
|
||||
@ -1 +1 @@
|
||||
"use strict";const e=require("../vendor.js"),o=require("../../gen/Apis.js"),i=require("../libraries/setTabBar.js"),u=require("../libraries/apiLoading.js"),a="wx31500e871924b903",n=e.defineStore("we_app_auth",(()=>{const n=e.ref(!1),s=e.ref(!1),t=e.ref(0),l=e.ref({user:{id:0,name:""},work_info:{session_key:"",openid:""},selected_house:{},environment:"",house_occupant:!1,house_register:!1,is_house_exist:0,config:{}});const r=(u,t)=>{o.Apis.Login.Auth.Login({code:t,app_id:a}).then((o=>{var a,t,r,v,c,g;console.log("登录",null==o?void 0:o.data),l.value.user=null==(a=o.data)?void 0:a.user,l.value.selected_house=null==(t=o.data)?void 0:t.selected_house,l.value.config=null==(r=o.data)?void 0:r.config,i.setTabBar(null==(v=null==o?void 0:o.data)?void 0:v.config),e.index.setStorageSync("NCHL_TEST_ACCESS_TOKEN_CUSTOMER",null==(g=null==(c=null==o?void 0:o.data)?void 0:c.token)?void 0:g.token),l.value.user&&d(),setTimeout((()=>{n.value=!1,s.value=!1}),300),null==u||u.appContext.config.globalProperties.$isResolve()})).catch((()=>{n.value=!1,s.value=!0}))},d=()=>{o.Apis.Archive.HouseOccupants.GetCustomerHouseIsExist().then((e=>{var o,i;l.value.house_occupant=(null==(o=e.data)?void 0:o.house_occupant)||!1,l.value.house_register=(null==(i=e.data)?void 0:i.house_register)||!1,l.value.is_house_exist=t.value+1}))};function v(e){u.getApiLoading(o.Apis.Login.Auth.Me,{}).then((o=>{var u,a,t;return l.value.user=o.data.user,l.value.config=null==(u=o.data)?void 0:u.config,l.value.selected_house=null==(a=o.data)?void 0:a.selected_house,i.setTabBar(null==(t=null==o?void 0:o.data)?void 0:t.config),console.log("me",o.data),l.value.user&&d(),setTimeout((()=>{n.value=!1,s.value=!1}),300),null==e?void 0:e()}))}return{loading:n,hasError:s,data:l,login:function(o){e.index.login({provider:"weixin",success:function(e){console.log(e),r(o,e.code)}})},me:v,handleUserLogin:async i=>{u.getApiLoading(o.Apis.Login.Auth.BindPhoneNumber,{app_id:a,...i}).then((o=>{v((()=>{e.index.navigateBack({delta:1})}))}))},getIsHouseExist:d}}));exports.useWeAppAuthStore=n;
|
||||
"use strict";const e=require("../vendor.js"),o=require("../../gen/Apis.js"),i=require("../libraries/setTabBar.js"),u=require("../libraries/apiLoading.js"),a="wx31500e871924b903",n=e.defineStore("we_app_auth",(()=>{const n=e.ref(!1),s=e.ref(!1),t=e.ref(0),l=e.ref({user:{id:0,name:""},work_info:{session_key:"",openid:""},selected_house:{},environment:"",house_occupant:!1,house_register:!1,is_house_exist:0,config:{}});const r=(u,t)=>{o.Apis.Login.Auth.Login({code:t,app_id:a}).then((o=>{var a,t,r,v,c,g;console.log("登录",null==o?void 0:o.data),e.index.setStorageSync("NCHL_PROD_ACCESS_TOKEN_CUSTOMER",null==(t=null==(a=null==o?void 0:o.data)?void 0:a.token)?void 0:t.token),null==u||u.appContext.config.globalProperties.$isResolve(),setTimeout((()=>{n.value=!1,s.value=!1}),300),l.value.selected_house=null==(r=o.data)?void 0:r.selected_house,l.value.user=null==(v=o.data)?void 0:v.user,l.value.config=null==(c=o.data)?void 0:c.config,i.setTabBar(null==(g=null==o?void 0:o.data)?void 0:g.config),l.value.user&&d()})).catch((()=>{n.value=!1,s.value=!0}))},d=()=>{o.Apis.Archive.HouseOccupants.GetCustomerHouseIsExist().then((e=>{var o,i;l.value.house_occupant=(null==(o=e.data)?void 0:o.house_occupant)||!1,l.value.house_register=(null==(i=e.data)?void 0:i.house_register)||!1,l.value.is_house_exist=t.value+1}))};function v(e){u.getApiLoading(o.Apis.Login.Auth.Me,{}).then((o=>{var u,a,t;return l.value.user=o.data.user,l.value.config=null==(u=o.data)?void 0:u.config,l.value.selected_house=null==(a=o.data)?void 0:a.selected_house,console.log("me",o.data),l.value.user&&d(),setTimeout((()=>{n.value=!1,s.value=!1}),300),i.setTabBar(null==(t=null==o?void 0:o.data)?void 0:t.config),null==e?void 0:e()}))}return{loading:n,hasError:s,data:l,login:function(o){e.index.login({provider:"weixin",success:function(e){console.log(e),r(o,e.code)}})},me:v,handleUserLogin:async i=>{u.getApiLoading(o.Apis.Login.Auth.BindPhoneNumber,{app_id:a,...i}).then((o=>{v((()=>{e.index.navigateBack({delta:1})}))}))},getIsHouseExist:d}}));exports.useWeAppAuthStore=n;
|
||||
|
||||
17
dist/build/mp-weixin/custom-tab-bar/index.js
vendored
17
dist/build/mp-weixin/custom-tab-bar/index.js
vendored
@ -12,9 +12,11 @@ Component({
|
||||
text: '首页'
|
||||
},
|
||||
{
|
||||
pagePath: '/pages/ai/chat',
|
||||
iconPath: '/static/tabbar/news_icon.png',
|
||||
selectedIconPath: '/static/tabbar/news_active.png',
|
||||
pagePath: '/pages/ai/index',
|
||||
iconPath:
|
||||
'https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN63WTGSX2T5X8N233CJ5K0Q.png',
|
||||
selectedIconPath:
|
||||
'https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN63WTGSX2T5X8N233CJ5K0Q.png',
|
||||
text: '管家在线'
|
||||
},
|
||||
{
|
||||
@ -32,17 +34,20 @@ Component({
|
||||
let _this = this
|
||||
const pages = getCurrentPages()
|
||||
const currentPage = pages[pages.length - 1]
|
||||
console.log('currentList', getApp().globalData.menuList)
|
||||
if (currentPage) {
|
||||
console.log('currentList', getApp().globalData, currentPage)
|
||||
if (currentPage && this.data.list) {
|
||||
const currentPath = currentPage.route
|
||||
const index = this.data.list.findIndex(item => item.pagePath === `/${currentPath}`)
|
||||
if (index !== -1) {
|
||||
this.setData({
|
||||
selected: index,
|
||||
list: getApp().globalData.menuList
|
||||
list: this.data.list
|
||||
})
|
||||
App.globalData.selectedIndex = index
|
||||
}
|
||||
if (!getApp().globalData.menuList) {
|
||||
getApp().globalData.menuList = this.data.list
|
||||
}
|
||||
}
|
||||
}
|
||||
// 初始化时执行一次
|
||||
|
||||
13
dist/build/mp-weixin/custom-tab-bar/index.wxml
vendored
13
dist/build/mp-weixin/custom-tab-bar/index.wxml
vendored
@ -1,8 +1,11 @@
|
||||
<!--miniprogram/custom-tab-bar/index.wxml-->
|
||||
<view class="tab-bar">
|
||||
<!-- <view class="tab-bar-border"></view>-->
|
||||
<view wx:for="{{list}}" wx:key="index" class="{{index === 1 ? 'tab-bar-item-center' : 'tab-bar-item'}}" data-path="{{item.pagePath}}" data-index="{{index}}" bindtap="switchTab">
|
||||
<image class="{{index === 1 ? 'tab-bar-item-icon' : ''}}" src="{{selected === index ? item.selectedIconPath : item.iconPath}}"></image>
|
||||
<view wx:if="{{index !== 1}}" style="color: {{selected === index ? selectedColor : color}}">{{item.text}}</view>
|
||||
<view class="tab-bar" style="">
|
||||
<!-- <view class="tab-bar-border"></view>-->
|
||||
<view class='tab-bar-content'>
|
||||
<view wx:for="{{list}}" wx:key="index" class="{{index === 1 ? 'tab-bar-item-center' : 'tab-bar-item'}}" data-path="{{item.pagePath}}" data-index="{{index}}" bindtap="switchTab">
|
||||
<image class="{{index === 1 ? 'tab-bar-item-icon' : ''}}" src="{{selected === index ? item.selectedIconPath : item.iconPath}}"></image>
|
||||
<view wx:if="{{index !== 1}}" style="color: {{selected === index ? selectedColor : color}}">{{item.text}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="safe-area-inset-bottom"></view>
|
||||
</view>
|
||||
|
||||
24
dist/build/mp-weixin/custom-tab-bar/index.wxss
vendored
24
dist/build/mp-weixin/custom-tab-bar/index.wxss
vendored
@ -3,16 +3,22 @@
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 48px;
|
||||
/* background: url('https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN62JHV37KC4W8K8A391MS3Y.png')
|
||||
no-repeat; */
|
||||
background: url(' https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN62VGEVV8NSR4GDDQAYC2JV.png')
|
||||
no-repeat;
|
||||
background-size: 100% auto;
|
||||
display: flex;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
/* padding-bottom: env(safe-area-inset-bottom); */
|
||||
}
|
||||
.safe-area-inset-bottom {
|
||||
width: 100%;
|
||||
height: env(safe-area-inset-bottom);
|
||||
background-color: #fff;
|
||||
}
|
||||
.tab-bar-content {
|
||||
display: flex;
|
||||
height: 48px;
|
||||
width: 100%;
|
||||
background: url('https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN6H4Z5VTWGPRGQZ35CPYHF5.png')
|
||||
center no-repeat;
|
||||
background-size: 100%;
|
||||
}
|
||||
.tab-bar-border {
|
||||
background-color: rgba(0, 0, 0, 0.33);
|
||||
position: absolute;
|
||||
|
||||
2
dist/build/mp-weixin/pages/ai/chat.js
vendored
2
dist/build/mp-weixin/pages/ai/chat.js
vendored
File diff suppressed because one or more lines are too long
5
dist/build/mp-weixin/pages/ai/chat.json
vendored
5
dist/build/mp-weixin/pages/ai/chat.json
vendored
@ -2,6 +2,9 @@
|
||||
"navigationBarTitleText": "客服服务",
|
||||
"enablePullDownRefresh": true,
|
||||
"usingComponents": {
|
||||
"uni-icons": "../../uni_modules/uni-icons/components/uni-icons/uni-icons"
|
||||
"uni-icons": "../../uni_modules/uni-icons/components/uni-icons/uni-icons",
|
||||
"hs-empty": "../../components/hs-empty/hs-empty",
|
||||
"hs-button": "../../components/hs-button/hs-button",
|
||||
"my-header-prologue": "./components/HeaderPrologue"
|
||||
}
|
||||
}
|
||||
2
dist/build/mp-weixin/pages/ai/chat.wxml
vendored
2
dist/build/mp-weixin/pages/ai/chat.wxml
vendored
@ -1 +1 @@
|
||||
<view class="chat-container"><view class="chat_container_linear_gradient"></view><view class="chat_messages_body"><view class="opening_remarks"><view class="opening_remarks_body"><view class="opening_remarks_server_img"><image src="https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN5XRPWKSMDDHRJTY4F2TG1G.png" mode="heightFix"/></view><view class="opening_remarks_server_info"><view class="label"> 我是管家-邻邻,有什么可以帮助您的吗? </view><view class="group_btn"><view class="group_btn_item"> 房屋绑定 </view><view class="group_btn_item"> 物业缴费 </view><view class="group_btn_item"> 工单报事 </view><view class="group_btn_item"> 社区服务 </view><view class="group_btn_item"> 访客邀请 </view><view class="group_btn_item"> 房屋管理 </view></view></view></view></view><view class="chat-messages"><view wx:for="{{a}}" wx:for-item="message" wx:key="F" id="{{message.G}}" class="{{['message-item', message.H]}}"><view wx:if="{{message.a}}" class="message-avatar"><image src="https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN43RH4M09FAFBD8D9TQPM2B.png" mode="aspectFit"/></view><view class="message-content-wrapper"><view class="message-content"><view wx:if="{{message.b}}" class="message-images"><view wx:for="{{message.c}}" wx:for-item="image" wx:key="c" class="{{['message-image-item', message.e && 'single-image']}}"><image src="{{image.a}}" mode="{{message.d}}" class="message-image" bindtap="{{image.b}}"/></view></view><view wx:elif="{{message.f}}" class="message-images"><view wx:for="{{message.g}}" wx:for-item="image" wx:key="c" class="{{['message-image-item', message.i && 'single-image']}}"><image src="{{image.a}}" mode="{{message.h}}" class="message-image" bindtap="{{image.b}}"/></view></view><view wx:elif="{{message.j}}" class="message-images"><view wx:for="{{message.k}}" wx:for-item="image" wx:key="c" class="{{['message-image-item', message.m && 'single-image']}}"><image src="{{image.a}}" mode="{{message.l}}" class="message-image" bindtap="{{image.b}}"/></view></view><block wx:if="{{message.n}}"><view wx:for="{{message.o}}" wx:for-item="line" wx:key="b" class="message-text-line"><text>{{line.a}}</text></view></block></view><view wx:if="{{message.p}}" class="quick-questions"><view wx:for="{{message.q}}" wx:for-item="question" wx:key="b" class="question-btn" bindtap="{{question.c}}"><text>{{question.a}}</text></view></view><view wx:if="{{message.r}}" class="confirmation-buttons"><view class="{{['confirmation-btn', message.s && 'selected', message.t && 'disabled']}}" bindtap="{{message.v}}"><text>是</text></view><view class="{{['confirmation-btn', message.w && 'selected', message.x && 'disabled']}}" bindtap="{{message.y}}"><text>否</text></view></view><view wx:if="{{message.z}}" class="message-meta"><view wx:if="{{message.A}}" class="copy-button" bindtap="{{message.B}}"><image src="/static/svg/copy.svg" mode="aspectFit" class="copy-icon"/></view><text class="message-time">{{message.C}}</text><view wx:if="{{message.D}}" class="copy-button" bindtap="{{message.E}}"><image src="/static/svg/copy.svg" mode="aspectFit" class="copy-icon"/></view></view></view></view><view wx:if="{{b}}" class="message-item ai-message"><view class="message-avatar"><image src="/static/svg/ai_icon.svg" mode="aspectFit"/></view><view class="message-content loading"><text>{{c}}</text></view></view></view><view class="chat-input-area"><view wx:if="{{d}}" class="image-preview-area"><view class="image-preview-list"><view wx:for="{{e}}" wx:for-item="image" wx:key="d" class="image-preview-item"><image src="{{image.a}}" mode="aspectFill" class="preview-image"/><view class="remove-image" bindtap="{{image.c}}"><uni-icons wx:if="{{f}}" u-i="{{image.b}}" bind:__l="__l" u-p="{{f}}"/></view></view><view wx:if="{{g}}" class="image-preview-item add-more-button" bindtap="{{i}}"><uni-icons wx:if="{{h}}" u-i="25c36616-1" bind:__l="__l" u-p="{{h}}"/><text class="add-more-text">添加图片</text></view></view></view><view class="input-container"><input class="message-input" placeholder="请输入您的问题..." confirm-type="{{'send'}}" bindfocus="{{j}}" bindblur="{{k}}" bindconfirm="{{l}}" value="{{m}}" bindinput="{{n}}"/><view wx:if="{{o}}" class="upload-button" bindtap="{{q}}"><uni-icons wx:if="{{p}}" u-i="25c36616-2" bind:__l="__l" u-p="{{p}}"/></view><view wx:if="{{r}}" class="send-button" bindtap="{{t}}"><uni-icons wx:if="{{s}}" u-i="25c36616-3" bind:__l="__l" u-p="{{s}}"/></view><view wx:if="{{v}}" class="send-button disabled"><uni-icons wx:if="{{w}}" u-i="25c36616-4" bind:__l="__l" u-p="{{w}}"/></view></view></view></view></view>
|
||||
<view class="chat-container"><view class="chat_container_linear_gradient"></view><view wx:if="{{a}}" class="chat_messages_body"><my-header-prologue bindhandleQuickFast="{{b}}" u-i="25c36616-0" bind:__l="__l"/><view class="chat-messages chat-messages-chat"><view wx:for="{{c}}" wx:for-item="message" wx:key="F" id="{{message.G}}" class="{{['message-item', message.H]}}"><view wx:if="{{message.a}}" class="message-avatar"><image src="https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN43RH4M09FAFBD8D9TQPM2B.png" mode="aspectFit"/></view><view class="message-content-wrapper"><view class="message-content"><view wx:if="{{message.b}}" class="message-images"><view wx:for="{{message.c}}" wx:for-item="image" wx:key="c" class="{{['message-image-item', message.e && 'single-image']}}"><image src="{{image.a}}" mode="{{message.d}}" class="message-image" bindtap="{{image.b}}"/></view></view><view wx:elif="{{message.f}}" class="message-images"><view wx:for="{{message.g}}" wx:for-item="image" wx:key="c" class="{{['message-image-item', message.i && 'single-image']}}"><image src="{{image.a}}" mode="{{message.h}}" class="message-image" bindtap="{{image.b}}"/></view></view><view wx:elif="{{message.j}}" class="message-images"><view wx:for="{{message.k}}" wx:for-item="image" wx:key="c" class="{{['message-image-item', message.m && 'single-image']}}"><image src="{{image.a}}" mode="{{message.l}}" class="message-image" bindtap="{{image.b}}"/></view></view><block wx:if="{{message.n}}"><view wx:for="{{message.o}}" wx:for-item="line" wx:key="b" class="message-text-line"><text>{{line.a}}</text></view></block></view><view wx:if="{{message.p}}" class="quick-questions"><view wx:for="{{message.q}}" wx:for-item="question" wx:key="b" class="question-btn" bindtap="{{question.c}}"><text>{{question.a}}</text></view></view><view wx:if="{{message.r}}" class="confirmation-buttons"><view class="{{['confirmation-btn', message.s && 'selected', message.t && 'disabled']}}" bindtap="{{message.v}}"><text>是</text></view><view class="{{['confirmation-btn', message.w && 'selected', message.x && 'disabled']}}" bindtap="{{message.y}}"><text>否</text></view></view><view wx:if="{{message.z}}" class="message-meta"><view wx:if="{{message.A}}" class="copy-button" bindtap="{{message.B}}"><image src="/static/svg/copy.svg" mode="aspectFit" class="copy-icon"/></view><text class="message-time">{{message.C}}</text><view wx:if="{{message.D}}" class="copy-button" bindtap="{{message.E}}"><image src="/static/svg/copy.svg" mode="aspectFit" class="copy-icon"/></view></view></view></view><view wx:if="{{d}}" class="message-item ai-message"><view class="message-avatar"><image src="https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN43RH4M09FAFBD8D9TQPM2B.png" mode="aspectFit"/></view><view class="message-content loading"><text>{{e}}</text></view></view></view><view class="chat-input-area chat-input-area-chat"><view wx:if="{{f}}" class="image-preview-area"><view class="image-preview-list"><view wx:for="{{g}}" wx:for-item="image" wx:key="d" class="image-preview-item"><image src="{{image.a}}" mode="aspectFill" class="preview-image"/><view class="remove-image" bindtap="{{image.c}}"><uni-icons wx:if="{{h}}" u-i="{{image.b}}" bind:__l="__l" u-p="{{h}}"/></view></view><view wx:if="{{i}}" class="image-preview-item add-more-button" bindtap="{{k}}"><uni-icons wx:if="{{j}}" u-i="25c36616-2" bind:__l="__l" u-p="{{j}}"/><text class="add-more-text">添加图片</text></view></view></view><view class="input-container"><input class="message-input" placeholder="请输入您的问题..." adjust-position confirm-type="{{'send'}}" cursor-spacing="{{15}}" bindfocus="{{l}}" bindblur="{{m}}" bindconfirm="{{n}}" value="{{o}}" bindinput="{{p}}"/><view wx:if="{{q}}" class="upload-button" bindtap="{{s}}"><uni-icons wx:if="{{r}}" u-i="25c36616-3" bind:__l="__l" u-p="{{r}}"/></view><view wx:if="{{t}}" class="send-button" bindtap="{{w}}"><uni-icons wx:if="{{v}}" u-i="25c36616-4" bind:__l="__l" u-p="{{v}}"/></view><view wx:if="{{x}}" class="send-button disabled"><uni-icons wx:if="{{y}}" u-i="25c36616-5" bind:__l="__l" u-p="{{y}}"/></view></view></view></view><view wx:else class="chat_messages_body"><hs-empty wx:if="{{z}}" u-i="25c36616-6" bind:__l="__l" u-p="{{z}}"/><view class="login_btn"><hs-button wx:if="{{B}}" bindclick="{{A}}" u-i="25c36616-7" bind:__l="__l" u-p="{{B}}"/></view></view></view>
|
||||
2
dist/build/mp-weixin/pages/ai/chat.wxss
vendored
2
dist/build/mp-weixin/pages/ai/chat.wxss
vendored
File diff suppressed because one or more lines are too long
1
dist/build/mp-weixin/static/svg/ai_icon.svg
vendored
1
dist/build/mp-weixin/static/svg/ai_icon.svg
vendored
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 692 KiB |
358
dist/dev/mp-weixin/pages/ai/chat.js
vendored
358
dist/dev/mp-weixin/pages/ai/chat.js
vendored
@ -3,11 +3,13 @@ const common_vendor = require("../../common/vendor.js");
|
||||
require("../../common/libraries/request.js");
|
||||
const common_store_useWeAppAuthStore = require("../../common/store/useWeAppAuthStore.js");
|
||||
require("../../common/store/useWorkStore.js");
|
||||
const common_libraries_upload = require("../../common/libraries/upload.js");
|
||||
const pages_ai_method = require("./method.js");
|
||||
const pages_ai_model = require("./model.js");
|
||||
const common_libraries_userUserLogin = require("../../common/libraries/userUserLogin.js");
|
||||
require("../../gen/Apis.js");
|
||||
require("../../common/libraries/setTabBar.js");
|
||||
require("../../common/libraries/apiLoading.js");
|
||||
require("../../common/libraries/upload.js");
|
||||
if (!Array) {
|
||||
const _easycom_uni_icons2 = common_vendor.resolveComponent("uni-icons");
|
||||
const _easycom_hs_empty2 = common_vendor.resolveComponent("hs-empty");
|
||||
@ -18,8 +20,9 @@ const _easycom_uni_icons = () => "../../uni_modules/uni-icons/components/uni-ico
|
||||
const _easycom_hs_empty = () => "../../components/hs-empty/hs-empty.js";
|
||||
const _easycom_hs_button = () => "../../components/hs-button/hs-button.js";
|
||||
if (!Math) {
|
||||
(_easycom_uni_icons + _easycom_hs_empty + _easycom_hs_button)();
|
||||
(MyHeaderPrologue + _easycom_uni_icons + _easycom_hs_empty + _easycom_hs_button)();
|
||||
}
|
||||
const MyHeaderPrologue = () => "./components/HeaderPrologue.js";
|
||||
const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
__name: "chat",
|
||||
setup(__props) {
|
||||
@ -28,15 +31,12 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
const auth = common_store_useWeAppAuthStore.useWeAppAuthStore();
|
||||
const userLoginStatus = common_vendor.ref(false);
|
||||
const inputMessage = common_vendor.ref("");
|
||||
const selectedImages = common_vendor.ref([]);
|
||||
const isInputFocused = common_vendor.ref(false);
|
||||
const messages = common_vendor.ref([]);
|
||||
const loading = common_vendor.ref(false);
|
||||
const loadingText = common_vendor.ref("正在输入中...");
|
||||
let socketTask = null;
|
||||
let isConnected = common_vendor.ref(false);
|
||||
const API_BASE_URL = "https://kf-api-test.linyikj.com.cn";
|
||||
const WS_BASE_URL = "wss://kf-api-test.linyikj.com.cn";
|
||||
const currentPage = common_vendor.ref(1);
|
||||
const pageSize = common_vendor.ref(10);
|
||||
const hasMore = common_vendor.ref(true);
|
||||
@ -45,82 +45,11 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
const currentOffset = common_vendor.ref(0);
|
||||
const quickQuestionsData = common_vendor.ref({});
|
||||
const lastMessageContent = common_vendor.ref("");
|
||||
const getQuickQuestions = async () => {
|
||||
var _a;
|
||||
try {
|
||||
let selected_house = (_a = auth == null ? void 0 : auth.data) == null ? void 0 : _a.selected_house;
|
||||
const response = await common_vendor.index.request({
|
||||
url: `${API_BASE_URL}/api/public/quick-questions?platform=property&company_id=${selected_house == null ? void 0 : selected_house.companies_id}&project_id=${selected_house == null ? void 0 : selected_house.asset_projects_id}`,
|
||||
method: "GET"
|
||||
});
|
||||
if (response.statusCode === 200) {
|
||||
const result = response.data;
|
||||
console.log("获取到开场白按钮数据2:", result);
|
||||
return result;
|
||||
} else {
|
||||
console.error("获取开场白数据失败,状态码:", response.statusCode);
|
||||
return [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取开场白数据异常:", error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
const goToPageLogin = () => {
|
||||
common_vendor.index.navigateTo({
|
||||
url: "/pages/login"
|
||||
});
|
||||
};
|
||||
const formatMessageContent = (content) => {
|
||||
if (!content || typeof content !== "string") {
|
||||
return [""];
|
||||
}
|
||||
return content.split("\n").filter((line) => line.trim() !== "");
|
||||
};
|
||||
const previewImage = (currentImage, images) => {
|
||||
common_vendor.index.previewImage({
|
||||
current: currentImage,
|
||||
urls: images
|
||||
});
|
||||
};
|
||||
const copyMessage = (content) => {
|
||||
if (!content) {
|
||||
common_vendor.index.showToast({
|
||||
title: "暂无内容可复制",
|
||||
icon: "none"
|
||||
});
|
||||
return;
|
||||
}
|
||||
common_vendor.index.setClipboardData({
|
||||
data: content,
|
||||
success: () => {
|
||||
common_vendor.index.showToast({
|
||||
title: "复制成功",
|
||||
icon: "success"
|
||||
});
|
||||
},
|
||||
fail: () => {
|
||||
common_vendor.index.showToast({
|
||||
title: "复制失败",
|
||||
icon: "none"
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
const formatTime = (timeStr) => {
|
||||
if (!timeStr)
|
||||
return "";
|
||||
try {
|
||||
const date = common_vendor.dayjs(timeStr);
|
||||
if (!date.isValid()) {
|
||||
return "";
|
||||
}
|
||||
return date.fromNow();
|
||||
} catch (e) {
|
||||
console.error("时间格式化错误:", e);
|
||||
return "";
|
||||
}
|
||||
};
|
||||
const scrollToBottom = () => {
|
||||
common_vendor.nextTick$1(() => {
|
||||
common_vendor.index.pageScrollTo({
|
||||
@ -130,7 +59,7 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
});
|
||||
};
|
||||
const getHistoryMessages = async (page = 1) => {
|
||||
var _a, _b;
|
||||
var _a, _b, _c;
|
||||
const userPhone = (_b = (_a = auth.data) == null ? void 0 : _a.user) == null ? void 0 : _b.phone;
|
||||
if (!userPhone) {
|
||||
console.log("用户未登录,无法获取历史记录");
|
||||
@ -143,18 +72,13 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
isLoadingHistory.value = true;
|
||||
const offset = (page - 1) * pageSize.value;
|
||||
currentOffset.value = offset;
|
||||
console.log("分页信息 - 页码:", page, "每页数量:", pageSize.value, "计算出的offset:", offset);
|
||||
const response = await common_vendor.index.request({
|
||||
url: `${API_BASE_URL}/api/public/customer/init`,
|
||||
method: "POST",
|
||||
data: {
|
||||
platform: "property",
|
||||
platform_user_id: userPhone,
|
||||
//userPhone
|
||||
limit: pageSize.value,
|
||||
offset
|
||||
}
|
||||
});
|
||||
const response = await ((_c = pages_ai_method.method) == null ? void 0 : _c.customRequest("public/customer/init", {
|
||||
platform: "property",
|
||||
platform_user_id: userPhone,
|
||||
//userPhone
|
||||
limit: pageSize.value,
|
||||
offset
|
||||
}));
|
||||
if (response.statusCode === 200) {
|
||||
const result = response.data;
|
||||
let historyMessages = [];
|
||||
@ -278,26 +202,6 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
const totalItems = result.total || result.count || result.total_count || 0;
|
||||
hasMore.value = totalItems > messages.value.length;
|
||||
currentPage.value = page;
|
||||
if (page > 1 && !hasMore.value) {
|
||||
console.log("分页加载完成,当前页:", page, "hasMore:", hasMore.value, "展示开场白");
|
||||
setTimeout(() => {
|
||||
addQuickQuestionsToFirstAIMessage(true);
|
||||
}, 500);
|
||||
}
|
||||
console.log(
|
||||
"第",
|
||||
page,
|
||||
"页数据加载完成,offset:",
|
||||
offset,
|
||||
", limit:",
|
||||
pageSize.value,
|
||||
", 总数据:",
|
||||
totalItems,
|
||||
", 当前已加载:",
|
||||
messages.value.length,
|
||||
", 是否有更多:",
|
||||
hasMore.value
|
||||
);
|
||||
if (page === 1) {
|
||||
setTimeout(() => {
|
||||
scrollToBottom();
|
||||
@ -332,13 +236,12 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
}
|
||||
});
|
||||
const initWebSocket = () => {
|
||||
var _a;
|
||||
if (socketTask) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const wsUrl = `${WS_BASE_URL}/ws/socket.io/?EIO=4&transport=websocket`;
|
||||
console.log("正在建立Socket.IO连接");
|
||||
console.log("连接URL:", wsUrl);
|
||||
const wsUrl = `${(_a = pages_ai_model.useModel) == null ? void 0 : _a.WS_BASE_URL}/ws/socket.io/?EIO=4&transport=websocket`;
|
||||
socketTask = common_vendor.index.connectSocket({
|
||||
url: wsUrl,
|
||||
header: {
|
||||
@ -346,13 +249,11 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
}
|
||||
});
|
||||
common_vendor.index.onSocketOpen((res) => {
|
||||
console.log("[Customer] WebSocket connected", res);
|
||||
isConnected.value = true;
|
||||
const connectPacket = '40/customer,{"jwt":""}';
|
||||
common_vendor.index.sendSocketMessage({
|
||||
data: connectPacket,
|
||||
success: () => {
|
||||
console.log("[Customer] Socket.IO连接包发送成功");
|
||||
if (conversationId.value) {
|
||||
setTimeout(() => {
|
||||
const joinMessage = `42/customer,["join_conversation",{"conversation_id":"${conversationId.value}"}]`;
|
||||
@ -385,9 +286,6 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
socketTask = null;
|
||||
});
|
||||
common_vendor.index.onSocketMessage((res) => {
|
||||
console.log("收到WebSocket原始消息:", res);
|
||||
console.log("消息数据类型:", typeof res.data);
|
||||
console.log("消息内容:", res.data);
|
||||
const data = res.data;
|
||||
if (typeof data === "string") {
|
||||
if (data.startsWith("42/customer,")) {
|
||||
@ -470,7 +368,6 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
}
|
||||
};
|
||||
const processTypingIndicator = (typingData) => {
|
||||
console.log("[Customer] 处理typing指示器:", typingData);
|
||||
if (typingData.is_typing && typingData.user_type === "staff") {
|
||||
loading.value = true;
|
||||
loadingText.value = "客服正在输入...";
|
||||
@ -478,35 +375,8 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
const checkShouldShowQuickQuestions = (isLastPage = false) => {
|
||||
return quickQuestionsData.value.length > 0;
|
||||
};
|
||||
const addQuickQuestionsToFirstAIMessage = (isLastPage = false) => {
|
||||
if (quickQuestionsData.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (!checkShouldShowQuickQuestions(isLastPage)) {
|
||||
return;
|
||||
}
|
||||
const welcomeMessage = {
|
||||
role: "ai",
|
||||
content: "您好!我是物业客服,有什么可以帮助您的吗?",
|
||||
quickQuestions: quickQuestionsData.value,
|
||||
created_at: new Date().toISOString()
|
||||
};
|
||||
console.log("[Customer] 创建开场白消息,是否最后一页:", isLastPage);
|
||||
if (messages.value.length === 0) {
|
||||
messages.value = [welcomeMessage];
|
||||
console.log("[Customer] 设置开场白为第一条消息");
|
||||
} else {
|
||||
messages.value.unshift(welcomeMessage);
|
||||
console.log("[Customer] 在第一条消息前面插入开场白");
|
||||
}
|
||||
};
|
||||
const processMessage = (messageData) => {
|
||||
console.log("[Customer] 处理消息数据:", messageData);
|
||||
if (messageData.sender_type === "customer" || messageData.role === "user") {
|
||||
console.log("[Customer] 过滤掉客户消息");
|
||||
return;
|
||||
}
|
||||
let messageContent = "";
|
||||
@ -565,46 +435,15 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
handleSendMessage();
|
||||
}, 300);
|
||||
};
|
||||
const chooseImage = async () => {
|
||||
const maxImages = 9;
|
||||
if (selectedImages.value.length >= maxImages) {
|
||||
common_vendor.index.showToast({
|
||||
title: "最多选择9张图片",
|
||||
icon: "none"
|
||||
});
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const remainingCount = maxImages - selectedImages.value.length;
|
||||
const uploadResult = await common_libraries_upload.upload(remainingCount, 2, ["image"]);
|
||||
if (uploadResult && Array.isArray(uploadResult) && uploadResult.length > 0) {
|
||||
const imageUrls = uploadResult.map((item) => item.url);
|
||||
selectedImages.value.push(...imageUrls);
|
||||
common_vendor.index.showToast({
|
||||
title: "图片上传成功",
|
||||
icon: "success"
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("选择图片失败:", error);
|
||||
common_vendor.index.showToast({
|
||||
title: "选择图片失败",
|
||||
icon: "none"
|
||||
});
|
||||
}
|
||||
};
|
||||
const removeImage = (index) => {
|
||||
selectedImages.value.splice(index, 1);
|
||||
};
|
||||
const handleSendMessage = async () => {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
||||
const message = inputMessage.value.trim();
|
||||
const hasImages = selectedImages.value.length > 0;
|
||||
const hasImages = ((_c = (_b = (_a = pages_ai_model.useModel) == null ? void 0 : _a.selectedImages) == null ? void 0 : _b.value) == null ? void 0 : _c.length) > 0;
|
||||
if (!message && !hasImages || loading.value)
|
||||
return;
|
||||
const userPhone = (_b = (_a = auth.data) == null ? void 0 : _a.user) == null ? void 0 : _b.phone;
|
||||
const projectId = (_d = (_c = auth.data) == null ? void 0 : _c.selected_house) == null ? void 0 : _d.asset_projects_id;
|
||||
const projectName = (_f = (_e = auth.data) == null ? void 0 : _e.selected_house) == null ? void 0 : _f.full_name;
|
||||
const userPhone = (_e = (_d = auth.data) == null ? void 0 : _d.user) == null ? void 0 : _e.phone;
|
||||
const projectId = (_g = (_f = auth.data) == null ? void 0 : _f.selected_house) == null ? void 0 : _g.asset_projects_id;
|
||||
const projectName = (_i = (_h = auth.data) == null ? void 0 : _h.selected_house) == null ? void 0 : _i.full_name;
|
||||
if (!userPhone || !projectId) {
|
||||
common_vendor.index.showToast({
|
||||
title: "请先登录并绑定房屋",
|
||||
@ -616,7 +455,7 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
initWebSocket();
|
||||
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
||||
}
|
||||
const uploadedImages = selectedImages.value;
|
||||
const uploadedImages = ((_k = (_j = pages_ai_model.useModel) == null ? void 0 : _j.selectedImages) == null ? void 0 : _k.value) || [];
|
||||
let messageType = "text";
|
||||
if (hasImages && message) {
|
||||
messageType = "mixed";
|
||||
@ -634,7 +473,7 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
};
|
||||
messages.value.push(userMessage);
|
||||
inputMessage.value = "";
|
||||
selectedImages.value = [];
|
||||
pages_ai_model.useModel.selectedImages.value = [];
|
||||
scrollToBottom();
|
||||
if (message && message.includes("查询")) {
|
||||
loadingText.value = "正在查询中请稍后...";
|
||||
@ -643,24 +482,16 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
}
|
||||
loading.value = true;
|
||||
try {
|
||||
const response = await common_vendor.index.request({
|
||||
url: `${API_BASE_URL}/api/public/chat`,
|
||||
method: "POST",
|
||||
data: {
|
||||
platform: "property",
|
||||
message: message || "",
|
||||
// 纯图片时传空字符串
|
||||
tenant_project_id: projectId,
|
||||
tenant_project_name: projectName || "",
|
||||
platform_user_id: userPhone,
|
||||
conversation_id: conversationId.value,
|
||||
message_type: messageType,
|
||||
image_url: uploadedImages.length > 0 ? uploadedImages : void 0
|
||||
},
|
||||
header: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
const response = await ((_l = pages_ai_method.method) == null ? void 0 : _l.customRequest("public/chat", {
|
||||
platform: "property",
|
||||
message: message || "",
|
||||
// 纯图片时传空字符串
|
||||
tenant_project_id: projectId,
|
||||
message_type: messageType,
|
||||
tenant_project_name: projectName || "",
|
||||
conversation_id: conversationId.value,
|
||||
image_url: uploadedImages.length > 0 ? uploadedImages : void 0
|
||||
}));
|
||||
if (response.statusCode === 200) {
|
||||
const result = response.data;
|
||||
console.log("[Customer] HTTP接口响应数据:", result);
|
||||
@ -755,17 +586,10 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
});
|
||||
common_vendor.onLoad(async (op) => {
|
||||
var _a, _b, _c;
|
||||
console.log(
|
||||
"页面加载时已获取开场白按钮数据1:",
|
||||
quickQuestionsData.value.length,
|
||||
(_a = common_libraries_userUserLogin.getUserLogin) == null ? void 0 : _a.getLoginStatus()
|
||||
);
|
||||
await ((_b = common_vendor.getCurrentInstance()) == null ? void 0 : _b.appContext.config.globalProperties.$onLaunched);
|
||||
if ((_c = common_libraries_userUserLogin.getUserLogin) == null ? void 0 : _c.getLoginStatus()) {
|
||||
await ((_a = common_vendor.getCurrentInstance()) == null ? void 0 : _a.appContext.config.globalProperties.$onLaunched);
|
||||
if ((_b = common_libraries_userUserLogin.getUserLogin) == null ? void 0 : _b.getLoginStatus()) {
|
||||
userLoginStatus.value = true;
|
||||
console.log("页面加载时已获取开场白按钮数据3:", quickQuestionsData.value.length);
|
||||
quickQuestionsData.value = await getQuickQuestions();
|
||||
console.log("页面加载时已获取开场白按钮数据2:", quickQuestionsData.value.length);
|
||||
quickQuestionsData.value = await ((_c = pages_ai_method.method) == null ? void 0 : _c.getQuickQuestions());
|
||||
getHistoryMessages(1);
|
||||
if (op == null ? void 0 : op.message) {
|
||||
handleQuickAction(op);
|
||||
@ -776,19 +600,13 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
}
|
||||
});
|
||||
return (_ctx, _cache) => {
|
||||
var _a, _b;
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
|
||||
return common_vendor.e({
|
||||
a: userLoginStatus.value
|
||||
}, userLoginStatus.value ? common_vendor.e({
|
||||
b: common_vendor.t(((_a = quickQuestionsData.value) == null ? void 0 : _a.greeting_text) || "我是管家-邻邻,有什么可以帮助您的吗?"),
|
||||
c: common_vendor.f((_b = quickQuestionsData.value) == null ? void 0 : _b.questions, (i, index, i0) => {
|
||||
return {
|
||||
a: common_vendor.t(i),
|
||||
b: `item_${index}`,
|
||||
c: common_vendor.o(($event) => handleQuickFast(i), `item_${index}`)
|
||||
};
|
||||
}),
|
||||
d: common_vendor.f(messages.value, (message, index, i0) => {
|
||||
b: common_vendor.o(handleQuickFast),
|
||||
c: common_vendor.f(messages.value, (message, index, i0) => {
|
||||
var _a2, _b2;
|
||||
return common_vendor.e({
|
||||
a: message.role === "ai"
|
||||
}, message.role === "ai" ? {} : {}, {
|
||||
@ -797,7 +615,10 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
c: common_vendor.f(message.image_url, (image, imgIndex, i1) => {
|
||||
return {
|
||||
a: image,
|
||||
b: common_vendor.o(($event) => previewImage(image, message.image_url), imgIndex),
|
||||
b: common_vendor.o(($event) => {
|
||||
var _a3;
|
||||
return (_a3 = common_vendor.unref(pages_ai_method.method)) == null ? void 0 : _a3.previewImage(image, message.image_url);
|
||||
}, imgIndex),
|
||||
c: imgIndex
|
||||
};
|
||||
}),
|
||||
@ -807,7 +628,10 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
g: common_vendor.f(message.images, (image, imgIndex, i1) => {
|
||||
return {
|
||||
a: image,
|
||||
b: common_vendor.o(($event) => previewImage(image, message.images), imgIndex),
|
||||
b: common_vendor.o(($event) => {
|
||||
var _a3;
|
||||
return (_a3 = common_vendor.unref(pages_ai_method.method)) == null ? void 0 : _a3.previewImage(image, message.images);
|
||||
}, imgIndex),
|
||||
c: imgIndex
|
||||
};
|
||||
}),
|
||||
@ -817,7 +641,10 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
k: common_vendor.f(message.metadata.image_url, (image, imgIndex, i1) => {
|
||||
return {
|
||||
a: image,
|
||||
b: common_vendor.o(($event) => previewImage(image, message.metadata.image_url), imgIndex),
|
||||
b: common_vendor.o(($event) => {
|
||||
var _a3;
|
||||
return (_a3 = common_vendor.unref(pages_ai_method.method)) == null ? void 0 : _a3.previewImage(image, message.metadata.image_url);
|
||||
}, imgIndex),
|
||||
c: imgIndex
|
||||
};
|
||||
}),
|
||||
@ -828,7 +655,7 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
j: message.metadata && message.metadata.image_url && message.metadata.image_url.length > 0,
|
||||
n: message.content && message.content.trim()
|
||||
}, message.content && message.content.trim() ? {
|
||||
o: common_vendor.f(formatMessageContent(message.content), (line, lineIndex, i1) => {
|
||||
o: common_vendor.f((_a2 = common_vendor.unref(pages_ai_method.method)) == null ? void 0 : _a2.formatMessageContent(message.content), (line, lineIndex, i1) => {
|
||||
return {
|
||||
a: common_vendor.t(line),
|
||||
b: "text-" + lineIndex
|
||||
@ -858,86 +685,101 @@ const _sfc_defineComponent = /* @__PURE__ */ common_vendor.defineComponent({
|
||||
}, message.created_at && !message.quickQuestions ? common_vendor.e({
|
||||
A: message.role === "ai"
|
||||
}, message.role === "ai" ? {
|
||||
B: common_vendor.o(($event) => copyMessage(message.content), index)
|
||||
B: common_vendor.o(($event) => {
|
||||
var _a3;
|
||||
return (_a3 = common_vendor.unref(pages_ai_method.method)) == null ? void 0 : _a3.copyMessage(message.content);
|
||||
}, index)
|
||||
} : {}, {
|
||||
C: common_vendor.t(formatTime(message.created_at)),
|
||||
C: common_vendor.t((_b2 = common_vendor.unref(pages_ai_method.method)) == null ? void 0 : _b2.formatTime(message.created_at)),
|
||||
D: message.role === "user"
|
||||
}, message.role === "user" ? {
|
||||
E: common_vendor.o(($event) => copyMessage(message.content), index)
|
||||
E: common_vendor.o(($event) => {
|
||||
var _a3;
|
||||
return (_a3 = common_vendor.unref(pages_ai_method.method)) == null ? void 0 : _a3.copyMessage(message.content);
|
||||
}, index)
|
||||
} : {}) : {}, {
|
||||
F: index,
|
||||
G: `msg-${index}`,
|
||||
H: common_vendor.n(message.role === "user" ? "user-message" : "ai-message")
|
||||
});
|
||||
}),
|
||||
e: loading.value
|
||||
d: loading.value
|
||||
}, loading.value ? {
|
||||
f: common_vendor.t(loadingText.value)
|
||||
e: common_vendor.t(loadingText.value)
|
||||
} : {}, {
|
||||
g: selectedImages.value.length > 0
|
||||
}, selectedImages.value.length > 0 ? common_vendor.e({
|
||||
h: common_vendor.f(selectedImages.value, (image, index, i0) => {
|
||||
f: ((_c = (_b = (_a = common_vendor.unref(pages_ai_model.useModel)) == null ? void 0 : _a.selectedImages) == null ? void 0 : _b.value) == null ? void 0 : _c.length) > 0
|
||||
}, ((_f = (_e = (_d = common_vendor.unref(pages_ai_model.useModel)) == null ? void 0 : _d.selectedImages) == null ? void 0 : _e.value) == null ? void 0 : _f.length) > 0 ? common_vendor.e({
|
||||
g: common_vendor.f((_h = (_g = common_vendor.unref(pages_ai_model.useModel)) == null ? void 0 : _g.selectedImages) == null ? void 0 : _h.value, (image, index, i0) => {
|
||||
return {
|
||||
a: image,
|
||||
b: "25c36616-0-" + i0,
|
||||
c: common_vendor.o(($event) => removeImage(index), index),
|
||||
b: "25c36616-1-" + i0,
|
||||
c: common_vendor.o(($event) => {
|
||||
var _a2;
|
||||
return (_a2 = common_vendor.unref(pages_ai_method.method)) == null ? void 0 : _a2.removeImage(index);
|
||||
}, index),
|
||||
d: index
|
||||
};
|
||||
}),
|
||||
i: common_vendor.p({
|
||||
h: common_vendor.p({
|
||||
type: "closeempty",
|
||||
size: "14",
|
||||
color: "#fff"
|
||||
}),
|
||||
j: selectedImages.value.length < 9
|
||||
}, selectedImages.value.length < 9 ? {
|
||||
k: common_vendor.p({
|
||||
i: ((_k = (_j = (_i = common_vendor.unref(pages_ai_model.useModel)) == null ? void 0 : _i.selectedImages) == null ? void 0 : _j.value) == null ? void 0 : _k.length) < 9
|
||||
}, ((_n = (_m = (_l = common_vendor.unref(pages_ai_model.useModel)) == null ? void 0 : _l.selectedImages) == null ? void 0 : _m.value) == null ? void 0 : _n.length) < 9 ? {
|
||||
j: common_vendor.p({
|
||||
type: "plus",
|
||||
size: "30",
|
||||
color: "#999"
|
||||
}),
|
||||
l: common_vendor.o(chooseImage)
|
||||
k: common_vendor.o(($event) => {
|
||||
var _a2;
|
||||
return (_a2 = common_vendor.unref(pages_ai_method.method)) == null ? void 0 : _a2.chooseImage();
|
||||
})
|
||||
} : {}) : {}, {
|
||||
m: common_vendor.o(($event) => isInputFocused.value = true),
|
||||
n: common_vendor.o(($event) => isInputFocused.value = false),
|
||||
o: common_vendor.o(handleSendMessage),
|
||||
p: inputMessage.value,
|
||||
q: common_vendor.o(($event) => inputMessage.value = $event.detail.value),
|
||||
r: !inputMessage.value.trim() && !isInputFocused.value && selectedImages.value.length === 0
|
||||
}, !inputMessage.value.trim() && !isInputFocused.value && selectedImages.value.length === 0 ? {
|
||||
s: common_vendor.p({
|
||||
l: common_vendor.o(($event) => isInputFocused.value = true),
|
||||
m: common_vendor.o(($event) => isInputFocused.value = false),
|
||||
n: common_vendor.o(handleSendMessage),
|
||||
o: inputMessage.value,
|
||||
p: common_vendor.o(($event) => inputMessage.value = $event.detail.value),
|
||||
q: !inputMessage.value.trim() && !isInputFocused.value && ((_q = (_p = (_o = common_vendor.unref(pages_ai_model.useModel)) == null ? void 0 : _o.selectedImages) == null ? void 0 : _p.value) == null ? void 0 : _q.length) === 0
|
||||
}, !inputMessage.value.trim() && !isInputFocused.value && ((_t = (_s = (_r = common_vendor.unref(pages_ai_model.useModel)) == null ? void 0 : _r.selectedImages) == null ? void 0 : _s.value) == null ? void 0 : _t.length) === 0 ? {
|
||||
r: common_vendor.p({
|
||||
type: "camera",
|
||||
size: "24",
|
||||
color: "#666"
|
||||
}),
|
||||
t: common_vendor.o(chooseImage)
|
||||
s: common_vendor.o(($event) => {
|
||||
var _a2;
|
||||
return (_a2 = common_vendor.unref(pages_ai_method.method)) == null ? void 0 : _a2.chooseImage();
|
||||
})
|
||||
} : {}, {
|
||||
v: (inputMessage.value.trim() || isInputFocused.value || selectedImages.value.length > 0) && !loading.value
|
||||
}, (inputMessage.value.trim() || isInputFocused.value || selectedImages.value.length > 0) && !loading.value ? {
|
||||
w: common_vendor.p({
|
||||
t: (inputMessage.value.trim() || isInputFocused.value || ((_w = (_v = (_u = common_vendor.unref(pages_ai_model.useModel)) == null ? void 0 : _u.selectedImages) == null ? void 0 : _v.value) == null ? void 0 : _w.length) > 0) && !loading.value
|
||||
}, (inputMessage.value.trim() || isInputFocused.value || ((_z = (_y = (_x = common_vendor.unref(pages_ai_model.useModel)) == null ? void 0 : _x.selectedImages) == null ? void 0 : _y.value) == null ? void 0 : _z.length) > 0) && !loading.value ? {
|
||||
v: common_vendor.p({
|
||||
type: "paperplane-filled",
|
||||
size: "20",
|
||||
color: "#fff"
|
||||
}),
|
||||
x: common_vendor.o(handleSendMessage)
|
||||
w: common_vendor.o(handleSendMessage)
|
||||
} : {}, {
|
||||
y: loading.value
|
||||
x: loading.value
|
||||
}, loading.value ? {
|
||||
z: common_vendor.p({
|
||||
y: common_vendor.p({
|
||||
type: "spinner-cycle",
|
||||
size: "20",
|
||||
color: "#ccc"
|
||||
})
|
||||
} : {}) : {
|
||||
A: common_vendor.p({
|
||||
z: common_vendor.p({
|
||||
height: "20vh",
|
||||
baseStyle: {
|
||||
paddingTop: "35%"
|
||||
},
|
||||
text: "登录体验更多功能"
|
||||
}),
|
||||
B: common_vendor.o(goToPageLogin),
|
||||
C: common_vendor.p({
|
||||
A: common_vendor.o(goToPageLogin),
|
||||
B: common_vendor.p({
|
||||
label: "去登录",
|
||||
size: "md",
|
||||
type: "primary"
|
||||
|
||||
3
dist/dev/mp-weixin/pages/ai/chat.json
vendored
3
dist/dev/mp-weixin/pages/ai/chat.json
vendored
@ -4,6 +4,7 @@
|
||||
"usingComponents": {
|
||||
"uni-icons": "../../uni_modules/uni-icons/components/uni-icons/uni-icons",
|
||||
"hs-empty": "../../components/hs-empty/hs-empty",
|
||||
"hs-button": "../../components/hs-button/hs-button"
|
||||
"hs-button": "../../components/hs-button/hs-button",
|
||||
"my-header-prologue": "./components/HeaderPrologue"
|
||||
}
|
||||
}
|
||||
2
dist/dev/mp-weixin/pages/ai/chat.wxml
vendored
2
dist/dev/mp-weixin/pages/ai/chat.wxml
vendored
@ -1 +1 @@
|
||||
<view class="chat-container"><view class="chat_container_linear_gradient"></view><view wx:if="{{a}}" class="chat_messages_body"><view class="opening_remarks"><view class="opening_remarks_body"><view class="opening_remarks_server_img"><image src="https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN5XRPWKSMDDHRJTY4F2TG1G.png" mode="heightFix"/></view><view class="opening_remarks_server_info"><view class="label">{{b}}</view><view class="group_btn"><view wx:for="{{c}}" wx:for-item="i" wx:key="b" class="group_btn_item" bindtap="{{i.c}}">{{i.a}}</view></view></view></view></view><view class="chat-messages chat-messages-chat"><view wx:for="{{d}}" wx:for-item="message" wx:key="F" id="{{message.G}}" class="{{['message-item', message.H]}}"><view wx:if="{{message.a}}" class="message-avatar"><image src="https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN43RH4M09FAFBD8D9TQPM2B.png" mode="aspectFit"/></view><view class="message-content-wrapper"><view class="message-content"><view wx:if="{{message.b}}" class="message-images"><view wx:for="{{message.c}}" wx:for-item="image" wx:key="c" class="{{['message-image-item', message.e && 'single-image']}}"><image src="{{image.a}}" mode="{{message.d}}" class="message-image" bindtap="{{image.b}}"/></view></view><view wx:elif="{{message.f}}" class="message-images"><view wx:for="{{message.g}}" wx:for-item="image" wx:key="c" class="{{['message-image-item', message.i && 'single-image']}}"><image src="{{image.a}}" mode="{{message.h}}" class="message-image" bindtap="{{image.b}}"/></view></view><view wx:elif="{{message.j}}" class="message-images"><view wx:for="{{message.k}}" wx:for-item="image" wx:key="c" class="{{['message-image-item', message.m && 'single-image']}}"><image src="{{image.a}}" mode="{{message.l}}" class="message-image" bindtap="{{image.b}}"/></view></view><block wx:if="{{message.n}}"><view wx:for="{{message.o}}" wx:for-item="line" wx:key="b" class="message-text-line"><text>{{line.a}}</text></view></block></view><view wx:if="{{message.p}}" class="quick-questions"><view wx:for="{{message.q}}" wx:for-item="question" wx:key="b" class="question-btn" bindtap="{{question.c}}"><text>{{question.a}}</text></view></view><view wx:if="{{message.r}}" class="confirmation-buttons"><view class="{{['confirmation-btn', message.s && 'selected', message.t && 'disabled']}}" bindtap="{{message.v}}"><text>是</text></view><view class="{{['confirmation-btn', message.w && 'selected', message.x && 'disabled']}}" bindtap="{{message.y}}"><text>否</text></view></view><view wx:if="{{message.z}}" class="message-meta"><view wx:if="{{message.A}}" class="copy-button" bindtap="{{message.B}}"><image src="/static/svg/copy.svg" mode="aspectFit" class="copy-icon"/></view><text class="message-time">{{message.C}}</text><view wx:if="{{message.D}}" class="copy-button" bindtap="{{message.E}}"><image src="/static/svg/copy.svg" mode="aspectFit" class="copy-icon"/></view></view></view></view><view wx:if="{{e}}" class="message-item ai-message"><view class="message-avatar"><image src="/static/svg/ai_icon.svg" mode="aspectFit"/></view><view class="message-content loading"><text>{{f}}</text></view></view></view><view class="chat-input-area chat-input-area-chat"><view wx:if="{{g}}" class="image-preview-area"><view class="image-preview-list"><view wx:for="{{h}}" wx:for-item="image" wx:key="d" class="image-preview-item"><image src="{{image.a}}" mode="aspectFill" class="preview-image"/><view class="remove-image" bindtap="{{image.c}}"><uni-icons wx:if="{{i}}" u-i="{{image.b}}" bind:__l="__l" u-p="{{i}}"/></view></view><view wx:if="{{j}}" class="image-preview-item add-more-button" bindtap="{{l}}"><uni-icons wx:if="{{k}}" u-i="25c36616-1" bind:__l="__l" u-p="{{k}}"/><text class="add-more-text">添加图片</text></view></view></view><view class="input-container"><input class="message-input" placeholder="请输入您的问题..." confirm-type="{{'send'}}" bindfocus="{{m}}" bindblur="{{n}}" bindconfirm="{{o}}" value="{{p}}" bindinput="{{q}}"/><view wx:if="{{r}}" class="upload-button" bindtap="{{t}}"><uni-icons wx:if="{{s}}" u-i="25c36616-2" bind:__l="__l" u-p="{{s}}"/></view><view wx:if="{{v}}" class="send-button" bindtap="{{x}}"><uni-icons wx:if="{{w}}" u-i="25c36616-3" bind:__l="__l" u-p="{{w}}"/></view><view wx:if="{{y}}" class="send-button disabled"><uni-icons wx:if="{{z}}" u-i="25c36616-4" bind:__l="__l" u-p="{{z}}"/></view></view></view></view><view wx:else class="chat_messages_body"><hs-empty wx:if="{{A}}" u-i="25c36616-5" bind:__l="__l" u-p="{{A}}"/><view class="login_btn"><hs-button wx:if="{{C}}" bindclick="{{B}}" u-i="25c36616-6" bind:__l="__l" u-p="{{C}}"/></view></view></view>
|
||||
<view class="chat-container"><view class="chat_container_linear_gradient"></view><view wx:if="{{a}}" class="chat_messages_body"><my-header-prologue bindhandleQuickFast="{{b}}" u-i="25c36616-0" bind:__l="__l"/><view class="chat-messages chat-messages-chat"><view wx:for="{{c}}" wx:for-item="message" wx:key="F" id="{{message.G}}" class="{{['message-item', message.H]}}"><view wx:if="{{message.a}}" class="message-avatar"><image src="https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN43RH4M09FAFBD8D9TQPM2B.png" mode="aspectFit"/></view><view class="message-content-wrapper"><view class="message-content"><view wx:if="{{message.b}}" class="message-images"><view wx:for="{{message.c}}" wx:for-item="image" wx:key="c" class="{{['message-image-item', message.e && 'single-image']}}"><image src="{{image.a}}" mode="{{message.d}}" class="message-image" bindtap="{{image.b}}"/></view></view><view wx:elif="{{message.f}}" class="message-images"><view wx:for="{{message.g}}" wx:for-item="image" wx:key="c" class="{{['message-image-item', message.i && 'single-image']}}"><image src="{{image.a}}" mode="{{message.h}}" class="message-image" bindtap="{{image.b}}"/></view></view><view wx:elif="{{message.j}}" class="message-images"><view wx:for="{{message.k}}" wx:for-item="image" wx:key="c" class="{{['message-image-item', message.m && 'single-image']}}"><image src="{{image.a}}" mode="{{message.l}}" class="message-image" bindtap="{{image.b}}"/></view></view><block wx:if="{{message.n}}"><view wx:for="{{message.o}}" wx:for-item="line" wx:key="b" class="message-text-line"><text>{{line.a}}</text></view></block></view><view wx:if="{{message.p}}" class="quick-questions"><view wx:for="{{message.q}}" wx:for-item="question" wx:key="b" class="question-btn" bindtap="{{question.c}}"><text>{{question.a}}</text></view></view><view wx:if="{{message.r}}" class="confirmation-buttons"><view class="{{['confirmation-btn', message.s && 'selected', message.t && 'disabled']}}" bindtap="{{message.v}}"><text>是</text></view><view class="{{['confirmation-btn', message.w && 'selected', message.x && 'disabled']}}" bindtap="{{message.y}}"><text>否</text></view></view><view wx:if="{{message.z}}" class="message-meta"><view wx:if="{{message.A}}" class="copy-button" bindtap="{{message.B}}"><image src="/static/svg/copy.svg" mode="aspectFit" class="copy-icon"/></view><text class="message-time">{{message.C}}</text><view wx:if="{{message.D}}" class="copy-button" bindtap="{{message.E}}"><image src="/static/svg/copy.svg" mode="aspectFit" class="copy-icon"/></view></view></view></view><view wx:if="{{d}}" class="message-item ai-message"><view class="message-avatar"><image src="https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN43RH4M09FAFBD8D9TQPM2B.png" mode="aspectFit"/></view><view class="message-content loading"><text>{{e}}</text></view></view></view><view class="chat-input-area chat-input-area-chat"><view wx:if="{{f}}" class="image-preview-area"><view class="image-preview-list"><view wx:for="{{g}}" wx:for-item="image" wx:key="d" class="image-preview-item"><image src="{{image.a}}" mode="aspectFill" class="preview-image"/><view class="remove-image" bindtap="{{image.c}}"><uni-icons wx:if="{{h}}" u-i="{{image.b}}" bind:__l="__l" u-p="{{h}}"/></view></view><view wx:if="{{i}}" class="image-preview-item add-more-button" bindtap="{{k}}"><uni-icons wx:if="{{j}}" u-i="25c36616-2" bind:__l="__l" u-p="{{j}}"/><text class="add-more-text">添加图片</text></view></view></view><view class="input-container"><input class="message-input" placeholder="请输入您的问题..." adjust-position confirm-type="{{'send'}}" cursor-spacing="{{15}}" bindfocus="{{l}}" bindblur="{{m}}" bindconfirm="{{n}}" value="{{o}}" bindinput="{{p}}"/><view wx:if="{{q}}" class="upload-button" bindtap="{{s}}"><uni-icons wx:if="{{r}}" u-i="25c36616-3" bind:__l="__l" u-p="{{r}}"/></view><view wx:if="{{t}}" class="send-button" bindtap="{{w}}"><uni-icons wx:if="{{v}}" u-i="25c36616-4" bind:__l="__l" u-p="{{v}}"/></view><view wx:if="{{x}}" class="send-button disabled"><uni-icons wx:if="{{y}}" u-i="25c36616-5" bind:__l="__l" u-p="{{y}}"/></view></view></view></view><view wx:else class="chat_messages_body"><hs-empty wx:if="{{z}}" u-i="25c36616-6" bind:__l="__l" u-p="{{z}}"/><view class="login_btn"><hs-button wx:if="{{B}}" bindclick="{{A}}" u-i="25c36616-7" bind:__l="__l" u-p="{{B}}"/></view></view></view>
|
||||
@ -21,6 +21,7 @@
|
||||
},
|
||||
"libVersion": "3.13.2",
|
||||
"setting": {
|
||||
"bigPackageSizeSupport": false
|
||||
"bigPackageSizeSupport": false,
|
||||
"urlCheck": true
|
||||
}
|
||||
}
|
||||
1
dist/dev/mp-weixin/static/svg/ai_icon.svg
vendored
1
dist/dev/mp-weixin/static/svg/ai_icon.svg
vendored
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 692 KiB |
@ -2,31 +2,7 @@
|
||||
<view class="chat-container">
|
||||
<view class="chat_container_linear_gradient"> </view>
|
||||
<view class="chat_messages_body" v-if="userLoginStatus">
|
||||
<view class="opening_remarks">
|
||||
<view class="opening_remarks_body">
|
||||
<view class="opening_remarks_server_img">
|
||||
<image
|
||||
src="https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN5XRPWKSMDDHRJTY4F2TG1G.png"
|
||||
mode="heightFix"
|
||||
/>
|
||||
</view>
|
||||
<view class="opening_remarks_server_info">
|
||||
<view class="label">
|
||||
{{ quickQuestionsData?.greeting_text || '我是管家-邻邻,有什么可以帮助您的吗?' }}
|
||||
</view>
|
||||
<view class="group_btn">
|
||||
<view
|
||||
v-for="(i, index) in quickQuestionsData?.questions"
|
||||
:key="`item_${index}`"
|
||||
class="group_btn_item"
|
||||
@click="handleQuickFast(i)"
|
||||
>
|
||||
{{ i }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<MyHeaderPrologue @handleQuickFast="handleQuickFast" />
|
||||
|
||||
<view class="chat-messages chat-messages-chat">
|
||||
<view
|
||||
@ -56,7 +32,7 @@
|
||||
:src="image"
|
||||
:mode="message.image_url.length === 1 ? 'widthFix' : 'aspectFill'"
|
||||
class="message-image"
|
||||
@click="previewImage(image, message.image_url!)"
|
||||
@click="method?.previewImage(image, message.image_url!)"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
@ -73,7 +49,7 @@
|
||||
:src="image"
|
||||
:mode="message.images.length === 1 ? 'widthFix' : 'aspectFill'"
|
||||
class="message-image"
|
||||
@click="previewImage(image, message.images!)"
|
||||
@click="method?.previewImage(image, message.images!)"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
@ -97,7 +73,7 @@
|
||||
:src="image"
|
||||
:mode="message.metadata.image_url.length === 1 ? 'widthFix' : 'aspectFill'"
|
||||
class="message-image"
|
||||
@click="previewImage(image, message.metadata.image_url!)"
|
||||
@click="method?.previewImage(image, message.metadata.image_url!)"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
@ -105,7 +81,7 @@
|
||||
<!-- 文本内容 -->
|
||||
<view
|
||||
v-if="message.content && message.content.trim()"
|
||||
v-for="(line, lineIndex) in formatMessageContent(message.content)"
|
||||
v-for="(line, lineIndex) in method?.formatMessageContent(message.content)"
|
||||
:key="'text-' + lineIndex"
|
||||
class="message-text-line"
|
||||
>
|
||||
@ -153,15 +129,15 @@
|
||||
<view
|
||||
v-if="message.role === 'ai'"
|
||||
class="copy-button"
|
||||
@click="copyMessage(message.content)"
|
||||
@click="method?.copyMessage(message.content)"
|
||||
>
|
||||
<image src="/static/svg/copy.svg" mode="aspectFit" class="copy-icon" />
|
||||
</view>
|
||||
<text class="message-time">{{ formatTime(message.created_at) }}</text>
|
||||
<text class="message-time">{{ method?.formatTime(message.created_at) }}</text>
|
||||
<view
|
||||
v-if="message.role === 'user'"
|
||||
class="copy-button"
|
||||
@click="copyMessage(message.content)"
|
||||
@click="method?.copyMessage(message.content)"
|
||||
>
|
||||
<image src="/static/svg/copy.svg" mode="aspectFit" class="copy-icon" />
|
||||
</view>
|
||||
@ -171,7 +147,10 @@
|
||||
|
||||
<view v-if="loading" class="message-item ai-message">
|
||||
<view class="message-avatar">
|
||||
<image src="/static/svg/ai_icon.svg" mode="aspectFit" />
|
||||
<image
|
||||
src="https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN43RH4M09FAFBD8D9TQPM2B.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
<view class="message-content loading">
|
||||
<text>{{ loadingText }}</text>
|
||||
@ -181,20 +160,24 @@
|
||||
|
||||
<view class="chat-input-area chat-input-area-chat">
|
||||
<!-- 图片预览区域 -->
|
||||
<view v-if="selectedImages.length > 0" class="image-preview-area">
|
||||
<view v-if="useModel?.selectedImages?.value?.length > 0" class="image-preview-area">
|
||||
<view class="image-preview-list">
|
||||
<view v-for="(image, index) in selectedImages" :key="index" class="image-preview-item">
|
||||
<view
|
||||
v-for="(image, index) in useModel?.selectedImages?.value"
|
||||
:key="index"
|
||||
class="image-preview-item"
|
||||
>
|
||||
<image :src="image" mode="aspectFill" class="preview-image" />
|
||||
<view class="remove-image" @click="removeImage(index)">
|
||||
<view class="remove-image" @click="method?.removeImage(index)">
|
||||
<uni-icons type="closeempty" size="14" color="#fff" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 添加更多图片按钮 -->
|
||||
<view
|
||||
v-if="selectedImages.length < 9"
|
||||
v-if="useModel?.selectedImages?.value?.length < 9"
|
||||
class="image-preview-item add-more-button"
|
||||
@click="chooseImage"
|
||||
@click="method?.chooseImage()"
|
||||
>
|
||||
<uni-icons type="plus" size="30" color="#999" />
|
||||
<text class="add-more-text">添加图片</text>
|
||||
@ -219,7 +202,9 @@
|
||||
v-model="inputMessage"
|
||||
class="message-input"
|
||||
placeholder="请输入您的问题..."
|
||||
adjust-position
|
||||
:confirm-type="'send'"
|
||||
:cursor-spacing="15"
|
||||
@focus="isInputFocused = true"
|
||||
@blur="isInputFocused = false"
|
||||
@confirm="handleSendMessage"
|
||||
@ -227,16 +212,25 @@
|
||||
|
||||
<!-- 相机按钮(当没有输入内容且输入框未聚焦时显示) -->
|
||||
<view
|
||||
v-if="!inputMessage.trim() && !isInputFocused && selectedImages.length === 0"
|
||||
v-if="
|
||||
!inputMessage.trim() &&
|
||||
!isInputFocused &&
|
||||
useModel?.selectedImages?.value?.length === 0
|
||||
"
|
||||
class="upload-button"
|
||||
@click="chooseImage"
|
||||
@click="method?.chooseImage()"
|
||||
>
|
||||
<uni-icons type="camera" size="24" color="#666" />
|
||||
</view>
|
||||
|
||||
<!-- 发送按钮(当有输入内容或输入框聚焦或选择了图片时显示) -->
|
||||
<view
|
||||
v-if="(inputMessage.trim() || isInputFocused || selectedImages.length > 0) && !loading"
|
||||
v-if="
|
||||
(inputMessage.trim() ||
|
||||
isInputFocused ||
|
||||
useModel?.selectedImages?.value?.length > 0) &&
|
||||
!loading
|
||||
"
|
||||
class="send-button"
|
||||
@click="handleSendMessage"
|
||||
>
|
||||
@ -263,12 +257,14 @@
|
||||
import { ref, nextTick, onUnmounted, getCurrentInstance } from 'vue'
|
||||
import { useWeAppAuthStore } from '@/common'
|
||||
import { onPullDownRefresh, onLoad, onPageScroll, onShow } from '@dcloudio/uni-app'
|
||||
import method from './method'
|
||||
import dayjs from 'dayjs'
|
||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||
import 'dayjs/locale/zh-cn'
|
||||
import { upload } from '@/common/libraries/upload'
|
||||
import { quickActions, QuickAction } from '@/common/libraries/public'
|
||||
import useModel from './model'
|
||||
import { QuickAction } from '@/common/libraries/public'
|
||||
import getLoginStatus from '@/common/libraries/userUserLogin'
|
||||
import MyHeaderPrologue from './components/HeaderPrologue.vue'
|
||||
|
||||
// 配置dayjs
|
||||
dayjs.extend(relativeTime)
|
||||
@ -294,7 +290,6 @@ interface Message {
|
||||
const auth = useWeAppAuthStore()
|
||||
const userLoginStatus = ref(false)
|
||||
const inputMessage = ref('')
|
||||
const selectedImages = ref<string[]>([]) // 选中的图片
|
||||
const isInputFocused = ref(false) // 输入框是否聚焦
|
||||
const messages = ref<Message[]>([])
|
||||
const loading = ref(false)
|
||||
@ -302,12 +297,6 @@ const loadingText = ref('正在输入中...')
|
||||
let socketTask: any = null
|
||||
let isConnected = ref(false)
|
||||
|
||||
// 接口域名配置
|
||||
// const API_BASE_URL = 'http://10.39.13.78:8000' //dev环境
|
||||
// const WS_BASE_URL = 'wss://10.39.13.78:8000' //dev环境
|
||||
const API_BASE_URL = 'https://kf-api-test.linyikj.com.cn' //测试环境
|
||||
const WS_BASE_URL = 'wss://kf-api-test.linyikj.com.cn' //测试环境
|
||||
|
||||
// 历史记录相关
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(10)
|
||||
@ -318,98 +307,13 @@ const currentOffset = ref(0) // 当前偏移量
|
||||
const quickQuestionsData = ref<any>({}) // 存储开场白数据
|
||||
const lastMessageContent = ref('') // 用于防止重复显示相同的消息
|
||||
|
||||
// 获取开场白按钮数据
|
||||
const getQuickQuestions = async () => {
|
||||
try {
|
||||
let selected_house = auth?.data?.selected_house
|
||||
const response = await uni.request({
|
||||
url: `${API_BASE_URL}/api/public/quick-questions?platform=property&company_id=${selected_house?.companies_id}&project_id=${selected_house?.asset_projects_id}`,
|
||||
method: 'GET'
|
||||
})
|
||||
|
||||
if (response.statusCode === 200) {
|
||||
const result = response.data as any
|
||||
|
||||
console.log('获取到开场白按钮数据2:', result)
|
||||
return result
|
||||
} else {
|
||||
console.error('获取开场白数据失败,状态码:', response.statusCode)
|
||||
return []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取开场白数据异常:', error)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
const goToPageLogin = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/login'
|
||||
})
|
||||
}
|
||||
|
||||
// 格式化消息内容,处理换行符
|
||||
const formatMessageContent = (content: string) => {
|
||||
if (!content || typeof content !== 'string') {
|
||||
return ['']
|
||||
}
|
||||
return content.split('\n').filter(line => line.trim() !== '')
|
||||
}
|
||||
|
||||
// 预览图片
|
||||
const previewImage = (currentImage: string, images: string[]) => {
|
||||
uni.previewImage({
|
||||
current: currentImage,
|
||||
urls: images
|
||||
})
|
||||
}
|
||||
|
||||
// 复制消息内容
|
||||
const copyMessage = (content: string) => {
|
||||
if (!content) {
|
||||
uni.showToast({
|
||||
title: '暂无内容可复制',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
uni.setClipboardData({
|
||||
data: content,
|
||||
success: () => {
|
||||
uni.showToast({
|
||||
title: '复制成功',
|
||||
icon: 'success'
|
||||
})
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
title: '复制失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 时间格式化函数
|
||||
const formatTime = (timeStr: string) => {
|
||||
if (!timeStr) return ''
|
||||
|
||||
try {
|
||||
const date = dayjs(timeStr)
|
||||
|
||||
// 检查日期是否有效
|
||||
if (!date.isValid()) {
|
||||
return ''
|
||||
}
|
||||
|
||||
// 使用相对时间显示
|
||||
return date.fromNow()
|
||||
} catch (e) {
|
||||
console.error('时间格式化错误:', e)
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
const scrollToBottom = () => {
|
||||
nextTick(() => {
|
||||
@ -441,17 +345,11 @@ const getHistoryMessages = async (page: number = 1) => {
|
||||
const offset = (page - 1) * pageSize.value
|
||||
currentOffset.value = offset
|
||||
|
||||
console.log('分页信息 - 页码:', page, '每页数量:', pageSize.value, '计算出的offset:', offset)
|
||||
|
||||
const response = await uni.request({
|
||||
url: `${API_BASE_URL}/api/public/customer/init`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
platform: 'property',
|
||||
platform_user_id: userPhone, //userPhone
|
||||
limit: pageSize.value,
|
||||
offset: offset
|
||||
}
|
||||
const response = await method?.customRequest('public/customer/init', {
|
||||
platform: 'property',
|
||||
platform_user_id: userPhone, //userPhone
|
||||
limit: pageSize.value,
|
||||
offset: offset
|
||||
})
|
||||
|
||||
if (response.statusCode === 200) {
|
||||
@ -648,30 +546,6 @@ const getHistoryMessages = async (page: number = 1) => {
|
||||
hasMore.value = totalItems > messages.value.length
|
||||
currentPage.value = page
|
||||
|
||||
// 如果不是第一页且已经加载完所有数据,展示开场白
|
||||
if (page > 1 && !hasMore.value) {
|
||||
console.log('分页加载完成,当前页:', page, 'hasMore:', hasMore.value, '展示开场白')
|
||||
// 等待数据渲染完成后再添加开场白
|
||||
setTimeout(() => {
|
||||
addQuickQuestionsToFirstAIMessage(true)
|
||||
}, 500)
|
||||
}
|
||||
|
||||
console.log(
|
||||
'第',
|
||||
page,
|
||||
'页数据加载完成,offset:',
|
||||
offset,
|
||||
', limit:',
|
||||
pageSize.value,
|
||||
', 总数据:',
|
||||
totalItems,
|
||||
', 当前已加载:',
|
||||
messages.value.length,
|
||||
', 是否有更多:',
|
||||
hasMore.value
|
||||
)
|
||||
|
||||
// 如果是第一页,滚动到底部
|
||||
if (page === 1) {
|
||||
setTimeout(() => {
|
||||
@ -724,10 +598,7 @@ const initWebSocket = () => {
|
||||
|
||||
try {
|
||||
// Socket.IO兼容的WebSocket连接,使用/customer命名空间
|
||||
const wsUrl = `${WS_BASE_URL}/ws/socket.io/?EIO=4&transport=websocket`
|
||||
|
||||
console.log('正在建立Socket.IO连接')
|
||||
console.log('连接URL:', wsUrl)
|
||||
const wsUrl = `${useModel?.WS_BASE_URL}/ws/socket.io/?EIO=4&transport=websocket`
|
||||
|
||||
socketTask = uni.connectSocket({
|
||||
url: wsUrl,
|
||||
@ -735,25 +606,19 @@ const initWebSocket = () => {
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
// 监听Socket.IO连接打开事件
|
||||
uni.onSocketOpen((res: any) => {
|
||||
console.log('[Customer] WebSocket connected', res)
|
||||
isConnected.value = true
|
||||
|
||||
// 发送Socket.IO连接包到/customer命名空间
|
||||
const connectPacket = '40/customer,{"jwt":""}'
|
||||
uni.sendSocketMessage({
|
||||
data: connectPacket,
|
||||
success: () => {
|
||||
console.log('[Customer] Socket.IO连接包发送成功')
|
||||
|
||||
// 加入会话房间
|
||||
if (conversationId.value) {
|
||||
setTimeout(() => {
|
||||
const joinMessage = `42/customer,["join_conversation",{"conversation_id":"${conversationId.value}"}]`
|
||||
console.log('[Customer] 加入会话房间:', joinMessage)
|
||||
|
||||
uni.sendSocketMessage({
|
||||
data: joinMessage,
|
||||
success: () => {
|
||||
@ -788,10 +653,6 @@ const initWebSocket = () => {
|
||||
|
||||
// 监听Socket.IO消息事件
|
||||
uni.onSocketMessage((res: any) => {
|
||||
console.log('收到WebSocket原始消息:', res)
|
||||
console.log('消息数据类型:', typeof res.data)
|
||||
console.log('消息内容:', res.data)
|
||||
|
||||
// 处理WebSocket消息
|
||||
const data = res.data
|
||||
|
||||
@ -898,8 +759,6 @@ const handleObjectMessage = (objData: any) => {
|
||||
|
||||
// 处理typing指示器
|
||||
const processTypingIndicator = (typingData: any) => {
|
||||
console.log('[Customer] 处理typing指示器:', typingData)
|
||||
|
||||
// 检查是否是客服正在输入
|
||||
if (typingData.is_typing && typingData.user_type === 'staff') {
|
||||
loading.value = true
|
||||
@ -909,52 +768,10 @@ const processTypingIndicator = (typingData: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否应该展示开场白
|
||||
const checkShouldShowQuickQuestions = (isLastPage: boolean = false) => {
|
||||
// 只要有开场白数据,就展示开场白
|
||||
return quickQuestionsData.value.length > 0
|
||||
}
|
||||
|
||||
// 找到第一条AI消息并添加开场白
|
||||
const addQuickQuestionsToFirstAIMessage = (isLastPage: boolean = false) => {
|
||||
if (quickQuestionsData.value.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否应该展示开场白
|
||||
if (!checkShouldShowQuickQuestions(isLastPage)) {
|
||||
return
|
||||
}
|
||||
|
||||
// 创建开场白消息
|
||||
const welcomeMessage: Message = {
|
||||
role: 'ai',
|
||||
content: '您好!我是物业客服,有什么可以帮助您的吗?',
|
||||
quickQuestions: quickQuestionsData.value,
|
||||
created_at: new Date().toISOString()
|
||||
}
|
||||
|
||||
console.log('[Customer] 创建开场白消息,是否最后一页:', isLastPage)
|
||||
|
||||
// 如果没有历史记录,直接设置开场白
|
||||
if (messages.value.length === 0) {
|
||||
messages.value = [welcomeMessage]
|
||||
console.log('[Customer] 设置开场白为第一条消息')
|
||||
}
|
||||
// 如果有历史记录,在第一条消息前面插入开场白
|
||||
else {
|
||||
messages.value.unshift(welcomeMessage)
|
||||
console.log('[Customer] 在第一条消息前面插入开场白')
|
||||
}
|
||||
}
|
||||
|
||||
// 处理消息内容的统一函数
|
||||
const processMessage = (messageData: any) => {
|
||||
console.log('[Customer] 处理消息数据:', messageData)
|
||||
|
||||
// 不显示自己发的消息(已经通过HTTP显示了)
|
||||
if (messageData.sender_type === 'customer' || messageData.role === 'user') {
|
||||
console.log('[Customer] 过滤掉客户消息')
|
||||
return
|
||||
}
|
||||
|
||||
@ -1036,7 +853,7 @@ const handleQuickFast = (name: string) => {
|
||||
}
|
||||
|
||||
// 处理快捷按钮点击
|
||||
const handleQuickAction = (action: QuickAction) => {
|
||||
const handleQuickAction = (action: any) => {
|
||||
inputMessage.value = action.message
|
||||
handleSendMessage()
|
||||
}
|
||||
@ -1057,45 +874,9 @@ const handleConfirmation = (message: Message, confirmation: string) => {
|
||||
}, 300)
|
||||
}
|
||||
|
||||
const chooseImage = async () => {
|
||||
const maxImages = 9
|
||||
if (selectedImages.value.length >= maxImages) {
|
||||
uni.showToast({
|
||||
title: '最多选择9张图片',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const remainingCount = maxImages - selectedImages.value.length
|
||||
const uploadResult = await upload(remainingCount, 2, ['image'])
|
||||
|
||||
if (uploadResult && Array.isArray(uploadResult) && uploadResult.length > 0) {
|
||||
const imageUrls = uploadResult.map((item: any) => item.url)
|
||||
selectedImages.value.push(...imageUrls)
|
||||
|
||||
uni.showToast({
|
||||
title: '图片上传成功',
|
||||
icon: 'success'
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('选择图片失败:', error)
|
||||
uni.showToast({
|
||||
title: '选择图片失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const removeImage = (index: number) => {
|
||||
selectedImages.value.splice(index, 1)
|
||||
}
|
||||
|
||||
const handleSendMessage = async () => {
|
||||
const message = inputMessage.value.trim()
|
||||
const hasImages = selectedImages.value.length > 0
|
||||
const hasImages = useModel?.selectedImages?.value?.length > 0
|
||||
|
||||
if ((!message && !hasImages) || loading.value) return
|
||||
|
||||
@ -1119,7 +900,7 @@ const handleSendMessage = async () => {
|
||||
}
|
||||
|
||||
// 图片已经在上传时就存储了OSS链接,直接使用
|
||||
const uploadedImages = selectedImages.value
|
||||
const uploadedImages = useModel?.selectedImages?.value || []
|
||||
|
||||
// 确定消息类型
|
||||
let messageType: 'text' | 'image' | 'mixed' = 'text'
|
||||
@ -1142,7 +923,7 @@ const handleSendMessage = async () => {
|
||||
messages.value.push(userMessage)
|
||||
|
||||
inputMessage.value = ''
|
||||
selectedImages.value = []
|
||||
useModel.selectedImages.value = []
|
||||
scrollToBottom()
|
||||
|
||||
// 判断消息中是否包含"查询"关键词,设置相应的loading文案
|
||||
@ -1156,22 +937,14 @@ const handleSendMessage = async () => {
|
||||
|
||||
try {
|
||||
// 使用HTTP接口发送消息
|
||||
const response = await uni.request({
|
||||
url: `${API_BASE_URL}/api/public/chat`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
platform: 'property',
|
||||
message: message || '', // 纯图片时传空字符串
|
||||
tenant_project_id: projectId,
|
||||
tenant_project_name: projectName || '',
|
||||
platform_user_id: userPhone,
|
||||
conversation_id: conversationId.value,
|
||||
message_type: messageType,
|
||||
image_url: uploadedImages.length > 0 ? uploadedImages : undefined
|
||||
},
|
||||
header: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
const response = await method?.customRequest('public/chat', {
|
||||
platform: 'property',
|
||||
message: message || '', // 纯图片时传空字符串
|
||||
tenant_project_id: projectId,
|
||||
message_type: messageType,
|
||||
tenant_project_name: projectName || '',
|
||||
conversation_id: conversationId.value,
|
||||
image_url: uploadedImages.length > 0 ? uploadedImages : undefined
|
||||
})
|
||||
|
||||
if (response.statusCode === 200) {
|
||||
@ -1290,17 +1063,10 @@ onUnmounted(() => {
|
||||
})
|
||||
|
||||
onLoad(async op => {
|
||||
console.log(
|
||||
'页面加载时已获取开场白按钮数据1:',
|
||||
quickQuestionsData.value.length,
|
||||
getLoginStatus?.getLoginStatus()
|
||||
)
|
||||
await getCurrentInstance()?.appContext.config.globalProperties.$onLaunched
|
||||
if (getLoginStatus?.getLoginStatus()) {
|
||||
userLoginStatus.value = true
|
||||
console.log('页面加载时已获取开场白按钮数据3:', quickQuestionsData.value.length)
|
||||
quickQuestionsData.value = await getQuickQuestions()
|
||||
console.log('页面加载时已获取开场白按钮数据2:', quickQuestionsData.value.length)
|
||||
quickQuestionsData.value = await method?.getQuickQuestions()
|
||||
// 获取历史记录(如果有历史记录,会在接口返回成功后自动在最前方插入开场白)
|
||||
getHistoryMessages(1)
|
||||
if (op?.message) {
|
||||
|
||||
37
src/pages/ai/components/HeaderPrologue.vue
Normal file
37
src/pages/ai/components/HeaderPrologue.vue
Normal file
@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<view class="opening_remarks">
|
||||
<view class="opening_remarks_body">
|
||||
<view class="opening_remarks_server_img">
|
||||
<image
|
||||
src="https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KN5XRPWKSMDDHRJTY4F2TG1G.png"
|
||||
mode="heightFix"
|
||||
/>
|
||||
</view>
|
||||
<view class="opening_remarks_server_info">
|
||||
<view class="label">
|
||||
{{
|
||||
useModel?.quickQuestionsData?.value?.greeting_text ||
|
||||
'我是管家-邻邻,有什么可以帮助您的吗?'
|
||||
}}
|
||||
</view>
|
||||
<view class="group_btn">
|
||||
<view
|
||||
v-for="(i, index) in useModel?.quickQuestionsData?.value?.questions"
|
||||
:key="`item_${index}`"
|
||||
class="group_btn_item"
|
||||
@click="handleSendFast(i)"
|
||||
>
|
||||
{{ i }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import useModel from '../model'
|
||||
const emit = defineEmits(['handleQuickFast'])
|
||||
const handleSendFast = (name: string) => {
|
||||
emit('handleQuickFast', name)
|
||||
}
|
||||
</script>
|
||||
1080
src/pages/ai/index.vue
Normal file
1080
src/pages/ai/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
141
src/pages/ai/method.ts
Normal file
141
src/pages/ai/method.ts
Normal file
@ -0,0 +1,141 @@
|
||||
import { ref, nextTick, onUnmounted, getCurrentInstance } from 'vue'
|
||||
import { useWeAppAuthStore } from '@/common'
|
||||
import { onPullDownRefresh, onLoad, onPageScroll, onShow } from '@dcloudio/uni-app'
|
||||
import dayjs from 'dayjs'
|
||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||
import 'dayjs/locale/zh-cn'
|
||||
import useModel from './model'
|
||||
import { upload } from '@/common/libraries/upload'
|
||||
|
||||
const auth = useWeAppAuthStore()
|
||||
|
||||
// 配置dayjs
|
||||
dayjs.extend(relativeTime)
|
||||
dayjs.locale('zh-cn')
|
||||
|
||||
export default {
|
||||
customRequest: async (
|
||||
url: string,
|
||||
data: any,
|
||||
type?: 'POST' | 'OPTIONS' | 'GET' | 'HEAD' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT'
|
||||
) => {
|
||||
const selected_house: any = auth?.data?.selected_house
|
||||
console.log('selected_house:', selected_house)
|
||||
const response = await uni.request({
|
||||
url: `${useModel?.API_BASE_URL}/api/${url}`,
|
||||
method: type || 'POST',
|
||||
data: { ...data, tenant_company_id: selected_house?.companies_id },
|
||||
header: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
return response
|
||||
},
|
||||
getQuickQuestions: async () => {
|
||||
try {
|
||||
const selected_house: any = auth?.data?.selected_house
|
||||
|
||||
const response = await uni.request({
|
||||
url: `${useModel?.API_BASE_URL}/api/public/quick-questions?platform=property&company_id=${selected_house?.companies_id}&project_id=${selected_house?.asset_projects_id}`,
|
||||
method: 'GET'
|
||||
})
|
||||
if (response.statusCode === 200) {
|
||||
const result = response.data as any
|
||||
return result
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
} catch (error) {
|
||||
return []
|
||||
}
|
||||
},
|
||||
chooseImage: async () => {
|
||||
const maxImages = 9
|
||||
if (useModel?.selectedImages?.value.length >= maxImages) {
|
||||
uni.showToast({
|
||||
title: '最多选择9张图片',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const remainingCount = maxImages - useModel?.selectedImages?.value.length
|
||||
const uploadResult = await upload(remainingCount, 2, ['image'])
|
||||
|
||||
if (uploadResult && Array.isArray(uploadResult) && uploadResult.length > 0) {
|
||||
const imageUrls = uploadResult.map((item: any) => item.url)
|
||||
useModel.selectedImages.value.push(...imageUrls)
|
||||
|
||||
uni.showToast({
|
||||
title: '图片上传成功',
|
||||
icon: 'success'
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('选择图片失败:', error)
|
||||
uni.showToast({
|
||||
title: '选择图片失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
},
|
||||
removeImage: (index: number) => {
|
||||
useModel.selectedImages.value.splice(index, 1)
|
||||
},
|
||||
previewImage: (currentImage: string, images: string[]) => {
|
||||
uni.previewImage({
|
||||
current: currentImage,
|
||||
urls: images
|
||||
})
|
||||
},
|
||||
copyMessage: (content: string) => {
|
||||
if (!content) {
|
||||
uni.showToast({
|
||||
title: '暂无内容可复制',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
uni.setClipboardData({
|
||||
data: content,
|
||||
success: () => {
|
||||
uni.showToast({
|
||||
title: '复制成功',
|
||||
icon: 'success'
|
||||
})
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
title: '复制失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
formatMessageContent: (content: string) => {
|
||||
if (!content || typeof content !== 'string') {
|
||||
return ['']
|
||||
}
|
||||
return content.split('\n').filter(line => line.trim() !== '')
|
||||
},
|
||||
formatTime: (timeStr: string) => {
|
||||
if (!timeStr) return ''
|
||||
|
||||
try {
|
||||
const date = dayjs(timeStr)
|
||||
|
||||
// 检查日期是否有效
|
||||
if (!date.isValid()) {
|
||||
return ''
|
||||
}
|
||||
|
||||
// 使用相对时间显示
|
||||
return date.fromNow()
|
||||
} catch (e) {
|
||||
console.error('时间格式化错误:', e)
|
||||
return ''
|
||||
}
|
||||
}
|
||||
}
|
||||
11
src/pages/ai/model.ts
Normal file
11
src/pages/ai/model.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { reactive, ref } from 'vue'
|
||||
export default {
|
||||
selectedImages: ref<string[]>([]), // 选中的图片
|
||||
quickQuestionsData: ref<any>({}),
|
||||
// API_BASE_URL: 'http://10.39.13.78:8000', //dev环境
|
||||
// WS_BASE_URL: 'wss://10.39.13.78:8000' //dev环境
|
||||
// API_BASE_URL: 'https://kf-api-test.linyikj.com.cn', //测试环境
|
||||
// WS_BASE_URL: 'wss://kf-api-test.linyikj.com.cn' //测试环境
|
||||
API_BASE_URL: 'https://kf-api.linyikj.com.cn', //正式环境
|
||||
WS_BASE_URL: 'wss://kf-api.linyikj.com.cn' //正式环境
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 692 KiB |
Loading…
x
Reference in New Issue
Block a user