Communitygithub.com

pharder56k/quote-generator-skill

Compétence de devis d'intérieur : Tableau Feishu/Excel → Devis PDF professionnel. MIT.

Qu'est-ce que quote-generator-skill ?

Cette compétence permet de transformer des données de liste de quantités (depuis un tableau Feishu ou un fichier Excel) en un devis PDF professionnel. Elle prend en charge la génération multi-pages incluant une page de couverture, un tableau récapitulatif des coûts et des pages de détails. Utile pour les designers d'intérieur, les architectes et les entrepreneurs, elle automatise le processus de création de devis, réduit les erreurs et garantit une présentation cohérente. Elle exige des prérequis tels que l'outil en ligne de commande `lark-cli` pour l'accès aux données Feishu, un environnement Node.js (≥ 18) et Playwright pour le rendu PDF. Le processus comprend la validation des données, le traitement du logo, la confirmation du taux de TVA, la sélection du modèle et l'exportation du PDF final, qui peut être envoyé dans une conversation Feishu ou sauvegardé sur le cloud. Elle fonctionne sur les plateformes Feishu et les environnements de bureau prenant en charge Node.js.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add pharder56k/quote-generator-skill

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Système de devis de conception complète

Cette compétence transforme les données de la liste de quantités en un devis PDF professionnel, avec prise en charge de la page de couverture, du tableau récapitulatif des coûts et de plusieurs pages de détails.

1. Quand utiliser cette compétence

Conditions de déclenchement

Les scénarios suivants doivent utiliser cette compétence :

  • L'utilisateur saisit /quote — Générer un devis PDF
  • L'utilisateur mentionne vouloir convertir des données de devis d'un tableau Feishu ou d'Excel en devis PDF

Les scénarios suivants ne doivent pas utiliser cette compétence :

  • L'utilisateur modifie simplement les données d'un tableau Feishu (utiliser la compétence lark-base)
  • L'utilisateur consulte simplement l'historique des devis (pas besoin de regénérer)

Dépendances préalables

  • Compétence lark-base — Lire les données du tableau Feishu
  • Compétence lark-im — Envoyer le PDF dans la conversation Feishu
  • Compétence lark-drive — Télécharger le PDF vers les documents Feishu
  • Compétence xlsx — Analyser les fichiers Excel (lorsque l'utilisateur fournit un fichier Excel)
  • Environnement d'exécution Node.js + Playwright (déjà installé dans le répertoire du projet)

Étape 0 : Vérification initiale

Lorsque l'utilisateur utilise la compétence pour la première fois, ou lorsqu'il rencontre des erreurs liées aux dépendances lors de l'exécution de commandes, l'agent doit exécuter le processus de vérification suivant.

1. Vérifier l'environnement Node.js

Exécuter node --version. Exiger >= 18. En cas d'échec ou de version trop ancienne :

  • Demander à l'utilisateur d'installer Node.js (>= 18) : https://nodejs.org
  • Suggérer d'utiliser nvm pour gérer les versions

2. Vérifier le navigateur Playwright

Vérifier si npx playwright install chromium a été exécuté dans le répertoire du projet. Si l'exécution de render.js génère une erreur Executable doesn't exist :

  • Exécuter dans le répertoire du projet : npx playwright install chromium
  • Réessayer le rendu

3. Vérifier lark-cli

Exécuter lark-cli --version. En cas d'échec (command not found) :

  • Demander à l'utilisateur d'installer lark-cli (outil en ligne de commande Feishu)
  • Après l'installation, exécuter : lark-cli auth login

4. Vérifier l'état de connexion à Feishu

Exécuter lark-cli base +table-list --base-token LfjJbLrTHacijesHmIjcDtSpnJf pour tester l'état de connexion. Si une erreur d'authentification est renvoyée :

  • Demander à l'utilisateur d'exécuter : lark-cli auth login
  • Réessayer après

5. Fournir le modèle Feishu

L'utilisateur doit copier le modèle de projet dans son propre espace Feishu :

Traitement des données Excel

Lorsque l'utilisateur fournit un fichier Excel, ne pas l'analyser et le rendre directement. Processus guidé :

  1. Suggérer : Il est recommandé d'importer d'abord dans un tableau Feishu, les champs et l'ordre sont mieux alignés
  2. Guider l'utilisateur pour importer Excel dans Feishu :
    • Ouvrir Feishu → Créer un nouveau tableau → Importer → Sélectionner le fichier Excel
    • Ou copier directement le modèle de tableau, coller les données Excel dedans
  3. Une fois que l'utilisateur a fourni le lien du tableau, continuer le processus /quote

2. Flux de travail

Déclenchement utilisateur → Vérification de l'environnement → Confirmation de la source de données → Lecture des données → Validation des données → Confirmation du logo → Confirmation du taux de TVA → Confirmation du modèle → Rendu PDF → Envoi Feishu

Étape 1 : Confirmer la source de données

L'utilisateur doit fournir l'un des éléments suivants :

  1. Lien du tableau Feishu — Comme https://xxx.feishu.cn/base/XXX
  2. Fichier Excel — Chemin de fichier local ou téléchargé via la conversation

Si l'utilisateur n'a pas fourni, lui demander de choisir une source de données.

Étape 2 : Lire les données

Source de données : tableau Feishu

  1. Extraire le base-token du lien fourni par l'utilisateur (la partie après /base/ dans l'URL)
  2. Lister les tableaux : lark-cli base +table-list --base-token <token>
  3. Trouver les table_id des tableaux Informations du projet et Détails du devis
  4. Lire les informations du projet : lark-cli base +record-list --base-token <token> --table-id <id_table_projet> --format json
  5. D'abord interroger les vues : lark-cli base +view-list --base-token <token> --table-id <id_table_details> , prendre le view_id de la vue grid par défaut (comme « Tous les éléments »)
  6. Lire les détails du devis (doit inclure --view-id, sinon l'ordre de retour ne correspond pas à l'ordre glissé-déposé par l'utilisateur dans l'interface Feishu) : lark-cli base +record-list --base-token <token> --table-id <id_table_details> --view-id <ID_vue> --format json --limit 200
  7. Extraire des informations du projet : nom du projet, numéro de projet, date de préparation, préparateur, email de contact, logo de l'entreprise, taux de TVA, frais de gestion
  8. Extraire des détails du devis : zone, classification des travaux, nom du projet, caractéristiques du projet, unité, quantité, prix unitaire, montant total, remarques (le numéro de série n'a pas besoin d'être lu, il est généré automatiquement lors du rendu)

