首页更新
This commit is contained in:
parent
89f384e858
commit
6138987986
@ -163,6 +163,25 @@ export function reqApproveUserSearch(data){
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 咨询表单状态切换
|
||||||
|
export function reqUserInquiryStatusSwitch(data){
|
||||||
|
return request({
|
||||||
|
url: '/product/update_user_inquiry.dspy',
|
||||||
|
method: 'get',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
params: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 咨询表单删除(批量 单个)
|
||||||
|
export function reqUserInquiryDelete(data){
|
||||||
|
return request({
|
||||||
|
url: '/product/delete_user_inquiry.dspy',
|
||||||
|
method: 'get',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
params: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
//政企审核 更新 /user/enterprise_audit_info_update.dspy
|
//政企审核 更新 /user/enterprise_audit_info_update.dspy
|
||||||
|
|
||||||
export function reqEnterpriseUpdate(data){
|
export function reqEnterpriseUpdate(data){
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div>
|
<div>
|
||||||
<div class="contener" v-if=" orgType == 2 || orgType == 3 || !userid">
|
<div class="contener" v-if="shouldShowFloatingConsult">
|
||||||
|
|
||||||
|
|
||||||
<transition name="slide">
|
<transition name="slide">
|
||||||
@ -79,6 +79,7 @@ import axios from "axios";
|
|||||||
import {mapState} from "vuex";
|
import {mapState} from "vuex";
|
||||||
import {getCustomerOfSaleUserId} from "@/api/customer/vedio";
|
import {getCustomerOfSaleUserId} from "@/api/customer/vedio";
|
||||||
import { getHomePath } from "@/views/setting/tools";
|
import { getHomePath } from "@/views/setting/tools";
|
||||||
|
import { reqNewHomeConsult } from "@/api/newHome";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
// 组件的逻辑代码
|
// 组件的逻辑代码
|
||||||
@ -149,7 +150,16 @@ export default {
|
|||||||
// console.log("路由展示~~~",this.$route)
|
// console.log("路由展示~~~",this.$route)
|
||||||
|
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {
|
||||||
|
shouldShowFloatingConsult() {
|
||||||
|
const isHomePage = [
|
||||||
|
'/homePage/index',
|
||||||
|
'/homePage/indexLast',
|
||||||
|
'/ncmatchHome/index'
|
||||||
|
].includes(this.$route.path)
|
||||||
|
return isHomePage || this.orgType == 2 || this.orgType == 3 || !this.userid
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 让模板中可以直接调用 getHomePath()
|
// 让模板中可以直接调用 getHomePath()
|
||||||
getHomePath,
|
getHomePath,
|
||||||
@ -245,7 +255,376 @@ export default {
|
|||||||
this.isShowChangeChat = true
|
this.isShowChangeChat = true
|
||||||
},
|
},
|
||||||
openAiConsult() {
|
openAiConsult() {
|
||||||
window.dispatchEvent(new CustomEvent('kboss-open-ai-chat'))
|
this.resetYunbaoChatInstance()
|
||||||
|
this.installYunbaoChat()
|
||||||
|
window.YunbaoChat.init({
|
||||||
|
avatarUrl: require('./img/ocai.jpg'),
|
||||||
|
name: '云宝小助手'
|
||||||
|
})
|
||||||
|
window.YunbaoChat.open()
|
||||||
|
},
|
||||||
|
resetYunbaoChatInstance() {
|
||||||
|
const oldModal = document.getElementById('yunbaoModal')
|
||||||
|
const oldStyle = document.getElementById('yunbao-chat-css')
|
||||||
|
if (oldModal) oldModal.remove()
|
||||||
|
if (oldStyle) oldStyle.remove()
|
||||||
|
window.YunbaoChat = null
|
||||||
|
},
|
||||||
|
installYunbaoChat() {
|
||||||
|
if (window.YunbaoChat && document.getElementById('yunbaoModal')) return
|
||||||
|
if (window.YunbaoChat && !document.getElementById('yunbaoModal')) {
|
||||||
|
window.YunbaoChat = null
|
||||||
|
}
|
||||||
|
|
||||||
|
const vm = this
|
||||||
|
window.YunbaoChat = {
|
||||||
|
_inited: false,
|
||||||
|
_chatInited: false,
|
||||||
|
_selectedProduct: '',
|
||||||
|
_config: {},
|
||||||
|
init(config = {}) {
|
||||||
|
if (this._inited) return
|
||||||
|
this._inited = true
|
||||||
|
this._config = Object.assign({
|
||||||
|
avatarUrl: '',
|
||||||
|
name: '云宝小助手',
|
||||||
|
submitUrl: '',
|
||||||
|
products: [
|
||||||
|
{ key: 'E投标', intro: '适配全品类电子招投标场景的线上投标工具,支持在线完成信息注册、标书获取、文件编制、加密提交全流程操作。实时同步招标变更与澄清信息,保障投标过程安全可追溯。' },
|
||||||
|
{ key: 'E招标', intro: '全流程电子化招标交易核心工具,支持多品类招标业务线上开展,实现招投标全过程无纸化运行。搭载多CA互认、在线清标、电子保函等实用功能,保障招标合规高效。' },
|
||||||
|
{ key: 'E评标', intro: '智能化线上评审系统,覆盖专家签到、清标比对、符合性评审、打分汇总、报告生成全流程。支持标书交叉比对、废标在线操作与澄清收发,提升评标效率与规范性。' },
|
||||||
|
{ key: '采伐智审', intro: '面向林业管理的行业智能体,可在线完成采伐申请材料的智能核验,自动比对采伐范围、树种、蓄积量等核心指标与合规要求,快速识别违规申请,助力林业资源可持续利用。' },
|
||||||
|
{ key: '燃机智慧监盘', intro: '能源领域工业智能体,实时采集燃机运行的温度、压力、振动等多维度数据,通过AI算法识别异常运行征兆,提前预判潜在故障,保障燃机稳定运行,降低运维成本。' },
|
||||||
|
{ key: '电价预测', intro: '面向能源行业的预测智能体,结合历史电价数据、供需变化、政策调整、天气影响等多维度变量,通过机器学习模型实现不同周期的电价精准预测,帮助电力企业优化收益管理。' },
|
||||||
|
{ key: 'AI漫剧制作', intro: '互联网内容创作智能体,覆盖从剧本生成、分镜拆解、素材生成到视频合成的全流程制作。支持工业化批量生产,帮助中小团队低成本快速产出AI漫画作品,大幅降低创作门槛。' },
|
||||||
|
{ key: '合同智能审查', intro: 'AI驱动的办公智能体,可快速识别合同中的风险条款、表述歧义、合规漏洞,自动标注问题位置并给出修改建议。支持多类型合同模板适配,大幅缩短人工审查时长。' },
|
||||||
|
{ key: '投策智能体', intro: '面向企业投资决策的辅助智能体,整合多维度市场数据、行业趋势与政策信息,通过算法模拟不同决策场景的收益与风险,自动生成可视化分析报告,提升投资方案科学性。' }
|
||||||
|
],
|
||||||
|
pages: {
|
||||||
|
'合同智能审查': '/homePage/agentStore/contractCase',
|
||||||
|
'投策智能体': '/homePage/agentStore/decisionCase'
|
||||||
|
}
|
||||||
|
}, config)
|
||||||
|
this.injectCSS()
|
||||||
|
this.injectHTML()
|
||||||
|
this.bindBaseEvents()
|
||||||
|
},
|
||||||
|
open() {
|
||||||
|
const modal = document.getElementById('yunbaoModal')
|
||||||
|
if (!modal) return
|
||||||
|
modal.querySelectorAll('.yb-chat-avatar img,.yb-chat-msg-avatar img').forEach((img) => {
|
||||||
|
img.src = this._config.avatarUrl
|
||||||
|
})
|
||||||
|
modal.classList.add('active')
|
||||||
|
if (!this._chatInited) {
|
||||||
|
this._chatInited = true
|
||||||
|
this.initChat()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
const modal = document.getElementById('yunbaoModal')
|
||||||
|
if (modal) modal.classList.remove('active')
|
||||||
|
},
|
||||||
|
injectCSS() {
|
||||||
|
if (document.getElementById('yunbao-chat-css')) return
|
||||||
|
const style = document.createElement('style')
|
||||||
|
style.id = 'yunbao-chat-css'
|
||||||
|
style.textContent = vm.getYunbaoChatCSS()
|
||||||
|
document.head.appendChild(style)
|
||||||
|
},
|
||||||
|
injectHTML() {
|
||||||
|
if (document.getElementById('yunbaoModal')) return
|
||||||
|
const div = document.createElement('div')
|
||||||
|
div.innerHTML = vm.getYunbaoChatHTML(this._config)
|
||||||
|
document.body.appendChild(div.firstElementChild)
|
||||||
|
},
|
||||||
|
bindBaseEvents() {
|
||||||
|
const modal = document.getElementById('yunbaoModal')
|
||||||
|
const closeBtn = document.getElementById('yunbaoCloseBtn')
|
||||||
|
if (modal) {
|
||||||
|
modal.addEventListener('click', (event) => {
|
||||||
|
if (event.target === modal) this.close()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (closeBtn) closeBtn.addEventListener('click', () => this.close())
|
||||||
|
},
|
||||||
|
initChat() {
|
||||||
|
const body = document.getElementById('yunbaoChatBody')
|
||||||
|
if (!body) return
|
||||||
|
body.innerHTML = ''
|
||||||
|
setTimeout(() => {
|
||||||
|
this.addBotMsg('嗨~我是云宝 👋<br>请问您想随便看看,还是直接聊聊需求?', [
|
||||||
|
{ text: '随便看看', action: 'browse' },
|
||||||
|
{ text: '直接聊聊需求', action: 'direct' }
|
||||||
|
])
|
||||||
|
}, 200)
|
||||||
|
},
|
||||||
|
addBotMsg(html, options = [], displayType = '') {
|
||||||
|
const body = document.getElementById('yunbaoChatBody')
|
||||||
|
if (!body) return
|
||||||
|
|
||||||
|
const msg = document.createElement('div')
|
||||||
|
msg.className = 'yb-chat-msg'
|
||||||
|
const type = displayType || (options[0] && options[0].type) || ''
|
||||||
|
let optionHtml = ''
|
||||||
|
if (options.length) {
|
||||||
|
if (type === 'cards') {
|
||||||
|
optionHtml = `<div class="yb-chat-product-cards">${options.map(item => `
|
||||||
|
<div class="yb-chat-product-card" data-action="${item.action || ''}" data-param="${item.param || ''}" data-url="${item.url || ''}" data-text="${item.text || ''}">
|
||||||
|
<div class="yb-chat-product-card-title">${item.text}</div>
|
||||||
|
<div class="yb-chat-product-card-desc">${item.desc || ''}</div>
|
||||||
|
<span class="yb-chat-product-card-link">查看更多 →</span>
|
||||||
|
</div>
|
||||||
|
`).join('')}</div>`
|
||||||
|
} else if (type === 'tags') {
|
||||||
|
optionHtml = `<div class="yb-chat-tag-options">${options.map(item => `<button class="yb-chat-tag-btn" data-action="${item.action || ''}" data-param="${item.param || ''}" data-text="${item.text || ''}">${item.text}</button>`).join('')}</div>`
|
||||||
|
} else {
|
||||||
|
optionHtml = `<div class="yb-chat-options">${options.map(item => `<button class="${item.primary ? 'yb-chat-option-btn primary' : 'yb-chat-option-btn'}" data-action="${item.action || ''}" data-param="${item.param || ''}" data-text="${item.text || ''}">${item.text}</button>`).join('')}</div>`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.innerHTML = `
|
||||||
|
<div class="yb-chat-msg-avatar"><img src="${this._config.avatarUrl}" alt="云宝"></div>
|
||||||
|
<div>
|
||||||
|
<div class="yb-chat-msg-bubble">${html}</div>
|
||||||
|
${optionHtml}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
body.appendChild(msg)
|
||||||
|
body.scrollTop = body.scrollHeight
|
||||||
|
msg.querySelectorAll('[data-action]').forEach(btn => {
|
||||||
|
btn.addEventListener('click', () => this.handleAction(btn.getAttribute('data-action'), btn.getAttribute('data-param'), btn.getAttribute('data-text') || btn.innerText.trim(), btn.getAttribute('data-url')))
|
||||||
|
})
|
||||||
|
},
|
||||||
|
addUserMsg(text) {
|
||||||
|
const body = document.getElementById('yunbaoChatBody')
|
||||||
|
if (!body) return
|
||||||
|
|
||||||
|
const msg = document.createElement('div')
|
||||||
|
msg.className = 'yb-chat-msg yb-chat-msg-user'
|
||||||
|
msg.innerHTML = `<div class="yb-chat-msg-avatar yb-chat-user-avatar"><span>👤</span></div><div class="yb-chat-msg-bubble">${text}</div>`
|
||||||
|
body.appendChild(msg)
|
||||||
|
body.scrollTop = body.scrollHeight
|
||||||
|
},
|
||||||
|
handleAction(action, param, text, url) {
|
||||||
|
this.addUserMsg(text || param)
|
||||||
|
if (action === 'retrySubmit') {
|
||||||
|
setTimeout(() => this.submitForm(), 200)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (action === 'browse') {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.addBotMsg('好的~为您推荐我们的热门产品 👇', [
|
||||||
|
{ text: 'E投标', desc: '更智能的标书写作引擎', action: 'goExternal', url: 'https://bid-ocai-v2.jinan.opencomputing.cn/', type: 'cards' },
|
||||||
|
{ text: '合同智能审查', desc: 'AI驱动合同风险审查,效率提升60%+', action: 'goContract', type: 'cards' },
|
||||||
|
{ text: '投策智能体', desc: '分钟级投研分析,精准辅助投资决策', action: 'goInvest', type: 'cards' }
|
||||||
|
])
|
||||||
|
setTimeout(() => {
|
||||||
|
this.addBotMsg('或者您还有其他想了解的产品吗?', this.getProductTags(), 'tags')
|
||||||
|
}, 1200)
|
||||||
|
}, 200)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (action === 'direct') {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.addBotMsg('您想了解哪方面的产品或服务呢?', this.getProductTags(), 'tags')
|
||||||
|
}, 200)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (action === 'goContract') {
|
||||||
|
vm.$router.push(this._config.pages['合同智能审查'] || '/homePage/agentStore/contractCase').catch(() => {})
|
||||||
|
this.close()
|
||||||
|
setTimeout(() => {
|
||||||
|
this.addBotMsg('已为您打开合同智能审查页面 📄<br>还有其他想了解的吗?', this.getProductTags(), 'tags')
|
||||||
|
}, 200)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (action === 'goExternal') {
|
||||||
|
window.open(url, '_blank')
|
||||||
|
setTimeout(() => {
|
||||||
|
this.addBotMsg('已为您打开相关页面。还有其他想了解的吗?', this.getProductTags(), 'tags')
|
||||||
|
}, 200)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (action === 'goInvest') {
|
||||||
|
vm.$router.push(this._config.pages['投策智能体'] || '/homePage/agentStore/decisionCase').catch(() => {})
|
||||||
|
this.close()
|
||||||
|
setTimeout(() => {
|
||||||
|
this.addBotMsg('已为您打开投策智能体页面 📊<br>还有其他想了解的吗?', this.getProductTags(), 'tags')
|
||||||
|
}, 200)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (action === 'productIntro') {
|
||||||
|
this._selectedProduct = param
|
||||||
|
const intro = this.getProductIntro(param)
|
||||||
|
setTimeout(() => {
|
||||||
|
this.addBotMsg(intro)
|
||||||
|
setTimeout(() => this.addContactForm(), 800)
|
||||||
|
}, 200)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getProductTags() {
|
||||||
|
return this._config.products.map(item => ({
|
||||||
|
text: item.key,
|
||||||
|
action: 'productIntro',
|
||||||
|
param: item.key
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
getProductIntro(key) {
|
||||||
|
const product = this._config.products.find(item => item.key === key)
|
||||||
|
return product ? product.intro : '这是一款优秀的AI产品,欢迎进一步了解!'
|
||||||
|
},
|
||||||
|
addContactForm() {
|
||||||
|
const body = document.getElementById('yunbaoChatBody')
|
||||||
|
if (!body) return
|
||||||
|
|
||||||
|
const form = document.createElement('div')
|
||||||
|
form.className = 'yb-chat-msg'
|
||||||
|
form.innerHTML = `
|
||||||
|
<div class="yb-chat-msg-avatar"><img src="${this._config.avatarUrl}" alt="云宝"></div>
|
||||||
|
<div>
|
||||||
|
<div class="yb-chat-msg-bubble">
|
||||||
|
请留下您的联系方式,我们的顾问将尽快与您联系 😊
|
||||||
|
<div class="yb-chat-form">
|
||||||
|
<input type="text" class="yb-chat-form-input" id="yunbaoChatName" placeholder="您的姓名">
|
||||||
|
<input type="tel" class="yb-chat-form-input" id="yunbaoChatPhone" placeholder="联系电话">
|
||||||
|
<input type="text" class="yb-chat-form-input" id="yunbaoChatCompany" placeholder="公司名称">
|
||||||
|
<button class="yb-chat-form-submit" id="yunbaoChatSubmit">提交咨询</button>
|
||||||
|
<div class="yb-chat-form-tip">信息仅用于顾问联系</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
body.appendChild(form)
|
||||||
|
body.scrollTop = body.scrollHeight
|
||||||
|
document.getElementById('yunbaoChatSubmit').addEventListener('click', () => this.submitForm())
|
||||||
|
},
|
||||||
|
async submitForm() {
|
||||||
|
const name = document.getElementById('yunbaoChatName').value.trim()
|
||||||
|
const phone = document.getElementById('yunbaoChatPhone').value.trim()
|
||||||
|
const company = document.getElementById('yunbaoChatCompany').value.trim()
|
||||||
|
const submitBtn = document.getElementById('yunbaoChatSubmit')
|
||||||
|
if (!name || !phone) {
|
||||||
|
this.addBotMsg('请先填写姓名和联系电话哦~')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!/^1[3-9]\d{9}$/.test(phone)) {
|
||||||
|
this.addBotMsg('请输入正确的 11 位手机号哦~')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (submitBtn && submitBtn.disabled) return
|
||||||
|
|
||||||
|
if (submitBtn) {
|
||||||
|
submitBtn.disabled = true
|
||||||
|
submitBtn.innerText = '提交中...'
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addUserMsg('已提交联系方式')
|
||||||
|
const data = {
|
||||||
|
custom_type: '1',
|
||||||
|
name,
|
||||||
|
phone,
|
||||||
|
company,
|
||||||
|
email: '',
|
||||||
|
content: this._selectedProduct ? `我想咨询关于【${this._selectedProduct}】的产品信息` : '云宝对话咨询',
|
||||||
|
source: '官网',
|
||||||
|
url_link: window.location.href
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await reqNewHomeConsult(data)
|
||||||
|
if (response && response.status) {
|
||||||
|
this.addBotMsg('收到!我们的顾问将尽快与您联系 🎉<br>感谢您的信任!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.addBotMsg((response && response.msg) || '提交失败了,您可以稍后重试。', [
|
||||||
|
{ text: '重新提交', action: 'retrySubmit', primary: true }
|
||||||
|
])
|
||||||
|
} catch (error) {
|
||||||
|
this.addBotMsg('网络开小差了,提交失败,您可以重试一次。', [
|
||||||
|
{ text: '重新提交', action: 'retrySubmit', primary: true }
|
||||||
|
])
|
||||||
|
} finally {
|
||||||
|
if (submitBtn) {
|
||||||
|
submitBtn.disabled = false
|
||||||
|
submitBtn.innerText = '提交咨询'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getYunbaoChatHTML(config) {
|
||||||
|
return `
|
||||||
|
<div id="yunbaoModal" class="yb-assistant-modal-overlay">
|
||||||
|
<div class="yb-assistant-modal">
|
||||||
|
<div class="yb-assistant-modal-header">
|
||||||
|
<div class="yb-chat-avatar"><img src="${config.avatarUrl}" alt="云宝"></div>
|
||||||
|
<div class="yb-chat-header-info">
|
||||||
|
<div class="yb-chat-header-name">${config.name}</div>
|
||||||
|
<div class="yb-chat-header-status">在线</div>
|
||||||
|
</div>
|
||||||
|
<button class="yb-assistant-close-btn" id="yunbaoCloseBtn">
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6L6 18M6 6l12 12"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="yb-chat-body" id="yunbaoChatBody"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
},
|
||||||
|
getYunbaoChatCSS() {
|
||||||
|
return `
|
||||||
|
.yb-assistant-modal-overlay{position:fixed;bottom:100px;right:24px;z-index:9999;display:none}
|
||||||
|
.yb-assistant-modal-overlay.active{display:block}
|
||||||
|
.yb-assistant-modal{background:rgba(255,255,255,0.85);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border-radius:20px;width:400px;height:560px;display:flex;flex-direction:column;overflow:hidden;box-shadow:0 8px 32px rgba(59,130,246,0.08),0 0 0 1px rgba(255,255,255,0.6) inset;border:1px solid rgba(255,255,255,0.5);animation:ybChatSlideIn 0.35s cubic-bezier(0.34,1.56,0.64,1)}
|
||||||
|
@keyframes ybChatSlideIn{from{opacity:0;transform:translateY(20px) scale(0.95)}to{opacity:1;transform:translateY(0) scale(1)}}
|
||||||
|
@keyframes ybToastIn{from{opacity:0;transform:translateX(-50%) translateY(-10px)}to{opacity:1;transform:translateX(-50%) translateY(0)}}
|
||||||
|
@keyframes ybToastOut{from{opacity:1;transform:translateX(-50%) translateY(0)}to{opacity:0;transform:translateX(-50%) translateY(-10px)}}
|
||||||
|
.yb-assistant-modal-header{background:linear-gradient(135deg,rgba(240,247,255,0.9) 0%,rgba(255,255,255,0.7) 100%);backdrop-filter:blur(10px);padding:16px 20px;display:flex;align-items:center;gap:12px;flex-shrink:0;border-bottom:1px solid rgba(59,130,246,0.08)}
|
||||||
|
.yb-chat-avatar{width:48px;height:48px;border-radius:50%;overflow:visible;flex-shrink:0;display:flex;align-items:center;justify-content:center}
|
||||||
|
.yb-chat-avatar img{width:48px;height:48px;object-fit:contain;display:block}
|
||||||
|
.yb-chat-header-info{flex:1}
|
||||||
|
.yb-chat-header-name{font-size:15px;font-weight:600;color:#1e293b}
|
||||||
|
.yb-chat-header-status{font-size:12px;color:#64748b;display:flex;align-items:center;gap:4px}
|
||||||
|
.yb-chat-header-status:before{content:"";width:6px;height:6px;border-radius:50%;background:#22c55e;box-shadow:0 0 6px rgba(34,197,94,0.4)}
|
||||||
|
.yb-assistant-close-btn{width:32px;height:32px;background:rgba(0,0,0,0.04);border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all 0.2s;border:none}
|
||||||
|
.yb-assistant-close-btn:hover{background:rgba(0,0,0,0.08)}
|
||||||
|
.yb-assistant-close-btn svg{width:18px;height:18px;stroke:#64748b}
|
||||||
|
.yb-chat-body{flex:1;overflow-y:auto;padding:20px;display:flex;flex-direction:column;gap:16px;background:linear-gradient(180deg,rgba(240,247,255,0.3) 0%,rgba(255,255,255,0.1) 100%)}
|
||||||
|
.yb-chat-body::-webkit-scrollbar{width:4px}
|
||||||
|
.yb-chat-body::-webkit-scrollbar-thumb{background:rgba(59,130,246,0.15);border-radius:4px}
|
||||||
|
.yb-chat-msg{display:flex;gap:10px;animation:ybChatMsgIn 0.3s ease}
|
||||||
|
@keyframes ybChatMsgIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
|
||||||
|
.yb-chat-msg-avatar{width:40px;height:40px;border-radius:50%;overflow:visible;flex-shrink:0;margin-top:2px;display:flex;align-items:center;justify-content:center}
|
||||||
|
.yb-chat-msg-avatar img{width:40px;height:40px;object-fit:contain;display:block}
|
||||||
|
.yb-chat-user-avatar{background:#e2e8f0;font-size:16px;overflow:hidden}
|
||||||
|
.yb-chat-user-avatar span{display:flex;align-items:center;justify-content:center;width:100%;height:100%}
|
||||||
|
.yb-chat-msg-bubble{background:#fff;border-radius:16px 16px 16px 4px;padding:12px 16px;font-size:14px;line-height:1.6;color:#334155;max-width:300px;box-shadow:0 1px 3px rgba(0,0,0,0.06)}
|
||||||
|
.yb-chat-msg-user{flex-direction:row-reverse}
|
||||||
|
.yb-chat-msg-user .yb-chat-msg-bubble{background:#1e293b;color:#fff;border-radius:16px 16px 4px 16px}
|
||||||
|
.yb-chat-options{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}
|
||||||
|
.yb-chat-option-btn{padding:8px 16px;border-radius:20px;border:1px solid rgba(59,130,246,0.2);background:rgba(255,255,255,0.8);backdrop-filter:blur(4px);font-size:13px;color:#3b82f6;cursor:pointer;transition:all 0.2s;white-space:nowrap}
|
||||||
|
.yb-chat-option-btn:hover{border-color:#3b82f6;background:rgba(59,130,246,0.06);box-shadow:0 2px 8px rgba(59,130,246,0.1)}
|
||||||
|
.yb-chat-option-btn.primary{background:linear-gradient(135deg,#3b82f6,#2563eb);color:#fff;border-color:transparent;box-shadow:0 2px 8px rgba(59,130,246,0.25)}
|
||||||
|
.yb-chat-product-cards{display:flex;flex-direction:column;gap:10px;margin-top:10px}
|
||||||
|
.yb-chat-product-card{background:rgba(255,255,255,0.7);border:1px solid rgba(59,130,246,0.1);border-radius:12px;padding:10px 14px!important;height:92px!important;min-height:92px!important;max-height:92px!important;cursor:pointer;transition:all 0.2s;backdrop-filter:blur(4px);box-sizing:border-box;overflow:hidden;display:flex!important;flex-direction:column;justify-content:flex-start}
|
||||||
|
.yb-chat-product-card:hover{border-color:rgba(59,130,246,0.25);background:rgba(255,255,255,0.9);box-shadow:0 4px 16px rgba(59,130,246,0.08);transform:translateY(-1px)}
|
||||||
|
.yb-chat-product-card-title{font-size:14px;font-weight:600;color:#1e293b;margin-bottom:4px;line-height:1.3}
|
||||||
|
.yb-chat-product-card-desc{font-size:12px;color:#64748b;line-height:1.35;margin-bottom:6px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
|
||||||
|
.yb-chat-product-card-link{font-size:12px;color:#3b82f6;font-weight:500;display:inline-flex;align-items:center;gap:4px;line-height:1.2}
|
||||||
|
.yb-chat-tag-options{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
|
||||||
|
.yb-chat-tag-btn{padding:6px 12px;border-radius:16px;border:1px solid rgba(59,130,246,0.15);background:rgba(255,255,255,0.7);font-size:12px;color:#3b82f6;cursor:pointer;transition:all 0.2s;backdrop-filter:blur(4px)}
|
||||||
|
.yb-chat-tag-btn:hover{border-color:#3b82f6;background:rgba(59,130,246,0.06);box-shadow:0 2px 8px rgba(59,130,246,0.1)}
|
||||||
|
.yb-chat-form{margin-top:10px;display:flex;flex-direction:column;gap:10px}
|
||||||
|
.yb-chat-form-input{width:100%;padding:10px 14px;border:1px solid rgba(59,130,246,0.15);border-radius:10px;font-size:13px;color:#1e293b;background:rgba(255,255,255,0.8);outline:none;transition:all 0.2s;box-sizing:border-box}
|
||||||
|
.yb-chat-form-input:focus{border-color:#3b82f6;box-shadow:0 0 0 3px rgba(59,130,246,0.08);background:#fff}
|
||||||
|
.yb-chat-form-input::placeholder{color:#94a3b8}
|
||||||
|
.yb-chat-form-submit{width:100%;padding:10px;background:#1a1a2e;color:#fff;border:none;border-radius:9999px;font-size:14px;font-weight:500;cursor:pointer;transition:all 0.2s;box-shadow:0 2px 8px rgba(26,26,46,0.2)}
|
||||||
|
.yb-chat-form-submit:hover{background:#0f0f1a;box-shadow:0 4px 12px rgba(26,26,46,0.3);transform:translateY(-1px)}
|
||||||
|
.yb-chat-form-submit:disabled{background:#cbd5e1;box-shadow:none;cursor:not-allowed}
|
||||||
|
.yb-chat-form-tip{font-size:11px;color:#94a3b8;text-align:center}
|
||||||
|
@media(max-width:480px){.yb-assistant-modal{width:calc(100vw - 32px);height:calc(100vh - 140px);right:0}.yb-assistant-modal-overlay{right:16px;bottom:90px}}
|
||||||
|
`
|
||||||
},
|
},
|
||||||
//关闭弹窗
|
//关闭弹窗
|
||||||
closeWindow() {
|
closeWindow() {
|
||||||
@ -345,6 +724,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.box {
|
.box {
|
||||||
|
|
||||||
.contener {
|
.contener {
|
||||||
.dialog {
|
.dialog {
|
||||||
width: 400px;
|
width: 400px;
|
||||||
|
|||||||
@ -179,6 +179,7 @@ export const constantRoutes = [
|
|||||||
title: "H5关于我们", fullPath: "/h5about/index",
|
title: "H5关于我们", fullPath: "/h5about/index",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: '/beforeLogin',
|
path: '/beforeLogin',
|
||||||
name: 'BeforeLogin',
|
name: 'BeforeLogin',
|
||||||
|
|||||||
@ -429,6 +429,13 @@ export default {
|
|||||||
margin-bottom: 18px;
|
margin-bottom: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::v-deep .el-form-item__content,
|
||||||
|
::v-deep .el-input,
|
||||||
|
::v-deep .el-select,
|
||||||
|
::v-deep .el-textarea {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
::v-deep .el-form-item__label {
|
::v-deep .el-form-item__label {
|
||||||
padding-bottom: 6px;
|
padding-bottom: 6px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
@ -465,6 +472,7 @@ export default {
|
|||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.option-item {
|
.option-item {
|
||||||
@ -473,6 +481,10 @@ export default {
|
|||||||
border: 1px solid #e5e7eb;
|
border: 1px solid #e5e7eb;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
::v-deep .el-radio__label {
|
::v-deep .el-radio__label {
|
||||||
padding-left: 6px;
|
padding-left: 6px;
|
||||||
@ -489,6 +501,7 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.direction-item {
|
.direction-item {
|
||||||
@ -498,6 +511,8 @@ export default {
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
::v-deep .el-checkbox__label {
|
::v-deep .el-checkbox__label {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<el-dialog
|
<el-dialog
|
||||||
title="联系销售"
|
title="联系销售"
|
||||||
:visible="dialogVisible"
|
:visible="dialogVisible"
|
||||||
width="580px"
|
width="400px"
|
||||||
center
|
center
|
||||||
append-to-body
|
append-to-body
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
@ -15,34 +15,64 @@
|
|||||||
<div class="talk-body">
|
<div class="talk-body">
|
||||||
<div class="talk-form">
|
<div class="talk-form">
|
||||||
<el-form ref="ruleForm" :rules="rules" label-position="top" label-width="80px" :model="addData">
|
<el-form ref="ruleForm" :rules="rules" label-position="top" label-width="80px" :model="addData">
|
||||||
<el-form-item label="需求描述">
|
|
||||||
<el-input :autosize="{ minRows: 4, maxRows: 4 }" type="textarea" v-model="addData.content" placeholder="请输入您的具体需求"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="客户类型">
|
|
||||||
<el-radio v-model="addData.custom_type" label="1">企业</el-radio>
|
|
||||||
<el-radio v-model="addData.custom_type" label="0">个人</el-radio>
|
|
||||||
</el-form-item>
|
|
||||||
<div class="form-grid">
|
<div class="form-grid">
|
||||||
<el-form-item label="联系人姓名" prop="name">
|
<el-form-item label="1. 请填写您的姓名" prop="name">
|
||||||
<el-input v-model="addData.name" placeholder="请输入联系人姓名"></el-input>
|
<el-input v-model.trim="addData.name" maxlength="20" placeholder="请输入您的姓名"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="phone" label="联系人手机">
|
<el-form-item prop="phone" label="2. 请填写您的联系方式">
|
||||||
<el-input v-model="addData.phone" placeholder="请输入联系人手机"></el-input>
|
<el-input v-model.trim="addData.phone" maxlength="11" placeholder="请输入您的联系电话"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-show="addData.custom_type==='1'" label="公司名称" class="form-item--compact">
|
<el-form-item label="3. 请填写您的邮箱" prop="email" class="form-item--compact">
|
||||||
<el-input v-model="addData.company" placeholder="请输入公司名称"></el-input>
|
<el-input v-model.trim="addData.email" maxlength="60" placeholder="请输入您的邮箱"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="联系人邮箱" class="form-item--compact">
|
<el-form-item label="4. 请填写您的公司名称" prop="company" class="form-item--compact">
|
||||||
<el-input v-model="addData.email" placeholder="请输入联系人邮箱"></el-input>
|
<el-input v-model.trim="addData.company" maxlength="80" placeholder="请输入您的公司名称"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="5. 请选择您的企业类型(单选)" prop="enterprise_type" class="form-item--full">
|
||||||
|
<el-radio-group v-model="addData.enterprise_type" class="option-grid">
|
||||||
|
<el-radio
|
||||||
|
v-for="item in enterpriseOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.id"
|
||||||
|
class="option-item"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="6. 请选择您所在的省份(单选)" prop="region" class="form-item--full">
|
||||||
|
<el-select
|
||||||
|
v-model="addData.region"
|
||||||
|
filterable
|
||||||
|
placeholder="输入省份名称或拼音首字母搜索..."
|
||||||
|
class="full-select"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in provinceOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="7. 如果您有其他问题需要咨询,请留言" class="form-item--message">
|
||||||
|
<el-input
|
||||||
|
v-model.trim="addData.content"
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 3, maxRows: 5 }"
|
||||||
|
maxlength="500"
|
||||||
|
show-word-limit
|
||||||
|
placeholder="请输入您想咨询的内容..."
|
||||||
|
></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-checkbox class="agreement-checkbox" v-model="checked">
|
<el-checkbox class="agreement-checkbox" v-model="checked">
|
||||||
勾选表示:您同意<span v-if="JSON.stringify(logoInfoNew)!=='{}'">{{ logoInfoNew.home.bannerTitle }}</span>及其授权的合作伙伴通过您填写的联系方式联系您。
|
您填写的信息仅用于本次业务对接沟通,公司将严格落实信息安全保护机制,不泄露、不滥用您的任何个人资料。
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</div>
|
</div>
|
||||||
<div class="qcode">
|
<div v-if="qrCodeUrl" class="qcode">
|
||||||
<img v-if="JSON.stringify(logoInfoNew)!=='{}'" :src="logoInfoNew.home.qrCode" alt="">
|
<img :src="qrCodeUrl" alt="官方客服二维码">
|
||||||
<span>扫码添加官方客服</span>
|
<span>扫码添加官方客服</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -57,28 +87,48 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import {mapState} from "vuex";
|
import {mapState} from "vuex";
|
||||||
import {reqNewHomeConsult} from "@/api/newHome";
|
import {reqNewHomeConsult} from "@/api/newHome";
|
||||||
|
import {reqConsultForm} from "@/api/H5";
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: "talk",
|
name: "talk",
|
||||||
data() {
|
data() {
|
||||||
|
const validatePhone = (rule, value, callback) => {
|
||||||
|
if (!value) {
|
||||||
|
callback(new Error('请输入联系电话'))
|
||||||
|
} else if (!/^1[3-9]\d{9}$/.test(value)) {
|
||||||
|
callback(new Error('请输入正确的手机号'))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rules: {
|
rules: {
|
||||||
name: [
|
name: [
|
||||||
{required: true, message: '请输入姓名', trigger: 'blur'},
|
{required: true, message: '请输入姓名', trigger: 'blur'},
|
||||||
],
|
],
|
||||||
phone: [
|
phone: [
|
||||||
{required: true, message: '请输入手机号', trigger: 'change'},
|
{required: true, validator: validatePhone, trigger: 'blur'}
|
||||||
{
|
],
|
||||||
pattern: /^1[3-9]\d{9}$/,
|
email: [
|
||||||
message: '请输入正确的手机号码',
|
{required: true, message: '请输入邮箱', trigger: 'blur'},
|
||||||
trigger: 'blur'
|
{type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur'}
|
||||||
}
|
],
|
||||||
|
company: [
|
||||||
|
{required: true, message: '请输入公司名称', trigger: 'blur'}
|
||||||
|
],
|
||||||
|
enterprise_type: [
|
||||||
|
{required: true, message: '请选择企业类型', trigger: 'change'}
|
||||||
|
],
|
||||||
|
region: [
|
||||||
|
{required: true, message: '请选择所在省份', trigger: 'change'}
|
||||||
]
|
]
|
||||||
|
|
||||||
},
|
},
|
||||||
addBtnLoading: false,
|
addBtnLoading: false,
|
||||||
checked: false,
|
checked: false,
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
|
enterpriseOptions: [],
|
||||||
|
provinceOptions: [],
|
||||||
addData: {
|
addData: {
|
||||||
content: '',//需求内容
|
content: '',//需求内容
|
||||||
custom_type: "1",//客户类型 0-个人 1-企业
|
custom_type: "1",//客户类型 0-个人 1-企业
|
||||||
@ -86,6 +136,8 @@ export default Vue.extend({
|
|||||||
phone: "",//手机号
|
phone: "",//手机号
|
||||||
company: "",//公司名称
|
company: "",//公司名称
|
||||||
email: "",//邮箱
|
email: "",//邮箱
|
||||||
|
enterprise_type: '',
|
||||||
|
region: '',
|
||||||
},
|
},
|
||||||
labelPosition: 'right',
|
labelPosition: 'right',
|
||||||
formLabelAlign: {
|
formLabelAlign: {
|
||||||
@ -100,10 +152,54 @@ export default Vue.extend({
|
|||||||
immediate: true,
|
immediate: true,
|
||||||
handler(value) {
|
handler(value) {
|
||||||
this.dialogVisible = value
|
this.dialogVisible = value
|
||||||
|
if (value) {
|
||||||
|
this.fetchConsultOptions()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getDefaultFormData() {
|
||||||
|
return {
|
||||||
|
content: '',
|
||||||
|
custom_type: '1',
|
||||||
|
name: '',
|
||||||
|
phone: '',
|
||||||
|
company: '',
|
||||||
|
email: '',
|
||||||
|
enterprise_type: '',
|
||||||
|
region: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
normalizeDictOptions(list, type) {
|
||||||
|
return list
|
||||||
|
.filter(item => item && item.dict_type === type)
|
||||||
|
.sort((a, b) => Number(a.sort_order || 0) - Number(b.sort_order || 0))
|
||||||
|
.map(item => ({
|
||||||
|
id: item.dict_key,
|
||||||
|
name: item.dict_value
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
extractConsultOptionList(res) {
|
||||||
|
if (res && Array.isArray(res.data)) return res.data
|
||||||
|
if (res && res.data && Array.isArray(res.data.data)) return res.data.data
|
||||||
|
return []
|
||||||
|
},
|
||||||
|
async fetchConsultOptions() {
|
||||||
|
try {
|
||||||
|
const res = await reqConsultForm()
|
||||||
|
const list = this.extractConsultOptionList(res)
|
||||||
|
if (!list.length) return
|
||||||
|
|
||||||
|
const enterpriseOptions = this.normalizeDictOptions(list, 'enterprise_type')
|
||||||
|
const provinceOptions = this.normalizeDictOptions(list, 'region')
|
||||||
|
|
||||||
|
if (enterpriseOptions.length) this.enterpriseOptions = enterpriseOptions
|
||||||
|
if (provinceOptions.length) this.provinceOptions = provinceOptions
|
||||||
|
} catch (error) {
|
||||||
|
// 字典接口异常时保持当前选项,避免影响基础提交。
|
||||||
|
}
|
||||||
|
},
|
||||||
handleDialogVisibleUpdate(value) {
|
handleDialogVisibleUpdate(value) {
|
||||||
this.dialogVisible = value;
|
this.dialogVisible = value;
|
||||||
if (!value) {
|
if (!value) {
|
||||||
@ -113,7 +209,6 @@ export default Vue.extend({
|
|||||||
cancelBtn() {
|
cancelBtn() {
|
||||||
this.dialogVisible = false;
|
this.dialogVisible = false;
|
||||||
this.$store.commit('setShowTalk', false);
|
this.$store.commit('setShowTalk', false);
|
||||||
console.log("取消按钮被点击了");
|
|
||||||
},
|
},
|
||||||
confirmBtn() {
|
confirmBtn() {
|
||||||
if (!this.checked) {
|
if (!this.checked) {
|
||||||
@ -123,8 +218,12 @@ export default Vue.extend({
|
|||||||
this.$refs['ruleForm'].validate((valid) => {
|
this.$refs['ruleForm'].validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
this.addBtnLoading = true
|
this.addBtnLoading = true
|
||||||
this.addData.url_link = window.location.href
|
const submitData = {
|
||||||
reqNewHomeConsult(this.addData).then(response => {
|
...this.addData,
|
||||||
|
source: '官网',
|
||||||
|
url_link: window.location.href
|
||||||
|
}
|
||||||
|
reqNewHomeConsult(submitData).then(response => {
|
||||||
this.addBtnLoading = false
|
this.addBtnLoading = false
|
||||||
if (response.status) {
|
if (response.status) {
|
||||||
this.$message({
|
this.$message({
|
||||||
@ -132,14 +231,8 @@ export default Vue.extend({
|
|||||||
message: '感谢您关注人工智能服务平台,我们将尽快联系您!~'
|
message: '感谢您关注人工智能服务平台,我们将尽快联系您!~'
|
||||||
});
|
});
|
||||||
this.$store.commit('setShowTalk', false);
|
this.$store.commit('setShowTalk', false);
|
||||||
this.addData = {
|
this.addData = this.getDefaultFormData()
|
||||||
content: '',
|
this.checked = false
|
||||||
custom_type: "1",
|
|
||||||
name: "",
|
|
||||||
phone: "",
|
|
||||||
company: "",
|
|
||||||
email: "",
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.$message.error(response.msg || '提交失败,请稍后再试!');
|
this.$message.error(response.msg || '提交失败,请稍后再试!');
|
||||||
}
|
}
|
||||||
@ -161,6 +254,11 @@ export default Vue.extend({
|
|||||||
showTalk: (state) => state.product.showTalk,
|
showTalk: (state) => state.product.showTalk,
|
||||||
logoInfoNew: state => state.product.logoInfoNew,
|
logoInfoNew: state => state.product.logoInfoNew,
|
||||||
}),
|
}),
|
||||||
|
qrCodeUrl() {
|
||||||
|
return this.logoInfoNew && this.logoInfoNew.home && this.logoInfoNew.home.qrCode
|
||||||
|
? this.logoInfoNew.home.qrCode
|
||||||
|
: ''
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
@ -171,7 +269,8 @@ export default Vue.extend({
|
|||||||
border-radius: 22px;
|
border-radius: 22px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: 0 24px 70px rgba(15, 23, 42, 0.18);
|
box-shadow: 0 24px 70px rgba(15, 23, 42, 0.18);
|
||||||
z-index: 99999999999999999!important;
|
// z-index: 99999999999999999!important;
|
||||||
|
width: 600px !important;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +296,7 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .el-dialog__body {
|
::v-deep .el-dialog__body {
|
||||||
padding: 6px 22px 4px;
|
padding: 6px 24px 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .el-form-item__label {
|
::v-deep .el-form-item__label {
|
||||||
@ -209,7 +308,14 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .el-form-item {
|
::v-deep .el-form-item {
|
||||||
margin-bottom: 14px;
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-form-item__error {
|
||||||
|
position: static;
|
||||||
|
padding-top: 6px;
|
||||||
|
line-height: 1.25;
|
||||||
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .el-input__inner,
|
::v-deep .el-input__inner,
|
||||||
@ -241,26 +347,70 @@ export default Vue.extend({
|
|||||||
position: relative;
|
position: relative;
|
||||||
min-height: 430px;
|
min-height: 430px;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.talk-form {
|
.talk-form {
|
||||||
|
width: 100%;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::v-deep .talk-form .el-form-item__content,
|
||||||
|
::v-deep .talk-form .el-input,
|
||||||
|
::v-deep .talk-form .el-select,
|
||||||
|
::v-deep .talk-form .el-textarea {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.form-grid {
|
.form-grid {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-item--compact {
|
.form-item--compact {
|
||||||
width: calc(100% - 164px);
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item--full {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item--message {
|
||||||
|
width: calc(100% - 184px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-select {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 8px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-item {
|
||||||
|
margin-right: 0 !important;
|
||||||
|
padding: 9px 8px;
|
||||||
|
border: 1px solid #e5eaf3;
|
||||||
|
border-radius: 12px;
|
||||||
|
white-space: nowrap;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
::v-deep .el-radio__label {
|
||||||
|
padding-left: 6px;
|
||||||
|
color: #374151;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.agreement-checkbox {
|
.agreement-checkbox {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
max-width: calc(100% - 164px);
|
max-width: calc(100% - 184px);
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: flex-start;
|
||||||
|
|
||||||
::v-deep .el-checkbox__label {
|
::v-deep .el-checkbox__label {
|
||||||
color: #6b7280;
|
color: #6b7280;
|
||||||
@ -270,17 +420,17 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .el-checkbox__input {
|
::v-deep .el-checkbox__input {
|
||||||
align-self: center;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.qcode {
|
.qcode {
|
||||||
width: 140px;
|
width: 150px;
|
||||||
min-height: 162px;
|
min-height: 162px;
|
||||||
padding: 12px 10px;
|
padding: 12px 10px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 8px;
|
bottom: 18px;
|
||||||
border-radius: 18px;
|
border-radius: 18px;
|
||||||
background: linear-gradient(180deg, #f4f8ff 0%, #ffffff 100%);
|
background: linear-gradient(180deg, #f4f8ff 0%, #ffffff 100%);
|
||||||
border: 1px solid #edf1f7;
|
border: 1px solid #edf1f7;
|
||||||
@ -336,8 +486,15 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 900px) {
|
@media (max-width: 900px) {
|
||||||
|
::v-deep .talk-dialog {
|
||||||
|
width: 92vw !important;
|
||||||
|
}
|
||||||
|
|
||||||
.talk-body {
|
.talk-body {
|
||||||
min-height: auto;
|
min-height: auto;
|
||||||
|
display: block;
|
||||||
|
padding-right: 0;
|
||||||
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.talk-form {
|
.talk-form {
|
||||||
@ -354,5 +511,17 @@ export default Vue.extend({
|
|||||||
.form-item--compact {
|
.form-item--compact {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-item--full {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item--message {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agreement-checkbox {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -55,15 +55,26 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="action-bar">
|
<div class="action-bar">
|
||||||
<el-button
|
<div class="batch-actions">
|
||||||
type="success"
|
<el-button
|
||||||
icon="el-icon-download"
|
type="success"
|
||||||
size="small"
|
icon="el-icon-download"
|
||||||
:loading="exportLoading"
|
size="small"
|
||||||
@click="getTableData('1')"
|
:loading="exportLoading"
|
||||||
>
|
@click="getTableData('1')"
|
||||||
导出Excel
|
>
|
||||||
</el-button>
|
导出Excel
|
||||||
|
</el-button>
|
||||||
|
<el-button type="primary" size="small" :loading="actionLoading" :disabled="!selectedRows.length" @click="batchUpdateFeedback('1')">
|
||||||
|
批量标记沟通中
|
||||||
|
</el-button>
|
||||||
|
<el-button type="warning" size="small" :loading="actionLoading" :disabled="!selectedRows.length" @click="batchUpdateFeedback('0')">
|
||||||
|
批量标记待回复
|
||||||
|
</el-button>
|
||||||
|
<el-button type="danger" size="small" :loading="actionLoading" :disabled="!selectedRows.length" @click="batchDelete">
|
||||||
|
批量删除
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
<div class="record-count">共 {{ totalCount }} 条记录</div>
|
<div class="record-count">共 {{ totalCount }} 条记录</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -74,7 +85,9 @@
|
|||||||
class="consulting-table"
|
class="consulting-table"
|
||||||
empty-text="暂无咨询数据"
|
empty-text="暂无咨询数据"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
>
|
>
|
||||||
|
<el-table-column type="selection" width="46" align="center" />
|
||||||
<el-table-column label="ID" width="80" align="center">
|
<el-table-column label="ID" width="80" align="center">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
{{ getRowNo(scope.$index) }}
|
{{ getRowNo(scope.$index) }}
|
||||||
@ -83,21 +96,42 @@
|
|||||||
<el-table-column prop="name" label="姓名" min-width="90" />
|
<el-table-column prop="name" label="姓名" min-width="90" />
|
||||||
<el-table-column prop="phone" label="手机号" min-width="120" />
|
<el-table-column prop="phone" label="手机号" min-width="120" />
|
||||||
<el-table-column prop="email" label="邮箱" min-width="180" show-overflow-tooltip />
|
<el-table-column prop="email" label="邮箱" min-width="180" show-overflow-tooltip />
|
||||||
<el-table-column prop="company" label="公司名称" min-width="140" show-overflow-tooltip />
|
<el-table-column label="公司名称/企业规模" min-width="180" show-overflow-tooltip>
|
||||||
<el-table-column prop="source" label="咨询渠道" min-width="120" show-overflow-tooltip />
|
<template slot-scope="scope">
|
||||||
|
<div class="company-cell">
|
||||||
|
<span class="company-name">{{ scope.row.company || '-' }}</span>
|
||||||
|
<span class="company-scale">企业规模:{{ scope.row.enterprise_type_name || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="咨询渠道" min-width="120" align="center">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span :class="['source-tag', getSourceClass(scope.row.source)]">
|
||||||
|
{{ scope.row.source || '-' }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column prop="consult_direction_name" label="咨询方向" min-width="220" show-overflow-tooltip />
|
<el-table-column prop="consult_direction_name" label="咨询方向" min-width="220" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="content" label="需求描述" min-width="220" show-overflow-tooltip />
|
||||||
<el-table-column prop="update_time" label="提交时间" min-width="160" />
|
<el-table-column prop="update_time" label="提交时间" min-width="160" />
|
||||||
<el-table-column label="回复状态" min-width="110" align="center">
|
<el-table-column label="回复状态" min-width="110" align="center">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-tag size="mini" effect="plain" :type="feedbackTagType(scope.row.feedback)">
|
<el-tag
|
||||||
|
size="mini"
|
||||||
|
effect="plain"
|
||||||
|
class="feedback-tag"
|
||||||
|
:type="feedbackTagType(scope.row.feedback)"
|
||||||
|
@click="toggleFeedback(scope.row)"
|
||||||
|
>
|
||||||
{{ feedbackText(scope.row) }}
|
{{ feedbackText(scope.row) }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="120" fixed="right">
|
<el-table-column label="操作" width="110" align="center" fixed="right">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button type="text" size="small">查看</el-button>
|
<el-button type="text" size="small" @click="viewUser(scope.row)">详情</el-button>
|
||||||
<el-button type="text" size="small" @click="replyUser(scope.row)">回复</el-button>
|
<el-button type="text" size="small" text="warning" @click="openRemark(scope.row)">备注</el-button>
|
||||||
|
<!-- <el-button type="text" size="small" class="danger-text" @click="deleteRows([scope.row])">删除</el-button> -->
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@ -115,11 +149,112 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
title="咨询详情"
|
||||||
|
:visible.sync="detailVisible"
|
||||||
|
width="600px"
|
||||||
|
|
||||||
|
append-to-body
|
||||||
|
custom-class="detail-dialog"
|
||||||
|
top="8vh"
|
||||||
|
>
|
||||||
|
<div v-if="currentRow" class="detail-panel">
|
||||||
|
<div class="detail-grid">
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="detail-label">姓名</span>
|
||||||
|
<strong>{{ currentRow.name || '-' }}</strong>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="detail-label">联系电话</span>
|
||||||
|
<strong>{{ currentRow.phone || '-' }}</strong>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="detail-label">邮箱</span>
|
||||||
|
<strong>{{ currentRow.email || '-' }}</strong>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="detail-label">公司名称</span>
|
||||||
|
<strong>{{ currentRow.company || '-' }}</strong>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="detail-label">企业类型</span>
|
||||||
|
<strong>{{ currentRow.enterprise_type_name || currentRow.custom_type_name || '-' }}</strong>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="detail-label">咨询渠道</span>
|
||||||
|
<strong>{{ currentRow.source || '-' }}</strong>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="detail-label">提交时间</span>
|
||||||
|
<strong>{{ currentRow.update_time || currentRow.create_at || '-' }}</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-section">
|
||||||
|
<span class="detail-label">咨询方向</span>
|
||||||
|
<strong>{{ currentRow.consult_direction_name || '-' }}</strong>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-section">
|
||||||
|
<span class="detail-label">需求描述/留言</span>
|
||||||
|
<div class="detail-content-box">{{ currentRow.content || '-' }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-divider"></div>
|
||||||
|
|
||||||
|
<div class="detail-section">
|
||||||
|
<span class="detail-label">回复状态</span>
|
||||||
|
<el-tag size="small" effect="plain" :type="feedbackTagType(currentRow.feedback)">
|
||||||
|
{{ feedbackText(currentRow) }}
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-section">
|
||||||
|
<span class="detail-label">备注信息</span>
|
||||||
|
<div class="detail-content-box detail-remark-text">{{ currentRow.remark || '暂无备注' }}</div>
|
||||||
|
<div class="detail-remark-row">
|
||||||
|
<el-input
|
||||||
|
v-model.trim="detailRemarkText"
|
||||||
|
maxlength="300"
|
||||||
|
placeholder="添加备注..."
|
||||||
|
@keyup.enter.native="saveDetailRemark"
|
||||||
|
/>
|
||||||
|
<el-button type="primary" class="detail-save-btn" :loading="actionLoading" @click="saveDetailRemark">
|
||||||
|
保存
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
title="添加备注"
|
||||||
|
:visible.sync="remarkVisible"
|
||||||
|
width="520px"
|
||||||
|
append-to-body
|
||||||
|
custom-class="remark-dialog"
|
||||||
|
:close-on-click-modal="true"
|
||||||
|
@close="saveRemarkOnClose"
|
||||||
|
>
|
||||||
|
<div class="remark-content">
|
||||||
|
<label class="remark-label">备注内容</label>
|
||||||
|
<el-input
|
||||||
|
v-model.trim="remarkText"
|
||||||
|
type="textarea"
|
||||||
|
:rows="6"
|
||||||
|
maxlength="300"
|
||||||
|
show-word-limit
|
||||||
|
placeholder="请输入备注信息..."
|
||||||
|
/>
|
||||||
|
<p class="remark-tip">点击弹窗外任意位置或关闭弹窗,将自动保存备注。</p>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { reqSearchUserInquiry } from '@/api/ncmatch'
|
import { reqSearchUserInquiry, reqUserInquiryDelete, reqUserInquiryStatusSwitch } from '@/api/ncmatch'
|
||||||
import XLSX from 'xlsx'
|
import XLSX from 'xlsx'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -129,9 +264,17 @@ export default {
|
|||||||
tableData: [],
|
tableData: [],
|
||||||
tableLoading: false,
|
tableLoading: false,
|
||||||
exportLoading: false,
|
exportLoading: false,
|
||||||
|
actionLoading: false,
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
totalCount: 0,
|
totalCount: 0,
|
||||||
|
selectedRows: [],
|
||||||
|
detailVisible: false,
|
||||||
|
remarkVisible: false,
|
||||||
|
remarkText: '',
|
||||||
|
detailRemarkText: '',
|
||||||
|
originalRemarkText: '',
|
||||||
|
currentRow: null,
|
||||||
sourceList: [],
|
sourceList: [],
|
||||||
queryForm: {
|
queryForm: {
|
||||||
name: '',
|
name: '',
|
||||||
@ -186,6 +329,18 @@ export default {
|
|||||||
if (value === '3') return 'info'
|
if (value === '3') return 'info'
|
||||||
return 'warning'
|
return 'warning'
|
||||||
},
|
},
|
||||||
|
getSourceClass(source) {
|
||||||
|
const value = String(source || '')
|
||||||
|
if (value.includes('公众号')) return 'source-tag-green'
|
||||||
|
if (value.includes('官网')) return 'source-tag-blue'
|
||||||
|
return 'source-tag-gray'
|
||||||
|
},
|
||||||
|
getRowId(row) {
|
||||||
|
return row && (row.id || row.inquiry_id || row.user_inquiry_id)
|
||||||
|
},
|
||||||
|
buildIds(rows) {
|
||||||
|
return JSON.stringify(rows.map(row => this.getRowId(row)).filter(Boolean))
|
||||||
|
},
|
||||||
getRowNo(index) {
|
getRowNo(index) {
|
||||||
return (this.page - 1) * this.pageSize + index + 1
|
return (this.page - 1) * this.pageSize + index + 1
|
||||||
},
|
},
|
||||||
@ -229,8 +384,13 @@ export default {
|
|||||||
extractSourceList(res, rows = []) {
|
extractSourceList(res, rows = []) {
|
||||||
const data = (res && res.data) || {}
|
const data = (res && res.data) || {}
|
||||||
const fromApi = data.source_list || data.sourceList || res.source_list || res.sourceList
|
const fromApi = data.source_list || data.sourceList || res.source_list || res.sourceList
|
||||||
if (Array.isArray(fromApi) && fromApi.length) return fromApi
|
const apiList = Array.isArray(fromApi) ? fromApi : []
|
||||||
return [...new Set(rows.map(item => String(item.source || '').trim()).filter(Boolean))]
|
const rowList = rows.map(item => item.source)
|
||||||
|
return [...new Set(
|
||||||
|
[...this.sourceList, ...apiList, ...rowList]
|
||||||
|
.map(item => String(item || '').trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
)]
|
||||||
},
|
},
|
||||||
getTableData(to_excel) {
|
getTableData(to_excel) {
|
||||||
const params = this.buildSearchParams(to_excel)
|
const params = this.buildSearchParams(to_excel)
|
||||||
@ -249,6 +409,7 @@ export default {
|
|||||||
this.tableData = rows
|
this.tableData = rows
|
||||||
this.totalCount = this.extractTotal(res, rows.length)
|
this.totalCount = this.extractTotal(res, rows.length)
|
||||||
this.sourceList = this.extractSourceList(res, rows)
|
this.sourceList = this.extractSourceList(res, rows)
|
||||||
|
this.selectedRows = []
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,18 +449,111 @@ export default {
|
|||||||
this.page = page
|
this.page = page
|
||||||
this.getTableData('0')
|
this.getTableData('0')
|
||||||
},
|
},
|
||||||
async replyUser(row) {
|
handleSelectionChange(rows) {
|
||||||
if (row.email) {
|
this.selectedRows = rows
|
||||||
window.location.href = `mailto:${row.email}`
|
},
|
||||||
|
async updateInquiryStatus(rows, feedback, remark) {
|
||||||
|
const ids = this.buildIds(rows)
|
||||||
|
if (!ids || ids === '[]') {
|
||||||
|
this.$message.warning('请选择有效数据')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
ids,
|
||||||
|
feedback: String(feedback)
|
||||||
|
}
|
||||||
|
if (remark !== undefined) params.remark = remark
|
||||||
|
|
||||||
|
this.actionLoading = true
|
||||||
|
try {
|
||||||
|
const res = await reqUserInquiryStatusSwitch(params)
|
||||||
|
if (res && res.status) {
|
||||||
|
this.$message.success('操作成功')
|
||||||
|
this.getTableData('0')
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
this.$message.error((res && res.msg) || '操作失败')
|
||||||
|
return false
|
||||||
|
} catch (error) {
|
||||||
|
this.$message.error('操作失败,请稍后重试')
|
||||||
|
return false
|
||||||
|
} finally {
|
||||||
|
this.actionLoading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toggleFeedback(row) {
|
||||||
|
const nextFeedback = String(row.feedback) === '0' ? '1' : '0'
|
||||||
|
this.updateInquiryStatus([row], nextFeedback)
|
||||||
|
},
|
||||||
|
batchUpdateFeedback(feedback) {
|
||||||
|
this.updateInquiryStatus(this.selectedRows, feedback)
|
||||||
|
},
|
||||||
|
async deleteRows(rows) {
|
||||||
|
const ids = this.buildIds(rows)
|
||||||
|
if (!ids || ids === '[]') {
|
||||||
|
this.$message.warning('请选择有效数据')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (row.phone) {
|
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(row.phone)
|
await this.$confirm('确认删除选中的咨询记录吗?', '提示', {
|
||||||
this.$message.success('手机号已复制,可直接联系用户')
|
confirmButtonText: '确认',
|
||||||
} catch (error) {
|
cancelButtonText: '取消',
|
||||||
this.$message.warning('联系方式复制失败,请手动联系')
|
type: 'warning'
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.actionLoading = true
|
||||||
|
try {
|
||||||
|
const res = await reqUserInquiryDelete({ ids })
|
||||||
|
if (res && res.status) {
|
||||||
|
this.$message.success('删除成功')
|
||||||
|
this.getTableData('0')
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
this.$message.error((res && res.msg) || '删除失败')
|
||||||
|
} catch (error) {
|
||||||
|
this.$message.error('删除失败,请稍后重试')
|
||||||
|
} finally {
|
||||||
|
this.actionLoading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
batchDelete() {
|
||||||
|
this.deleteRows(this.selectedRows)
|
||||||
|
},
|
||||||
|
viewUser(row) {
|
||||||
|
this.currentRow = row
|
||||||
|
this.detailRemarkText = row.remark || ''
|
||||||
|
this.detailVisible = true
|
||||||
|
},
|
||||||
|
openRemark(row) {
|
||||||
|
this.currentRow = row
|
||||||
|
this.remarkText = row.remark || ''
|
||||||
|
this.originalRemarkText = this.remarkText
|
||||||
|
this.remarkVisible = true
|
||||||
|
},
|
||||||
|
saveRemarkOnClose() {
|
||||||
|
if (!this.currentRow) return
|
||||||
|
if (this.remarkText === this.originalRemarkText) return
|
||||||
|
|
||||||
|
this.updateInquiryStatus(
|
||||||
|
[this.currentRow],
|
||||||
|
this.currentRow.feedback === undefined || this.currentRow.feedback === null ? '0' : this.currentRow.feedback,
|
||||||
|
this.remarkText
|
||||||
|
)
|
||||||
|
},
|
||||||
|
async saveDetailRemark() {
|
||||||
|
if (!this.currentRow) return
|
||||||
|
const success = await this.updateInquiryStatus(
|
||||||
|
[this.currentRow],
|
||||||
|
this.currentRow.feedback === undefined || this.currentRow.feedback === null ? '0' : this.currentRow.feedback,
|
||||||
|
this.detailRemarkText
|
||||||
|
)
|
||||||
|
if (success) {
|
||||||
|
this.currentRow.remark = this.detailRemarkText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -414,6 +668,17 @@ export default {
|
|||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.batch-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.batch-actions ::v-deep .el-button + .el-button {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.record-count {
|
.record-count {
|
||||||
color: #6b7280;
|
color: #6b7280;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
@ -442,6 +707,240 @@ export default {
|
|||||||
background: #f9fafb;
|
background: #f9fafb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.company-cell {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.company-name {
|
||||||
|
color: #1f2937;
|
||||||
|
font-weight: 600;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.company-scale {
|
||||||
|
color: #8a94a6;
|
||||||
|
font-size: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.source-tag {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 52px;
|
||||||
|
height: 24px;
|
||||||
|
padding: 0 10px;
|
||||||
|
border-radius: 999px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.source-tag-green {
|
||||||
|
color: #15803d;
|
||||||
|
background: #dcfce7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.source-tag-blue {
|
||||||
|
color: #1d4ed8;
|
||||||
|
background: #dbeafe;
|
||||||
|
}
|
||||||
|
|
||||||
|
.source-tag-gray {
|
||||||
|
color: #64748b;
|
||||||
|
background: #f1f5f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feedback-tag {
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.danger-text {
|
||||||
|
color: #f56c6c;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .detail-dialog {
|
||||||
|
border-radius: 24px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 24px 70px rgba(15, 23, 42, 0.22);
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .detail-dialog .el-dialog__header {
|
||||||
|
padding: 28px 34px 22px;
|
||||||
|
border-bottom: 1px solid #eef2f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .detail-dialog .el-dialog__title {
|
||||||
|
color: #111827;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .detail-dialog .el-dialog__headerbtn {
|
||||||
|
top: 30px;
|
||||||
|
right: 34px;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .detail-dialog .el-dialog__body {
|
||||||
|
padding: 28px 34px 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-panel {
|
||||||
|
color: #111827;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
gap: 28px 72px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: #8a94a6;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-item strong,
|
||||||
|
.detail-section strong {
|
||||||
|
color: #111827;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-section {
|
||||||
|
margin-top: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-content-box {
|
||||||
|
min-height: 42px;
|
||||||
|
padding: 14px 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #f8fafc;
|
||||||
|
color: #1f2937;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 1.7;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-remark-text {
|
||||||
|
color: #d97706;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-divider {
|
||||||
|
height: 1px;
|
||||||
|
margin: 24px 0;
|
||||||
|
background: #edf1f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-remark-row {
|
||||||
|
margin-top: 14px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-remark-row ::v-deep .el-input__inner {
|
||||||
|
height: 42px;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-save-btn {
|
||||||
|
width: 72px;
|
||||||
|
height: 42px;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #9333ea;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .remark-dialog {
|
||||||
|
border-radius: 24px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 24px 70px rgba(15, 23, 42, 0.22);
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .remark-dialog .el-dialog__header {
|
||||||
|
padding: 28px 34px 22px;
|
||||||
|
border-bottom: 1px solid #eef2f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .remark-dialog .el-dialog__title {
|
||||||
|
color: #111827;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .remark-dialog .el-dialog__headerbtn {
|
||||||
|
top: 30px;
|
||||||
|
right: 34px;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .remark-dialog .el-dialog__body {
|
||||||
|
padding: 28px 34px 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remark-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remark-label {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
color: #1f2937;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remark-content ::v-deep .el-textarea__inner {
|
||||||
|
min-height: 150px !important;
|
||||||
|
padding: 16px 18px;
|
||||||
|
border: 1px solid #dfe6f0;
|
||||||
|
border-radius: 12px;
|
||||||
|
color: #111827;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 1.7;
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remark-content ::v-deep .el-textarea__inner::placeholder {
|
||||||
|
color: #a0aec0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remark-content ::v-deep .el-input__count {
|
||||||
|
right: 14px;
|
||||||
|
bottom: 10px;
|
||||||
|
color: #9ca3af;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remark-tip {
|
||||||
|
margin: 12px 0 0;
|
||||||
|
color: #8a94a6;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
.pager-wrap {
|
.pager-wrap {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user