Hoşgeldin Misafir

Mobil Berber Randevu Sistemi

Mustafa73

20 Eyl 2023
423 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
1. Backend (Node.js ve Express ile)
Adım 1: Node.js Projesi Başlatma
JavaScript:
mkdir barber-appointment-system
cd barber-appointment-system
npm init -y

Adım 2: Gerekli Paketleri Yükleyin

Kod:
npm install express mongoose multer cors bcrypt jsonwebtoken
npm install --save-dev nodemon

Adım 3: Basit Bir Sunucu Kurun
server.js dosyasını oluşturun ve aşağıdaki kodu ekleyin.
JavaScript:
const express = require('express');
const mongoose = require('mongoose');
const multer = require('multer');
const path = require('path');
const cors = require('cors');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const { exec } = require('child_process');
const app = express();
app.use(express.json());
app.use(cors());
app.use('/uploads', express.static('uploads'));
// MongoDB bağlantısı
mongoose.connect('mongodb://localhost:27017/barber', { useNewUrlParser: true, useUnifiedTopology: true });
// Kullanıcı şeması ve modeli
const userSchema = new mongoose.Schema({
  name: String,
  email: String,
  password: String,
});
const User = mongoose.model('User', userSchema);
// Randevu şeması ve modeli
const appointmentSchema = new mongoose.Schema({
  userId: String,
  date: Date,
  slot: String,
});
const Appointment = mongoose.model('Appointment', appointmentSchema);
// Kullanıcı kayıt
app.post('/register', async (req, res) => {
  const { name, email, password } = req.body;
  const hashedPassword = await bcrypt.hash(password, 10);
  const newUser = new User({ name, email, password: hashedPassword });
  await newUser.save();
  res.send('Kullanıcı kaydedildi');
});
// Kullanıcı giriş
app.post('/login', async (req, res) => {
  const { email, password } = req.body;
  const user = await User.findOne({ email });
  if (user && await bcrypt.compare(password, user.password)) {
    const token = jwt.sign({ userId: user._id }, 'secretkey', { expiresIn: '1h' });
    res.json({ message: 'Giriş başarılı', token });
  } else {
    res.status(401).send('Giriş başarısız');
  }
});
// Middleware for authenticating tokens
const authenticateToken = (req, res, next) => {
  const token = req.header('Authorization')?.split(' ')[1];
  if (!token) return res.status(401).send('Token gerekli');
  jwt.verify(token, 'secretkey', (err, user) => {
    if (err) return res.status(403).send('Geçersiz token');
    req.user = user;
    next();
  });
};
// Randevu alma
app.post('/appointment', authenticateToken, async (req, res) => {
  const { date, slot } = req.body;
  const newAppointment = new Appointment({ userId: req.user.userId, date, slot });
  await newAppointment.save();
  res.send('Randevu alındı');
});
// Resim yükleme ayarları
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, 'uploads/');
  },
  filename: (req, file, cb) => {
    cb(null, Date.now() + path.extname(file.originalname));
  },
});
const upload = multer({ storage: storage });
// Resim yükleme
app.post('/upload', authenticateToken, upload.single('image'), (req, res) => {
  res.send(`Resim yüklendi: ${req.file.path}`);
});
// Görüntü işleme
app.post('/process-image', authenticateToken, (req, res) => {
  const { imagePath, filterPath } = req.body;
  exec(`python3 image_processing.py ${imagePath} ${filterPath}`, (err, stdout, stderr) => {
    if (err) {
      res.status(500).send('Görüntü işleme hatası');
      return;
    }
    res.send('Görüntü işlendi');
  });
});

app.listen(3000, () => {
  console.log('Sunucu çalışıyor');
});

MongoDB Kurulumu
MongoDB'nin yerel makinede çalıştığından emin olun. MongoDB'yi başlatmak için aşağıdaki komutları kullanabilirsiniz:

Kod:
mongod --dbpath ./data

2. Frontend (Flutter ile)
Adım 1: Flutter Projesi Başlatma

Kod:
flutter create barber_appointment_app
cd barber_appointment_app

Adım 2: Gerekli Paketleri Yükleyin
pubspec.yaml dosyasına aşağıdaki bağımlılıkları ekleyin:

Kod:
dependencies:

  flutter:

    sdk: flutter

  image_picker: ^0.8.4+8

  http: ^0.13.3

  shared_preferences: ^2.0.6

Adım 3: Kullanıcı Arayüzü ve İşlevsellik

lib/main.dart dosyasını düzenleyin:

dart

import 'package:flutter/material.dart';

import 'package:image_picker/image_picker.dart';

import 'dart:io';

import 'package:http/http.dart' as http;

import 'dart:convert';

import 'package:shared_preferences/shared_preferences.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

  @override

  Widget build(BuildContext context) {

    return MaterialApp(

      home: HomeScreen(),

    );

  }

}

class HomeScreen extends StatefulWidget {

  @override

  _HomeScreenState createState() => _HomeScreenState();

}

class _HomeScreenState extends State<HomeScreen> {

  final ImagePicker _picker = ImagePicker();

  XFile? _image;

  String _token = '';

  String _status = '';

  @override

  void initState() {

    super.initState();

    _loadToken();

  }

  Future<void> _loadToken() async {

    final prefs = await SharedPreferences.getInstance();

    setState(() {

      _token = prefs.getString('token') ?? '';

    });

  }