Source de données : Excel

Utiliser la compétence xlsx pour analyser Excel et extraire des données de même structure. Excel peut avoir plusieurs feuilles, il faut trouver celle qui contient les détails du devis (généralement avec des en-têtes de colonne comme « Numéro de série », « Classification des travaux », « Prix unitaire », etc.).

Étape 3 : Valider les données

Avant de rendre le PDF, l'agent doit valider les données lues. Ne pas sauter cette étape.

Liste de vérification (à exécuter point par point) :

3.1 Intégrité des informations du projet

Vérifier les trois champs Nom du projet, Numéro de projet, Date de préparation :

  • Si l'un est vide → Informer l'utilisateur du champ manquant et lui demander de le compléter dans le tableau « Informations du projet » de Feishu
  • Si tous sont OK → Continuer

3.2 Nombre d'entrées dans les détails du devis

Vérifier le tableau items :

  • Si 0 ou inexistant → "Aucune donnée dans les détails du devis. Veuillez ajouter des entrées dans le tableau « Détails du devis » de Feishu et réessayer."
  • Si des données existent → Continuer

3.3 Vérification champ par champ

Pour chaque enregistrement, vérifier les champs obligatoires (classification des travaux, nom du projet, unité, quantité, prix unitaire) et générer un rapport récapitulatif :

Résultat de la validation des données :
- Nombre total d'entrées : 104
- Zone manquante : 3 (entrées 6, 9, 20)
- Classification des travaux manquante : 2 (entrées 5, 18)
- Nom du projet manquant : 0
- Unité manquante : 1 (entrée 12)
- Quantité manquante : 0
- Prix unitaire manquant : 3 (entrées 5, 7, 22)
- Classification des travaux absente de la liste standard : 0

3.4 Gestion des champs manquants

  • Entrées manquantes ≤ 20 % du total : Informer l'utilisateur des entrées problématiques et demander "Sauter ces entrées et continuer la génération ?"
  • Entrées manquantes > 20 % : Demander à l'utilisateur de corriger les données et réessayer, ne pas continuer le rendu
  • L'utilisateur confirme le saut → Filtrer les entrées problématiques et continuer avec les données valides

