修改在线聊天页面

This commit is contained in:
hejin 2025-09-02 23:47:25 +08:00
parent 8aaa864c49
commit bb0aeef750
10 changed files with 144 additions and 51 deletions

View File

@ -1,4 +1,4 @@
NODE_ENV='development' NODE_ENV='development'
VITE_APP_TITLE='开发环境' VITE_APP_TITLE='开发环境'
VITE_APP_BASE_API='http://114.132.197.85:8099' VITE_APP_BASE_API='http://1.92.99.15:8099'
VITE_APP_SCOKET='ws://114.132.197.85:8099/ws/asset/' VITE_APP_SCOKET='ws://1.92.99.15:8099/ws/asset/'

View File

@ -1,4 +1,4 @@
NODE_ENV='production' NODE_ENV='production'
VITE_APP_TITLE='生产环境' VITE_APP_TITLE='生产环境'
VITE_APP_BASE_API='http://114.132.197.85:8099' VITE_APP_BASE_API='http://1.92.99.15:8099'
VITE_APP_SCOKET='ws://114.132.197.85:8099/ws/asset/' VITE_APP_SCOKET='ws://1.92.99.15:8099/ws/asset/'

View File

@ -1,3 +1,4 @@
NODE_ENV='test' NODE_ENV='test'
VITE_APP_TITLE='测试环境' VITE_APP_TITLE='测试环境'
VITE_APP_BASE_API='' VITE_APP_BASE_API='http://1.92.99.15:8099'
VITE_APP_SCOKET='ws://1.92.99.15:8099/ws/asset/'

View File

@ -95,23 +95,6 @@ export const articlePageApi = (params) => {
return request.get('/web/newsPageList', {params}) return request.get('/web/newsPageList', {params})
} }
/**
* @function 获取聊天窗口信息
* @param {string} cusCode 设备唯一值
* @param {string} prodId 产品ID
**/
export const msgListApi = (data) => {
return request.post('/web/chatMain',data)
}
/**
* @function 保存消息
* @param {string} id
* @param {array} jsonArray 最新的消息列表
**/
export const saveMsg = (data) => {
return request.post('/web/saveMessage', data)
}
/** /**
* @function 全站搜索 * @function 全站搜索
@ -134,3 +117,36 @@ export const appInfoApi = () => {
export const newAppApi = () => { export const newAppApi = () => {
return request.get('/web/getNewApp') return request.get('/web/getNewApp')
} }
/**
* @function 获取活跃聊天
* @param {string} deviceCode 唯一
* @param {string} prodId 产品id
**/
export const activeMsgApi = (params) => {
return request.get('/chat/active', {params})
}
/**
* @function 加载指定会话内容
* @param {string} sessionId
**/
export const sessionMsgApi = (sessionId) => {
return request.get(`/chat/session/${sessionId}`)
}
/**
* @function 创建新聊天会话
* @param {string} cusCode deviceCode
* @param {string} prodId 产品id
**/
export const createSessiongMsgApi = (data) => {
return request.post('/chat/newChat', data)
}
/**
* @function 发送消息
**/
export const newsMsgApi = (data) => {
return request.post('/chat/newMes', data)
}

View File

