From 33250ae12ae0649010436bcc636e44d6acd6d86b Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 15 六月 2026 09:40:57 +0800
Subject: [PATCH] 修改客户,销售,协同,报价,质量

---
 src/main/java/com/ruoyi/mock/service/DataCheckService.java             |   15 
 docs/routing_operation_plan_person.md                                  |   91 +++
 src/main/java/com/ruoyi/mock/vo/DataGenerateResult.java                |   37 +
 src/main/java/com/ruoyi/mock/vo/DataCheckResult.java                   |   36 +
 src/main/java/com/ruoyi/mock/dto/DataCheckRequest.java                 |   15 
 src/main/java/com/ruoyi/mock/service/DataGenerateService.java          |   15 
 docs/mock_data_check.md                                                |  167 ++++++
 doc/20260615_add_plan_person_and_executor_to_routing_operation.sql     |    8 
 src/main/java/com/ruoyi/mock/service/impl/DataCheckServiceImpl.java    |  146 +++++
 src/main/java/com/ruoyi/mock/controller/DataCheckController.java       |   54 ++
 src/main/java/com/ruoyi/mock/prompt/MockDataPrompt.java                |  213 ++++++++
 docs/mock_data_generate.md                                             |  243 +++++++++
 src/main/java/com/ruoyi/mock/service/impl/DataGenerateServiceImpl.java |  466 +++++++++++++++++
 src/main/java/com/ruoyi/mock/dto/DataGenerateRequest.java              |   33 +
 14 files changed, 1,539 insertions(+), 0 deletions(-)

