# panda_ai_code_generate
**Repository Path**: pan_shengdong/ai_code_generate
## Basic Information
- **Project Name**: panda_ai_code_generate
- **Description**: 基于 Spring Boot 3 + Langchain4j+ LangGraph4j的 AI零代码应用生成平台。用户输入自然语言描述,由 Al Agent 自动执行并发素材搜集、代码生成、质量检査、项目构建的完整工作流,最终一键部署为可访问的 Web 应用。项目核心为一套AI工作流,并采用多级缓存、分布式限流、异步处理、护轨重试等多种优化策略,保证系统的高性能与稳定性。
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-08-27
- **Last Updated**: 2025-09-08
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 简介
基于 Spring Boot 3 + Langchain4j+ LangGraph4j的 AI零代码应用生成平台。用户输入自然语言描述,由 Al Agent 自动执行并发素材搜集、代码生成、质量
检査、项目构建的完整工作流,最终一键部署为可访问的 Web 应用。项目核心为一套AI工作流,并采用多级缓存、分布式限流、异步处理、护轨重试等多种优化
策略,保证系统的高性能与稳定性。
# 项目初始化
https://start.aliyun.com/
https://start.spring.io/
# 后端增删改查代码生成
本次使用新的方式,一键式生成所有代码,包含controller代码,且能支持联表查询。
```xml
com.mybatis-flex
mybatis-flex-spring-boot3-starter
1.11.0
com.mybatis-flex
mybatis-flex-codegen
1.11.0
com.zaxxer
HikariCP
```
```java
package generator;
import cn.hutool.core.lang.Dict;
import cn.hutool.setting.yaml.YamlUtil;
import com.mybatisflex.codegen.Generator;
import com.mybatisflex.codegen.config.GlobalConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.util.Map;
/**
* @Author panda
* @Date 2025-08-28
* @Des
*/
public class MyBatisCodeGenerator {
// 需要生成的表名
private static final String[] TABLE_NAMES = {"user"};
public static void main(String[] args) {
// 获取数据源信息
Dict dict = YamlUtil.loadByPath("application.yml");
Map dataSourceConfig = dict.getByPath("spring.datasource");
String url = String.valueOf(dataSourceConfig.get("url"));
String username = String.valueOf(dataSourceConfig.get("username"));
String password = String.valueOf(dataSourceConfig.get("password"));
// 配置数据源
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
// 创建配置内容
GlobalConfig globalConfig = createGlobalConfig();
// 通过 datasource 和 globalConfig 创建代码生成器
Generator generator = new Generator(dataSource, globalConfig);
// 生成代码
generator.generate();
}
// 详细配置见:https://mybatis-flex.com/zh/others/codegen.html
public static GlobalConfig createGlobalConfig() {
// 创建配置内容
GlobalConfig globalConfig = new GlobalConfig();
// 设置根包,建议先生成到一个临时目录下,生成代码后,再移动到项目目录下
globalConfig.getPackageConfig()
.setBasePackage("com.panda.genresult");
// 设置表前缀和只生成哪些表,setGenerateTable 未配置时,生成所有表
globalConfig.getStrategyConfig()
.setGenerateTable(TABLE_NAMES)
// 设置逻辑删除的默认字段名称
.setLogicDeleteColumn("isDelete");
// 设置生成 entity 并启用 Lombok
globalConfig.enableEntity()
.setWithLombok(true)
.setJdkVersion(21);
// 设置生成 mapper
globalConfig.enableMapper();
globalConfig.enableMapperXml();
// 设置生成 service
globalConfig.enableService();
globalConfig.enableServiceImpl();
// 设置生成 controller
globalConfig.enableController();
// 设置生成时间和字符串为空,避免多余的代码改动
globalConfig.getJavadocConfig()
.setAuthor("程序员panda")
.setSince("");
return globalConfig;
}
}
```