@ -5,6 +5,9 @@
:scroll-y="true" :scroll-y="true"
:scroll-top="msgScroll" :scroll-top="msgScroll"
> >
<view class="msg opposite" v-if="!useScoketMsg().msgList.length">
{{t('online.littleTitle')}}
</view>
<view <view
class="msg" class="msg"
:class="item.dataFrom === 'customer' ? 'oneself' : 'opposite'" :class="item.dataFrom === 'customer' ? 'oneself' : 'opposite'"
@ -12,6 +15,9 @@
:key="index" :key="index"
> >
{{item.content}} {{item.content}}
<text class="time">
{{dayJs(item.createTime).format('HH:mm')}}
</text>
</view> </view>
</scroll-view </scroll-view
> >
@ -45,24 +51,48 @@
<script setup> <script setup>
import { onLoad, onUnload } from '@dcloudio/uni-app'; import { onLoad, onUnload } from '@dcloudio/uni-app';
import { ref, nextTick } from 'vue'; import { ref, nextTick } from 'vue';
import dayJs from 'dayjs';
import { useI18n } from 'vue-i18n';
import { useScoketMsg } from '@/stores/index.js'; import { useScoketMsg } from '@/stores/index.js';
import {
activeMsgApi,
newsMsgApi,
createSessiongMsgApi,
sessionMsgApi
} from '@/api/index.js';
const { t } = useI18n()
const inputFocus = ref(true) const inputFocus = ref(true)
const sendVal = ref('') const sendVal = ref('')
const send = () => { const send = async () => {
if (!sendVal.value) { if (!sendVal.value) {
return return
} }
useScoketMsg().send(`customer,${sendVal.value}`).then(() => { let data = {
mainId: sessionId.value,
dataFrom: "customer",
senderId: useScoketMsg().onlyId,
receiverId: serviceId.value,
content: sendVal.value,
}
await newsMsgApi(data)
const wsMsg = {
type: 1,// 1-
toUserId: serviceId.value,
content: sendVal.value,
sessionId: sessionId.value,
fromUserId: useScoketMsg().onlyId
};
useScoketMsg().send(JSON.stringify(wsMsg)).then(() => {
sendVal.value = '' sendVal.value = ''
inputFocus.value = false inputFocus.value = false
useScoketMsg().msgList = [...useScoketMsg().msgList, data]
nextTick(() => { nextTick(() => {
inputFocus.value = true inputFocus.value = true
if (useScoketMsg().msgList.length < 7) { nextTick(() => {
uni.pageScrollTo({ scrollJump()
offsetTop: 0
}) })
}
}) })
}) })
} }
@ -76,6 +106,48 @@
useScoketMsg().msgCallback = scrollJump useScoketMsg().msgCallback = scrollJump
const prodId = ref('') const prodId = ref('')
const sessionId = ref(null)
const serviceId = ref(null)
const getActiveMsg = () => {
let params = {
deviceCode: useScoketMsg().onlyId,
prodId: prodId.value
}
activeMsgApi(params).then(({data:res}) => {
if (res.data && res.data.id!==null) {
sessionId.value = res.data.id
serviceId.value = res.data.userId
loadMessages()
} else {
createNewSession()
}
})
}
const loadMessages = () => {
sessionMsgApi(sessionId.value).then(({data:res}) => {
useScoketMsg().msgList = res.data
nextTick(() => {
scrollJump()
})
})
}
const createNewSession = () => {
let data = {
cusCode: useScoketMsg().onlyId,
prodId: prodId.value
}
createSessiongMsgApi(data).then(({data:res}) => {
sessionId.value = res.data.id
serviceId.value = res.data.userId
const wsMsg = {
type: 2,// 2-
toUserId: serviceId.value,
sessionId: sessionId.value,
fromUserId: useScoketMsg().onlyId
}
useScoketMsg().send(JSON.stringify(wsMsg))
})
}
onUnload(() => { onUnload(() => {
useScoketMsg().closeScoket() useScoketMsg().closeScoket()
@ -83,8 +155,8 @@
onLoad(async(options) => { onLoad(async(options) => {
prodId.value = options.prodId prodId.value = options.prodId
await useScoketMsg().getMsgList(prodId.value) await useScoketMsg().scoketInit()
useScoketMsg().scoketInit() getActiveMsg()
scrollJump() scrollJump()
}) })
</script> </script>
@ -107,16 +179,28 @@
width: max-content; width: max-content;
max-width: 80%; max-width: 80%;
height: min-content; height: min-content;
position: relative;
margin-bottom: 46rpx; margin-bottom: 46rpx;
padding: 23rpx 34rpx; padding: 23rpx 34rpx;
word-break: break-word; word-break: break-word;
border-radius: 8rpx; border-radius: 8rpx;
border: 2rpx solid #eeeeef; border: 2rpx solid #eeeeef;
font-size: 28rpx; font-size: 28rpx;
.time {
position: absolute;
bottom: -40rpx;
right: 0;
color: #ccc;
font-size: 24rpx;
}
} }
.opposite { .opposite {
color: #0d0e0e; color: #0d0e0e;
background-color: #fff; background-color: #fff;
.time {
left: 0;
right: unset;
}
} }
.oneself { .oneself {
margin-left: auto; margin-left: auto;

View File

@ -132,7 +132,8 @@
}, },
"online": { "online": {
"placeholder": "Send your requiremen", "placeholder": "Send your requiremen",
"Retry": "Please try again later" "Retry": "Please try again later",
"littleTitle": "Hello! It's a pleasure to assist you. How may I help you?"
}, },
"seo": { "seo": {
"news": { "news": {

View File

@ -132,7 +132,8 @@
}, },
"online": { "online": {
"placeholder": "Send your requiremen", "placeholder": "Send your requiremen",
"Retry": "请稍后重试" "Retry": "请稍后重试",
"littleTitle": "您好!很高兴为您服务,请问有什么可以帮您?"
}, },
"seo": { "seo": {
"news": { "news": {

View File

@ -196,7 +196,7 @@
const catgTreeInit = () => { const catgTreeInit = () => {
return prodOrNewsCatgApi(params.value.maxCatgId).then(({data:res}) => { return prodOrNewsCatgApi(params.value.maxCatgId).then(({data:res}) => {
catgTree.value = res.data catgTree.value = res.data
if (res.data.length) { if (res.data.length && !finalCatgId.value) {
params.value.catgId = res.data[0].children.length ? res.data[0].children[0].id : res.data[0].id params.value.catgId = res.data[0].children.length ? res.data[0].children[0].id : res.data[0].id
} }
}) })

View File

@ -217,7 +217,7 @@
const catgTreeInit = () => { const catgTreeInit = () => {
return prodOrNewsCatgApi(params.value.maxCatgId).then(({data:res}) => { return prodOrNewsCatgApi(params.value.maxCatgId).then(({data:res}) => {
catgTree.value = res.data catgTree.value = res.data
if (res.data.length) { if (res.data.length && !finalCatgId.value) {
params.value.catgId = res.data[0].children.length ? res.data[0].children[0].id : res.data[0].id params.value.catgId = res.data[0].children.length ? res.data[0].children[0].id : res.data[0].id
} }
}) })
@ -249,6 +249,7 @@
} }
onShow( async() => { onShow( async() => {
console.log(level2.value)
await getMaxCatgId() await getMaxCatgId()
await catgTreeInit() await catgTreeInit()
init() init()

View File

@ -3,8 +3,6 @@ import { ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { import {
menuCategoryApi, menuCategoryApi,
msgListApi,
saveMsg,
appInfoApi, appInfoApi,
newAppApi newAppApi
} from '@/api/index.js'; } from '@/api/index.js';
@ -95,18 +93,6 @@ export const useScoketMsg = defineStore('scoketMsg', () => {
const chatMain = ref({}) const chatMain = ref({})
const getMsgList = (prodId) => {
const data = {
cusCode: onlyId.value,
prodId
}
return msgListApi(data).then(({data:res}) => {
chatMain.value = res.data
if (res.data.jsonArray) {
msgList.value = res.data.jsonArray
}
})
}
const scoketInit = () => { const scoketInit = () => {
scoket.value = uni.connectSocket({ scoket.value = uni.connectSocket({
@ -119,6 +105,9 @@ export const useScoketMsg = defineStore('scoketMsg', () => {
} }
}) })
scoket.value.onMessage((e) => { scoket.value.onMessage((e) => {
if (e.data === '连接成功') {
return
}
if (e.data.startsWith("C")) { if (e.data.startsWith("C")) {
count.value = e.data; count.value = e.data;
} }
@ -129,7 +118,6 @@ export const useScoketMsg = defineStore('scoketMsg', () => {
} else { } else {
msgList.value.push(JSON.parse(e.data)) msgList.value.push(JSON.parse(e.data))
msgCallback.value && msgCallback.value() msgCallback.value && msgCallback.value()
saveMsg({id:chatMain.value.id,jsonArray:msgList.value})
} }
}) })
scoket.value.onError((err) => { scoket.value.onError((err) => {
@ -153,16 +141,17 @@ export const useScoketMsg = defineStore('scoketMsg', () => {
} }
const closeScoket = () => { const closeScoket = () => {
if (scoket.value) { if (scoket.value) {
msgList.value = []
scoket.value.close() scoket.value.close()
scoket.value = null scoket.value = null
} }
} }
return { return {
scoket, scoket,
onlyId,
scoketInit, scoketInit,
closeScoket, closeScoket,
msgList, msgList,
getMsgList,
chatMain, chatMain,
send, send,
msgCallback msgCallback