open-saas AI功能实现:从GPT响应生成到任务自动化

open-saas AI功能实现:从GPT响应生成到任务自动化

【免费下载链接】open-saas A free, open-source SaaS app starter for React & Node.js with superpowers. Production-ready. Community-driven. 【免费下载链接】open-saas 项目地址: https://gitcode.com/GitHub_Trending/op/open-saas

引言:AI驱动的任务管理新范式

你是否还在为每日任务规划耗费大量精力?open-saas提供的AI功能套件通过GPT响应生成与任务自动化,彻底革新了传统工作流。本文将深入剖析其实现原理,从API集成到任务调度的全流程拆解,助你掌握生产级AI功能开发要点。读完本文,你将获得:

  • GPT响应生成系统的架构设计与代码实现
  • 任务自动化的核心数据模型与状态管理
  • 基于用户订阅的AI功能访问控制方案
  • 完整的前端交互与后端服务集成案例

技术架构概览

open-saas的AI功能采用前后端分离架构,通过以下核心模块实现端到端任务自动化:

mermaid

核心技术栈

  • 前端:React + TypeScript + Zod(类型验证)
  • 后端:Node.js + Wasp(全栈框架)+ Prisma(ORM)
  • AI服务:OpenAI API(GPT-3.5/4)
  • 数据库:PostgreSQL

数据模型设计

核心实体关系

// schema.prisma 核心模型定义
model User {
  id                String       @id @default(uuid())
  email             String?      @unique
  subscriptionStatus String?     // 'active', 'cancel_at_period_end', 'past_due'
  credits           Int          @default(3)  // 免费用户AI调用次数
  gptResponses      GptResponse[]
  tasks             Task[]
}

model GptResponse {
  id        String   @id @default(uuid())
  user      User     @relation(fields: [userId], references: [id])
  userId    String
  content   String   // 存储GPT生成的JSON响应
}

model Task {
  id          String   @id @default(uuid())
  user        User     @relation(fields: [userId], references: [id])
  userId      String
  description String
  time        String   @default("1")  // 预估工时
  isDone      Boolean  @default(false)
}

任务优先级与调度模型

// schedule.ts 类型定义
export type TaskPriority = 'low' | 'medium' | 'high';

export type GeneratedSchedule = {
  tasks: Task[];          // 主任务列表
  taskItems: TaskItem[];  // 分解后的子任务
};

export type TaskItem = {
  description: string;    // 子任务描述
  time: number;           // 预估工时(小时)
  taskName: string;       // 关联的主任务名称
};

GPT响应生成系统实现

OpenAI客户端初始化

// operations.ts 中的GPT客户端配置
function setUpOpenAi(): OpenAI {
  if (process.env.OPENAI_API_KEY) {
    return new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
  } else {
    throw new Error('OpenAI API key is not set');
  }
}

结构化响应生成流程

// operations.ts 核心实现
async function generateScheduleWithGpt(tasks: Task[], hours: number): Promise<GeneratedSchedule | null> {
  const parsedTasks = tasks.map(({ description, time }) => ({
    description,
    time
  }));

  const completion = await openAi.chat.completions.create({
    model: 'gpt-3.5-turbo',
    messages: [
      {
        role: 'system',
        content: '你是专业的日程规划师,将用户任务分解为至少3个带优先级的子任务'
      },
      {
        role: 'user',
        content: `我今天工作${hours}小时,任务列表:${JSON.stringify(parsedTasks)}`
      }
    ],
    tools: [
      {
        type: 'function',
        function: {
          name: 'parseTodaysSchedule',
          parameters: {
            type: 'object',
            properties: {
              tasks: {
                type: 'array',
                items: {
                  type: 'object',
                  properties: {
                    name: { type: 'string' },
                    priority: { type: 'string', enum: ['low', 'medium', 'high'] }
                  }
                }
              },
              taskItems: { /* 子任务结构定义 */ }
            }
          }
        }
      }
    ],
    tool_choice: { type: 'function', function: { name: 'parseTodaysSchedule' } }
  });

  const gptResponse = completion?.choices[0]?.message?.tool_calls?.[0]?.function.arguments;
  return gptResponse ? JSON.parse(gptResponse) : null;
}

权限控制与调用限制

