Merge branch 'yongpxu-dev' into develop

This commit is contained in:
超级老白兔
2025-09-11 10:11:50 +08:00
10 changed files with 100 additions and 73 deletions

View File

@@ -1,17 +1,17 @@
{
"_charts-BjEBSMrK.js": {
"file": "assets/charts-BjEBSMrK.js",
"_charts-DN1cefc8.js": {
"file": "assets/charts-DN1cefc8.js",
"name": "charts",
"imports": [
"_ui-CiJ_pikt.js",
"_vendor-BPPoWDlG.js"
"_ui-5V-xZWkf.js",
"_vendor-Bq99rrm8.js"
]
},
"_ui-CiJ_pikt.js": {
"file": "assets/ui-CiJ_pikt.js",
"_ui-5V-xZWkf.js": {
"file": "assets/ui-5V-xZWkf.js",
"name": "ui",
"imports": [
"_vendor-BPPoWDlG.js"
"_vendor-Bq99rrm8.js"
],
"css": [
"assets/ui-D0C0OGrH.css"
@@ -21,30 +21,30 @@
"file": "assets/ui-D0C0OGrH.css",
"src": "_ui-D0C0OGrH.css"
},
"_utils-DiZV3oaL.js": {
"file": "assets/utils-DiZV3oaL.js",
"_utils-Ft3ushmX.js": {
"file": "assets/utils-Ft3ushmX.js",
"name": "utils",
"imports": [
"_vendor-BPPoWDlG.js"
"_vendor-Bq99rrm8.js"
]
},
"_vendor-BPPoWDlG.js": {
"file": "assets/vendor-BPPoWDlG.js",
"_vendor-Bq99rrm8.js": {
"file": "assets/vendor-Bq99rrm8.js",
"name": "vendor"
},
"index.html": {
"file": "assets/index-DPe1huLQ.js",
"file": "assets/index-9Clf2a7g.js",
"name": "index",
"src": "index.html",
"isEntry": true,
"imports": [
"_vendor-BPPoWDlG.js",
"_utils-DiZV3oaL.js",
"_ui-CiJ_pikt.js",
"_charts-BjEBSMrK.js"
"_vendor-Bq99rrm8.js",
"_ui-5V-xZWkf.js",
"_utils-Ft3ushmX.js",
"_charts-DN1cefc8.js"
],
"css": [
"assets/index-prcd5sVt.css"
"assets/index-CK1wd128.css"
]
}
}

View File

@@ -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-DPe1huLQ.js"></script>
<link rel="modulepreload" crossorigin href="/assets/vendor-BPPoWDlG.js">
<link rel="modulepreload" crossorigin href="/assets/utils-DiZV3oaL.js">
<link rel="modulepreload" crossorigin href="/assets/ui-CiJ_pikt.js">
<link rel="modulepreload" crossorigin href="/assets/charts-BjEBSMrK.js">
<script type="module" crossorigin src="/assets/index-9Clf2a7g.js"></script>
<link rel="modulepreload" crossorigin href="/assets/vendor-Bq99rrm8.js">
<link rel="modulepreload" crossorigin href="/assets/ui-5V-xZWkf.js">
<link rel="modulepreload" crossorigin href="/assets/utils-Ft3ushmX.js">
<link rel="modulepreload" crossorigin href="/assets/charts-DN1cefc8.js">
<link rel="stylesheet" crossorigin href="/assets/ui-D0C0OGrH.css">
<link rel="stylesheet" crossorigin href="/assets/index-prcd5sVt.css">
<link rel="stylesheet" crossorigin href="/assets/index-CK1wd128.css">
</head>
<body>
<div id="root"></div>

View File

@@ -48,6 +48,11 @@ export default function ContentForm() {
const [showEndPicker, setShowEndPicker] = useState(false);
const [keywordsInclude, setKeywordsInclude] = useState("");
const [keywordsExclude, setKeywordsExclude] = useState("");
const [catchType, setCatchType] = useState<string[]>([
"text",
"image",
"video",
]);
const [submitting, setSubmitting] = useState(false);
const [loading, setLoading] = useState(false);
@@ -65,6 +70,7 @@ export default function ContentForm() {
setSelectedFriendsOptions(data.friendsGroupsOptions || []);
setKeywordsInclude((data.keywordInclude || []).join(","));
setKeywordsExclude((data.keywordExclude || []).join(","));
setCatchType(data.catchType || ["text", "image", "video"]);
setAIPrompt(data.aiPrompt || "");
setUseAI(!!data.aiPrompt);
setEnabled(data.status === 1);
@@ -108,6 +114,7 @@ export default function ContentForm() {
.split(/,||\n|\s+/)
.map(s => s.trim())
.filter(Boolean),
catchType,
aiPrompt,
timeEnabled: dateRange[0] || dateRange[1] ? 1 : 0,
startTime: dateRange[0] ? formatDate(dateRange[0]) : "",
@@ -236,6 +243,46 @@ export default function ContentForm() {
</Collapse.Panel>
</Collapse>
{/* 采集内容类型 */}
<div className={style["section-title"]}></div>
<div className={style["form-section"]}>
<div style={{ display: "flex", flexWrap: "wrap", gap: 12 }}>
{["text", "image", "video"].map(type => (
<div
key={type}
style={{
display: "flex",
alignItems: "center",
gap: 8,
padding: "8px 12px",
border: "1px solid #d9d9d9",
borderRadius: "6px",
backgroundColor: catchType.includes(type)
? "#1890ff"
: "#fff",
color: catchType.includes(type) ? "#fff" : "#333",
cursor: "pointer",
}}
onClick={() => {
setCatchType(prev =>
prev.includes(type)
? prev.filter(t => t !== type)
: [...prev, type],
);
}}
>
<span>
{type === "text"
? "文本"
: type === "image"
? "图片"
: "视频"}
</span>
</div>
))}
</div>
</div>
<div className={style["section-title"]}>AI</div>
<div
className={style["form-section"]}

View File

@@ -2,17 +2,16 @@ import React, { useState } from "react";
import { Button, Modal, Input, DatePicker, message } from "antd";
import { MessageOutlined } from "@ant-design/icons";
import dayjs from "dayjs";
import { useWeChatStore } from "@/store/module/weChat/weChat";
const { RangePicker } = DatePicker;
interface ChatRecordProps {
onSearch?: (data: { dateRange: [string, string]; content: string }) => void;
className?: string;
disabled?: boolean;
}
const ChatRecord: React.FC<ChatRecordProps> = ({
onSearch,
className,
disabled = false,
}) => {
@@ -22,6 +21,7 @@ const ChatRecord: React.FC<ChatRecordProps> = ({
null,
);
const [loading, setLoading] = useState(false);
const SearchMessage = useWeChatStore(state => state.SearchMessage);
// 打开弹窗
const openModal = () => {
@@ -43,26 +43,15 @@ const ChatRecord: React.FC<ChatRecordProps> = ({
return;
}
if (!searchContent.trim()) {
message.warning("请输入查找内容");
return;
}
try {
setLoading(true);
const [From, To] = dateRange;
const searchData = {
dateRange: [
dateRange[0].format("YYYY-MM-DD 00:00:00"),
dateRange[1].format("YYYY-MM-DD 23:59:59"),
] as [string, string],
content: searchContent.trim(),
From: From.unix() * 1000,
To: To.unix() * 1000,
keyword: searchContent.trim(),
};
// 调用回调函数
if (onSearch) {
await onSearch(searchData);
}
await SearchMessage(searchData);
message.success("查找完成");
closeModal();

View File

@@ -7,7 +7,7 @@ import {
WechatFriendRebackAllot,
} from "@/pages/pc/ckbox/weChat/api";
import { useCurrentContact } from "@/store/module/weChat/weChat";
import { deleteChatSession } from "@/store/module/ckchat/ckchat";
import { useCkChatStore } from "@/store/module/ckchat/ckchat";
import { contractService, weChatGroupService } from "@/utils/db";
const { TextArea } = Input;
const { Option } = Select;
@@ -39,6 +39,7 @@ const ToContract: React.FC<ToContractProps> = ({
const [customerServiceList, setCustomerServiceList] = useState<DepartItem[]>(
[],
);
const deleteChatSession = useCkChatStore(state => state.deleteChatSession);
// 打开弹窗
const openModal = () => {
setVisible(true);
@@ -89,12 +90,12 @@ const ToContract: React.FC<ToContractProps> = ({
message.success("转接成功");
try {
// 删除聊天会话
deleteChatSession(currentContact.id.toString());
deleteChatSession(currentContact.id);
// 删除本地数据库记录
if ("chatroomId" in currentContact) {
await weChatGroupService.delete(currentContact.id);
} else {
await contractService.delete(currentContact.id.toString());
await contractService.delete(currentContact.id);
}
} catch (deleteError) {
console.error("删除本地数据失败:", deleteError);
@@ -129,7 +130,7 @@ const ToContract: React.FC<ToContractProps> = ({
message.success("转回成功");
try {
// 删除聊天会话
deleteChatSession(currentContact.id.toString());
deleteChatSession(currentContact.id);
// 删除本地数据库记录
if ("chatroomId" in currentContact) {
await weChatGroupService.delete(currentContact.id);

View File

@@ -1,12 +1,9 @@
import React, { useState } from "react";
import { Layout, Input, Button, Tooltip, Modal } from "antd";
import { Layout, Input, Button, Modal } from "antd";
import {
ShareAltOutlined,
SendOutlined,
AudioOutlined,
FolderOutlined,
PictureOutlined,
MessageOutlined,
} from "@ant-design/icons";
import { ContractData, weChatGroup } from "@/pages/pc/ckbox/data";
import { useWebSocketStore } from "@/store/module/websocket/websocket";
@@ -176,24 +173,8 @@ const MessageEnter: React.FC<MessageEnterProps> = ({ contract }) => {
/>
</div>
<div className={styles.rightTool}>
<ToContract
className={styles.rightToolItem}
onTransfer={data => {
console.log("转接数据:", data);
// 这里可以添加实际的转接逻辑
}}
onReturn={() => {
console.log("执行一键转回操作");
// 这里可以添加实际的转回逻辑
}}
/>
<ChatRecord
className={styles.rightToolItem}
onSearch={data => {
console.log("查找数据:", data);
// 这里可以添加实际的查找逻辑
}}
/>
<ToContract className={styles.rightToolItem} />
<ChatRecord className={styles.rightToolItem} />
</div>
</div>
<div className={styles.inputArea}>

View File

@@ -60,7 +60,7 @@ export interface CkChatState {
updateCtrlUser: (user: KfUserListData) => void;
clearkfUserList: () => void;
addChatSession: (session: any) => void;
deleteChatSession: (sessionId: string) => void;
deleteChatSession: (sessionId: number) => void;
setUserInfo: (userInfo: CkUserInfo) => void;
clearUserInfo: () => void;
updateAccount: (account: Partial<CkAccount>) => void;

View File

@@ -9,7 +9,10 @@ import {
} from "@/pages/pc/ckbox/data";
import { weChatGroupService, contractService } from "@/utils/db";
import { createContractList } from "@/store/module/ckchat/api";
import { useWeChatStore } from "@/store/module/weChat/weChat";
// 从weChat store获取clearCurrentContact方法
const getClearCurrentContact = () =>
useWeChatStore.getState().clearCurrentContact;
export const useCkChatStore = createPersistStore<CkChatState>(
set => ({
userInfo: null,
@@ -389,10 +392,12 @@ export const useCkChatStore = createPersistStore<CkChatState>(
}));
},
// 删除聊天会话
deleteChatSession: (sessionId: string) => {
deleteChatSession: (sessionId: number) => {
set(state => ({
chatSessions: state.chatSessions.filter(item => item.id !== sessionId),
}));
//当前选中的客户清空
getClearCurrentContact();
},
// 设置用户信息
setUserInfo: (userInfo: CkUserInfo) => {

View File

@@ -6,7 +6,8 @@ export interface WeChatState {
// 当前聊天用户的消息列表(只存储当前聊天用户的消息)
currentMessages: ChatRecord[];
// 清空当前联系人
clearCurrentContact: () => void;
// 消息加载状态
messagesLoading: boolean;
isLoadingData: boolean;

View File

@@ -24,7 +24,10 @@ export const useWeChatStore = create<WeChatState>()(
messagesLoading: false,
isLoadingData: false,
currentGroupMembers: [],
//清空当前联系人
clearCurrentContact: () => {
set({ currentContract: null, currentMessages: [] });
},
// Actions
setCurrentContact: (
contract: ContractData | weChatGroup,