feat:update dark light mode

This commit is contained in:
leeliforever 2026-02-13 02:45:38 +08:00
parent a68db2976d
commit 418d372a9b
4 changed files with 599 additions and 24 deletions

View File

@ -167,7 +167,7 @@
}
.chatCenter {
background: #fff;
max-width: 840px;
/* max-width: 840px; */
margin: 0 auto;
box-shadow: 2px 2px 6px rgba(0,0,0,.3);
border-top: none;
@ -190,7 +190,7 @@
overflow-y: auto;
}
.chatVisitorPage .chatBox{
padding: 5px 4px;
padding: 5px 14px;
}
.chatBox .el-col{margin:10px 0;}
.chatUser{
@ -203,6 +203,12 @@
.chatMainPage{
margin-top: 1px;
}
.kefuMe{
padding-left: 10px;
}
.chatMsgContent{
padding-right: 10px;
}
.chatContent {
background-color: rgb(255,255,255);
color: #000;
@ -217,8 +223,8 @@
font-size: 14px;
}
.chatContent2 {
border-radius: 8px 8px 8px 0px;
padding: 10px 15px;
border-radius: 3px;
padding: 6px 15px;
}
.chatBoxMe{
margin-top: 10px;
@ -249,6 +255,9 @@ a{color: #07a9fe;text-decoration: none;}
z-index: 99;
border-top: 1px solid #e4e4e4;
}
.el-button--primary{
border-radius: 5px;
}
.chatBoxSendBtn{float: right;margin: 12px 4px 0 0;}
.footContact{text-align: center;
position: absolute;
@ -350,7 +359,8 @@ a{color: #07a9fe;text-decoration: none;}
overflow: hidden;
background-color: rgb(11 113 236);
background-image: url(../images/visitor_title_bg.png);
background-size: auto 72px;
background-repeat: no-repeat;
background-size: 100% 72px;
background-position: center 0;
align-items: center;
}
@ -367,6 +377,7 @@ a{color: #07a9fe;text-decoration: none;}
position: relative;
}
.chatArticle{
height: 100%;
display: none;
}
.visitorIconBox{
@ -403,7 +414,7 @@ a{color: #07a9fe;text-decoration: none;}
}
@media screen and (min-width: 900px) {
.chatCenter {
max-height: 650px;
/* max-height: 650px; */
box-shadow: 0 2px 8px rgba(0,0,0,.15);
border-radius: 8px;
}
@ -424,7 +435,7 @@ a{color: #07a9fe;text-decoration: none;}
.chatEntBox {
width: calc(100% - 265px);
float: left;
border-right: 1px solid #e6e6e6;
/* border-right: 1px solid #e6e6e6; */
}
.chatArticle {
display: block;
@ -444,19 +455,32 @@ a{color: #07a9fe;text-decoration: none;}
color: rgb(250, 84, 28);
}
}
.message-box-send{
display: flex;
gap: 10px;
}
.message-box-send .btn-box{
display: flex;
align-items: end;
padding-right: 10px;
}
.message-box-send .el-textarea__inner{
background-color: rgba(0, 0, 0, 0.1);
color: #000;
}
.visitorEditorArea{
width: 80%;
margin-top: 5px;
padding-left: 8px;
}
.visitorEditorArea textarea {
padding: 7px 0 7px 8px;
font-size:16px;
line-height: 21px;
font-size:14px;
line-height: 15px;
border: none;
}
.visitorEditorBtn{
position: absolute;
right: 10px;
bottom: 2px;
padding: 8px 20px;
}
.mainLeftMenu {
width: 70px;
@ -532,7 +556,13 @@ a{color: #07a9fe;text-decoration: none;}
line-height: 23px;
color: #666;
}
.el-textarea{
/* padding: 5px 10px ; */
}
.chatArea .el-textarea__inner{
border: none;
}
.tongji{

216
static/css/dark-mode.css Normal file
View File

@ -0,0 +1,216 @@
/* Dark Mode Styles for Customer Service Chat - Deep Green Theme */
/* 暗色模式下的背景和文字颜色 */
body.dark-mode {
background-color: #1a3d35 !important;
color: #FFFFFF !important;
}
body.dark-mode .visitorBody {
/* background-color: #1E3838 !important; */
}
/* 聊天容器 */
body.dark-mode .chatCenter {
background-color: #1a3d35 !important;
/* background-color: red !important; */
}
/* 聊天标题区域 */
body.dark-mode .chatEntTitle {
background: linear-gradient(to right, #001E14 0%, #007C34 100%);
color: #FFFFFF !important;
border-bottom: 1px solid #355050 !important;
}
/* 聊天内容区域 */
body.dark-mode .chatEntBox {
background-color: #1a3d35 !important;
}
body.dark-mode .chatVisitorPage {
background-color: #1a3d35 !important;
}
body.dark-mode .chatBox {
background-color: #1a3d35 !important;
}
/* 聊天消息气泡 - 客服消息 */
body.dark-mode .chatContent {
background-color: #2D5050 !important;
color: #FFFFFF !important;
border: 1px solid #355858 !important;
}
/* 聊天消息气泡 - 访客消息 */
body.dark-mode .chatBoxMe .chatContent {
background-color: #246153 !important;
color: #FFFFFF !important;
border: 1px solid #246153 !important;
}
/* 时间戳 */
body.dark-mode .chatTime {
color: #A0BFBF !important;
}
body.dark-mode .chatTime span {
background-color: #2A4848 !important;
color: #A0BFBF !important;
}
/* 通知消息 */
body.dark-mode .chatNotice {
/* background-color: #2D4A4A !important; */
}
body.dark-mode .chatNoticeContent {
color: #fff !important;
background-color: #2D5050;
}
/* 输入框区域 */
body.dark-mode .chatBoxSend {
background-color: #065946 !important;
border-top: 1px solid #355050 !important;
}
/* Element UI 输入框暗色模式 */
body.dark-mode .el-textarea__inner {
background-color: rgba(0,0,0,0.2) !important;
border-color: #fff !important;
color: #FFFFFF !important;
}
body.dark-mode .el-textarea__inner:focus {
border-color: #507070 !important;
}
body.dark-mode .el-textarea__inner::placeholder {
color: #7A9999 !important;
}
/* 图标按钮 */
body.dark-mode .iconBtn {
color: #FFFFFF !important;
}
body.dark-mode .iconBtn:hover {
color: #FFB84D !important;
}
body.dark-mode .visitorIconBtns {
color: #FFFFFF !important;
}
body.dark-mode .visitorIconBtns:hover {
color: #FFB84D !important;
}
/* 表情面板 */
body.dark-mode .faceBox {
background-color: #2A4848 !important;
border: 1px solid #355050 !important;
}
body.dark-mode .faceBoxList li {
border-color: #355050 !important;
background-color: #1E3838 !important;
}
body.dark-mode .faceBoxList li:hover {
background-color: #355050 !important;
}
/* 公告区域 */
body.dark-mode .chatArticle {
background-color: #27463f !important;
border-top: 1px solid #355050 !important;
}
body.dark-mode .hotQuestionTitle {
color: #FFFFFF !important;
border-bottom: 1px solid #355050 !important;
}
body.dark-mode .allNotice {
color: #A0BFBF !important;
}
/* Element UI 组件暗色模式 */
body.dark-mode .el-button--primary {
background-color: #ffc800 !important;
border-color: #ffc800 !important;
color: #000;
}
body.dark-mode .el-button--primary:hover {
background-color: #ffc800 !important;
}
body.dark-mode .el-button--primary.is-disabled {
opacity: 0.5;
color: #000 !important;
}
/* 链接 */
body.dark-mode a {
color: #FFB84D !important;
}
body.dark-mode a:hover {
color: #FFC870 !important;
}
/* 滚动条 */
body.dark-mode ::-webkit-scrollbar {
width: 8px;
height: 8px;
}
body.dark-mode ::-webkit-scrollbar-track {
background-color: #1E3838;
}
body.dark-mode ::-webkit-scrollbar-thumb {
background-color: #355050;
border-radius: 4px;
}
body.dark-mode ::-webkit-scrollbar-thumb:hover {
background-color: #406060;
}
/* Badge */
body.dark-mode .el-badge__content {
background-color: #FFB84D !important;
}
/* Message 组件 */
body.dark-mode .el-message {
background-color: #2A4848 !important;
border-color: #355050 !important;
color: #FFFFFF !important;
}
body.dark-mode .el-message--warning {
background-color: #6A5A3A !important;
border-color: #8A7A5A !important;
}
/* Tooltip */
body.dark-mode .el-tooltip__popper {
background-color: #2A4848 !important;
color: #FFFFFF !important;
}
body.dark-mode .el-tooltip__popper[x-placement^=top] .popper__arrow {
border-top-color: #2A4848 !important;
}
body.dark-mode .el-tooltip__popper[x-placement^=bottom] .popper__arrow {
border-bottom-color: #2A4848 !important;
}

View File

@ -0,0 +1,212 @@
/* Dark Mode Styles for Customer Service Chat */
/* 暗色模式下的背景和文字颜色 */
body.dark-mode {
/* background-color: #1a1a1a !important; */
color: #e0e0e0 !important;
}
body.dark-mode .visitorBody {
background-color: #1a1a1a !important;
}
/* 聊天容器 */
body.dark-mode .chatCenter {
/* background-color: #1a1a1a !important; */
}
/* 聊天标题区域 */
body.dark-mode .chatEntTitle {
background-color: #2d2d2d !important;
color: #e0e0e0 !important;
border-bottom: 1px solid #3d3d3d !important;
}
/* 聊天内容区域 */
body.dark-mode .chatEntBox {
/* background-color: #1a1a1a !important; */
}
body.dark-mode .chatVisitorPage {
/* background-color: #1a1a1a !important; */
}
body.dark-mode .chatBox {
/* background-color: #1a1a1a !important; */
}
/* 聊天消息气泡 - 客服消息 */
body.dark-mode .chatContent {
background-color: #2d2d2d !important;
color: #e0e0e0 !important;
border: 1px solid #3d3d3d !important;
}
/* 聊天消息气泡 - 访客消息 */
body.dark-mode .chatBoxMe .chatContent {
background-color: #1e5a8e !important;
color: #ffffff !important;
border: 1px solid #2d7ab8 !important;
}
/* 时间戳 */
body.dark-mode .chatTime {
color: #888888 !important;
}
body.dark-mode .chatTime span {
background-color: #2d2d2d !important;
color: #888888 !important;
}
/* 通知消息 */
body.dark-mode .chatNotice {
/* background-color: #2d2d2d !important; */
}
body.dark-mode .chatNoticeContent {
color: #4a9eff !important;
}
/* 输入框区域 */
body.dark-mode .chatBoxSend {
background-color: #2d2d2d !important;
border-top: 1px solid #3d3d3d !important;
}
/* Element UI 输入框暗色模式 */
body.dark-mode .el-textarea__inner {
background-color: #1a1a1a !important;
border-color: #3d3d3d !important;
color: #e0e0e0 !important;
}
body.dark-mode .el-textarea__inner:focus {
border-color: #4a9eff !important;
}
body.dark-mode .el-textarea__inner::placeholder {
color: #666666 !important;
}
/* 图标按钮 */
body.dark-mode .iconBtn {
color: #b0b0b0 !important;
}
body.dark-mode .iconBtn:hover {
color: #4a9eff !important;
}
body.dark-mode .visitorIconBtns {
color: #b0b0b0 !important;
}
body.dark-mode .visitorIconBtns:hover {
color: #4a9eff !important;
}
/* 表情面板 */
body.dark-mode .faceBox {
background-color: #2d2d2d !important;
border: 1px solid #3d3d3d !important;
}
body.dark-mode .faceBoxList li {
border-color: #3d3d3d !important;
background-color: #1a1a1a !important;
}
body.dark-mode .faceBoxList li:hover {
background-color: #3d3d3d !important;
}
/* 公告区域 */
body.dark-mode .chatArticle {
background-color: #2d2d2d !important;
border-top: 1px solid #3d3d3d !important;
}
body.dark-mode .hotQuestionTitle {
color: #e0e0e0 !important;
border-bottom: 1px solid #3d3d3d !important;
}
body.dark-mode .allNotice {
color: #b0b0b0 !important;
}
/* Element UI 组件暗色模式 */
body.dark-mode .el-button--primary {
background-color: #1e5a8e !important;
border-color: #2d7ab8 !important;
}
body.dark-mode .el-button--primary:hover {
background-color: #2d7ab8 !important;
}
body.dark-mode .el-button--primary.is-disabled {
background-color: #3d3d3d !important;
border-color: #3d3d3d !important;
color: #666666 !important;
}
/* 链接 */
body.dark-mode a {
color: #4a9eff !important;
}
body.dark-mode a:hover {
color: #70b4ff !important;
}
/* 滚动条 */
body.dark-mode ::-webkit-scrollbar {
width: 8px;
height: 8px;
}
body.dark-mode ::-webkit-scrollbar-track {
background-color: #1a1a1a;
}
body.dark-mode ::-webkit-scrollbar-thumb {
background-color: #3d3d3d;
border-radius: 4px;
}
body.dark-mode ::-webkit-scrollbar-thumb:hover {
background-color: #4d4d4d;
}
/* Badge */
body.dark-mode .el-badge__content {
background-color: #4a9eff !important;
}
/* Message 组件 */
body.dark-mode .el-message {
background-color: #2d2d2d !important;
border-color: #3d3d3d !important;
color: #e0e0e0 !important;
}
body.dark-mode .el-message--warning {
background-color: #5a4e1e !important;
border-color: #7a6e3e !important;
}
/* Tooltip */
body.dark-mode .el-tooltip__popper {
background-color: #2d2d2d !important;
color: #e0e0e0 !important;
}
body.dark-mode .el-tooltip__popper[x-placement^=top] .popper__arrow {
border-top-color: #2d2d2d !important;
}
body.dark-mode .el-tooltip__popper[x-placement^=bottom] .popper__arrow {
border-bottom-color: #2d2d2d !important;
}

View File

@ -5,6 +5,73 @@
<meta name="keywords" content="Golang Open Source LiveChat Software"/>
<meta name="description" content="Golang Open Source LiveChat Software"/>
<title>Live Chat Support</title>
<!-- 防止闪烁:在页面渲染前应用主题 -->
<script>
(function() {
// 1. 从 URL 参数获取主题
const urlParams = new URLSearchParams(window.location.search);
const themeParam = urlParams.get('theme');
// 2. 从 localStorage 获取保存的主题
const savedTheme = localStorage.getItem('theme');
// 3. 检测是否在 iframe 中
const isInIframe = window.parent !== window;
// 4. 确定要使用的主题
// 如果在 iframe 中且没有明确指定主题,默认使用暗色模式(避免闪烁)
let theme;
if (themeParam) {
theme = themeParam;
} else if (savedTheme) {
theme = savedTheme;
} else if (isInIframe) {
// iframe 环境默认暗色,等待父页面发送实际主题
theme = 'dark';
} else {
theme = 'light';
}
// 5. 立即设置HTML背景色和应用主题类
if (theme === 'dark') {
// 暗色模式:立即设置内联样式防止闪烁
document.documentElement.style.backgroundColor = '#1a3d35';
document.documentElement.style.color = '#FFFFFF';
document.documentElement.classList.add('dark-mode-init');
} else {
// 白天模式:移除可能存在的暗色类和样式
document.documentElement.classList.remove('dark-mode-init');
document.documentElement.style.backgroundColor = '';
document.documentElement.style.color = '';
}
// 6. 在脚本末尾立即尝试给body添加类此时body可能还不存在
// 使用定时器快速重试,确保尽早添加
let retryCount = 0;
const maxRetries = 50; // 最多重试50次
const applyBodyClass = function() {
if (document.body) {
if (theme === 'dark') {
document.body.classList.add('dark-mode');
// 移除html的内联样式让CSS接管
document.documentElement.style.backgroundColor = '';
document.documentElement.style.color = '';
} else {
// 白天模式:确保移除暗色类
document.body.classList.remove('dark-mode');
}
return true;
} else if (retryCount < maxRetries) {
retryCount++;
setTimeout(applyBodyClass, 10); // 10ms后重试
return false;
}
return false;
};
applyBodyClass();
})();
</script>
<link rel="stylesheet" href="/static/cdn/element-ui/2.15.1/theme-chalk/index.min.css">
<script src="/static/cdn/vue/2.6.11/vue.min.js"></script>
<script src="/static/cdn/element-ui/2.15.1/index.js"></script>
@ -15,6 +82,7 @@
<link rel="stylesheet" href="/static/css/common.css?v=sdsderfrgfgdfdf" />
<link rel="stylesheet" href="/static/css/icono.min.css" />
<link rel="stylesheet" href="/static/css/icon/iconfont.css?v=fgjlgfda"/>
<link rel="stylesheet" href="/static/css/dark-mode.css" />
</head>
<body class="visitorBody">
<div id="app" class="chatCenter">
@ -25,14 +93,14 @@
<el-avatar class="chatEntTitleLogo" :size="35" :src="kefuInfo.avatar"></el-avatar>
</el-badge>
<div>
<div>Live Chat Support</div>
<div>在线客服</div>
</div>
</div>
<div class="chatEntBox">
<div class="chatContext chatVisitorPage">
<div class="chatBox">
<div class="chatNotice" v-on:click="getHistoryMessage" v-show="showLoadMore">
<a href="javascript:;" class="chatNoticeContent" style="color: #07a9fe;">Load more messages</a>
<a href="javascript:;" class="chatNoticeContent" style="color: #07a9fe;">加载更多消息</a>
</div>
<el-row :gutter="2" v-for="v in msgList" v-bind:class="{'chatBoxMe': v.is_kefu==false}">
<div class="chatTime" v-bind:class="{'chatTimeHide': v.show_time==false}"><span><{v.time}></span></div>
@ -53,14 +121,14 @@
<div class="chatBoxSend">
<div class="visitorIconBox">
<el-tooltip content="Send emoji" placement="top">
<div class="iconBtn iconfont icon-xiaolian" style="margin-left:10px;font-size: 24px;cursor: pointer;" @click.stop="showFaceIcon==true?showFaceIcon=false:showFaceIcon=true"></div>
<div class="iconBtn iconfont icon-xiaolian" style="margin-left:15px;font-size: 20px;cursor: pointer;" @click.stop="showFaceIcon==true?showFaceIcon=false:showFaceIcon=true"></div>
</el-tooltip>
<el-tooltip content="Upload image" placement="top">
<div class="iconBtn el-icon-picture" id="uploadImg" v-on:click="uploadImg('/uploadimg')" style="font-size: 24px;"></div>
<div class="iconBtn el-icon-picture" id="uploadImg" v-on:click="uploadImg('/uploadimg')" style="font-size: 20px;"></div>
</el-tooltip>
<el-tooltip content="Upload file" placement="top">
<div class="iconBtn el-icon-upload" id="uploadFile" v-on:click="uploadFile('/uploadfile')" style="font-size: 26px;"></div>
<div class="iconBtn el-icon-upload" id="uploadFile" v-on:click="uploadFile('/uploadfile')" style="font-size: 20px;"></div>
</el-tooltip>
<div style="display: none" title="Emoji" class="icono-smile visitorIconBtns visitorFaceBtn"></div>
@ -73,13 +141,17 @@
</ul>
<div class="clear"></div>
</div>
<el-input :rows="2" type="textarea" resize="none" class="visitorEditorArea" @focus="scrollBottom;showIconBtns=false" @blur="scrollBottom;showIconBtns=false" v-model="messageContent" v-on:keyup.enter.native="chatToUser">
</el-input>
<el-button type="primary" size="mini" class="visitorEditorBtn" :loading="sendDisabled" :disabled="sendDisabled||messageContent==''" v-on:click="chatToUser();showIconBtns=false"><{ sendDisabled ? 'Sending...' : 'Send' }></el-button>
<div class="message-box-send">
<el-input :rows="2" type="textarea" resize="none" class="visitorEditorArea" @focus="scrollBottom;showIconBtns=false" @blur="scrollBottom;showIconBtns=false" v-model="messageContent" v-on:keyup.enter.native="chatToUser">
</el-input>
<div class="btn-box">
<el-button type="primary" size="mini" class="visitorEditorBtn" :loading="sendDisabled" :disabled="sendDisabled||messageContent==''" v-on:click="chatToUser();showIconBtns=false"><{ sendDisabled ? '发送中...' : '发送' }></el-button>
</div>
</div>
</div>
</div>
<div class="chatArticle">
<h3 class="hotQuestionTitle">Announcements</h3>
<h3 class="hotQuestionTitle">公告</h3>
<div class="allNotice" v-html><{kefuInfo.allNotice}></div>
</div>
@ -91,6 +163,51 @@
<script>
var KEFU_ID='{{.KEFU_ID}}';
var REFER='{{.Refer}}';
// 主题切换函数
function setTheme(theme) {
if (theme === 'dark') {
document.body.classList.add('dark-mode');
localStorage.setItem('theme', 'dark');
} else {
document.body.classList.remove('dark-mode');
localStorage.setItem('theme', 'light');
}
}
// 监听来自父页面的主题变化消息
window.addEventListener('message', function(event) {
// 安全检查:可以添加 origin 验证
// if (event.origin !== 'https://your-parent-domain.com') return;
if (event.data && event.data.type === 'theme-change') {
console.log('Received theme change:', event.data.theme);
setTheme(event.data.theme);
}
});
// 页面加载时,应用主题(已在 head 中预设)
(function() {
// 检查是否在 head 中已经设置了暗色模式
const isDarkInit = document.documentElement.classList.contains('dark-mode-init');
if (isDarkInit) {
// 已在 head 中设置为暗色,直接应用
document.body.classList.add('dark-mode');
localStorage.setItem('theme', 'dark');
// 移除临时类
document.documentElement.classList.remove('dark-mode-init');
} else {
// 确保是亮色模式
document.body.classList.remove('dark-mode');
localStorage.setItem('theme', 'light');
}
// 通知父页面已准备好接收主题消息
if (window.parent !== window) {
window.parent.postMessage({ type: 'iframe-ready' }, '*');
}
})();
</script>
<script>
var initVue=function(){
@ -149,7 +266,7 @@
return;
}
this.visitor.to_id=msg.id;
this.showTitle(msg.name+", is chatting with you");
this.showTitle(msg.name+", 正正与您对话");
this.scrollBottom();
this.showKfonline=true;
}
@ -361,7 +478,7 @@
var code=res.code;
if(code!=200) return;
_this.kefuInfo=res.result;
_this.showTitle(_this.kefuInfo.nickname+" at your service.");
_this.showTitle(_this.kefuInfo.nickname+" 为您服务.");
if(!_this.kefuInfo.welcome) return;
var msg={
content:replaceContent(_this.kefuInfo.welcome),