前端调用示例.md 7.0 KB

前端调用Coze工作流API示例

接口信息

接口地址: POST /api/coze/generate-questions

功能: 在设定学习目标页面点击保存目标后调用该接口,生成学习题目并自动存储到goal_of_detail表中

重要更新:

  • 修复重复生成: 已修复保存目标时重复生成题目的问题(v1.1.0)
  • ⚠️ 调用说明: 请确保只在前端调用此接口,服务器端已禁用自动生成逻辑

请求参数

CozeWorkflowRequest 对象结构

{
  "userId": 1,                    // 必填:用户ID
  "goalId": 1,                    // 可选:目标ID,用于关联已创建的目标
  "subject": "物理",              // 必填:学习主题/科目
  "difficulty": "中等",           // 必填:题目难度(简单/中等/困难)
  "type": "选择题",               // 必填:目标类型(选择题/填空题/单词题)
  "totalQuantity": 3,            // 必填:题目数量(1-20)
  "knowledgePoint": "万有引力定律"  // 必填:目标描述/知识点
}

前端调用示例

JavaScript/TypeScript 示例

// 保存目标并生成题目的函数
async function saveGoalAndGenerateQuestions(goalData) {
  try {
    // 构建请求参数
    const requestData = {
      userId: getCurrentUserId(),        // 获取当前用户ID
      goalId: goalData.goalId,          // 目标ID(如果已创建目标)
      subject: goalData.subject,        // 学习科目
      difficulty: goalData.difficulty,  // 难度级别
      type: goalData.type,             // 题目类型
      totalQuantity: goalData.quantity, // 题目数量
      knowledgePoint: goalData.description // 知识点描述
    };

    // 调用API
    const response = await fetch('/api/coze/generate-questions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${getAuthToken()}` // 如果需要认证
      },
      body: JSON.stringify(requestData)
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const result = await response.json();
    
    if (result.success) {
      console.log(`成功生成 ${result.questions.length} 道题目`);
      // 处理成功响应
      handleGenerateSuccess(result);
    } else {
      console.error('题目生成失败:', result.message);
      // 处理失败响应
      handleGenerateError(result.message);
    }
    
  } catch (error) {
    console.error('调用API失败:', error);
    handleGenerateError(error.message);
  }
}

// 在保存目标按钮点击事件中调用
document.getElementById('saveGoalBtn').addEventListener('click', async () => {
  const goalData = {
    goalId: document.getElementById('goalId').value || null,
    subject: document.getElementById('subject').value,
    difficulty: document.getElementById('difficulty').value,
    type: document.getElementById('type').value,
    quantity: parseInt(document.getElementById('quantity').value),
    description: document.getElementById('description').value
  };
  
  // 验证必填字段
  if (!goalData.subject || !goalData.difficulty || !goalData.type || 
      !goalData.quantity || !goalData.description) {
    alert('请填写所有必填字段');
    return;
  }
  
  await saveGoalAndGenerateQuestions(goalData);
});

Vue.js 示例

<template>
  <div class="goal-form">
    <form @submit.prevent="saveGoal">
      <div class="form-group">
        <label>学习科目:</label>
        <input v-model="goalForm.subject" type="text" required>
      </div>
      
      <div class="form-group">
        <label>难度级别:</label>
        <select v-model="goalForm.difficulty" required>
          <option value="简单">简单</option>
          <option value="中等">中等</option>
          <option value="困难">困难</option>
        </select>
      </div>
      
      <div class="form-group">
        <label>题目类型:</label>
        <select v-model="goalForm.type" required>
          <option value="选择题">选择题</option>
          <option value="填空题">填空题</option>
          <option value="单词题">单词题</option>
        </select>
      </div>
      
      <div class="form-group">
        <label>题目数量:</label>
        <input v-model.number="goalForm.quantity" type="number" min="1" max="20" required>
      </div>
      
      <div class="form-group">
        <label>知识点描述:</label>
        <textarea v-model="goalForm.description" required></textarea>
      </div>
      
      <button type="submit" :disabled="loading">保存目标并生成题目</button>
    </form>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      loading: false,
      goalForm: {
        subject: '',
        difficulty: '中等',
        type: '选择题',
        quantity: 3,
        description: '',
        goalId: null // 如果是编辑已有目标,设置此值
      }
    };
  },
  methods: {
    async saveGoal() {
      this.loading = true;
      
      try {
        const requestData = {
          userId: this.$store.state.user.id, // 从状态管理获取用户ID
          goalId: this.goalForm.goalId,
          subject: this.goalForm.subject,
          difficulty: this.goalForm.difficulty,
          type: this.goalForm.type,
          totalQuantity: this.goalForm.quantity,
          knowledgePoint: this.goalForm.description
        };
        
        const response = await axios.post('/api/coze/generate-questions', requestData);
        
        if (response.data.success) {
          this.$message.success(`成功生成 ${response.data.questions.length} 道题目`);
          // 跳转到题目列表或其他页面
          this.$router.push('/questions');
        } else {
          this.$message.error(response.data.message || '题目生成失败');
        }
        
      } catch (error) {
        console.error('API调用失败:', error);
        this.$message.error('网络错误,请稍后重试');
      } finally {
        this.loading = false;
      }
    }
  }
};
</script>

响应格式

成功响应

{
  "success": true,
  "message": "题目生成成功",
  "questions": [
    {
      "question": "题目内容",
      "options": ["选项A", "选项B", "选项C", "选项D"],
      "answer": "正确答案",
      "explanation": "解析说明",
      "knowledgePoint": "知识点",
      "type": "选择题",
      "difficulty": "中等"
    }
  ],
  "totalCount": 3
}

失败响应

{
  "success": false,
  "message": "错误信息描述"
}

注意事项

  1. 必填字段验证: 前端需要验证所有必填字段
  2. 数量限制: 题目数量必须在1-20之间
  3. 错误处理: 需要处理网络错误和业务错误
  4. 加载状态: 建议显示加载状态,因为API调用可能需要一些时间
  5. 自动存储: 调用成功后,题目会自动存储到goal_of_detail表中,每道题目都有唯一的detail_id

API文档地址

完整的API文档可以访问: http://localhost:8080/api/docs