Interface Utilisateur Vue.js
Voici le composant Vue.js pour gérer le téléchargement d'images en utilisant Element UI.
<el-row>
<el-form-item label="Télécharger des fichiers" prop="fileList">
<el-upload
ref="uploader"
action="#"
list-type="picture-card"
multiple
accept="image/jpeg, image/jpg, image/png, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/pdf, application/msword"
:file-list="fichiersSelectionnes"
:auto-upload="false"
:on-change="gestionChangementFichier"
:on-remove="gestionSuppressionFichier"
:on-preview="gestionApercuFichier"
>
<i slot="default" class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogApercuVisible">
<img width="100%" :src="urlImageApercu" alt="">
</el-dialog>
</el-form-item>
</el-row>
Logique de Validation des Fichiers
La fonction suivante gère la validation de la taille des fichiers et détecte les doublons avant le télécahrgement.
verifierTailleEtDoublons(contexte, fichier, listeFichiers) {
const MAX_TAILLE_MB = 10;
const tailleMo = fichier.size / 1024 / 1024;
if (tailleMo > MAX_TAILLE_MB) {
alert(`Le fichier ${fichier.name} dépasse la limite de ${MAX_TAILLE_MB} Mo.`);
const index = contexte.fichiersSelectionnes.indexOf(fichier);
if (index > -1) {
contexte.fichiersSelectionnes.splice(index, 1);
}
contexte.fichiersSelectionnes = listeFichiers; // Met à jour l'état
return;
}
const fichiersIdentiques = listeFichiers.filter(item => item.name === fichier.name);
if (fichiersIdentiques.length > 1) {
alert(`Le fichier ${fichier.name} existe déjà.`);
const index = listeFichiers.indexOf(fichier);
if (index > -1) {
listeFichiers.splice(index, 1);
}
}
contexte.fichiersSelectionnes = listeFichiers; // Met à jour l'état
}
Méthodes Vue.js
Ces méthodes gèrent les événements de l'interface utilisateur, y compris le changement, la suppression et l'aperçu des fichiers.
gestionChangementFichier(fichier, listeFichiers) {
this.verifierTailleEtDoublons(this, fichier, listeFichiers);
},
gestionSuppressionFichier(fichier, listeFichiers) {
this.fichiersSelectionnes = listeFichiers;
if (fichier.id) {
this.$confirm('Êtes-vous sûr de vouloir supprimer ce fichier ? Cette action est irréversible.', 'Confirmation', {
confirmButtonText: 'Oui',
cancelButtonText: 'Non',
type: 'warning'
}).then(() => {
supprimerFichierServeur(fichier.id).then(reponse => {
if (reponse.code === 200) {
alert(reponse.message);
} else {
// En cas d'échec, remet le fichier dans la liste
this.fichiersSelectionnes.push(fichier);
alert(reponse.message);
}
});
}).catch(() => {
// En cas d'annulation, remet le fichier dans la liste
this.fichiersSelectionnes.push(fichier);
});
}
},
gestionApercuFichier(fichier) {
this.urlImageApercu = fichier.url;
this.dialogApercuVisible = true;
}
Sauvegarde des Données avec Fichiers
Cette méthode prépare et envoie les données du formulaire, y compris les fcihiers, au backend.
sauvegarderDonnees() {
this.$refs["formulaire"].validate((estValide) => {
if (estValide) {
const donneesFormulaire = new FormData();
this.fichiersSelectionnes.forEach(fichier => {
if (fichier.raw) { // S'assure que c'est un fichier brut
donneesFormulaire.append("fichiers", fichier.raw);
}
});
// Ajoute les autres champs du formulaire
Object.keys(this.formulaire).forEach(cle => {
if (this.formulaire[cle] !== "") {
donneesFormulaire.append(cle, this.formulaire[cle]);
}
});
if (this.formulaire.id === "") {
ajouterEntree(donneesFormulaire).then(reponse => {
if (reponse.code === 200) {
alert(reponse.message);
this.actualiserListe();
this.afficherTableau = true;
this.afficherArbre = true;
} else {
alert(reponse.message);
}
});
} else {
mettreAJourEntree(donneesFormulaire).then(reponse => {
if (reponse.code === 200) {
alert(reponse.message);
this.actualiserListe();
this.afficherTableau = true;
this.afficherArbre = true;
} else {
alert(reponse.message);
}
});
}
this.fichiersSelectionnes = []; // Réinitialise la liste des fichiers
}
});
}
Interactions avec le Backend (API)
Définitions des appels d'API pour la gestion des fichiers.
// Récupération des fichiers liés à un élément
export function recupererFichiersElement(parametres) {
return clientApi({
url: 'api/sys-attach-filepath-info/query',
method: 'get',
parametres
});
}
// Suppression d'un fichier spécifique
export function supprimerFichierServeur(id) {
return clientApi({
url: `api/sys-attach-filepath-info/${id}`,
method: 'delete'
});
}
// Ajout d'une nouvelle entrée avec fichiers
export function ajouterEntree(donnees) {
return clientApi({
url: 'api/sys-case-info/add',
method: 'post',
donnees
});
}
// Mise à jour d'une entrée existante avec fichiers
export function mettreAJourEntree(donnees) {
return clientApi({
url: 'api/sys-case-info',
method: 'put',
donnees
});
}
API Backend Spring Boot (Contrôleur)
Points d'entrée de l'API pour les opérations sur les fichiers et les entités.
@ApiOperation(value = "Récupérer des données paginées")
@ApiImplicitParams({
@ApiImplicitParam(name = "pageIndex", value = "Numéro de page"),
@ApiImplicitParam(name = "pageCount", value = "Nombre d'éléments par page"),
@ApiImplicitParam(name = "relationId", value = "ID de l'entité associée")
})
@GetMapping(value = "/query")
public Response<String> findListByPage(@RequestParam(value = "page_index", required = false) Integer pageIndex,
@RequestParam(value = "page_count") Integer pageCount,
String relationId) {
// Implémentation...
}
@ApiOperation(value = "Supprimer un fichier")
@DeleteMapping("{id}")
public Response<Integer> delete(@PathVariable("id") String id) {
int result = sysAttachFilepathInfoService.delete(id);
if (result > 0) {
return new Response<>(ErrorCode.SUCESS_CODE, "Suppression réussie", result);
} else {
return new Response<>(ErrorCode.INTERNAL, "Échec de la suppression, erreur inconnue", null);
}
}
@ApiOperation(value = "Ajouter une nouvelle entrée")
@PostMapping(value = "/add")
public Response<Integer> add(SysCaseInfo sysCaseInfo, @RequestParam("fichiers") MultipartFile[] files) {
// Implémentation...
}
@ApiOperation(value = "Mettre à jour une entrée")
@PutMapping()
public Response<Integer> update(SysCaseInfo sysCaseInfo, @RequestParam("fichiers") MultipartFile[] files) {
// Implémentation...
}
Implémentation Backend Spring Boot (Services)
Logique de gestion des fichiers et de persistance des données.
public static String telechargerFichier(MultipartFile[] fichiers, String id, String cheminBase, String nomTable) throws Exception {
StringBuilder cheminsFichiers = new StringBuilder();
if (fichiers != null && fichiers.length > 0) {
File repertoireCible = new File(cheminBase + nomTable);
if (!repertoireCible.exists()) {
repertoireCible.mkdirs();
}
for (int i = 0; i < fichiers.length; i++) {
String nomOriginal = fichiers[i].getOriginalFilename();
String extension = nomOriginal.substring(nomOriginal.lastIndexOf("."));
String nomFichierUnique = nomTable + "/" + id + "_" + System.currentTimeMillis() + extension;
File fichierDestination = new File(cheminBase + nomFichierUnique);
// Supprime le fichier existant s'il y en a un avant d'écrire
if (fichierDestination.exists() && !fichierDestination.delete()) {
throw new IOException("Erreur lors de la suppression du fichier existant : " + cheminBase + nomFichierUnique);
}
Path cheminDestination = Paths.get(cheminBase + nomFichierUnique);
Files.write(cheminDestination, fichiers[i].getBytes());
if (cheminsFichiers.length() > 0) {
cheminsFichiers.append(",");
}
cheminsFichiers.append(nomFichierUnique);
}
}
return cheminsFichiers.toString();
}
public void ajouterFichiersAssocies(MultipartFile[] fichiers, String idEntite, String nomTable) {
List<SysAttachFilepathInfo> listeInfosFichiers = new ArrayList<>();
if (fichiers != null && fichiers.length > 0) {
String cheminServeurFichiers = fileConfig.getFileServer();
try {
String cheminsConcaténés = telechargerFichier(fichiers, idEntite, cheminServeurFichiers, nomTable);
String[] cheminsIndividuels = cheminsConcaténés.split(",");
for (String chemin : cheminsIndividuels) {
SysAttachFilepathInfo info = new SysAttachFilepathInfo();
info.setId(SnowIdUtil.getId()); // Génération d'ID unique
info.setRelationId(idEntite);
info.setRelationTable(nomTable);
info.setFilePath(chemin);
listeInfosFichiers.add(info);
}
if (!CollectionUtils.isEmpty(listeInfosFichiers)) {
sysAttachFilepathInfoMapper.batchInsert(listeInfosFichiers);
}
} catch (IOException e) {
// Gérer l'exception, par exemple logger ou lancer une exception personnalisée
e.printStackTrace();
} catch (Exception e) {
// Gérer d'autres exceptions potentielles
e.printStackTrace();
}
}
}
Configuration XML MyBatis
Instructions pour les opérations de base de données en masse.
<!-- Insertion groupée -->
<insert id="batchInsert" parameterType="com.hengan.involved.entity.SysAttachFilepathInfo">
INSERT INTO sys_attach_filepath_info (id, relation_table, relation_id, file_path) values
<foreach collection="list" item="item" separator=",">
(#{item.id}, #{item.relationTable}, #{item.relationId}, #{item.filePath})
</foreach>
</insert>
<!-- Mise à jour groupée (exemple simple) -->
<update id="batchUpdate" parameterType="java.util.List">
<foreach collection="list" item="item" index="index" separator=";">
UPDATE show_overview set item_num = #{item.itemNum} WHERE id=#{item.id}
</foreach>
</update>