|
|
@@ -0,0 +1,840 @@
|
|
|
+<!DOCTYPE html>
|
|
|
+<html lang="en">
|
|
|
+
|
|
|
+<head>
|
|
|
+ <meta charset="UTF-8">
|
|
|
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
|
+ <meta name="viewport"
|
|
|
+ content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no, viewport-fit=cover" />
|
|
|
+ <title>微分AI</title>
|
|
|
+ <!--引入 element-ui 的样式,-->
|
|
|
+ <link rel="stylesheet"
|
|
|
+ href="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742018383195/element-ui.css">
|
|
|
+ <!-- 必须先引入vue, 后使用element-ui -->
|
|
|
+ <script
|
|
|
+ src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017957144/vue.js"></script>
|
|
|
+ <!-- 引入element 的组件库-->
|
|
|
+ <script
|
|
|
+ src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017747738/element-ui.js"></script>
|
|
|
+ <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
|
|
|
+ <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
|
|
|
+ <!-- <script src="js/vconsole.min.js"></script>
|
|
|
+ <script>
|
|
|
+ var vConsole = new window.VConsole();
|
|
|
+ </script> -->
|
|
|
+</head>
|
|
|
+<style>
|
|
|
+ body {
|
|
|
+ margin: 0;
|
|
|
+ padding: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .box {
|
|
|
+ width: 100vw;
|
|
|
+ height: auto;
|
|
|
+ box-sizing: border-box;
|
|
|
+ background: #FAFAFA;
|
|
|
+ }
|
|
|
+
|
|
|
+ .page6 {
|
|
|
+ width: 100vw;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ .tab_list {
|
|
|
+ width: 100%;
|
|
|
+ height: 50px;
|
|
|
+ background: #FAFCFF;
|
|
|
+ position: absolute;
|
|
|
+ top: 90px;
|
|
|
+ border-radius: 15px 15px 0 0;
|
|
|
+ display: flex;
|
|
|
+ padding-top: 15px;
|
|
|
+ padding-left: 15px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+ .tab_item {
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #222222;
|
|
|
+ line-height: 24px;
|
|
|
+ margin-right: 40px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ flex-direction: column;
|
|
|
+ }
|
|
|
+ .tab_item img {
|
|
|
+ width: 12px;
|
|
|
+ }
|
|
|
+ .show_active {
|
|
|
+ color: #1677FF;
|
|
|
+ }
|
|
|
+ .smart_reply {
|
|
|
+ width: 100%;
|
|
|
+ height: calc(100vh - 120px);
|
|
|
+ box-sizing: border-box;
|
|
|
+ background: linear-gradient( 180deg, #FAFCFF 0%, #FAFAFA 100%);
|
|
|
+ padding: 25px 15px 60px 15px;
|
|
|
+ overflow-y: auto;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: space-between;
|
|
|
+ }
|
|
|
+
|
|
|
+ .smart_see {
|
|
|
+ width: 100%;
|
|
|
+ height: calc(100vh - 140px);
|
|
|
+ box-sizing: border-box;
|
|
|
+ background: linear-gradient( 180deg, #FAFCFF 0%, #FAFAFA 100%);
|
|
|
+ padding: 25px 15px 85px 15px;
|
|
|
+ overflow-y: auto;
|
|
|
+ }
|
|
|
+ .smart_form {
|
|
|
+ padding: 15px;
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-radius: 10px;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ }
|
|
|
+ .intent_car {
|
|
|
+ padding: 15px;
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-radius: 10px;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #666666;
|
|
|
+ }
|
|
|
+ .intent {
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #1677FF;
|
|
|
+ padding: 8px 12px 8px 10px;
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-radius: 5px;
|
|
|
+ border: 1px solid #1677FF;
|
|
|
+ width: fit-content;
|
|
|
+ margin-top: 15px;
|
|
|
+ }
|
|
|
+ .sync_btn {
|
|
|
+ background: #1677FF;
|
|
|
+ border-radius: 20px;
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #FFFFFF;
|
|
|
+ text-align: center;
|
|
|
+ padding: 15px 96px;
|
|
|
+ position: fixed;
|
|
|
+ bottom: 34px;
|
|
|
+ margin: 0 20px;
|
|
|
+
|
|
|
+ }
|
|
|
+ .item_lable {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #666666;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
+ .edit_btn {
|
|
|
+ color: #1677FF;
|
|
|
+ }
|
|
|
+ .el-input__inner{
|
|
|
+ border-top: none;
|
|
|
+ border-left: none;
|
|
|
+ border-right: none;
|
|
|
+ border-bottom: 1px solid #F4F3FD;
|
|
|
+ padding: 0;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ border-radius: 0;
|
|
|
+ background-color: #FFFFFF !important;
|
|
|
+ }
|
|
|
+ .el-textarea__inner{
|
|
|
+ border: none;
|
|
|
+ padding: 0;
|
|
|
+ border-radius: 10px;
|
|
|
+ padding: 10px;
|
|
|
+ }
|
|
|
+ .client_msg {
|
|
|
+ width: 100%;
|
|
|
+ height: 120px;
|
|
|
+ background: url('./img/smart_bg.png');
|
|
|
+ background-size: 100% 120px;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ position: relative;
|
|
|
+ padding-top: 20px;
|
|
|
+ padding-left: 20px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ .client_wx {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .client_wx img {
|
|
|
+ width: 56px;
|
|
|
+ height: 56px;
|
|
|
+ border-radius: 10px ;
|
|
|
+ margin-right: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .wx_msg {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: flex-start;
|
|
|
+ justify-content: center;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #FFFFFF;
|
|
|
+ }
|
|
|
+ .wx_name {
|
|
|
+ font-size: 16px;
|
|
|
+ padding-bottom: 5px;
|
|
|
+ }
|
|
|
+ .wx_tag {
|
|
|
+ font-size: 10px;
|
|
|
+ }
|
|
|
+ .loading_text {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #999999;
|
|
|
+ padding-top: 90px;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ .input_style {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ position: fixed;
|
|
|
+ bottom: 10px;
|
|
|
+ }
|
|
|
+ .smart_input {
|
|
|
+ width: 288px;
|
|
|
+ margin-right: 15px;
|
|
|
+ }
|
|
|
+ .smart_input .el-input__inner {
|
|
|
+ height: 50px;
|
|
|
+ border: none;
|
|
|
+ padding: 15px;
|
|
|
+ background: #F6F6F7;
|
|
|
+ border-radius: 20px;
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 20px;
|
|
|
+ margin-bottom: 0;
|
|
|
+ }
|
|
|
+ .send_btn {
|
|
|
+ width: 42px;
|
|
|
+ height: 42px;
|
|
|
+ }
|
|
|
+ .reply_content {
|
|
|
+ background: #F0F4FA;
|
|
|
+ border-radius: 10px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #222222;
|
|
|
+ line-height: 28px;
|
|
|
+ padding: 15px;
|
|
|
+ margin-bottom: 7px;
|
|
|
+ }
|
|
|
+ .reply_title {
|
|
|
+ color: #1677FF;
|
|
|
+ }
|
|
|
+ .copy_div {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: flex-end;
|
|
|
+ border-top: 1px solid #CCD8E8;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #1677FF;
|
|
|
+ line-height: 20px;
|
|
|
+ padding-top: 13px;
|
|
|
+ margin-top: 15px;
|
|
|
+ }
|
|
|
+ .copy_div img {
|
|
|
+ width: 14px;
|
|
|
+ height: 14px;
|
|
|
+ margin-right: 8px;
|
|
|
+ }
|
|
|
+ .send_msg {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #222222;
|
|
|
+ padding: 12px 10px 12px 15px;
|
|
|
+ background: #FFFFFF;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ width: fit-content;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
+ .msg_list {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #222222;
|
|
|
+ padding: 12px 10px 12px 15px;
|
|
|
+ background: #FFFFFF;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ width: fit-content;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
+ .msg_list img {
|
|
|
+ width: 16px;
|
|
|
+ height: 16px;
|
|
|
+ margin-left: 8px;
|
|
|
+ }
|
|
|
+</style>
|
|
|
+
|
|
|
+<body>
|
|
|
+ <div id="box" class="box">
|
|
|
+ <div class="page6">
|
|
|
+ <div class="client_msg">
|
|
|
+ <div class="client_wx">
|
|
|
+ <img :src="clientData.avatar" />
|
|
|
+ <div class="wx_msg">
|
|
|
+ <div class="wx_name">{{clientData.name}}</div>
|
|
|
+ <div class="wx_tag">@微信</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="tab_list">
|
|
|
+ <div class="tab_item" @click="handleClick('first')">
|
|
|
+ <div :class="activeName === 'first' ? 'show_active' : ''">智能回复</div>
|
|
|
+ <img src="./img/tab_line.png" v-show="activeName ==='first'" />
|
|
|
+ </div>
|
|
|
+ <div class="tab_item" @click="handleClick('second')">
|
|
|
+ <div :class="activeName === 'second' ? 'show_active' : ''">智能洞察</div>
|
|
|
+ <img src="./img/tab_line.png" v-show="activeName ==='second'" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="smart_reply" v-if="activeName ==='first'">
|
|
|
+ <div class="loading_text" v-if="!lastMsgData.length && !replyData.problem">暂无新提问或正在同步中…</div>
|
|
|
+ <div>
|
|
|
+ <div class="send_msg" v-if="replyData.problem">
|
|
|
+ <span>{{replyData.problem}}</span>
|
|
|
+ </div>
|
|
|
+ <div class="reply_content" v-if="loading || replyData.reply">
|
|
|
+ <div class="reply_title">智能回复:</div>
|
|
|
+ <div>{{loading ? '思考中...' : replyData.reply}}</div>
|
|
|
+ <div class="copy_div" @click="handleCopy(replyData.reply)">
|
|
|
+ <img src="./img/copy_icon2.png" alt="">
|
|
|
+ <span>复制</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <div class="msg_list" v-for="(item, index) in lastMsgData" :key="index" @click="sendMsg(item)">
|
|
|
+ <span>{{item.content}}</span>
|
|
|
+ <img src="./img/msg_icon.png" alt="">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="input_style">
|
|
|
+ <el-input class="smart_input" placeholder="请输入您的问题" v-model="problem">
|
|
|
+ </el-input>
|
|
|
+ <img class="send_btn" src="./img/send_btn2.png" @click="sendMsg('')"></img>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="smart_see" v-if="activeName === 'second'">
|
|
|
+ <div class="smart_form">
|
|
|
+ <div class="item_lable">
|
|
|
+ <div>手机号</div>
|
|
|
+ <div class="edit_btn" @click="handleSave(1, disabled1)">{{disabled1 ? '编辑' : '确定'}}</div>
|
|
|
+ </div>
|
|
|
+ <el-input v-model="insightData.phone" type="number" :readonly="disabled1" placeholder="请输入内容"></el-input>
|
|
|
+ <div class="item_lable">
|
|
|
+ <div>地区</div>
|
|
|
+ <div class="edit_btn" @click="handleSave(2, disabled2)">{{disabled2 ? '编辑' : '确定'}}</div>
|
|
|
+ </div>
|
|
|
+ <el-cascader v-model="areaData" :options="transformedData" style="width: 100%;" :disabled="disabled2"
|
|
|
+ @change="handleInfoCity">
|
|
|
+ </el-cascader>
|
|
|
+ <div class="item_lable">
|
|
|
+ <div>详细地址</div>
|
|
|
+ <div class="edit_btn" @click="handleSave(3, disabled3)">{{disabled3 ? '编辑' : '确定'}}</div>
|
|
|
+ </div>
|
|
|
+ <el-input type="textarea" :autosize="{ minRows: 3 }" placeholder="暂无" v-model="insightData.address" :disabled="disabled3">
|
|
|
+ </el-input>
|
|
|
+ </div>
|
|
|
+ <div class="intent_car">
|
|
|
+ <div>意向车型</div>
|
|
|
+ <div class="intent" v-if="insightData.intent">{{insightData.intent}}</div>
|
|
|
+ </div>
|
|
|
+ <div class="sync_btn" @click="handleSync">同步到用户画像</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</body>
|
|
|
+<script>
|
|
|
+ new Vue({
|
|
|
+ el: '#box',
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ httpUrl: '',
|
|
|
+ bId: null,
|
|
|
+ env: '',
|
|
|
+ memberId: null,
|
|
|
+ externalUserId: null,
|
|
|
+ activeName: 'first',
|
|
|
+ clientData: {
|
|
|
+ avatar: '',
|
|
|
+ name: '',
|
|
|
+ },
|
|
|
+ lastMsgData: [],
|
|
|
+ problem: '',
|
|
|
+ replyData: {
|
|
|
+ messageId: '',
|
|
|
+ problem: '',
|
|
|
+ reply: '',
|
|
|
+ },
|
|
|
+ timer: null,
|
|
|
+ secondTimer: null,
|
|
|
+ loading: false,
|
|
|
+ disabled1: true,
|
|
|
+ disabled2: true,
|
|
|
+ disabled3: true,
|
|
|
+ insightData: {
|
|
|
+ phone: '',
|
|
|
+ province: '',
|
|
|
+ city: '',
|
|
|
+ address: '',
|
|
|
+ intent: '',
|
|
|
+ },
|
|
|
+ transformedData: [],
|
|
|
+ areaData: [],
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.bId = this.getQueryParam('bId')
|
|
|
+ this.env = this.getQueryParam('env')
|
|
|
+ if (!this.env || this.env === 'prod') {
|
|
|
+ this.httpUrl = 'https://wlapi.wefanbot.com'
|
|
|
+ } else {
|
|
|
+ this.httpUrl = 'http://test.wefanbot.com:18993'
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.getQueryParam('memberId')) {
|
|
|
+ // 已授权
|
|
|
+ this.memberId = this.getQueryParam('memberId')
|
|
|
+ if (this.getQueryParam('externalUserId')) {
|
|
|
+ this.externalUserId = this.getQueryParam('externalUserId')
|
|
|
+ this.getClientExt()
|
|
|
+ this.getLastMsg()
|
|
|
+ // 设置定时器:每60秒刷新一次
|
|
|
+ this.timer = setInterval(() => {
|
|
|
+ this.getLastMsg()
|
|
|
+ }, 60 * 1000)
|
|
|
+ this.insight()
|
|
|
+ this.secondTimer = setInterval(() => {
|
|
|
+ this.insight()
|
|
|
+ }, 60 * 1000)
|
|
|
+ this.getCityLevel()
|
|
|
+ } else {
|
|
|
+ this.getQyWxSign()
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 授权
|
|
|
+ this.getAuth()
|
|
|
+ }
|
|
|
+ // this.memberId = "woU17nDAAAfzP9lzjd-G8iwCiveKR8GA"
|
|
|
+ // this.externalUserId = "wmU17nDAAALFy-xUBJDwHbB5CsjzeY_g"
|
|
|
+ // this.getClientExt()
|
|
|
+ // this.getLastMsg()
|
|
|
+ // // 设置定时器:每60秒刷新一次
|
|
|
+ // this.timer = setInterval(() => {
|
|
|
+ // this.getLastMsg()
|
|
|
+ // }, 60 * 1000)
|
|
|
+ // this.getCityLevel()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ getAuth() {
|
|
|
+ fetch(this.httpUrl + `/p/insuite/p/getRedirectUri?env=${this.env}&bId=${this.bId}`)
|
|
|
+ .then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ window.location.replace(data)
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: msg,
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getQyWxSign() {
|
|
|
+ fetch(this.httpUrl + '/scrm/v1/wxcp-corp/p/getAgentConfig', {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ bId: this.bId,
|
|
|
+ url: window.location.href,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json'
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ let that = this
|
|
|
+ wx.agentConfig({
|
|
|
+ corpid: data.corpid,
|
|
|
+ agentid: data.agentId,
|
|
|
+ timestamp: data.timestamp, // 必填,生成签名的时间戳
|
|
|
+ nonceStr: data.nonceStr, // 必填,生成签名的随机串
|
|
|
+ signature: data.agentSignature, // 必填,签名,见附录1
|
|
|
+ jsApiList: ['getCurExternalContact'], // 必填,需要使用的JS接口列表
|
|
|
+ success: function (res) {
|
|
|
+ // 回调
|
|
|
+ // 此处直接在注入回调中调用了获取当前外部联系人userId的接口,注意此接口是从聊天框的工具栏进入才能获取
|
|
|
+ wx.invoke('getCurExternalContact', {
|
|
|
+ }, function (res) {
|
|
|
+ if (res.err_msg == "getCurExternalContact:ok") {
|
|
|
+ console.log('invoke成功:', res.userId);
|
|
|
+ that.externalUserId = res.userId
|
|
|
+ that.getClientExt()
|
|
|
+ that.getLastMsg()
|
|
|
+ // 设置定时器:每60秒刷新一次
|
|
|
+ that.timer = setInterval(() => {
|
|
|
+ that.getLastMsg()
|
|
|
+ }, 60 * 1000)
|
|
|
+ that.insight()
|
|
|
+ that.secondTimer = setInterval(() => {
|
|
|
+ that.insight()
|
|
|
+ }, 60 * 1000)
|
|
|
+ that.getCityLevel()
|
|
|
+ } else {
|
|
|
+ //错误处理
|
|
|
+ console.log('invoke失败:', res)
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ },
|
|
|
+ fail: function (res) {
|
|
|
+ if (res.errMsg.indexOf('function not exist') > -1) {
|
|
|
+ alert('版本过低请升级');
|
|
|
+ }
|
|
|
+ },
|
|
|
+ complete: function (res) {
|
|
|
+ // 回调
|
|
|
+ console.log('complete1', res);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: msg,
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ handleClick(tabName) {
|
|
|
+ this.activeName = tabName
|
|
|
+ if (tabName === 'second') {
|
|
|
+ this.insight()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 获取客户画像
|
|
|
+ getClientExt() {
|
|
|
+ fetch(this.httpUrl + '/scrm/v1/wxcp-client/p/h5clientInfo', {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ bid: this.bId,
|
|
|
+ externalUserId: this.externalUserId,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json'
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.clientData = data
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: msg,
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 获取智能回复提示
|
|
|
+ getLastMsg() {
|
|
|
+ fetch(this.httpUrl + '/scrm/v1/wxcp-message/p/getLastMessagesByH5', {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ bid: this.bId,
|
|
|
+ externalUserId: this.externalUserId,
|
|
|
+ memberId: this.memberId,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json'
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.lastMsgData = data
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: msg,
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ sendMsg(item) {
|
|
|
+ if (!item.id && !this.problem) {
|
|
|
+ this.$message({
|
|
|
+ message: '请输入内容',
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.replyData.problem = item.id ? item.content : this.problem
|
|
|
+ this.loading = true
|
|
|
+ fetch(this.httpUrl + '/scrm/v1/tenancy-ai/p/h5AiReply', {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ bid: this.bId,
|
|
|
+ externalUserId: this.externalUserId,
|
|
|
+ memberId: this.memberId,
|
|
|
+ messageId: item.id,
|
|
|
+ problem: item.id ? '' : this.problem,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json'
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.replyData = {
|
|
|
+ messageId: item.id,
|
|
|
+ problem: item.id ? item.content : data.problem,
|
|
|
+ reply: '',
|
|
|
+ }
|
|
|
+ this.titleWriter(data.reply)
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: msg,
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }).finally(() => {
|
|
|
+ this.problem = ''
|
|
|
+ this.loading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ titleWriter (str) {
|
|
|
+ let that = this
|
|
|
+ let i = 0;
|
|
|
+ let timer = setInterval(function () {
|
|
|
+ that.replyData.reply += str[i];
|
|
|
+ i++;
|
|
|
+ if (i >= str.length) {
|
|
|
+ clearInterval(timer);
|
|
|
+ }
|
|
|
+ }, 50);
|
|
|
+ },
|
|
|
+ // 客户洞察
|
|
|
+ insight () {
|
|
|
+ fetch(this.httpUrl + '/scrm/v1/wxcp-chat-tool/p/h5Insight', {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ bid: this.bId,
|
|
|
+ externalUserId: this.externalUserId,
|
|
|
+ memberId: this.memberId,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json'
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.insightData = data
|
|
|
+ this.areaData = [data.province, data.city]
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: msg,
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ handleSave (num, status) {
|
|
|
+ if (num === 1) {
|
|
|
+ if (this.insightData.phone && this.insightData.phone.length !== 11) {
|
|
|
+ this.$message({
|
|
|
+ message: '请输入正确的手机号',
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.disabled1 = !status
|
|
|
+ if (status) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ } else if (num === 2) {
|
|
|
+ this.disabled2 = !status
|
|
|
+ if (status) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ } else if (num === 3) {
|
|
|
+ this.disabled3 = !status
|
|
|
+ if (status) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ fetch(this.httpUrl + '/scrm/v1/wxcp-chat-tool/p/update2Insight', {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ bid: this.bId,
|
|
|
+ externalUserId: this.externalUserId,
|
|
|
+ memberId: this.memberId,
|
|
|
+ ...this.insightData
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json'
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.$message({
|
|
|
+ message: '保存成功',
|
|
|
+ type: 'success'
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: msg,
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ handleSync () {
|
|
|
+ fetch(this.httpUrl + '/scrm/v1/wxcp-chat-tool/p/sync2Ext', {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ bid: this.bId,
|
|
|
+ externalUserId: this.externalUserId,
|
|
|
+ memberId: this.memberId,
|
|
|
+ ...this.insightData
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json'
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.$message({
|
|
|
+ message: '同步成功',
|
|
|
+ type: 'success'
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: msg,
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }).finally(() => {
|
|
|
+ this.disabled1 = true
|
|
|
+ this.disabled2 = true
|
|
|
+ this.disabled3 = true
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 获取城市数据
|
|
|
+ getCityLevel() {
|
|
|
+ fetch('https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/1000/1720161853377/pc-code.json')
|
|
|
+ .then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ this.transformedData = this.transformData(result)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ handleInfoCity(value) {
|
|
|
+ this.insightData.province = value[0]
|
|
|
+ this.insightData.city = value[1]
|
|
|
+ },
|
|
|
+ // 省市数据做转换
|
|
|
+ transformData(data) {
|
|
|
+ return data.map(item => {
|
|
|
+ // 创建一个新对象,避免直接修改原始对象
|
|
|
+ const newItem = { ...item };
|
|
|
+
|
|
|
+ // 重命名 text 为 label
|
|
|
+ if (newItem.text) {
|
|
|
+ newItem.label = newItem.text;
|
|
|
+ newItem.value = newItem.text;
|
|
|
+ delete newItem.text;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果存在 children 数组,则递归处理每个子项
|
|
|
+ if (newItem.children && Array.isArray(newItem.children)) {
|
|
|
+ newItem.children = this.transformData(newItem.children);
|
|
|
+ }
|
|
|
+
|
|
|
+ return newItem;
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 截取url中的数据
|
|
|
+ getQueryParam(paramName) {
|
|
|
+ // 获取当前URL的查询字符串部分
|
|
|
+ const queryString = window.location.search;
|
|
|
+ // 创建一个URLSearchParams对象
|
|
|
+ const urlParams = new URLSearchParams(queryString);
|
|
|
+ // 返回指定参数的值,如果不存在则返回null
|
|
|
+ return urlParams.get(paramName);
|
|
|
+ },
|
|
|
+ // 检测是否iOS端
|
|
|
+ iosAgent() {
|
|
|
+ return navigator.userAgent.match(/(iPhone|iPod|iPad);?/i);
|
|
|
+ },
|
|
|
+ // 复制文本函数,微信端,需要在用户触发 Click 事件里面才能执行成功
|
|
|
+ handleCopy(message) {
|
|
|
+ if (this.iosAgent()) {
|
|
|
+ let inputObj = document.createElement("input");
|
|
|
+ inputObj.value = message;
|
|
|
+ document.body.appendChild(inputObj);
|
|
|
+ inputObj.select();
|
|
|
+ inputObj.setSelectionRange(0, inputObj.value.length);
|
|
|
+ this.execCommand('Copy');
|
|
|
+ document.body.removeChild(inputObj);
|
|
|
+ } else {
|
|
|
+ let domObj = document.createElement("span");
|
|
|
+ domObj.innerHTML = message;
|
|
|
+ document.body.appendChild(domObj);
|
|
|
+ let selection = window.getSelection();
|
|
|
+ let range = document.createRange();
|
|
|
+ range.selectNodeContents(domObj);
|
|
|
+ selection.removeAllRanges();
|
|
|
+ selection.addRange(range);
|
|
|
+ this.execCommand('Copy');
|
|
|
+ document.body.removeChild(domObj);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 执行浏览器命令 Copy 顺便输出一下日志,如果在移动端推荐写个方法展示日志或者用alert(msg)也行。
|
|
|
+ execCommand(action) {
|
|
|
+ let is = document.execCommand(action);
|
|
|
+ if (is) {
|
|
|
+ this.$message({
|
|
|
+ message: '复制成功',
|
|
|
+ type: 'success'
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: '复制失败',
|
|
|
+ type: 'error'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ }
|
|
|
+ })
|
|
|
+</script>
|
|
|
+
|
|
|
+</html>
|