|
@@ -1,9 +1,10 @@
|
|
<template>
|
|
<template>
|
|
<view class="content" :style="{paddingBottom: paddingBottom}">
|
|
<view class="content" :style="{paddingBottom: paddingBottom}">
|
|
- <view class="item" v-for="(item, index) in json" :class="item.classText.join(' ')" @click="click(item)">
|
|
|
|
|
|
+ <view class="item" v-for="(item, index) in json" :class="item.classText.join(' ')" @click="click(item, 0)">
|
|
<p v-if="item.type === 'h5-text'" :style="item.style">{{ item.content }}</p>
|
|
<p v-if="item.type === 'h5-text'" :style="item.style">{{ item.content }}</p>
|
|
- <img :ref="'myImage' + index" @load="handleImageLoad(index, item)" v-if="item.type === 'h5-image'"
|
|
|
|
- :src="item.url"/>
|
|
|
|
|
|
+ <img :ref="'myImage' + index" @load="handleImageLoad(index, item)" v-if="item.type === 'h5-image'" :src="item.url"/>
|
|
|
|
+ <view class="image-child" v-if="item.type === 'h5-image'"></view>
|
|
|
|
+
|
|
<div v-if="item.type === 'h5-sep'" :class="item.classText.join(' ')"></div>
|
|
<div v-if="item.type === 'h5-sep'" :class="item.classText.join(' ')"></div>
|
|
<div class="countdown2-box"
|
|
<div class="countdown2-box"
|
|
:style="{ backgroundImage: item.bgImage && item.bgImage !== '#' ? `url(${item.bgImage})` : '' }"
|
|
:style="{ backgroundImage: item.bgImage && item.bgImage !== '#' ? `url(${item.bgImage})` : '' }"
|
|
@@ -21,13 +22,14 @@
|
|
<div v-for="(message, index) in item.messages" :key="index"
|
|
<div v-for="(message, index) in item.messages" :key="index"
|
|
:class="['message-wrapper', message.sender === 'user' ? 'user-message' : 'agent-message']"
|
|
:class="['message-wrapper', message.sender === 'user' ? 'user-message' : 'agent-message']"
|
|
>
|
|
>
|
|
|
|
+
|
|
<div class="avatar">
|
|
<div class="avatar">
|
|
<img :src="message.sender === 'user' ? userAvatar : getAgentAvatar(item)" alt="Avatar"/>
|
|
<img :src="message.sender === 'user' ? userAvatar : getAgentAvatar(item)" alt="Avatar"/>
|
|
</div>
|
|
</div>
|
|
<div class="message-content">
|
|
<div class="message-content">
|
|
<div v-if="message.text" class="message-text" v-html="message.text"></div>
|
|
<div v-if="message.text" class="message-text" v-html="message.text"></div>
|
|
<!-- Options buttons -->
|
|
<!-- Options buttons -->
|
|
- <div v-if="message.options && message.options.length > 0" class="options-container">
|
|
|
|
|
|
+ <div v-if="message.options && message.options.length > 0 && !message.click" class="options-container">
|
|
<button
|
|
<button
|
|
v-for="(option, optIndex) in message.options"
|
|
v-for="(option, optIndex) in message.options"
|
|
:key="optIndex"
|
|
:key="optIndex"
|
|
@@ -42,6 +44,7 @@
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
+ <img v-if="item.showButton" :ref="'addButton' + index" @load="handleImageLoad2(index, item)" :style="item.addWxButtonStyle" :src="item.addWxButtonImg" @click.stop="click(item, 1)" style="width: 100%;" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@@ -50,7 +53,7 @@
|
|
</template>
|
|
</template>
|
|
<script>
|
|
<script>
|
|
// 引入Clipboard
|
|
// 引入Clipboard
|
|
-import {getTemplateByNo, getTemplateById, callback, youkuClickCallback, iqiyiClickCallback} from '../../api/api.js'
|
|
|
|
|
|
+import {getTemplateByNo, getTemplateById, baiduClickCallback, callback, youkuClickCallback, iqiyiClickCallback, dyClickCallback} from '../../api/api.js'
|
|
import agentAvatar from '../../static/customer.png'
|
|
import agentAvatar from '../../static/customer.png'
|
|
import userAvatar from '../../static/profile.png'
|
|
import userAvatar from '../../static/profile.png'
|
|
|
|
|
|
@@ -72,6 +75,7 @@ export default {
|
|
type: 0,
|
|
type: 0,
|
|
show: false,
|
|
show: false,
|
|
name: '',
|
|
name: '',
|
|
|
|
+ url: "",
|
|
tel: '',
|
|
tel: '',
|
|
accountId: '',
|
|
accountId: '',
|
|
ip: '',
|
|
ip: '',
|
|
@@ -87,6 +91,7 @@ export default {
|
|
window.vueInstance = this // 将 Vue 实例暴露到全局
|
|
window.vueInstance = this // 将 Vue 实例暴露到全局
|
|
},
|
|
},
|
|
onLoad(option) {
|
|
onLoad(option) {
|
|
|
|
+ this.url = window.location.href;
|
|
this.params = option;
|
|
this.params = option;
|
|
this.no = this.params.no;
|
|
this.no = this.params.no;
|
|
this.id = this.params.tid;
|
|
this.id = this.params.tid;
|
|
@@ -145,6 +150,13 @@ export default {
|
|
this.impress_id = this.params.impress_id;
|
|
this.impress_id = this.params.impress_id;
|
|
this.sign = this.params.sign;
|
|
this.sign = this.params.sign;
|
|
}
|
|
}
|
|
|
|
+ // 巨量(抖音)
|
|
|
|
+ if (this.type == 3) {
|
|
|
|
+ this.click_id = this.params.clickid;
|
|
|
|
+ this.creative_id = this.params.creativeid;
|
|
|
|
+ this.vid = this.params.adid;
|
|
|
|
+ }
|
|
|
|
+ console.info(this.params.adid)
|
|
this.loadCountdownData();
|
|
this.loadCountdownData();
|
|
this.loadChatMessage();
|
|
this.loadChatMessage();
|
|
},
|
|
},
|
|
@@ -173,7 +185,7 @@ export default {
|
|
}
|
|
}
|
|
// 如果有答案就直接用户消息和客服消息
|
|
// 如果有答案就直接用户消息和客服消息
|
|
let nextMsg = h5ChatItem.agentMsg.shift();
|
|
let nextMsg = h5ChatItem.agentMsg.shift();
|
|
-
|
|
|
|
|
|
+ message.click = true;
|
|
h5ChatItem.messages.push({
|
|
h5ChatItem.messages.push({
|
|
id: this.getChatMsgIdMax(),
|
|
id: this.getChatMsgIdMax(),
|
|
sender: 'user',
|
|
sender: 'user',
|
|
@@ -212,15 +224,22 @@ export default {
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
if (h5ChatItem.agentMsg.length === 0) {
|
|
if (h5ChatItem.agentMsg.length === 0) {
|
|
- await this.delay(1000);
|
|
|
|
|
|
+ await this.delay(200);
|
|
|
|
+ if(h5ChatItem.addWxFun){
|
|
|
|
+ //显示加微按钮
|
|
|
|
+ h5ChatItem.showButton = true;
|
|
|
|
+ }
|
|
h5ChatItem.messages.push({
|
|
h5ChatItem.messages.push({
|
|
id: this.getChatMsgIdMax(),
|
|
id: this.getChatMsgIdMax(),
|
|
sender: 'agent',
|
|
sender: 'agent',
|
|
- text: "好的,已经为您分配专业老师。<span style='color:red'>【点击下方按钮】</span>添加老师,获取免费上课链接。!",
|
|
|
|
|
|
+ text: h5ChatItem.lastMsg.map(e => {
|
|
|
|
+ if(e.type == 0) return e.text;
|
|
|
|
+ if(e.type == 1) return "<span style='color: red'>"+ e.text +"</span>";
|
|
|
|
+ }).join(""),
|
|
options: []
|
|
options: []
|
|
});
|
|
});
|
|
|
|
+
|
|
}
|
|
}
|
|
}catch (err) {
|
|
}catch (err) {
|
|
console.error(err);
|
|
console.error(err);
|
|
@@ -243,6 +262,7 @@ export default {
|
|
// 加载聊天组件的消息
|
|
// 加载聊天组件的消息
|
|
async loadChatMessage() {
|
|
async loadChatMessage() {
|
|
let h5ChatItem = this.json.filter(e => e.type === 'h5-chat')[0]
|
|
let h5ChatItem = this.json.filter(e => e.type === 'h5-chat')[0]
|
|
|
|
+ if(!h5ChatItem) return;
|
|
h5ChatItem.messages = []
|
|
h5ChatItem.messages = []
|
|
|
|
|
|
// 先输出所有的欢迎信息,欢迎信息为没有options的数据,以及后面一条数据
|
|
// 先输出所有的欢迎信息,欢迎信息为没有options的数据,以及后面一条数据
|
|
@@ -392,17 +412,53 @@ export default {
|
|
this.paddingBottom = clientHeight + "px";
|
|
this.paddingBottom = clientHeight + "px";
|
|
}
|
|
}
|
|
},
|
|
},
|
|
|
|
+ handleImageLoad2(index, item) {
|
|
|
|
+ const imgElement = this.$refs["addButton" + index][0]; // 获取图片 DOM 元素
|
|
|
|
+
|
|
|
|
+ // 1. 获取图片原始宽高
|
|
|
|
+ const naturalWidth = imgElement.naturalWidth;
|
|
|
|
+ const naturalHeight = imgElement.naturalHeight;
|
|
|
|
+
|
|
|
|
+ // 2. 获取容器尺寸(假设容器是图片的父元素)
|
|
|
|
+ const container = imgElement.parentElement;
|
|
|
|
+ const containerWidth = container.clientWidth;
|
|
|
|
+ const containerHeight = container.clientHeight;
|
|
|
|
+
|
|
|
|
+ // 3. 计算缩放后的宽高(保持比例)
|
|
|
|
+ const imageAspectRatio = naturalWidth / naturalHeight; // 原始宽高比
|
|
|
|
+ const containerAspectRatio = containerWidth / containerHeight; // 容器宽高比
|
|
|
|
+
|
|
|
|
+ let targetWidth, targetHeight;
|
|
|
|
+
|
|
|
|
+ // 根据容器宽高比决定以哪一边为基准缩放
|
|
|
|
+ if (containerAspectRatio > imageAspectRatio) {
|
|
|
|
+ // 容器更宽,以高度为基准
|
|
|
|
+ targetHeight = containerHeight;
|
|
|
|
+ targetWidth = targetHeight * imageAspectRatio;
|
|
|
|
+ } else {
|
|
|
|
+ // 容器更高,以宽度为基准
|
|
|
|
+ targetWidth = containerWidth;
|
|
|
|
+ targetHeight = targetWidth / imageAspectRatio;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 4. 应用缩放后的尺寸
|
|
|
|
+ imgElement.style.width = `${targetWidth - 16}px`;
|
|
|
|
+ imgElement.style.height = `${targetHeight}px`;
|
|
|
|
+ },
|
|
confirm() {
|
|
confirm() {
|
|
this.show = false
|
|
this.show = false
|
|
},
|
|
},
|
|
clickToWx(workUrl) {
|
|
clickToWx(workUrl) {
|
|
|
|
+ if(this.site && this.site.workUrl != null && this.site.workUrl != undefined && this.site.workUrl != ''){
|
|
|
|
+ workUrl = this.site.workUrl;
|
|
|
|
+ }
|
|
// 百度
|
|
// 百度
|
|
if (this.type == 0) {
|
|
if (this.type == 0) {
|
|
let data = {
|
|
let data = {
|
|
id: this.id,
|
|
id: this.id,
|
|
url: window.location.href,
|
|
url: window.location.href,
|
|
vid: this.vid,
|
|
vid: this.vid,
|
|
- clickType: 67,
|
|
|
|
|
|
+ clickType: 79,
|
|
};
|
|
};
|
|
baiduClickCallback(data).then(e => {
|
|
baiduClickCallback(data).then(e => {
|
|
window.location.href = workUrl + "?customer_channel=" + this.vid;
|
|
window.location.href = workUrl + "?customer_channel=" + this.vid;
|
|
@@ -417,6 +473,7 @@ export default {
|
|
aid: this.aid,
|
|
aid: this.aid,
|
|
clickId: this.click_id,
|
|
clickId: this.click_id,
|
|
ip: this.ip,
|
|
ip: this.ip,
|
|
|
|
+ clickType: "wechat"
|
|
};
|
|
};
|
|
youkuClickCallback(data).then(e => {
|
|
youkuClickCallback(data).then(e => {
|
|
window.location.href = workUrl + "?customer_channel=" + this.vid;
|
|
window.location.href = workUrl + "?customer_channel=" + this.vid;
|
|
@@ -448,18 +505,41 @@ export default {
|
|
sign: this.sign,
|
|
sign: this.sign,
|
|
clickType: "200"
|
|
clickType: "200"
|
|
};
|
|
};
|
|
- iqiyiClickCallback(data).then(e => {
|
|
|
|
|
|
+ dyClickCallback(data).then(e => {
|
|
window.location.href = workUrl + "?customer_channel=" + this.impress_id;
|
|
window.location.href = workUrl + "?customer_channel=" + this.impress_id;
|
|
})
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ // 爱奇艺
|
|
|
|
+ if (this.type == 3) {
|
|
|
|
+ let data = {
|
|
|
|
+ url: window.location.href,
|
|
|
|
+ id: this.id,
|
|
|
|
+ clickId: this.click_id,
|
|
|
|
+ creativeId: this.creative_id,
|
|
|
|
+ vid:this.vid
|
|
|
|
+ };
|
|
|
|
+ dyClickCallback(data).then(e => {
|
|
|
|
+ window.location.href = workUrl + "?customer_channel=" + this.vid;
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if (this.type == 99) {
|
|
|
|
+ window.location.href = workUrl + "?customer_channel=" + '{"siteId":'+this.id+'}';
|
|
|
|
+ }
|
|
|
|
|
|
},
|
|
},
|
|
- click(item) {
|
|
|
|
- if (!item.addWxFun) {
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
- this.clickToWx(item.workUrl)
|
|
|
|
|
|
+ click(item, type) {
|
|
|
|
+ if(type == 0){
|
|
|
|
+ console.info(item)
|
|
|
|
+ if (!item.addWxFun || item.type === "h5-chat") {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ this.clickToWx(item.workUrl)
|
|
|
|
+ }else{
|
|
|
|
+ this.clickToWx(item.workUrl)
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -484,6 +564,7 @@ export default {
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
width: 100%;
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
|
|
+ font-weight: bold;
|
|
}
|
|
}
|
|
|
|
|
|
.message-wrapper {
|
|
.message-wrapper {
|
|
@@ -493,6 +574,9 @@ export default {
|
|
width: auto;
|
|
width: auto;
|
|
align-items: flex-start;
|
|
align-items: flex-start;
|
|
}
|
|
}
|
|
|
|
+.message-wrapper:last-child{
|
|
|
|
+ margin-bottom: 0 !important;
|
|
|
|
+}
|
|
|
|
|
|
.agent-message {
|
|
.agent-message {
|
|
align-self: flex-start;
|
|
align-self: flex-start;
|
|
@@ -527,6 +611,9 @@ export default {
|
|
min-width: 0;
|
|
min-width: 0;
|
|
width: auto;
|
|
width: auto;
|
|
}
|
|
}
|
|
|
|
+.message-content>.message-text,.message-content .option-button{
|
|
|
|
+ font-size: 17px;
|
|
|
|
+}
|
|
|
|
|
|
.message-text {
|
|
.message-text {
|
|
padding: 10px 12px;
|
|
padding: 10px 12px;
|
|
@@ -639,12 +726,21 @@ input, button {
|
|
min-height: 32px;
|
|
min-height: 32px;
|
|
}
|
|
}
|
|
.item {
|
|
.item {
|
|
|
|
+ position: relative;
|
|
display: flex;
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
flex: 1;
|
|
flex: 1;
|
|
margin: 0;
|
|
margin: 0;
|
|
width: 100%;
|
|
width: 100%;
|
|
-
|
|
|
|
|
|
+ .image-child{
|
|
|
|
+ position: absolute;
|
|
|
|
+ top: 0%;
|
|
|
|
+ left: 0;
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100%;
|
|
|
|
+ background-color: transparent; /* 设置为透明 */
|
|
|
|
+ z-index: 1000;
|
|
|
|
+ }
|
|
img {
|
|
img {
|
|
width: 100%;
|
|
width: 100%;
|
|
}
|
|
}
|