当前位置:首页>PPT>PPT 生成智能体 |如何设计一个支持断点续传的复杂 AI Agent?

PPT 生成智能体 |如何设计一个支持断点续传的复杂 AI Agent?

  • 2026-05-23 18:42:43
PPT 生成智能体 |如何设计一个支持断点续传的复杂 AI Agent?

在最近的项目中,我们团队负责孵化一个”PPT生成智能体”。坦白讲,这可以说是我们整个系统里最复杂的一个 Agent。

为什么复杂?因为”一句话生成一份高质量 PPT”并不是调用一次大模型 API 就能搞定的。它是一个典型的长耗时、多阶段的复杂业务流。这个过程涉及到用户意图识别、需求澄清、联网检索、大纲生成、内容填充乃至配图和最终的渲染。通常来说,完整生成一份极具干货的 PPT 需要几分钟之久。

在项目初期,我们面临着两个极其棘手的灵魂拷问:

  1. 代码怎么写才不会变成”屎山”?
    多个阶段的逻辑完全不同,有的要查库,有的要调搜索,有的要调用文生图 API,如果全塞在一个 Service 里,代码将变得无法维护。
  2. 生成的过程中,用户把网页关了怎么办?网络断了怎么办?
    几分钟的等待期内,用户的任何中断行为都会导致前功尽弃,这对于一款商业级产品来说,体验是灾难性的。

为了解决这两个问题,我们最终采用了一套状态机 + 策略模式 + 状态持久化的架构方案。

一、整体架构

在动手写代码之前,先看整体架构。下图是这套系统的核心数据流:

每一个阶段(State)对应一个独立的 Strategy 类。状态机引擎负责加载上下文、分发任务、并在每个状态边界触发持久化。整个系统的核心设计哲学是:状态是唯一真相(Single Source of Truth),只要状态能恢复,任务就能恢复。

二、状态定义

首先,我们将整个 PPT 生成过程的各个阶段严格地抽象为若干个状态(State)

public enum PptState {    INIT,         // 初始状态:接收并解析用户初步意图    REQUIREMENT,  // 需求澄清:信息不足时主动向用户追问    SEARCH,       // 信息收集:联网检索,获取最新资料    SCHEMA,       // 结构生成:搭建 PPT 整体章节骨架    OUTLINE,      // 大纲生成:为每个章节生成详细大纲    CONTENT,      // 内容填充:为每页生成文案,调用文生图配插图    RENDER,       // 渲染生成:结构化数据转为真实 PPT 文件    SUCCESS,      // 终态(成功)    FAILED        // 终态(失败)}

几个值得注意的设计决策:

