跳到主要内容

最佳实践

本文档提供基于 Lovrabet 平台进行开发的最佳实践指南。

前置阅读

如果您还不了解 Lovrabet 的工具体系,建议先阅读 开发者工具全景


核心理念

AI 负责可标准化的重复劳动,人类专注于创造性的价值输出

  • AI 的优势 - 快速生成、标准化、零错误率的基础功能
  • 人类的优势 - 创造性思维、行业洞察、用户共情能力
  • 完美协作 - AI 提供基础设施,人类构建独特价值

应用场景示例

1. 小程序生态扩展

基于企业数据构建微信小程序、支付宝小程序:

import { createClient } from "@lovrabet/sdk";

const client = createClient({
appCode: "your-enterprise-app",
token: wx.getStorageSync("userToken"),
});

const customerData = await client.models.customers.filter({
region: "华东",
level: "VIP",
});

2. 工作流自动化

构建复杂的审批流程、数据处理管道:

const approvalWorkflow = {
trigger: await client.models.orders.filter({ status: "pending" }),
conditions: [
{ field: "amount", operator: ">", value: 10000 },
{ field: "customer.level", operator: "=", value: "VIP" },
],
actions: ["sendNotification", "createApprovalTask", "updateOrderStatus"],
};

3. 多系统集成中台

连接 Lovrabet 与企业现有系统(ERP、CRM、OA):

const dataHub = {
lovrabet: await lovrabetClient.models.products.filter(),
erp: await erpConnector.getInventory(),
crm: await crmConnector.getCustomers(),
synchronize: () => {
// 复杂的数据同步和转换逻辑
},
};

客户端管理

前端:单例模式复用

// ✅ 推荐:单例模式,全局复用
// src/api/client.ts
import { createClient } from "@lovrabet/sdk";

export const client = createClient({
appCode: "your-app-code",
});

// 在组件中使用
import { client } from "@/api/client";
// ❌ 不推荐:每次都创建新实例
function MyComponent() {
const client = createClient({ appCode: "..." }); // 每次渲染都创建
}

后端:Spring Bean 单例

// ✅ 推荐:使用 @Bean 单例
@Configuration
public class LovrabetConfig {
@Bean
public LovrabetSDKClient lovrabetSDKClient() {
return new LovrabetSDKClient(accessKey, baseUrl);
}
}

安全性

AccessKey 管理

# ✅ 使用环境变量
export LOVRABET_ACCESS_KEY="ak-your-access-key"
// ❌ 前端永远不要硬编码 AccessKey
const client = createClient({
accessKey: "ak-xxx", // 危险!会暴露在浏览器中
});

// ✅ 浏览器中使用 Cookie 或 Token
const client = createClient({
appCode: "your-app-code",
// 自动使用 Cookie 认证
});

敏感数据脱敏

// 前端:脱敏手机号
const maskPhone = (phone: string) => {
return phone.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
};
// 138****8000
// 后端:日志脱敏
String maskedPhone = phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
log.info("客户电话: {}", maskedPhone);

性能优化

分页与防抖

// ✅ 使用分页
const { data } = await client.models.customers.filter({
currentPage: 1,
pageSize: 20,
});

// ✅ 搜索防抖
import { debounce } from "lodash-es";

const handleSearch = debounce(async (keyword) => {
await client.models.customers.filter({ searchKeyword: keyword });
}, 300);

代码分割

// ✅ 路由懒加载
import { lazy } from "react";

const CustomerAnalysis = lazy(() => import("./pages/CustomerAnalysis"));

后端缓存

// 使用 Caffeine 缓存
private final Cache<String, Object> cache = Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(5, TimeUnit.MINUTES)
.build();

错误处理

前端统一处理

try {
const result = await client.models.customers.filter(params);
if (result.success) {
setData(result.data);
} else {
message.error(result.message);
}
} catch (error) {
console.error("API 调用失败:", error);
message.error("网络错误,请稍后重试");
}

后端重试机制

public <T> LovrabetResult<T> executeWithRetry(
Supplier<LovrabetResult<T>> operation, int maxRetries) {
for (int attempt = 0; attempt <= maxRetries; attempt++) {
try {
LovrabetResult<T> result = operation.get();
if (result.isSuccess()) return result;
Thread.sleep((long) Math.pow(2, attempt) * 1000);
} catch (Exception e) {
if (attempt == maxRetries) throw new RuntimeException("重试失败", e);
}
}
return null;
}

日志规范

结构化日志

@Slf4j
public class DataService {
public void createData(Map<String, Object> data) {
long startTime = System.currentTimeMillis();

log.info("开始操作 - operation={}, dataSize={}", "create", data.size());

LovrabetResult<String> result = sdkClient.create(request);
long duration = System.currentTimeMillis() - startTime;

if (result.isSuccess()) {
log.info("操作成功 - id={}, duration={}ms", result.getData(), duration);
} else {
log.error("操作失败 - code={}, duration={}ms", result.getResultCode(), duration);
}
}
}

测试策略

前端单元测试

import { render, screen, waitFor } from "@testing-library/react";

test("should load customers", async () => {
render(<CustomerList />);
await waitFor(() => {
expect(screen.getByText("张三")).toBeInTheDocument();
});
});

后端集成测试

@SpringBootTest
public class DataServiceIntegrationTest {
@Autowired
private DataService dataService;

@Test
public void testGetCustomers() {
List<Map<String, Object>> customers = dataService.getCustomers(1, 10);
assertNotNull(customers);
assertTrue(customers.size() > 0);
}
}

部署建议

前端部署

lovrabet build
# 产物在 dist/ 目录,部署到 CDN

Nginx 配置

server {
listen 80;
root /var/www/your-app/dist;

location / {
try_files $uri $uri/ /index.html;
}

location ~* \.(js|css|png|jpg|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}

后端 Docker 部署

FROM openjdk:11-jre-slim
WORKDIR /app
COPY target/myapp.jar app.jar
ENV LOVRABET_ACCESS_KEY=""
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

健康检查

@GetMapping("/health/lovrabet")
public Map<String, Object> checkHealth() {
Map<String, Object> health = new HashMap<>();
try {
long start = System.currentTimeMillis();
LovrabetResult<?> result = sdkClient.getDatasetCodeList(request);
health.put("status", result.isSuccess() ? "UP" : "DOWN");
health.put("responseTime", (System.currentTimeMillis() - start) + "ms");
} catch (Exception e) {
health.put("status", "DOWN");
health.put("error", e.getMessage());
}
return health;
}

总结

实践领域核心要点
客户端管理前后端都使用单例模式
安全性永远不要在前端硬编码 AccessKey
性能优化分页、缓存、代码分割
错误处理统一处理 + 重试机制
日志管理结构化日志、敏感信息脱敏
测试策略单元测试 + 集成测试
部署健康检查、容器化

相关文档