3.7 Vérification de la zone manquante (uniquement lors du classement par zone)

Lorsque l'utilisateur choisit de classer par zone (étape 5.6, sélectionner "Par zone"), vérifier en plus le champ Zone pour chaque enregistrement :

Zone manquante : X (entrée X)
  • Entrées manquantes ≤ 20 % du total : Informer l'utilisateur des entrées sans zone et demander "Classer ces entrées dans « Autres » et continuer la génération ?"
  • Entrées manquantes > 20 % : Demander à l'utilisateur de compléter les zones et réessayer
  • L'utilisateur confirme → Les entrées sans zone sont classées dans le groupe "Autres" (mutuellement exclusif avec la logique de saut de l'étape 3.4, l'utilisateur choisit entre les deux : sauter ou classer dans Autres)

3.5 Correction automatique du montant total

Pour chaque enregistrement, vérifier si le Montant total est égal à Quantité × Prix unitaire :

  • Écart < 1 yuan → Ne pas traiter
  • Écart ≥ 1 yuan ou vide → Calculer automatiquement Montant total = Quantité × Prix unitaire, écrire la valeur dans les données de rendu
  • Si le nombre d'entrées corrigées dépasse 10 % → Informer l'utilisateur "X entrées de montant total ont été automatiquement corrigées" et suggérer de vérifier la formule dans le tableau Feishu

3.6 Liste standard des classifications de travaux

Voici les 13 classifications standard :

Mesures de projet, Travaux de démolition, Travaux de maçonnerie, Travaux de béton armé,
Travaux de charpente métallique, Travaux d'étanchéité, Travaux d'isolation thermique, Travaux de revêtement de sol,
Travaux de revêtement mural et de cloisons, Travaux de plafond, Travaux de peinture et de revêtement,
Autres travaux de finition, Travaux d'installation

Les classifications qui ne figurent pas dans la liste peuvent toujours être rendues, mais informer l'utilisateur "La classification 'XXX' ne fait pas partie de la liste standard."

Étape 4 : Traitement du logo

