Support keword

This commit is contained in:
2025-09-24 03:38:32 +08:00
parent a4891b1c30
commit 8592833d74
16 changed files with 2888 additions and 2 deletions

View File

@@ -0,0 +1,139 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_modify %}
{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:core_crawltask_changelist' %}">爬取任务</a>
&rsaquo; {{ title }}
</div>
{% endblock %}
{% block content %}
<h1>{{ title }}</h1>
<div class="help" style="background: #fff3cd; border: 1px solid #ffeaa7; padding: 15px; margin-bottom: 20px; border-radius: 5px;">
<strong>注意:</strong>全站爬取会爬取整个网站的所有文章,可能需要很长时间。建议在非高峰时段进行。
</div>
<form method="post" id="full-site-task-form">
{% csrf_token %}
<fieldset class="module aligned">
<h2>基本信息</h2>
<div class="form-row">
<div>
<label for="id_name" class="required">任务名称:</label>
<input type="text" name="name" id="id_name" required maxlength="200" style="width: 300px;">
<p class="help">为这个全站爬取任务起一个容易识别的名称</p>
</div>
</div>
</fieldset>
<fieldset class="module aligned">
<h2>目标网站</h2>
<div class="form-row">
<div>
<label>选择要爬取的网站:</label>
<div style="max-height: 200px; overflow-y: auto; border: 1px solid #ddd; padding: 10px; margin-top: 5px;">
<label style="display: block; margin: 5px 0;">
<input type="checkbox" id="select_all" onchange="toggleAllWebsites()">
<strong>全选/取消全选</strong>
</label>
<hr style="margin: 10px 0;">
{% for website in websites %}
<label style="display: block; margin: 3px 0;">
<input type="checkbox" name="websites" value="{{ website.name }}" class="website-checkbox">
{{ website.name }}
</label>
{% endfor %}
</div>
<p class="help">不选择任何网站将爬取所有支持的网站</p>
</div>
</div>
</fieldset>
<fieldset class="module aligned">
<h2>爬取设置</h2>
<div class="form-row">
<div>
<label for="id_max_pages">最大爬取页数:</label>
<input type="number" name="max_pages" id="id_max_pages" value="500" min="1" max="5000" style="width: 100px;">
<p class="help">每个网站最多爬取的页数 (1-5000)</p>
</div>
</div>
</fieldset>
<div class="submit-row">
<input type="submit" value="创建任务" class="default" name="_save">
<a href="{% url 'admin:core_crawltask_changelist' %}" class="button cancel-link">取消</a>
</div>
</form>
<script>
function toggleAllWebsites() {
const selectAll = document.getElementById('select_all');
const checkboxes = document.querySelectorAll('.website-checkbox');
checkboxes.forEach(checkbox => {
checkbox.checked = selectAll.checked;
});
}
</script>
<style>
.form-row {
margin-bottom: 15px;
}
.form-row label {
display: block;
font-weight: bold;
margin-bottom: 5px;
}
.form-row input[type="text"],
.form-row input[type="number"] {
padding: 5px;
border: 1px solid #ddd;
border-radius: 3px;
}
.form-row .help {
color: #666;
font-size: 12px;
margin-top: 3px;
}
.submit-row {
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid #ddd;
}
.submit-row input[type="submit"] {
background: #417690;
color: white;
padding: 10px 20px;
border: none;
border-radius: 3px;
cursor: pointer;
}
.submit-row .cancel-link {
margin-left: 10px;
padding: 10px 20px;
background: #f8f8f8;
color: #333;
text-decoration: none;
border-radius: 3px;
border: 1px solid #ddd;
}
.submit-row .cancel-link:hover {
background: #e8e8e8;
}
</style>
{% endblock %}

View File

@@ -0,0 +1,164 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_modify %}
{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:core_crawltask_changelist' %}">爬取任务</a>
&rsaquo; {{ title }}
</div>
{% endblock %}
{% block content %}
<h1>{{ title }}</h1>
<form method="post" id="historical-task-form">
{% csrf_token %}
<fieldset class="module aligned">
<h2>基本信息</h2>
<div class="form-row">
<div>
<label for="id_name" class="required">任务名称:</label>
<input type="text" name="name" id="id_name" required maxlength="200" style="width: 300px;">
<p class="help">为这个历史文章爬取任务起一个容易识别的名称</p>
</div>
</div>
</fieldset>
<fieldset class="module aligned">
<h2>目标网站</h2>
<div class="form-row">
<div>
<label>选择要爬取的网站:</label>
<div style="max-height: 200px; overflow-y: auto; border: 1px solid #ddd; padding: 10px; margin-top: 5px;">
<label style="display: block; margin: 5px 0;">
<input type="checkbox" id="select_all" onchange="toggleAllWebsites()">
<strong>全选/取消全选</strong>
</label>
<hr style="margin: 10px 0;">
{% for website in websites %}
<label style="display: block; margin: 3px 0;">
<input type="checkbox" name="websites" value="{{ website.name }}" class="website-checkbox">
{{ website.name }}
</label>
{% endfor %}
</div>
<p class="help">不选择任何网站将爬取所有支持的网站</p>
</div>
</div>
</fieldset>
<fieldset class="module aligned">
<h2>时间范围</h2>
<div class="form-row">
<div>
<label for="id_start_date" class="required">开始日期:</label>
<input type="date" name="start_date" id="id_start_date" required>
<p class="help">历史文章的开始日期</p>
</div>
</div>
<div class="form-row">
<div>
<label for="id_end_date" class="required">结束日期:</label>
<input type="date" name="end_date" id="id_end_date" required>
<p class="help">历史文章的结束日期</p>
</div>
</div>
</fieldset>
<fieldset class="module aligned">
<h2>爬取设置</h2>
<div class="form-row">
<div>
<label for="id_max_articles">每个网站最大文章数:</label>
<input type="number" name="max_articles" id="id_max_articles" value="50" min="1" max="500" style="width: 100px;">
<p class="help">每个网站最多爬取的文章数量 (1-500)</p>
</div>
</div>
</fieldset>
<div class="submit-row">
<input type="submit" value="创建任务" class="default" name="_save">
<a href="{% url 'admin:core_crawltask_changelist' %}" class="button cancel-link">取消</a>
</div>
</form>
<script>
function toggleAllWebsites() {
const selectAll = document.getElementById('select_all');
const checkboxes = document.querySelectorAll('.website-checkbox');
checkboxes.forEach(checkbox => {
checkbox.checked = selectAll.checked;
});
}
// 设置默认日期
document.addEventListener('DOMContentLoaded', function() {
const today = new Date();
const oneMonthAgo = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate());
document.getElementById('id_end_date').value = today.toISOString().split('T')[0];
document.getElementById('id_start_date').value = oneMonthAgo.toISOString().split('T')[0];
});
</script>
<style>
.form-row {
margin-bottom: 15px;
}
.form-row label {
display: block;
font-weight: bold;
margin-bottom: 5px;
}
.form-row input[type="text"],
.form-row input[type="number"],
.form-row input[type="date"] {
padding: 5px;
border: 1px solid #ddd;
border-radius: 3px;
}
.form-row .help {
color: #666;
font-size: 12px;
margin-top: 3px;
}
.submit-row {
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid #ddd;
}
.submit-row input[type="submit"] {
background: #417690;
color: white;
padding: 10px 20px;
border: none;
border-radius: 3px;
cursor: pointer;
}
.submit-row .cancel-link {
margin-left: 10px;
padding: 10px 20px;
background: #f8f8f8;
color: #333;
text-decoration: none;
border-radius: 3px;
border: 1px solid #ddd;
}
.submit-row .cancel-link:hover {
background: #e8e8e8;
}
</style>
{% endblock %}

