Avec la progression rapide des technologies de l'information, les organisations modernes orientent leur gestion vers des solutions informatisées et automatisées. La gestion des ressources humaines (GRH), composante vitale de l'administration d'entreprise, ne peut plus s'appuyer sur des méthodes manuelles pour répondre aux exigences d'efficacité actuelles. C'est dans ce contexte qu'émerge le Système d'Information des Ressources Humaines (SIRH), une solution basée sur les technologies de l'information. Cet article explore la conception et la réalisation d'un tel système, s'appuyant sur l'écosystème Spring Boot pour le backend, Vue.js pour le frontend, et une base de données MySQL. Nous couvrirons l'analyse des besoins, la conception architecturale et de la base de données, ainsi que les extraits de code clés.
1. Contexte et Pertinence du Projet
Dans la gestion contemporaine des ressources humaines, les entreprises doivent traiter un volume considérable de données : informations personnelles des employés, historiques de travail, salaires, informations de recrutement, etc. Les méthodes traditionnelles de saisie manuelle posent des défis significatifs en matière de recherche, de gestion et de sécurité des données. À mesure que les entreprises se développent et que le nombre d'employés augmente, ces méthodes deviennent inadaptées face au besoin de rapidité et d'efficacité. Le développement d'un SIRH robuste et fiable est donc devenu impératif.
Ce type de système vise à automatiser le traitement des données, réduisant ainsi l'intervention humaine et améliorant la précision et la sécurité des informations. Il facilite également les analyses statistiques, les rapports et le support à la décision, contribuant à l'amélioration globale de la gestion des RH et de la prise de décision stratégique.
2. Architecture Système et Choix Technologiques
2.1. Architecture Technique
Le système est basé sur une architecture classique Client-Serveur (B/S). Le frontend est développé avec le framework Vue.js, tandis que le backend est bâti sur l'écosystème Spring Boot. Les données sont stockées et gérées par une base de données MySQL. Cette architecture favorise une séparation claire entre le frontend et le backend, facilitant le développement parallèle et la maintenance.
- Spring Boot : Utilisé comme framework principal pour le développement backend Java, il simplifie grandement la configuration et accélère le développement d'applications robustes.
- Spring MVC : Intégré à Spring Boot, il gère les requêtes web et les réponses, en s'appuyant sur le modèle de conception MVC (Modèle-Vue-Contrôleur).
- Mybatis : Framework de persistance qui simplifie les opérations de base de données et améliore l'efficacité des interactions avec MySQL.
- Vue.js : Framework JavaScript progressif pour le développement d'interfaces utilisateur interactives et réactives.
- MySQL : Base de données relationnelle open source, choisie pour sa fiabilité, ses performances élevées et sa capacité à gérer de grands volumes de données.
2.2. Conception Fonctionnelle du Système
Le système est conçu pour deux types d'utilisateurs : les administrateurs et les employés, chacun ayant des rôles et des modules fonctionnels distincts.
- Modules pour Administrateurs :
- Gestion des Collaborateurs : Création, modification, suppression, recherche et statistiques concernant les informations des employés.
- Administration des Départements : Gestion des structures départementales (création, mise à jour, suppression).
- Gestion des Salaires : Consultation et ajustement des informations salariales des employés, y compris le calcul des paies.
- Gestion du Recrutement : Publication d'offres d'emploi, suivi et gestion des candidatures.
- Gestion des Mouvements de Personnel : Suivi des affectations, promotions et transferts.
- Modules pour Employés :
- Consultation du Profil Personnel : Affichage et mise à jour des informations personnelles.
- Accès aux Offres d'Emploi : Consultation des postes ouverts et soumission de candidatures internes ou externes.
- Historique Salarial : Consultation des fiches de paie et de l'historique des salaires.
- Historique des Affectations : Consultation des enregistrements de mouvements de personnel.
2.3. Modélisation de la Base de Données
La conception de la base de données est cruciale pour la performance du système. Voici les principales tables et leurs attributs :
Table des Employés (tbl_employes)
| Champ | Type de Données | Description |
|---|---|---|
id_employe |
INT |
Identifiant unique de l'employé (Clé primaire) |
nom_complet |
VARCHAR(100) |
Nom et prénom de l'employé |
telephone |
VARCHAR(20) |
Numéro de téléphone |
email_perso |
VARCHAR(100) |
Adressse email professionnelle |
id_departement |
INT |
ID du département (Clé étrangère vers tbl_departements) |
titre_poste |
VARCHAR(50) |
Poste occupé par l'employé |
date_embauche |
DATE |
Date d'entrée en fonction |
salaire_base |
DECIMAL(10, 2) |
Salaire mensuel de base |
Table des Départements (tbl_departements)
| Champ | Type de Données | Description |
|---|---|---|
id_departement |
INT |
Identifiant unique du département (Clé primaire) |
nom_departement |
VARCHAR(100) |
Nom du département |
id_manager |
INT |
ID de l'employé gérant ce département |
localisation |
VARCHAR(100) |
Emplacement géographique du département |
Table des Bulletins de Salaire (tbl_salaires)
| Champ | Type de Données | Description |
|---|---|---|
id_bulletin |
INT |
Identifiant unique du bulletin de salaire (Clé primaire) |
id_employe |
INT |
ID de l'employé (Clé étrangère vers tbl_employes) |
montant_brut |
DECIMAL(10, 2) |
Salaire brut |
primes |
DECIMAL(10, 2) |
Montant des primes |
total_net |
DECIMAL(10, 2) |
Salaire net versé |
periode_paie |
DATE |
Mois et année de la paie |
Table des Offres d'Emploi (tbl_offres_emploi)
| Champ | Type de Données | Description |
|---|---|---|
id_offre |
INT |
Identifiant unique de l'offre (Clé primaire) |
intitule_poste |
VARCHAR(100) |
Titre du poste à pourvoir |
id_departement |
INT |
Département recruteur (Clé étrangère) |
nb_postes_ouverts |
INT |
Nombre de postes disponibles |
description_poste |
TEXT |
Détail de la description du poste |
date_publication |
DATE |
Date de publication de l'offre |
Table des Candidatures (tbl_candidatures)
| Champ | Type de Données | Description |
|---|---|---|
id_candidature |
INT |
Identifiant unique de la candidature (Clé primaire) |
nom_candidat |
VARCHAR(100) |
Nom complet du candidat |
telephone_candidat |
VARCHAR(20) |
Téléphone du candidat |
cv_candidat |
TEXT |
Contenu ou lien vers le CV |
statut_entretien |
VARCHAR(50) |
Statut de l'entretien (Ex: "Planifié", "Réalisé", "Annulé") |
date_entretien |
DATE |
Date de l'entretien |
resultat_final |
VARCHAR(50) |
Résultat de la candidature (Ex: "Accepté", "Refusé", "En attente") |
3. Implémentation du Système
3.1. Code Backend (Spring Boot)
Voici des extraits de code pour les contrôleurs REST gérant les employés et les offres d'emploi, démontrant les opérations CRUD.
API de Gestion des Employés
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/admin/personnel")
public class GestionPersonnelController {
@Autowired
private PersonnelService servicePersonnel; // Renommé de EmployeeService
/**
* Ajoute un nouvel employé au système.
* @param nouvelEmploye L'objet Employe à ajouter.
* @return Réponse HTTP indiquant le succès ou l'échec.
*/
@PostMapping("/ajouter")
public ResponseEntity<String> enregistrerEmploye(@RequestBody Employe nouvelEmploye) {
servicePersonnel.creerEmploye(nouvelEmploye);
return ResponseEntity.status(HttpStatus.CREATED).body("Employé enregistré avec succès.");
}
/**
* Met à jour les informations d'un employé existant.
* @param id Identifiant de l'employé à modifier.
* @param employeModifie Les nouvelles données de l'employé.
* @return Réponse HTTP indiquant le succès ou l'échec.
*/
@PutMapping("/modifier/{id}")
public ResponseEntity<String> mettreAJourEmploye(@PathVariable("id") int id, @RequestBody Employe employeModifie) {
servicePersonnel.actualiserEmploye(id, employeModifie);
return ResponseEntity.ok("Informations de l'employé mises à jour.");
}
/**
* Supprime un employé du système.
* @param id Identifiant de l'employé à supprimer.
* @return Réponse HTTP indiquant le succès ou l'échec.
*/
@DeleteMapping("/supprimer/{id}")
public ResponseEntity<String> effacerEmploye(@PathVariable("id") int id) {
servicePersonnel.supprimerEmploye(id);
return ResponseEntity.ok("Employé supprimé du système.");
}
/**
* Récupère la liste de tous les employés.
* @return Une liste d'objets Employe.
*/
@GetMapping("/liste")
public ResponseEntity<List<Employe>> obtenirTousLesEmployes() {
List<Employe> listeEmployes = servicePersonnel.recupererTousLesEmployes();
return ResponseEntity.ok(listeEmployes);
}
}
API de Gestion des Offres d'Emploi
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/admin/recrutement")
public class GestionRecrutementController {
@Autowired
private OffreEmploiService serviceOffreEmploi; // Renommé de RecruitmentService
/**
* Crée une nouvelle offre d'emploi.
* @param nouvelleOffre L'objet OffreEmploi à publier.
* @return Réponse HTTP confirmant la création.
*/
@PostMapping("/publier")
public ResponseEntity<String> creerOffre(@RequestBody OffreEmploi nouvelleOffre) {
serviceOffreEmploi.ajouterOffre(nouvelleOffre);
return ResponseEntity.status(HttpStatus.CREATED).body("Offre d'emploi publiée avec succès.");
}
/**
* Met à jour une offre d'emploi existante.
* @param id Identifiant de l'offre à modifier.
* @param offreMiseAJour Les nouvelles données de l'offre.
* @return Réponse HTTP confirmant la mise à jour.
*/
@PutMapping("/actualiser/{id}")
public ResponseEntity<String> modifierOffre(@PathVariable("id") int id, @RequestBody OffreEmploi offreMiseAJour) {
serviceOffreEmploi.modifierOffre(id, offreMiseAJour);
return ResponseEntity.ok("Offre d'emploi mise à jour.");
}
/**
* Supprime une offre d'emploi.
* @param id Identifiant de l'offre à retirer.
* @return Réponse HTTP confirmant la suppression.
*/
@DeleteMapping("/retirer/{id}")
public ResponseEntity<String> annulerOffre(@PathVariable("id") int id) {
serviceOffreEmploi.supprimerOffre(id);
return ResponseEntity.ok("Offre d'emploi supprimée.");
}
/**
* Récupère toutes les offres d'emploi actives.
* @return Une liste d'objets OffreEmploi.
*/
@GetMapping("/active")
public ResponseEntity<List<OffreEmploi>> listerOffresActives() {
List<OffreEmploi> offres = serviceOffreEmploi.recupererToutesLesOffres();
return ResponseEntity.ok(offres);
}
}
3.2. Présentation Frontend (Vue.js)
Le composant Vue.js suivant illustre l'affichage et la gestion des offres d'emploi pour l'administrateur, incluant les actions d'édition et de suppression.
<template>
<div>
<h2>Gestion des Offres d'Emploi</h2>
<el-table :data="listeOffres" style="width: 100%" border>
<el-table-column prop="intitulePoste" label="Intitulé du Poste" width="250"></el-table-column>
<el-table-column prop="nomDepartement" label="Département" width="200"></el-table-column>
<el-table-column prop="datePublication" label="Date de Publication" width="180"></el-table-column>
<el-table-column label="Actions">
<template slot-scope="scope">
<el-button @click="editerOffre(scope.row.id)" size="mini" type="primary">Modifier</el-button>
<el-button @click="confirmerSuppression(scope.row.id)" size="mini" type="danger">Supprimer</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import axios from 'axios'; // Assurez-vous d'avoir axios installé (npm install axios)
export default {
name: 'GestionOffresEmploi',
data() {
return {
listeOffres: [] // Renommé de recruitmentList
};
},
methods: {
/**
* Récupère la liste des offres d'emploi depuis le backend.
*/
chargerOffresEmploi() { // Renommé de fetchRecruitments
axios.get('/api/admin/recrutement/active') // Nouvelle route d'API
.then(response => {
this.listeOffres = response.data;
})
.catch(error => {
console.error("Erreur lors de la récupération des offres d'emploi:", error);
this.$message.error("Impossible de charger les offres d'emploi."); // Exemple d'affichage d'erreur avec Element UI
});
},
/**
* Navigue vers la page d'édition d'une offre spécifique.
* @param id L'identifiant de l'offre à éditer.
*/
editerOffre(id) { // Renommé de editRecruitment
this.$router.push({ path: `/admin/recrutement/edition/${id}` });
},
/**
* Demande une confirmation avant de supprimer une offre.
* @param id L'identifiant de l'offre à supprimer.
*/
confirmerSuppression(id) {
this.$confirm('Voulez-vous vraiment supprimer cette offre d\'emploi ?', 'Confirmation', {
confirmButtonText: 'Oui',
cancelButtonText: 'Non',
type: 'warning'
}).then(() => {
this.supprimerOffre(id);
}).catch(() => {
this.$message({
type: 'info',
message: 'Suppression annulée'
});
});
},
/**
* Envoie une requête de suppression au backend pour une offre spécifique.
* @param id L'identifiant de l'offre à supprimer.
*/
supprimerOffre(id) { // Renommé de deleteRecruitment
axios.delete(`/api/admin/recrutement/retirer/${id}`) // Nouvelle route d'API
.then(response => {
this.$message.success("Offre supprimée avec succès!"); // Affichage de succès avec Element UI
this.chargerOffresEmploi(); // Recharger la liste après suppression
})
.catch(error => {
console.error("Erreur lors de la suppression de l'offre:", error);
this.$message.error("Échec de la suppression de l'offre.");
});
}
},
mounted() { // Utilisation de mounted au lieu de created pour des appels de données
this.chargerOffresEmploi();
}
};
</script>
<style scoped>
h2 {
color: #333;
margin-bottom: 20px;
}
</style>