From 70e6bfb8d4be92eb6a711131213016f0b32588fe Mon Sep 17 00:00:00 2001
From: huminmin <mac@MacBook-Pro.local>
Date: 星期四, 18 六月 2026 09:53:23 +0800
Subject: [PATCH] Merge branch 'dev_NEW_pro' of http://114.132.189.42:9002/r/product-inventory-management into dev_NEW_pro

---
 src/views/inventoryManagement/dispatchLog/Record.vue |   41 +++
 src/views/salesManagement/deliveryLedger/index.vue   |   14 
 src/views/mock/dataCheck/index.vue                   |  182 ++++++++++++++
 doc/mock_data_check.md                               |  183 +++++++++++++++
 src/api/inventoryManagement/stockOut.js              |    9 
 multiple/assets/favicon/SDZZfavicon.ico              |    0 
 doc/mock_data_generate.md                            |  243 ++++++++++++++++++++
 src/api/mock/generate.js                             |   10 
 vite.config.js                                       |    2 
 9 files changed, 673 insertions(+), 11 deletions(-)

diff --git a/doc/mock_data_check.md b/doc/mock_data_check.md
new file mode 100644
index 0000000..8c67159
--- /dev/null
+++ b/doc/mock_data_check.md
@@ -0,0 +1,183 @@
+# 鏁版嵁妯℃嫙 - 鍩虹鏁版嵁妫�娴�
+
+## 娑夊強椤甸潰
+
+- 鏁版嵁妯℃嫙鎿嶄綔椤甸潰锛堟柊澧烇級
+
+## API
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | /mock/dataCheck | 妫�娴嬫寚瀹氭ā鍧楃殑鍩虹鏁版嵁鏄惁灏辩华 |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| modules | List\<String\> | 鏄� | 瑕佹娴嬬殑妯″潡鍒楄〃锛屽彲閫夊�硷細sales锛堥攢鍞級銆乸urchase锛堥噰璐級銆乹uality锛堣川閲忥級銆乸roduction锛堢敓浜э級 |
+
+璇锋眰浣撶ず渚嬶細
+```json
+{ "modules": ["sales", "purchase", "quality", "production"] }
+```
+
+**鍝嶅簲锛�**
+```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 | 缂哄皯閲囪喘瀹℃壒妯℃澘锛岃鍏堝湪銆愮郴缁熺鐞�-瀹℃壒妯℃澘銆戜腑鍒涘缓閲囪喘瀹℃壒妯℃澘 |
+
+### 鐢熶骇妯″潡 (production)
+| 妫�娴嬮」 | 鏈�浣庢暟閲� | 鏈�氳繃鎻愮ず |
+|--------|----------|------------|
+| 浜у搧鏁版嵁 | 1 | 缂哄皯浜у搧鏁版嵁锛岃鍏堝湪銆愬熀纭�鏁版嵁-浜у搧绠$悊銆戜腑娣诲姞鑷冲皯1鏉′骇鍝� |
+| 浜у搧瑙勬牸 | 1 | 缂哄皯浜у搧瑙勬牸锛岃鍏堝湪銆愬熀纭�鏁版嵁-浜у搧绠$悊銆戜腑涓轰骇鍝佹坊鍔犺鏍煎瀷鍙� |
+| 宸ュ簭 | 1 | 缂哄皯宸ュ簭锛岃鍏堝湪銆愬伐鑹鸿璁�-宸ュ簭绠$悊銆戜腑鍒涘缓宸ュ簭 |
+| BOM | 1 | 缂哄皯BOM锛岃鍏堝湪銆愬伐鑹鸿璁�-BOM绠$悊銆戜腑鍒涘缓BOM |
+| BOM浜у搧缁撴瀯 | 1 | 缂哄皯BOM浜у搧缁撴瀯锛岃鍏堝湪銆愬伐鑹鸿璁�-BOM绠$悊銆戜腑涓築OM娣诲姞浜у搧缁撴瀯鑺傜偣 |
+| 宸ヨ壓璺嚎 | 1 | 缂哄皯宸ヨ壓璺嚎锛岃鍏堝湪銆愬伐鑹鸿璁�-宸ヨ壓璺嚎銆戜腑鍒涘缓宸ヨ壓璺嚎 |
+| 宸ヨ壓璺嚎宸ュ簭 | 1 | 缂哄皯宸ヨ壓璺嚎宸ュ簭锛岃鍏堝湪銆愬伐鑹鸿璁�-宸ヨ壓璺嚎銆戜腑涓哄伐鑹鸿矾绾挎坊鍔犲伐搴� |
+| 浜у搧-宸ヨ壓璺嚎鍏宠仈 | 鈮�1 | 閮ㄥ垎浜у搧瑙勬牸鏈叧鑱斿伐鑹鸿矾绾匡紝璇峰厛鍦ㄣ�愬伐鑹鸿璁�-宸ヨ壓璺嚎銆戜腑涓轰骇鍝佽鏍煎垱寤哄伐鑹鸿矾绾� |
+| 宸ヨ壓璺嚎-宸ュ簭鍏宠仈 | 鈮�1 | 閮ㄥ垎宸ヨ壓璺嚎鏈坊鍔犲伐搴忥紝璇峰厛鍦ㄣ�愬伐鑹鸿璁�-宸ヨ壓璺嚎銆戜腑涓哄伐鑹鸿矾绾挎坊鍔犲伐搴� |
+| BOM-浜у搧缁撴瀯鍏宠仈 | 鈮�1 | 閮ㄥ垎BOM鏈坊鍔犱骇鍝佺粨鏋勶紝璇峰厛鍦ㄣ�愬伐鑹鸿璁�-BOM绠$悊銆戜腑涓築OM娣诲姞浜у搧缁撴瀯鑺傜偣 |
+
+### 璐ㄩ噺妯″潡 (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 label="production">鐢熶骇妯″潡</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', 'production'],
+    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
+    }
+  }
+}
+```
+
+## 娉ㄦ剰浜嬮」
+
+- 浜у搧鏁版嵁锛堝叕鍏卞熀纭�锛夊湪澶氫釜妯″潡闂村叡浜紝妫�娴嬬粨鏋滀腑鍙嚭鐜颁竴娆★紝涓嶄細閲嶅灞曠ず
+- 妫�娴嬩粎鍋氬彧璇绘煡璇紝涓嶅啓鍏ヤ换浣曟暟鎹�
+- 妯″潡鍙傛暟涓虹┖鏁扮粍鏃惰繑鍥炵┖妫�娴嬪垪琛�
+- 寤鸿鍦ㄦ暟鎹ā鎷熷紑濮嬪墠鍏堣皟鐢ㄦ鎺ュ彛纭鍩虹鏁版嵁灏辩华
+- 鐢熶骇妯″潡闄や簡妫�娴嬫暟鎹噺锛岃繕浼氭娴嬪叧鑱旀�э紙浜у搧-宸ヨ壓璺嚎銆佸伐鑹鸿矾绾�-宸ュ簭銆丅OM-浜у搧缁撴瀯锛夛紝纭繚宸ヨ壓璁捐鏁版嵁瀹屾暣
diff --git a/doc/mock_data_generate.md b/doc/mock_data_generate.md
new file mode 100644
index 0000000..6dc801e
--- /dev/null
+++ b/doc/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/multiple/assets/favicon/SDZZfavicon.png b/multiple/assets/favicon/SDZZfavicon.ico
similarity index 100%
rename from multiple/assets/favicon/SDZZfavicon.png
rename to multiple/assets/favicon/SDZZfavicon.ico
Binary files differ
diff --git a/src/api/inventoryManagement/stockOut.js b/src/api/inventoryManagement/stockOut.js
index 004ba99..b54e004 100644
--- a/src/api/inventoryManagement/stockOut.js
+++ b/src/api/inventoryManagement/stockOut.js
@@ -35,3 +35,12 @@
         data,
     });
 }