View File

@@ -0,0 +1,180 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_modify %}
{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:core_crawltask_changelist' %}">爬取任务</a>
&rsaquo; {{ title }}
</div>
{% endblock %}
{% block content %}
<h1>{{ title }}</h1>
<form method="post" id="keyword-task-form">
{% csrf_token %}
<fieldset class="module aligned">
<h2>基本信息</h2>
<div class="form-row">
<div>
<label for="id_name" class="required">任务名称:</label>
<input type="text" name="name" id="id_name" required maxlength="200" style="width: 300px;">
<p class="help">为这个爬取任务起一个容易识别的名称</p>
</div>
</div>
<div class="form-row">
<div>
<label for="id_keyword" class="required">搜索关键词:</label>
<input type="text" name="keyword" id="id_keyword" required maxlength="200" style="width: 300px;">
<p class="help">输入要搜索的关键词,例如:人工智能、两会、政策等</p>
</div>
</div>
</fieldset>
<fieldset class="module aligned">
<h2>目标网站</h2>
<div class="form-row">
<div>
<label>选择要爬取的网站:</label>
<div style="max-height: 200px; overflow-y: auto; border: 1px solid #ddd; padding: 10px; margin-top: 5px;">
<label style="display: block; margin: 5px 0;">
<input type="checkbox" id="select_all" onchange="toggleAllWebsites()">
<strong>全选/取消全选</strong>
</label>
<hr style="margin: 10px 0;">
{% for website in websites %}
<label style="display: block; margin: 3px 0;">
<input type="checkbox" name="websites" value="{{ website.name }}" class="website-checkbox">
{{ website.name }}
</label>
{% endfor %}
</div>
<p class="help">不选择任何网站将爬取所有支持的网站</p>
</div>
</div>
</fieldset>
<fieldset class="module aligned">
<h2>时间范围 (可选)</h2>
<div class="form-row">
<div>
<label for="id_start_date">开始日期:</label>
<input type="date" name="start_date" id="id_start_date">
<p class="help">留空则搜索所有时间</p>
</div>
</div>
<div class="form-row">
<div>
<label for="id_end_date">结束日期:</label>
<input type="date" name="end_date" id="id_end_date">
<p class="help">留空则搜索到当前时间</p>
</div>
</div>
</fieldset>
<fieldset class="module aligned">
<h2>爬取设置</h2>
<div class="form-row">
<div>
<label for="id_max_pages">最大搜索页数:</label>
<input type="number" name="max_pages" id="id_max_pages" value="10" min="1" max="100" style="width: 100px;">
<p class="help">每个网站最多搜索的页数 (1-100)</p>
</div>
</div>
<div class="form-row">
<div>
<label for="id_max_articles">最大文章数量:</label>
<input type="number" name="max_articles" id="id_max_articles" value="100" min="1" max="1000" style="width: 100px;">
<p class="help">总共最多爬取的文章数量 (1-1000)</p>
</div>
</div>
</fieldset>
<div class="submit-row">
<input type="submit" value="创建任务" class="default" name="_save">
<a href="{% url 'admin:core_crawltask_changelist' %}" class="button cancel-link">取消</a>
</div>
</form>
<script>
function toggleAllWebsites() {
const selectAll = document.getElementById('select_all');
const checkboxes = document.querySelectorAll('.website-checkbox');
checkboxes.forEach(checkbox => {
checkbox.checked = selectAll.checked;
});
}
// 设置默认日期
document.addEventListener('DOMContentLoaded', function() {
const today = new Date();
const oneMonthAgo = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate());
document.getElementById('id_end_date').value = today.toISOString().split('T')[0];
document.getElementById('id_start_date').value = oneMonthAgo.toISOString().split('T')[0];
});
</script>
<style>
.form-row {
margin-bottom: 15px;
}
.form-row label {
display: block;
font-weight: bold;
margin-bottom: 5px;
}
.form-row input[type="text"],
.form-row input[type="number"],
.form-row input[type="date"] {
padding: 5px;
border: 1px solid #ddd;
border-radius: 3px;
}
.form-row .help {
color: #666;
font-size: 12px;
margin-top: 3px;
}
.submit-row {
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid #ddd;
}
.submit-row input[type="submit"] {
background: #417690;
color: white;
padding: 10px 20px;
border: none;
border-radius: 3px;
cursor: pointer;
}
.submit-row .cancel-link {
margin-left: 10px;
padding: 10px 20px;
background: #f8f8f8;
color: #333;
text-decoration: none;
border-radius: 3px;
border: 1px solid #ddd;
}
.submit-row .cancel-link:hover {
background: #e8e8e8;
}
</style>
{% endblock %}

