01MVP 标识01MVP
包文档认证与配置config 配置

config 配置

共享配置数据和常量,提供图片模板等应用级配置

本页面介绍应用配置数据 API。环境变量配置请参考 开发指南

概述

@mono/config 是项目的配置包,提供应用程序级别的配置数据和常量。目前主要包含图片模板配置,用于活动封面图等场景。

核心功能

图片模板系统

提供预定义的图片模板,支持按类别分类和智能推荐。

获取推荐模板

import { getRecommendedTemplates } from "@mono/config";

// 根据活动类型获取推荐模板
const templates = getRecommendedTemplates("hackathon");

获取随机模板

import { getRandomTemplate } from "@mono/config";

// 获取随机模板作为默认封面
const template = getRandomTemplate("meetup");
console.log(template.url); // 图片 URL

按类别浏览

import {
  getTemplateCategories,
  getTemplatesByCategory,
} from "@mono/config";

// 获取所有类别
const categories = getTemplateCategories();
// ["tech", "gradient"]

// 获取特定类别的模板
const techTemplates = getTemplatesByCategory("tech");

实战示例

示例 1:活动创建表单

import { getRecommendedTemplates } from "@mono/config";
import { useState } from "react";

export function EventCreateForm() {
  const [eventType, setEventType] = useState("hackathon");
  const [selectedTemplate, setSelectedTemplate] = useState("");

  // 根据活动类型获取推荐模板
  const templates = getRecommendedTemplates(eventType);

  return (
    <form>
      <select
        value={eventType}
        onChange={(e) => setEventType(e.target.value)}
      >
        <option value="hackathon">Hackathon</option>
        <option value="meetup">Meetup</option>
      </select>

      <div className="grid grid-cols-3 gap-4">
        {templates.map((template) => (
          <button
            key={template.id}
            type="button"
            onClick={() => setSelectedTemplate(template.url)}
            className={
              selectedTemplate === template.url
                ? "ring-2 ring-primary"
                : ""
            }
          >
            <img
              src={template.url}
              alt={template.name}
              className="w-full h-32 object-cover rounded"
            />
            <p className="text-sm mt-2">{template.name}</p>
          </button>
        ))}
      </div>
    </form>
  );
}

示例 2:服务端默认封面

import { getRandomTemplate } from "@mono/config";

export async function POST(request: Request) {
  const data = await request.json();

  // 如果用户没有选择封面,使用随机模板
  if (!data.coverImage) {
    const template = getRandomTemplate(data.eventType);
    data.coverImage = template.url;
  }

  const event = await db.event.create({ data });
  return Response.json(event);
}

示例 3:模板选择器组件

import {
  getTemplateCategories,
  getTemplatesByCategory,
  type ImageTemplate,
} from "@mono/config";
import { useState } from "react";

interface TemplateSelectorProps {
  onSelect: (template: ImageTemplate) => void;
}

export function TemplateSelector({ onSelect }: TemplateSelectorProps) {
  const categories = getTemplateCategories();
  const [activeCategory, setActiveCategory] = useState(categories[0]);
  const templates = getTemplatesByCategory(activeCategory);

  return (
    <div>
      {/* 类别标签 */}
      <div className="flex gap-2 mb-4">
        {categories.map((category) => (
          <button
            key={category}
            onClick={() => setActiveCategory(category)}
            className={
              activeCategory === category
                ? "bg-primary text-white"
                : "bg-gray-100"
            }
          >
            {category}
          </button>
        ))}
      </div>

      {/* 模板网格 */}
      <div className="grid grid-cols-3 gap-4">
        {templates.map((template) => (
          <div
            key={template.id}
            onClick={() => onSelect(template)}
            className="cursor-pointer hover:opacity-80"
          >
            <img
              src={template.url}
              alt={template.name}
              className="w-full h-32 object-cover rounded"
            />
            <p className="text-sm mt-1">{template.name}</p>
            {template.description && (
              <p className="text-xs text-gray-500">
                {template.description}
              </p>
            )}
          </div>
        ))}
      </div>
    </div>
  );
}

API 参考

类型

interface ImageTemplate {
  id: string;           // 唯一标识
  name: string;         // 模板名称
  url: string;          // 图片 URL
  category: string;     // 类别
  description?: string; // 描述
}

常量

  • IMAGE_TEMPLATES - 所有模板数组
  • EVENT_TYPE_TO_TEMPLATE_CATEGORY - 活动类型到类别的映射

函数

  • getRecommendedTemplates(eventType?) - 获取推荐模板
  • getRandomTemplate(eventType?) - 获取随机模板
  • getTemplateCategories() - 获取所有类别
  • getTemplatesByCategory(category) - 获取指定类别的模板

扩展配置

添加新模板

编辑 packages/config/src/image-templates.ts

export const IMAGE_TEMPLATES: ImageTemplate[] = [
  // ... 现有模板
  {
    id: "custom-1",
    name: "自定义模板",
    url: "https://example.com/image.jpg",
    category: "custom",
    description: "自定义模板描述",
  },
];

添加活动类型映射

export const EVENT_TYPE_TO_TEMPLATE_CATEGORY: Record<string, string> = {
  meetup: "gradient",
  hackathon: "gradient",
  workshop: "tech",      // 新增
  conference: "gradient", // 新增
};

最佳实践

  1. 使用类型定义 - 导入 ImageTemplate 类型确保类型安全
  2. 缓存模板数据 - 模板数据是静态的,可以安全缓存
  3. 图片优化 - 使用 Next.js Image 组件优化图片加载
  4. 错误处理 - 为 getRandomTemplate 提供备用方案

完整的 API 文档请参考 README.md