parent
f22713668a
commit
3f88043322
@ -1,154 +1,162 @@ |
|||||||
<script setup> |
<script setup> |
||||||
import { RouterView, useRoute } from 'vue-router' |
import { RouterView, useRoute } from 'vue-router' |
||||||
import { onMounted, onUnmounted, provide } from 'vue' |
import { onMounted, onUnmounted, provide } from 'vue' |
||||||
import { storeToRefs } from 'pinia' |
import { storeToRefs } from 'pinia' |
||||||
import { useAppStore } from '@/store/app.js' |
import { useAppStore } from '@/store/app.js' |
||||||
// import { leaveProject } from '@/utils/api.js' |
// import { leaveProject } from '@/utils/api.js' |
||||||
import wx from 'weixin-js-sdk' |
import wx from 'weixin-js-sdk' |
||||||
const route = useRoute() |
const route = useRoute() |
||||||
import { isIOS, isAndroid, isPureHarmonyOS, handleFontSize, detectFontSize } from '@/utils/common' |
import { isIOS, isAndroid, isPureHarmonyOS, handleFontSize, detectFontSize } from '@/utils/common' |
||||||
console.log('navigator.userAgent', navigator.userAgent, navigator.userAgentData) |
console.log('navigator.userAgent', navigator.userAgent, navigator.userAgentData) |
||||||
window.wx = wx |
window.wx = wx |
||||||
|
|
||||||
// 全局 provide 接线:子组件统一通过 inject('appStore') / inject('xxx') 使用 store |
// 全局 provide 接线:子组件统一通过 inject('appStore') / inject('xxx') 使用 store |
||||||
const appStore = useAppStore() |
const appStore = useAppStore() |
||||||
const appStoreRefs = storeToRefs(appStore) |
const appStoreRefs = storeToRefs(appStore) |
||||||
provide('appStore', appStore) |
provide('appStore', appStore) |
||||||
Object.keys(appStoreRefs).forEach((key) => { |
// Object.keys(appStoreRefs).forEach((key) => { |
||||||
provide(key, appStoreRefs[key]) |
// provide(key, appStoreRefs[key]) |
||||||
}) |
// }) |
||||||
|
|
||||||
const handleGlobalBrowserExit = (reason, extra = {}) => { |
const handleGlobalBrowserExit = (reason, extra = {}) => { |
||||||
const payload = { |
const payload = { |
||||||
reason, |
reason, |
||||||
href: window.location.href, |
href: window.location.href, |
||||||
route: route.fullPath, |
route: route.fullPath, |
||||||
timestamp: Date.now(), |
timestamp: Date.now(), |
||||||
...extra, |
...extra, |
||||||
} |
} |
||||||
// leaveProject() |
// leaveProject() |
||||||
// alert('关闭页面') |
// alert('关闭页面') |
||||||
|
|
||||||
console.log('📴 全局检测到浏览器关闭/返回动作', payload) |
console.log('📴 全局检测到浏览器关闭/返回动作', payload) |
||||||
|
|
||||||
// 在这里统一处理关闭浏览器、手势返回、刷新离开等动作。 |
// 在这里统一处理关闭浏览器、手势返回、刷新离开等动作。 |
||||||
// 如果后续需要接业务方法,直接在这里调用即可。 |
// 如果后续需要接业务方法,直接在这里调用即可。 |
||||||
// example: |
// example: |
||||||
// someBusinessMethod(payload) |
// someBusinessMethod(payload) |
||||||
} |
} |
||||||
|
|
||||||
const handleBrowserPopState = () => { |
const handleBrowserPopState = () => { |
||||||
handleGlobalBrowserExit('popstate') |
handleGlobalBrowserExit('popstate') |
||||||
} |
} |
||||||
|
|
||||||
const handleBrowserPageHide = (event) => { |
const handleBrowserPageHide = (event) => { |
||||||
handleGlobalBrowserExit('pagehide', { |
handleGlobalBrowserExit('pagehide', { |
||||||
persisted: Boolean(event?.persisted), |
persisted: Boolean(event?.persisted), |
||||||
}) |
}) |
||||||
} |
} |
||||||
|
|
||||||
const handleBrowserBeforeUnload = () => { |
const handleBrowserBeforeUnload = () => { |
||||||
handleGlobalBrowserExit('beforeunload') |
handleGlobalBrowserExit('beforeunload') |
||||||
} |
} |
||||||
|
|
||||||
onMounted(() => { |
onMounted(() => { |
||||||
var html = document.getElementsByTagName('html')[0] |
var html = document.getElementsByTagName('html')[0] |
||||||
|
|
||||||
// 初始化 |
// 初始化 |
||||||
function init() { |
function init() { |
||||||
console.log('navigator.userAgent', navigator.userAgent, navigator.userAgentData) |
console.log('navigator.userAgent', navigator.userAgent, navigator.userAgentData) |
||||||
console.log('handleFontSize called with:', localStorage.getItem('bigFont')) |
console.log('handleFontSize called with:', localStorage.getItem('bigFont')) |
||||||
if (localStorage.getItem('bigFont') === 'true') |
if (localStorage.getItem('bigFont') === 'true') |
||||||
document.getElementsByTagName('html')[0].style.fontSize = '0.79333275px' |
document.getElementsByTagName('html')[0].style.fontSize = '0.79333275px' |
||||||
if (localStorage.getItem('localfontSize')) |
if (localStorage.getItem('localfontSize')) |
||||||
html.style.fontSize = localStorage.getItem('localfontSize') |
html.style.fontSize = localStorage.getItem('localfontSize') |
||||||
// 监听WeixinJSBridge |
// 监听WeixinJSBridge |
||||||
if (typeof WeixinJSBridge == 'object' && typeof WeixinJSBridge.invoke == 'function') { |
if (typeof WeixinJSBridge == 'object' && typeof WeixinJSBridge.invoke == 'function') { |
||||||
detectFontSize() |
detectFontSize() |
||||||
handleFontSize() |
handleFontSize() |
||||||
} else { |
} else { |
||||||
if (document.addEventListener) { |
if (document.addEventListener) { |
||||||
document.addEventListener( |
document.addEventListener( |
||||||
'WeixinJSBridgeReady', |
'WeixinJSBridgeReady', |
||||||
function () { |
function () { |
||||||
detectFontSize() |
detectFontSize() |
||||||
handleFontSize() |
handleFontSize() |
||||||
}, |
}, |
||||||
false |
false |
||||||
) |
) |
||||||
} else if (document.attachEvent) { |
} else if (document.attachEvent) { |
||||||
document.attachEvent('WeixinJSBridgeReady', function () { |
document.attachEvent('WeixinJSBridgeReady', function () { |
||||||
detectFontSize() |
detectFontSize() |
||||||
handleFontSize() |
handleFontSize() |
||||||
}) |
}) |
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
init() |
init() |
||||||
console.log(isPureHarmonyOS(), 'isPureHarmonyOS') |
console.log(isPureHarmonyOS(), 'isPureHarmonyOS') |
||||||
|
window.onresize = function () { |
||||||
window.onresize = function () { |
if (!isIOS() && !isAndroid() && !isPureHarmonyOS()) init() |
||||||
if (!isIOS() && !isAndroid() && !isPureHarmonyOS()) init() |
} |
||||||
} |
|
||||||
|
window.addEventListener('popstate', handleBrowserPopState) |
||||||
window.addEventListener('popstate', handleBrowserPopState) |
window.addEventListener('pagehide', handleBrowserPageHide) |
||||||
window.addEventListener('pagehide', handleBrowserPageHide) |
window.addEventListener('beforeunload', handleBrowserBeforeUnload) |
||||||
window.addEventListener('beforeunload', handleBrowserBeforeUnload) |
}) |
||||||
}) |
|
||||||
|
onUnmounted(() => { |
||||||
onUnmounted(() => { |
window.removeEventListener('popstate', handleBrowserPopState) |
||||||
window.removeEventListener('popstate', handleBrowserPopState) |
window.removeEventListener('pagehide', handleBrowserPageHide) |
||||||
window.removeEventListener('pagehide', handleBrowserPageHide) |
window.removeEventListener('beforeunload', handleBrowserBeforeUnload) |
||||||
window.removeEventListener('beforeunload', handleBrowserBeforeUnload) |
}) |
||||||
}) |
</script> |
||||||
</script> |
|
||||||
|
<template> |
||||||
<template> |
<div class="app-wrapper opacity"> |
||||||
<div id="app" class="app-wrapper opacity"> |
<RouterView v-slot="{ Component, route }"> |
||||||
<RouterView v-slot="{ Component }"> |
<keep-alive> |
||||||
<keep-alive include="chat"> |
<component |
||||||
<component :is="Component" /> |
:is="Component" |
||||||
|
v-if="Component && route.meta.keepAlive" |
||||||
|
:key="route.name" |
||||||
|
/> |
||||||
</keep-alive> |
</keep-alive> |
||||||
|
<component |
||||||
|
:is="Component" |
||||||
|
v-if="Component && !route.meta.keepAlive" |
||||||
|
:key="route.name" |
||||||
|
/> |
||||||
</RouterView> |
</RouterView> |
||||||
</div> |
</div> |
||||||
</template> |
</template> |
||||||
|
|
||||||
<style scoped> |
<style scoped> |
||||||
.header-box { |
.header-box { |
||||||
width: 100%; |
width: 100%; |
||||||
height: 88rem; |
height: 88rem; |
||||||
display: flex; |
display: flex; |
||||||
align-items: center; |
align-items: center; |
||||||
background: #e8f2ff; |
background: #e8f2ff; |
||||||
padding: 0 24rem 0 54rem; |
padding: 0 24rem 0 54rem; |
||||||
} |
} |
||||||
|
|
||||||
.view { |
.view { |
||||||
width: 100vw; |
width: 100vw; |
||||||
height: 100vh; |
height: 100vh; |
||||||
overflow: hidden; |
overflow: hidden; |
||||||
} |
} |
||||||
|
|
||||||
.left-box { |
.left-box { |
||||||
display: flex; |
display: flex; |
||||||
align-items: center; |
align-items: center; |
||||||
} |
} |
||||||
|
|
||||||
.back-icon { |
.back-icon { |
||||||
display: block; |
display: block; |
||||||
width: 18rem; |
width: 18rem; |
||||||
height: 32rem; |
height: 32rem; |
||||||
} |
} |
||||||
|
|
||||||
.back-icon img { |
.back-icon img { |
||||||
width: 100%; |
width: 100%; |
||||||
height: 100%; |
height: 100%; |
||||||
} |
} |
||||||
</style> |
</style> |
||||||
<style scoped lang="scss"> |
<style scoped lang="scss"> |
||||||
#app { |
#app { |
||||||
.con { |
.con { |
||||||
color: red; |
color: red; |
||||||
} |
} |
||||||
} |
} |
||||||
</style> |
</style> |
||||||
|
|||||||
|
After Width: | Height: | Size: 9.4 KiB |
@ -1,301 +1,340 @@ |
|||||||
<script setup> |
<script setup> |
||||||
import { ref, onMounted, computed, inject } from 'vue'; |
import { ref, onMounted, onActivated, computed, inject } from 'vue'; |
||||||
import { Post } from '@/utils/https' |
import { Post } from '@/utils/https' |
||||||
import { messageSend } from '@/utils/api' |
import { messageSend } from '@/utils/api' |
||||||
import { getHiddenProp, getVisibilityState, decryptByVersionNo1, isSit, Encrypt, isDev, isProd } from "@/utils"; |
import { getHiddenProp, getVisibilityState, decryptByVersionNo1, isSit, Encrypt, isDev, isProd } from "@/utils"; |
||||||
const store = inject('appStore', null) |
const store = inject('appStore', null) |
||||||
const businessHandleInfo = ref({}) |
const businessHandleInfo = ref({}) |
||||||
const orderCount = ref(0) |
const orderCount = ref(0) |
||||||
const abstractList = computed(() => [ |
const emit = defineEmits(['ready', 'businessClick']) |
||||||
{ |
const abstractList = computed(() => [ |
||||||
title: '保障状态', |
{ |
||||||
num: orderCount.value, |
title: '保障状态', |
||||||
text: '保单保障中', |
num: orderCount.value, |
||||||
unit: '张', |
text: '保单保障中', |
||||||
name: '查保单', |
unit: '张', |
||||||
btnText: '查保单', |
name: '查保单', |
||||||
btnBg: 'linear-gradient(90deg, #025cea 0%, #0595f6 100%)', |
btnText: '查保单', |
||||||
}, |
btnBg: 'linear-gradient(90deg, #025cea 0%, #0595f6 100%)', |
||||||
{ |
}, |
||||||
title: '待办任务', |
{ |
||||||
num: businessHandleInfo.value?.contents?.length || 0, |
title: '待办任务', |
||||||
text: '待办需处理', |
num: businessHandleInfo.value?.contents?.length || 0, |
||||||
unit: '个', |
text: '待办需处理', |
||||||
name: '去处理', |
unit: '个', |
||||||
btnText: '去处理', |
name: '去处理', |
||||||
btnBg: 'linear-gradient(111deg, #ff752a 44%, #feb52d 136%)', |
btnText: '去处理', |
||||||
}, |
btnBg: 'linear-gradient(111deg, #ff752a 44%, #feb52d 136%)', |
||||||
{ |
}, |
||||||
title: '权益领取', |
{ |
||||||
num: 0, |
title: '权益领取', |
||||||
text: '生存金权益', |
num: 0, |
||||||
unit: '项', |
text: '生存金权益', |
||||||
name: '去领取', |
unit: '项', |
||||||
btnText: '去领取', |
name: '去领取', |
||||||
btnBg: 'linear-gradient(261deg, #2ed0c6 3%, #08b7ac 65%)', |
btnText: '去领取', |
||||||
}, |
btnBg: 'linear-gradient(261deg, #2ed0c6 3%, #08b7ac 65%)', |
||||||
].filter(item => item.num > 0)) |
}, |
||||||
const businessHandle = () => { |
].filter(item => item.num > 0)) |
||||||
if ( |
const businessHandle = (userId) => { |
||||||
store.source == "95270000" || |
if ( |
||||||
store.source == "95320000" || |
store.source == "95270000" || |
||||||
store.source == "95350000" || |
store.source == "95320000" || |
||||||
store.source == "96060000" |
store.source == "95350000" || |
||||||
) { |
store.source == "96060000" |
||||||
Post("notify/info", { userInfoId: store.userId }) |
) { |
||||||
.then((res) => { |
return Post("notify/info", { userInfoId: userId }) |
||||||
if (res.data?.contents.length > 0) { |
.then((res) => { |
||||||
businessHandleInfo.value = res.data; |
if (res.data?.contents?.length > 0) { |
||||||
} |
businessHandleInfo.value = res.data |
||||||
}) |
} else { |
||||||
.catch((error) => { |
businessHandleInfo.value = {} |
||||||
console.log(error); |
} |
||||||
}); |
store?.setBusinessHandleInfo?.(businessHandleInfo.value) |
||||||
} |
}) |
||||||
} |
.catch((error) => { |
||||||
const isIdentityNo = (value) => /^\d{15}$|^\d{17}[\dXx]$/.test(String(value || '').trim()) |
console.log(error); |
||||||
|
}); |
||||||
// 与 liics 一致:明文身份证来自解密 userInfo.pid(encryptPid 是给外部系统用的密文,不能直接解) |
} |
||||||
const getIdentityCardno = () => { |
return Promise.resolve() |
||||||
const versionNo = store.userInfo?.versionNo1 || '' |
} |
||||||
const pidCipher = store.userInfo?.pid || '' |
|
||||||
if (!versionNo || !pidCipher) return '' |
const businessClick = () => { |
||||||
|
emit('businessClick') |
||||||
const identityCardno = decryptByVersionNo1(versionNo, pidCipher) |
} |
||||||
console.log(decryptByVersionNo1(versionNo, '0FLzZwhD08nkUE4BjRGOSEri4KWO'),id); |
const isIdentityNo = (value) => /^\d{15}$|^\d{17}[\dXx]$/.test(String(value || '').trim()) |
||||||
return isIdentityNo(identityCardno) ? identityCardno.trim() : '' |
|
||||||
} |
// 与 liics 一致:明文身份证来自解密 userInfo.pid(encryptPid 是给外部系统用的密文,不能直接解) |
||||||
|
const getIdentityCardno = () => { |
||||||
const getOrderCount = () => { |
const versionNo = store.userInfo?.versionNo1 || '' |
||||||
try { |
const pidCipher = store.userInfo?.pid || '' |
||||||
const identityCardno = getIdentityCardno() |
if (!versionNo || !pidCipher) return '' |
||||||
if (!identityCardno) { |
|
||||||
console.warn('证件号解密失败', { |
const identityCardno = decryptByVersionNo1(versionNo, pidCipher) |
||||||
hasPid: Boolean(store.userInfo?.pid), |
console.log('decrypt pid =>', JSON.stringify(identityCardno)) |
||||||
hasVersionNo1: Boolean(store.userInfo?.versionNo1), |
return isIdentityNo(identityCardno) ? identityCardno.trim() : '' |
||||||
}) |
} |
||||||
return |
|
||||||
} |
const getOrderCount = () => { |
||||||
|
try { |
||||||
Post('policy/queryCount', { |
const identityCardno = getIdentityCardno() |
||||||
dentityCardno: identityCardno, |
if (!identityCardno) { |
||||||
userId: store.userId |
console.warn('证件号解密失败', { |
||||||
}).then(res => { |
hasPid: Boolean(store.userInfo?.pid), |
||||||
orderCount.value = res?.data?.policyCount || 0 |
hasVersionNo1: Boolean(store.userInfo?.versionNo1), |
||||||
}) |
}) |
||||||
} catch (error) { |
return Promise.resolve() |
||||||
console.log(error) |
} |
||||||
} |
|
||||||
} |
return Post('policy/queryCount', { |
||||||
const toDetail = (record) => { |
dentityCardno: identityCardno, |
||||||
const text = record?.name |
userId: store.userId |
||||||
console.log('text', text); |
}).then(res => { |
||||||
if (!text) return |
orderCount.value = res?.data?.policyCount || 0 |
||||||
messageSend(text).catch((err) => { |
}).catch((error) => { |
||||||
console.log(err) |
console.log(error) |
||||||
}) |
}) |
||||||
} |
} catch (error) { |
||||||
onMounted(async () => { |
console.log(error) |
||||||
businessHandle() |
return Promise.resolve() |
||||||
getOrderCount() |
} |
||||||
}) |
} |
||||||
</script> |
const toDetail = (record) => { |
||||||
<template> |
if (record.title === '待办任务') { |
||||||
<div class="abstract-con" v-if="abstractList.length"> |
businessClick() |
||||||
<div class="title"> |
} |
||||||
<span>今日皮卡丘摘要</span><img src="@/assets/images/chat/star.svg" alt="" srcset="" /> |
if (record.title === '保障状态') { |
||||||
</div> |
// 只把问题写入对话气泡,不走对话接口 |
||||||
<div class="list"> |
store.addSendMessageList({ msgText: record.name, reqAndResType: '1', sendLoading: false }) |
||||||
<div :class="`item ${(abstractList || []).length === 1 ? 'singleItem' : ''}`" |
} |
||||||
v-for="(item, index) in abstractList || []" :key="index"> |
} |
||||||
<div> |
const refreshAbstractData = async () => { |
||||||
<div class="title">{{ item.title }}</div> |
await Promise.all([businessHandle(store?.userId), getOrderCount()]) |
||||||
<div class="content" :style="{ display: (abstractList || []).length > 2 ? 'block' : 'flex' }"> |
} |
||||||
<div class="nums"> |
|
||||||
<div class="num"> |
const hasLoadedOnce = ref(false) |
||||||
{{ item.num }}<span>{{ item.unit }}</span> |
|
||||||
</div> |
onMounted(async () => { |
||||||
</div> |
try { |
||||||
<div class="text" :style="{ marginTop: (abstractList || []).length > 2 ? '8rem' : '0' }"> |
await refreshAbstractData() |
||||||
{{ item.text }} |
} finally { |
||||||
</div> |
hasLoadedOnce.value = true |
||||||
</div> |
emit('ready') |
||||||
</div> |
} |
||||||
<div class="btn" :style="{ background: item.btnBg }" @click="toDetail(item)">{{ item.btnText }}</div> |
}) |
||||||
</div> |
|
||||||
</div> |
// keep-alive 返回 chat 时刷新待办和保单数量 |
||||||
</div> |
onActivated(async () => { |
||||||
</template> |
if (!hasLoadedOnce.value) return |
||||||
<style lang="scss" scoped> |
await refreshAbstractData() |
||||||
.abstract-con { |
}) |
||||||
position: relative; |
</script> |
||||||
z-index: 1; |
<template> |
||||||
flex-direction: column; |
<div class="abstract-con" v-if="abstractList.length"> |
||||||
justify-content: center; |
<div class="title"> |
||||||
padding: 10rem 12rem; |
<span>今日皮卡丘摘要</span><img src="@/assets/images/chat/star.svg" alt="" srcset="" /> |
||||||
gap: 12rem; |
</div> |
||||||
align-self: stretch; |
<div class="list"> |
||||||
margin-top: 10rem; |
<div |
||||||
background: linear-gradient(77deg, #fcfdfd80 -1%, #f5f7fee6 99%); |
:class="`item ${(abstractList || []).length === 1 ? 'singleItem' : ''}`" |
||||||
|
v-for="(item, index) in abstractList || []" |
||||||
box-sizing: border-box; |
:key="index" |
||||||
border: 1rem solid rgba(255, 255, 255, 0.9); |
> |
||||||
|
<div> |
||||||
backdrop-filter: blur(10rem); |
<div class="title">{{ item.title }}</div> |
||||||
border-radius: 12rem; |
<div |
||||||
|
class="content" |
||||||
.title { |
:style="{ display: (abstractList || []).length > 2 ? 'block' : 'flex' }" |
||||||
font-family: PingFang SC; |
> |
||||||
font-size: 16rem; |
<div class="nums"> |
||||||
font-weight: 500; |
<div class="num"> |
||||||
line-height: normal; |
{{ item.num }}<span>{{ item.unit }}</span> |
||||||
letter-spacing: 0rem; |
</div> |
||||||
|
</div> |
||||||
/* 科个中性/正文-标题 17204D */ |
<div |
||||||
/* 样式描述:用于正文标题 */ |
class="text" |
||||||
color: #17204d; |
:style="{ marginTop: (abstractList || []).length > 2 ? '8rem' : '0' }" |
||||||
|
> |
||||||
img { |
{{ item.text }} |
||||||
width: 20rem; |
</div> |
||||||
margin-left: 4.6rem; |
</div> |
||||||
} |
</div> |
||||||
} |
<div class="btn" :style="{ background: item.btnBg }" @click="toDetail(item)"> |
||||||
|
{{ item.btnText }} |
||||||
.list { |
</div> |
||||||
margin-top: 13rem; |
</div> |
||||||
display: flex; |
</div> |
||||||
gap: 8rem; |
</div> |
||||||
|
</template> |
||||||
.item { |
<style lang="scss" scoped> |
||||||
display: flex; |
.abstract-con { |
||||||
flex-direction: column; |
position: relative; |
||||||
gap: 12rem; |
z-index: 1; |
||||||
flex: 1; |
flex-direction: column; |
||||||
border-radius: 8rem; |
justify-content: center; |
||||||
display: flex; |
padding: 10rem 12rem; |
||||||
flex-direction: column; |
gap: 12rem; |
||||||
padding: 12rem; |
align-self: stretch; |
||||||
gap: 12rem; |
background: linear-gradient(77deg, #fcfdfd80 -1%, #f5f7fee6 99%); |
||||||
|
margin-bottom: 16rem; |
||||||
background: #fcfdfd; |
box-sizing: border-box; |
||||||
|
border: 1rem solid rgba(255, 255, 255, 0.9); |
||||||
box-shadow: 0rem 4rem 10rem 0rem #e7effd; |
|
||||||
|
backdrop-filter: blur(10rem); |
||||||
.title { |
border-radius: 12rem; |
||||||
margin-left: 18rem; |
|
||||||
font-family: PingFang SC; |
.title { |
||||||
font-size: 12rem; |
font-family: PingFang SC; |
||||||
font-weight: normal; |
font-size: 16rem; |
||||||
line-height: 16rem; |
font-weight: 500; |
||||||
letter-spacing: 0rem; |
line-height: normal; |
||||||
|
letter-spacing: 0rem; |
||||||
/* 科个中性/正文-副标题 7E849F */ |
|
||||||
color: #7e849f; |
/* 科个中性/正文-标题 17204D */ |
||||||
} |
/* 样式描述:用于正文标题 */ |
||||||
|
color: #17204d; |
||||||
.content { |
|
||||||
.nums { |
img { |
||||||
font-family: DIN-Medium; |
width: 20rem; |
||||||
font-size: 24rem; |
margin-left: 4.6rem; |
||||||
font-weight: bold; |
} |
||||||
line-height: 24rem; |
} |
||||||
letter-spacing: 0rem; |
|
||||||
|
.list { |
||||||
font-variation-settings: 'opsz' auto; |
margin-top: 13rem; |
||||||
color: #17204d; |
display: flex; |
||||||
|
gap: 8rem; |
||||||
.num { |
|
||||||
display: flex; |
.item { |
||||||
align-items: flex-end; |
display: flex; |
||||||
} |
flex-direction: column; |
||||||
|
gap: 12rem; |
||||||
span { |
flex: 1; |
||||||
font-family: PingFang SC; |
border-radius: 8rem; |
||||||
font-size: 12rem; |
display: flex; |
||||||
font-weight: normal; |
flex-direction: column; |
||||||
line-height: 16rem; |
padding: 12rem; |
||||||
letter-spacing: 0rem; |
gap: 12rem; |
||||||
margin: 0 3rem 0 3rem; |
|
||||||
|
background: #fcfdfd; |
||||||
/* 中性/重要文本色 */ |
|
||||||
/* 样式描述:17204D */ |
box-shadow: 0rem 4rem 10rem 0rem #e7effd; |
||||||
color: #17204d; |
|
||||||
} |
.title { |
||||||
} |
margin-left: 18rem; |
||||||
|
font-family: PingFang SC; |
||||||
.text { |
font-size: 12rem; |
||||||
font-family: PingFang SC; |
font-weight: normal; |
||||||
font-size: 12rem; |
line-height: 16rem; |
||||||
font-weight: normal; |
letter-spacing: 0rem; |
||||||
line-height: 16rem; |
|
||||||
letter-spacing: 0rem; |
/* 科个中性/正文-副标题 7E849F */ |
||||||
|
color: #7e849f; |
||||||
/* 中性/次要文本色 */ |
} |
||||||
/* 样式描述:7E849F */ |
|
||||||
color: #7e849f; |
.content { |
||||||
align-self: flex-end; |
.nums { |
||||||
} |
font-family: DIN-Medium; |
||||||
} |
font-size: 24rem; |
||||||
|
font-weight: bold; |
||||||
.btn { |
line-height: 24rem; |
||||||
border-radius: 100rem; |
letter-spacing: 0rem; |
||||||
font-family: PingFang SC; |
|
||||||
font-size: 14rem; |
font-variation-settings: 'opsz' auto; |
||||||
font-weight: 500; |
color: #17204d; |
||||||
line-height: 19rem; |
|
||||||
text-align: center; |
.num { |
||||||
letter-spacing: 0rem; |
display: flex; |
||||||
|
align-items: flex-end; |
||||||
color: #ffffff; |
} |
||||||
padding: 4rem 12rem; |
|
||||||
height: 28rem; |
span { |
||||||
cursor: pointer; |
font-family: PingFang SC; |
||||||
} |
font-size: 12rem; |
||||||
} |
font-weight: normal; |
||||||
|
line-height: 16rem; |
||||||
.singleItem { |
letter-spacing: 0rem; |
||||||
display: flex; |
margin: 0 3rem 0 3rem; |
||||||
flex-direction: row; |
|
||||||
justify-content: space-between; |
/* 中性/重要文本色 */ |
||||||
align-items: center; |
/* 样式描述:17204D */ |
||||||
|
color: #17204d; |
||||||
>div { |
} |
||||||
margin-left: 36rem; |
} |
||||||
|
|
||||||
.title { |
.text { |
||||||
font-family: PingFang SC; |
font-family: PingFang SC; |
||||||
font-size: 14rem; |
font-size: 12rem; |
||||||
font-weight: 500; |
font-weight: normal; |
||||||
line-height: normal; |
line-height: 16rem; |
||||||
letter-spacing: 0rem; |
letter-spacing: 0rem; |
||||||
margin-left: 0; |
|
||||||
|
/* 中性/次要文本色 */ |
||||||
/* 科个中性/正文-标题 17204D */ |
/* 样式描述:7E849F */ |
||||||
/* 样式描述:用于正文标题 */ |
color: #7e849f; |
||||||
color: #17204d; |
align-self: flex-end; |
||||||
margin-bottom: 4rem; |
} |
||||||
} |
} |
||||||
|
|
||||||
.content { |
.btn { |
||||||
.nums { |
border-radius: 100rem; |
||||||
font-size: 12rem; |
font-family: PingFang SC; |
||||||
font-weight: normal; |
font-size: 14rem; |
||||||
line-height: 16rem; |
font-weight: 500; |
||||||
letter-spacing: 0rem; |
line-height: 19rem; |
||||||
|
text-align: center; |
||||||
z-index: 1; |
letter-spacing: 0rem; |
||||||
font-family: PingFang SC; |
|
||||||
font-weight: 500; |
color: #ffffff; |
||||||
color: #17204d; |
padding: 4rem 12rem; |
||||||
|
height: 28rem; |
||||||
span { |
cursor: pointer; |
||||||
color: #7e849f; |
} |
||||||
margin-left: 0; |
} |
||||||
} |
|
||||||
} |
.singleItem { |
||||||
} |
display: flex; |
||||||
} |
flex-direction: row; |
||||||
} |
justify-content: space-between; |
||||||
} |
align-items: center; |
||||||
} |
|
||||||
</style> |
> div { |
||||||
|
margin-left: 36rem; |
||||||
|
|
||||||
|
.title { |
||||||
|
font-family: PingFang SC; |
||||||
|
font-size: 14rem; |
||||||
|
font-weight: 500; |
||||||
|
line-height: normal; |
||||||
|
letter-spacing: 0rem; |
||||||
|
margin-left: 0; |
||||||
|
|
||||||
|
/* 科个中性/正文-标题 17204D */ |
||||||
|
/* 样式描述:用于正文标题 */ |
||||||
|
color: #17204d; |
||||||
|
margin-bottom: 4rem; |
||||||
|
} |
||||||
|
|
||||||
|
.content { |
||||||
|
.nums { |
||||||
|
font-size: 12rem; |
||||||
|
font-weight: normal; |
||||||
|
line-height: 16rem; |
||||||
|
letter-spacing: 0rem; |
||||||
|
|
||||||
|
z-index: 1; |
||||||
|
font-family: PingFang SC; |
||||||
|
font-weight: 500; |
||||||
|
color: #17204d; |
||||||
|
|
||||||
|
span { |
||||||
|
color: #7e849f; |
||||||
|
margin-left: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
||||||
|
|||||||
@ -1,168 +1,211 @@ |
|||||||
<template> |
<template> |
||||||
<div> |
<div> |
||||||
<van-swipe style="height:30rem;margin-top:10rem" class="businessBox" vertical :scrollable="false" :autoplay="3000" |
<!-- <van-swipe style="height:30rem;margin-top:10rem" class="businessBox" vertical :scrollable="false" :autoplay="3000" |
||||||
:show-indicators="false"> |
:show-indicators="false"> |
||||||
<van-swipe-item @click="swiperClick" v-for="(item, index) in businessHandleInfo.contents" :key="index"> |
<van-swipe-item @click="swiperClick" v-for="(item, index) in businessHandleInfo.contents" :key="index"> |
||||||
<div class="item"> |
<div class="item"> |
||||||
<img :src="getIconUrl(item.icon)" alt="" style="width:30rem;height:30rem;"> |
<img :src="getIconUrl(item.icon)" alt="" style="width:30rem;height:30rem;"> |
||||||
<div class="item-content"> |
<div class="item-content"> |
||||||
<div class="line">{{ item.name }}</div> |
<div class="line">{{ item.name }}</div> |
||||||
<van-icon name="arrow-down" /> |
<van-icon name="arrow-down" /> |
||||||
</div> |
</div> |
||||||
</div> |
</div> |
||||||
</van-swipe-item> |
</van-swipe-item> |
||||||
</van-swipe> |
</van-swipe> --> |
||||||
|
<van-popup |
||||||
<van-popup get-container="#app" v-model:show="Popupshow" round position="bottom" |
v-model:show="Popupshow" |
||||||
:style="{ padding: '15rem', boxSizing: ' border-box' }"> |
teleport="body" |
||||||
<div class="displayFlex"> |
round |
||||||
<div style="font-size: 13rem;color: #878D99;"> |
position="bottom" |
||||||
您有{{ businessHandleInfo.contents.length }}个待办{{ businessHandleInfo.tip }}</div> |
closeable |
||||||
<van-icon name="close" color="#5A9CFF" @click="Popupshow = false" /> |
:z-index="3000" |
||||||
</div> |
> |
||||||
<div class="popupContent"> |
<div class="displayFlex"> |
||||||
<div class="item popupContentItem" v-for="(item, index) in businessHandleInfo.contents" :key="index" |
<div class="title">您有{{ displayInfo?.contents?.length || 0 }}个待办</div> |
||||||
@click="richCallAnswer(item)"> |
<div class="popupContent"> |
||||||
<img :src="getIconUrl(item.icon)" alt="" style="width:30rem;height:30rem;"> |
<div |
||||||
<div class="item-content"> |
class="item popupContentItem" |
||||||
<div>{{ item.name }}</div> |
v-for="(item, index) in displayInfo.contents || []" |
||||||
<van-icon name="arrow" color="#5A9CFF" /> |
:key="index" |
||||||
</div> |
@click="richCallAnswer(item)" |
||||||
</div> |
> |
||||||
</div> |
<img |
||||||
</van-popup> |
src="@/assets/images/chat/todo-icon.svg" |
||||||
</div> |
alt="" |
||||||
</template> |
style="width: 22rem; height: 22rem" |
||||||
|
/> |
||||||
<script setup> |
<div class="item-content"> |
||||||
import { ref, inject, computed } from 'vue' |
<div>{{ item.name }}</div> |
||||||
import { Icon, Swipe, SwipeItem, Popup } from 'vant' |
<van-icon name="arrow" color="#5A9CFF" /> |
||||||
|
</div> |
||||||
defineProps({ |
</div> |
||||||
businessHandleInfo: { type: Object, default: () => ({}) } |
</div> |
||||||
}) |
</div> |
||||||
|
</van-popup> |
||||||
const store = inject('appStore', null) |
</div> |
||||||
const userId = inject('userId', ref('')) |
</template> |
||||||
const mescrollContent = inject('mescrollContent', ref(null)) |
|
||||||
const manualService = inject('manualService', ref('1')) |
<script setup> |
||||||
|
import { ref, inject, computed, watch } from 'vue' |
||||||
const Popupshow = ref(false) |
import { Icon, Swipe, SwipeItem, Popup } from 'vant' |
||||||
const isBtnsubmit = ref(true) |
|
||||||
|
const props = defineProps({ |
||||||
function getIconUrl(icon) { |
businessHandleInfo: { type: Object, default: () => ({}) }, |
||||||
try { |
autoOpen: { type: Boolean, default: true }, |
||||||
return require(`../assets/images/${icon}.png`) |
}) |
||||||
} catch (e) { |
|
||||||
return '' |
const store = inject('appStore', null) |
||||||
} |
const userId = inject('userId', ref('')) |
||||||
} |
const mescrollContent = inject('mescrollContent', ref(null)) |
||||||
|
const manualService = inject('manualService', ref('1')) |
||||||
function swiperClick() { |
|
||||||
Popupshow.value = true |
const Popupshow = ref(false) |
||||||
} |
const isBtnsubmit = ref(true) |
||||||
|
const hasAutoOpened = ref(false) |
||||||
function richCallAnswer(item) { |
|
||||||
const text = item.name |
const displayInfo = computed(() => { |
||||||
const serialNumber = item.serialNumber |
const fromProp = props.businessHandleInfo |
||||||
const sessionId = item.sessionId |
if (fromProp && Array.isArray(fromProp.contents) && fromProp.contents.length) return fromProp |
||||||
|
return store?.businessHandleInfo || {} |
||||||
const mdParmas = { |
}) |
||||||
userInfoId: userId.value, |
|
||||||
sessionId, |
function getIconUrl(icon) { |
||||||
serialNumber, |
try { |
||||||
clickTime: new Date().getTime() |
return new URL(`../assets/images/${icon}.png`, import.meta.url).href |
||||||
} |
} catch (e) { |
||||||
store?.dispatch?.('updateClickTime', mdParmas).catch(err => { |
return '' |
||||||
console.error(err) |
} |
||||||
}) |
} |
||||||
|
|
||||||
let sendParmas = { |
function swiperClick() { |
||||||
cmd: 'business-handle', |
Popupshow.value = true |
||||||
reqAndResType: '1', |
} |
||||||
msgText: '&' + text + '&', |
|
||||||
intentId: '', |
function richCallAnswer(item) { |
||||||
msgSource: manualService.value, |
const text = item.name |
||||||
questionType: 6 |
const serialNumber = item.serialNumber |
||||||
} |
const sessionId = item.sessionId |
||||||
|
|
||||||
if (isBtnsubmit.value) { |
const mdParmas = { |
||||||
isBtnsubmit.value = false |
userInfoId: userId.value, |
||||||
Popupshow.value = false |
sessionId, |
||||||
scrollTopBody() |
serialNumber, |
||||||
store?.dispatch?.('sendingRobot', sendParmas).then(() => { |
clickTime: new Date().getTime() |
||||||
isBtnsubmit.value = true |
} |
||||||
}).catch(err => { |
store?.dispatch?.('updateClickTime', mdParmas).catch(err => { |
||||||
isBtnsubmit.value = true |
console.error(err) |
||||||
console.log(err) |
}) |
||||||
}) |
|
||||||
} |
let sendParmas = { |
||||||
} |
cmd: 'business-handle', |
||||||
|
reqAndResType: '1', |
||||||
function scrollTopBody() { |
msgText: '&' + text + '&', |
||||||
setTimeout(() => { |
intentId: '', |
||||||
try { |
msgSource: manualService.value, |
||||||
if (mescrollContent.value) { |
questionType: 6 |
||||||
mescrollContent.value.scrollTop = mescrollContent.value.scrollHeight || 0 |
} |
||||||
} |
|
||||||
} catch (error) { |
if (isBtnsubmit.value) { |
||||||
console.log(error.message) |
isBtnsubmit.value = false |
||||||
} |
Popupshow.value = false |
||||||
}, 300) |
scrollTopBody() |
||||||
} |
const sending = store?.sendingRobot?.(sendParmas) || store?.dispatch?.('sendingRobot', sendParmas) |
||||||
</script> |
Promise.resolve(sending).then(() => { |
||||||
|
isBtnsubmit.value = true |
||||||
<style scoped> |
}).catch(err => { |
||||||
.businessBox { |
isBtnsubmit.value = true |
||||||
background: #fff; |
console.log(err) |
||||||
padding: 10rem; |
}) |
||||||
border-radius: 16rem 16rem 16rem 2rem; |
} |
||||||
} |
} |
||||||
|
|
||||||
.item { |
function scrollTopBody() { |
||||||
display: flex; |
setTimeout(() => { |
||||||
align-items: center; |
try { |
||||||
justify-content: space-around; |
if (mescrollContent.value) { |
||||||
} |
mescrollContent.value.scrollTop = mescrollContent.value.scrollHeight || 0 |
||||||
|
} |
||||||
.item>img { |
} catch (error) { |
||||||
width: 30rem; |
console.log(error.message) |
||||||
height: 30rem; |
} |
||||||
margin-right: 10rem; |
}, 300) |
||||||
} |
} |
||||||
|
defineExpose({ |
||||||
.item-content { |
swiperClick |
||||||
flex: 1; |
}) |
||||||
display: flex; |
</script> |
||||||
align-items: center; |
|
||||||
justify-content: space-between; |
<style scoped lang="scss"> |
||||||
font-size: 15rem; |
.businessBox { |
||||||
} |
background: #fff; |
||||||
|
padding: 10rem; |
||||||
.line { |
border-radius: 16rem 16rem 16rem 2rem; |
||||||
font-size: 14rem; |
} |
||||||
} |
|
||||||
|
.item { |
||||||
.displayFlex { |
display: flex; |
||||||
display: flex; |
justify-content: space-around; |
||||||
align-items: center; |
} |
||||||
justify-content: space-between; |
|
||||||
} |
.item > img { |
||||||
|
width: 30rem; |
||||||
.popupContent { |
height: 30rem; |
||||||
min-height: 180rem; |
margin-right: 10rem; |
||||||
max-height: 290rem; |
} |
||||||
overflow: auto; |
|
||||||
} |
.item-content { |
||||||
|
flex: 1; |
||||||
.popupContentItem { |
display: flex; |
||||||
height: 50rem; |
justify-content: space-between; |
||||||
background: #FFFFFF; |
font-size: 15rem; |
||||||
border: 1rem solid #F1F3F6; |
i{ |
||||||
padding: 13rem; |
padding-top: 4rem; |
||||||
box-shadow: 0 2rem 8rem 0 rgba(229, 234, 237, 0.50); |
} |
||||||
border-radius: 8rem; |
} |
||||||
box-sizing: border-box; |
|
||||||
margin: 7rem 5rem; |
.line { |
||||||
} |
font-size: 14rem; |
||||||
</style> |
} |
||||||
|
|
||||||
|
.displayFlex { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
border-radius: 16rem 16rem 0rem 0rem; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: center; |
||||||
|
padding: 16rem 16rem 0rem 16rem; |
||||||
|
gap: 24rem; |
||||||
|
width: 100vw; |
||||||
|
background: linear-gradient(180deg, #f0f8ff 0%, #f6f9ff 100%); |
||||||
|
.title { |
||||||
|
font-family: PingFang SC; |
||||||
|
font-size: 16rem; |
||||||
|
font-weight: 500; |
||||||
|
line-height: normal; |
||||||
|
text-align: center; |
||||||
|
letter-spacing: 0rem; |
||||||
|
|
||||||
|
font-variation-settings: 'opsz' auto; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.popupContent { |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
max-height: 300rem; |
||||||
|
overflow: auto; |
||||||
|
width: 100%; |
||||||
|
gap: 12rem; |
||||||
|
padding-bottom: 12rem; |
||||||
|
} |
||||||
|
|
||||||
|
.popupContentItem { |
||||||
|
background: #ffffff; |
||||||
|
border: 1px solid rgba(255, 255, 255, 0.9); |
||||||
|
padding: 12px; |
||||||
|
gap: 12px; |
||||||
|
border-radius: 12px; |
||||||
|
} |
||||||
|
</style> |
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,457 +1,457 @@ |
|||||||
<template> |
<template> |
||||||
<div class="text-template-box" v-if="introduce"> |
<div class="text-template-box" v-if="introduce"> |
||||||
<div |
<div |
||||||
class="question-answer-con" |
class="question-answer-con" |
||||||
v-if="introduce" |
v-if="introduce" |
||||||
ref="desc" |
ref="desc" |
||||||
:class="showTotal || heightMax == 'autoHeight' ? 'total-introduce' : 'detailed-introduce'" |
:class="showTotal || heightMax == 'autoHeight' ? 'total-introduce' : 'detailed-introduce'" |
||||||
> |
> |
||||||
<p |
<p |
||||||
:class="{ connectionArtificial: disabled }" |
:class="{ connectionArtificial: disabled }" |
||||||
v-html="replacementRagEmoticon(introduce)" |
v-html="replacementRagEmoticon(introduce)" |
||||||
:data-qaid="itemlist && itemlist.qaId ? itemlist.qaId : ''" |
:data-qaid="itemlist && itemlist.qaId ? itemlist.qaId : ''" |
||||||
></p> |
></p> |
||||||
</div> |
</div> |
||||||
<div class="content-question-answer" v-if="intents && intents.length > 0"> |
<div class="content-question-answer" v-if="intents && intents.length > 0"> |
||||||
<button |
<button |
||||||
class="answer-items" |
class="answer-items" |
||||||
v-for="(items, index) in intents" |
v-for="(items, index) in intents" |
||||||
:key="index" |
:key="index" |
||||||
:disabled="disabled ? true : false" |
:disabled="disabled ? true : false" |
||||||
@click.stop="richCallAnswer(items)" |
@click.stop="richCallAnswer(items)" |
||||||
> |
> |
||||||
{{ items.intent }} |
{{ items.intent }} |
||||||
</button> |
</button> |
||||||
</div> |
</div> |
||||||
<div |
<div |
||||||
class="unfold-box" |
class="unfold-box" |
||||||
:class="exchangeButton ? 'unfold-bg' : 'unfold-style'" |
:class="exchangeButton ? 'unfold-bg' : 'unfold-style'" |
||||||
v-if="(!intents || intents.length == 0) && showExchangeButton" |
v-if="(!intents || intents.length == 0) && showExchangeButton" |
||||||
> |
> |
||||||
<a href="javascript:;" @click="showTotalIntro" |
<a href="javascript:;" @click="showTotalIntro" |
||||||
>{{ exchangeButton ? '展开' : '收起' |
>{{ exchangeButton ? '展开' : '收起' |
||||||
}}<em class="look-more-icon" :class="!exchangeButton ? 'active' : ''"></em |
}}<em class="look-more-icon" :class="!exchangeButton ? 'active' : ''"></em |
||||||
></a> |
></a> |
||||||
</div> |
</div> |
||||||
</div> |
</div> |
||||||
</template> |
</template> |
||||||
|
|
||||||
<script setup> |
<script setup> |
||||||
import { ref, inject, onMounted, nextTick } from 'vue' |
import { ref, inject, onMounted, nextTick } from 'vue' |
||||||
import { showToast, showLoadingToast, closeToast } from 'vant' |
import { showToast, showLoadingToast, closeToast } from 'vant' |
||||||
import faceJSON from '@/mock/face.json' |
import faceJSON from '@/mock/face.json' |
||||||
import utils from '@/utils/utils' |
import utils from '@/utils/utils' |
||||||
import wx from 'weixin-js-sdk' |
import wx from 'weixin-js-sdk' |
||||||
|
|
||||||
const props = defineProps({ |
const props = defineProps({ |
||||||
introduce: { type: String, default: '' }, |
introduce: { type: String, default: '' }, |
||||||
intents: { type: Array, default: () => [] }, |
intents: { type: Array, default: () => [] }, |
||||||
disabled: { type: Boolean, default: false }, |
disabled: { type: Boolean, default: false }, |
||||||
heightMax: { type: String, default: '' }, |
heightMax: { type: String, default: '' }, |
||||||
itemlist: { type: Object, default: () => ({}) }, |
itemlist: { type: Object, default: () => ({}) }, |
||||||
}) |
}) |
||||||
|
|
||||||
const store = inject('appStore', null) |
const store = inject('appStore', null) |
||||||
const userId = inject('userId', ref('')) |
const userId = inject('userId', ref('')) |
||||||
const userInfo = inject('userInfo', ref({})) |
const userInfo = inject('userInfo', ref({})) |
||||||
const mescrollContent = inject('mescrollContent', ref(null)) |
const mescrollContent = inject('mescrollContent', ref(null)) |
||||||
const manualService = inject('manualService', ref('1')) |
const manualService = inject('manualService', ref('1')) |
||||||
const sendLoading = inject('sendLoading', ref(false)) |
const sendLoading = inject('sendLoading', ref(false)) |
||||||
|
|
||||||
const publicPath = import.meta.env.BASE_URL |
const publicPath = import.meta.env.BASE_URL |
||||||
const showTotal = ref(true) |
const showTotal = ref(true) |
||||||
const exchangeButton = ref(true) |
const exchangeButton = ref(true) |
||||||
const showExchangeButton = ref(false) |
const showExchangeButton = ref(false) |
||||||
const expressionProcessing = ref({}) |
const expressionProcessing = ref({}) |
||||||
const bigExpressionProcessing = ref({}) |
const bigExpressionProcessing = ref({}) |
||||||
const isBtnsubmit = ref(true) |
const isBtnsubmit = ref(true) |
||||||
const desc = ref(null) |
const desc = ref(null) |
||||||
|
|
||||||
onMounted(() => { |
onMounted(() => { |
||||||
processedEmoji() |
processedEmoji() |
||||||
descHeightChange() |
descHeightChange() |
||||||
nextTick(() => { |
nextTick(() => { |
||||||
initGlobalCallbacks() |
initGlobalCallbacks() |
||||||
}) |
}) |
||||||
}) |
}) |
||||||
|
|
||||||
function initGlobalCallbacks() { |
function initGlobalCallbacks() { |
||||||
try { |
try { |
||||||
window.getLink = (item) => { |
window.getLink = (item) => { |
||||||
utils.AppToHttpHtml(item) |
utils.AppToHttpHtml(item) |
||||||
} |
} |
||||||
window.jumpOpenLink = (item) => { |
window.jumpOpenLink = (item) => { |
||||||
utils.AppToHttpHtml(item) |
utils.AppToHttpHtml(item) |
||||||
} |
} |
||||||
|
|
||||||
window.jumpOpenWeb = (type, url, urlType) => { |
window.jumpOpenWeb = (type, url, urlType) => { |
||||||
let params = {} |
let params = {} |
||||||
if (type === 'YY_0000') { |
if (type === 'YY_0000') { |
||||||
params = { |
params = { |
||||||
idnum: '1', |
idnum: '1', |
||||||
ownerId: userInfo.value?.encryptPid, |
ownerId: userInfo.value?.encryptPid, |
||||||
openid: userInfo.value?.sourceUserId, |
openid: userInfo.value?.sourceUserId, |
||||||
} |
} |
||||||
const completeURL = handleURL(url, params) |
const completeURL = handleURL(url, params) |
||||||
store |
store |
||||||
?.dispatch?.('post', { |
?.dispatch?.('post', { |
||||||
url: 'semantic/getYdbqTicket', |
url: 'semantic/getYdbqTicket', |
||||||
data: { url: completeURL, userId: userId.value }, |
data: { url: completeURL, userId: userId.value }, |
||||||
}) |
}) |
||||||
.then((res) => { |
.then((res) => { |
||||||
if (res.code === 0) { |
if (res.code === 0) { |
||||||
if (!res.data) { |
if (!res.data) { |
||||||
utils.openWxPage(url, params) |
utils.openWxPage(url, params) |
||||||
} else { |
} else { |
||||||
utils.openWxPage(url, { accessTicket: res.data }) |
utils.openWxPage(url, { accessTicket: res.data }) |
||||||
} |
} |
||||||
} else { |
} else { |
||||||
showToast('网络异常,请重试') |
showToast('网络异常,请重试') |
||||||
} |
} |
||||||
}) |
}) |
||||||
} else if (type === 'YY_ydbq') { |
} else if (type === 'YY_ydbq') { |
||||||
params = { |
params = { |
||||||
mobile: userInfo.value?.phone, |
mobile: userInfo.value?.phone, |
||||||
pid: userInfo.value?.encryptPid, |
pid: userInfo.value?.encryptPid, |
||||||
openid: userInfo.value?.sourceUserId, |
openid: userInfo.value?.sourceUserId, |
||||||
} |
} |
||||||
const completeURL = handleURL(url, params) |
const completeURL = handleURL(url, params) |
||||||
store |
store |
||||||
?.dispatch?.('post', { |
?.dispatch?.('post', { |
||||||
url: 'semantic/getYdbqTicket', |
url: 'semantic/getYdbqTicket', |
||||||
data: { url: completeURL, userId: userId.value }, |
data: { url: completeURL, userId: userId.value }, |
||||||
}) |
}) |
||||||
.then((res) => { |
.then((res) => { |
||||||
if (res.code === 0) { |
if (res.code === 0) { |
||||||
if (!res.data) { |
if (!res.data) { |
||||||
utils.openWxPage(url, params) |
utils.openWxPage(url, params) |
||||||
} else { |
} else { |
||||||
utils.openWxPage(url, { accessTicket: res.data }) |
utils.openWxPage(url, { accessTicket: res.data }) |
||||||
} |
} |
||||||
} else { |
} else { |
||||||
showToast('网络异常,请重试') |
showToast('网络异常,请重试') |
||||||
} |
} |
||||||
}) |
}) |
||||||
} else if (type === 'YY_APP_H5') { |
} else if (type === 'YY_APP_H5') { |
||||||
utils.AppOpenH5(url, { mobile: userInfo.value?.phone, pid: userInfo.value?.encryptPid }) |
utils.AppOpenH5(url, { mobile: userInfo.value?.phone, pid: userInfo.value?.encryptPid }) |
||||||
} else if (type === 'ydbq_2') { |
} else if (type === 'ydbq_2') { |
||||||
utils.openSpecPage({ url, generateType: type, userId: userId.value }) |
utils.openSpecPage({ url, generateType: type, userId: userId.value }) |
||||||
} else if (type === 'YY_CMD') { |
} else if (type === 'YY_CMD') { |
||||||
const newUrl = |
const newUrl = |
||||||
url + |
url + |
||||||
`&idnum=1&openId=${userInfo.value?.sourceUserId}&entryOpenid=${userInfo.value?.entryOpenid}` |
`&idnum=1&openId=${userInfo.value?.sourceUserId}&entryOpenid=${userInfo.value?.entryOpenid}` |
||||||
store |
store |
||||||
?.dispatch?.('post', { |
?.dispatch?.('post', { |
||||||
url: 'semantic/getYdbqTicket', |
url: 'semantic/getYdbqTicket', |
||||||
data: { url: newUrl, userId: userId.value, isCmd: '1' }, |
data: { url: newUrl, userId: userId.value, isCmd: '1' }, |
||||||
}) |
}) |
||||||
.then((res) => { |
.then((res) => { |
||||||
if (res.code === 0) { |
if (res.code === 0) { |
||||||
if (!res.data) { |
if (!res.data) { |
||||||
utils.AppToHttpHtml(newUrl) |
utils.AppToHttpHtml(newUrl) |
||||||
} else { |
} else { |
||||||
utils.AppToHttpHtml(url + `&accessTicket=${res.data}`) |
utils.AppToHttpHtml(url + `&accessTicket=${res.data}`) |
||||||
} |
} |
||||||
} else { |
} else { |
||||||
showToast('网络异常,请重试') |
showToast('网络异常,请重试') |
||||||
} |
} |
||||||
}) |
}) |
||||||
} else if (type === 'YY_hfhz') { |
} else if (type === 'YY_hfhz') { |
||||||
store |
store |
||||||
?.dispatch?.('post', { |
?.dispatch?.('post', { |
||||||
url: 'semantic/xdhfCreateToken', |
url: 'semantic/xdhfCreateToken', |
||||||
data: { certNum: '1', systemSource: 'yykf', userId: userId.value }, |
data: { certNum: '1', systemSource: 'yykf', userId: userId.value }, |
||||||
}) |
}) |
||||||
.then((res) => { |
.then((res) => { |
||||||
const entryptedId = userInfo.value?.versionHFHZ |
const entryptedId = userInfo.value?.versionHFHZ |
||||||
utils.openWxPage(url, { |
utils.openWxPage(url, { |
||||||
sessionToken: res.data, |
sessionToken: res.data, |
||||||
holderId: encodeURI(entryptedId), |
holderId: encodeURI(entryptedId), |
||||||
holderType: 'a', |
holderType: 'a', |
||||||
hzhfSystemSource: '0803', |
hzhfSystemSource: '0803', |
||||||
ishwFlag: '1', |
ishwFlag: '1', |
||||||
isqshzFlag: '1', |
isqshzFlag: '1', |
||||||
}) |
}) |
||||||
}) |
}) |
||||||
} else if (type === 'YY_1v1') { |
} else if (type === 'YY_1v1') { |
||||||
store |
store |
||||||
?.dispatch?.('post', { url: 'thirdPartyAuth/getExclusiveServicesToken' }) |
?.dispatch?.('post', { url: 'thirdPartyAuth/getExclusiveServicesToken' }) |
||||||
.then((res) => { |
.then((res) => { |
||||||
if (res.code === 0 && res.data) { |
if (res.code === 0 && res.data) { |
||||||
utils.openWxPage(url, { |
utils.openWxPage(url, { |
||||||
sour: 'yykf', |
sour: 'yykf', |
||||||
omoSource: userInfo.value?.source, |
omoSource: userInfo.value?.source, |
||||||
omoSourceName: encodeURIComponent(userInfo.value?.sourceName), |
omoSourceName: encodeURIComponent(userInfo.value?.sourceName), |
||||||
token: res.data, |
token: res.data, |
||||||
}) |
}) |
||||||
} else { |
} else { |
||||||
showToast('网络异常,请重试') |
showToast('网络异常,请重试') |
||||||
} |
} |
||||||
}) |
}) |
||||||
} else if (type === 'YY_yzsfx') { |
} else if (type === 'YY_yzsfx') { |
||||||
store |
store |
||||||
?.dispatch?.('post', { |
?.dispatch?.('post', { |
||||||
url: 'semantic/getYzsUrl', |
url: 'semantic/getYzsUrl', |
||||||
data: { userId: userId.value, bqType: url, urlType }, |
data: { userId: userId.value, bqType: url, urlType }, |
||||||
}) |
}) |
||||||
.then((res) => { |
.then((res) => { |
||||||
if (res.code === 0 && res.data) { |
if (res.code === 0 && res.data) { |
||||||
utils.openWxPage(res.data, '') |
utils.openWxPage(res.data, '') |
||||||
} else { |
} else { |
||||||
showToast('网络异常,请重试') |
showToast('网络异常,请重试') |
||||||
} |
} |
||||||
}) |
}) |
||||||
} else if (type === 'YY_GWXCX') { |
} else if (type === 'YY_GWXCX') { |
||||||
wx.miniProgram.navigateTo({ url: url }) |
wx.miniProgram.navigateTo({ url: url }) |
||||||
} else if (type === 'YY_GWXCX_HOME') { |
} else if (type === 'YY_GWXCX_HOME') { |
||||||
wx.miniProgram.reLaunch({ url: url }) |
wx.miniProgram.reLaunch({ url: url }) |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
window.openAppPage = (params) => { |
window.openAppPage = (params) => { |
||||||
if (params) { |
if (params) { |
||||||
params = params.replace(/\'/g, '"') |
params = params.replace(/\'/g, '"') |
||||||
utils.AppToOutModules(params) |
utils.AppToOutModules(params) |
||||||
} |
} |
||||||
} |
} |
||||||
window.connectionArtificial = (event) => { |
window.connectionArtificial = (event) => { |
||||||
let isClick = false, |
let isClick = false, |
||||||
isclassName = false |
isclassName = false |
||||||
if (event.parentElement && !event.parentElement.className) { |
if (event.parentElement && !event.parentElement.className) { |
||||||
isclassName = false |
isclassName = false |
||||||
} else { |
} else { |
||||||
isclassName = true |
isclassName = true |
||||||
} |
} |
||||||
if (isclassName && event.parentElement) { |
if (isclassName && event.parentElement) { |
||||||
isClick = utils.hasClass(event.parentElement, 'connectionArtificial') |
isClick = utils.hasClass(event.parentElement, 'connectionArtificial') |
||||||
} |
} |
||||||
if (!isclassName || !isClick) { |
if (!isclassName || !isClick) { |
||||||
connectionArtificial(event) |
connectionArtificial(event) |
||||||
} |
} |
||||||
} |
} |
||||||
} catch (error) { |
} catch (error) { |
||||||
console.log(error) |
console.log(error) |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
function handleURL(url, params) { |
function handleURL(url, params) { |
||||||
let flag = url.indexOf('?') != -1 |
let flag = url.indexOf('?') != -1 |
||||||
let urlPar = '' |
let urlPar = '' |
||||||
if (params) { |
if (params) { |
||||||
Object.getOwnPropertyNames(params).forEach((item, index) => { |
Object.getOwnPropertyNames(params).forEach((item, index) => { |
||||||
if (index === 0 && !flag) { |
if (index === 0 && !flag) { |
||||||
urlPar += `?${item}=${params[item]}` |
urlPar += `?${item}=${params[item]}` |
||||||
} else { |
} else { |
||||||
urlPar += `&${item}=${params[item]}` |
urlPar += `&${item}=${params[item]}` |
||||||
} |
} |
||||||
}) |
}) |
||||||
} |
} |
||||||
return url + urlPar |
return url + urlPar |
||||||
} |
} |
||||||
|
|
||||||
function replacementRagEmoticon(str) { |
function replacementRagEmoticon(str) { |
||||||
str = str || '' |
str = str || '' |
||||||
let res = str.replace(/\\n/gm, '<br/>') |
let res = str.replace(/\\n/gm, '<br/>') |
||||||
return emojiToImage(res) |
return emojiToImage(res) |
||||||
} |
} |
||||||
|
|
||||||
function processedEmoji() { |
function processedEmoji() { |
||||||
const tempExp = {} |
const tempExp = {} |
||||||
const tempBigExp = {} |
const tempBigExp = {} |
||||||
faceJSON.forEach((item) => { |
faceJSON.forEach((item) => { |
||||||
item.faceList.forEach((items) => { |
item.faceList.forEach((items) => { |
||||||
tempExp[`[${items.title}]`] = items.src |
tempExp[`[${items.title}]`] = items.src |
||||||
}) |
}) |
||||||
item.bigExpression.forEach((items) => { |
item.bigExpression.forEach((items) => { |
||||||
tempBigExp[`[${items.title}]`] = items.src |
tempBigExp[`[${items.title}]`] = items.src |
||||||
}) |
}) |
||||||
}) |
}) |
||||||
expressionProcessing.value = tempExp |
expressionProcessing.value = tempExp |
||||||
bigExpressionProcessing.value = tempBigExp |
bigExpressionProcessing.value = tempBigExp |
||||||
} |
} |
||||||
|
|
||||||
function emojiToImage(str) { |
function emojiToImage(str) { |
||||||
let srcImg = '' |
let srcImg = '' |
||||||
let regex = /\[[^\]]+\]/g |
let regex = /\[[^\]]+\]/g |
||||||
srcImg = str.replace(regex, (item) => { |
srcImg = str.replace(regex, (item) => { |
||||||
if (expressionProcessing.value[item]) { |
if (expressionProcessing.value[item]) { |
||||||
return `<img src="${ |
return `<img src="${ |
||||||
publicPath + expressionProcessing.value[item] |
publicPath + expressionProcessing.value[item] |
||||||
}" alt="small-image" title="${item}" />` |
}" alt="small-image" title="${item}" />` |
||||||
} else if (bigExpressionProcessing.value[item]) { |
} else if (bigExpressionProcessing.value[item]) { |
||||||
return `<img src="${ |
return `<img src="${ |
||||||
publicPath + bigExpressionProcessing.value[item] |
publicPath + bigExpressionProcessing.value[item] |
||||||
}" alt="big-image" title="${item}"/>` |
}" alt="big-image" title="${item}"/>` |
||||||
} |
} |
||||||
return item |
return item |
||||||
}) |
}) |
||||||
return srcImg |
return srcImg |
||||||
} |
} |
||||||
|
|
||||||
function showTotalIntro() { |
function showTotalIntro() { |
||||||
showTotal.value = !showTotal.value |
showTotal.value = !showTotal.value |
||||||
exchangeButton.value = !exchangeButton.value |
exchangeButton.value = !exchangeButton.value |
||||||
} |
} |
||||||
|
|
||||||
function getRem() { |
function getRem() { |
||||||
let winWidth = window.innerWidth |
let winWidth = window.innerWidth |
||||||
const defaultRem = document.body.style.fontSize.replace('rem', '') |
const defaultRem = document.body.style.fontSize.replace('rem', '') |
||||||
let rem = (winWidth / 375) * defaultRem |
let rem = (winWidth / 375) * defaultRem |
||||||
return rem |
return rem |
||||||
} |
} |
||||||
|
|
||||||
function descHeightChange() { |
function descHeightChange() { |
||||||
nextTick(() => { |
nextTick(() => { |
||||||
let rem = parseFloat(getRem()) |
let rem = parseFloat(getRem()) |
||||||
if (!desc.value) return |
if (!desc.value) return |
||||||
let descHeight = window.getComputedStyle(desc.value).height.replace('rem', '') |
let descHeight = window.getComputedStyle(desc.value).height.replace('rem', '') |
||||||
descHeight = descHeight || desc.value.offsetHeight |
descHeight = descHeight || desc.value.offsetHeight |
||||||
if (descHeight > 2.325 * rem) { |
if (descHeight > 2.325 * rem) { |
||||||
showExchangeButton.value = true |
showExchangeButton.value = true |
||||||
exchangeButton.value = true |
exchangeButton.value = true |
||||||
showTotal.value = false |
showTotal.value = false |
||||||
} else { |
} else { |
||||||
showExchangeButton.value = false |
showExchangeButton.value = false |
||||||
showTotal.value = true |
showTotal.value = true |
||||||
} |
} |
||||||
}) |
}) |
||||||
} |
} |
||||||
|
|
||||||
function scrollTopBody() { |
function scrollTopBody() { |
||||||
setTimeout(() => { |
setTimeout(() => { |
||||||
try { |
try { |
||||||
if (mescrollContent.value) |
if (mescrollContent.value) |
||||||
mescrollContent.value.scrollTop = mescrollContent.value.scrollHeight || 0 |
mescrollContent.value.scrollTop = mescrollContent.value.scrollHeight || 0 |
||||||
} catch (e) { |
} catch (e) { |
||||||
console.log(e.message) |
console.log(e.message) |
||||||
} |
} |
||||||
}, 300) |
}, 300) |
||||||
} |
} |
||||||
|
|
||||||
function connectionArtificial(event) { |
function connectionArtificial(event) { |
||||||
try { |
try { |
||||||
let qaId = event.parentNode ? event.parentNode.dataset.qaid : '' |
let qaId = event.parentNode ? event.parentNode.dataset.qaid : '' |
||||||
let sendParmas = { reqAndResType: '1', msgText: '&转人工服务&', msgSource: manualService.value } |
let sendParmas = { reqAndResType: '1', msgText: '&转人工服务&', msgSource: manualService.value } |
||||||
scrollTopBody() |
scrollTopBody() |
||||||
store |
store |
||||||
?.dispatch?.('connectionArtificial', sendParmas) |
?.dispatch?.('connectionArtificial', sendParmas) |
||||||
.then(() => { |
.then(() => { |
||||||
event.disabled = true |
event.disabled = true |
||||||
}) |
}) |
||||||
.catch((err) => console.log(err)) |
.catch((err) => console.log(err)) |
||||||
store |
store |
||||||
?.dispatch?.('userBehavior', { qaId, eventType: '5', eventMsg: '知识库进入人工服务' }) |
?.dispatch?.('userBehavior', { qaId, eventType: '5', eventMsg: '知识库进入人工服务' }) |
||||||
.catch((err) => console.log(err)) |
.catch((err) => console.log(err)) |
||||||
} catch (error) { |
} catch (error) { |
||||||
console.log(error) |
console.log(error) |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
function richCallAnswer(item) { |
function richCallAnswer(item) { |
||||||
if (!isBtnsubmit.value) return |
if (!isBtnsubmit.value) return |
||||||
isBtnsubmit.value = false |
isBtnsubmit.value = false |
||||||
let sendParmas = { |
let sendParmas = { |
||||||
reqAndResType: '1', |
reqAndResType: '1', |
||||||
msgText: item.intent, |
msgText: item.intent, |
||||||
intentId: item.intentId, |
intentId: item.intentId, |
||||||
msgSource: manualService.value, |
msgSource: manualService.value, |
||||||
} |
} |
||||||
scrollTopBody() |
scrollTopBody() |
||||||
store |
store |
||||||
?.dispatch?.('sendingRobot', sendParmas) |
?.dispatch?.('sendingRobot', sendParmas) |
||||||
.then(() => { |
.then(() => { |
||||||
isBtnsubmit.value = true |
isBtnsubmit.value = true |
||||||
}) |
}) |
||||||
.catch((err) => { |
.catch((err) => { |
||||||
isBtnsubmit.value = true |
isBtnsubmit.value = true |
||||||
console.log(err) |
console.log(err) |
||||||
}) |
}) |
||||||
} |
} |
||||||
|
|
||||||
function manualAnswer(event, item) { |
function manualAnswer(event, item) { |
||||||
let sendParmas = { reqAndResType: '1', msgText: '&转人工服务&', msgSource: manualService.value } |
let sendParmas = { reqAndResType: '1', msgText: '&转人工服务&', msgSource: manualService.value } |
||||||
const toast = showLoadingToast({ |
const toast = showLoadingToast({ |
||||||
message: '加载中...', |
message: '加载中...', |
||||||
duration: 0, |
duration: 0, |
||||||
loadingType: 'spinner', |
loadingType: 'spinner', |
||||||
forbidClick: true, |
forbidClick: true, |
||||||
}) |
}) |
||||||
if (!sendLoading.value) { |
if (!sendLoading.value) { |
||||||
scrollTopBody() |
scrollTopBody() |
||||||
store |
store |
||||||
?.dispatch?.('sendingRobot', sendParmas) |
?.dispatch?.('sendingRobot', sendParmas) |
||||||
.then(() => { |
.then(() => { |
||||||
closeToast() |
closeToast() |
||||||
event.disabled = true |
event.disabled = true |
||||||
}) |
}) |
||||||
.catch((err) => { |
.catch((err) => { |
||||||
closeToast() |
closeToast() |
||||||
console.log(err) |
console.log(err) |
||||||
}) |
}) |
||||||
} else { |
} else { |
||||||
closeToast() |
closeToast() |
||||||
} |
} |
||||||
} |
} |
||||||
</script> |
</script> |
||||||
|
|
||||||
<style scoped> |
<style scoped> |
||||||
.text-template-box { |
.text-template-box { |
||||||
padding: 0; |
padding: 0; |
||||||
} |
} |
||||||
|
|
||||||
.question-answer-con { |
.question-answer-con { |
||||||
overflow: hidden; |
overflow: hidden; |
||||||
} |
} |
||||||
|
|
||||||
.total-introduce { |
.total-introduce { |
||||||
max-height: none; |
max-height: none; |
||||||
} |
} |
||||||
|
|
||||||
.detailed-introduce { |
.detailed-introduce { |
||||||
max-height: 2.325rem; |
max-height: 2.325rem; |
||||||
} |
} |
||||||
|
|
||||||
.content-question-answer { |
.content-question-answer { |
||||||
display: flex; |
display: flex; |
||||||
flex-wrap: wrap; |
flex-wrap: wrap; |
||||||
gap: 8rem; |
gap: 8rem; |
||||||
margin-top: 10rem; |
margin-top: 10rem; |
||||||
} |
} |
||||||
|
|
||||||
.answer-items { |
.answer-items { |
||||||
padding: 6rem 12rem; |
padding: 6rem 12rem; |
||||||
background: #f0f6ff; |
background: #f0f6ff; |
||||||
border: 1rem solid #d6e4ff; |
border: 1rem solid #d6e4ff; |
||||||
border-radius: 16rem; |
border-radius: 16rem; |
||||||
font-size: 13rem; |
font-size: 13rem; |
||||||
color: #025cea; |
color: #025cea; |
||||||
cursor: pointer; |
cursor: pointer; |
||||||
} |
} |
||||||
|
|
||||||
.answer-items[disabled] { |
.answer-items[disabled] { |
||||||
opacity: 0.5; |
opacity: 0.5; |
||||||
cursor: not-allowed; |
cursor: not-allowed; |
||||||
} |
} |
||||||
|
|
||||||
.unfold-box { |
.unfold-box { |
||||||
text-align: center; |
text-align: center; |
||||||
margin-top: 8rem; |
margin-top: 8rem; |
||||||
} |
} |
||||||
|
|
||||||
.unfold-box a { |
.unfold-box a { |
||||||
font-size: 13rem; |
font-size: 13rem; |
||||||
color: #025cea; |
color: #025cea; |
||||||
} |
} |
||||||
|
|
||||||
.look-more-icon { |
.look-more-icon { |
||||||
display: inline-block; |
display: inline-block; |
||||||
width: 12rem; |
width: 12rem; |
||||||
height: 12rem; |
height: 12rem; |
||||||
margin-left: 4rem; |
margin-left: 4rem; |
||||||
transition: transform 0.3s; |
transition: transform 0.3s; |
||||||
} |
} |
||||||
|
|
||||||
.look-more-icon.active { |
.look-more-icon.active { |
||||||
transform: rotate(180deg); |
transform: rotate(180deg); |
||||||
} |
} |
||||||
</style> |
</style> |
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,37 +1,34 @@ |
|||||||
import { createRouter, createWebHashHistory } from 'vue-router' |
import { createRouter, createWebHashHistory } from 'vue-router' |
||||||
import Utils from "@/utils/utils"; |
import Utils from "@/utils/utils"; |
||||||
|
|
||||||
const router = createRouter({ |
const router = createRouter({ |
||||||
history: createWebHashHistory(), |
history: createWebHashHistory(), |
||||||
routes: [ |
routes: [ |
||||||
{ path: '/', redirect: '/chat' }, |
{ path: '/', redirect: '/chat' }, |
||||||
{ path: '/chat', name: 'chat', component: () => import('../views/chat.vue') }, |
{ path: '/chat', name: 'chat', component: () => import('../views/chat.vue'), meta: { keepAlive: true, title: '小蓝管家' } }, |
||||||
{ |
{ path: '/word', name: 'word', component: () => import('../views/word.vue'), meta: { keepAlive: true, title: '小蓝管家' } }, |
||||||
path: '/history', |
// {
|
||||||
name: 'history', |
// path: '/history',
|
||||||
component: () => import('../views/history.vue'), |
// name: 'history',
|
||||||
meta: { title: '洋洋客服-历史记录查询' }, |
// component: () => import('../views/history.vue'),
|
||||||
}, |
// meta: { title: '小蓝管家-历史记录查询' },
|
||||||
{ |
// },
|
||||||
path: '/previewPdf', |
// {
|
||||||
name: 'previewPdf', |
// path: '/previewPdf',
|
||||||
component: () => import('../components/previewPDF/index.vue'), |
// name: 'previewPdf',
|
||||||
meta: { title: '预览PDF' }, |
// component: () => import('../components/previewPDF/index.vue'),
|
||||||
}, |
// meta: { title: '预览PDF' },
|
||||||
// { path: '/uploadPage', name: 'uploadPage', component: () => import('../views/uploadPage.vue') },
|
// },
|
||||||
// { path: '/claimPage', name: 'claimPage', component: () => import('../views/claimPage/index.vue'), },
|
], |
||||||
// { path: '/outView', name: 'outView', component: () => import('../views/outView.vue') },
|
}) |
||||||
// { path: '/sign', name: 'sign', component: () => import('../components/input/sign.vue') },
|
const defaultTitle = '小蓝管家' |
||||||
], |
|
||||||
}) |
// 全局前置路由守卫
|
||||||
const defaultTitle = '洋洋客服' |
router.beforeEach(async (to, from, next) => { |
||||||
|
/* 路由发生变化修改页面title */ |
||||||
// 全局前置路由守卫
|
var title = to.meta.title ? to.meta.title : defaultTitle; |
||||||
router.beforeEach(async (to, from, next) => { |
Utils.setTitle(title);//修改页面title
|
||||||
/* 路由发生变化修改页面title */ |
next(); |
||||||
var title = to.meta.title ? to.meta.title : defaultTitle; |
}) |
||||||
Utils.setTitle(title);//修改页面title
|
|
||||||
next(); |
export default router |
||||||
}) |
|
||||||
|
|
||||||
export default router |
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,465 +1,465 @@ |
|||||||
import config from './config' |
import config from './config' |
||||||
import { showToast, showDialog, showConfirmDialog } from 'vant' |
import { showToast, showDialog, showConfirmDialog } from 'vant' |
||||||
import { useAppStore } from '@/store/app.js' |
import { useAppStore } from '@/store/app.js' |
||||||
import utils from './utils' |
import utils from './utils' |
||||||
|
|
||||||
// Keep the legacy socket implementation independent from Vuex. The proxy
|
// Keep the legacy socket implementation independent from Vuex. The proxy
|
||||||
// exposes the old state/commit/dispatch shape while reading the live Pinia
|
// exposes the old state/commit/dispatch shape while reading the live Pinia
|
||||||
// store instance for every call.
|
// store instance for every call.
|
||||||
const store = { |
const store = { |
||||||
get state() { |
get state() { |
||||||
return useAppStore().state |
return useAppStore().state |
||||||
}, |
}, |
||||||
commit(type, payload) { |
commit(type, payload) { |
||||||
return useAppStore().commit(type, payload) |
return useAppStore().commit(type, payload) |
||||||
}, |
}, |
||||||
dispatch(type, payload) { |
dispatch(type, payload) { |
||||||
return useAppStore().dispatch(type, payload) |
return useAppStore().dispatch(type, payload) |
||||||
}, |
}, |
||||||
} |
} |
||||||
/** |
/** |
||||||
* 提示函数 |
* 提示函数 |
||||||
* 禁止点击蒙层、显示3秒后关闭 |
* 禁止点击蒙层、显示3秒后关闭 |
||||||
*/ |
*/ |
||||||
const toast = msg => { |
const toast = msg => { |
||||||
showToast({ |
showToast({ |
||||||
message: msg, |
message: msg, |
||||||
duration: 5000, |
duration: 5000, |
||||||
position: 'top', |
position: 'top', |
||||||
}); |
}); |
||||||
} |
} |
||||||
|
|
||||||
const sendMessageFunction = (msgText) => { |
const sendMessageFunction = (msgText) => { |
||||||
return { |
return { |
||||||
token: store.state.token, |
token: store.state.token, |
||||||
fromFlag: 'other', |
fromFlag: 'other', |
||||||
userId: store.state.userId, |
userId: store.state.userId, |
||||||
sessionId: store.state.sessionId, |
sessionId: store.state.sessionId, |
||||||
reqAndResType: '', |
reqAndResType: '', |
||||||
msgType: '', //
|
msgType: '', //
|
||||||
msgText: msgText, |
msgText: msgText, |
||||||
intentId: '', |
intentId: '', |
||||||
source: store.state.source, |
source: store.state.source, |
||||||
timestamp: (new Date()).valueOf(), |
timestamp: (new Date()).valueOf(), |
||||||
msgSource: store.state.manualService, //1机器人 2人工
|
msgSource: store.state.manualService, //1机器人 2人工
|
||||||
cmd: '' |
cmd: '' |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
//设置title
|
//设置title
|
||||||
document.setTitle = function (title) { |
document.setTitle = function (title) { |
||||||
title = title || '洋洋客服'; |
title = title || '洋洋客服'; |
||||||
store.commit('set_otherTips', title); |
store.commit('set_otherTips', title); |
||||||
|
|
||||||
// document.title = title;
|
// document.title = title;
|
||||||
var iframe = document.createElement('iframe'); |
var iframe = document.createElement('iframe'); |
||||||
iframe.src = `${import.meta.env.BASE_URL}favicon.ico`; |
iframe.src = `${import.meta.env.BASE_URL}favicon.ico`; |
||||||
iframe.style.display = 'none'; |
iframe.style.display = 'none'; |
||||||
iframe.onload = function () { |
iframe.onload = function () { |
||||||
setTimeout(function () { |
setTimeout(function () { |
||||||
iframe.remove(); |
iframe.remove(); |
||||||
}, 9) |
}, 9) |
||||||
} |
} |
||||||
document.body.appendChild(iframe); |
document.body.appendChild(iframe); |
||||||
} |
} |
||||||
|
|
||||||
|
|
||||||
let wsConnection = { |
let wsConnection = { |
||||||
WSS_URL: config.WSURL, |
WSS_URL: config.WSURL, |
||||||
$ws: null, |
$ws: null, |
||||||
lockReturn: false, |
lockReturn: false, |
||||||
//6s发一次心跳
|
//6s发一次心跳
|
||||||
timeout: 60 * 100 * 1, |
timeout: 60 * 100 * 1, |
||||||
timeoutObj: null, |
timeoutObj: null, |
||||||
timeoutNum: null, |
timeoutNum: null, |
||||||
serverTimeoutObj: null, |
serverTimeoutObj: null, |
||||||
globalCallback: null, |
globalCallback: null, |
||||||
sendMessageData: null, |
sendMessageData: null, |
||||||
reconectNum: 0, |
reconectNum: 0, |
||||||
//最大限制 重连次数
|
//最大限制 重连次数
|
||||||
reconectTimes: 20, |
reconectTimes: 20, |
||||||
closeSession: false,//是否关闭当前会话
|
closeSession: false,//是否关闭当前会话
|
||||||
//初始化webSocket长连接
|
//初始化webSocket长连接
|
||||||
initWebSocket: function (callback) { |
initWebSocket: function (callback) { |
||||||
var that = this; |
var that = this; |
||||||
var userId = store.state.userId; |
var userId = store.state.userId; |
||||||
var checkParam = store.state.token; |
var checkParam = store.state.token; |
||||||
var sessionId = store.state.sessionId; |
var sessionId = store.state.sessionId; |
||||||
|
|
||||||
try { |
try { |
||||||
if ('WebSocket' in window) { |
if ('WebSocket' in window) { |
||||||
// this.$ws = new WebSocket(this.WSS_URL + userId + "," + sessionId);
|
// this.$ws = new WebSocket(this.WSS_URL + userId + "," + sessionId);
|
||||||
this.$ws = new WebSocket(`${this.WSS_URL}${userId}&${encodeURIComponent(checkParam)}`); |
this.$ws = new WebSocket(`${this.WSS_URL}${userId}&${encodeURIComponent(checkParam)}`); |
||||||
} else if ('MozWebSocket' in window) { |
} else if ('MozWebSocket' in window) { |
||||||
// this.$ws = new MozWebSocket(this.WSS_URL + userId + "," + sessionId);
|
// this.$ws = new MozWebSocket(this.WSS_URL + userId + "," + sessionId);
|
||||||
this.$ws = new MozWebSocket(`${this.WSS_URL}${userId}&${encodeURIComponent(checkParam)}`); |
this.$ws = new MozWebSocket(`${this.WSS_URL}${userId}&${encodeURIComponent(checkParam)}`); |
||||||
} else { |
} else { |
||||||
showDialog({ |
showDialog({ |
||||||
message: '您的浏览器不支持websocket协议,建议您使用Android系统版本大于4.0,ios系统版本大于7.0。' |
message: '您的浏览器不支持websocket协议,建议您使用Android系统版本大于4.0,ios系统版本大于7.0。' |
||||||
}).then(() => { |
}).then(() => { |
||||||
utils.closeWindow(); //关闭页面
|
utils.closeWindow(); //关闭页面
|
||||||
}); |
}); |
||||||
} |
} |
||||||
// this.$ws.onopen = this.wsOpen;
|
// this.$ws.onopen = this.wsOpen;
|
||||||
this.$ws.addEventListener("open", event => { |
this.$ws.addEventListener("open", event => { |
||||||
this.wsOpen(); |
this.wsOpen(); |
||||||
}) |
}) |
||||||
|
|
||||||
// this.$ws = new WebSocket(this.WSS_URL + userId + "," + sessionId);
|
// this.$ws = new WebSocket(this.WSS_URL + userId + "," + sessionId);
|
||||||
this.$ws.onclose = this.wsClose; |
this.$ws.onclose = this.wsClose; |
||||||
this.$ws.onmessage = this.onMessage; |
this.$ws.onmessage = this.onMessage; |
||||||
this.$ws.onerror = this.wsError; |
this.$ws.onerror = this.wsError; |
||||||
|
|
||||||
callback && callback(); |
callback && callback(); |
||||||
|
|
||||||
// store.commit('set_otherTips', "连接中...");
|
// store.commit('set_otherTips', "连接中...");
|
||||||
document.setTitle('连接中...') |
document.setTitle('连接中...') |
||||||
} catch (e) { |
} catch (e) { |
||||||
wsConnection.reconnect() |
wsConnection.reconnect() |
||||||
console.log(e); |
console.log(e); |
||||||
} |
} |
||||||
}, |
}, |
||||||
wsResendMessage() { |
wsResendMessage() { |
||||||
var sendFailList = store.state.sendFailList;//取出上次发送失败的消息
|
var sendFailList = store.state.sendFailList;//取出上次发送失败的消息
|
||||||
if (sendFailList.length > 0) { |
if (sendFailList.length > 0) { |
||||||
for (let i = 0; i < sendFailList.length; i++) { |
for (let i = 0; i < sendFailList.length; i++) { |
||||||
(function (i) {//这个匿名函数生成了闭包的效果,新建了一个作用域,这个作用域接收到每次循环的i值保存了下来,即使循环结束,闭包形成的作用域也不会被销毁
|
(function (i) {//这个匿名函数生成了闭包的效果,新建了一个作用域,这个作用域接收到每次循环的i值保存了下来,即使循环结束,闭包形成的作用域也不会被销毁
|
||||||
setTimeout(function () { |
setTimeout(function () { |
||||||
var dataResend = sendFailList[i]; |
var dataResend = sendFailList[i]; |
||||||
console.log("发送失败的数据ID==", dataResend.timestamp); |
console.log("发送失败的数据ID==", dataResend.timestamp); |
||||||
|
|
||||||
wsConnection.sendMessage(dataResend, wsConnection.globalCallback); |
wsConnection.sendMessage(dataResend, wsConnection.globalCallback); |
||||||
store.commit('set_currentItemId', dataResend.timestamp); |
store.commit('set_currentItemId', dataResend.timestamp); |
||||||
store.commit('set_findActiveItem', false);//发送成功
|
store.commit('set_findActiveItem', false);//发送成功
|
||||||
}, 200); |
}, 200); |
||||||
})(i); |
})(i); |
||||||
} |
} |
||||||
|
|
||||||
store.commit('del_sendFailList');//删除发送成功的
|
store.commit('del_sendFailList');//删除发送成功的
|
||||||
console.log(store.state.sendFailList); |
console.log(store.state.sendFailList); |
||||||
} |
} |
||||||
}, |
}, |
||||||
//打开websocket
|
//打开websocket
|
||||||
wsOpen: function (e) { |
wsOpen: function (e) { |
||||||
var that = this; |
var that = this; |
||||||
//开始websocket心跳
|
//开始websocket心跳
|
||||||
wsConnection.startWsHeartbeat(); |
wsConnection.startWsHeartbeat(); |
||||||
// toast('会话建立成功');
|
// toast('会话建立成功');
|
||||||
// store.commit('set_otherTips', "洋洋客服");
|
// store.commit('set_otherTips', "洋洋客服");
|
||||||
document.setTitle('洋洋客服') |
document.setTitle('洋洋客服') |
||||||
|
|
||||||
//执行重新发送
|
//执行重新发送
|
||||||
// if(wsConnection.isReconnet){
|
// if(wsConnection.isReconnet){
|
||||||
// wsConnection.wsResendMessage();
|
// wsConnection.wsResendMessage();
|
||||||
// wsConnection.isReconnet = false;
|
// wsConnection.isReconnet = false;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
console.log("ws success " + new Date().format("yyyy-MM-dd hh:mm:ss")); |
console.log("ws success " + new Date().format("yyyy-MM-dd hh:mm:ss")); |
||||||
}, |
}, |
||||||
onMessage: function (event) { |
onMessage: function (event) { |
||||||
//每次接收到服务端消息后 重置websocket心跳
|
//每次接收到服务端消息后 重置websocket心跳
|
||||||
wsConnection.resetHeartbeat(); |
wsConnection.resetHeartbeat(); |
||||||
let res = event.data; |
let res = event.data; |
||||||
try { |
try { |
||||||
if (event.data === 'pong') { |
if (event.data === 'pong') { |
||||||
console.log("收到心跳了:", event.data); |
console.log("收到心跳了:", event.data); |
||||||
return; |
return; |
||||||
} |
} |
||||||
|
|
||||||
if (event.data.match(/^\d+$/)) { |
if (event.data.match(/^\d+$/)) { |
||||||
wsConnection.globalCallback && wsConnection.globalCallback(event.data); |
wsConnection.globalCallback && wsConnection.globalCallback(event.data); |
||||||
return; |
return; |
||||||
} |
} |
||||||
|
|
||||||
res = JSON.parse(res); |
res = JSON.parse(res); |
||||||
console.log("收到消息啦:", res.data || res); |
console.log("收到消息啦:", res.data || res); |
||||||
if (res.data.cmd === 'ServiceSessionClosedEvent' && store.state.hxOpenSucceseds.includes(res.data.sessionId)) { |
if (res.data.cmd === 'ServiceSessionClosedEvent' && store.state.hxOpenSucceseds.includes(res.data.sessionId)) { |
||||||
if(store.state.integratedUser){ |
if(store.state.integratedUser){ |
||||||
utils.useSdk(res.data) |
utils.useSdk(res.data) |
||||||
}else{ |
}else{ |
||||||
setTimeout(() => { |
setTimeout(() => { |
||||||
utils.useSdk(res.data) |
utils.useSdk(res.data) |
||||||
}, 100); |
}, 100); |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
if (res.code != 0) { |
if (res.code != 0) { |
||||||
// toast(data.msg);
|
// toast(data.msg);
|
||||||
if (res.code === 10001) { |
if (res.code === 10001) { |
||||||
// 删除已经失效或过期的token(不删除也可以,因为登录后覆盖)
|
// 删除已经失效或过期的token(不删除也可以,因为登录后覆盖)
|
||||||
sessionStorage.removeItem("token"); |
sessionStorage.removeItem("token"); |
||||||
wsConnection.$ws.close(); |
wsConnection.$ws.close(); |
||||||
|
|
||||||
if (store.state.notitle === '1') { |
if (store.state.notitle === '1') { |
||||||
toast('当前会话已结束,请刷新页面或关闭页面重新进入'); |
toast('当前会话已结束,请刷新页面或关闭页面重新进入'); |
||||||
return |
return |
||||||
} |
} |
||||||
|
|
||||||
showConfirmDialog({ |
showConfirmDialog({ |
||||||
title: '提示', |
title: '提示', |
||||||
message: '当前会话已结束,请刷新页面或关闭页面重新进入', |
message: '当前会话已结束,请刷新页面或关闭页面重新进入', |
||||||
confirmButtonText: '取消', |
confirmButtonText: '取消', |
||||||
cancelButtonText: '确认', |
cancelButtonText: '确认', |
||||||
confirmButtonColor: '#000000', |
confirmButtonColor: '#000000', |
||||||
cancelButtonColor: '#000000' |
cancelButtonColor: '#000000' |
||||||
}).then(() => { |
}).then(() => { |
||||||
// on cancel (现在是右边的取消按钮)
|
// on cancel (现在是右边的取消按钮)
|
||||||
// utils.closeWindow();
|
// utils.closeWindow();
|
||||||
// router.replace({
|
// router.replace({
|
||||||
// path: '/404' // 到登录页重新获取token
|
// path: '/404' // 到登录页重新获取token
|
||||||
// })
|
// })
|
||||||
}).catch(() => { |
}).catch(() => { |
||||||
// on confirm (现在是左边的确认按钮)
|
// on confirm (现在是左边的确认按钮)
|
||||||
//确认重新刷新页面获取token
|
//确认重新刷新页面获取token
|
||||||
// window.location.reload();
|
// window.location.reload();
|
||||||
utils.AppReloadHtml(); |
utils.AppReloadHtml(); |
||||||
}); |
}); |
||||||
} else { |
} else { |
||||||
if (res.msg) { |
if (res.msg) { |
||||||
toast(res.msg); |
toast(res.msg); |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
return; |
return; |
||||||
} |
} |
||||||
|
|
||||||
//是否转接人工参数
|
//是否转接人工参数
|
||||||
// if (res.data.cmd && res.data.cmd == "ServiceSessionCreatedEvent") {
|
// if (res.data.cmd && res.data.cmd == "ServiceSessionCreatedEvent") {
|
||||||
// store.dispatch('setTransferCustomer', 2);
|
// store.dispatch('setTransferCustomer', 2);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
//客服接起不排队了
|
//客服接起不排队了
|
||||||
if (res.data.cmd && res.data.cmd == "ServiceSessionOpenedEvent") { |
if (res.data.cmd && res.data.cmd == "ServiceSessionOpenedEvent") { |
||||||
store.commit('set_queuedTimeout', true); |
store.commit('set_queuedTimeout', true); |
||||||
|
|
||||||
store.commit('set_msgStatus', '');//人工客服排队状态值 等待中:"1",其他:""
|
store.commit('set_msgStatus', '');//人工客服排队状态值 等待中:"1",其他:""
|
||||||
store.commit('set_msgReply', false);//人工客服排队是否调取自动回复话术
|
store.commit('set_msgReply', false);//人工客服排队是否调取自动回复话术
|
||||||
} |
} |
||||||
|
|
||||||
if (res.data.cmd && res.data.cmd == "ServiceSessionClosedEvent") { |
if (res.data.cmd && res.data.cmd == "ServiceSessionClosedEvent") { |
||||||
wsConnection.closeSession = true;//是关闭会话
|
wsConnection.closeSession = true;//是关闭会话
|
||||||
setTimeout(() => { |
setTimeout(() => { |
||||||
store.commit('set_queuedTimeout', true); |
store.commit('set_queuedTimeout', true); |
||||||
store.dispatch('setTransferCustomer', 1);//人工改为机器人
|
store.dispatch('setTransferCustomer', 1);//人工改为机器人
|
||||||
wsConnection.$ws.close(); |
wsConnection.$ws.close(); |
||||||
|
|
||||||
}, 2500) |
}, 2500) |
||||||
} |
} |
||||||
|
|
||||||
//服务端发送来的消息存到vuex
|
//服务端发送来的消息存到vuex
|
||||||
store.dispatch('sendingDrtificial', res.data).then((res) => { |
store.dispatch('sendingDrtificial', res.data).then((res) => { |
||||||
}).catch(err => { |
}).catch(err => { |
||||||
console.log(err) |
console.log(err) |
||||||
}); |
}); |
||||||
|
|
||||||
//如果会话关闭不用推送消息回执
|
//如果会话关闭不用推送消息回执
|
||||||
if (res.data && res.data.chatId) { |
if (res.data && res.data.chatId) { |
||||||
let chatParam = JSON.stringify(res.data); |
let chatParam = JSON.stringify(res.data); |
||||||
// wsConnection.$ws.send(chatParam, '');
|
// wsConnection.$ws.send(chatParam, '');
|
||||||
wsConnection.sendMessage(chatParam, ''); |
wsConnection.sendMessage(chatParam, ''); |
||||||
console.log("发送消息回执", chatParam) |
console.log("发送消息回执", chatParam) |
||||||
} |
} |
||||||
} catch (error) { |
} catch (error) { |
||||||
console.log(error) |
console.log(error) |
||||||
} |
} |
||||||
}, |
}, |
||||||
//发送数据,接收处理数据
|
//发送数据,接收处理数据
|
||||||
sendMessage: function (data, callback) { |
sendMessage: function (data, callback) { |
||||||
//存储事件
|
//存储事件
|
||||||
wsConnection.globalCallback = callback; |
wsConnection.globalCallback = callback; |
||||||
// console.log(data, callback)
|
// console.log(data, callback)
|
||||||
|
|
||||||
switch (wsConnection.$ws.readyState) { |
switch (wsConnection.$ws.readyState) { |
||||||
//CONNECTING:值为0,表示正在连接。
|
//CONNECTING:值为0,表示正在连接。
|
||||||
case wsConnection.$ws.CONNECTING: |
case wsConnection.$ws.CONNECTING: |
||||||
setTimeout(function () { |
setTimeout(function () { |
||||||
wsConnection.sendMessage(data, callback); |
wsConnection.sendMessage(data, callback); |
||||||
}, 1000); |
}, 1000); |
||||||
break; |
break; |
||||||
//OPEN:值为1,表示连接成功,可以通信了。
|
//OPEN:值为1,表示连接成功,可以通信了。
|
||||||
case wsConnection.$ws.OPEN: |
case wsConnection.$ws.OPEN: |
||||||
wsConnection.$ws.send(data); |
wsConnection.$ws.send(data); |
||||||
break; |
break; |
||||||
//CLOSING:值为2,表示连接正在关闭。
|
//CLOSING:值为2,表示连接正在关闭。
|
||||||
case wsConnection.$ws.CLOSING: |
case wsConnection.$ws.CLOSING: |
||||||
setTimeout(function () { |
setTimeout(function () { |
||||||
wsConnection.sendMessage(data, callback); |
wsConnection.sendMessage(data, callback); |
||||||
}, 1000); |
}, 1000); |
||||||
break; |
break; |
||||||
//CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
|
//CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
|
||||||
case wsConnection.$ws.CLOSED: |
case wsConnection.$ws.CLOSED: |
||||||
// do something
|
// do something
|
||||||
break; |
break; |
||||||
default: |
default: |
||||||
// this never happens
|
// this never happens
|
||||||
break; |
break; |
||||||
} |
} |
||||||
|
|
||||||
//重新监听onmessage,并把数据传给回调函数
|
//重新监听onmessage,并把数据传给回调函数
|
||||||
// wsConnection.onmessage = ev =>{
|
// wsConnection.onmessage = ev =>{
|
||||||
// callback && callback(ev)
|
// callback && callback(ev)
|
||||||
// }
|
// }
|
||||||
}, |
}, |
||||||
//重启websocket
|
//重启websocket
|
||||||
reconnect: function () { |
reconnect: function () { |
||||||
let _this = this; |
let _this = this; |
||||||
if (_this.lockReturn) { |
if (_this.lockReturn) { |
||||||
return; |
return; |
||||||
} |
} |
||||||
_this.isReconnet = true; |
_this.isReconnet = true; |
||||||
_this.lockReturn = true; |
_this.lockReturn = true; |
||||||
|
|
||||||
//没连接上会一直重连,设置延迟避免请求过多
|
//没连接上会一直重连,设置延迟避免请求过多
|
||||||
if (_this.reconectNum < this.reconectTimes) { |
if (_this.reconectNum < this.reconectTimes) { |
||||||
_this.timeoutNum && clearTimeout(_this.timeoutNum); |
_this.timeoutNum && clearTimeout(_this.timeoutNum); |
||||||
_this.timeoutNum = setTimeout(function () { |
_this.timeoutNum = setTimeout(function () { |
||||||
_this.initWebSocket(); |
_this.initWebSocket(); |
||||||
// toast('正在重连,请稍后...');
|
// toast('正在重连,请稍后...');
|
||||||
// store.commit('set_otherTips', "正在重连...");
|
// store.commit('set_otherTips', "正在重连...");
|
||||||
document.setTitle('正在重连...') |
document.setTitle('正在重连...') |
||||||
console.info(`正在重连第${_this.reconectNum + 1}次`) |
console.info(`正在重连第${_this.reconectNum + 1}次`) |
||||||
_this.reconectNum++ |
_this.reconectNum++ |
||||||
_this.lockReturn = false; |
_this.lockReturn = false; |
||||||
}, 4000); |
}, 4000); |
||||||
} else { |
} else { |
||||||
// toast('重连次数超出设定值,不再重连,请检查配置项');
|
// toast('重连次数超出设定值,不再重连,请检查配置项');
|
||||||
showDialog({ |
showDialog({ |
||||||
message: '重连次数超出设定值,不再重连。请检查您的网络设置,点击“确定”刷新页面,重新建立会话。' |
message: '重连次数超出设定值,不再重连。请检查您的网络设置,点击“确定”刷新页面,重新建立会话。' |
||||||
}).then(() => { |
}).then(() => { |
||||||
// window.location.reload();
|
// window.location.reload();
|
||||||
utils.AppReloadHtml(); |
utils.AppReloadHtml(); |
||||||
}); |
}); |
||||||
} |
} |
||||||
}, |
}, |
||||||
//心跳检测,每5s心跳一次
|
//心跳检测,每5s心跳一次
|
||||||
startWsHeartbeat: function () { |
startWsHeartbeat: function () { |
||||||
let _this = this; |
let _this = this; |
||||||
this.timeoutObj && clearTimeout(this.timeoutObj); |
this.timeoutObj && clearTimeout(this.timeoutObj); |
||||||
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj); |
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj); |
||||||
|
|
||||||
this.timeoutObj = setTimeout(() => { |
this.timeoutObj = setTimeout(() => { |
||||||
//这里发送一个心跳,后端收到后,返回一个心跳消息,
|
//这里发送一个心跳,后端收到后,返回一个心跳消息,
|
||||||
//onmessage拿到返回的心跳就说明连接正常
|
//onmessage拿到返回的心跳就说明连接正常
|
||||||
if (wsConnection.$ws && wsConnection.$ws.readyState != wsConnection.$ws.CLOSED) { |
if (wsConnection.$ws && wsConnection.$ws.readyState != wsConnection.$ws.CLOSED) { |
||||||
//关闭当前会话后不发送ping
|
//关闭当前会话后不发送ping
|
||||||
if (!wsConnection.closeSession) { |
if (!wsConnection.closeSession) { |
||||||
_this.$ws.send("ping"); |
_this.$ws.send("ping"); |
||||||
console.log("ping!", new Date().format("yyyy-MM-dd hh:mm:ss")); |
console.log("ping!", new Date().format("yyyy-MM-dd hh:mm:ss")); |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
//如果超过一定时间还没重置,说明后端主动断开了
|
//如果超过一定时间还没重置,说明后端主动断开了
|
||||||
_this.serverTimeoutObj = setTimeout(() => { |
_this.serverTimeoutObj = setTimeout(() => { |
||||||
//如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
|
//如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
|
||||||
_this.$ws.close(); |
_this.$ws.close(); |
||||||
}, _this.timeout) |
}, _this.timeout) |
||||||
}, this.timeout); |
}, this.timeout); |
||||||
}, |
}, |
||||||
//重置websocket心跳
|
//重置websocket心跳
|
||||||
resetHeartbeat: function () { |
resetHeartbeat: function () { |
||||||
let _this = this; |
let _this = this; |
||||||
this.reconectNum = 0; |
this.reconectNum = 0; |
||||||
clearTimeout(_this.timeoutObj); |
clearTimeout(_this.timeoutObj); |
||||||
clearTimeout(_this.serverTimeoutObj); |
clearTimeout(_this.serverTimeoutObj); |
||||||
_this.startWsHeartbeat(); |
_this.startWsHeartbeat(); |
||||||
}, |
}, |
||||||
wsError: function (err) { |
wsError: function (err) { |
||||||
console.log(err, 'ws error'); |
console.log(err, 'ws error'); |
||||||
// store.commit('set_otherTips', "洋洋客服(未连接)");
|
// store.commit('set_otherTips', "洋洋客服(未连接)");
|
||||||
document.setTitle('洋洋客服(未连接)') |
document.setTitle('洋洋客服(未连接)') |
||||||
wsConnection.reconnect() |
wsConnection.reconnect() |
||||||
}, |
}, |
||||||
wsClose: function (e) { |
wsClose: function (e) { |
||||||
// console.log(e, 'ws close')
|
// console.log(e, 'ws close')
|
||||||
console.log("连接关闭! " + new Date().format("yyyy-MM-dd hh:mm:ss")); |
console.log("连接关闭! " + new Date().format("yyyy-MM-dd hh:mm:ss")); |
||||||
console.log('websocket 断开: ' + e.code + ' 关闭的原因:' + e.reason + ' 是否正常关闭' + e.wasClean); |
console.log('websocket 断开: ' + e.code + ' 关闭的原因:' + e.reason + ' 是否正常关闭' + e.wasClean); |
||||||
|
|
||||||
if (e.code !== 1000) { |
if (e.code !== 1000) { |
||||||
// toast('当前会话已结束');
|
// toast('当前会话已结束');
|
||||||
this.lockReturn = false |
this.lockReturn = false |
||||||
clearTimeout(this.timeoutNum) |
clearTimeout(this.timeoutNum) |
||||||
wsConnection.reconnect(); |
wsConnection.reconnect(); |
||||||
// store.commit('set_otherTips', "洋洋客服(未连接)");
|
// store.commit('set_otherTips', "洋洋客服(未连接)");
|
||||||
document.setTitle('洋洋客服(未连接)') |
document.setTitle('洋洋客服(未连接)') |
||||||
//当前转成机器人
|
//当前转成机器人
|
||||||
// store.dispatch('setTransferCustomer', 1);
|
// store.dispatch('setTransferCustomer', 1);
|
||||||
} else { |
} else { |
||||||
this.$ws = null; |
this.$ws = null; |
||||||
clearInterval(this.timeoutObj) |
clearInterval(this.timeoutObj) |
||||||
clearTimeout(this.serverTimeoutObj) |
clearTimeout(this.serverTimeoutObj) |
||||||
// toast('会话已关闭');
|
// toast('会话已关闭');
|
||||||
// store.commit('set_otherTips', "洋洋客服");
|
// store.commit('set_otherTips', "洋洋客服");
|
||||||
document.setTitle('洋洋客服') |
document.setTitle('洋洋客服') |
||||||
wsConnection.$ws.close(); |
wsConnection.$ws.close(); |
||||||
} |
} |
||||||
}, |
}, |
||||||
}; |
}; |
||||||
|
|
||||||
//时间格式化
|
//时间格式化
|
||||||
Date.prototype.format = function (fmt) { |
Date.prototype.format = function (fmt) { |
||||||
var o = { |
var o = { |
||||||
"M+": this.getMonth() + 1, //月份
|
"M+": this.getMonth() + 1, //月份
|
||||||
"d+": this.getDate(), //日
|
"d+": this.getDate(), //日
|
||||||
"h+": this.getHours(), //小时
|
"h+": this.getHours(), //小时
|
||||||
"m+": this.getMinutes(), //分
|
"m+": this.getMinutes(), //分
|
||||||
"s+": this.getSeconds(), //秒
|
"s+": this.getSeconds(), //秒
|
||||||
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
|
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
|
||||||
"S": this.getMilliseconds() //毫秒
|
"S": this.getMilliseconds() //毫秒
|
||||||
}; |
}; |
||||||
if (/(y+)/.test(fmt)) { |
if (/(y+)/.test(fmt)) { |
||||||
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); |
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); |
||||||
} |
} |
||||||
for (var k in o) { |
for (var k in o) { |
||||||
if (new RegExp("(" + k + ")").test(fmt)) { |
if (new RegExp("(" + k + ")").test(fmt)) { |
||||||
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); |
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); |
||||||
} |
} |
||||||
} |
} |
||||||
return fmt; |
return fmt; |
||||||
} |
} |
||||||
|
|
||||||
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
|
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
|
||||||
window.onbeforeunload = function (event) { |
window.onbeforeunload = function (event) { |
||||||
event = event || window.event; |
event = event || window.event; |
||||||
try { |
try { |
||||||
// toast('onbeforeunload关闭当前会话窗口啦');
|
// toast('onbeforeunload关闭当前会话窗口啦');
|
||||||
var oldSessionId = localStorage.getItem('sessionId'); |
var oldSessionId = localStorage.getItem('sessionId'); |
||||||
var liccsAds = localStorage.getItem('liccsAds'); // 记录用户弹窗提示
|
var liccsAds = localStorage.getItem('liccsAds'); // 记录用户弹窗提示
|
||||||
// sessionStorage.removeItem("manualService");
|
// sessionStorage.removeItem("manualService");
|
||||||
if (wsConnection.$ws) { |
if (wsConnection.$ws) { |
||||||
wsConnection.$ws.close(); |
wsConnection.$ws.close(); |
||||||
} |
} |
||||||
//清除本地缓存
|
//清除本地缓存
|
||||||
localStorage.clear(); |
localStorage.clear(); |
||||||
localStorage.sessionId = oldSessionId || ''; |
localStorage.sessionId = oldSessionId || ''; |
||||||
localStorage.liccsAds = liccsAds || ''; |
localStorage.liccsAds = liccsAds || ''; |
||||||
//清除session
|
//清除session
|
||||||
sessionStorage.clear(); |
sessionStorage.clear(); |
||||||
} catch (error) { |
} catch (error) { |
||||||
console.log(error.message) |
console.log(error.message) |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
//安卓处理解决方案
|
//安卓处理解决方案
|
||||||
window.onunload = function (event) { |
window.onunload = function (event) { |
||||||
event = event || window.event; |
event = event || window.event; |
||||||
try { |
try { |
||||||
// toast('onunload关闭当前会话窗口啦');
|
// toast('onunload关闭当前会话窗口啦');
|
||||||
var oldSessionId = localStorage.getItem('sessionId'); |
var oldSessionId = localStorage.getItem('sessionId'); |
||||||
var liccsAds = localStorage.getItem('liccsAds'); // 记录用户弹窗提示
|
var liccsAds = localStorage.getItem('liccsAds'); // 记录用户弹窗提示
|
||||||
// sessionStorage.removeItem("manualService");
|
// sessionStorage.removeItem("manualService");
|
||||||
if (wsConnection.$ws) { |
if (wsConnection.$ws) { |
||||||
wsConnection.$ws.close(); |
wsConnection.$ws.close(); |
||||||
} |
} |
||||||
//清除本地缓存
|
//清除本地缓存
|
||||||
localStorage.clear(); |
localStorage.clear(); |
||||||
localStorage.sessionId = oldSessionId || ''; |
localStorage.sessionId = oldSessionId || ''; |
||||||
localStorage.liccsAds = liccsAds || ''; |
localStorage.liccsAds = liccsAds || ''; |
||||||
//清除session
|
//清除session
|
||||||
sessionStorage.clear(); |
sessionStorage.clear(); |
||||||
} catch (error) { |
} catch (error) { |
||||||
console.log(error.message) |
console.log(error.message) |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
//抛出websocket对象
|
//抛出websocket对象
|
||||||
export default wsConnection |
export default wsConnection |
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,10 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
vue3 |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script setup> |
||||||
|
defineOptions({ |
||||||
|
name: 'word', |
||||||
|
}) |
||||||
|
</script> |
||||||
Loading…
Reference in new issue