diff --git a/doc/20260615_add_plan_person_and_executor_to_routing_operation.sql b/doc/20260615_add_plan_person_and_executor_to_routing_operation.sql
new file mode 100644
index 0000000..b98e8ca
--- /dev/null
+++ b/doc/20260615_add_plan_person_and_executor_to_routing_operation.sql
@@ -0,0 +1,8 @@
+# 鐢熶骇宸ュ簭鏂板璁″垝浜哄憳鍜岃鍒掓墽琛屼汉鍛樺瓧娈�
+ALTER TABLE technology_routing_operation
+    ADD plan_person bigint NULL COMMENT '璁″垝浜哄憳ID',
+    ADD executor bigint NULL COMMENT '璁″垝鎵ц浜哄憳ID';
+
+ALTER TABLE production_order_routing_operation
+    ADD plan_person bigint NULL COMMENT '璁″垝浜哄憳ID',
+    ADD executor bigint NULL COMMENT '璁″垝鎵ц浜哄憳ID';
diff --git a/docs/mock_data_check.md b/docs/mock_data_check.md
new file mode 100644
index 0000000..e423eb5
--- /dev/null
+++ b/docs/mock_data_check.md
@@ -0,0 +1,167 @@
+# 鏁版嵁妯℃嫙 - 鍩虹鏁版嵁妫�娴�
+
+## 娑夊強椤甸潰
+
+- 鏁版嵁妯℃嫙鎿嶄綔椤甸潰锛堟柊澧烇級
+
+## API
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | /mock/dataCheck | 妫�娴嬫寚瀹氭ā鍧楃殑鍩虹鏁版嵁鏄惁灏辩华 |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| modules | List\<String\> | 鏄� | 瑕佹娴嬬殑妯″潡鍒楄〃锛屽彲閫夊�硷細sales锛堥攢鍞級銆乸urchase锛堥噰璐級銆乹uality锛堣川閲忥級 |
+
+璇锋眰浣撶ず渚嬶細
+```json
+{ "modules": ["sales", "purchase", "quality"] }
+```
+
+**鍝嶅簲锛�**
+```json
+{
+  "code": 200,
+  "msg": "鎿嶄綔鎴愬姛",
+  "data": {
+    "totalItems": 6,
+    "passedItems": 3,
+    "items": [
+      {
+        "module": "common",
+        "itemName": "浜у搧鏁版嵁",
+        "minRequired": 1,
+        "currentCount": 5,
+        "passed": true,
+        "message": "閫氳繃"
+      },
+      {
+        "module": "sales",
+        "itemName": "瀹㈡埛鏁版嵁",
+        "minRequired": 1,
+        "currentCount": 0,
+        "passed": false,
+        "message": "缂哄皯瀹㈡埛鏁版嵁锛岃鍏堝湪銆愬熀纭�鏁版嵁-瀹㈡埛绠$悊銆戜腑娣诲姞鑷冲皯1鏉″鎴�"
+      }
+    ]
+  }
+}
+```
+
+## 妫�娴嬭鍒�
+
+### 閿�鍞ā鍧� (sales)
+| 妫�娴嬮」 | 鏈�浣庢暟閲� | 鏈�氳繃鎻愮ず |
+|--------|----------|------------|
+| 浜у搧鏁版嵁 | 1 | 缂哄皯浜у搧鏁版嵁锛岃鍏堝湪銆愬熀纭�鏁版嵁-浜у搧绠$悊銆戜腑娣诲姞鑷冲皯1鏉′骇鍝� |
+| 瀹㈡埛鏁版嵁 | 1 | 缂哄皯瀹㈡埛鏁版嵁锛岃鍏堝湪銆愬熀纭�鏁版嵁-瀹㈡埛绠$悊銆戜腑娣诲姞鑷冲皯1鏉″鎴� |
+| 鎶ヤ环瀹℃壒妯℃澘 | 1 | 缂哄皯鎶ヤ环瀹℃壒妯℃澘锛岃鍏堝湪銆愮郴缁熺鐞�-瀹℃壒妯℃澘銆戜腑鍒涘缓鎶ヤ环瀹℃壒妯℃澘 |
+| 鍙戣揣瀹℃壒妯℃澘 | 1 | 缂哄皯鍙戣揣瀹℃壒妯℃澘锛岃鍏堝湪銆愮郴缁熺鐞�-瀹℃壒妯℃澘銆戜腑鍒涘缓鍙戣揣瀹℃壒妯℃澘 |
+
+### 閲囪喘妯″潡 (purchase)
+| 妫�娴嬮」 | 鏈�浣庢暟閲� | 鏈�氳繃鎻愮ず |
+|--------|----------|------------|
+| 浜у搧鏁版嵁 | 1 | 缂哄皯浜у搧鏁版嵁锛岃鍏堝湪銆愬熀纭�鏁版嵁-浜у搧绠$悊銆戜腑娣诲姞鑷冲皯1鏉′骇鍝� |
+| 渚涘簲鍟嗘暟鎹� | 1 | 缂哄皯渚涘簲鍟嗘暟鎹紝璇峰厛鍦ㄣ�愬熀纭�鏁版嵁-渚涘簲鍟嗙鐞嗐�戜腑娣诲姞鑷冲皯1鏉′緵搴斿晢 |
+| 閲囪喘瀹℃壒妯℃澘 | 1 | 缂哄皯閲囪喘瀹℃壒妯℃澘锛岃鍏堝湪銆愮郴缁熺鐞�-瀹℃壒妯℃澘銆戜腑鍒涘缓閲囪喘瀹℃壒妯℃澘 |
+
+### 璐ㄩ噺妯″潡 (quality)
+| 妫�娴嬮」 | 鏈�浣庢暟閲� | 鏈�氳繃鎻愮ず |
+|--------|----------|------------|
+| 浜у搧鏁版嵁 | 1 | 缂哄皯浜у搧鏁版嵁锛岃鍏堝湪銆愬熀纭�鏁版嵁-浜у搧绠$悊銆戜腑娣诲姞鑷冲皯1鏉′骇鍝� |
+| 妫�娴嬫爣鍑� | 1 | 缂哄皯妫�娴嬫爣鍑嗭紝璇峰厛鍦ㄣ�愯川閲忕鐞�-妫�娴嬫爣鍑嗐�戜腑鍒涘缓妫�娴嬫爣鍑� |
+| 鎸囨爣缁戝畾 | 1 | 缂哄皯鎸囨爣缁戝畾锛岃鍏堝湪銆愯川閲忕鐞�-妫�娴嬫爣鍑嗙粦瀹氥�戜腑灏嗘娴嬫爣鍑嗕笌浜у搧缁戝畾 |
+
+## 鍓嶇淇敼鐐�
+
+### 1. 鏁版嵁妯℃嫙椤甸潰鍏ュ彛
+
+鍦ㄥ乏渚ц彍鍗曟柊澧�"鏁版嵁妯℃嫙"鑿滃崟椤癸紝璺敱 `/mock`銆�
+
+### 2. 鏁版嵁妫�娴嬪尯鍩�
+
+```html
+<template>
+  <div class="mock-container">
+    <el-card header="鍩虹鏁版嵁妫�娴�">
+      <el-checkbox-group v-model="selectedModules">
+        <el-checkbox label="sales">閿�鍞ā鍧�</el-checkbox>
+        <el-checkbox label="purchase">閲囪喘妯″潡</el-checkbox>
+        <el-checkbox label="quality">璐ㄩ噺妯″潡</el-checkbox>
+      </el-checkbox-group>
+      <el-button type="primary" @click="handleCheck" :loading="checking">
+        寮�濮嬫娴�
+      </el-button>
+    </el-card>
+
+    <el-card v-if="checkResult" header="妫�娴嬬粨鏋�" style="margin-top: 16px">
+      <el-alert
+        :title="`閫氳繃 ${checkResult.passedItems} / ${checkResult.totalItems} 椤筦"
+        :type="checkResult.passedItems === checkResult.totalItems ? 'success' : 'warning'"
+        :closable="false"
+        show-icon
+      />
+      <el-table :data="checkResult.items" style="margin-top: 12px">
+        <el-table-column prop="module" label="妯″潡" width="100" />
+        <el-table-column prop="itemName" label="妫�娴嬮」" width="160" />
+        <el-table-column prop="minRequired" label="鏈�浣庤姹�" width="80" />
+        <el-table-column prop="currentCount" label="褰撳墠鏁伴噺" width="80" />
+        <el-table-column label="鐘舵��" width="80">
+          <template #default="{ row }">
+            <el-tag :type="row.passed ? 'success' : 'danger'">
+              {{ row.passed ? '閫氳繃' : '鏈�氳繃' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="message" label="鎻愮ず" />
+      </el-table>
+    </el-card>
+  </div>
+</template>
+```
+
+### 3. data 鏁版嵁
+
+```js
+data() {
+  return {
+    selectedModules: ['sales', 'purchase', 'quality'],
+    checking: false,
+    checkResult: null,
+  }
+}
+```
+
+### 4. 鏂规硶
+
+```js
+import request from '@/utils/request'
+
+methods: {
+  async handleCheck() {
+    if (this.selectedModules.length === 0) {
+      this.$message.warning('璇疯嚦灏戦�夋嫨涓�涓ā鍧�')
+      return
+    }
+    this.checking = true
+    try {
+      const res = await request.post('/mock/dataCheck', {
+        modules: this.selectedModules
+      })
+      this.checkResult = res.data
+    } finally {
+      this.checking = false
+    }
+  }
+}
+```
+
+## 娉ㄦ剰浜嬮」
+
+- 浜у搧鏁版嵁锛堝叕鍏卞熀纭�锛夊湪澶氫釜妯″潡闂村叡浜紝妫�娴嬬粨鏋滀腑鍙嚭鐜颁竴娆★紝涓嶄細閲嶅灞曠ず
+- 妫�娴嬩粎鍋氬彧璇绘煡璇紝涓嶅啓鍏ヤ换浣曟暟鎹�
+- 妯″潡鍙傛暟涓虹┖鏁扮粍鏃惰繑鍥炵┖妫�娴嬪垪琛�
+- 寤鸿鍦ㄦ暟鎹ā鎷熷紑濮嬪墠鍏堣皟鐢ㄦ鎺ュ彛纭鍩虹鏁版嵁灏辩华
diff --git a/docs/mock_data_generate.md b/docs/mock_data_generate.md
new file mode 100644
index 0000000..6dc801e
--- /dev/null
+++ b/docs/mock_data_generate.md
@@ -0,0 +1,243 @@
+# 鏁版嵁妯℃嫙 - AI 鏁版嵁鐢熸垚
+
+## 娑夊強椤甸潰
+
+- 鏁版嵁妯℃嫙鎿嶄綔椤甸潰锛堟柊澧�/淇敼锛�
+
+## API
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | /mock/generate | AI 鐢熸垚妯℃嫙鏁版嵁锛堝惈鍓嶇疆鍩虹鏁版嵁妫�娴嬶級 |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| modules | List\<String\> | 鏄� | 瑕佺敓鎴愭暟鎹殑妯″潡锛歴ales锛堥攢鍞級銆乸urchase锛堥噰璐級銆乹uality锛堣川閲忥級銆乸roduction锛堢敓浜э級銆乻tock锛堝簱瀛橈級 |
+| industries | List\<String\> | 鏄� | 琛屼笟锛屽锛歔"鏈烘鍒堕��", "椋熷搧鍔犲伐", "鐢靛瓙瑁呴厤"] |
+| countMin | int | 鍚� | 姣忎釜瀹炰綋鐢熸垚鏉℃暟鏈�灏忓�硷紝榛樿 3 |
+| countMax | int | 鍚� | 姣忎釜瀹炰綋鐢熸垚鏉℃暟鏈�澶у�硷紝榛樿 10 |
+| dateStart | String | 鍚� | 鏃堕棿鑼冨洿寮�濮嬶紙yyyy-MM-dd锛� |
+| dateEnd | String | 鍚� | 鏃堕棿鑼冨洿缁撴潫锛坹yyy-MM-dd锛� |
+| additionalInfo | String | 鍚� | 鍏朵粬琛ュ厖鎻忚堪锛屽"浜у搧浠ラ噾灞為浂閮ㄤ欢涓轰富" |
+
+璇锋眰浣撶ず渚嬶細
+```json
+{
+  "modules": ["sales", "purchase", "quality"],
+  "industries": ["鏈烘鍒堕��", "鐢靛瓙瑁呴厤"],
+  "countMin": 3,
+  "countMax": 8,
+  "dateStart": "2026-01-01",
+  "dateEnd": "2026-06-01",
+  "additionalInfo": "浜у搧浠ラ噾灞為浂閮ㄤ欢鍜岀數瀛愬厓鍣ㄤ欢涓轰富"
+}
+```
+
+**鍝嶅簲锛堟垚鍔燂級锛�**
+```json
+{
+  "code": 200,
+  "msg": "鎿嶄綔鎴愬姛",
+  "data": {
+    "status": "SUCCESS",
+    "totalGenerated": 24,
+    "moduleSummaries": [
+      { "module": "sales", "entityName": "瀹㈡埛", "generatedCount": 5, "successCount": 5, "failCount": 0 },
+      { "module": "sales", "entityName": "閿�鍞彴璐�", "generatedCount": 5, "successCount": 5, "failCount": 0 },
+      { "module": "purchase", "entityName": "渚涘簲鍟�", "generatedCount": 4, "successCount": 4, "failCount": 0 },
+      { "module": "purchase", "entityName": "閲囪喘鍙拌处", "generatedCount": 4, "successCount": 4, "failCount": 0 },
+      { "module": "quality", "entityName": "妫�娴嬫爣鍑�", "generatedCount": 3, "successCount": 3, "failCount": 0 },
+      { "module": "quality", "entityName": "鎸囨爣缁戝畾", "generatedCount": 3, "successCount": 3, "failCount": 0 }
+    ],
+    "errors": [],
+    "checkResult": null
+  }
+}
+```
+
+**鍝嶅簲锛堝熀纭�鏁版嵁涓嶈冻锛屽墠缃娴嬫湭閫氳繃锛夛細**
+```json
+{
+  "code": 500,
+  "msg": "鍩虹鏁版嵁涓嶈冻锛岃鍏堣ˉ鍏呭悗鍐嶇敓鎴�",
+  "data": {
+    "status": "CHECK_FAILED",
+    "checkResult": {
+      "totalItems": 6,
+      "passedItems": 3,
+      "items": [
+        { "module": "common", "itemName": "浜у搧鏁版嵁", "passed": true, "message": "閫氳繃" },
+        { "module": "sales", "itemName": "瀹㈡埛鏁版嵁", "passed": false, "message": "缂哄皯瀹㈡埛鏁版嵁锛岃鍏�..." }
+      ]
+    }
+  }
+}
+```
+
+## 宸ヤ綔娴佺▼
+
+1. 鐢ㄦ埛鍦ㄩ〉闈㈤�夋嫨妯″潡 + 濉啓琛屼笟/鏁伴噺/鏃堕棿绛変俊鎭�
+2. 璋冪敤 `POST /mock/generate`
+3. 鍚庣棣栧厛璋冪敤 `POST /mock/dataCheck` 妫�娴嬪熀纭�鏁版嵁鏄惁灏辩华
+4. 鑻ュ熀纭�鏁版嵁涓嶈冻锛岃繑鍥炴娴嬬粨鏋滐紝鎻愮ず鐢ㄦ埛鍏堣ˉ榻�
+5. 鑻ュ熀纭�鏁版嵁灏辩华锛岃皟鐢� AI 澶фā鍨嬬敓鎴愮鍚堣涓氱壒寰佺殑 JSON 鏁版嵁
+6. 鎸変緷璧栭『搴忓垱寤烘暟鎹紙瀹㈡埛鈫掗攢鍞彴璐︺�佷緵搴斿晢鈫掗噰璐彴璐︺�佹娴嬫爣鍑嗏啋鎸囨爣缁戝畾...锛�
+7. 杩斿洖鐢熸垚鎽樿
+
+## 鍓嶇淇敼鐐�
+
+### 1. 鏁版嵁鐢熸垚鍖哄煙锛堝湪鏁版嵁妫�娴嬪尯鍩熶笅鏂癸級
+
+```html
+<el-card header="AI 鏁版嵁鐢熸垚" style="margin-top: 16px">
+  <el-form :model="generateForm" label-width="100px">
+    <el-form-item label="閫夋嫨妯″潡">
+      <el-checkbox-group v-model="generateForm.modules">
+        <el-checkbox label="sales">閿�鍞�</el-checkbox>
+        <el-checkbox label="purchase">閲囪喘</el-checkbox>
+        <el-checkbox label="quality">璐ㄩ噺</el-checkbox>
+        <el-checkbox label="production">鐢熶骇</el-checkbox>
+        <el-checkbox label="stock">搴撳瓨</el-checkbox>
+      </el-checkbox-group>
+    </el-form-item>
+
+    <el-form-item label="琛屼笟">
+      <el-select
+        v-model="generateForm.industries"
+        multiple
+        filterable
+        allow-create
+        placeholder="杈撳叆鎴栭�夋嫨琛屼笟"
+      >
+        <el-option label="鏈烘鍒堕��" value="鏈烘鍒堕��" />
+        <el-option label="椋熷搧鍔犲伐" value="椋熷搧鍔犲伐" />
+        <el-option label="鐢靛瓙瑁呴厤" value="鐢靛瓙瑁呴厤" />
+        <el-option label="姹借溅闆堕儴浠�" value="姹借溅闆堕儴浠�" />
+        <el-option label="鍖荤枟鍣ㄦ" value="鍖荤枟鍣ㄦ" />
+        <el-option label="鍖栧伐鏉愭枡" value="鍖栧伐鏉愭枡" />
+        <el-option label="绾虹粐鏈嶈" value="绾虹粐鏈嶈" />
+        <el-option label="瀹跺叿鍒堕��" value="瀹跺叿鍒堕��" />
+      </el-select>
+    </el-form-item>
+
+    <el-row :gutter="16">
+      <el-col :span="12">
+        <el-form-item label="鐢熸垚鏉℃暟">
+          <el-slider
+            v-model="generateForm.countRange"
+            range
+            :min="1"
+            :max="50"
+            :marks="{1:'1', 10:'10', 20:'20', 50:'50'}"
+          />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="鏃堕棿鑼冨洿">
+          <el-date-picker
+            v-model="generateForm.dateRange"
+            type="daterange"
+            range-separator="鑷�"
+            start-placeholder="寮�濮嬫棩鏈�"
+            end-placeholder="缁撴潫鏃ユ湡"
+            value-format="yyyy-MM-dd"
+          />
+        </el-form-item>
+      </el-col>
+    </el-row>
+
+    <el-form-item label="琛ュ厖淇℃伅">
+      <el-input
+        v-model="generateForm.additionalInfo"
+        type="textarea"
+        :rows="2"
+        placeholder="濡傦細浜у搧浠ラ噾灞為浂閮ㄤ欢涓轰富锛屽鎴烽泦涓湪鍗庝笢鍦板尯"
+      />
+    </el-form-item>
+
+    <el-form-item>
+      <el-button type="primary" @click="handleGenerate" :loading="generating">
+        寮�濮嬬敓鎴�
+      </el-button>
+      <el-button @click="handleCheckFirst" :loading="checking">
+        鍏堟娴嬪啀鐢熸垚
+      </el-button>
+    </el-form-item>
+  </el-form>
+</el-card>
+```
+
+### 3. data 鏁版嵁
+
+```js
+data() {
+  return {
+    generateForm: {
+      modules: [],
+      industries: [],
+      countRange: [3, 10],
+      dateRange: [],
+      additionalInfo: '',
+    },
+    generating: false,
+    generateResult: null,
+  }
+}
+```
+
+### 4. 鏂规硶
+
+```js
+methods: {
+  // 鐩存帴鐢熸垚锛堝唴閮ㄨ嚜鍔ㄦ娴嬶級
+  async handleGenerate() {
+    if (this.generateForm.modules.length === 0) {
+      this.$message.warning('璇疯嚦灏戦�夋嫨涓�涓ā鍧�')
+      return
+    }
+    this.generating = true
+    try {
+      const res = await request.post('/mock/generate', {
+        modules: this.generateForm.modules,
+        industries: this.generateForm.industries,
+        countMin: this.generateForm.countRange[0],
+        countMax: this.generateForm.countRange[1],
+        dateStart: this.generateForm.dateRange[0] || null,
+        dateEnd: this.generateForm.dateRange[1] || null,
+        additionalInfo: this.generateForm.additionalInfo,
+      })
+      if (res.code === 200) {
+        this.generateResult = res.data
+        this.$message.success(`鎴愬姛鐢熸垚 ${res.data.totalGenerated} 鏉℃暟鎹甡)
+      } else {
+        // 鍩虹鏁版嵁涓嶈冻
+        this.generateResult = res.data
+        this.checkResult = res.data.checkResult
+        this.$message.warning(res.msg)
+      }
+    } finally {
+      this.generating = false
+    }
+  },
+
+  // 鍏堟娴嬪啀鐢熸垚
+  async handleCheckFirst() {
+    await this.handleCheck()
+    if (this.checkResult && this.checkResult.passedItems === this.checkResult.totalItems) {
+      await this.handleGenerate()
+    } else {
+      this.$message.warning('璇峰厛琛ラ綈鍩虹鏁版嵁鍚庡啀鐢熸垚')
+    }
+  },
+}
+```
+
+## 娉ㄦ剰浜嬮」
+
+- `POST /mock/generate` 鍐呴儴浼氳嚜鍔ㄨ皟鐢ㄦ暟鎹娴嬶紝涓嶉渶瑕佹墜鍔ㄥ垎涓ゆ璧�
+- AI 鐢熸垚鐨勬暟鎹細灏介噺绗﹀悎琛屼笟鐗瑰緛锛屼絾寤鸿鐢熸垚鍚庢鏌ュ叧閿暟鎹殑鍚堢悊鎬�
+- 鐢熶骇妯″潡鍜屽簱瀛樻ā鍧椾緷璧栦骇鍝佹暟鎹紙Product/ProductModel锛夛紝璇风‘淇濆熀纭�鏁版嵁涓湁浜у搧
+- 閿�鍞彴璐︾殑鍚堝悓閲戦鐢变骇鍝佹槑缁嗚嚜鍔ㄨ绠楋紝AI 鍙渶鐢熸垚浜у搧琛岀殑鍗曚环鍜屾暟閲�
+- 浜х敓鐨勬暟鎹�氳繃鏈嶅姟灞傚垱寤猴紝浼氳嚜鍔ㄥ~鍏� tenantId/deptId/createUser 绛夊瓧娈�
diff --git a/docs/routing_operation_plan_person.md b/docs/routing_operation_plan_person.md
new file mode 100644
index 0000000..999d9a3
--- /dev/null
+++ b/docs/routing_operation_plan_person.md
@@ -0,0 +1,91 @@
+# 鐢熶骇宸ュ簭鏂板璁″垝浜哄憳鍜岃鍒掓墽琛屼汉鍛�
+
+## 娑夊強椤甸潰
+
+- 宸ヨ壓璺嚎宸ュ簭绠$悊椤甸潰锛坱echnology_routing_operation锛�
+
+## API
+
+娑夊強浠ヤ笅鎺ュ彛鐨勮姹�/鍝嶅簲鏂板瀛楁锛�
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /technologyRoutingOperation/page | 鍒嗛〉鏌ヨ |
+| GET | /technologyRoutingOperation/list | 鍒楄〃鏌ヨ |
+| GET | /technologyRoutingOperation/{id} | 璇︽儏 |
+| POST | /technologyRoutingOperation/add | 鏂板 |
+| PUT | /technologyRoutingOperation | 淇敼 |
+
+**鏂板鍝嶅簲/璇锋眰瀛楁锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| planPerson | Long | 鍚� | 璁″垝浜哄憳ID |
+| executor | Long | 鍚� | 璁″垝鎵ц浜哄憳ID |
+| planPersonName | String | 鍚� | 璁″垝浜哄憳濮撳悕锛堝搷搴斿瓧娈碉紝鍚庣鑷姩鍏宠仈鏌ヨ锛� |
+| executorName | String | 鍚� | 璁″垝鎵ц浜哄憳濮撳悕锛堝搷搴斿瓧娈碉紝鍚庣鑷姩鍏宠仈鏌ヨ锛� |
+
+## 鍓嶇淇敼鐐�
+
+### 1. 琛ㄥ崟鏂板瀛楁
+
+鍦ㄥ伐搴忚〃鍗曚腑鏂板涓や釜浜哄憳閫夋嫨涓嬫媺妗嗭細
+
+```html
+<el-form-item label="璁″垝浜哄憳" prop="planPerson">
+  <el-select v-model="processForm.planPerson"
+             placeholder="璇烽�夋嫨璁″垝浜哄憳"
+             clearable
+             filterable
+             style="width: 100%">
+    <el-option v-for="item in employeeOptions"
+               :key="item.id"
+               :label="item.staffName"
+               :value="item.id" />
+  </el-select>
+</el-form-item>
+<el-form-item label="璁″垝鎵ц浜哄憳" prop="executor">
+  <el-select v-model="processForm.executor"
+             placeholder="璇烽�夋嫨璁″垝鎵ц浜哄憳"
+             clearable
+             filterable
+             style="width: 100%">
+    <el-option v-for="item in employeeOptions"
+               :key="item.id"
+               :label="item.staffName"
+               :value="item.id" />
+  </el-select>
+</el-form-item>
+```
+
+### 2. data 鏁版嵁
+
+```js
+data() {
+  return {
+    processForm: {
+      planPerson: null,
+      executor: null,
+      // ...鍏朵粬瀛楁
+    },
+    employeeOptions: [],  // 鍛樺伐鍒楄〃锛岄渶浠庢帴鍙h幏鍙�
+  }
+}
+```
+
+### 3. 琛ㄦ牸鍒楁柊澧�
+
+鍒楄〃涓彲鐩存帴浣跨敤鍚庣杩斿洖鐨勫鍚嶅睍绀猴細
+
+```html
+<el-table-column label="璁″垝浜哄憳" prop="planPersonName" />
+<el-table-column label="璁″垝鎵ц浜哄憳" prop="executorName" />
+```
+
+## 娉ㄦ剰浜嬮」
+
+- `planPerson` 鍜� `executor` 瀛樺偍鐨勬槸鍛樺伐ID锛圠ong绫诲瀷锛夛紝鎻愪氦琛ㄥ崟鏃朵紶ID
+- 鍝嶅簲涓� `planPersonName` 鍜� `executorName` 鐢卞悗绔�氳繃 `staff_on_job` 琛ㄨ嚜鍔ㄥ叧鑱旀煡璇紝鍓嶇鏃犻渶棰濆杞崲
+- 鍛樺伐涓嬫媺鍒楄〃鏁版嵁闇�浠庡憳宸ユ帴鍙h幏鍙栵紙鍙傝�冪幇鏈� `employeeOptions` 鏁版嵁婧愶級
+- 鏁版嵁搴撹縼绉籗QL锛歚doc/20260615_add_plan_person_and_executor_to_routing_operation.sql`
+- 鐢熶骇璁㈠崟宸ュ簭锛坄production_order_routing_operation`锛夊悓姝ユ敮鎸佽繖涓や釜瀛楁
diff --git a/src/main/java/com/ruoyi/mock/controller/DataCheckController.java b/src/main/java/com/ruoyi/mock/controller/DataCheckController.java
new file mode 100644
index 0000000..e8c0b8d
--- /dev/null
+++ b/src/main/java/com/ruoyi/mock/controller/DataCheckController.java
@@ -0,0 +1,54 @@
+package com.ruoyi.mock.controller;
+
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.mock.dto.DataCheckRequest;
+import com.ruoyi.mock.dto.DataGenerateRequest;
+import com.ruoyi.mock.service.DataCheckService;
+import com.ruoyi.mock.service.DataGenerateService;
+import com.ruoyi.mock.vo.DataCheckResult;
+import com.ruoyi.mock.vo.DataCheckResult.CheckItem;
+import com.ruoyi.mock.vo.DataGenerateResult;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/mock")
+@RequiredArgsConstructor
+@Tag(name = "鏁版嵁妯℃嫙")
+public class DataCheckController {
+
+    private final DataCheckService dataCheckService;
+    private final DataGenerateService dataGenerateService;
+
+    @PostMapping("/dataCheck")
+    @Operation(summary = "妫�娴嬪熀纭�鏁版嵁")
+    public R<DataCheckResult> dataCheck(@RequestBody DataCheckRequest request) {
+        DataCheckResult result = dataCheckService.check(request);
+        return R.ok(result);
+    }
+
+    @PostMapping("/generate")
+    @Operation(summary = "AI鐢熸垚妯℃嫙鏁版嵁")
+    public R<?> generate(@RequestBody DataGenerateRequest request) {
+        // 鍏堟牎楠屽熀纭�鏁版嵁
+        DataCheckRequest checkRequest = new DataCheckRequest();
+        checkRequest.setModules(request.getModules());
+        DataCheckResult checkResult = dataCheckService.check(checkRequest);
+
+        boolean allPassed = checkResult.getItems().stream().allMatch(CheckItem::isPassed);
+        if (!allPassed) {
+            DataGenerateResult failResult = new DataGenerateResult();
+            failResult.setStatus("CHECK_FAILED");
+            failResult.setCheckResult(checkResult);
+            return R.fail(failResult, "鍩虹鏁版嵁涓嶈冻锛岃鍏堣ˉ鍏呭悗鍐嶇敓鎴�");
+        }
+
+        DataGenerateResult result = dataGenerateService.generate(request);
+        return R.ok(result);
+    }
+}
diff --git a/src/main/java/com/ruoyi/mock/dto/DataCheckRequest.java b/src/main/java/com/ruoyi/mock/dto/DataCheckRequest.java
new file mode 100644
index 0000000..9e1d7db
--- /dev/null
+++ b/src/main/java/com/ruoyi/mock/dto/DataCheckRequest.java
@@ -0,0 +1,15 @@
+package com.ruoyi.mock.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 鍩虹鏁版嵁妫�娴嬭姹�
+ */
+@Data
+public class DataCheckRequest {
+
+    /** 闇�瑕佹娴嬬殑妯″潡: sales / purchase / quality */
+    private List<String> modules;
+}
diff --git a/src/main/java/com/ruoyi/mock/dto/DataGenerateRequest.java b/src/main/java/com/ruoyi/mock/dto/DataGenerateRequest.java
new file mode 100644
index 0000000..9f9522c
--- /dev/null
+++ b/src/main/java/com/ruoyi/mock/dto/DataGenerateRequest.java
@@ -0,0 +1,33 @@
+package com.ruoyi.mock.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * AI鏁版嵁鐢熸垚璇锋眰
+ */
+@Data
+public class DataGenerateRequest {
+
+    /** 瑕佺敓鎴愭暟鎹殑妯″潡: sales / purchase / quality / production / stock */
+    private List<String> modules;
+
+    /** 琛屼笟锛堝涓級锛屽: ["鏈烘鍒堕��", "椋熷搧鍔犲伐", "鐢靛瓙瑁呴厤"] */
+    private List<String> industries;
+
+    /** 姣忎釜瀹炰綋鐢熸垚鏁伴噺鐨勬渶灏忓�� */
+    private int countMin;
+
+    /** 姣忎釜瀹炰綋鐢熸垚鏁伴噺鐨勬渶澶у�� */
+    private int countMax;
+
+    /** 鏃堕棿鑼冨洿-寮�濮�, yyyy-MM-dd */
+    private String dateStart;
+
+    /** 鏃堕棿鑼冨洿-缁撴潫, yyyy-MM-dd */
+    private String dateEnd;
+
+    /** 鍏朵粬琛ュ厖鎻忚堪 */
+    private String additionalInfo;
+}
diff --git a/src/main/java/com/ruoyi/mock/prompt/MockDataPrompt.java b/src/main/java/com/ruoyi/mock/prompt/MockDataPrompt.java
new file mode 100644
index 0000000..e52ab8e
--- /dev/null
+++ b/src/main/java/com/ruoyi/mock/prompt/MockDataPrompt.java
@@ -0,0 +1,213 @@
+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 """
+            浣犳槸涓�涓紒涓欵RP绯荤粺鐨勬暟鎹ā鎷熶笓瀹躲�備綘闇�瑕佹牴鎹敤鎴锋彁渚涚殑琛屼笟銆佹暟閲忋�佹椂闂磋寖鍥寸瓑淇℃伅锛�
+            鐢熸垚绗﹀悎涓氬姟閫昏緫鐨勬ā鎷熸暟鎹��
+
+            瑕佹眰:
+            1. 杈撳嚭蹇呴』鏄函JSON鏁扮粍锛屼笉瑕佺敤markdown浠g爜鍧楀寘瑁癸紝涓嶈鏈変换浣曞叾浠栨枃瀛�
+            2. 姣忎釜JSON瀵硅薄蹇呴』鍖呭惈 "entity" 瀛楁锛屽�间负瀹炰綋绫诲瀷鍚�
+            3. 鏁版嵁鍐呭瑕佺鍚堟寚瀹氳涓氱殑鐗瑰緛锛堝叕鍙稿悕绉般�佷骇鍝佸悕绉般�佽仈绯讳汉绛夎鍍忚琛屼笟鐨勶級
+            4. 鏃ユ湡瀛楁鍦ㄦ寚瀹氱殑鏃堕棿鑼冨洿鍐呴殢鏈哄垎甯�
+            5. 閲戦銆佹暟閲忕瓑鏁板�煎瓧娈佃鍚堢悊
+            6. 鍚屼竴妯″潡鍐呯殑瀹炰綋涔嬮棿瑕佹湁寮曠敤鍏崇郴锛堝閿�鍞彴璐﹀紩鐢ㄥ鎴峰悕绉帮級
+            7. 鎵�鏈夊瓧绗︿覆瀛楁涓嶈浣跨敤emoji鎴栫壒娈妘nicode瀛楃
+            """;
+    }
+
+    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("鍙敤鐨勪骇鍝両D鍒楄〃: ").append(productIds.stream().map(String::valueOf).collect(Collectors.joining(","))).append("\n");
+        sb.append("鍙敤鐨勪骇鍝佽鏍糏D鍒楄〃: ").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));
+        }
+        if (modules.contains("production")) {
+            sb.append(buildProductionPrompt(countMin, countMax, dateStart, dateEnd));
+        }
+        if (modules.contains("stock")) {
+            sb.append(buildStockPrompt(countMin, countMax));
+        }
+
+        sb.append("\n璇风洿鎺ヨ緭鍑篔SON鏁扮粍锛屼笉瑕佹湁浠讳綍鍏朵粬鍐呭:");
+        return sb.toString();
+    }
+
+    private static String buildSalesPrompt(int min, int max, String dateStart, String dateEnd) {
+        return """
+            閿�鍞ā鍧� - 鎸変互涓嬫牸寮忕敓鎴�:
+            {
+              "entity": "customer",
+              "customerName": "XX绉戞妧鏈夐檺鍏徃",
+              "customerType": "浼佷笟瀹㈡埛",
+              "contactPerson": "寮犱笁",
+              "contactPhone": "13800138000",
+              "companyAddress": "XX鐪乆X甯俋X鍖篨X璺疿X鍙�",
+              "taxpayerIdentificationNumber": "91110108XXXXXXXXXX"
+            }
+            {
+              "entity": "salesLedger",
+              "customerName": "寮曠敤涓婇潰鐢熸垚鐨勫鎴峰悕绉�",
+              "salesContractNo": "XS-20260601-001",
+              "projectName": "XX椤圭洰",
+              "entryDate": "2026-06-01",
+              "salesman": "閿�鍞憳濮撳悕",
+              "contractAmount": 50000.00,
+              "paymentMethod": "鏈堢粨30澶�",
+              "executionDate": "2026-06-01",
+              "deliveryDate": "2026-07-01",
+              "type": 1,
+              "productData": [
+                {
+                  "productId": 1,
+                  "productModelId": 1,
+                  "quantity": 100,
+                  "taxInclusiveUnitPrice": 500.00,
+                  "taxInclusiveTotalPrice": 50000.00,
+                  "taxRate": 13.00,
+                  "unit": "浠�",
+                  "type": 1
+                }
+              ]
+            }
+            瀹㈡埛鍚嶇О瑕佸儚鎸囧畾琛屼笟鐨勫叕鍙革紝鍚堝悓缂栧彿鏍煎紡XS-骞存湀鏃�-搴忓彿锛岄噾棰濆悎鐞嗐��
+            鏃ユ湡鑼冨洿: %s ~ %s锛屾瘡绉嶅疄浣撶敓鎴�%d-%d鏉°��
+            """.formatted(dateStart, dateEnd, min, max);
+    }
+
+    private static String buildPurchasePrompt(int min, int max, String dateStart, String dateEnd) {
+        return """
+            閲囪喘妯″潡 - 鎸変互涓嬫牸寮忕敓鎴�:
+            {
+              "entity": "supplier",
+              "supplierName": "XX鍘熸潗鏂欐湁闄愬叕鍙�",
+              "supplierType": "鍘熸潗鏂欎緵搴斿晢",
+              "contactUserName": "鏉庡洓",
+              "contactUserPhone": "13900139000",
+              "companyAddress": "XX鐪乆X甯俋X鍖篨X璺疿X鍙�",
+              "taxpayerIdentificationNum": "91110108XXXXXXXXXX",
+              "bankAccountName": "XX閾惰XX鏀",
+              "bankAccountNum": "622202XXXXXXXXXXXX",
+              "isWhite": 0
+            }
+            {
+              "entity": "purchaseLedger",
+              "supplierName": "寮曠敤涓婇潰鐢熸垚鐨勪緵搴斿晢鍚嶇О",
+              "purchaseContractNumber": "CG-20260601-001",
+              "projectName": "XX閲囪喘椤圭洰",
+              "entryDate": "2026-06-01",
+              "contractAmount": 30000.00,
+              "paymentMethod": "璐у埌浠樻",
+              "executionDate": "2026-06-01",
+              "productData": [
+                {
+                  "productId": 1,
+                  "productModelId": 1,
+                  "quantity": 50,
+                  "taxInclusiveUnitPrice": 600.00,
+                  "taxInclusiveTotalPrice": 30000.00,
+                  "taxRate": 13.00,
+                  "unit": "浠�",
+                  "type": 2
+                }
+              ]
+            }
+            渚涘簲鍟嗗悕绉拌鍍忔寚瀹氳涓氱殑渚涘簲鍟嗭紝鍚堝悓缂栧彿鏍煎紡CG-骞存湀鏃�-搴忓彿銆�
+            鏃ユ湡鑼冨洿: %s ~ %s锛屾瘡绉嶅疄浣撶敓鎴�%d-%d鏉°��
+            """.formatted(dateStart, dateEnd, min, max);
+    }
+
+    private static String buildQualityPrompt(int min, int max) {
+        return """
+            璐ㄩ噺妯″潡 - 鎸変互涓嬫牸寮忕敓鎴�:
+            {
+              "entity": "qualityTestStandard",
+              "standardNo": "QTS-20260601-001",
+              "standardName": "XX浜у搧妫�楠屾爣鍑�",
+              "inspectType": 0,
+              "remark": "閫傜敤浜嶺X琛屼笟鐨勮川閲忔楠屾爣鍑�"
+            }
+            inspectType: 0=鍘熸潗鏂欐楠�, 1=杩囩▼妫�楠�, 2=鍑哄巶妫�楠屻�備笁绉嶇被鍨嬮兘瑕佽鐩栥��
+            {
+              "entity": "qualityTestStandardBinding",
+              "productId": 1,
+              "testStandardId": 1
+            }
+            姣忕瀹炰綋鐢熸垚%d-%d鏉°��
+            """.formatted(min, max);
+    }
+
+    private static String buildProductionPrompt(int min, int max, String dateStart, String dateEnd) {
+        return """
+            鐢熶骇妯″潡 - 鎸変互涓嬫牸寮忕敓鎴�:
+            {
+              "entity": "productionPlan",
+              "productModelId": 1,
+              "qtyRequired": 200,
+              "requiredDate": "2026-06-15",
+              "source": "閿�鍞�",
+              "promisedDeliveryDate": "2026-07-01",
+              "remark": "XX瀹㈡埛璁㈠崟闇�姹�"
+            }
+            {
+              "entity": "productionOrder",
+              "productModelId": 1,
+              "quantity": 200,
+              "planCompleteTime": "2026-06-30",
+              "remark": "鏍规嵁鐢熶骇璁″垝XX鐢熸垚"
+            }
+            productionPlan鐨剆ource鍙��"閿�鍞�"鎴�"鍐呴儴"銆�
+            鏃ユ湡鑼冨洿: %s ~ %s锛屾瘡绉嶅疄浣撶敓鎴�%d-%d鏉°��
+            """.formatted(dateStart, dateEnd, min, max);
+    }
+
+    private static String buildStockPrompt(int min, int max) {
+        return """
+            搴撳瓨妯″潡 - 鎸変互涓嬫牸寮忕敓鎴�:
+            {
+              "entity": "stockInventory",
+              "productModelId": 1,
+              "qualitity": 500,
+              "batchNo": "BATCH-20260601-001",
+              "warnNum": 50,
+              "remark": "瀹夊叏搴撳瓨"
+            }
+            姣忕瀹炰綋鐢熸垚%d-%d鏉°�俠atchNo鏍煎紡BATCH-骞存湀鏃�-搴忓彿銆�
+            """.formatted(min, max);
+    }
+}
diff --git a/src/main/java/com/ruoyi/mock/service/DataCheckService.java b/src/main/java/com/ruoyi/mock/service/DataCheckService.java
new file mode 100644
index 0000000..ac3b652
--- /dev/null
+++ b/src/main/java/com/ruoyi/mock/service/DataCheckService.java
@@ -0,0 +1,15 @@
+package com.ruoyi.mock.service;
+
+import com.ruoyi.mock.dto.DataCheckRequest;
+import com.ruoyi.mock.vo.DataCheckResult;
+
+/**
+ * 鍩虹鏁版嵁妫�娴嬫湇鍔�
+ */
+public interface DataCheckService {
+
+    /**
+     * 妫�娴嬫寚瀹氭ā鍧楃殑鍩虹鏁版嵁鏄惁灏辩华
+     */
+    DataCheckResult check(DataCheckRequest request);
+}
diff --git a/src/main/java/com/ruoyi/mock/service/DataGenerateService.java b/src/main/java/com/ruoyi/mock/service/DataGenerateService.java
new file mode 100644
index 0000000..1b0b6b0
--- /dev/null
+++ b/src/main/java/com/ruoyi/mock/service/DataGenerateService.java
@@ -0,0 +1,15 @@
+package com.ruoyi.mock.service;
+
+import com.ruoyi.mock.dto.DataGenerateRequest;
+import com.ruoyi.mock.vo.DataGenerateResult;
+
+/**
+ * AI鏁版嵁鐢熸垚鏈嶅姟
+ */
+public interface DataGenerateService {
+
+    /**
+     * 鏍规嵁璇锋眰鍙傛暟璋冪敤AI鐢熸垚妯℃嫙鏁版嵁骞跺垱寤�
+     */
+    DataGenerateResult generate(DataGenerateRequest request);
+}
diff --git a/src/main/java/com/ruoyi/mock/service/impl/DataCheckServiceImpl.java b/src/main/java/com/ruoyi/mock/service/impl/DataCheckServiceImpl.java
new file mode 100644
index 0000000..870e20b
--- /dev/null
+++ b/src/main/java/com/ruoyi/mock/service/impl/DataCheckServiceImpl.java
@@ -0,0 +1,146 @@
+package com.ruoyi.mock.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.ruoyi.approve.pojo.ApprovalTemplate;
+import com.ruoyi.approve.mapper.ApprovalTemplateMapper;
+import com.ruoyi.basic.mapper.CustomerMapper;
+import com.ruoyi.basic.mapper.ProductMapper;
+import com.ruoyi.basic.mapper.SupplierManageMapper;
+import com.ruoyi.common.enums.TypeEnums;
+import com.ruoyi.mock.dto.DataCheckRequest;
+import com.ruoyi.mock.service.DataCheckService;
+import com.ruoyi.mock.vo.DataCheckResult;
+import com.ruoyi.mock.vo.DataCheckResult.CheckItem;
+import com.ruoyi.quality.mapper.QualityTestStandardBindingMapper;
+import com.ruoyi.quality.mapper.QualityTestStandardMapper;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+@RequiredArgsConstructor
+public class DataCheckServiceImpl implements DataCheckService {
+
+    private final ProductMapper productMapper;
+    private final CustomerMapper customerMapper;
+    private final SupplierManageMapper supplierManageMapper;
+    private final ApprovalTemplateMapper approvalTemplateMapper;
+    private final QualityTestStandardMapper qualityTestStandardMapper;
+    private final QualityTestStandardBindingMapper qualityTestStandardBindingMapper;
+
+    @Override
+    public DataCheckResult check(DataCheckRequest request) {
+        List<String> modules = request.getModules();
+        if (modules == null) {
+            modules = List.of();
+        }
+
+        Map<String, CheckItem> itemMap = new LinkedHashMap<>();
+
+        if (!modules.isEmpty()) {
+            addProductCheck(itemMap);
+        }
+
+        for (String module : modules) {
+            switch (module) {
+                case "sales" -> addSalesChecks(itemMap);
+                case "purchase" -> addPurchaseChecks(itemMap);
+                case "quality" -> addQualityChecks(itemMap);
+            }
+        }
+
+        List<CheckItem> items = new ArrayList<>(itemMap.values());
+
+        DataCheckResult result = new DataCheckResult();
+        result.setItems(items);
+        result.setTotalItems(items.size());
+        result.setPassedItems((int) items.stream().filter(CheckItem::isPassed).count());
+        return result;
+    }
+
+    private void addProductCheck(Map<String, CheckItem> itemMap) {
+        String key = "common:浜у搧鏁版嵁";
+        if (itemMap.containsKey(key)) {
+            return;
+        }
+        long count = productMapper.selectCount(null);
+        itemMap.put(key, buildItem("common", "浜у搧鏁版嵁", 1, (int) count,
+                "缂哄皯浜у搧鏁版嵁锛岃鍏堝湪銆愬熀纭�鏁版嵁-浜у搧绠$悊銆戜腑娣诲姞鑷冲皯1鏉′骇鍝�"));
+    }
+
+    private void addSalesChecks(Map<String, CheckItem> itemMap) {
+        String customerKey = "sales:瀹㈡埛鏁版嵁";
+        if (!itemMap.containsKey(customerKey)) {
+            long count = customerMapper.selectCount(null);
+            itemMap.put(customerKey, buildItem("sales", "瀹㈡埛鏁版嵁", 1, (int) count,
+                    "缂哄皯瀹㈡埛鏁版嵁锛岃鍏堝湪銆愬熀纭�鏁版嵁-瀹㈡埛绠$悊銆戜腑娣诲姞鑷冲皯1鏉″鎴�"));
+        }
+
+        String quotationKey = "sales:鎶ヤ环瀹℃壒妯℃澘";
+        if (!itemMap.containsKey(quotationKey)) {
+            long count = approvalTemplateMapper.selectCount(
+                    new LambdaQueryWrapper<ApprovalTemplate>()
+                            .eq(ApprovalTemplate::getBusinessType, TypeEnums.QUOTATION_APPROVAL.getCode()));
+            itemMap.put(quotationKey, buildItem("sales", "鎶ヤ环瀹℃壒妯℃澘", 1, (int) count,
+                    "缂哄皯鎶ヤ环瀹℃壒妯℃澘锛岃鍏堝湪銆愮郴缁熺鐞�-瀹℃壒妯℃澘銆戜腑鍒涘缓鎶ヤ环瀹℃壒妯℃澘"));
+        }
+
+        String shippingKey = "sales:鍙戣揣瀹℃壒妯℃澘";
+        if (!itemMap.containsKey(shippingKey)) {
+            long count = approvalTemplateMapper.selectCount(
+                    new LambdaQueryWrapper<ApprovalTemplate>()
+                            .eq(ApprovalTemplate::getBusinessType, TypeEnums.SHIPPING_APPROVAL.getCode()));
+            itemMap.put(shippingKey, buildItem("sales", "鍙戣揣瀹℃壒妯℃澘", 1, (int) count,
+                    "缂哄皯鍙戣揣瀹℃壒妯℃澘锛岃鍏堝湪銆愮郴缁熺鐞�-瀹℃壒妯℃澘銆戜腑鍒涘缓鍙戣揣瀹℃壒妯℃澘"));
+        }
+    }
+
+    private void addPurchaseChecks(Map<String, CheckItem> itemMap) {
+        String supplierKey = "purchase:渚涘簲鍟嗘暟鎹�";
+        if (!itemMap.containsKey(supplierKey)) {
+            long count = supplierManageMapper.selectCount(null);
+            itemMap.put(supplierKey, buildItem("purchase", "渚涘簲鍟嗘暟鎹�", 1, (int) count,
+                    "缂哄皯渚涘簲鍟嗘暟鎹紝璇峰厛鍦ㄣ�愬熀纭�鏁版嵁-渚涘簲鍟嗙鐞嗐�戜腑娣诲姞鑷冲皯1鏉′緵搴斿晢"));
+        }
+
+        String tplKey = "purchase:閲囪喘瀹℃壒妯℃澘";
+        if (!itemMap.containsKey(tplKey)) {
+            long count = approvalTemplateMapper.selectCount(
+                    new LambdaQueryWrapper<ApprovalTemplate>()
+                            .eq(ApprovalTemplate::getBusinessType, TypeEnums.PURCHASE_APPROVAL.getCode()));
+            itemMap.put(tplKey, buildItem("purchase", "閲囪喘瀹℃壒妯℃澘", 1, (int) count,
+                    "缂哄皯閲囪喘瀹℃壒妯℃澘锛岃鍏堝湪銆愮郴缁熺鐞�-瀹℃壒妯℃澘銆戜腑鍒涘缓閲囪喘瀹℃壒妯℃澘"));
+        }
+    }
+
+    private void addQualityChecks(Map<String, CheckItem> itemMap) {
+        String standardKey = "quality:妫�娴嬫爣鍑�";
+        if (!itemMap.containsKey(standardKey)) {
+            long count = qualityTestStandardMapper.selectCount(null);
+            itemMap.put(standardKey, buildItem("quality", "妫�娴嬫爣鍑�", 1, (int) count,
+                    "缂哄皯妫�娴嬫爣鍑嗭紝璇峰厛鍦ㄣ�愯川閲忕鐞�-妫�娴嬫爣鍑嗐�戜腑鍒涘缓妫�娴嬫爣鍑�"));
+        }
+
+        String bindingKey = "quality:鎸囨爣缁戝畾";
+        if (!itemMap.containsKey(bindingKey)) {
+            long count = qualityTestStandardBindingMapper.selectCount(null);
+            itemMap.put(bindingKey, buildItem("quality", "鎸囨爣缁戝畾", 1, (int) count,
+                    "缂哄皯鎸囨爣缁戝畾锛岃鍏堝湪銆愯川閲忕鐞�-妫�娴嬫爣鍑嗙粦瀹氥�戜腑灏嗘娴嬫爣鍑嗕笌浜у搧缁戝畾"));
+        }
+    }
+
+    private CheckItem buildItem(String module, String itemName, int minRequired, int currentCount, String failMessage) {
+        CheckItem item = new CheckItem();
+        item.setModule(module);
+        item.setItemName(itemName);
+        item.setMinRequired(minRequired);
+        item.setCurrentCount(currentCount);
+        item.setPassed(currentCount >= minRequired);
+        item.setMessage(item.isPassed() ? "閫氳繃" : failMessage);
+        return item;
+    }
+}
diff --git a/src/main/java/com/ruoyi/mock/service/impl/DataGenerateServiceImpl.java b/src/main/java/com/ruoyi/mock/service/impl/DataGenerateServiceImpl.java
new file mode 100644
index 0000000..9eacfec
--- /dev/null
+++ b/src/main/java/com/ruoyi/mock/service/impl/DataGenerateServiceImpl.java
@@ -0,0 +1,466 @@
+package com.ruoyi.mock.service.impl;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.ai.assistant.Assistant;
+import com.ruoyi.basic.mapper.ProductMapper;
+import com.ruoyi.basic.mapper.ProductModelMapper;
+import com.ruoyi.basic.pojo.Customer;
+import com.ruoyi.basic.pojo.SupplierManage;
+import com.ruoyi.basic.service.ICustomerService;
+import com.ruoyi.basic.service.ISupplierService;
+import com.ruoyi.mock.dto.DataGenerateRequest;
+import com.ruoyi.mock.prompt.MockDataPrompt;
+import com.ruoyi.mock.service.DataGenerateService;
+import com.ruoyi.mock.vo.DataGenerateResult;
+import com.ruoyi.mock.vo.DataGenerateResult.ModuleSummary;
+import com.ruoyi.production.pojo.ProductionOrder;
+import com.ruoyi.production.pojo.ProductionPlan;
+import com.ruoyi.production.service.ProductionOrderService;
+import com.ruoyi.production.service.ProductionPlanService;
+import com.ruoyi.purchase.dto.PurchaseLedgerDto;
+import com.ruoyi.purchase.service.IPurchaseLedgerService;
+import com.ruoyi.quality.pojo.QualityTestStandard;
+import com.ruoyi.quality.pojo.QualityTestStandardBinding;
+import com.ruoyi.quality.service.IQualityTestStandardService;
+import com.ruoyi.quality.service.QualityTestStandardBindingService;
+import com.ruoyi.sales.dto.SalesLedgerDto;
+import com.ruoyi.sales.pojo.SalesLedgerProduct;
+import com.ruoyi.sales.service.ISalesLedgerService;
+import com.ruoyi.stock.dto.StockInventoryDto;
+import com.ruoyi.stock.service.StockInventoryService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class DataGenerateServiceImpl implements DataGenerateService {
+
+    private final Assistant assistant;
+    private final ProductMapper productMapper;
+    private final ProductModelMapper productModelMapper;
+
+    private final ICustomerService customerService;
+    private final ISalesLedgerService salesLedgerService;
+    private final ISupplierService supplierService;
+    private final IPurchaseLedgerService purchaseLedgerService;
+    private final IQualityTestStandardService qualityTestStandardService;
+    private final QualityTestStandardBindingService qualityTestStandardBindingService;
+    private final ProductionPlanService productionPlanService;
+    private final ProductionOrderService productionOrderService;
+    private final StockInventoryService stockInventoryService;
+
+    @Override
+    public DataGenerateResult generate(DataGenerateRequest request) {
+        DataGenerateResult result = new DataGenerateResult();
+        List<ModuleSummary> summaries = new ArrayList<>();
+        List<String> errors = new ArrayList<>();
+        int totalGenerated = 0;
+
+        try {
+            List<Long> productIds = productMapper.selectList(null).stream()
+                    .map(p -> p.getId()).collect(Collectors.toList());
+            List<Long> productModelIds = productModelMapper.selectList(null).stream()
+                    .map(m -> m.getId()).collect(Collectors.toList());
+
+            String systemPrompt = MockDataPrompt.buildSystemPrompt();
+            String userMessage = MockDataPrompt.buildUserMessage(
+                    request.getModules(), request.getIndustries(),
+                    request.getCountMin(), request.getCountMax(),
+                    request.getDateStart(), request.getDateEnd(),
+                    request.getAdditionalInfo(),
+                    productIds, productModelIds);
+
+            String fullPrompt = systemPrompt + "\n\n" + userMessage;
+            log.info("璋冪敤AI鐢熸垚妯℃嫙鏁版嵁, modules={}, industries={}", request.getModules(), request.getIndustries());
+            String llmResponse = assistant.chat(fullPrompt);
+            log.info("AI杩斿洖鏁版嵁闀垮害: {}", llmResponse != null ? llmResponse.length() : 0);
+
+            if (llmResponse == null || llmResponse.isBlank()) {
+                result.setStatus("FAILED");
+                errors.add("AI鏈繑鍥炰换浣曟暟鎹�");
+                result.setErrors(errors);
+                return result;
+            }
+
+            List<JSONObject> entities = parseJsonResponse(llmResponse);
+            if (entities.isEmpty()) {
+                result.setStatus("FAILED");
+                errors.add("鏃犳硶瑙f瀽AI杩斿洖鐨勬暟鎹�");
+                result.setErrors(errors);
+                return result;
+            }
+
+            Map<String, List<JSONObject>> grouped = entities.stream()
+                    .collect(Collectors.groupingBy(e -> e.getString("entity")));
+
+            // 鍚嶇О鈫扞D 鏄犲皠琛紝鐢ㄤ簬鍒涘缓涓氬姟鍗曟嵁鏃跺洖濉閿�
+            Map<String, Long> customerNameToId = new HashMap<>();
+            Map<String, Long> supplierNameToId = new HashMap<>();
+
+            // Tier 0: 鍩虹鏁版嵁
+            if (grouped.containsKey("customer")) {
+                ModuleSummary s = createCustomers(grouped.get("customer"), customerNameToId);
+                summaries.add(s);
+                totalGenerated += s.getSuccessCount();
+            }
+            if (grouped.containsKey("supplier")) {
+                ModuleSummary s = createSuppliers(grouped.get("supplier"), supplierNameToId);
+                summaries.add(s);
+                totalGenerated += s.getSuccessCount();
+            }
+            if (grouped.containsKey("qualityTestStandard")) {
+                ModuleSummary s = createQualityStandards(grouped.get("qualityTestStandard"));
+                summaries.add(s);
+                totalGenerated += s.getSuccessCount();
+            }
+
+            // Tier 1: 涓氬姟鍗曟嵁
+            if (grouped.containsKey("salesLedger")) {
+                ModuleSummary s = createSalesLedgers(grouped.get("salesLedger"), customerNameToId);
+                summaries.add(s);
+                totalGenerated += s.getSuccessCount();
+            }
+            if (grouped.containsKey("purchaseLedger")) {
+                ModuleSummary s = createPurchaseLedgers(grouped.get("purchaseLedger"), supplierNameToId);
+                summaries.add(s);
+                totalGenerated += s.getSuccessCount();
+            }
+            if (grouped.containsKey("productionPlan")) {
+                ModuleSummary s = createProductionPlans(grouped.get("productionPlan"));
+                summaries.add(s);
+                totalGenerated += s.getSuccessCount();
+            }
+
+            // Tier 2
+            if (grouped.containsKey("productionOrder")) {
+                ModuleSummary s = createProductionOrders(grouped.get("productionOrder"));
+                summaries.add(s);
+                totalGenerated += s.getSuccessCount();
+            }
+            if (grouped.containsKey("qualityTestStandardBinding")) {
+                ModuleSummary s = createQualityBindings(grouped.get("qualityTestStandardBinding"));
+                summaries.add(s);
+                totalGenerated += s.getSuccessCount();
+            }
+            if (grouped.containsKey("stockInventory")) {
+                ModuleSummary s = createStockInventories(grouped.get("stockInventory"));
+                summaries.add(s);
+                totalGenerated += s.getSuccessCount();
+            }
+
+            result.setStatus(errors.isEmpty() ? "SUCCESS" : "PARTIAL");
+            result.setTotalGenerated(totalGenerated);
+            result.setModuleSummaries(summaries);
+            result.setErrors(errors);
+
+        } catch (Exception e) {
+            log.error("鏁版嵁鐢熸垚澶辫触", e);
+            result.setStatus("FAILED");
+            errors.add("鏁版嵁鐢熸垚寮傚父: " + e.getMessage());
+            result.setErrors(errors);
+        }
+
+        return result;
+    }
+
+    private List<JSONObject> parseJsonResponse(String response) {
+        try {
+            String trimmed = response.trim();
+            if (trimmed.startsWith("```")) {
+                int start = trimmed.indexOf("\n");
+                int end = trimmed.lastIndexOf("```");
+                if (start > 0 && end > start) {
+                    trimmed = trimmed.substring(start + 1, end).trim();
+                }
+            }
+            return JSON.parseArray(trimmed, JSONObject.class);
+        } catch (Exception e) {
+            log.warn("JSON瑙f瀽澶辫触锛屽皾璇曟彁鍙栨暟缁勭墖娈�: {}", e.getMessage());
+            int start = response.indexOf('[');
+            int end = response.lastIndexOf(']');
+            if (start >= 0 && end > start) {
+                return JSON.parseArray(response.substring(start, end + 1), JSONObject.class);
+            }
+            return List.of();
+        }
+    }
+
+    // ---- Tier 0: 鍩虹鏁版嵁 ----
+
+    private ModuleSummary createCustomers(List<JSONObject> items, Map<String, Long> nameToId) {
+        int success = 0, fail = 0;
+        for (JSONObject item : items) {
+            try {
+                Customer c = new Customer();
+                c.setCustomerName(item.getString("customerName"));
+                c.setCustomerType(item.getString("customerType"));
+                c.setContactPerson(item.getString("contactPerson"));
+                c.setContactPhone(item.getString("contactPhone"));
+                c.setCompanyAddress(item.getString("companyAddress"));
+                c.setTaxpayerIdentificationNumber(item.getString("taxpayerIdentificationNumber"));
+                customerService.insertCustomer(c);
+                if (c.getId() != null) {
+                    nameToId.put(c.getCustomerName(), c.getId());
+                }
+                success++;
+            } catch (Exception e) {
+                log.warn("鍒涘缓瀹㈡埛澶辫触: {}", e.getMessage());
+                fail++;
+            }
+        }
+        return summary("sales", "瀹㈡埛", items.size(), success, fail);
+    }
+
+    private ModuleSummary createSuppliers(List<JSONObject> items, Map<String, Long> nameToId) {
+        int success = 0, fail = 0;
+        for (JSONObject item : items) {
+            try {
+                SupplierManage s = new SupplierManage();
+                s.setSupplierName(item.getString("supplierName"));
+                s.setSupplierType(item.getString("supplierType"));
+                s.setContactUserName(item.getString("contactUserName"));
+                s.setContactUserPhone(item.getString("contactUserPhone"));
+                s.setCompanyAddress(item.getString("companyAddress"));
+                s.setTaxpayerIdentificationNum(item.getString("taxpayerIdentificationNum"));
+                s.setBankAccountName(item.getString("bankAccountName"));
+                s.setBankAccountNum(item.getString("bankAccountNum"));
+                if (item.containsKey("isWhite")) {
+                    s.setIsWhite(item.getInteger("isWhite"));
+                }
+                supplierService.saveSupplier(s);
+                if (s.getId() != null) {
+                    nameToId.put(s.getSupplierName(), s.getId());
+                }
+                success++;
+            } catch (Exception e) {
+                log.warn("鍒涘缓渚涘簲鍟嗗け璐�: {}", e.getMessage());
+                fail++;
+            }
+        }
+        return summary("purchase", "渚涘簲鍟�", items.size(), success, fail);
+    }
+
+    private ModuleSummary createQualityStandards(List<JSONObject> items) {
+        int success = 0, fail = 0;
+        for (JSONObject item : items) {
+            try {
+                QualityTestStandard std = new QualityTestStandard();
+                std.setStandardNo(item.getString("standardNo"));
+                std.setStandardName(item.getString("standardName"));
+                std.setInspectType(item.getInteger("inspectType"));
+                std.setRemark(item.getString("remark"));
+                qualityTestStandardService.save(std);
+                success++;
+            } catch (Exception e) {
+                log.warn("鍒涘缓妫�娴嬫爣鍑嗗け璐�: {}", e.getMessage());
+                fail++;
+            }
+        }
+        return summary("quality", "妫�娴嬫爣鍑�", items.size(), success, fail);
+    }
+
+    // ---- Tier 1: 涓氬姟鍗曟嵁 ----
+
+    private ModuleSummary createSalesLedgers(List<JSONObject> items, Map<String, Long> customerNameToId) {
+        int success = 0, fail = 0;
+        for (JSONObject item : items) {
+            try {
+                String customerName = item.getString("customerName");
+                Long customerId = customerNameToId.get(customerName);
+
+                SalesLedgerDto dto = new SalesLedgerDto();
+                dto.setCustomerId(customerId);
+                dto.setCustomerName(customerName);
+                dto.setProjectName(item.getString("projectName"));
+                dto.setSalesman(item.getString("salesman"));
+                dto.setPaymentMethod(item.getString("paymentMethod"));
+                dto.setType(item.getInteger("type"));
+                if (item.containsKey("entryDate")) {
+                    dto.setEntryDate(java.sql.Date.valueOf(item.getString("entryDate")));
+                }
+                if (item.containsKey("executionDate")) {
+                    dto.setExecutionDate(LocalDate.parse(item.getString("executionDate")));
+                }
+                if (item.containsKey("deliveryDate")) {
+                    dto.setDeliveryDate(LocalDate.parse(item.getString("deliveryDate")));
+                }
+                JSONArray productData = item.getJSONArray("productData");
+                if (productData != null) {
+                    List<SalesLedgerProduct> products = new ArrayList<>();
+                    for (int i = 0; i < productData.size(); i++) {
+                        JSONObject pd = productData.getJSONObject(i);
+                        SalesLedgerProduct slp = new SalesLedgerProduct();
+                        slp.setProductId(pd.getLong("productId"));
+                        slp.setProductModelId(pd.getLong("productModelId"));
+                        slp.setQuantity(pd.getBigDecimal("quantity"));
+                        slp.setTaxInclusiveUnitPrice(pd.getBigDecimal("taxInclusiveUnitPrice"));
+                        slp.setTaxInclusiveTotalPrice(pd.getBigDecimal("taxInclusiveTotalPrice"));
+                        slp.setTaxRate(pd.getBigDecimal("taxRate"));
+                        slp.setUnit(pd.getString("unit"));
+                        slp.setType(pd.getInteger("type"));
+                        products.add(slp);
+                    }
+                    dto.setProductData(products);
+                }
+                salesLedgerService.addOrUpdateSalesLedger(dto);
+                success++;
+            } catch (Exception e) {
+                log.warn("鍒涘缓閿�鍞彴璐﹀け璐�: {}", e.getMessage());
+                fail++;
+            }
+        }
+        return summary("sales", "閿�鍞彴璐�", items.size(), success, fail);
+    }
+
+    private ModuleSummary createPurchaseLedgers(List<JSONObject> items, Map<String, Long> supplierNameToId) {
+        int success = 0, fail = 0;
+        for (JSONObject item : items) {
+            try {
+                String supplierName = item.getString("supplierName");
+                Long supplierId = supplierNameToId.get(supplierName);
+
+                PurchaseLedgerDto dto = new PurchaseLedgerDto();
+                dto.setSupplierId(supplierId);
+                dto.setSupplierName(supplierName);
+                dto.setProjectName(item.getString("projectName"));
+                dto.setContractAmount(item.getBigDecimal("contractAmount"));
+                dto.setPaymentMethod(item.getString("paymentMethod"));
+                if (item.containsKey("entryDate")) {
+                    dto.setEntryDate(java.sql.Date.valueOf(item.getString("entryDate")));
+                }
+                if (item.containsKey("executionDate")) {
+                    dto.setExecutionDate(java.sql.Date.valueOf(item.getString("executionDate")));
+                }
+                JSONArray productData = item.getJSONArray("productData");
+                if (productData != null) {
+                    List<SalesLedgerProduct> products = new ArrayList<>();
+                    for (int i = 0; i < productData.size(); i++) {
+                        JSONObject pd = productData.getJSONObject(i);
+                        SalesLedgerProduct slp = new SalesLedgerProduct();
+                        slp.setProductId(pd.getLong("productId"));
+                        slp.setProductModelId(pd.getLong("productModelId"));
+                        slp.setQuantity(pd.getBigDecimal("quantity"));
+                        slp.setTaxInclusiveUnitPrice(pd.getBigDecimal("taxInclusiveUnitPrice"));
+                        slp.setTaxInclusiveTotalPrice(pd.getBigDecimal("taxInclusiveTotalPrice"));
+                        slp.setTaxRate(pd.getBigDecimal("taxRate"));
+                        slp.setUnit(pd.getString("unit"));
+                        slp.setType(2);
+                        products.add(slp);
+                    }
+                    dto.setProductData(products);
+                }
+                purchaseLedgerService.addOrEditPurchase(dto);
+                success++;
+            } catch (Exception e) {
+                log.warn("鍒涘缓閲囪喘鍙拌处澶辫触: {}", e.getMessage());
+                fail++;
+            }
+        }
+        return summary("purchase", "閲囪喘鍙拌处", items.size(), success, fail);
+    }
+
+    private ModuleSummary createProductionPlans(List<JSONObject> items) {
+        int success = 0, fail = 0;
+        for (JSONObject item : items) {
+            try {
+                ProductionPlan plan = new ProductionPlan();
+                plan.setProductModelId(item.getLong("productModelId"));
+                plan.setQtyRequired(item.getBigDecimal("qtyRequired"));
+                plan.setSource(item.getString("source"));
+                plan.setRemark(item.getString("remark"));
+                if (item.containsKey("requiredDate")) {
+                    plan.setRequiredDate(LocalDate.parse(item.getString("requiredDate")));
+                }
+                if (item.containsKey("promisedDeliveryDate")) {
+                    plan.setPromisedDeliveryDate(LocalDate.parse(item.getString("promisedDeliveryDate")));
+                }
+                productionPlanService.save(plan);
+                success++;
+            } catch (Exception e) {
+                log.warn("鍒涘缓鐢熶骇璁″垝澶辫触: {}", e.getMessage());
+                fail++;
+            }
+        }
+        return summary("production", "鐢熶骇璁″垝", items.size(), success, fail);
+    }
+
+    // ---- Tier 2: 鍚庣画鍗曟嵁 ----
+
+    private ModuleSummary createProductionOrders(List<JSONObject> items) {
+        int success = 0, fail = 0;
+        for (JSONObject item : items) {
+            try {
+                ProductionOrder order = new ProductionOrder();
+                order.setProductModelId(item.getLong("productModelId"));
+                order.setQuantity(item.getBigDecimal("quantity"));
+                if (item.containsKey("planCompleteTime")) {
+                    order.setPlanCompleteTime(LocalDate.parse(item.getString("planCompleteTime")));
+                }
+                productionOrderService.saveProductionOrder(order);
+                success++;
+            } catch (Exception e) {
+                log.warn("鍒涘缓鐢熶骇璁㈠崟澶辫触: {}", e.getMessage());
+                fail++;
+            }
+        }
+        return summary("production", "鐢熶骇璁㈠崟", items.size(), success, fail);
+    }
+
+    private ModuleSummary createQualityBindings(List<JSONObject> items) {
+        int success = 0, fail = 0;
+        for (JSONObject item : items) {
+            try {
+                QualityTestStandardBinding binding = new QualityTestStandardBinding();
+                binding.setProductId(item.getLong("productId"));
+                binding.setTestStandardId(item.getInteger("testStandardId"));
+                qualityTestStandardBindingService.add(List.of(binding));
+                success++;
+            } catch (Exception e) {
+                log.warn("鍒涘缓鎸囨爣缁戝畾澶辫触: {}", e.getMessage());
+                fail++;
+            }
+        }
+        return summary("quality", "鎸囨爣缁戝畾", items.size(), success, fail);
+    }
+
+    private ModuleSummary createStockInventories(List<JSONObject> items) {
+        int success = 0, fail = 0;
+        for (JSONObject item : items) {
+            try {
+                StockInventoryDto dto = new StockInventoryDto();
+                dto.setProductModelId(item.getLong("productModelId"));
+                dto.setQualitity(item.getBigDecimal("qualitity"));
+                dto.setBatchNo(item.getString("batchNo"));
+                dto.setWarnNum(item.getBigDecimal("warnNum"));
+                dto.setRemark(item.getString("remark"));
+                stockInventoryService.addstockInventory(dto);
+                success++;
+            } catch (Exception e) {
+                log.warn("鍒涘缓搴撳瓨璁板綍澶辫触: {}", e.getMessage());
+                fail++;
+            }
+        }
+        return summary("stock", "搴撳瓨璁板綍", items.size(), success, fail);
+    }
+
+    private ModuleSummary summary(String module, String entityName, int total, int success, int fail) {
+        ModuleSummary s = new ModuleSummary();
+        s.setModule(module);
+        s.setEntityName(entityName);
+        s.setGeneratedCount(total);
+        s.setSuccessCount(success);
+        s.setFailCount(fail);
+        return s;
+    }
+}
diff --git a/src/main/java/com/ruoyi/mock/vo/DataCheckResult.java b/src/main/java/com/ruoyi/mock/vo/DataCheckResult.java
new file mode 100644
index 0000000..ed48b72
--- /dev/null
+++ b/src/main/java/com/ruoyi/mock/vo/DataCheckResult.java
@@ -0,0 +1,36 @@
+package com.ruoyi.mock.vo;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 鍩虹鏁版嵁妫�娴嬬粨鏋�
+ */
+@Data
+public class DataCheckResult {
+
+    /** 妫�娴嬮」鎬绘暟 */
+    private int totalItems;
+    /** 宸查�氳繃鐨勬娴嬮」鏁伴噺 */
+    private int passedItems;
+    /** 妫�娴嬫槑缁� */
+    private List<CheckItem> items = new ArrayList<>();
+
+    @Data
+    public static class CheckItem {
+        /** 妯″潡锛歴ales / purchase / quality / common */
+        private String module;
+        /** 妫�娴嬮」鍚嶇О */
+        private String itemName;
+        /** 鎵�闇�鏈�浣庢暟閲� */
+        private int minRequired;
+        /** 褰撳墠瀹為檯鏁伴噺 */
+        private int currentCount;
+        /** 鏄惁閫氳繃 */
+        private boolean passed;
+        /** 鎻愮ず淇℃伅 */
+        private String message;
+    }
+}
diff --git a/src/main/java/com/ruoyi/mock/vo/DataGenerateResult.java b/src/main/java/com/ruoyi/mock/vo/DataGenerateResult.java
new file mode 100644
index 0000000..e4487fc
--- /dev/null
+++ b/src/main/java/com/ruoyi/mock/vo/DataGenerateResult.java
@@ -0,0 +1,37 @@
+package com.ruoyi.mock.vo;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * AI鏁版嵁鐢熸垚缁撴灉
+ */
+@Data
+public class DataGenerateResult {
+
+    /** 鐢熸垚鐘舵��: SUCCESS / PARTIAL / FAILED */
+    private String status;
+
+    /** 鎬昏鐢熸垚鏉℃暟 */
+    private int totalGenerated;
+
+    /** 鍚勬ā鍧楃敓鎴愭憳瑕� */
+    private List<ModuleSummary> moduleSummaries = new ArrayList<>();
+
+    /** 閿欒淇℃伅锛堝鏈夛級 */
+    private List<String> errors = new ArrayList<>();
+
+    /** 鍩虹鏁版嵁妫�娴嬬粨鏋滐紙鍓嶇疆鏍¢獙鏈�氳繃鏃惰繑鍥烇級 */
+    private DataCheckResult checkResult;
+
+    @Data
+    public static class ModuleSummary {
+        private String module;
+        private String entityName;
+        private int generatedCount;
+        private int successCount;
+        private int failCount;
+    }
+}

--
Gitblit v1.9.3