View File

@@ -0,0 +1,172 @@
{% extends "admin/base_site.html" %}
{% load i18n static %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/dashboard.css" %}">{% endblock %}
{% block coltype %}colMS{% endblock %}
{% block bodyclass %}{{ block.super }} dashboard{% endblock %}
{% block breadcrumbs %}{% endblock %}
{% block nav-sidebar %}{% endblock %}
{% block content %}
<div id="content-main">
{% if app_list %}
{% for app in app_list %}
<div class="app-{{ app.app_label }} module">
<table>
<caption>
<a href="{{ app.app_url }}" class="section" title="{% blocktranslate with name=app.name %}Models in the {{ name }} application{% endblocktranslate %}">{{ app.name }}</a>
</caption>
{% for model in app.models %}
<tr class="model-{{ model.object_name|lower }}">
{% if model.admin_url %}
<th scope="row"><a href="{{ model.admin_url }}"{% if model.add_url %} class="addlink"{% endif %}>{{ model.name }}</a></th>
{% else %}
<th scope="row">{{ model.name }}</th>
{% endif %}
{% if model.add_url %}
<td><a href="{{ model.add_url }}" class="addlink">{% translate 'Add' %}</a></td>
{% else %}
<td>&nbsp;</td>
{% endif %}
{% if model.admin_url %}
{% if model.view_only %}
<td><a href="{{ model.admin_url }}" class="viewlink">{% translate 'View' %}</a></td>
{% else %}
<td><a href="{{ model.admin_url }}" class="changelink">{% translate 'Change' %}</a></td>
{% endif %}
{% else %}
<td>&nbsp;</td>
{% endif %}
</tr>
{% endfor %}
</table>
</div>
{% endfor %}
{% else %}
<p>{% translate "You don't have permission to view or edit anything." %}</p>
{% endif %}
<!-- 自定义快速操作区域 -->
<div class="module" style="margin-top: 20px;">
<h2>快速创建爬取任务</h2>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 15px; margin-top: 15px;">
<div style="border: 1px solid #ddd; padding: 15px; border-radius: 5px; text-align: center;">
<h3 style="margin-top: 0; color: #417690;">关键词搜索</h3>
<p style="color: #666; font-size: 14px;">根据关键词搜索并爬取相关文章</p>
<a href="{% url 'admin:create_keyword_task' %}" class="button" style="background: #417690; color: white; padding: 8px 16px; text-decoration: none; border-radius: 3px; display: inline-block;">
创建任务
</a>
</div>
<div style="border: 1px solid #ddd; padding: 15px; border-radius: 5px; text-align: center;">
<h3 style="margin-top: 0; color: #28a745;">历史文章</h3>
<p style="color: #666; font-size: 14px;">爬取指定日期范围的历史文章</p>
<a href="{% url 'admin:create_historical_task' %}" class="button" style="background: #28a745; color: white; padding: 8px 16px; text-decoration: none; border-radius: 3px; display: inline-block;">
创建任务
</a>
</div>
<div style="border: 1px solid #ddd; padding: 15px; border-radius: 5px; text-align: center;">
<h3 style="margin-top: 0; color: #dc3545;">全站爬取</h3>
<p style="color: #666; font-size: 14px;">爬取整个网站的所有文章</p>
<a href="{% url 'admin:create_full_site_task' %}" class="button" style="background: #dc3545; color: white; padding: 8px 16px; text-decoration: none; border-radius: 3px; display: inline-block;">
创建任务
</a>
</div>
</div>
</div>
<!-- 最近任务状态 -->
<div class="module" style="margin-top: 20px;">
<h2>最近任务状态</h2>
<div style="margin-top: 15px;">
{% load core_extras %}
{% get_recent_tasks as recent_tasks %}
{% if recent_tasks %}
<table style="width: 100%;">
<thead>
<tr style="background: #f8f9fa;">
<th style="padding: 8px; text-align: left;">任务名称</th>
<th style="padding: 8px; text-align: left;">类型</th>
<th style="padding: 8px; text-align: left;">状态</th>
<th style="padding: 8px; text-align: left;">进度</th>
<th style="padding: 8px; text-align: left;">创建时间</th>
<th style="padding: 8px; text-align: left;">操作</th>
</tr>
</thead>
<tbody>
{% for task in recent_tasks %}
<tr>
<td style="padding: 8px;">{{ task.name }}</td>
<td style="padding: 8px;">{{ task.get_task_type_display }}</td>
<td style="padding: 8px;">
<span style="color: {% if task.status == 'completed' %}green{% elif task.status == 'failed' %}red{% elif task.status == 'running' %}blue{% else %}gray{% endif %};">
{{ task.get_status_display }}
</span>
</td>
<td style="padding: 8px;">
{% if task.status == 'running' %}
<div style="width: 100px; background-color: #f0f0f0; border-radius: 3px; overflow: hidden;">
<div style="width: {{ task.progress }}%; background-color: #4CAF50; height: 16px; text-align: center; line-height: 16px; color: white; font-size: 12px;">
{{ task.progress }}%
</div>
</div>
{% else %}
-
{% endif %}
</td>
<td style="padding: 8px;">{{ task.created_at|date:"m-d H:i" }}</td>
<td style="padding: 8px;">
<a href="{% url 'admin:core_crawltask_change' task.id %}" style="color: #417690; text-decoration: none;">查看</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p style="color: #666; text-align: center; padding: 20px;">暂无任务</p>
{% endif %}
</div>
</div>
</div>
{% endblock %}
{% block sidebar %}
<div id="content-related">
<div class="module" id="recent-actions-module">
<h2>{% translate 'Recent actions' %}</h2>
<h3>{% translate 'My actions' %}</h3>
{% load log %}
{% get_admin_log 10 as admin_log for_user user %}
{% if not admin_log %}
<p>{% translate 'None available' %}</p>
{% else %}
<ul class="actionlist">
{% for entry in admin_log %}
<li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">
{% if entry.is_deletion or not entry.get_admin_url %}
{{ entry.object_repr }}
{% else %}
<a href="{{ entry.get_admin_url }}">{{ entry.object_repr }}</a>
{% endif %}
<br>
{% if entry.content_type %}
<span class="mini quiet">{% filter capfirst %}{{ entry.content_type.name }}{% endfilter %}</span>
{% else %}
<span class="mini quiet">{% translate 'Unknown content' %}</span>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,184 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_modify %}
{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:core_crawltask_changelist' %}">爬取任务</a>
&rsaquo; {{ title }}
</div>
{% endblock %}
{% block content %}
<h1>{{ title }}</h1>
<div class="results-summary" style="background: #f8f9fa; border: 1px solid #dee2e6; padding: 20px; margin-bottom: 20px; border-radius: 5px;">
<h2>任务概览</h2>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px;">
<div>
<strong>任务名称:</strong><br>
{{ task.name }}
</div>
<div>
<strong>任务类型:</strong><br>
{{ task.get_task_type_display }}
</div>
<div>
<strong>状态:</strong><br>
<span style="color: {% if task.status == 'completed' %}green{% elif task.status == 'failed' %}red{% elif task.status == 'running' %}blue{% else %}gray{% endif %};">
{{ task.get_status_display }}
</span>
</div>
<div>
<strong>创建时间:</strong><br>
{{ task.created_at|date:"Y-m-d H:i:s" }}
</div>
{% if task.started_at %}
<div>
<strong>开始时间:</strong><br>
{{ task.started_at|date:"Y-m-d H:i:s" }}
</div>
{% endif %}
{% if task.completed_at %}
<div>
<strong>完成时间:</strong><br>
{{ task.completed_at|date:"Y-m-d H:i:s" }}
</div>
{% endif %}
{% if task.get_duration %}
<div>
<strong>执行时长:</strong><br>
{{ task.duration_display }}
</div>
{% endif %}
</div>
</div>
<div class="results-stats" style="background: #fff; border: 1px solid #dee2e6; padding: 20px; margin-bottom: 20px; border-radius: 5px;">
<h2>统计信息</h2>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 15px;">
<div style="text-align: center; padding: 15px; background: #e3f2fd; border-radius: 5px;">
<div style="font-size: 24px; font-weight: bold; color: #1976d2;">{{ task.total_articles }}</div>
<div>总文章数</div>
</div>
<div style="text-align: center; padding: 15px; background: #e8f5e8; border-radius: 5px;">
<div style="font-size: 24px; font-weight: bold; color: #388e3c;">{{ task.success_count }}</div>
<div>成功数</div>
</div>
<div style="text-align: center; padding: 15px; background: #ffebee; border-radius: 5px;">
<div style="font-size: 24px; font-weight: bold; color: #d32f2f;">{{ task.failed_count }}</div>
<div>失败数</div>
</div>
{% if task.total_articles > 0 %}
<div style="text-align: center; padding: 15px; background: #fff3e0; border-radius: 5px;">
<div style="font-size: 24px; font-weight: bold; color: #f57c00;">
{% widthratio task.success_count task.total_articles 100 %}%
</div>
<div>成功率</div>
</div>
{% endif %}
</div>
</div>
{% if task.keyword %}
<div class="task-config" style="background: #fff; border: 1px solid #dee2e6; padding: 20px; margin-bottom: 20px; border-radius: 5px;">
<h2>任务配置</h2>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px;">
<div>
<strong>搜索关键词:</strong><br>
{{ task.keyword }}
</div>
<div>
<strong>目标网站:</strong><br>
{{ task.get_websites_display }}
</div>
{% if task.start_date %}
<div>
<strong>开始日期:</strong><br>
{{ task.start_date }}
</div>
{% endif %}
{% if task.end_date %}
<div>
<strong>结束日期:</strong><br>
{{ task.end_date }}
</div>
{% endif %}
<div>
<strong>最大页数:</strong><br>
{{ task.max_pages }}
</div>
<div>
<strong>最大文章数:</strong><br>
{{ task.max_articles }}
</div>
</div>
</div>
{% endif %}
{% if task.current_website or task.current_action %}
<div class="current-status" style="background: #fff; border: 1px solid #dee2e6; padding: 20px; margin-bottom: 20px; border-radius: 5px;">
<h2>当前状态</h2>
{% if task.current_website %}
<div>
<strong>当前网站:</strong> {{ task.current_website }}
</div>
{% endif %}
{% if task.current_action %}
<div>
<strong>当前操作:</strong> {{ task.current_action }}
</div>
{% endif %}
{% if task.status == 'running' %}
<div style="margin-top: 10px;">
<div style="width: 100%; background-color: #f0f0f0; border-radius: 10px; overflow: hidden;">
<div style="width: {{ task.progress }}%; background-color: #4CAF50; height: 20px; text-align: center; line-height: 20px; color: white;">
{{ task.progress }}%
</div>
</div>
</div>
{% endif %}
</div>
{% endif %}
{% if task.error_message %}
<div class="error-info" style="background: #ffebee; border: 1px solid #f44336; padding: 20px; margin-bottom: 20px; border-radius: 5px;">
<h2 style="color: #d32f2f;">错误信息</h2>
<pre style="white-space: pre-wrap; word-wrap: break-word;">{{ task.error_message }}</pre>
</div>
{% endif %}
{% if task.result_details %}
<div class="detailed-results" style="background: #fff; border: 1px solid #dee2e6; padding: 20px; margin-bottom: 20px; border-radius: 5px;">
<h2>详细结果</h2>
{% for website, result in task.result_details.items %}
<div style="margin-bottom: 15px; padding: 10px; background: #f8f9fa; border-radius: 3px;">
<strong>{{ website }}:</strong>
<ul style="margin: 5px 0; padding-left: 20px;">
<li>找到链接: {{ result.found_urls }}</li>
<li>已处理: {{ result.processed }}</li>
<li>成功: {{ result.success }}</li>
<li>失败: {{ result.failed }}</li>
{% if result.error %}
<li style="color: red;">错误: {{ result.error }}</li>
{% endif %}
</ul>
</div>
{% endfor %}
</div>
{% endif %}
<div class="actions" style="text-align: center; margin-top: 30px;">
<a href="{% url 'admin:core_crawltask_changelist' %}" class="button" style="padding: 10px 20px; background: #417690; color: white; text-decoration: none; border-radius: 3px; margin-right: 10px;">
返回任务列表
</a>
{% if task.status == 'completed' %}
<a href="{% url 'admin:core_article_changelist' %}" class="button" style="padding: 10px 20px; background: #28a745; color: white; text-decoration: none; border-radius: 3px;">
查看文章
</a>
{% endif %}
</div>
{% endblock %}