// operations.ts 中的访问控制逻辑
export const generateGptResponse: GenerateGptResponse<GenerateGptResponseInput, GeneratedSchedule> = async (
  rawArgs,
  context
) => {
  if (!context.user) throw new HttpError(401, '未授权用户');

  // 检查订阅状态或 credits
  if (!isUserSubscribed(context.user) && context.user.credits <= 0) {
    throw new HttpError(402, '用户 credits 已用尽');
  }

  // 生成GPT响应...

  // 非订阅用户消耗 credits
  if (!isUserSubscribed(context.user)) {
    await context.entities.User.update({
      where: { id: context.user.id },
      data: { credits: { decrement: 1 } }
    });
  }

  return generatedSchedule;
};

function isUserSubscribed(user: User) {
  return user.subscriptionStatus === SubscriptionStatus.Active || 
         user.subscriptionStatus === SubscriptionStatus.CancelAtPeriodEnd;
}

任务自动化实现

任务CRUD操作

// operations.ts 中的任务管理
export const createTask: CreateTask<CreateTaskInput, Task> = async (rawArgs, context) => {
  if (!context.user) throw new HttpError(401);
  
  const { description } = ensureArgsSchemaOrThrowHttpError(createTaskInputSchema, rawArgs);
  
  return context.entities.Task.create({
    data: { description, user: { connect: { id: context.user.id } } }
  });
};

export const updateTask: UpdateTask<UpdateTaskInput, Task> = async (rawArgs, context) => {
  if (!context.user) throw new HttpError(401);
  
  const { id, isDone, time } = ensureArgsSchemaOrThrowHttpError(updateTaskInputSchema, rawArgs);
  
  return context.entities.Task.update({
    where: { id, userId: context.user.id },
    data: { isDone, time }
  });
};

前端任务调度界面

// DemoAppPage.tsx 中的任务展示组件
function Schedule({ schedule }: { schedule: GeneratedSchedule }) {
  return (
    <div className="flex flex-col gap-6 py-6">
      {schedule.tasks
        .map(task => (
          <TaskCard 
            key={task.name} 
            task={task} 
            taskItems={schedule.taskItems} 
          />
        ))
        .sort((a, b) => {
          // 按优先级排序任务
          const priorityOrder: TaskPriority[] = ['low', 'medium', 'high'];
          return priorityOrder.indexOf(b.props.task.priority) - 
                 priorityOrder.indexOf(a.props.task.priority);
        })}
    </div>
  );
}

优先级视觉化实现

// TaskCard组件中的优先级样式映射
const taskPriorityToColorMap: Record<TaskPriority, string> = {
  high: 'bg-destructive/10 border-destructive/20 text-red-500',
  medium: 'bg-warning/10 border-warning/20 text-warning',
  low: 'bg-success/10 border-success/20 text-success'
};

<Card className={cn('border-2', taskPriorityToColorMap[task.priority])}>
  <CardHeader>
    <CardTitle>
      <span>{task.name}</span>
      <span className="text-xs font-medium italic"> {task.priority} priority</span>
    </CardTitle>
  </CardHeader>
  <CardContent>
    {/* 子任务列表 */}
  </CardContent>
</Card>

订阅与支付集成

订阅状态对AI功能的影响

// plans.ts 中的订阅状态定义
export enum SubscriptionStatus {
  PastDue = 'past_due',
  CancelAtPeriodEnd = 'cancel_at_period_end',
  Active = 'active',
  Deleted = 'deleted'
}

export enum PaymentPlanId {
  Hobby = 'hobby',    // 基础订阅
  Pro = 'pro',        // 专业订阅
  Credits10 = 'credits10' // 额外 credits 包
}

支付处理器集成

// paymentProcessor.ts 中的支付处理器选择
import { stripePaymentProcessor } from './stripe/paymentProcessor';
import { lemonSqueezyPaymentProcessor } from './lemonSqueezy/paymentProcessor';

// 选择支付处理器(Stripe 或 Lemon Squeezy)
export const paymentProcessor: PaymentProcessor = stripePaymentProcessor;

性能优化与监控

响应时间优化

  1. 请求批处理:合并多个GPT请求为批处理调用
  2. 缓存策略:对相同任务类型的GPT响应进行短期缓存
  3. 异步处理:长耗时任务通过后台作业处理

使用统计与分析

