From 728b3e45f4e88fae9255899a74dd6389d97a7b9f Mon Sep 17 00:00:00 2001 From: keep <1603421097@qq.com> Date: Thu, 16 Apr 2026 18:43:13 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E4=BC=98=E5=85=88=E7=BA=A7=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在前后端添加优先级字段(高/中/低) - 更新任务表单和列表显示优先级 - 添加优先级筛选和排序功能 --- .../task_app/migrations/0004_task_priority.py | 22 +++++++ todo_app_backend/task_app/models.py | 6 ++ todo_app_frontend/src/App.tsx | 60 +++++++++++++++---- todo_app_frontend/src/components/TaskForm.tsx | 21 ++++++- todo_app_frontend/src/components/TaskItem.tsx | 37 +++++++++++- todo_app_frontend/src/types/Task.ts | 3 + 6 files changed, 133 insertions(+), 16 deletions(-) create mode 100644 todo_app_backend/task_app/migrations/0004_task_priority.py diff --git a/todo_app_backend/task_app/migrations/0004_task_priority.py b/todo_app_backend/task_app/migrations/0004_task_priority.py new file mode 100644 index 0000000..0619479 --- /dev/null +++ b/todo_app_backend/task_app/migrations/0004_task_priority.py @@ -0,0 +1,22 @@ +# Generated by Django 5.2.8 on 2026-04-16 10:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("task_app", "0003_alter_task_status"), + ] + + operations = [ + migrations.AddField( + model_name="task", + name="priority", + field=models.CharField( + choices=[("High", "High"), ("Medium", "Medium"), ("Low", "Low")], + default="Medium", + max_length=20, + ), + ), + ] diff --git a/todo_app_backend/task_app/models.py b/todo_app_backend/task_app/models.py index dff2f03..a7cc483 100644 --- a/todo_app_backend/task_app/models.py +++ b/todo_app_backend/task_app/models.py @@ -6,8 +6,14 @@ class Task(models.Model): ('In-Progress','In-progress'), ('Completed','Completed') ) + PRIORITY = ( + ('High','High'), + ('Medium','Medium'), + ('Low','Low') + ) task_name = models.CharField(max_length=100) description = models.TextField() status = models.CharField(max_length=20, choices=STATUS, default='In-Progress') + priority = models.CharField(max_length=20, choices=PRIORITY, default='Medium') created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) \ No newline at end of file diff --git a/todo_app_frontend/src/App.tsx b/todo_app_frontend/src/App.tsx index c38f864..5b32d89 100644 --- a/todo_app_frontend/src/App.tsx +++ b/todo_app_frontend/src/App.tsx @@ -7,16 +7,19 @@ function App() { const [error, setError] = useState(null); const [searchTerm, setSearchTerm] = useState(''); const [filterStatus, setFilterStatus] = useState('All'); + const [filterPriority, setFilterPriority] = useState('All'); + const [sortBy, setSortBy] = useState('None'); const [showAddForm, setShowAddForm] = useState(false); const [editingTask, setEditingTask] = useState(null); const [newTask, setNewTask] = useState({ task_name: '', - description: '' + description: '', + priority: 'Medium' }); // API Base URL - Update this to your Django backend URL - // const API_BASE_URL = 'http://localhost:8000/api'; // Change this to your backend URL - const API_BASE_URL = 'https://todo-app-fullstack-nrfk.onrender.com/api'; + const API_BASE_URL = 'http://localhost:8000/api'; // Change this to your backend URL + // const API_BASE_URL = 'https://todo-app-fullstack-nrfk.onrender.com/api'; // Fetch tasks from API const fetchTasks = async () => { @@ -122,10 +125,11 @@ function App() { } }; - const getPriorityColor = (status) => { - switch(status) { - case 'In-Progress': return 'bg-orange-100 text-orange-800 border-orange-200'; - case 'Completed': return 'bg-green-100 text-green-800 border-green-200'; + const getPriorityColor = (priority) => { + switch(priority) { + case 'High': return 'bg-red-100 text-red-800 border-red-200'; + case 'Medium': return 'bg-yellow-100 text-yellow-800 border-yellow-200'; + case 'Low': return 'bg-green-100 text-green-800 border-green-200'; default: return 'bg-gray-100 text-gray-800 border-gray-200'; } }; @@ -142,7 +146,16 @@ function App() { const matchesSearch = task.task_name.toLowerCase().includes(searchTerm.toLowerCase()) || task.description.toLowerCase().includes(searchTerm.toLowerCase()); const matchesStatus = filterStatus === 'All' || task.status === filterStatus; - return matchesSearch && matchesStatus; + const matchesPriority = filterPriority === 'All' || task.priority === filterPriority; + return matchesSearch && matchesStatus && matchesPriority; + }); + + const sortedTasks = [...filteredTasks].sort((a, b) => { + if (sortBy === 'Priority') { + const priorityOrder = { 'High': 0, 'Medium': 1, 'Low': 2 }; + return priorityOrder[a.priority] - priorityOrder[b.priority]; + } + return 0; }); const taskStats = { @@ -276,6 +289,24 @@ function App() { + + @@ -302,7 +333,7 @@ function App() { ) : (