```java
@Table("user")
public class User implements Serializable {
@Id(keyType = KeyType.Generator, value = KeyGenerators.snowFlakeId)
private Long id;
}
```
# AI生成代码应用
## 需求分析
1、让AI生成原始网页 html css javascript
2、打包到一个文件中html
## 方案设计
1、用户输入提示词
2、AI大模型生成
3、提取生成内容
4、保存到本地文件
https://api-docs.deepseek.com/zh-cn/
https://platform.deepseek.com/api_keys
https://docs.langchain4j.dev/integrations/language-models/open-ai/#spring-boot
## 测试AI调用
注意充值:



## 参数调整


### 参数调整的结果

页面显示:图片显示与主题不符合,可以优化下提示词或调用MCP工具调整。

## 保存到文件



# SSE流式输出
## reactor模式
```xml
dev.langchain4j
langchain4j-reactor
1.1.0-beta7
```
## 流式输出
```java
@Override
public Flux chatToGenCode(Long appId, String message, User loginUser) {
//xxxxxxxxxxxxxxxxxx
// 6. 调用 AI 生成代码(流式)
Flux contentFlux = aiCodeGeneratorFacade.generateAndSaveCodeStream(message, codeGenTypeEnum, appId);
// 7. 收集AI响应内容并在完成后记录到对话历史
StringBuilder aiResponseBuilder = new StringBuilder();
return contentFlux
.map(chunk -> {
// 收集AI响应内容
aiResponseBuilder.append(chunk);
return chunk;
})
.doOnComplete(() -> {
// 流式响应完成后,添加AI消息到对话历史
String aiResponse = aiResponseBuilder.toString();
if (StrUtil.isNotBlank(aiResponse)) {
chatHistoryService.addChatMessage(appId, aiResponse, ChatHistoryMessageTypeEnum.AI.getValue(), loginUser.getId());
}
})
.doOnError(error -> {
// 如果AI回复失败,也要记录错误消息
String errorMessage = "AI回复失败: " + error.getMessage();
chatHistoryService.addChatMessage(appId, errorMessage, ChatHistoryMessageTypeEnum.AI.getValue(), loginUser.getId());
});
}
```

```sh
1. 用户登录
curl -X POST "http://localhost:8855/api/user/login" \
-H "Content-Type: application/json" \
-d '{
"userAccount": "panda",
"userPassword": "xxxxx"
}' \
-c cookies.txt
2. 调用生成代码接口(流式)
curl -G "http://localhost:8855/api/app/chat/gen/code" \
--data-urlencode "appId=xxxxxx" \
--data-urlencode "message=我需要一个简单的任务记录工具网站" \
-H "Accept: text/event-stream" \
-H "Cache-Control: no-cache" \
-b cookies.txt \
--no-buffer
```
# 部署AI应用
nginx部署:

# cursor前端生成
效果如下:

打开部署地址:

# 多轮历史对话
## 需求分析
1、对话持久化存储
2、对话历史的应用级别隔离
3、对话历史查询,展示10条历史消息
4、管理历史对话
## 方案设计
1、分页查询,使用游标查询。【createTime】
```java
/**
* 分页查询某个应用的对话历史(游标查询)
*
* @param appId 应用ID
* @param pageSize 页面大小
* @param lastCreateTime 最后一条记录的创建时间
* @param request 请求
* @return 对话历史分页
*/
@GetMapping("/app/{appId}")
public BaseResponse> listAppChatHistory(@PathVariable Long appId,
@RequestParam(defaultValue = "10") int pageSize,
@RequestParam(required = false) LocalDateTime lastCreateTime,
HttpServletRequest request) {
User loginUser = userService.getLoginUser(request);
Page result = chatHistoryService.listAppChatHistoryByPage(appId, pageSize, lastCreateTime, loginUser);
return ResultUtils.success(result);
}
@Override
public Page listAppChatHistoryByPage(Long appId, int pageSize,
LocalDateTime lastCreateTime,
User loginUser) {
ThrowUtils.throwIf(appId == null || appId <= 0, ErrorCode.PARAMS_ERROR, "应用ID不能为空");
ThrowUtils.throwIf(pageSize <= 0 || pageSize > 50, ErrorCode.PARAMS_ERROR, "页面大小必须在1-50之间");
ThrowUtils.throwIf(loginUser == null, ErrorCode.NOT_LOGIN_ERROR);
// 验证权限:只有应用创建者和管理员可以查看
App app = appService.getById(appId);
ThrowUtils.throwIf(app == null, ErrorCode.NOT_FOUND_ERROR, "应用不存在");
boolean isAdmin = UserConstant.ADMIN_ROLE.equals(loginUser.getUserRole());
boolean isCreator = app.getUserId().equals(loginUser.getId());
ThrowUtils.throwIf(!isAdmin && !isCreator, ErrorCode.NO_AUTH_ERROR, "无权查看该应用的对话历史");
// 构建查询条件
ChatHistoryQueryRequest queryRequest = new ChatHistoryQueryRequest();
queryRequest.setAppId(appId);
queryRequest.setLastCreateTime(lastCreateTime);
QueryWrapper queryWrapper = this.getQueryWrapper(queryRequest);
// 查询数据
return this.page(Page.of(1, pageSize), queryWrapper);
}
```
## 代码实现
```xml
dev.langchain4j
langchain4j-community-redis-spring-boot-starter
1.1.0-beta7
```
yml
```yaml
spring
data:
redis:
host: localhost
port: 6379
password:
ttl: 3600
```
config
```java
@Configuration
@ConfigurationProperties(prefix = "spring.data.redis")
@Data
public class RedisChatMemoryStoreConfig {
private String host;
private int port;
private String password;
private long ttl;
@Bean
public RedisChatMemoryStore redisChatMemoryStore() {
return RedisChatMemoryStore.builder()
.host(host)
.port(port)
.password(password)
.ttl(ttl)
.build();
}
}
```
interface
```java
/**
* 保持上下文会话信息到历史记录
* @param memoryId
* @param userMessage
* @return
*/
HtmlCodeResult generateHtmlCode(@MemoryId int memoryId, @UserMessage String userMessage);
```
工厂类构造
```java
@Configuration
public class AiCodeGeneratorServiceFactory {
@Resource
private ChatModel chatModel;
@Resource
private StreamingChatModel streamingChatModel;
// @Bean
// public AiCodeGeneratorService aiCodeGeneratorService() {
// return AiServices.builder(AiCodeGeneratorService.class)
// .chatModel(chatModel)
// .streamingChatModel(streamingChatModel)
// .build();
// }
private final RedisChatMemoryStore redisChatMemoryStore;
public AiCodeGeneratorServiceFactory(RedisChatMemoryStore redisChatMemoryStore) {
this.redisChatMemoryStore = redisChatMemoryStore;
}
@Bean
public AiCodeGeneratorService aiCodeGeneratorService() {
return AiServices.builder(AiCodeGeneratorService.class)
.chatModel(chatModel)
.streamingChatModel(streamingChatModel)
// 根据 id 构建独立的对话记忆
.chatMemoryProvider(memoryId -> MessageWindowChatMemory
.builder()
.id(memoryId)
.chatMemoryStore(redisChatMemoryStore)
.maxMessages(20)
.build())
.build();
}
}
```
测试类测试:
```java
@Test
public void testMemory() {
HtmlCodeResult htmlCodeResult = aiCodeGeneratorService.generateHtmlCode(1, "做个helloword网页,代码总量不超过20行");
System.out.println("第一步:" + htmlCodeResult);
HtmlCodeResult result = aiCodeGeneratorService.generateHtmlCode(1, "不要生成网站,高速我你刚刚做了什么?");
System.out.println("第二步:" + result);
}
```
结果:


# AI工作流