TIFNGK_E41222722/templates/expert_system.html

341 lines
18 KiB
HTML

{% extends "base.html" %}
{% block title %}Sistem Pakar PMK{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card shadow">
<div class="card-header bg-success text-white">
<h4 class="mb-0"><i class="fas fa-stethoscope me-2"></i>Sistem Pakar Forward Chaining - Diagnosis PMK</h4>
</div>
<div class="card-body">
{% set is_image_mode = context_mode == 'image' %}
<!-- Breadcrumb -->
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ url_for('index') }}">Home</a></li>
<li class="breadcrumb-item active" aria-current="page">Sistem Pakar</li>
</ol>
</nav>
<!-- Info Panel -->
<div class="alert alert-info mb-4">
<i class="fas fa-info-circle me-2"></i>
<strong>Cara Penggunaan:</strong> Pilih gejala yang Anda amati pada sapi, kemudian klik tombol diagnosis untuk mendapatkan hasil.
</div>
{% if is_image_mode %}
<div class="alert alert-success mb-4">
<i class="fas fa-image me-2"></i>
Mode ini mengikuti hasil deteksi gambar sebelumnya.
</div>
{% else %}
<div class="alert alert-secondary mb-4">
<i class="fas fa-brain me-2"></i>
Mode ini berjalan langsung sebagai sistem pakar tanpa keterikatan gambar.
</div>
{% endif %}
{% if image_info %}
<div class="alert alert-success mb-4">
<h5 class="alert-heading"><i class="fas fa-camera me-2"></i>Informasi Deteksi Sebelumnya</h5>
<div class="row">
<div class="col-md-8">
<p class="mb-1"><strong>File:</strong> {{ image_info.filename }}</p>
<p class="mb-1"><strong>Hasil Deteksi:</strong>
<span class="badge {% if image_info.prediction == 'sakit' %}bg-warning text-dark{% else %}bg-success{% endif %}">
{{ image_info.prediction|upper }}
</span>
</p>
</div>
<!-- <div class="col-md-4 text-center">
<i class="fas fa-arrow-right fa-2x text-success"></i>
<p class="mb-0"><small>Lanjutkan diagnosis</small></p>
</div> -->
</div>
</div>
{% endif %}
{% if diagnosis %}
<!-- Hasil Diagnosis -->
<div class="alert alert-info" id="hasil">
<h5 class="alert-heading mb-3">
<i class="fas fa-clipboard-check me-2"></i>Hasil Diagnosis
</h5>
{% if diagnosis.status == 'terdiagnosis' %}
<div class="alert alert-success mb-3">
<strong>Status:</strong> Positif PMK
<div class="mt-2">
Diagnosis utama akan ditampilkan di bawah sebagai bentuk PMK yang paling sesuai.
</div>
</div>
{% for diag in diagnosis.diagnosis %}
<div class="card mb-3 {% if loop.first %}border-success border-3{% endif %}">
<div class="card-header {% if loop.first %}bg-success text-white{% else %}bg-light{% endif %}">
<h5 class="mb-0">
<i class="fas fa-diagnoses me-2"></i>{{ diag.nama }}
{% if loop.first %}
<span class="badge bg-light text-success float-end">{{ diag.persentase|default(diag.score * 100)|round(2) }}%</span>
{% endif %}
</h5>
</div>
<div class="card-body">
<div class="mb-3">
<label class="fw-bold">Kategori Penyakit:</label>
<div class="mt-2">
{% if diag.severity == 'oral' %}
<span class="badge bg-info fs-6">PMK ORAL</span>
{% elif diag.severity == 'podal' %}
<span class="badge bg-warning text-dark fs-6">PMK PODAL</span>
{% elif diag.severity == 'laktasi' %}
<span class="badge bg-primary fs-6">PMK LAKTASI</span>
{% elif diag.severity == 'juvenil' %}
<span class="badge bg-danger fs-6">PMK JUVENIL</span>
{% elif diag.severity == 'akut umum' %}
<span class="badge bg-dark fs-6">PMK AKUT UMUM</span>
{% else %}
<span class="badge bg-secondary fs-6">PMK</span>
{% endif %}
</div>
</div>
<div class="mb-3">
<label class="fw-bold">Deskripsi:</label>
<p class="mb-0">{{ diag.deskripsi }}</p>
</div>
{% if diag.bukti_aturan %}
<div class="mb-3">
<label class="fw-bold">Bukti Aturan yang Cocok:</label>
<ul class="mb-0 mt-2">
{% for bukti in diag.bukti_aturan %}
<li>{{ bukti.kode }} - {{ bukti.deskripsi }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="mb-0">
<label class="fw-bold">Rekomendasi Penanganan:</label>
<ol class="mb-0">
{% for s in diag.solusi %}
<li class="mb-1">{{ s }}</li>
{% endfor %}
</ol>
</div>
</div>
</div>
{% endfor %}
<div class="card mt-3">
<div class="card-header bg-secondary text-white">
<h5 class="mb-0"><i class="fas fa-list me-2"></i>Gejala yang Diamati</h5>
</div>
<div class="card-body">
<ul class="list-group">
{% for g in diagnosis.gejala_teramati %}
<li class="list-group-item">
<i class="fas fa-check-circle text-success me-2"></i>
{{ g }}
</li>
{% endfor %}
</ul>
</div>
</div>
<div class="alert alert-warning mt-3">
<i class="fas fa-exclamation-triangle me-2"></i>
<strong>Penanganan Awal:</strong> isolasi sapi yang terindikasi PMK, sediakan pakan lunak dan air minum cukup, jaga kebersihan kandang, dan hubungi dokter hewan secepatnya.
</div>
<div class="mt-4 text-center">
<button class="btn btn-success" onclick="window.print()">
<i class="fas fa-print me-2"></i>Cetak Hasil
</button>
<a href="{{ url_for('expert_system_page', mode=context_mode) }}" class="btn btn-primary">
<i class="fas fa-redo me-2"></i>Konsultasi Lagi
</a>
<a href="{{ url_for('index') }}" class="btn btn-secondary">
<i class="fas fa-home me-2"></i>Kembali ke Home
</a>
</div>
{% else %}
<div class="alert alert-warning">
<i class="fas fa-exclamation-circle me-2"></i>
{{ diagnosis.message }}
</div>
<div class="text-center">
<a href="{{ url_for('expert_system_page', mode=context_mode) }}" class="btn btn-primary">
<i class="fas fa-redo me-2"></i>Coba Lagi
</a>
</div>
{% endif %}
</div>
{% else %}
<!-- Form Gejala -->
<form method="POST" action="{{ url_for('expert_system_page', mode=context_mode) }}" id="expertForm">
<input type="hidden" name="mode" value="{{ context_mode }}">
<div class="mb-4">
<h5 class="mb-3"><i class="fas fa-list-ul me-2"></i>Pilih Gejala yang Diamati:</h5>
<!-- Kategori Gejala -->
<div class="accordion" id="gejalaAccordion">
{% for group_key, group in gejala_groups.items() %}
<div class="accordion-item">
<h2 class="accordion-header" id="heading{{ group_key|capitalize }}">
<button class="accordion-button {% if not loop.first %}collapsed{% endif %}" type="button" data-bs-toggle="collapse" data-bs-target="#collapse{{ group_key|capitalize }}">
{% if group_key == 'umum' %}<i class="fas fa-thermometer-half me-2"></i>{% elif group_key == 'mulut' %}<i class="fas fa-tooth me-2"></i>{% elif group_key == 'kaki' %}<i class="fas fa-shoe-prints me-2"></i>{% elif group_key == 'ambing' %}<i class="fas fa-cow me-2"></i>{% else %}<i class="fas fa-exclamation-triangle me-2"></i>{% endif %}
{{ group.title }}
</button>
</h2>
<div id="collapse{{ group_key|capitalize }}" class="accordion-collapse collapse {% if loop.first %}show{% endif %}" data-bs-parent="#gejalaAccordion">
<div class="accordion-body">
<div class="row">
{% for kode in group.codes %}
<div class="col-md-6 mb-2">
<div class="form-check">
<input class="form-check-input" type="checkbox"
name="gejala" value="{{ kode }}"
id="gejala{{ kode }}"
{% if selected_gejala and kode in selected_gejala %}checked{% endif %}>
<label class="form-check-label" for="gejala{{ kode }}">
<strong>{{ kode }}:</strong> {{ gejala_list[kode] }}
</label>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<!-- Action Buttons -->
<div class="mt-4 text-center">
<button type="submit" class="btn btn-success btn-lg">
<i class="fas fa-diagnoses me-2"></i>{% if is_image_mode %}Diagnosis dari Gambar{% else %}Diagnosis Langsung{% endif %}
</button>
<button type="reset" class="btn btn-secondary btn-lg">
<i class="fas fa-undo me-2"></i>Reset
</button>
</div>
<!-- Tombol Pilih Semua -->
<div class="mt-3 text-center">
<button type="button" class="btn btn-outline-primary btn-sm" id="selectAll">
<i class="fas fa-check-double me-2"></i>Pilih Semua
</button>
<button type="button" class="btn btn-outline-secondary btn-sm" id="unselectAll">
<i class="fas fa-times me-2"></i>Hapus Semua
</button>
</div>
</form>
{% endif %}
</div>
</div>
<!-- Informasi Tambahan -->
<div class="card mt-3">
<div class="card-header bg-info text-white">
<h5 class="mb-0"><i class="fas fa-question-circle me-2"></i>Tentang Sistem Pakar</h5>
</div>
<div class="card-body">
<p>Sistem pakar ini menggunakan metode <strong>Forward Chaining</strong> untuk mendiagnosis PMK pada sapi berdasarkan gejala yang diamati.</p>
<ul class="mb-0">
<li>Total gejala: {{ gejala_list|length }} gejala</li>
<li>Total aturan: 33 aturan</li>
<li>Fokus hasil: status positif PMK dan penanganan awal</li>
</ul>
</div>
</div>
</div>
</div>
<style>
.accordion-button:not(.collapsed) {
background-color: #d4edda;
color: #155724;
}
.form-check-input:checked {
background-color: #28a745;
border-color: #28a745;
}
@media print {
.btn, footer, nav, .accordion-button {
display: none !important;
}
.accordion-collapse {
display: block !important;
}
}
</style>
{% endblock %}
{% block scripts %}
<script>
document.addEventListener('DOMContentLoaded', function() {
// Simpan predictions.id ke localStorage agar riwayat deteksi hanya menampilkan data terkait
(function() {
const savedPredictionId = Number('{{ diagnosis.saved_prediction_id if diagnosis and diagnosis.saved_prediction_id else 0 }}');
const storageKey = 'pmk_predictions_ids';
let storedIds = [];
if (savedPredictionId <= 0) {
return;
}
try {
storedIds = JSON.parse(localStorage.getItem(storageKey) || '[]');
if (!Array.isArray(storedIds)) storedIds = [];
} catch (e) {
storedIds = [];
}
if (!storedIds.includes(savedPredictionId)) {
storedIds.unshift(savedPredictionId);
localStorage.setItem(storageKey, JSON.stringify(storedIds));
}
})();
// Reset button
document.querySelector('button[type="reset"]')?.addEventListener('click', function(e) {
e.preventDefault();
document.querySelectorAll('input[type="checkbox"]').forEach(cb => cb.checked = false);
});
// Select All button
document.getElementById('selectAll')?.addEventListener('click', function() {
document.querySelectorAll('input[type="checkbox"]').forEach(cb => cb.checked = true);
});
// Unselect All button
document.getElementById('unselectAll')?.addEventListener('click', function() {
document.querySelectorAll('input[type="checkbox"]').forEach(cb => cb.checked = false);
});
// Auto scroll to hasil diagnosis
if (window.location.hash === '#hasil') {
document.getElementById('hasil')?.scrollIntoView({ behavior: 'smooth' });
}
// Form validation
document.getElementById('expertForm')?.addEventListener('submit', function(e) {
const checkedBoxes = document.querySelectorAll('input[type="checkbox"]:checked');
if (checkedBoxes.length === 0) {
e.preventDefault();
alert('Pilih minimal satu gejala untuk melakukan diagnosis!');
}
});
});
</script>
{% endblock %}