Doit être exécuté, ne peut pas être sauté. Que la source de données soit un tableau Feishu ou Excel, le logo doit être vérifié et traité.

  1. Lire depuis le tableau : Vérifier le champ de pièce jointe Logo de l'entreprise dans le tableau des informations du projet
    • S'il y a une pièce jointe, utiliser l'API media pour télécharger (drive +download ne prend pas en charge les pièces jointes de tableau) :
      lark-cli api GET /open-apis/drive/v1/medias/{file_token}/download --output ./logo.png
      
    • Convertir l'image en URI de données base64 et l'assigner au champ logo_url des données de rendu
  2. Lire depuis Excel : Vérifier s'il y a une image de logo dans Excel (généralement intégrée dans une feuille ou comme pièce jointe)
    • Si oui, l'extraire et la convertir en URI de données
  3. Logo manquant (doit demander à l'utilisateur) :
    • Si aucun logo n'est trouvé dans la source de données, doit demander à l'utilisateur :
      • "Aucun logo d'entreprise trouvé dans la source de données. Comment souhaitez-vous procéder ?"
      • Option A : Télécharger une image de logo
      • Option B : Fournir une URL d'image de logo
      • Option C : Ne pas utiliser de logo (afficher l'identifiant textuel par défaut « R M » dans le PDF)
    • Ne pas sauter cette étape par défaut, même si l'utilisateur dit "générer directement", confirmer la méthode de traitement du logo

Étape 5 : Confirmer le taux de TVA et les frais de gestion

Prioriser l'utilisation des valeurs des champs Taux de TVA, Frais de gestion dans le tableau des informations du projet. Si le tableau Feishu ne contient pas ces champs, demander à l'utilisateur.

Règles de taux (applicables au taux de TVA et aux frais de gestion) :

  • Valeur > 1 → Considéré comme un pourcentage entier, ÷100 automatique (ex : 3 → 3%, 10 → 10%)
  • Valeur ≤ 1 → Considéré comme un nombre décimal à utiliser directement (ex : 0.03 → 3%, 0.1 → 10%)
  • Valeur vide : Taux de TVA par défaut 3%, Frais de gestion par défaut 0 (non facturés)

Ordre de calcul :

Total = Σ Montant total de chaque entrée
Frais de gestion = Total × Taux de frais de gestion
TVA = (Total + Frais de gestion) × Taux de TVA
Total général = Total + Frais de gestion + TVA

Si les frais de gestion > 0, le tableau récapitulatif des coûts affiche la ligne « Frais de gestion » ; si les frais de gestion = 0, ne pas afficher (compatible avec les anciennes données).

Étape 5.5 : Confirmer le style de modèle

Doit demander, ne peut pas être sauté. Même si un modèle a été utilisé précédemment, confirmer à chaque fois.

Demander à l'utilisateur de choisir un modèle :

Veuillez choisir le style de votre devis :
1. Swiss IKB (par défaut) — Couverture pleine page fond bleu + titres de catégorie bilingues
2. Swiss IKB Zebra — Idem + lignes de détail en rayures zébrées (blanc/bleu clair alternés)
3. B&W — Couverture fond blanc + accents gris clair, idéal pour l'impression noir et blanc
4. B&W Zebra — Idem + lignes de détail en rayures zébrées (blanc/gris clair alternés)

Si la réponse de l'utilisateur contient un nom ou un numéro de modèle explicite, utiliser le modèle correspondant :

  • swiss-ikb — Swiss IKB (par défaut)
  • swiss-ikb-zebra — Swiss IKB Zebra
  • bw — B&W version impression noir et blanc
  • bw-zebra — B&W Zebra version impression noir et blanc rayures zébrées

En développement (pas encore accessible au public) : Les codes des quatre modèles Editorial / Editorial B&W / Card / Card B&W existent déjà. Ils seront activés après des modifications et améliorations ultérieures. Si l'utilisateur demande activement à utiliser ces modèles, il peut exécuter la commande node scripts/render.js --template editorial, etc., mais il est recommandé de prioriser les 4 modèles en ligne ci-dessus.

Étape 5.6 : Confirmer la méthode de classement

Doit demander, ne peut pas être sauté. Confirmer avant chaque rendu, ne pas utiliser l'option précédente par défaut.

Demander à l'utilisateur de choisir la méthode de classement :

Veuillez choisir la méthode de classement du devis :
1. Par zone (Entrée, Salon, Chambre principale...) — Le tableau récapitulatif regroupe par zone, le tableau de détail ajoute une colonne de classification des travaux après le numéro de série
2. Par classification des travaux (Mesures de projet, Travaux de démolition...) — Méthode traditionnelle, le tableau de détail n'inclut pas la colonne de classification des travaux

Après que l'utilisateur a fourni un numéro ou un nom explicite, utiliser le mode correspondant :

  • area — Classement par zone, ajouter --group-by area à la commande de rendu
  • category — Classement par classification des travaux (par défaut), ne pas transmettre ou ajouter --group-by category

Remarque : Si vous choisissez "Par zone", assurez-vous que le champ Zone du tableau des détails du devis est rempli (l'étape 3.7 le vérifiera). Si les données n'ont pas encore de zone, il est recommandé d'utiliser d'abord "Par classification des travaux".

Étape 5.7 : Traduction en anglais des noms de zones (uniquement lors du classement par zone)

Les noms de zones varient d'un projet à l'autre. Doit être traduit dynamiquement avant chaque rendu, l'utilisation d'une correspondance codée en dur est interdite.

  1. Collecter tous les noms de zones apparaissant dans ce rendu à partir des détails du devis (déduplication)
  2. L'agent traduit les noms de zones un par un en anglais (traductions courantes dans le secteur du design, ex : 玄关 → Foyer, 客厅 → Living Room, 阳光房 → Sunroom)
  3. Écrire le résultat de la traduction en tant qu'objet region_names dans le JSON des données de rendu :
{
  "region_names": {
    "玄关": "Foyer",
    "阳光房": "Sunroom"
  }
}
  1. Lors du rendu, render.js utilise en priorité les traductions de region_names (les noms de zones non fournis reviennent à la correspondance intégrée des zones courantes, puis affichent AREA par défaut)
  2. Une fois le rendu terminé, lister la table de correspondance des traductions de zones dans le rapport, l'utilisateur peut les corriger, et la traduction sera refaite pour le prochain devis

Étape 6 : Rendu PDF

Exécuter dans le répertoire du projet :

node scripts/render.js --input <data.json> --template <nom_modèle> --vat-rate <taux_tva> --group-by <area|category> --output ./output/<nom_projet>_<numéro_projet>.pdf
  • --group-by area — Classement par zone (grande catégorie = zone, les détails incluent une colonne de classification des travaux)
  • --group-by category ou non transmis — Classement par classification des travaux (comportement d'origine)

Format JSON des données de rendu :

{
  "nom_projet": "xxx",
  "numéro_projet": "xxx",
  "date_préparation": "xxx",
  "préparateur": "xxx",
  "email_contact": "xxx",
  "logo_url": "data:image/png;base64,...",
  "taux_tva": 0.08,
  "frais_gestion": 0.1,
  "items": [
    {
      "zone": "Entrée",
      "classification_travaux": "Mesures de projet",
      "nom_projet": "Échafaudage",
      "caractéristiques_projet": "Échafaudage intérieur",
      "unité": "Poste",
      "quantité": 1,
      "prix_unitaire": 3200,
      "montant_total": 3200
    }
  ]
}

Règle de génération automatique du numéro de série : Le champ numéro_série n'a pas besoin d'être fourni dans les données (la colonne peut ne pas être créée dans le tableau Feishu). Lors du rendu, il est généré automatiquement sous la forme numéro_groupe.numéro_dans_groupe : En mode classement par zone, zone 01 → 1.1, 1.2, …, zone 02 → 2.1, 2.2, … ; En mode classement par classification des travaux, Mesures de projet → 1.x, Travaux de démolition → 2.x… Travaux d'installation → 13.x. L'ordre dans le groupe = ordre des enregistrements Feishu (les enregistrements peuvent être glissés et déposés dans le tableau Feishu).

Taux de TVA et frais de gestion (voir Étape 5 pour plus de détails) :

  • Valeur taux_tva / frais_gestion > 1 considéré comme un pourcentage entier (3 → 3%), ≤ 1 considéré comme un nombre décimal (0.08 → 8%)
  • Frais de gestion = Total × Taux de frais de gestion ; TVA = (Total + Frais de gestion) × Taux de TVA ; Total général = Total + Frais de gestion + TVA
  • Si les frais de gestion ne sont pas fournis ou sont 0 → Non facturés, le tableau récapitulatif des coûts n'affiche pas la ligne des frais de gestion
  • Si le paramètre --vat-rate n'est pas fourni, render.js lit d'abord le champ taux_tva dans les données

Étape 7 : Sauvegarde et envoi

Une fois le rendu PDF terminé, doit demander à l'utilisateur de choisir la méthode de sauvegarde :

PDF généré : <nom_projet>_<numéro_projet>_<nom_modèle>.pdf (XX entrées, ¥XXX TTC)

Comment souhaitez-vous le sauvegarder ?
1. Envoyer dans la fenêtre de chat actuelle
2. Sauvegarder dans les documents cloud Feishu, envoyer le lien du document
3. Les deux

Exécuter selon le choix de l'utilisateur :

Option 1 — Envoyer dans la fenêtre de chat

lark-cli im +messages-send --type media --file <chemin_du_pdf>

Option 2 — Sauvegarder dans les documents cloud Feishu

lark-cli drive +upload --file <chemin_du_pdf> --title "<nom_projet>_<numéro_projet>"

Obtenir le lien du fichier téléchargé et répondre à l'utilisateur :

Sauvegardé dans les documents cloud Feishu : <nom_projet>_<numéro_projet>_<nom_modèle>.pdf
Lien du document : https://xxx.feishu.cn/drive/xxx

Option 3 — Les deux

Exécuter d'abord l'option 2 (téléchargement), puis l'option 1 (envoi du fichier + lien).

Nettoyage des fichiers temporaires

Une fois l'envoi/la sauvegarde terminée, supprimer les fichiers JSON temporaires et les fichiers de téléchargement du logo (le cas échéant) générés pendant le processus de rendu.

3. Structure du projet

quote-generator-skill/
├── package.json                # Configuration du projet
├── setup.sh                    # Script d'installation en un clic
├── SKILL.md                    # Définition de la compétence
├── scripts/
│   ├── render.js               # Moteur de rendu HTML → PDF
│   ├── demo.js                 # Démonstration prête à l'emploi
│   └── generate-large-test.js  # Générateur de données de test volumineuses
├── references/
│   ├── templates/
│   │   ├── content.html        # Modèle PDF Handlebars (page de contenu)
│   │   ├── cover-screen.html   # Modèle de couverture Swiss IKB
│   │   ├── cover-bw.html       # Modèle de couverture B&W noir et blanc
│   │   ├── swiss-ikb.json      # Configuration Swiss IKB
│   │   ├── swiss-ikb-zebra.json # Configuration Swiss IKB Zebra
│   │   ├── bw.json             # Configuration B&W noir et blanc
│   │   └── bw-zebra.json       # Configuration B&W Zebra
│   ├── helpers.js              # Helpers personnalisés Handlebars
│   └── bitable-config.json     # Configuration des champs du tableau
├── docs/plans/                 # Documents de conception
├── output/                     # Répertoire de sortie des PDF générés
└── README.md

4. Description des modèles

Les modèles PDF contiennent trois types de pages :

  1. Couverture — Nom du projet, numéro, date, préparateur, logo (coin supérieur droit)
  2. Tableau récapitulatif des coûts — Résumé des montants par classification des travaux + Total/TVA/Total général
  3. Pages de détail — Environ 8 lignes de données par page, avec titre de classification, lignes de détail, ligne de sous-total, numéro de page

5. Remarques

  • Le Montant total dans le tableau est un champ de formule (= quantité × prix unitaire), déjà calculé lors de la lecture
  • Le Numéro de série n'a pas besoin d'être géré dans Feishu : généré automatiquement lors du rendu (numéro de groupe.numéro dans le groupe, ordre dans le groupe selon l'ordre des enregistrements). Pour ajuster l'ordre des détails, glisser-déposer les enregistrements dans le tableau Feishu
  • La Classification des travaux est un champ à sélection unique, les 13 options correspondent aux 13 classifications de travaux
  • La Zone est un champ de texte libre (il est recommandé de le transformer en sélection unique dans Feishu : Entrée, Salon, Salle à manger, Cuisine, Chambre principale, Chambre secondaire, Salle de bain, Balcon, Bureau, Dressing, Couloir, Maison entière, etc.), utilisée uniquement lors du classement par zone, peut être vide
  • Les titres de groupe en mode zone affichent une correspondance chinois-anglais (ex : Living Room 客厅). Les noms de zones varient d'un projet à l'autre, l'agent traduit dynamiquement avant chaque rendu selon l'étape 5.7 et les écrit dans region_names ; la correspondance intégrée des zones courantes n'est utilisée qu'en dernier recours, affichant AREA en cas d'absence
  • L'Unité est un champ à sélection unique, prend en charge les extensions personnalisées
  • Le logo prend en charge les deux formes : image (recommandé) et texte
  • Le taux de TVA est spécifié par l'utilisateur à chaque fois, il n'est pas fixe
  • Le PDF de sortie est au format A4, adapté à l'impression

6. Gestion des problèmes courants

Erreur d'exécutionCauseMéthode de traitement de l'agent
command not found: lark-clilark-cli n'est pas installéDemander d'installer lark-cli, voir Étape 0.3
lark-cli renvoie une erreur d'authentificationNon connecté ou token expiréDemander d'exécuter lark-cli auth login
Executable doesn't existPlaywright Chromium non installéExécuter npx playwright install chromium
Le PDF rendu est vide ou a un format chaotiqueLe format JSON des données est incorrectVérifier que nom_projet, numéro_projet ne sont pas vides, items a au moins 1 entrée
Les numéros de série ne correspondent pas à ceux saisis manuellementLes numéros de série sont désormais générés automatiquementPhénomène normal : les numéros de série sont automatiquement renumérotés par groupe (ex : 01 Maison entière → 1.1, 1.2…). Pour ajuster l'ordre, glisser-déposer les enregistrements dans Feishu
Taille de police ou police d'écriture anormaleTrès rare (les polices sont intégrées en WOFF2, ne dépendent pas d'un CDN externe)Vérifier que les fichiers de polices dans le répertoire references/fonts/ du projet sont complets
Échec du téléchargement du logoProblème d'autorisation de l'API des pièces jointes du tableauConfirmer que l'utilisateur a autorisé, ou choisir "Ne pas utiliser de logo"
Impossible d'extraire base-token de l'URLL'utilisateur n'a pas fourni un lien de tableau FeishuDemander à l'utilisateur de fournir un lien de tableau Feishu (l'URL doit contenir /base/)

Skills associés