文档

用户管理 API

SmartCV 用户管理 API 文档,包含用户信息、账户设置、订阅管理等功能

更新时间: 2024/12/30

SmartCV 用户管理 API 提供用户信息管理、账户设置、订阅管理等功能。

📋 API 端点概览

端点方法描述
/api/accountGET获取用户信息
/api/accountPUT更新用户信息
/api/account/securityPUT更新安全设置
/api/account/subscriptionGET获取订阅信息
/api/account/subscriptionPOST创建订阅
/api/account/subscriptionPUT更新订阅

👤 获取用户信息

端点: GET /api/account

描述: 获取当前用户的详细信息

认证: 需要登录

响应:

{
  "success": true,
  "data": {
    "id": "user_123",
    "email": "[email protected]",
    "name": "张三",
    "avatar": "https://storage.smartcv.cc/avatars/user_123.jpg",
    "emailVerified": true,
    "emailVerifiedAt": "2024-01-15T10:00:00Z",
    "subscriptionType": "PREMIUM",
    "subscriptionStatus": "ACTIVE",
    "subscriptionExpiresAt": "2025-01-15T10:00:00Z",
    "resumesCreated": 8,
    "resumesLimit": 50,
    "apiRequestsUsed": 150,
    "apiRequestsLimit": 1000,
    "storageUsed": 10485760,
    "storageLimit": 104857600,
    "preferences": {
      "language": "zh-cn",
      "timezone": "Asia/Shanghai",
      "theme": "light",
      "emailNotifications": true,
      "marketingEmails": false
    },
    "createdAt": "2024-01-15T10:00:00Z",
    "updatedAt": "2024-12-30T10:00:00Z",
    "lastLoginAt": "2024-12-30T09:00:00Z"
  }
}

✏️ 更新用户信息

端点: PUT /api/account

描述: 更新用户的基本信息和偏好设置

认证: 需要登录

请求体:

{
  "name": "李四",
  "avatar": "https://storage.smartcv.cc/avatars/new_avatar.jpg",
  "preferences": {
    "language": "en",
    "timezone": "America/New_York",
    "theme": "dark",
    "emailNotifications": false,
    "marketingEmails": true
  }
}

响应:

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

🔒 更新安全设置

端点: PUT /api/account/security

描述: 更新用户的密码和安全设置

认证: 需要登录

请求体:

{
  "currentPassword": "currentPassword123",
  "newPassword": "newSecurePassword456",
  "confirmPassword": "newSecurePassword456",
  "twoFactorEnabled": true
}

响应:

{
  "success": true,
  "message": "安全设置更新成功",
  "data": {
    "passwordUpdated": true,
    "twoFactorEnabled": true,
    "backupCodes": ["12345678", "87654321", "11223344"]
  }
}

📊 获取订阅信息

端点: GET /api/account/subscription

描述: 获取用户的订阅详情和使用情况

认证: 需要登录

响应:

{
  "success": true,
  "data": {
    "id": "sub_123",
    "type": "PREMIUM",
    "status": "ACTIVE",
    "currentPeriodStart": "2024-12-01T00:00:00Z",
    "currentPeriodEnd": "2025-01-01T00:00:00Z",
    "cancelAtPeriodEnd": false,
    "trialEnd": null,
    "plan": {
      "id": "plan_premium_monthly",
      "name": "Premium 月度套餐",
      "price": 29.99,
      "currency": "USD",
      "interval": "month",
      "features": ["无限简历数量", "所有高级模板", "AI 优化功能", "优先客服支持", "1000 API 请求/月"]
    },
    "usage": {
      "resumesCreated": 8,
      "resumesLimit": -1,
      "apiRequestsUsed": 150,
      "apiRequestsLimit": 1000,
      "storageUsed": 10485760,
      "storageLimit": 104857600,
      "resetDate": "2025-01-01T00:00:00Z"
    },
    "paymentMethod": {
      "type": "card",
      "last4": "4242",
      "brand": "visa",
      "expiryMonth": 12,
      "expiryYear": 2025
    },
    "nextBilling": {
      "date": "2025-01-01T00:00:00Z",
      "amount": 29.99,
      "currency": "USD"
    }
  }
}

