package com.ruoyi.mock.prompt; import java.util.List; import java.util.stream.Collectors; /** * 各模块的 AI Prompt 模板 */ public final class MockDataPrompt { private MockDataPrompt() {} public static String buildSystemPrompt() { return """ 你是一个企业ERP系统的数据模拟专家。你需要根据用户提供的行业、数量、时间范围等信息, 生成符合业务逻辑的模拟数据。 要求: 1. 输出必须是纯JSON数组,不要用markdown代码块包裹,不要有任何其他文字 2. 每个JSON对象必须包含 "entity" 字段,值为实体类型名 3. 数据内容要符合指定行业的特征(公司名称、产品名称、联系人等要像该行业的) 4. 所有日期字段必须在指定的时间范围内,严禁使用范围之外的日期 5. 金额、数量等数值字段要合理 6. 同一模块内的实体之间要有引用关系(如销售台账引用客户名称) 7. 所有字符串字段不要使用emoji或特殊unicode字符 8. 合同编号、批号等包含日期的字段,必须使用时间范围内的日期,不要使用示例中的具体日期 """; } public static String buildUserMessage(List modules, List industries, int countMin, int countMax, String dateStart, String dateEnd, String additionalInfo, List productIds, List productModelIds) { StringBuilder sb = new StringBuilder(); sb.append("请为以下行业生成模拟ERP业务数据:\n"); sb.append("- 行业: ").append(String.join("、", industries)).append("\n"); sb.append("- 数据条数: 每种实体 ").append(countMin).append("-").append(countMax).append(" 条\n"); sb.append("- 时间范围: ").append(dateStart).append(" ~ ").append(dateEnd).append("\n"); if (additionalInfo != null && !additionalInfo.isBlank()) { sb.append("- 补充信息: ").append(additionalInfo).append("\n"); } sb.append("\n"); sb.append("可用的产品ID列表: ").append(productIds.stream().map(String::valueOf).collect(Collectors.joining(","))).append("\n"); sb.append("可用的产品规格ID列表: ").append(productModelIds.stream().map(String::valueOf).collect(Collectors.joining(","))).append("\n"); sb.append("\n"); sb.append("需要生成的模块: ").append(String.join("、", modules)).append("\n\n"); if (modules.contains("sales")) { sb.append(buildSalesPrompt(countMin, countMax, dateStart, dateEnd)); } if (modules.contains("purchase")) { sb.append(buildPurchasePrompt(countMin, countMax, dateStart, dateEnd)); } if (modules.contains("quality")) { sb.append(buildQualityPrompt(countMin, countMax, dateStart)); } if (modules.contains("production")) { sb.append(buildProductionPrompt(countMin, countMax, dateStart, dateEnd)); } if (modules.contains("stock")) { sb.append(buildStockPrompt(countMin, countMax, dateStart)); } sb.append("\n请直接输出JSON数组,不要有任何其他内容:"); return sb.toString(); } private static String buildSalesPrompt(int min, int max, String dateStart, String dateEnd) { return """ 销售模块 - 按以下格式生成(注意:示例中的日期仅作格式参考,实际日期必须在 %s ~ %s 范围内): { "entity": "customer", "customerName": "XX科技有限公司", "customerType": "企业客户", "contactPerson": "张三", "contactPhone": "13800138000", "companyAddress": "XX省XX市XX区XX路XX号", "companyPhone": "0513-XXXXXXXX", "taxpayerIdentificationNumber": "91110108XXXXXXXXXX", "maintainer": "李四", "maintenanceTime": "%s", "bankAccount": "622202XXXXXXXXXXXX", "basicBankAccount": "XX银行XX支行", "bankCode": "308100XXXXXX" } { "entity": "salesLedger", "customerName": "引用上面生成的客户名称", "salesContractNo": "XS-年月日-序号", "projectName": "XX项目", "entryDate": "%s", "entryPerson": "张三", "salesman": "销售员姓名", "contractAmount": 50000.00, "paymentMethod": "月结30天", "executionDate": "%s", "deliveryDate": "%s", "type": 1, "productData": [ { "productId": 1, "productModelId": 1, "quantity": 100, "taxInclusiveUnitPrice": 500.00, "taxInclusiveTotalPrice": 50000.00, "taxExclusiveTotalPrice": 44247.79, "taxRate": 13.00, "unit": "件", "type": 1 } ] } 客户名称要像指定行业的公司,合同编号格式XS-年月日-序号(年月日取entryDate的日期),金额合理。 注意 taxExclusiveTotalPrice 是不含税总价,需要根据含税总价和税率计算(=含税总价/(1+税率/100))。 日期范围: %s ~ %s,每种实体生成%d-%d条。 """.formatted(dateStart, dateEnd, dateStart, dateStart, dateStart, dateEnd, dateStart, dateEnd, min, max); } private static String buildPurchasePrompt(int min, int max, String dateStart, String dateEnd) { return """ 采购模块 - 按以下格式生成(注意:示例中的日期仅作格式参考,实际日期必须在 %s ~ %s 范围内): { "entity": "supplier", "supplierName": "XX原材料有限公司", "supplierType": "原材料供应商", "contactUserName": "李四", "contactUserPhone": "13900139000", "companyAddress": "XX省XX市XX区XX路XX号", "companyPhone": "0513-XXXXXXXX", "taxpayerIdentificationNum": "91110108XXXXXXXXXX", "bankAccountName": "XX银行XX支行", "bankAccountNum": "622202XXXXXXXXXXXX", "isWhite": 0 } { "entity": "purchaseLedger", "supplierName": "引用上面生成的供应商名称", "purchaseContractNumber": "CG-年月日-序号", "projectName": "XX采购项目", "entryDate": "%s", "contractAmount": 30000.00, "paymentMethod": "货到付款", "executionDate": "%s", "productData": [ { "productId": 1, "productModelId": 1, "quantity": 50, "taxInclusiveUnitPrice": 600.00, "taxInclusiveTotalPrice": 30000.00, "taxExclusiveTotalPrice": 26548.67, "taxRate": 13.00, "unit": "件", "type": 2 } ] } 供应商名称要像指定行业的供应商,合同编号格式CG-年月日-序号(年月日取entryDate的日期)。 注意 taxExclusiveTotalPrice 是不含税总价,需要根据含税总价和税率计算(=含税总价/(1+税率/100))。 日期范围: %s ~ %s,每种实体生成%d-%d条。 """.formatted(dateStart, dateEnd, dateStart, dateStart, dateStart, dateEnd, min, max); } private static String buildQualityPrompt(int min, int max, String dateStart) { return """ 质量模块 - 按以下格式生成: { "entity": "qualityTestStandard", "standardNo": "QTS-年月日-序号", "standardName": "XX产品检验标准", "inspectType": 0, "remark": "适用于XX行业的质量检验标准" } inspectType: 0=原材料检验, 1=过程检验, 2=出厂检验。三种类型都要覆盖。 standardNo中的年月日使用 %s 这个日期。 { "entity": "qualityTestStandardBinding", "productId": 1, "testStandardId": 1 } 每种实体生成%d-%d条。 """.formatted(dateStart, min, max); } private static String buildProductionPrompt(int min, int max, String dateStart, String dateEnd) { return """ 生产模块 - 按以下格式生成(注意:示例中的日期仅作格式参考,实际日期必须在 %s ~ %s 范围内): { "entity": "productionPlan", "productModelId": 1, "qtyRequired": 200, "requiredDate": "%s", "source": "销售", "promisedDeliveryDate": "%s", "remark": "XX客户订单需求" } { "entity": "productionOrder", "productModelId": 1, "quantity": 200, "planCompleteTime": "%s", "remark": "根据生产计划XX生成" } productionPlan的source可选"销售"或"内部"。 日期范围: %s ~ %s,每种实体生成%d-%d条。 """.formatted(dateStart, dateEnd, dateStart, dateEnd, dateEnd, dateStart, dateEnd, min, max); } private static String buildStockPrompt(int min, int max, String dateStart) { return """ 库存模块 - 按以下格式生成: { "entity": "stockInventory", "productModelId": 1, "qualitity": 500, "batchNo": "BATCH-年月日-序号", "warnNum": 50, "remark": "安全库存" } 每种实体生成%d-%d条。batchNo格式BATCH-年月日-序号,年月日使用 %s 这个日期。 """.formatted(min, max, dateStart); } }