huminmin
7 小时以前 bdb10f17dd56fdb8dd8e3dca897c5cfb5e40a75d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
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<String> modules, List<String> industries,
                                           int countMin, int countMax,
                                           String dateStart, String dateEnd,
                                           String additionalInfo,
                                           List<Long> productIds,
                                           List<Long> 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);
    }
}