+
+// 鎵归噺鍙嶅鍑哄簱璁板綍
+export const batchUnapproveStockOutRecords = (data) => {
+    return request({
+        url: "/stockOutRecord/reAudit",
+        method: "post",
+        data,
+    });
+}
diff --git a/src/api/mock/generate.js b/src/api/mock/generate.js
new file mode 100644
index 0000000..a3eb689
--- /dev/null
+++ b/src/api/mock/generate.js
@@ -0,0 +1,10 @@
+import request from "@/utils/request";
+
+// AI 鐢熸垚妯℃嫙鏁版嵁锛堝惈鍓嶇疆鍩虹鏁版嵁妫�娴嬶級
+export function mockGenerate(data) {
+  return request({
+    url: "/mock/generate",
+    method: "post",
+    data,
+  });
+}
\ No newline at end of file
diff --git a/src/views/inventoryManagement/dispatchLog/Record.vue b/src/views/inventoryManagement/dispatchLog/Record.vue
index 2d7411d..5a056d6 100644
--- a/src/views/inventoryManagement/dispatchLog/Record.vue
+++ b/src/views/inventoryManagement/dispatchLog/Record.vue
@@ -76,6 +76,8 @@
     <div class="actions">
       <el-button type="primary"
                  @click="handleBatchApprove">瀹℃壒</el-button>