// analytics/stats.ts 中的AI使用统计
export const calculateDailyStats: DailyStatsJob<never, void> = async (_args, context) => {
  const userCount = await context.entities.User.count({});
  const paidUserCount = await context.entities.User.count({
    where: { subscriptionStatus: SubscriptionStatus.Active }
  });
  
  // 计算AI功能使用次数
  const gptResponseCount = await context.entities.GptResponse.count({
    where: { createdAt: { gte: new Date(yesterday) } }
  });
  
  // 存储每日统计数据
  await context.entities.DailyStats.create({
    data: {
      totalViews, userCount, paidUserCount,
      aiUsage: gptResponseCount,
      // 其他统计字段...
    }
  });
};

完整使用流程

用户操作流程图

mermaid

前端交互示例

// DemoAppPage.tsx 中的用户界面
function NewTaskForm({ handleCreateTask }: { handleCreateTask: typeof createTask }) {
  const [description, setDescription] = useState('');
  const [todaysHours, setTodaysHours] = useState(8);
  const [response, setResponse] = useState<GeneratedSchedule | null>(null);
  const [isPlanGenerating, setIsPlanGenerating] = useState(false);
  
  const { data: tasks } = useQuery(getAllTasksByUser);
  
  const handleGeneratePlan = async () => {
    setIsPlanGenerating(true);
    try {
      const response = await generateGptResponse({ hours: todaysHours });
      setResponse(response);
    } catch (err) {
      window.alert('生成计划失败: ' + err.message);
    } finally {
      setIsPlanGenerating(false);
    }
  };
  
  return (
    <div className="space-y-4">
      <Input 
        placeholder="输入任务描述" 
        value={description}
        onChange={(e) => setDescription(e.target.value)}
      />
      <Button onClick={handleSubmit}>添加任务</Button>
      
      {tasks?.length > 0 && (
        <Button 
          disabled={isPlanGenerating} 
          onClick={handleGeneratePlan}
          className="w-full"
        >
          {isPlanGenerating ? '生成中...' : '生成调度计划'}
        </Button>
      )}
      
      {response && <Schedule schedule={response} />}
    </div>
  );
}

部署与配置指南

环境变量配置

# 必要环境变量
OPENAI_API_KEY=your_openai_api_key
DATABASE_URL=postgresql://user:password@localhost:5432/open-saas
STRIPE_API_KEY=your_stripe_api_key
STRIPE_WEBHOOK_SECRET=your_webhook_secret

部署步骤概要

  1. 克隆仓库: git clone https://gitcode.com/GitHub_Trending/op/open-saas
  2. 安装依赖: npm install
  3. 配置环境变量: 复制 .env.example.env 并填写值
  4. 初始化数据库: wasp db migrate-dev
  5. 启动开发服务器: wasp start

总结与扩展方向

open-saas的AI功能通过GPT响应生成与任务自动化,为用户提供了智能任务管理解决方案。核心优势包括:

  • 完整的权限控制:基于订阅状态和credits的访问控制
  • 结构化响应处理:通过函数调用确保GPT输出格式一致性
  • 无缝前后端集成:React前端与Node.js后端的高效协作

未来扩展方向

  1. 多模型支持:集成Claude、Gemini等其他LLM模型
  2. 高级自动化:基于用户历史行为优化任务优先级
  3. 协作功能:团队共享任务与AI辅助协作
  4. 自定义提示:允许用户自定义GPT系统提示以适应特定需求

通过本文介绍的实现方案,开发者可以快速构建类似的AI驱动任务管理系统,或基于open-saas进一步扩展功能。

附录:核心API参考

操作描述参数返回值
generateGptResponse生成任务调度计划{ hours: number }GeneratedSchedule
createTask创建新任务{ description: string }Task
updateTask更新任务状态{ id: string, isDone?: boolean, time?: string }Task
deleteTask删除任务{ id: string }Task
getAllTasksByUser获取用户任务列表-Task[]

提示:完整API文档请参考项目源代码中的JSDoc注释。要开始使用open-saas AI功能,只需按照部署指南配置环境并添加任务即可体验智能调度。

【免费下载链接】open-saas A free, open-source SaaS app starter for React & Node.js with superpowers. Production-ready. Community-driven. 【免费下载链接】open-saas 项目地址: https://gitcode.com/GitHub_Trending/op/open-saas

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值