From 837c8227fb6389b3f0fcbbb04ef79d35348b6e9c Mon Sep 17 00:00:00 2001 From: DengDai <29502593+zzhhxx@users.noreply.github.com> Date: Tue, 9 Dec 2025 21:32:32 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BB=BB=E5=8A=A1=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E5=88=9B=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/tasks.py | 62 ++++++++++++ templates/task_create.html | 202 +++++++++++++++++++++++++++---------- 2 files changed, 212 insertions(+), 52 deletions(-) diff --git a/api/tasks.py b/api/tasks.py index 6335afb..3d1e1be 100644 --- a/api/tasks.py +++ b/api/tasks.py @@ -101,6 +101,68 @@ def create_task(group_id): return jsonify({'message': '任务创建成功', 'task_id': task.id}), 201 +# 批量创建任务(管理员) +@tasks_bp.route('/groups//tasks/batch', methods=['POST']) +@admin_required +def batch_create_tasks(group_id): + data = request.json + tasks_data = data.get('tasks', []) + + if not tasks_data: + return jsonify({'error': '任务列表不能为空'}), 400 + + user_id = get_jwt_identity() + created_tasks = [] + errors = [] + + for idx, task_data in enumerate(tasks_data): + try: + if not task_data.get('series_name'): + errors.append(f'第{idx+1}行:剧集名称不能为空') + continue + + if not task_data.get('series_date'): + errors.append(f'第{idx+1}行:日期不能为空') + continue + + try: + series_date = datetime.strptime(task_data['series_date'], '%Y%m%d').date() + except: + errors.append(f'第{idx+1}行:日期格式错误') + continue + + task = Task( + group_id=group_id, + series_name=task_data['series_name'], + series_date=series_date, + priority=task_data.get('priority', '中'), + created_by=user_id + ) + + db.session.add(task) + db.session.flush() + + log = TaskLog( + task_id=task.id, + user_id=user_id, + action='create', + comment=f'批量创建任务:{task.series_name}' + ) + db.session.add(log) + created_tasks.append(task.id) + + except Exception as e: + errors.append(f'第{idx+1}行:{str(e)}') + + db.session.commit() + + return jsonify({ + 'message': f'成功创建{len(created_tasks)}个任务', + 'created': len(created_tasks), + 'errors': errors + }), 201 + + # 认领任务 @tasks_bp.route('/tasks//claim', methods=['POST']) @login_required diff --git a/templates/task_create.html b/templates/task_create.html index 75e26b9..8b0142e 100644 --- a/templates/task_create.html +++ b/templates/task_create.html @@ -8,38 +8,59 @@
-
+

创建新任务

+
+ + + + +
-
- - + +
+
+ + +
+ +
+ + + 资源来源链接 +
+ +
+ + +
+ +
+ + +
- -
- - - 资源来源链接 + + + - -
- - -
- -
- - -
- +
取消 @@ -57,35 +78,112 @@ $(document).ready(function() { // 设置默认日期为今天 $('#series-date').val(new Date().toISOString().split('T')[0]); - + + // 模式切换 + $('input[name="mode"]').change(function() { + if ($(this).val() === 'single') { + $('#single-mode').show(); + $('#batch-mode').hide(); + } else { + $('#single-mode').hide(); + $('#batch-mode').show(); + } + }); + $('#create-task-form').submit(function(e) { e.preventDefault(); - - const data = { - series_name: $('#series-name').val(), - series_link: $('#series-link').val() || null, - series_date: $('#series-date').val(), - priority: $('#priority').val() - }; - - $.ajax({ - url: '/api/groups/1/tasks', - method: 'POST', - headers: { - 'Authorization': 'Bearer ' + localStorage.getItem('access_token'), - 'Content-Type': 'application/json' - }, - data: JSON.stringify(data), - success: function(response) { - alert('任务创建成功!'); - window.location.href = '/tasks'; - }, - error: function(xhr) { - const error = xhr.responseJSON?.error || '创建失败'; - alert(error); - } - }); + + const mode = $('input[name="mode"]:checked').val(); + + if (mode === 'single') { + createSingleTask(); + } else { + createBatchTasks(); + } }); }); + +function createSingleTask() { + const data = { + series_name: $('#series-name').val(), + series_link: $('#series-link').val() || null, + series_date: $('#series-date').val(), + priority: $('#priority').val() + }; + + $.ajax({ + url: '/api/groups/1/tasks', + method: 'POST', + headers: { + 'Authorization': 'Bearer ' + localStorage.getItem('access_token'), + 'Content-Type': 'application/json' + }, + data: JSON.stringify(data), + success: function(response) { + alert('任务创建成功!'); + window.location.href = '/tasks'; + }, + error: function(xhr) { + const error = xhr.responseJSON?.error || '创建失败'; + alert(error); + } + }); +} + +function createBatchTasks() { + const input = $('#batch-input').val().trim(); + + if (!input) { + alert('请输入任务数据'); + return; + } + + const lines = input.split('\n'); + const tasks = []; + + for (let i = 0; i < lines.length; i++) { + const line = lines[i].trim(); + if (!line) continue; + + const parts = line.split(','); + if (parts.length !== 3) { + alert(`第${i+1}行格式错误,应为:剧集名称,日期,优先级`); + return; + } + + tasks.push({ + series_name: parts[0].trim(), + series_date: parts[1].trim(), + priority: parts[2].trim() + }); + } + + if (tasks.length === 0) { + alert('没有有效的任务数据'); + return; + } + + $.ajax({ + url: '/api/groups/1/tasks/batch', + method: 'POST', + headers: { + 'Authorization': 'Bearer ' + localStorage.getItem('access_token'), + 'Content-Type': 'application/json' + }, + data: JSON.stringify({ tasks: tasks }), + success: function(response) { + let message = response.message; + if (response.errors && response.errors.length > 0) { + message += '\n\n错误信息:\n' + response.errors.join('\n'); + } + alert(message); + window.location.href = '/tasks'; + }, + error: function(xhr) { + const error = xhr.responseJSON?.error || '批量创建失败'; + alert(error); + } + }); +} {% endblock %} \ No newline at end of file