Compare commits
4 Commits
4e0b59106a
...
3aeadf7d80
| Author | SHA1 | Date | |
|---|---|---|---|
| 3aeadf7d80 | |||
| 72ef0b177b | |||
| e57767d3b9 | |||
|
|
87602e7144 |
@ -7,11 +7,12 @@ async def myuppassword(ns):
|
||||
user = await sor.R('users', ns)
|
||||
if len(user) >= 1:
|
||||
ns['password'] = password_encode(ns['newpassword'])
|
||||
await sor.U('users', ns)
|
||||
sql = "update users set password = '%s' where id = '%s'" % (ns['password'], ns['id'])
|
||||
await sor.sqlExe(sql, ns)
|
||||
return {'status': True, 'msg': '成功'}
|
||||
return {'status': False, 'msg': '历史密码错误'}
|
||||
except:
|
||||
return {'status': False, 'msg': '失败'}
|
||||
except Exception as e:
|
||||
return {'status': False, 'msg': '失败', 'error': str(e)}
|
||||
|
||||
ret = await myuppassword(params_kw)
|
||||
return ret
|
||||
70
f/web-kboss/src/api/AI/ai.js
Normal file
70
f/web-kboss/src/api/AI/ai.js
Normal file
@ -0,0 +1,70 @@
|
||||
const AI_CHAT_URL = 'https://dev.ncmatch.cn/api/ai-chat/chat/stream/'
|
||||
|
||||
// AI 对话
|
||||
export const reqAIChat = (data, onMessage) => {
|
||||
return fetch(AI_CHAT_URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
}).then(async(response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}`)
|
||||
}
|
||||
|
||||
if (!response.body) {
|
||||
throw new Error('当前浏览器不支持流式响应')
|
||||
}
|
||||
|
||||
const reader = response.body.getReader()
|
||||
const decoder = new TextDecoder()
|
||||
let fullResponse = ''
|
||||
let buffer = ''
|
||||
|
||||
while (true) {
|
||||
const { done, value } = await reader.read()
|
||||
if (done) break
|
||||
|
||||
buffer += decoder.decode(value, { stream: true })
|
||||
const lines = buffer.split('\n')
|
||||
buffer = lines.pop() || ''
|
||||
|
||||
lines.forEach((line) => {
|
||||
if (!line.startsWith('data: ')) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(line.slice(6))
|
||||
if (parsed && parsed.content) {
|
||||
fullResponse += parsed.content
|
||||
if (typeof onMessage === 'function') {
|
||||
onMessage(fullResponse)
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// Ignore incomplete stream fragments until the next chunk arrives.
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (buffer && buffer.startsWith('data: ')) {
|
||||
try {
|
||||
const parsed = JSON.parse(buffer.slice(6))
|
||||
if (parsed && parsed.content) {
|
||||
fullResponse += parsed.content
|
||||
if (typeof onMessage === 'function') {
|
||||
onMessage(fullResponse)
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// Ignore invalid trailing fragments.
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
content: fullResponse
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -54,6 +54,12 @@
|
||||
<div class="content unicode" style="display: block;">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">发送</div>
|
||||
<div class="code-name">&#xe60d;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">复制</div>
|
||||
@ -132,9 +138,9 @@
|
||||
<pre><code class="language-css"
|
||||
>@font-face {
|
||||
font-family: 'iconfont';
|
||||
src: url('iconfont.woff2?t=1760930186762') format('woff2'),
|
||||
url('iconfont.woff?t=1760930186762') format('woff'),
|
||||
url('iconfont.ttf?t=1760930186762') format('truetype');
|
||||
src: url('iconfont.woff2?t=1776735138822') format('woff2'),
|
||||
url('iconfont.woff?t=1776735138822') format('woff'),
|
||||
url('iconfont.ttf?t=1776735138822') format('truetype');
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
||||
@ -160,6 +166,15 @@
|
||||
<div class="content font-class">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-fasong"></span>
|
||||
<div class="name">
|
||||
发送
|
||||
</div>
|
||||
<div class="code-name">.icon-fasong
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-fuzhi"></span>
|
||||
<div class="name">
|
||||
@ -277,6 +292,14 @@
|
||||
<div class="content symbol">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-fasong"></use>
|
||||
</svg>
|
||||
<div class="name">发送</div>
|
||||
<div class="code-name">#icon-fasong</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-fuzhi"></use>
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 5043107 */
|
||||
src: url('iconfont.woff2?t=1760930186762') format('woff2'),
|
||||
url('iconfont.woff?t=1760930186762') format('woff'),
|
||||
url('iconfont.ttf?t=1760930186762') format('truetype');
|
||||
src: url('iconfont.woff2?t=1776735138822') format('woff2'),
|
||||
url('iconfont.woff?t=1776735138822') format('woff'),
|
||||
url('iconfont.ttf?t=1776735138822') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@ -13,6 +13,10 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-fasong:before {
|
||||
content: "\e60d";
|
||||
}
|
||||
|
||||
.icon-fuzhi:before {
|
||||
content: "\e61b";
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -5,6 +5,13 @@
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "12719937",
|
||||
"name": "发送",
|
||||
"font_class": "fasong",
|
||||
"unicode": "e60d",
|
||||
"unicode_decimal": 58893
|
||||
},
|
||||
{
|
||||
"icon_id": "300409",
|
||||
"name": "复制",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
f/web-kboss/src/assets/image/img.png
Normal file
BIN
f/web-kboss/src/assets/image/img.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 80 KiB |
BIN
f/web-kboss/src/assets/image/kefu.jpg
Normal file
BIN
f/web-kboss/src/assets/image/kefu.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
@ -46,13 +46,13 @@
|
||||
<div class="mobile-qr">
|
||||
<div class="qr-item">
|
||||
<div class="qr-code">
|
||||
<img src="@/assets/kyy/kyy公众号.jpg" alt="微信客服二维码">
|
||||
<img src="@/assets/image/kefu.jpg" alt="微信客服二维码">
|
||||
</div>
|
||||
<span class="qr-desc">关注公众号</span>
|
||||
</div>
|
||||
<div class="qr-item">
|
||||
<div class="qr-code">
|
||||
<img src="@/assets/kyy/客服wechat.png" alt="微信客服二维码">
|
||||
<img src="@/assets/image/img.png" alt="微信客服二维码">
|
||||
</div>
|
||||
<span class="qr-desc">微信客服</span>
|
||||
</div>
|
||||
|
||||
@ -160,7 +160,74 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 消息中心组件 -->
|
||||
<div v-show="aiDialogVisible" class="ai-chat-panel">
|
||||
<div class="ai-chat-panel__header">
|
||||
<div class="ai-chat-panel__title">
|
||||
<span class="ai-chat-panel__logo">AI</span>
|
||||
<span>有问题,找开元</span>
|
||||
</div>
|
||||
<i class="el-icon-close ai-chat-panel__close" @click="closeAIPanel"></i>
|
||||
</div>
|
||||
<div ref="aiChatMessages" class="ai-chat-panel__body">
|
||||
<div v-if="!aiMessages.length" class="ai-chat-panel__welcome">
|
||||
<h3>Hi!</h3>
|
||||
<p>我是开元智能助手,可以为您解答算力服务器选型、采购、部署和资源配置等问题。</p>
|
||||
<div class="ai-chat-panel__suggestions">
|
||||
<span
|
||||
v-for="item in aiQuickQuestions"
|
||||
:key="item"
|
||||
class="ai-chat-panel__tag"
|
||||
@click="useAISuggestion(item)"
|
||||
>
|
||||
{{ item }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="(item, index) in aiMessages"
|
||||
:key="index"
|
||||
:class="['ai-chat__message', `is-${item.role}`]"
|
||||
>
|
||||
<div class="ai-chat__avatar">
|
||||
{{ item.role === 'assistant' ? 'AI' : '我' }}
|
||||
</div>
|
||||
<div class="ai-chat__bubble">
|
||||
<div
|
||||
v-if="item.role === 'assistant'"
|
||||
class="ai-chat__rich-text"
|
||||
v-html="formatAIContent(item.content)"
|
||||
></div>
|
||||
<span v-else>{{ item.content }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ai-chat-panel__input-wrap">
|
||||
<div class="ai-chat-panel__actions">
|
||||
<span class="ai-chat-panel__new" @click="resetAIChat">新对话</span>
|
||||
<span class="ai-chat__tip">Enter 发送</span>
|
||||
</div>
|
||||
<div class="ai-chat-panel__input">
|
||||
<el-input
|
||||
v-model="aiInput"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
resize="none"
|
||||
maxlength="500"
|
||||
placeholder="请输入你的问题"
|
||||
@keydown.native="handleAIKeydown"
|
||||
/>
|
||||
<el-button
|
||||
class="ai-chat-panel__send"
|
||||
type="text"
|
||||
:loading="aiLoading"
|
||||
@click="sendAIMessage"
|
||||
>
|
||||
<i class="iconfont icon-fasong"></i>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<message-center
|
||||
ref="messageCenter"
|
||||
:visible.sync="messageCenterVisible"
|
||||
@ -180,6 +247,7 @@ import { reqApplyChannel } from "@/api/customer/channel";
|
||||
import store from "@/store";
|
||||
import { getHomePath } from '@/views/setting/tools'
|
||||
import MessageCenter from '@/components/MessageCenter/MessageCenter.vue'
|
||||
import { reqAIChat } from '@/api/AI/ai'
|
||||
|
||||
export default Vue.extend({
|
||||
name: "TopBox",
|
||||
@ -188,6 +256,16 @@ export default Vue.extend({
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
aiDialogVisible: false,
|
||||
aiInput: '',
|
||||
aiLoading: false,
|
||||
aiMessages: [],
|
||||
aiQuickQuestions: [
|
||||
'推荐适合训练大模型的 GPU 服务器',
|
||||
'4090 和 A100 怎么选',
|
||||
'有没有高性价比 8 卡方案',
|
||||
'国产化算力服务器有哪些'
|
||||
],
|
||||
messageCenterVisible: false,
|
||||
homePath: getHomePath(),
|
||||
isShowKbossCharge: false,
|
||||
@ -270,11 +348,134 @@ export default Vue.extend({
|
||||
|
||||
// 处理AI助手点击
|
||||
handleAIClick() {
|
||||
this.$message.info({
|
||||
message: '功能即将上线,敬请期待!',
|
||||
duration: 3000,
|
||||
showClose: true
|
||||
});
|
||||
this.aiDialogVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.scrollAIChatToBottom()
|
||||
})
|
||||
},
|
||||
|
||||
closeAIPanel() {
|
||||
this.aiDialogVisible = false
|
||||
},
|
||||
|
||||
resetAIChat() {
|
||||
this.aiMessages = []
|
||||
this.aiInput = ''
|
||||
},
|
||||
|
||||
useAISuggestion(question) {
|
||||
this.sendAIMessage(question)
|
||||
},
|
||||
|
||||
handleAIKeydown(event) {
|
||||
if (event.key === 'Enter' && !event.shiftKey) {
|
||||
event.preventDefault()
|
||||
this.sendAIMessage()
|
||||
}
|
||||
},
|
||||
|
||||
async sendAIMessage(quickQuestion) {
|
||||
const message = (quickQuestion || this.aiInput).trim()
|
||||
if (!message || this.aiLoading) return
|
||||
|
||||
this.aiMessages.push({
|
||||
role: 'user',
|
||||
content: message
|
||||
})
|
||||
this.aiInput = ''
|
||||
|
||||
const loadingMessageIndex = this.aiMessages.push({
|
||||
role: 'assistant',
|
||||
content: '[正在检索并生成回答...]'
|
||||
}) - 1
|
||||
|
||||
this.aiLoading = true
|
||||
this.$nextTick(() => {
|
||||
this.scrollAIChatToBottom()
|
||||
})
|
||||
|
||||
try {
|
||||
const response = await reqAIChat({ message }, (content) => {
|
||||
if (!content) return
|
||||
|
||||
this.$set(this.aiMessages, loadingMessageIndex, {
|
||||
role: 'assistant',
|
||||
content
|
||||
})
|
||||
this.$nextTick(() => {
|
||||
this.scrollAIChatToBottom()
|
||||
})
|
||||
})
|
||||
|
||||
if (response && response.content) {
|
||||
this.$set(this.aiMessages, loadingMessageIndex, {
|
||||
role: 'assistant',
|
||||
content: response.content
|
||||
})
|
||||
} else {
|
||||
this.$set(this.aiMessages, loadingMessageIndex, {
|
||||
role: 'assistant',
|
||||
content: '暂时没有获取到回复,请稍后再试。'
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
this.$set(this.aiMessages, loadingMessageIndex, {
|
||||
role: 'assistant',
|
||||
content: '抱歉,当前服务繁忙,请稍后再试。'
|
||||
})
|
||||
} finally {
|
||||
this.aiLoading = false
|
||||
this.$nextTick(() => {
|
||||
this.scrollAIChatToBottom()
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
escapeAIHtml(content) {
|
||||
return String(content || '')
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
},
|
||||
|
||||
formatAIInline(content) {
|
||||
return this.escapeAIHtml(content).replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
|
||||
},
|
||||
|
||||
formatAIContent(content) {
|
||||
if (!content) return ''
|
||||
|
||||
const normalizedContent = String(content)
|
||||
.replace(/\r\n/g, '\n')
|
||||
.replace(/ {2,}/g, '\n')
|
||||
.replace(/\n{3,}/g, '\n\n')
|
||||
|
||||
const lines = normalizedContent.split('\n')
|
||||
|
||||
return lines.map((line) => {
|
||||
const trimmed = line.trim()
|
||||
|
||||
if (!trimmed) {
|
||||
return '<div class="ai-chat__paragraph ai-chat__paragraph--space"></div>'
|
||||
}
|
||||
|
||||
if (/^-\s+/.test(trimmed)) {
|
||||
return `<div class="ai-chat__item"><span class="ai-chat__item-dot"></span><span>${this.formatAIInline(trimmed.replace(/^-\s+/, ''))}</span></div>`
|
||||
}
|
||||
|
||||
if (/^\*\*(.+?)\*\*$/.test(trimmed)) {
|
||||
return `<div class="ai-chat__section-title">${this.formatAIInline(trimmed)}</div>`
|
||||
}
|
||||
|
||||
return `<div class="ai-chat__paragraph">${this.formatAIInline(trimmed)}</div>`
|
||||
}).join('')
|
||||
},
|
||||
|
||||
scrollAIChatToBottom() {
|
||||
const messageBox = this.$refs.aiChatMessages
|
||||
if (messageBox) {
|
||||
messageBox.scrollTop = messageBox.scrollHeight
|
||||
}
|
||||
},
|
||||
|
||||
// 处理客服点击
|
||||
@ -1025,4 +1226,250 @@ export default Vue.extend({
|
||||
color: #1E6FFF;
|
||||
}
|
||||
}
|
||||
::v-deep .v-model{
|
||||
z-index: 1;
|
||||
}
|
||||
.ai-chat-panel {
|
||||
position: fixed;
|
||||
right: 24px;
|
||||
bottom: 24px;
|
||||
width: 380px;
|
||||
height: 620px;
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.12);
|
||||
z-index: 3000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
&__header {
|
||||
height: 64px;
|
||||
padding: 0 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
&__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
font-size: 16px !important;
|
||||
font-weight: 600;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
&__logo {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 50%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(90deg, #d66bff 0%, #7d7cff 100%);
|
||||
color: #fff;
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
&__close {
|
||||
cursor: pointer;
|
||||
color: #666;
|
||||
font-size: 18px !important;
|
||||
}
|
||||
|
||||
&__body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 18px 16px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
&__welcome {
|
||||
h3 {
|
||||
margin: 0 0 12px;
|
||||
color: #5f59ff;
|
||||
font-size: 22px !important;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 20px;
|
||||
font-size: 14px !important;
|
||||
line-height: 1.8;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
&__suggestions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
&__tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 10px 14px;
|
||||
border-radius: 10px;
|
||||
background: #f7f7f8;
|
||||
color: #333;
|
||||
font-size: 14px !important;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
color: #1E6FFF;
|
||||
background: #eef5ff;
|
||||
}
|
||||
}
|
||||
|
||||
&__input-wrap {
|
||||
border-top: 1px solid #f0f0f0;
|
||||
padding: 12px 14px 14px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
margin-bottom: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
&__new {
|
||||
font-size: 13px !important;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: #1E6FFF;
|
||||
}
|
||||
}
|
||||
|
||||
&__input {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&__send {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
bottom: 8px;
|
||||
padding: 0;
|
||||
color: #7d7cff;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .ai-chat-panel__input {
|
||||
.el-textarea__inner {
|
||||
min-height: 84px !important;
|
||||
padding: 12px 48px 12px 12px;
|
||||
border-radius: 14px;
|
||||
border: 1px solid #e5eaf3;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
|
||||
.ai-chat {
|
||||
&__message {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
margin-bottom: 16px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&.is-user {
|
||||
flex-direction: row-reverse;
|
||||
|
||||
.ai-chat__bubble {
|
||||
background: linear-gradient(90deg, #275AFF 0%, #2EBDFA 100%);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__avatar {
|
||||
flex-shrink: 0;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px !important;
|
||||
color: #1E6FFF;
|
||||
background: rgba(30, 111, 255, 0.12);
|
||||
}
|
||||
|
||||
&__bubble {
|
||||
max-width: calc(100% - 46px);
|
||||
padding: 12px 14px;
|
||||
border-radius: 12px;
|
||||
background: #f7f9fc;
|
||||
color: #333;
|
||||
font-size: 14px !important;
|
||||
line-height: 1.7;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
&__rich-text {
|
||||
font-size: 14px !important;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
&__paragraph {
|
||||
margin-bottom: 8px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&--space {
|
||||
height: 8px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__section-title {
|
||||
margin: 12px 0 8px;
|
||||
font-weight: 700;
|
||||
color: #222F60;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
&__item-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
margin-top: 9px;
|
||||
border-radius: 50%;
|
||||
background: #7d7cff;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&__tip {
|
||||
color: #999;
|
||||
font-size: 12px !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .ai-chat__rich-text strong {
|
||||
font-weight: 700;
|
||||
color: #222F60;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -50,11 +50,13 @@
|
||||
<ul class="bigUl"></ul>
|
||||
<div v-if="JSON.stringify(logoInfoNew) !== '{}' && logoInfoNew.home.bannerTitle !== '开元数智'" class="right-box">
|
||||
<div class="qr-box">
|
||||
<img src="../img/kefu.jpg" style="padding: 0.08rem" alt="">
|
||||
<img src="../img/img.png" style="padding: 0.08rem" alt="">
|
||||
|
||||
<span class="qr-content">微信客服</span>
|
||||
</div>
|
||||
<div class="qr-box" style="margin-left: 0.667rem">
|
||||
<img src="../img/img.png" alt="">
|
||||
<img src="../img/kefu.jpg" alt="">
|
||||
|
||||
<span class="qr-content">关注公众号</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -353,7 +355,7 @@ export default Vue.extend({
|
||||
color: #1b5bff;
|
||||
}
|
||||
}
|
||||
/deep/.el-pagination{
|
||||
/deep/.el-pagination{
|
||||
text-align: center !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user