💳 创建订阅

端点: POST /api/account/subscription

描述: 创建新的订阅计划

认证: 需要登录

请求体:

{
  "planId": "plan_premium_monthly",
  "paymentMethodId": "pm_1234567890",
  "couponCode": "WELCOME20"
}

响应:

{
  "success": true,
  "data": {
    "subscriptionId": "sub_123",
    "status": "ACTIVE",
    "clientSecret": "pi_1234567890_secret_xyz",
    "requiresAction": false,
    "nextAction": null
  }
}

🔄 更新订阅

端点: PUT /api/account/subscription

描述: 更新现有订阅(升级、降级、取消等)

认证: 需要登录

请求体:

{
  "action": "upgrade",
  "planId": "plan_premium_yearly",
  "prorationBehavior": "create_prorations"
}

支持的操作:

  • upgrade: 升级套餐
  • downgrade: 降级套餐
  • cancel: 取消订阅
  • reactivate: 重新激活订阅
  • update_payment_method: 更新支付方式

响应:

{
  "success": true,
  "data": {
    "subscriptionId": "sub_123",
    "status": "ACTIVE",
    "prorationAmount": 15.5,
    "effectiveDate": "2024-12-30T10:00:00Z"
  }
}

📝 使用示例

JavaScript 示例

// 获取用户信息
async function getUserInfo() {
  const response = await fetch('/api/account', {
    credentials: 'include'
  })
 
  const data = await response.json()
  if (data.success) {
    return data.data
  } else {
    throw new Error(data.error)
  }
}
 
// 更新用户偏好
async function updateUserPreferences(preferences) {
  const response = await fetch('/api/account', {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json'
    },
    credentials: 'include',
    body: JSON.stringify({
      preferences
    })
  })
 
  return response.json()
}
 
// 修改密码
async function changePassword(currentPassword, newPassword) {
  const response = await fetch('/api/account/security', {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json'
    },
    credentials: 'include',
    body: JSON.stringify({
      currentPassword,
      newPassword,
      confirmPassword: newPassword
    })
  })
 
  const data = await response.json()
  if (data.success) {
    return data.data
  } else {
    throw new Error(data.error)
  }
}
 
// 获取订阅信息
async function getSubscriptionInfo() {
  const response = await fetch('/api/account/subscription', {
    credentials: 'include'
  })
 
  return response.json()
}
 
// 升级订阅
async function upgradeSubscription(planId) {
  const response = await fetch('/api/account/subscription', {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json'
    },
    credentials: 'include',
    body: JSON.stringify({
      action: 'upgrade',
      planId
    })
  })
 
  return response.json()
}

React Hook 示例

import { useState, useEffect } from 'react'
 
function useUserAccount() {
  const [user, setUser] = useState(null)
  const [subscription, setSubscription] = useState(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(null)
 
  useEffect(() => {
    fetchUserData()
  }, [])
 
  const fetchUserData = async () => {
    try {
      setLoading(true)
 
      const [userResponse, subscriptionResponse] = await Promise.all([
        fetch('/api/account', { credentials: 'include' }),
        fetch('/api/account/subscription', { credentials: 'include' })
      ])
 
      const userData = await userResponse.json()
      const subscriptionData = await subscriptionResponse.json()
 
      if (userData.success) {
        setUser(userData.data)
      }
 
      if (subscriptionData.success) {
        setSubscription(subscriptionData.data)
      }
    } catch (err) {
      setError('获取用户信息失败')
    } finally {
      setLoading(false)
    }
  }
 
  const updatePreferences = async (preferences) => {
    try {
      const response = await fetch('/api/account', {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json'
        },
        credentials: 'include',
        body: JSON.stringify({ preferences })
      })
 
      const data = await response.json()
      if (data.success) {
        setUser(data.data)
        return data.data
      } else {
        throw new Error(data.error)
      }
    } catch (err) {
      setError(err.message)
      throw err
    }
  }
 
  const changePassword = async (currentPassword, newPassword) => {
    try {
      const response = await fetch('/api/account/security', {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json'
        },
        credentials: 'include',
        body: JSON.stringify({
          currentPassword,
          newPassword,
          confirmPassword: newPassword
        })
      })
 
      const data = await response.json()
      if (data.success) {
        return data.data
      } else {
        throw new Error(data.error)
      }
    } catch (err) {
      setError(err.message)
      throw err
    }
  }
 
  return {
    user,
    subscription,
    loading,
    error,
    updatePreferences,
    changePassword,
    refetch: fetchUserData
  }
}
 