+      <el-button :disabled="!canReverseApprove"
+                 @click="handleReverseApprove">鍙嶅</el-button>
       <el-button @click="handleOut">瀵煎嚭</el-button>
       <el-button type="danger"
                  plain
@@ -163,6 +165,7 @@
     getStockOutPage,
     delPendingStockOut,
     batchApproveStockOutRecords,
+    batchUnapproveStockOutRecords,
   } from "@/api/inventoryManagement/stockOut.js";
   import {
     findAllQualifiedStockOutRecordTypeOptions,
@@ -306,6 +309,44 @@
     selectedRows.value = selection.filter(item => item.id);
     console.log("selection", selectedRows.value);
   };
+
+  const isRejectedApproval = status => {
+    return status === 2 || status === "2" || status === "rejected" || status === "REJECTED";
+  };
+
+  const canReverseApprove = computed(() => {
+    return (
+      selectedRows.value.length > 0 &&
+      selectedRows.value.every(row => isRejectedApproval(row.approvalStatus))
+    );
+  });
+
+  const handleReverseApprove = () => {
+    if (!canReverseApprove.value) {
+      proxy.$modal.msgWarning("璇烽�夋嫨椹冲洖鐘舵�佺殑鏁版嵁");
+      return;
+    }
+    const ids = selectedRows.value.map(item => item.id);
+    ElMessageBox.confirm("鍙嶅鍚庤褰曞皢鎭㈠涓哄緟瀹℃壒鐘舵�侊紝鏄惁纭鍙嶅锛�", "鍙嶅", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        batchUnapproveStockOutRecords({ ids })
+          .then(() => {
+            proxy.$modal.msgSuccess("鍙嶅鎴愬姛");
+            getList();
+          })
+          .catch(() => {
+            proxy.$modal.msgError("鍙嶅澶辫触");
+          });
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+  };
+
   const expandedRowKeys = ref([]);
 
   const handleBatchApprove = () => {
diff --git a/src/views/mock/dataCheck/index.vue b/src/views/mock/dataCheck/index.vue
index f16727b..5782e7d 100644
--- a/src/views/mock/dataCheck/index.vue
+++ b/src/views/mock/dataCheck/index.vue
@@ -5,6 +5,7 @@
         <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-group>
       <div style="margin-top: 16px">
         <el-button type="primary" @click="handleCheck" :loading="checking">
@@ -35,17 +36,144 @@
         <el-table-column prop="message" label="鎻愮ず" min-width="200" />
       </el-table>
     </el-card>
+
+    <!-- AI 鏁版嵁鐢熸垚 -->
+    <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"
+                unlink-panels
+              />
+            </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>
+
+    <!-- 鐢熸垚缁撴灉 -->
+    <el-card v-if="generateResult" header="鐢熸垚缁撴灉" style="margin-top: 16px">
+      <el-alert
+        :title="`鍏辩敓鎴� ${generateResult.totalGenerated} 鏉℃暟鎹甡"
+        type="success"
+        :closable="false"
+        show-icon
+      />
+      <el-table :data="generateResult.moduleSummaries" style="margin-top: 12px" border>
+        <el-table-column prop="module" label="妯″潡" width="100" />
+        <el-table-column prop="entityName" label="瀹炰綋鍚嶇О" width="160" />
+        <el-table-column prop="generatedCount" label="鐢熸垚鏉℃暟" width="80" align="center" />
+        <el-table-column prop="successCount" label="鎴愬姛" width="80" align="center">
+          <template #default="{ row }">
+            <el-tag type="success">{{ row.successCount }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="failCount" label="澶辫触" width="80" align="center">
+          <template #default="{ row }">
+            <el-tag v-if="row.failCount > 0" type="danger">{{ row.failCount }}</el-tag>
+            <span v-else>0</span>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div v-if="generateResult.errors && generateResult.errors.length > 0" style="margin-top: 12px">
+        <el-alert
+          v-for="(err, i) in generateResult.errors"
+          :key="i"
+          :title="err"
+          type="error"
+          :closable="false"
+          style="margin-bottom: 4px"
+        />
+      </div>
+    </el-card>
   </div>
 </template>
 
 <script setup>
-import { ref } from "vue";
+import { ref, reactive } from "vue";
 import { ElMessage } from "element-plus";
 import { dataCheck } from "@/api/mock/dataCheck.js";
+import { mockGenerate } from "@/api/mock/generate.js";
 
-const selectedModules = ref(["sales", "purchase", "quality"]);
+const selectedModules = ref(["sales", "purchase", "quality", "production"]);
 const checking = ref(false);
 const checkResult = ref(null);
+
+const generateForm = reactive({
+  modules: [],
+  industries: [],
+  countRange: [3, 10],
+  dateRange: [],
+  additionalInfo: "",
+});
+
+const generating = ref(false);
+const generateResult = ref(null);
 
 const handleCheck = async () => {
   if (selectedModules.value.length === 0) {
@@ -60,6 +188,54 @@
     checking.value = false;
   }
 };
+
+// 鐩存帴鐢熸垚锛堝唴閮ㄨ嚜鍔ㄦ娴嬶級
+const handleGenerate = async () => {
+  if (generateForm.modules.length === 0) {
+    ElMessage.warning("璇疯嚦灏戦�夋嫨涓�涓ā鍧�");
+    return;
+  }
+  generating.value = true;
+  try {
+    const res = await mockGenerate({
+      modules: generateForm.modules,
+      industries: generateForm.industries,
+      countMin: generateForm.countRange[0],
+      countMax: generateForm.countRange[1],
+      dateStart: generateForm.dateRange[0] || null,
+      dateEnd: generateForm.dateRange[1] || null,
+      additionalInfo: generateForm.additionalInfo,
+    });
+    generateResult.value = res.data;
+    ElMessage.success(`鎴愬姛鐢熸垚 ${res.data.totalGenerated} 鏉℃暟鎹甡);
+  } catch (err) {
+    // code 500 鏃跺搷搴旀嫤鎴櫒浼氬脊閿欒鎻愮ず锛屾澶勪笉鍐嶉噸澶嶆彁绀�
+    // 鑻ラ渶瑕佸睍绀烘娴嬬粨鏋滐紝闇�瑕佸悗绔湪闈�200鏃朵篃杩斿洖鏁版嵁锛屾澶勬殏涓嶅鐞�
+  } finally {
+    generating.value = false;
+  }
+};
+
+// 鍏堟娴嬪啀鐢熸垚
+const handleCheckFirst = async () => {
+  if (generateForm.modules.length === 0) {
+    ElMessage.warning("璇疯嚦灏戦�夋嫨涓�涓ā鍧�");
+    return;
+  }
+  checking.value = true;
+  try {
+    const res = await dataCheck(generateForm.modules);
+    const result = res.data;
+    if (result.passedItems === result.totalItems) {
+      await handleGenerate();
+    } else {
+      checkResult.value = result;
+      ElMessage.warning("璇峰厛琛ラ綈鍩虹鏁版嵁鍚庡啀鐢熸垚");
+    }
+  } finally {
+    checking.value = false;
+  }
+};
 </script>
 
-<style scoped></style>
+<style scoped></style>
\ No newline at end of file
diff --git a/src/views/salesManagement/deliveryLedger/index.vue b/src/views/salesManagement/deliveryLedger/index.vue
index c8890cc..33fa45f 100644
--- a/src/views/salesManagement/deliveryLedger/index.vue
+++ b/src/views/salesManagement/deliveryLedger/index.vue
@@ -139,13 +139,13 @@
               @click="openDetail(scope.row)"
               >璇︽儏
             </el-button>
-            <el-button
-              link
-              type="danger"
-              :disabled="isApproving(scope.row.status)"
-              @click="handleDeleteSingle(scope.row)"
-              >鍒犻櫎
-            </el-button>
+            <!--            <el-button-->
+            <!--              link-->
+            <!--              type="danger"-->
+            <!--              :disabled="isApproving(scope.row.status)"-->
+            <!--              @click="handleDeleteSingle(scope.row)"-->
+            <!--              >鍒犻櫎-->
+            <!--            </el-button>-->
           </template>
         </el-table-column>
       </el-table>
diff --git a/vite.config.js b/vite.config.js
index 03311be..6b267a7 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -8,7 +8,7 @@
   const { VITE_APP_ENV } = env;
   const baseUrl =
       env.VITE_APP_ENV === "development"
-          ? "http://1.15.17.182:9048"
+          ? "http://localhost:7005"
           : env.VITE_BASE_API;
   const javaUrl =
       env.VITE_APP_ENV === "development"

--
Gitblit v1.9.3