diff --git a/README.md b/README.md index 0597bdf..37654c3 100644 --- a/README.md +++ b/README.md @@ -5,16 +5,18 @@ Eine Flask-basierte Webanwendung zur Suche in Kundendaten aus einer CSV-Datei. ## Features - Live-Suche während der Eingabe -- Suche nach: +- Spezifische Suchfelder für: - Kundennummer - Name (Vor- und Nachname) - Fachrichtung - Ort +- Allgemeine Suche über alle Felder - Klickbare Links für: - Telefonnummern (tel:) - E-Mail-Adressen (mailto:) - Adressen (Google Maps) - Kundennummern (KKBefe-System) +- Teilen-Funktion für einzelne Suchergebnisse - Responsive Design mit Bootstrap - Docker-Container-Unterstützung @@ -37,6 +39,7 @@ medi-customers/ ├── spezexpo.csv # Kundendaten ├── requirements.txt # Python-Abhängigkeiten ├── Dockerfile # Docker-Konfiguration +├── docker-compose.yml # Docker Compose Konfiguration └── .dockerignore # Docker-Ignore-Datei ``` @@ -76,14 +79,11 @@ Die Anwendung erwartet eine CSV-Datei (`spezexpo.csv`) mit folgenden Spalten: ### Docker-Container 1. Docker installieren -2. Container bauen: +2. Container mit Docker Compose starten: ```bash - docker build -t medi-customers . - ``` -3. Container starten: - ```bash - docker run -d -p 5000:5000 --name medi-customers medi-customers + docker-compose up --build ``` + Die Anwendung ist dann unter `http://localhost:5001` erreichbar. ## API-Endpunkte @@ -91,16 +91,22 @@ Die Anwendung erwartet eine CSV-Datei (`spezexpo.csv`) mit folgenden Spalten: - Rendert die Hauptseite ### GET /search -- Sucht nach Kunden basierend auf dem Query-Parameter -- Parameter: `q` (Suchbegriff) +- Sucht nach Kunden basierend auf verschiedenen Parametern +- Parameter: + - `name`: Suche nach Vor- oder Nachname + - `ort`: Suche nach Ort + - `kundennummer`: Suche nach Kundennummer + - `fachrichtung`: Suche nach Fachrichtung + - `q`: Allgemeine Suche über alle Felder - Returns: JSON-Array mit gefundenen Kunden ## Frontend-Funktionen ### Suchfunktion - Live-Suche mit 300ms Debounce -- Minimale Suchlänge: 2 Zeichen -- Suche wird bei Enter-Taste sofort ausgeführt +- Spezifische Suchfelder für präzise Suche +- Allgemeine Suche für breite Suche +- Kombinierbare Suchkriterien ### Link-Generierung - `createPhoneLink()`: Erstellt tel:-Links mit führender 0 @@ -108,6 +114,11 @@ Die Anwendung erwartet eine CSV-Datei (`spezexpo.csv`) mit folgenden Spalten: - `createAddressLink()`: Erstellt Google Maps-Links - `createCustomerLink()`: Erstellt KKBefe-System-Links +### Teilen-Funktion +- Individueller Teilen-Button für jedes Suchergebnis +- Kopiert einen direkten Link zum spezifischen Kunden +- Visuelles Feedback beim Kopieren + ## Fehlerbehandlung - Logging für Backend-Fehler @@ -132,25 +143,24 @@ python app.py ### Container-Verwaltung ```bash # Container stoppen -docker stop medi-customers +docker-compose down # Container starten -docker start medi-customers +docker-compose up + +# Container im Hintergrund starten +docker-compose up -d # Container-Logs anzeigen -docker logs medi-customers - -# Container entfernen -docker rm medi-customers +docker-compose logs -f ``` ### Datenaktualisierung 1. CSV-Datei aktualisieren 2. Container neu bauen und starten: ```bash - docker stop medi-customers - docker build -t medi-customers . - docker run -d -p 5000:5000 --name medi-customers medi-customers + docker-compose down + docker-compose up --build ``` ## Sicherheit diff --git a/app.py b/app.py index c46c58a..5f39b47 100644 --- a/app.py +++ b/app.py @@ -1,10 +1,10 @@ -from flask import Flask, render_template, request, jsonify +from flask import Flask, render_template, request, jsonify, url_for import pandas as pd import os import logging import numpy as np -app = Flask(__name__) +app = Flask(__name__, static_folder='static') logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) @@ -35,21 +35,54 @@ def index(): @app.route('/search') def search(): try: + # Spezifische Suchparameter + name = request.args.get('name', '').lower() + ort = request.args.get('ort', '').lower() + kundennummer = request.args.get('kundennummer', '').lower() + fachrichtung = request.args.get('fachrichtung', '').lower() + + # Allgemeine Suche (für die alte Funktionalität) query = request.args.get('q', '').lower() - logger.info(f"Suche nach: {query}") + + logger.info(f"Suche nach - Name: {name}, Ort: {ort}, Kundennummer: {kundennummer}, Fachrichtung: {fachrichtung}, Query: {query}") df = load_data() if df is None: return jsonify({"error": "Datenbank konnte nicht geladen werden"}), 500 - # Suche über verschiedene Felder - mask = ( - df['Vorname'].str.lower().str.contains(query, na=False) | - df['Nachname'].str.lower().str.contains(query, na=False) | - df['Fachrichtung'].str.lower().str.contains(query, na=False) | - df['Ort'].str.lower().str.contains(query, na=False) | - df['Nummer'].astype(str).str.contains(query, na=False) # Suche nach Kundennummer - ) + # Basis-Mask (immer True) + mask = pd.Series(True, index=df.index) + + # Spezifische Suchkriterien anwenden + if name: + name_mask = ( + df['Vorname'].str.lower().str.contains(name, na=False) | + df['Nachname'].str.lower().str.contains(name, na=False) + ) + mask &= name_mask + + if ort: + ort_mask = df['Ort'].str.lower().str.contains(ort, na=False) + mask &= ort_mask + + if kundennummer: + kunden_mask = df['Nummer'].astype(str).str.contains(kundennummer, na=False) + mask &= kunden_mask + + if fachrichtung: + fach_mask = df['Fachrichtung'].str.lower().str.contains(fachrichtung, na=False) + mask &= fach_mask + + # Wenn eine allgemeine Suche vorhanden ist, diese zusätzlich anwenden + if query: + query_mask = ( + df['Vorname'].str.lower().str.contains(query, na=False) | + df['Nachname'].str.lower().str.contains(query, na=False) | + df['Fachrichtung'].str.lower().str.contains(query, na=False) | + df['Ort'].str.lower().str.contains(query, na=False) | + df['Nummer'].astype(str).str.contains(query, na=False) + ) + mask &= query_mask results = df[mask].to_dict('records') logger.info(f"{len(results)} Ergebnisse gefunden") diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..e0a2a8a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,14 @@ +version: '3.8' + +services: + web: + build: . + ports: + - "5001:5000" + volumes: + - .:/app + environment: + - FLASK_APP=app.py + - FLASK_ENV=development + - FLASK_DEBUG=1 + command: flask run --host=0.0.0.0 \ No newline at end of file diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000..6e9601c Binary files /dev/null and b/static/favicon.ico differ diff --git a/templates/index.html b/templates/index.html index 453cedd..0c88ade 100644 --- a/templates/index.html +++ b/templates/index.html @@ -4,6 +4,7 @@