  Future<void> _pickImage() async {

    final pickedFile = await _picker.pickImage(source: ImageSource.gallery);

    setState(() {

      _image = pickedFile;

    });

  }

  Future<void> _uploadImage() async {

    if (_image == null) return;

    var request = http.MultipartRequest('POST', Uri.parse('http://10.0.2.2:3000/upload'));

    request.headers['Authorization'] = 'Bearer $_token';

    request.files.add(await http.MultipartFile.fromPath('image', _image!.path));

    var response = await request.send();

    if (response.statusCode == 200) {

      setState(() {

        _status = 'Resim yüklendi';

      });

    } else {

      setState(() {

        _status = 'Resim yükleme başarısız';

      });

    }

  }

  Future<void> _register() async {

    var response = await http.post(

      Uri.parse('http://10.0.2.2:3000/register'),

      headers: {'Content-Type': 'application/json'},

      body: jsonEncode({

        'name': 'Test User',

        'email': '[email protected]',

        'password': 'password123',

      }),

    );

    if (response.statusCode == 200) {

      setState(() {

        _status = 'Kullanıcı kaydedildi';

      });

    } else {

      setState(() {

        _status = 'Kayıt başarısız';

      });

    }

  }

  Future<void> _login() async {

    var response = await http.post(

      Uri.parse('http://10.0.2.2:3000/login'),

      headers: {'Content-Type': 'application/json'},

      body: jsonEncode({

        'email': '[email protected]',

        'password': 'password123',

      }),

    );

    if (response.statusCode == 200) {

      var jsonResponse = jsonDecode(await response.stream.bytesToString());

      setState(() {

        _token = jsonResponse['token'];

        _status = 'Giriş başarılı';

      });

      final prefs = await SharedPreferences.getInstance();

      prefs.setString('token', _token);

    } else {

      setState(() {

        _status = 'Giriş başarısız';

      });

    }

  }

  @override

  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(title: Text('Saç ve Sakal Filtreleri')),

      body: Center(

        child: Column(

          mainAxisAlignment: MainAxisAlignment.center,

          children: <Widget>[

            _image == null ? Text('Resim seçilmedi.') : Image.file(File(_image!.path)),

            ElevatedButton(

              onPressed: _pickImage,

              child: Text('Resim Seç'),

            ),

            ElevatedButton(

              onPressed: _uploadImage,

              child: Text('Filtre Uygula ve Yükle'),

            ),

            ElevatedButton(

              onPressed: _register,

              child: Text('Kayıt Ol'),

            ),

            ElevatedButton(

              onPressed: _login,

              child: Text('Giriş Yap'),

            ),

            Text(_status),

          ],

        ),

      ),

    );

  }

}


3. Görüntü İşleme (Python ve OpenCV ile)
image_processing.py dosyasını oluşturun ve aşağıdaki kodu ekleyin:


Python:
import cv2
import numpy as np
import sys
def apply_filter(image_path, filter_path):
    image = cv2.imread(image_path)
    filter_img = cv2.imread(filter_path, -1)
    (h, w) = image.shape[:2]
    filter_img = cv2.resize(filter_img, (w, h))   
    for i in range(3):
        image[:, :, i] = image[:, :, i] * (1 - filter_img[:, :, 3] / 255.0) + filter_img[:, :, i] * (filter_img[:, :, 3] / 255.0)
    output_path = 'output.png'
    cv2.imwrite(output_path, image)
    return output_path
if __name__ == "__main__":
    image_path = sys.argv[1]
    filter_path = sys.argv[2]
    apply_filter(image_path, filter_path)
 Son Adımlar
 Node.js sunucusunu başlat
nodemon server.js
Flutter uygulamasını çalıştır
flutter run

Bu, mobil berber randevu sistemi ve saç/sakal filtreleri uygulaması için geliştirilmiştir. Sistem üç ana bileşenden oluşur:
1. Backend (Node.js ve Express ile)
Backend, kullanıcı kaydı, giriş, randevu alma ve görüntü yükleme/işleme işlemlerini yönetir.
- Node.js projesi oluşturma ve paketleri yükleme
- Basit bir sunucu kurma: Kullanıcılar için kayıt ve giriş işlemleri, randevu oluşturma, resim yükleme ve işleme gibi API uç noktalarını içeren bir Express sunucusu kurulmuştur.
- MongoDB: Veritabanı olarak MongoDB kullanılmıştır.

2. Frontend (Flutter ile)
Flutter kullanarak mobil uygulama geliştirilmiştir.
- Flutter projesi oluşturma ve gerekli paketleri yükleme
- Kullanıcı arayüzü ve işlevsellik: Kullanıcılar resim seçebilir, yükleyebilir, kayıt olabilir ve giriş yapabilir. Giriş yapıldıktan sonra filtre uygulama işlemi gerçekleştirilir.
3. Görüntü İşleme (Python ve OpenCV ile)
Görüntü işleme, Python ve OpenCV kullanarak gerçekleştirilir.
- Python betiği: Bir resme filtre uygulamak için bir Python betiği oluşturulmuştur. Betik, verilen görüntü yoluna ve filtre yoluna göre işlemi gerçekleştirir.
Çalıştırma Talimatları
- Node.js sunucusunu başlatma: nodemon server.js komutu ile sunucuyu başlatabilirsiniz.
- Flutter uygulamasını çalıştırma: flutter run komutu ile Flutter uygulamasını çalıştırabilirsiniz.