新增待辦事項相關API接口及聊天窗口功能:在API中添加待辦事項列表、添加和處理功能,並在聊天窗口中整合好友ID以支持待辦事項管理,提升用戶互動體驗。
This commit is contained in:
@@ -352,3 +352,34 @@ export const addFollowUp = (params: {
|
||||
export const processFollowUp = (params: { ids?: string }) => {
|
||||
return request("/v1/kefu/followUp/process", params, "GET");
|
||||
};
|
||||
|
||||
// ============== 待办事项相关接口 ==============
|
||||
|
||||
// 待办事项列表
|
||||
export const getTodoList = (params: {
|
||||
isProcess?: string;
|
||||
isRemind?: string;
|
||||
keyword?: string;
|
||||
level?: string;
|
||||
limit?: string;
|
||||
page?: string;
|
||||
friendId?: string;
|
||||
}) => {
|
||||
return request("/v1/kefu/todo/list", params, "GET");
|
||||
};
|
||||
|
||||
// 待办事项添加
|
||||
export const addTodo = (params: {
|
||||
description?: string;
|
||||
friendId: string;
|
||||
level?: string; // 0低优先级 1中优先级 2高优先级 3紧急
|
||||
reminderTime?: string;
|
||||
title?: string;
|
||||
}) => {
|
||||
return request("/v1/kefu/todo/add", params, "POST");
|
||||
};
|
||||
|
||||
// 待办事项处理
|
||||
export const processTodo = (params: { ids: string }) => {
|
||||
return request("/v1/kefu/todo/process", params, "GET");
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import {
|
||||
Modal,
|
||||
Form,
|
||||
@@ -11,107 +11,165 @@ import {
|
||||
Tag,
|
||||
Space,
|
||||
Typography,
|
||||
message,
|
||||
} from "antd";
|
||||
import { PlusOutlined, CalendarOutlined } from "@ant-design/icons";
|
||||
import { getTodoList, addTodo, processTodo } from "@/pages/pc/ckbox/weChat/api";
|
||||
import styles from "./index.module.scss";
|
||||
|
||||
const { Option } = Select;
|
||||
const { TextArea } = Input;
|
||||
const { Text } = Typography;
|
||||
|
||||
// 优先级映射
|
||||
const priorityMap: { [key: string]: string } = {
|
||||
"0": "低",
|
||||
"1": "中",
|
||||
"2": "高",
|
||||
"3": "紧急",
|
||||
};
|
||||
|
||||
interface TodoItem {
|
||||
id: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
client?: string;
|
||||
priority: "高" | "中" | "低";
|
||||
priority: "高" | "中" | "低" | "紧急";
|
||||
dueDate: string;
|
||||
completed: boolean;
|
||||
friendId?: string;
|
||||
}
|
||||
|
||||
interface TodoListModalProps {
|
||||
visible: boolean;
|
||||
onClose: () => void;
|
||||
clientName?: string;
|
||||
friendId?: string;
|
||||
}
|
||||
|
||||
const TodoListModal: React.FC<TodoListModalProps> = ({
|
||||
visible,
|
||||
onClose,
|
||||
clientName = "客户",
|
||||
friendId,
|
||||
}) => {
|
||||
const [form] = Form.useForm();
|
||||
const [todos, setTodos] = useState<TodoItem[]>([
|
||||
{
|
||||
id: "1",
|
||||
title: "整理客户需求文档",
|
||||
description: "汇总本周客户反馈的功能需求",
|
||||
client: "李先生",
|
||||
priority: "高",
|
||||
dueDate: "03/08 18:00",
|
||||
completed: false,
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
title: "准备产品演示PPT",
|
||||
description: "针对大客户的定制化演示材料",
|
||||
client: "张总",
|
||||
priority: "中",
|
||||
dueDate: "03/09 16:00",
|
||||
completed: false,
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
title: "准备产品演示PPT",
|
||||
description: "针对大客户的定制化演示材料",
|
||||
client: "张总",
|
||||
priority: "中",
|
||||
dueDate: "03/09 16:00",
|
||||
completed: false,
|
||||
},
|
||||
]);
|
||||
const [todos, setTodos] = useState<TodoItem[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [addLoading, setAddLoading] = useState(false);
|
||||
|
||||
// 优先级选项
|
||||
const priorityOptions = [
|
||||
{ value: "高", label: "高优先级", color: "orange" },
|
||||
{ value: "中", label: "中优先级", color: "blue" },
|
||||
{ value: "低", label: "低优先级", color: "green" },
|
||||
{ value: "2", label: "高优先级", color: "orange" },
|
||||
{ value: "1", label: "中优先级", color: "blue" },
|
||||
{ value: "0", label: "低优先级", color: "green" },
|
||||
{ value: "3", label: "紧急", color: "red" },
|
||||
];
|
||||
|
||||
// 加载待办事项列表
|
||||
const loadTodoList = useCallback(async () => {
|
||||
if (!friendId) return;
|
||||
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await getTodoList({
|
||||
friendId,
|
||||
limit: "50",
|
||||
page: "1",
|
||||
});
|
||||
|
||||
if (response && response.list) {
|
||||
const formattedTodos = response.list.map((item: any) => ({
|
||||
id: item.id?.toString() || "",
|
||||
title: item.title || "",
|
||||
description: item.description || "",
|
||||
client: clientName,
|
||||
priority: priorityMap[item.level] || "中",
|
||||
dueDate: item.reminderTime || "",
|
||||
completed: item.isProcess === 1,
|
||||
friendId: item.friendId,
|
||||
}));
|
||||
setTodos(formattedTodos);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("加载待办事项列表失败:", error);
|
||||
message.error("加载待办事项列表失败");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [friendId, clientName]);
|
||||
|
||||
// 当模态框打开时加载数据
|
||||
useEffect(() => {
|
||||
if (visible && friendId) {
|
||||
loadTodoList();
|
||||
}
|
||||
}, [visible, friendId, loadTodoList]);
|
||||
|
||||
// 处理添加任务
|
||||
const handleAddTask = async () => {
|
||||
if (!friendId) {
|
||||
message.error("缺少好友ID,无法添加任务");
|
||||
return;
|
||||
}
|
||||
|
||||
setAddLoading(true);
|
||||
try {
|
||||
const values = await form.validateFields();
|
||||
const newTodo: TodoItem = {
|
||||
id: Date.now().toString(),
|
||||
|
||||
const params = {
|
||||
friendId,
|
||||
title: values.title,
|
||||
description: values.description,
|
||||
client: clientName,
|
||||
priority: values.priority,
|
||||
dueDate: values.dueDate.format("MM/DD HH:mm"),
|
||||
completed: false,
|
||||
level: values.priority,
|
||||
reminderTime: values.dueDate.format("YYYY-MM-DD HH:mm:ss"),
|
||||
};
|
||||
|
||||
setTodos([...todos, newTodo]);
|
||||
form.resetFields();
|
||||
const response = await addTodo(params);
|
||||
|
||||
if (response) {
|
||||
message.success("添加待办事项成功");
|
||||
form.resetFields();
|
||||
// 重新加载列表
|
||||
loadTodoList();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("表单验证失败:", error);
|
||||
console.error("添加待办事项失败:", error);
|
||||
message.error("添加待办事项失败");
|
||||
} finally {
|
||||
setAddLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 处理任务完成状态切换
|
||||
const handleToggleComplete = (id: string) => {
|
||||
setTodos(
|
||||
todos.map(todo =>
|
||||
todo.id === id ? { ...todo, completed: !todo.completed } : todo,
|
||||
),
|
||||
);
|
||||
const handleToggleComplete = async (id: string) => {
|
||||
try {
|
||||
const response = await processTodo({ ids: id });
|
||||
if (response) {
|
||||
message.success("任务状态更新成功");
|
||||
// 重新加载列表
|
||||
loadTodoList();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("更新任务状态失败:", error);
|
||||
message.error("更新任务状态失败");
|
||||
}
|
||||
};
|
||||
|
||||
// 获取优先级标签颜色
|
||||
const getPriorityColor = (priority: string) => {
|
||||
const option = priorityOptions.find(opt => opt.value === priority);
|
||||
return option?.color || "default";
|
||||
switch (priority) {
|
||||
case "高":
|
||||
return "orange";
|
||||
case "中":
|
||||
return "blue";
|
||||
case "低":
|
||||
return "green";
|
||||
case "紧急":
|
||||
return "red";
|
||||
default:
|
||||
return "default";
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -184,6 +242,7 @@ const TodoListModal: React.FC<TodoListModalProps> = ({
|
||||
icon={<PlusOutlined />}
|
||||
onClick={handleAddTask}
|
||||
className={styles.addButton}
|
||||
loading={addLoading}
|
||||
block
|
||||
>
|
||||
添加任务
|
||||
@@ -195,6 +254,7 @@ const TodoListModal: React.FC<TodoListModalProps> = ({
|
||||
<div className={styles.todoList}>
|
||||
<List
|
||||
dataSource={todos}
|
||||
loading={loading}
|
||||
renderItem={todo => (
|
||||
<List.Item className={styles.todoItem}>
|
||||
<div className={styles.todoContent}>
|
||||
|
||||
@@ -169,6 +169,7 @@ const ChatWindow: React.FC<ChatWindowProps> = ({ contract }) => {
|
||||
visible={todoModalVisible}
|
||||
onClose={handleTodoModalClose}
|
||||
clientName={contract.nickname || contract.name}
|
||||
friendId={contract.id?.toString()}
|
||||
/>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user