Merge branch 'yongpxu-dev' into yongpxu-dev2
# Conflicts: # Cunkebao/dist/.vite/manifest.json # Cunkebao/dist/index.html
This commit is contained in:
18
Cunkebao/dist/.vite/manifest.json
vendored
18
Cunkebao/dist/.vite/manifest.json
vendored
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"_charts-62ymwWYF.js": {
|
||||
"file": "assets/charts-62ymwWYF.js",
|
||||
"_charts-M0qaf_ew.js": {
|
||||
"file": "assets/charts-M0qaf_ew.js",
|
||||
"name": "charts",
|
||||
"imports": [
|
||||
"_ui-DUe_gloh.js",
|
||||
"_ui-D5qYGnLz.js",
|
||||
"_vendor-2vc8h_ct.js"
|
||||
]
|
||||
},
|
||||
@@ -11,8 +11,8 @@
|
||||
"file": "assets/ui-D0C0OGrH.css",
|
||||
"src": "_ui-D0C0OGrH.css"
|
||||
},
|
||||
"_ui-DUe_gloh.js": {
|
||||
"file": "assets/ui-DUe_gloh.js",
|
||||
"_ui-D5qYGnLz.js": {
|
||||
"file": "assets/ui-D5qYGnLz.js",
|
||||
"name": "ui",
|
||||
"imports": [
|
||||
"_vendor-2vc8h_ct.js"
|
||||
@@ -33,18 +33,18 @@
|
||||
"name": "vendor"
|
||||
},
|
||||
"index.html": {
|
||||
"file": "assets/index-BQZfedpY.js",
|
||||
"file": "assets/index-BQxyt58_.js",
|
||||
"name": "index",
|
||||
"src": "index.html",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_vendor-2vc8h_ct.js",
|
||||
"_utils-6WF66_dS.js",
|
||||
"_ui-DUe_gloh.js",
|
||||
"_charts-62ymwWYF.js"
|
||||
"_ui-D5qYGnLz.js",
|
||||
"_charts-M0qaf_ew.js"
|
||||
],
|
||||
"css": [
|
||||
"assets/index-ejYsXKTB.css"
|
||||
"assets/index-B6B8u-1D.css"
|
||||
]
|
||||
}
|
||||
}
|
||||
8
Cunkebao/dist/index.html
vendored
8
Cunkebao/dist/index.html
vendored
@@ -11,13 +11,13 @@
|
||||
</style>
|
||||
<!-- 引入 uni-app web-view SDK(必须) -->
|
||||
<script type="text/javascript" src="/websdk.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-BQZfedpY.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-BQxyt58_.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/vendor-2vc8h_ct.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/utils-6WF66_dS.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/ui-DUe_gloh.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/charts-62ymwWYF.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/ui-D5qYGnLz.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/charts-M0qaf_ew.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/ui-D0C0OGrH.css">
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-ejYsXKTB.css">
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-B6B8u-1D.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
@@ -1,50 +1,100 @@
|
||||
.headerContainer {
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.searchBar {
|
||||
padding: 16px 16px 8px;
|
||||
.sidebarMenu {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #fff;
|
||||
|
||||
:global(.ant-input) {
|
||||
border-radius: 20px;
|
||||
background: #f5f5f5;
|
||||
border: none;
|
||||
.headerContainer {
|
||||
padding: 16px;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
|
||||
&:focus {
|
||||
.searchBar {
|
||||
margin-bottom: 16px;
|
||||
padding: 0;
|
||||
background: #fff;
|
||||
border: 1px solid #1890ff;
|
||||
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
|
||||
|
||||
:global(.ant-input) {
|
||||
border-radius: 20px;
|
||||
background: #f5f5f5;
|
||||
border: none;
|
||||
|
||||
&:focus {
|
||||
background: #fff;
|
||||
border: 1px solid #1890ff;
|
||||
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tabsContainer {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
padding: 0 0 8px;
|
||||
|
||||
.tabItem {
|
||||
padding: 8px 0;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
color: #999;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: #1890ff;
|
||||
border-bottom: 2px solid #1890ff;
|
||||
}
|
||||
|
||||
span {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tabsContainer {
|
||||
// 骨架屏样式
|
||||
.skeletonContainer {
|
||||
height: 100%;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
padding: 0 16px 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
flex-direction: column;
|
||||
|
||||
.tabItem {
|
||||
.searchBarSkeleton {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.tabsContainerSkeleton {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
transition: all 0.3s;
|
||||
justify-content: space-around;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #1890ff;
|
||||
background-color: rgba(24, 144, 255, 0.1);
|
||||
}
|
||||
.contactListSkeleton {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
|
||||
&.active {
|
||||
color: #1890ff;
|
||||
background-color: rgba(24, 144, 255, 0.1);
|
||||
}
|
||||
.contactItemSkeleton {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
|
||||
span {
|
||||
margin-left: 4px;
|
||||
.contactInfoSkeleton {
|
||||
margin-left: 12px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,3 +109,16 @@
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.contentContainer {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.footer {
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
background: #fff;
|
||||
display: none; /* 默认隐藏底部,如果需要显示可以移除此行 */
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState } from "react";
|
||||
import { Input } from "antd";
|
||||
import { Input, Skeleton } from "antd";
|
||||
import {
|
||||
SearchOutlined,
|
||||
UserOutlined,
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
import { ContractData } from "@/pages/pc/ckbox/data";
|
||||
import WechatFriendsModule from "./WechatFriendsModule";
|
||||
import MessageList from "./MessageList/index";
|
||||
import LayoutFiexd from "@/components/Layout/LayoutFiexd";
|
||||
import styles from "./SidebarMenu.module.scss";
|
||||
import { getChatSessions } from "@/store/module/ckchat";
|
||||
|
||||
@@ -53,6 +52,51 @@ const SidebarMenu: React.FC<SidebarMenuProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
// 渲染骨架屏
|
||||
const renderSkeleton = () => (
|
||||
<div className={styles.skeletonContainer}>
|
||||
<div className={styles.searchBarSkeleton}>
|
||||
<Skeleton.Input active size="small" block />
|
||||
</div>
|
||||
<div className={styles.tabsContainerSkeleton}>
|
||||
<Skeleton.Button
|
||||
active
|
||||
size="small"
|
||||
shape="square"
|
||||
style={{ width: "30%" }}
|
||||
/>
|
||||
<Skeleton.Button
|
||||
active
|
||||
size="small"
|
||||
shape="square"
|
||||
style={{ width: "30%" }}
|
||||
/>
|
||||
<Skeleton.Button
|
||||
active
|
||||
size="small"
|
||||
shape="square"
|
||||
style={{ width: "30%" }}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.contactListSkeleton}>
|
||||
{Array(8)
|
||||
.fill(null)
|
||||
.map((_, index) => (
|
||||
<div
|
||||
key={`contact-skeleton-${index}`}
|
||||
className={styles.contactItemSkeleton}
|
||||
>
|
||||
<Skeleton.Avatar active size="large" shape="circle" />
|
||||
<div className={styles.contactInfoSkeleton}>
|
||||
<Skeleton.Input active size="small" style={{ width: "60%" }} />
|
||||
<Skeleton.Input active size="small" style={{ width: "80%" }} />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
// 渲染Header部分,包含搜索框和标签页切换
|
||||
const renderHeader = () => (
|
||||
<div className={styles.headerContainer}>
|
||||
@@ -125,10 +169,15 @@ const SidebarMenu: React.FC<SidebarMenuProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return renderSkeleton();
|
||||
}
|
||||
|
||||
return (
|
||||
<LayoutFiexd header={renderHeader()} footer="底部">
|
||||
{renderContent()}
|
||||
</LayoutFiexd>
|
||||
<div className={styles.sidebarMenu}>
|
||||
{renderHeader()}
|
||||
<div className={styles.contentContainer}>{renderContent()}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
.skeletonLayout {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.skeletonHeader {
|
||||
height: 64px;
|
||||
padding: 0 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.skeletonVerticalSider {
|
||||
background-color: #fff;
|
||||
border-right: 1px solid #f0f0f0;
|
||||
|
||||
.verticalUserList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 16px 0;
|
||||
|
||||
.verticalUserItem {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.skeletonSider {
|
||||
background-color: #fff;
|
||||
border-right: 1px solid #f0f0f0;
|
||||
padding: 16px;
|
||||
|
||||
.searchSkeleton {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.tabsSkeleton {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.contactListSkeleton {
|
||||
.contactItemSkeleton {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
|
||||
.contactInfoSkeleton {
|
||||
margin-left: 12px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.skeletonMainContent {
|
||||
background-color: #f5f5f5;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.chatHeaderSkeleton {
|
||||
background-color: #fff;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
border-radius: 8px 8px 0 0;
|
||||
}
|
||||
|
||||
.chatContentSkeleton {
|
||||
flex: 1;
|
||||
background-color: #fff;
|
||||
padding: 16px;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
|
||||
.messageSkeleton {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
|
||||
&.leftMessage {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
&.rightMessage {
|
||||
align-self: flex-end;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.inputAreaSkeleton {
|
||||
background-color: #fff;
|
||||
padding: 16px;
|
||||
border-radius: 0 0 8px 8px;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
}
|
||||
}
|
||||
}
|
||||
91
Cunkebao/src/pages/pc/ckbox/components/Skeleton/index.tsx
Normal file
91
Cunkebao/src/pages/pc/ckbox/components/Skeleton/index.tsx
Normal file
@@ -0,0 +1,91 @@
|
||||
import React from 'react';
|
||||
import { Skeleton, Layout } from 'antd';
|
||||
import styles from './index.module.scss';
|
||||
import pageStyles from '../../index.module.scss';
|
||||
|
||||
const { Header, Content, Sider } = Layout;
|
||||
|
||||
interface PageSkeletonProps {
|
||||
loading: boolean;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 页面骨架屏组件
|
||||
* 在数据加载完成前显示骨架屏
|
||||
*/
|
||||
const PageSkeleton: React.FC<PageSkeletonProps> = ({ loading, children }) => {
|
||||
if (!loading) return <>{children}</>;
|
||||
|
||||
return (
|
||||
<Layout className={pageStyles.ckboxLayout}>
|
||||
<Header className={pageStyles.header}>
|
||||
<Skeleton.Button active size="large" shape="square" block />
|
||||
</Header>
|
||||
<Layout>
|
||||
{/* 垂直侧边栏骨架 */}
|
||||
<Sider width={60} className={pageStyles.verticalSider}>
|
||||
<div className={styles.verticalUserList}>
|
||||
{Array(5)
|
||||
.fill(null)
|
||||
.map((_, index) => (
|
||||
<div key={`vertical-${index}`} className={styles.verticalUserItem}>
|
||||
<Skeleton.Avatar active size="large" shape="circle" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Sider>
|
||||
|
||||
{/* 左侧联系人边栏骨架 */}
|
||||
<Sider width={280} className={pageStyles.sider}>
|
||||
<div className={styles.searchSkeleton}>
|
||||
<Skeleton.Input active size="small" block />
|
||||
</div>
|
||||
<div className={styles.tabsSkeleton}>
|
||||
<Skeleton.Button active size="small" shape="square" style={{ width: '30%' }} />
|
||||
<Skeleton.Button active size="small" shape="square" style={{ width: '30%' }} />
|
||||
</div>
|
||||
<div className={styles.contactListSkeleton}>
|
||||
{Array(8)
|
||||
.fill(null)
|
||||
.map((_, index) => (
|
||||
<div key={`contact-${index}`} className={styles.contactItemSkeleton}>
|
||||
<Skeleton.Avatar active size="large" shape="circle" />
|
||||
<div className={styles.contactInfoSkeleton}>
|
||||
<Skeleton.Input active size="small" style={{ width: '60%' }} />
|
||||
<Skeleton.Input active size="small" style={{ width: '80%' }} />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Sider>
|
||||
|
||||
{/* 主内容区骨架 */}
|
||||
<Content className={styles.skeletonMainContent}>
|
||||
<div className={styles.chatHeaderSkeleton}>
|
||||
<Skeleton.Avatar active size="large" shape="circle" />
|
||||
<Skeleton.Input active size="small" style={{ width: '30%' }} />
|
||||
</div>
|
||||
<div className={styles.chatContentSkeleton}>
|
||||
{Array(5)
|
||||
.fill(null)
|
||||
.map((_, index) => (
|
||||
<div
|
||||
key={`message-${index}`}
|
||||
className={`${styles.messageSkeleton} ${index % 2 === 0 ? styles.leftMessage : styles.rightMessage}`}
|
||||
>
|
||||
<Skeleton.Avatar active size="small" shape="circle" />
|
||||
<Skeleton.Input active size="small" style={{ width: index % 2 === 0 ? '60%' : '40%' }} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className={styles.inputAreaSkeleton}>
|
||||
<Skeleton.Input active size="large" block />
|
||||
</div>
|
||||
</Content>
|
||||
</Layout>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
export default PageSkeleton;
|
||||
@@ -1,15 +1,17 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Layout, Button, Space, message, Tooltip, Spin } from "antd";
|
||||
import { Layout, Button, Space, message, Tooltip } from "antd";
|
||||
import { InfoCircleOutlined, MessageOutlined } from "@ant-design/icons";
|
||||
import dayjs from "dayjs";
|
||||
import { ContractData } from "./data";
|
||||
import ChatWindow from "./components/ChatWindow/index";
|
||||
import SidebarMenu from "./components/SidebarMenu/index";
|
||||
import VerticalUserList from "./components/VerticalUserList";
|
||||
import PageSkeleton from "./components/Skeleton";
|
||||
import styles from "./index.module.scss";
|
||||
import { addChatSession } from "@/store/module/ckchat";
|
||||
const { Header, Content, Sider } = Layout;
|
||||
import { chatInitAPIdata } from "./main";
|
||||
import { KfUserListData } from "@/store/module/ckchat.data";
|
||||
|
||||
const CkboxPage: React.FC = () => {
|
||||
const [messageApi, contextHolder] = message.useMessage();
|
||||
@@ -25,7 +27,17 @@ const CkboxPage: React.FC = () => {
|
||||
setLoading(true);
|
||||
chatInitAPIdata()
|
||||
.then(response => {
|
||||
const { contractList, chatRoomList, kfUserList } = response;
|
||||
const data = response as {
|
||||
contractList: any[];
|
||||
groupList: any[];
|
||||
kfUserList: KfUserListData[];
|
||||
newContractList: { groupName: string; contacts: any[] }[];
|
||||
};
|
||||
const { contractList, groupList, kfUserList, newContractList } = data;
|
||||
response;
|
||||
|
||||
console.log(contractList, groupList, kfUserList, newContractList);
|
||||
|
||||
//找出已经在聊天的
|
||||
const isChatList = contractList.filter(
|
||||
v => (v?.config && v.config?.chat) || false,
|
||||
@@ -77,66 +89,69 @@ const CkboxPage: React.FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Layout className={styles.ckboxLayout}>
|
||||
{contextHolder}
|
||||
<Header className={styles.header}>触客宝</Header>
|
||||
<Layout>
|
||||
{/* 垂直侧边栏 */}
|
||||
<PageSkeleton loading={loading}>
|
||||
<Layout className={styles.ckboxLayout}>
|
||||
{contextHolder}
|
||||
<Header className={styles.header}>触客宝</Header>
|
||||
<Layout>
|
||||
{/* 垂直侧边栏 */}
|
||||
|
||||
<Sider width={60} className={styles.verticalSider}>
|
||||
<VerticalUserList
|
||||
activeKfUserId={activeVerticalUserId}
|
||||
onUserSelect={handleVerticalUserSelect}
|
||||
/>
|
||||
</Sider>
|
||||
<Sider width={60} className={styles.verticalSider}>
|
||||
<VerticalUserList
|
||||
activeKfUserId={activeVerticalUserId}
|
||||
onUserSelect={handleVerticalUserSelect}
|
||||
/>
|
||||
</Sider>
|
||||
|
||||
{/* 左侧联系人边栏 */}
|
||||
<Sider width={280} className={styles.sider}>
|
||||
<SidebarMenu
|
||||
contracts={contracts}
|
||||
currentChat={currentChat}
|
||||
onContactClick={handleContactClick}
|
||||
onChatSelect={setCurrentChat}
|
||||
/>
|
||||
</Sider>
|
||||
{/* 左侧联系人边栏 */}
|
||||
<Sider width={280} className={styles.sider}>
|
||||
<SidebarMenu
|
||||
contracts={contracts}
|
||||
currentChat={currentChat}
|
||||
onContactClick={handleContactClick}
|
||||
onChatSelect={setCurrentChat}
|
||||
loading={loading}
|
||||
/>
|
||||
</Sider>
|
||||
|
||||
{/* 主内容区 */}
|
||||
<Content className={styles.mainContent}>
|
||||
{currentChat ? (
|
||||
<div className={styles.chatContainer}>
|
||||
<div className={styles.chatToolbar}>
|
||||
<Space>
|
||||
<Tooltip title={showProfile ? "隐藏资料" : "显示资料"}>
|
||||
<Button
|
||||
type={showProfile ? "primary" : "default"}
|
||||
icon={<InfoCircleOutlined />}
|
||||
onClick={() => setShowProfile(!showProfile)}
|
||||
size="small"
|
||||
>
|
||||
{showProfile ? "隐藏资料" : "显示资料"}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Space>
|
||||
{/* 主内容区 */}
|
||||
<Content className={styles.mainContent}>
|
||||
{currentChat ? (
|
||||
<div className={styles.chatContainer}>
|
||||
<div className={styles.chatToolbar}>
|
||||
<Space>
|
||||
<Tooltip title={showProfile ? "隐藏资料" : "显示资料"}>
|
||||
<Button
|
||||
type={showProfile ? "primary" : "default"}
|
||||
icon={<InfoCircleOutlined />}
|
||||
onClick={() => setShowProfile(!showProfile)}
|
||||
size="small"
|
||||
>
|
||||
{showProfile ? "隐藏资料" : "显示资料"}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Space>
|
||||
</div>
|
||||
<ChatWindow
|
||||
contract={currentChat}
|
||||
onSendMessage={handleSendMessage}
|
||||
showProfile={showProfile}
|
||||
onToggleProfile={() => setShowProfile(!showProfile)}
|
||||
/>
|
||||
</div>
|
||||
<ChatWindow
|
||||
contract={currentChat}
|
||||
onSendMessage={handleSendMessage}
|
||||
showProfile={showProfile}
|
||||
onToggleProfile={() => setShowProfile(!showProfile)}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className={styles.welcomeScreen}>
|
||||
<div className={styles.welcomeContent}>
|
||||
<MessageOutlined style={{ fontSize: 64, color: "#1890ff" }} />
|
||||
<h2>欢迎使用触客宝</h2>
|
||||
<p>选择一个联系人开始聊天</p>
|
||||
) : (
|
||||
<div className={styles.welcomeScreen}>
|
||||
<div className={styles.welcomeContent}>
|
||||
<MessageOutlined style={{ fontSize: 64, color: "#1890ff" }} />
|
||||
<h2>欢迎使用触客宝</h2>
|
||||
<p>选择一个联系人开始聊天</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Content>
|
||||
)}
|
||||
</Content>
|
||||
</Layout>
|
||||
</Layout>
|
||||
</Layout>
|
||||
</PageSkeleton>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -15,6 +15,11 @@ export const useCkChatStore = createPersistStore<CkChatState>(
|
||||
contractList: [], //联系人列表
|
||||
chatSessions: [], //聊天会话
|
||||
kfUserList: [], //客服列表
|
||||
newContractList: [], //联系人分组
|
||||
// 异步设置会话列表
|
||||
asyncNewContractList: data => {
|
||||
set({ newContractList: data });
|
||||
},
|
||||
// 异步设置会话列表
|
||||
asyncChatSessions: data => {
|
||||
set({ chatSessions: data });
|
||||
@@ -182,3 +187,6 @@ export const asyncContractList = (data: ContractData[]) =>
|
||||
useCkChatStore.getState().asyncContractList(data);
|
||||
export const asyncChatSessions = (data: ContractData[]) =>
|
||||
useCkChatStore.getState().asyncChatSessions(data);
|
||||
export const asyncNewContractList = (
|
||||
data: { groupName: string; contacts: any[] }[],
|
||||
) => useCkChatStore.getState().asyncNewContractList(data);
|
||||
|
||||
Reference in New Issue
Block a user