// 用户设置组件示例
function UserSettings() {
  const { user, updatePreferences } = useUserAccount()
  const [preferences, setPreferences] = useState(user?.preferences || {})
 
  const handleSave = async () => {
    try {
      await updatePreferences(preferences)
      alert('设置保存成功')
    } catch (error) {
      alert('保存失败: ' + error.message)
    }
  }
 
  if (!user) return <div>Loading...</div>
 
  return (
    <div className="user-settings">
      <h2>用户设置</h2>
 
      <div className="setting-group">
        <label>语言设置</label>
        <select
          value={preferences.language}
          onChange={(e) =>
            setPreferences({
              ...preferences,
              language: e.target.value
            })
          }
        >
          <option value="zh-cn">中文</option>
          <option value="en">English</option>
        </select>
      </div>
 
      <div className="setting-group">
        <label>主题设置</label>
        <select
          value={preferences.theme}
          onChange={(e) =>
            setPreferences({
              ...preferences,
              theme: e.target.value
            })
          }
        >
          <option value="light">浅色</option>
          <option value="dark">深色</option>
          <option value="auto">自动</option>
        </select>
      </div>
 
      <div className="setting-group">
        <label>
          <input
            type="checkbox"
            checked={preferences.emailNotifications}
            onChange={(e) =>
              setPreferences({
                ...preferences,
                emailNotifications: e.target.checked
              })
            }
          />
          接收邮件通知
        </label>
      </div>
 
      <button onClick={handleSave}>保存设置</button>
    </div>
  )
}

❌ 错误处理

常见错误码

错误码HTTP 状态描述
USER_NOT_FOUND404用户不存在
INVALID_PASSWORD400当前密码错误
WEAK_PASSWORD422新密码强度不足
SUBSCRIPTION_NOT_FOUND404订阅不存在
PAYMENT_FAILED402支付失败
PLAN_NOT_FOUND404订阅计划不存在
SUBSCRIPTION_LIMIT_EXCEEDED429超出订阅限制

错误响应示例

{
  "error": "当前密码不正确",
  "code": "INVALID_PASSWORD",
  "details": {
    "field": "currentPassword"
  }
}

📊 订阅计划说明

可用计划类型

计划类型价格功能
FREE免费5份简历,基础模板
PREMIUM$29.99/月无限简历,所有模板,AI功能
ENTERPRISE联系销售团队协作,API访问,自定义品牌

使用限制

不同订阅类型的使用限制:

{
  "FREE": {
    "resumesLimit": 5,
    "templatesAccess": "basic",
    "aiFeatures": false,
    "apiRequestsLimit": 100,
    "storageLimit": 10485760
  },
  "PREMIUM": {
    "resumesLimit": -1,
    "templatesAccess": "all",
    "aiFeatures": true,
    "apiRequestsLimit": 1000,
    "storageLimit": 104857600
  },
  "ENTERPRISE": {
    "resumesLimit": -1,
    "templatesAccess": "all",
    "aiFeatures": true,
    "apiRequestsLimit": -1,
    "storageLimit": -1
  }
}

下一步

🤖 AI 服务

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

🔗 Webhooks

了解如何使用 Webhooks 接收实时通知