  • REQUIREMENT 是可选的
    :只有当 INIT 阶段判断用户输入信息不足时,才会流转到 REQUIREMENT。否则直接跳到 SEARCH。这意味着状态转换不是严格的线性序列,而是由每个 Strategy 自主决定”下一步去哪”。
  • FAILED 是唯一的异常出口
    :任何阶段抛出的、不可重试的业务异常,都统一流转到 FAILED 状态,并在那里记录错误原因,方便前端展示和人工排查。
  • SUCCESS/FAILED 是幂等终态
    :一旦进入终态,后续所有重复请求都应直接返回结果,不再重新执行。

三、策略模式实现

3.1 策略接口定义

我们为每一个状态都编写了一个独立的 Strategy 类。所有策略类统一实现同一个接口:

public interface PptStateStrategy {    // 处理当前状态的核心逻辑,完成后调用 context.continueStateMachine(nextState) 推进    void process(PptStateStrategyContext context);    // 声明本策略负责处理哪个状态,引擎据此自动路由    PptState getHandleState();}

3.2 策略的自动注册:让引擎与策略完全解耦

我们利用 Spring 的 IoC 容器,实现策略的自动注册,完全消除引擎对具体策略类的感知:

@Componentpublic class PptStateMachineEngine {    private final Map<PptState, PptStateStrategy> strategyMap = new HashMap<>();    // Spring 启动时自动注入所有 Strategy Bean,按 getHandleState() 注册到 Map    @Autowired    public PptStateMachineEngine(List<PptStateStrategy> strategies) {        for (PptStateStrategy strategy : strategies) {            strategyMap.put(strategy.getHandleState(), strategy);        }    }    public void dispatch(PptStateStrategyContext context) {        PptState currentState = context.getPptInstance().getState();        PptStateStrategy strategy = strategyMap.get(currentState);        if (strategy == null) {            throw new IllegalStateException(“No strategy found for state: “ + currentState);        }        strategy.process(context);    }}

这样的好处是:新增一个状态,只需新增一个 Strategy 类并打上 @Component 注解,引擎完全不需要改动。 完全符合开闭原则(OCP)。

3.3 一个具体策略的实现:以 RequirementStrategy 为例

下面是需求澄清阶段的策略实现,可以完整看到一个 Strategy 的标准写法:

@Componentpublic class RequirementStrategy implements PptStateStrategy {    @Override    public PptState getHandleState() {        return PptState.REQUIREMENT;    }    @Override    public void process(PptStateStrategyContext context) {        PptInstance ppt = context.getPptInstance();        ChatClient chatClient = context.getChatClient();        ChatMemory chatMemory = context.getChatMemory();        // 1. 构建提示词:基于已有信息,询问大模型是否信息充足        String prompt = buildRequirementPrompt(ppt.getUserInput());        // 2. 调用大模型,获取结构化判断结果        RequirementCheckResult result = chatClient            .prompt(prompt)            .advisors(new MessageChatMemoryAdvisor(chatMemory))            .call()            .entity(RequirementCheckResult.class);        if (result.isInfoSufficient()) {            // 3a. 信息充足 → 将补全后的需求写回 PPT 实例,直接推进到 SEARCH            ppt.setRefinedRequirement(result.getRefinedRequirement());            context.continueStateMachine(PptState.SEARCH);        } else {            // 3b. 信息不足 → 将追问内容回传给用户,状态停留在 REQUIREMENT,等待用户答复            context.replyToUser(result.getFollowUpQuestion());            // 注意:此时不调用 continueStateMachine,状态机”暂停”,等待下一轮用户输入        }    }}

注意这里的关键设计:Strategy 对”下一步去哪”有完全的自主权。当信息不足时,流程可以暂停并等待用户输入,这是普通线性流程无法实现的。

3.4 上下文对象:各阶段数据流转的”大脑”

各个阶段独立了,但上下文(Context)是连贯的。PptStateStrategyContext 承担了所有共享资源的托管:

@Datapublic class PptStateStrategyContext {    private PptInstance pptInstance;  // PPT 实体(含当前状态)    private ChatClient chatClient;    // 大模型调用入口    private ChatMemory chatMemory;    // 对话历史(状态边界时序列化到 DB)    private SseEmitter sseEmitter;    // 向前端推送进度的通道    // 推动状态机向前:先持久化快照,再调用下一个 Strategy    public void continueStateMachine(PptState nextState) {        this.pptInstance.setState(nextState);        PptStatePersistenceService.persist(this);        StateMachineEngine.getInstance().dispatch(this);    }    // 向前端推送一条消息(追问、进度通知等)    public void replyToUser(String message) {        SseUtils.send(this.sseEmitter, message);    }}

四、断点续传实现

4.1 核心思路:在状态边界打快照

断点续传的实现,水到渠成地建立在状态机设计之上。核心思路:在每个状态转换的边界,将完整快照(包括 PPT 数据 + 对话历史 + 当前状态标识)持久化到数据库。

这样,无论任务在哪个阶段中断,我们都能从数据库中精确恢复到上一个完成的状态节点,并从那里继续执行,不会重复消耗 Token。

4.2 保存什么,怎么保存?

在 continueStateMachine() 内部,持久化逻辑如下:

// PptStatePersistenceService.javapublic static void persist(PptStateStrategyContext context) {    PptInstance ppt = context.getPptInstance();    // 1. 序列化对话历史    // ChatMemory 本身是内存对象,需要手动序列化为 JSON 存库    List<Message> messages = context.getChatMemory().get(ppt.getConversationId(), Integer.MAX_VALUE);    String chatHistoryJson = JSON.toJSONString(messages);    // 2. 构建持久化实体    PptTaskSnapshot snapshot = PptTaskSnapshot.builder()        .conversationId(ppt.getConversationId())        .currentState(ppt.getState().name())   // 关键!记录当前状态        .pptData(JSON.toJSONString(ppt))        // 完整 PPT 数据        .chatHistory(chatHistoryJson)            // 对话历史        .updatedAt(LocalDateTime.now())        .build();    // 3. 落库(upsert,有则更新,无则插入)    pptTaskSnapshotRepository.upsert(snapshot);}

对应的数据库表设计(精简版):

CREATE TABLE ppt_task_snapshot (    conversation_id VARCHAR(64) PRIMARY KEY COMMENT '会话ID,业务唯一标识',    current_state   VARCHAR(32) NOT NULL    COMMENT '当前状态枚举值',    ppt_data        LONGTEXT                COMMENT 'PPT实例数据(JSON)',    chat_history    LONGTEXT                COMMENT '对话历史(JSON)',    updated_at      DATETIME                COMMENT '最后更新时间');

4.3 恢复流程

下面是完整的断点续传恢复逻辑:

// PptAgentService.java - 用户发起请求的入口public void handleUserRequest(String conversationId, String userMessage, SseEmitter emitter) {    // 第一步:查询是否存在未完成的任务快照    Optional<PptTaskSnapshot> snapshot = pptTaskSnapshotRepository.findByConversationId(conversationId);    PptStateStrategyContext context;    if (snapshot.isPresent() && !isTerminal(snapshot.get().getCurrentState())) {        // ====== 断点续传分支 ======        PptTaskSnapshot snap = snapshot.get();        // 1. 反序列化 PPT 实例        PptInstance ppt = JSON.parseObject(snap.getPptData(), PptInstance.class);        // 2. 恢复对话历史(关键!大模型需要历史上下文才能”记起”之前的对话)        List<Message> messages = JSON.parseArray(snap.getChatHistory(), Message.class);        ChatMemory chatMemory = new InMemoryChatMemory();        chatMemory.add(conversationId, messages);        // 3. 如果用户此次带着新消息进来(比如回答了追问),追加到历史        if (StringUtils.isNotBlank(userMessage)) {            chatMemory.add(conversationId, new UserMessage(userMessage));        }        // 4. 重新拼装 Context        context = new PptStateStrategyContext(ppt, chatClient, chatMemory, emitter);        log.info(“断点续传恢复成功,conversationId={}, 继续状态={}”, conversationId, ppt.getState());    } else {        // ====== 全新任务分支 ======        PptInstance newPpt = PptInstance.create(conversationId, userMessage);        ChatMemory chatMemory = new InMemoryChatMemory();        context = new PptStateStrategyContext(newPpt, chatClient, chatMemory, emitter);    }    // 第二步:启动状态机(异步执行,避免阻塞 HTTP 线程)    asyncExecutor.execute(() -> stateMachineEngine.dispatch(context));}

4.4 前端如何配合后端

前端的核心逻辑非常简单,只需要做两件事:

  1. 使用 SSE(Server-Sent Events)接收流式进度
    :每个状态完成后,后端通过 SSE 推送一条进度消息,前端据此更新进度条(”正在搜索资料...” / “正在生成大纲...”)。
  2. 页面重新打开时,携带 conversationId 重新发起请求
    :前端将 conversationId 存储在 localStorage 中。用户下次进入时,直接用这个 ID 请求后端,后端会自动识别并执行断点续传。
// 前端伪代码async function startOrResumePptGeneration(userInput) {  const conversationId = localStorage.getItem('pptConversationId') || generateUUID();  localStorage.setItem('pptConversationId', conversationId);  const eventSource = new EventSource(`/api/ppt/generate?conversationId=${conversationId}&input=${userInput}`);  eventSource.onmessage = (event) => {    const data = JSON.parse(event.data);    if (data.type === 'PROGRESS') {      updateProgressBar(data.state, data.message);    } else if (data.type === 'DONE') {      showPptPreview(data.pptUrl);      eventSource.close();    } else if (data.type === 'QUESTION') {      // 需求澄清:展示追问弹窗,等待用户输入      showFollowUpDialog(data.question);    }  };}

五、踩坑记录

坑1:ChatMemory 序列化问题

Spring AI 的 Message 对象是接口,包含 UserMessageAssistantMessageSystemMessage 等多个子类型。直接 JSON.toJSONString(messages) 序列化没问题,但反序列化时 JSON.parseArray(json, Message.class) 会因为多态丢失子类型信息而失败。

💡 优雅解法序列化时在每条消息里带上类型标识,反序列化时手动按类型还原,或者使用 Jackson 的 @JsonTypeInfo 注解配置多态序列化策略。

坑2:并发重入问题

用户在任务进行中反复刷页面时,可能同时触发多个恢复请求,导致同一任务被并发执行两遍,产生重复的 Token 消耗和数据错乱。

💡 优雅解法在数据库层面对 conversation_id 加分布式锁(Redis SETNX 或数据库乐观锁),任务开始前先获取锁,任务完成或终止后释放锁。如果加锁失败,说明已有执行中的实例,直接返回”任务进行中”即可。

坑3:CONTENT 阶段耗时极长

CONTENT 阶段需要为每一页 PPT 分别调用大模型生成内容,如果是 20 页 PPT,就是 20 次串行 LLM 调用。这使得整体耗时急剧上升。

💡 优雅解法将 CONTENT 阶段内部改为并发执行(使用 CompletableFuture 或虚拟线程),多页内容同时生成。同时在 CONTENT 阶段内部也做细粒度的持久化(每完成一页就存库),避免中途中断导致已完成页面的 Token 浪费。

坑4:极端条件导致状态机”跑飞”

在测试中,曾出现状态机进入死循环的情况:某个 Strategy 在异常条件下既没有调用 continueStateMachine(),也没有流转到 FAILED,导致任务永久挂起。

💡 优雅解法在引擎的 dispatch() 方法中用整体 try-catch 兜底,所有未捕获的未卜异常都强制流转到 FAILED 状态。同时辅助加入超时检测的后台 Job,定期扫描 updated_at 超过阈值的未完成任务,主动标记为 FAILED 并触发告警。

六、为什么选自研而不是工作流引擎?

不少同学会问:为什么不用 Flowable、Camunda 这类成熟的工作流引擎?

维度
工作流引擎(如 Flowable)
自研状态机
上手成本
高(BPMN 语法、引擎配置)
低(接口 + 枚举)
AI 上下文感知
不感知(需要额外桥接)
原生支持(Context 直接持有 ChatMemory)
动态流转逻辑
需要在 BPMN 中定义网关
Strategy 内部自由决策
调试难度
高(日志分散、需专用工具)
低(就是普通 Java 代码)
适合规模
大型企业流程(审批等)
中小型 AI 任务编排

结论:工作流引擎是重型武器,为复杂的人工审批流而生。对于 AI Agent 这类以大模型调用为核心、需要动态分支、高度感知上下文的场景,自研轻量状态机更灵活、更易调试。

七、总结一下

把这套方案提炼成可以复用的工程经验,核心有以下几条:

  1. 复杂 AI 任务 = 状态机 + 策略模式,而非线性脚本。
    每个阶段独立成类,彼此不感知,通过 Context 传递数据。新增阶段只需新增类,完全符合 OCP。
  2. 状态边界是持久化的天然切点。
    不需要在业务逻辑中间插入持久化代码。状态转换就是快照时机,持久化逻辑集中在 continueStateMachine() 中,对各 Strategy 完全透明。
  3. ChatMemory 的序列化是 AI Agent 持久化的核心难点。
    不处理好对话历史的序列化/反序列化,模型恢复后就会”失忆”,上下文断裂,生成质量直线下降。
  4. 异步 + SSE 是长耗时 AI 任务的标配前后端交互模型。
    后端异步执行状态机,通过 SSE 流式推送进度,前端保存 conversationId 支持随时恢复。这套模式几乎适用于所有复杂 AI 生成任务。
  5. 最长阶段的内部并发化是性能优化的关键。
识别出耗时最长的阶段(如多页内容填充),将其内部改为并发执行,往往可以将整体耗时降低 50% 以上。

AI Agent 的工程化,本质上就是”如何让不可控的大模型嵌入可控的工程系统”。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-05-24 03:42:43 HTTP/2.0 GET : https://h.sjds.net/a/503424.html
  2. 运行时间 : 0.213525s [ 吞吐率:4.68req/s ] 内存消耗:4,330.89kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=4da7d2a8d5c35aca548800083a0acbeb
  1. /yingpanguazai/ssd/ssd1/www/h.sjds.net/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/h.sjds.net/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/h.sjds.net/runtime/temp/ad153693ed39fba6d1bda2fe72512cde.php ( 12.06 KB )
  140. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.001005s ] mysql:host=127.0.0.1;port=3306;dbname=h_sjds;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001504s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000673s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000636s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001408s ]
  6. SELECT * FROM `set` [ RunTime:0.000567s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001653s ]
  8. SELECT * FROM `article` WHERE `id` = 503424 LIMIT 1 [ RunTime:0.005731s ]
  9. UPDATE `article` SET `lasttime` = 1779565363 WHERE `id` = 503424 [ RunTime:0.007970s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000707s ]
  11. SELECT * FROM `article` WHERE `id` < 503424 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001221s ]
  12. SELECT * FROM `article` WHERE `id` > 503424 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001053s ]
  13. SELECT * FROM `article` WHERE `id` < 503424 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.001886s ]
  14. SELECT * FROM `article` WHERE `id` < 503424 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.007948s ]
  15. SELECT * FROM `article` WHERE `id` < 503424 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.006966s ]
0.217373s