文档

模板系统 API

SmartCV 模板系统 API 文档,包含模板管理、自定义样式等功能

更新时间: 2024/12/30

SmartCV 模板系统提供丰富的简历模板和自定义功能,支持模板查询、应用、自定义样式等操作。

📋 API 端点概览

端点方法描述
/api/templatesGET获取模板列表
/api/templates/[id]GET获取模板详情
/api/templatesPOST创建新模板(管理员)
/api/templates/[id]PUT更新模板(管理员)
/api/templates/[id]DELETE删除模板(管理员)

🔍 获取模板列表

端点: GET /api/templates

描述: 获取可用的简历模板列表

认证: 可选(影响付费模板可见性)

查询参数:

  • category (可选): 模板分类 (MODERN, PROFESSIONAL, CREATIVE, MINIMALIST, ACADEMIC)
  • isPremium (可选): 是否为付费模板 (true, false)
  • limit (可选): 返回数量限制,默认为 20
  • offset (可选): 偏移量,默认为 0

响应:

{
  "success": true,
  "data": [
    {
      "id": "template_123",
      "name": "现代简约",
      "description": "简洁现代的设计风格,适合大多数行业",
      "category": "MODERN",
      "previewUrl": "https://storage.smartcv.cc/templates/modern-preview.jpg",
      "thumbnailUrl": "https://storage.smartcv.cc/templates/modern-thumb.jpg",
      "isPremium": false,
      "usageCount": 1500,
      "ratingAvg": 4.5,
      "ratingCount": 120,
      "createdAt": "2024-01-15T10:00:00Z"
    },
    {
      "id": "template_456",
      "name": "专业商务",
      "description": "正式的商务风格,适合传统行业和高级职位",
      "category": "PROFESSIONAL",
      "previewUrl": "https://storage.smartcv.cc/templates/professional-preview.jpg",
      "thumbnailUrl": "https://storage.smartcv.cc/templates/professional-thumb.jpg",
      "isPremium": true,
      "usageCount": 800,
      "ratingAvg": 4.8,
      "ratingCount": 95,
      "createdAt": "2024-01-20T10:00:00Z"
    }
  ],
  "meta": {
    "total": 25,
    "limit": 20,
    "offset": 0,
    "userSubscriptionType": "FREE"
  }
}

📄 获取模板详情

端点: GET /api/templates/[id]

描述: 获取指定模板的详细信息,包含完整的HTML模板和CSS样式

认证: 可选(影响付费模板访问)

路径参数:

  • id: 模板 ID

响应:

{
  "success": true,
  "data": {
    "id": "template_123",
    "name": "现代简约",
    "description": "简洁现代的设计风格,适合大多数行业",
    "category": "MODERN",
    "htmlTemplate": "<!DOCTYPE html><html>...</html>",
    "cssStyles": ".resume { font-family: 'Arial', sans-serif; ... }",
    "previewUrl": "https://storage.smartcv.cc/templates/modern-preview.jpg",
    "thumbnailUrl": "https://storage.smartcv.cc/templates/modern-thumb.jpg",
    "isPremium": false,
    "customizableColors": true,
    "customizableFonts": true,
    "customizableSpacing": true,
    "usageCount": 1500,
    "ratingAvg": 4.5,
    "ratingCount": 120,
    "supportedSections": [
      "personalInfo",
      "workExperience",
      "education",
      "skills",
      "projects",
      "languages",
      "certifications"
    ],
    "colorSchemes": [
      {
        "name": "默认蓝色",
        "primary": "#2563eb",
        "secondary": "#64748b",
        "accent": "#0ea5e9"
      },
      {
        "name": "专业绿色",
        "primary": "#059669",
        "secondary": "#6b7280",
        "accent": "#10b981"
      }
    ],
    "fontOptions": [
      {
        "name": "Roboto",
        "family": "'Roboto', sans-serif",
        "weights": ["300", "400", "500", "700"]
      },
      {
        "name": "Open Sans",
        "family": "'Open Sans', sans-serif",
        "weights": ["400", "600", "700"]
      }
    ],
    "createdAt": "2024-01-15T10:00:00Z",
    "updatedAt": "2024-12-30T10:00:00Z"
  }
}

➕ 创建模板(管理员)

端点: POST /api/templates

描述: 创建新的简历模板(仅管理员可用)

认证: 需要管理员权限

请求体:

{
  "name": "新模板名称",
  "description": "模板描述",
  "category": "MODERN",
  "htmlTemplate": "<!DOCTYPE html><html>...</html>",
  "cssStyles": ".resume { ... }",
  "previewUrl": "https://storage.smartcv.cc/templates/new-preview.jpg",
  "thumbnailUrl": "https://storage.smartcv.cc/templates/new-thumb.jpg",
  "isPremium": false,
  "customizableColors": true,
  "customizableFonts": true,
  "customizableSpacing": true,
  "supportedSections": ["personalInfo", "workExperience", "education", "skills"],
  "colorSchemes": [
    {
      "name": "默认",
      "primary": "#2563eb",
      "secondary": "#64748b",
      "accent": "#0ea5e9"
    }
  ],
  "fontOptions": [
    {
      "name": "Roboto",
      "family": "'Roboto', sans-serif",
      "weights": ["400", "700"]
    }
  ]
}

响应:

{
  "success": true,
  "data": {
    "id": "template_789"
    /* 创建的模板完整信息 */
  }
}

✏️ 更新模板(管理员)

端点: PUT /api/templates/[id]

描述: 更新现有模板(仅管理员可用)

认证: 需要管理员权限

路径参数:

  • id: 模板 ID

请求体:

{
  "name": "更新的模板名称",
  "description": "更新的描述",
  "htmlTemplate": "<!DOCTYPE html><html>...</html>",
  "cssStyles": ".resume { ... }",
  "isPremium": true,
  "isActive": true
}

响应:

{
  "success": true,
  "data": {
    /* 更新后的模板信息 */
  }
}

🗑️ 删除模板(管理员)

端点: DELETE /api/templates/[id]

描述: 删除指定模板(仅管理员可用)

认证: 需要管理员权限

路径参数:

  • id: 模板 ID

响应:

{
  "success": true,
  "message": "模板删除成功"
}

🎨 模板分类

支持的模板分类

分类描述适用场景
MODERN现代简约科技、互联网、创新行业
PROFESSIONAL专业商务传统行业、管理职位
CREATIVE创意设计设计师、艺术家、创意工作
MINIMALIST极简风格注重内容的职位
ACADEMIC学术风格学术界、研究职位

模板自定义选项

  • 颜色自定义: 支持主色调、辅助色、强调色的自定义
  • 字体自定义: 提供多种字体选择和字重配置
  • 间距自定义: 调整页面边距、行间距、段落间距
  • 布局调整: 支持单栏、双栏布局切换

📝 使用示例

JavaScript 示例

// 获取所有模板
async function getAllTemplates() {
  const response = await fetch('/api/templates')
  const data = await response.json()
  return data.data
}
 
// 获取特定分类的模板
async function getTemplatesByCategory(category) {
  const response = await fetch(`/api/templates?category=${category}`)
  const data = await response.json()
  return data.data
}
 
// 获取模板详情
async function getTemplateDetail(templateId) {
  const response = await fetch(`/api/templates/${templateId}`)
  const data = await response.json()
 
  if (data.success) {
    return data.data
  } else {
    throw new Error(data.error)
  }
}
 
// 应用模板到简历
async function applyTemplateToResume(resumeId, templateId) {
  const response = await fetch(`/api/resumes/${resumeId}`, {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json'
    },
    credentials: 'include',
    body: JSON.stringify({
      templateId: templateId
    })
  })
 
  return response.json()
}

React Hook 示例

import { useState, useEffect } from 'react'
 
function useTemplates(category = null, isPremium = null) {
  const [templates, setTemplates] = useState([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(null)
 
  useEffect(() => {
    fetchTemplates()
  }, [category, isPremium])
 
  const fetchTemplates = async () => {
    try {
      setLoading(true)
 
      const params = new URLSearchParams()
      if (category) params.append('category', category)
      if (isPremium !== null) params.append('isPremium', isPremium)
 
      const response = await fetch(`/api/templates?${params}`)
      const data = await response.json()
 
      if (data.success) {
        setTemplates(data.data)
      } else {
        setError(data.error)
      }
    } catch (err) {
      setError('获取模板失败')
    } finally {
      setLoading(false)
    }
  }
 
  return {
    templates,
    loading,
    error,
    refetch: fetchTemplates
  }
}
 
// 模板预览组件
function TemplatePreview({ template, onApply }) {
  const [previewLoading, setPreviewLoading] = useState(false)
 
  const handleApply = async () => {
    setPreviewLoading(true)
    try {
      await onApply(template.id)
    } catch (error) {
      console.error('应用模板失败:', error)
    } finally {
      setPreviewLoading(false)
    }
  }
 
  return (
    <div className="template-card">
      <img src={template.thumbnailUrl} alt={template.name} className="template-thumbnail" />
      <div className="template-info">
        <h3>{template.name}</h3>
        <p>{template.description}</p>
        <div className="template-meta">
          <span className="category">{template.category}</span>
          {template.isPremium && <span className="premium">Premium</span>}
          <span className="rating">★ {template.ratingAvg}</span>
        </div>
        <button onClick={handleApply} disabled={previewLoading} className="apply-button">
          {previewLoading ? '应用中...' : '使用模板'}
        </button>
      </div>
    </div>
  )
}

模板自定义示例

// 自定义模板颜色
async function customizeTemplateColors(resumeId, colorScheme) {
  const response = await fetch(`/api/resumes/${resumeId}`, {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json'
    },
    credentials: 'include',
    body: JSON.stringify({
      customStyles: {
        colors: {
          primary: colorScheme.primary,
          secondary: colorScheme.secondary,
          accent: colorScheme.accent
        }
      }
    })
  })
 
  return response.json()
}
 
// 自定义模板字体
async function customizeTemplateFont(resumeId, fontFamily) {
  const response = await fetch(`/api/resumes/${resumeId}`, {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json'
    },
    credentials: 'include',
    body: JSON.stringify({
      customStyles: {
        font: {
          family: fontFamily,
          size: {
            base: '14px',
            heading: '18px',
            subheading: '16px'
          }
        }
      }
    })
  })
 
  return response.json()
}

❌ 错误处理

常见错误码

错误码HTTP 状态描述
TEMPLATE_NOT_FOUND404模板不存在
PREMIUM_TEMPLATE_ACCESS_DENIED403需要付费订阅才能访问
TEMPLATE_CREATION_FAILED500模板创建失败
INVALID_TEMPLATE_DATA400模板数据格式错误
TEMPLATE_IN_USE409模板正在被使用,无法删除

错误响应示例

{
  "error": "此模板需要付费订阅才能使用",
  "code": "PREMIUM_TEMPLATE_ACCESS_DENIED",
  "details": {
    "templateId": "template_456",
    "templateName": "专业商务",
    "userSubscriptionType": "FREE"
  }
}

下一步

👤 用户管理

了解用户信息和账户管理相关 API

🤖 AI 服务

学习如何使用 AI 分析和优化功能