From d29080af4e965ba341cb85a5bc45ecd183c06783 Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期五, 14 八月 2026 17:45:45 +0800
Subject: [PATCH] Merge branch 'dev_New_pro' into dev_pro_山西_晋和园

---
 src/main/java/com/ruoyi/production/bean/dto/ProductionPlanImportDto.java                             |    4 
 src/main/java/com/ruoyi/approve/pojo/KnowledgeBase.java                                              |   15 
 src/main/java/com/ruoyi/collaborativeApproval/vo/SearchMeetingUseVo.java                             |    2 
 src/main/java/com/ruoyi/staff/mapper/PersonalShiftMapper.java                                        |    2 
 src/main/java/com/ruoyi/collaborativeApproval/service/impl/MeetingServiceImpl.java                   |    4 
 src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml                                          |   44 
 src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java                                      |   27 
 src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java                             |  102 
 src/main/java/com/ruoyi/approve/pojo/KnowledgeBaseVector.java                                        |   80 
 sql/product-inventory-management-new-pro.sql                                                         | 5814 ++++++++++++++++++
 src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java                                  |   68 
 src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java                                       |   92 
 src/main/java/com/ruoyi/purchase/vo/SupplierTransactionsVo.java                                      |    5 
 src/main/resources/mapper/sales/SalesLedgerProductMapper.xml                                         |  102 
 doc/20260615_add_plan_person_and_executor_to_routing_operation.sql                                   |    8 
 src/main/resources/application-khyy.yml                                                              |  268 
 src/main/java/com/ruoyi/common/enums/StockOutQualifiedRecordTypeEnum.java                            |    1 
 src/main/java/com/ruoyi/staff/service/StaffSalaryMainService.java                                    |    8 
 src/main/resources/application-lsy.yml                                                               |  268 
 src/main/java/com/ruoyi/technology/controller/TechnologyOperationController.java                     |    2 
 src/main/java/com/ruoyi/mock/service/DataCheckService.java                                           |   15 
 src/main/java/com/ruoyi/purchase/pojo/PurchaseReturnOrders.java                                      |   12 
 src/main/resources/application-yss.yml                                                               |  268 
 src/main/java/com/ruoyi/approve/dto/KnowledgeBaseVectorVO.java                                       |   21 
 src/main/java/com/ruoyi/quality/pojo/QualityUnqualified.java                                         |    4 
 src/main/resources/mapper/procurementrecord/ReturnManagementMapper.xml                               |   27 
 src/main/java/com/ruoyi/staff/pojo/StaffSalaryDetail.java                                            |    3 
 src/main/java/com/ruoyi/approve/service/KnowledgeBaseVectorService.java                              |   43 
 src/main/java/com/ruoyi/staff/controller/PersonalAttendanceLocationConfigController.java             |   32 
 src/main/java/com/ruoyi/basic/vo/CustomerVo.java                                                     |    5 
 src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationParamServiceImpl.java |   12 
 src/main/java/com/ruoyi/staff/pojo/PersonalAttendanceLocationConfig.java                             |   22 
 docs/mock_data_check.md                                                                              |  183 
 src/main/java/com/ruoyi/approve/service/impl/ApprovalTemplateServiceImpl.java                        |   30 
 src/main/java/com/ruoyi/procurementrecord/service/impl/ReturnManagementServiceImpl.java              |   48 
 src/main/java/com/ruoyi/stock/service/StockOutRecordService.java                                     |    2 
 src/main/resources/mapper/staff/StaffSalaryMainMapper.xml                                            |    7 
 doc/知识库RAG功能实现文档.md                                                                                  | 1034 +++
 src/main/resources/application-xlgs.yml                                                              |  268 
 src/main/java/com/ruoyi/account/bean/vo/purchase/PurchaseReturnVo.java                               |   16 
 src/main/resources/application-qfsw.yml                                                              |  268 
 src/main/java/com/ruoyi/staff/excel/StaffSalaryExportData.java                                       |   64 
 src/main/resources/mapper/sales/SalesLedgerMapper.xml                                                |    1 
 src/main/java/com/ruoyi/account/controller/sales/AccountInvoiceApplicationController.java            |    8 
 src/main/java/com/ruoyi/purchase/service/impl/PurchaseReturnOrdersServiceImpl.java                   |   14 
 src/main/resources/mapper/basic/SupplierManageMapper.xml                                             |   42 
 src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java                                           |   22 
 src/main/resources/mapper/approve/ApprovalInstanceMapper.xml                                         |    3 
 src/main/java/com/ruoyi/procurementrecord/bean/dto/ReturnSaleProductDto.java                         |    3 
 src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java                        |   40 
 src/main/java/com/ruoyi/mock/service/DataGenerateService.java                                        |   15 
 src/main/java/com/ruoyi/staff/dto/StaffLeaveDto.java                                                 |    1 
 src/main/resources/application-nhxcl.yml                                                             |  268 
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java                        |   37 
 src/main/resources/mapper/account/purchase/AccountPaymentApplicationMapper.xml                       |   12 
 src/main/java/com/ruoyi/staff/controller/PersonalShiftController.java                                |    2 
 src/main/java/com/ruoyi/technology/service/impl/TechnologyOperationServiceImpl.java                  |   21 
 src/main/java/com/ruoyi/mock/controller/DataCheckController.java                                     |   54 
 src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java                            |   54 
 src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java                           |   54 
 docs/mock_data_generate.md                                                                           |  243 
 src/main/java/com/ruoyi/mock/service/impl/DataGenerateServiceImpl.java                               | 1745 +++++
 src/main/resources/mapper/procurementrecord/ReturnSaleProductMapper.xml                              |   15 
 src/main/java/com/ruoyi/ai/assistant/KnowledgeChatAgent.java                                         |   35 
 src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java                |    6 
 src/main/java/com/ruoyi/purchase/mapper/PurchaseLedgerMapper.java                                    |    2 
 src/main/java/com/ruoyi/ai/service/impl/KnowledgeRagServiceImpl.java                                 |  342 +
 src/main/java/com/ruoyi/purchase/vo/PurchaseStockInProductVo.java                                    |    3 
 src/main/resources/application-zdjc.yml                                                              |  268 
 src/main/java/com/ruoyi/account/bean/vo/sales/SalesReturnVo.java                                     |   16 
 src/main/resources/mapper/sales/ShippingInfoMapper.xml                                               |   12 
 src/main/java/com/ruoyi/sales/pojo/ShippingInfo.java                                                 |    1 
 src/main/java/com/ruoyi/ai/controller/KnowledgeChatController.java                                   |   85 
 src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java               |   80 
 src/main/resources/application-jfhy.yml                                                              |  268 
 src/main/java/com/ruoyi/procurementrecord/pojo/ReturnManagement.java                                 |   12 
 src/main/java/com/ruoyi/mock/service/impl/DataCheckServiceImpl.java                                  |  282 
 src/main/java/com/ruoyi/staff/service/impl/StaffSalaryMainServiceImpl.java                           |  181 
 src/main/resources/application-old-pro.yml                                                           |  268 
 src/main/java/com/ruoyi/purchase/vo/SupplierTransactionsDetailsVo.java                               |    3 
 src/main/resources/mapper/system/SysUserMapper.xml                                                   |   24 
 src/main/resources/application-xjgm-pro.yml                                                          |  268 
 src/main/java/com/ruoyi/mock/vo/DataGenerateResult.java                                              |   37 
 src/main/resources/mapper/basic/CustomerMapper.xml                                                   |   54 
 src/main/java/com/ruoyi/purchase/service/IPurchaseLedgerService.java                                 |    2 
 src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java                         |  248 
 src/main/java/com/ruoyi/approve/controller/KnowledgeBaseController.java                              |  140 
 src/main/resources/application-qyhy.yml                                                              |  268 
 src/main/java/com/ruoyi/staff/init/DataInitializer.java                                              |   33 
 src/main/java/com/ruoyi/staff/mapper/SchemeApplicableStaffMapper.java                                |    7 
 src/main/resources/application-hthb.yml                                                              |  268 
 src/main/java/com/ruoyi/approve/service/impl/FinReimbursementServiceImpl.java                        |   32 
 src/main/java/com/ruoyi/account/service/sales/AccountInvoiceApplicationService.java                  |    2 
 src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java                                     |    5 
 src/main/java/com/ruoyi/sales/vo/CustomerTransactionsDetailsVo.java                                  |    3 
 src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java                              |   32 
 src/main/resources/application-rbhb-pro.yml                                                          |  268 
 src/main/java/com/ruoyi/ai/service/KnowledgeRagService.java                                          |   34 
 src/main/java/com/ruoyi/approve/service/impl/KnowledgeBaseVectorServiceImpl.java                     |  144 
 src/main/java/com/ruoyi/production/service/impl/ProductionPlanServiceImpl.java                       |    2 
 src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceLocationConfigServiceImpl.java          |   33 
 src/main/java/com/ruoyi/sales/vo/CustomerTransactionsVo.java                                         |    5 
 src/main/java/com/ruoyi/mock/prompt/MockDataPrompt.java                                              |  242 
 doc/sql/20260609_knowledge_base_vector.sql                                                           |   30 
 src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java                      |   64 
 src/main/resources/application-lt.yml                                                                |  268 
 src/main/java/com/ruoyi/staff/service/impl/SchemeApplicableStaffServiceImpl.java                     |  208 
 src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java                            |    6 
 src/main/java/com/ruoyi/account/bean/vo/sales/SalesOutboundVo.java                                   |    5 
 src/main/java/com/ruoyi/production/enums/ProductOrderStatusEnum.java                                 |   11 
 src/main/java/com/ruoyi/basic/enums/ApplicationTypeEnum.java                                         |    3 
 src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java                            |   27 
 src/main/java/com/ruoyi/mock/vo/DataCheckResult.java                                                 |   36 
 src/main/java/com/ruoyi/technology/service/TechnologyOperationService.java                           |    2 
 src/main/resources/application-btw.yml                                                               |  268 
 src/main/resources/mapper/stock/StockInRecordMapper.xml                                              |    4 
 src/main/java/com/ruoyi/purchase/dto/PurchaseReturnOrderHasAllInfoDto.java                           |    7 
 src/main/java/com/ruoyi/quality/pojo/QualityInspect.java                                             |    2 
 src/main/resources/mapper/account/sales/AccountInvoiceApplicationMapper.xml                          |   31 
 src/main/java/com/ruoyi/staff/controller/StaffSalaryMainController.java                              |   18 
 src/main/java/com/ruoyi/ai/config/EmbeddingStoreConfig.java                                          |   44 
 src/main/resources/mapper/staff/PersonalAttendanceRecordsMapper.xml                                  |    9 
 src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java                                                |    2 
 docs/routing_operation_plan_person.md                                                                |   91 
 src/main/java/com/ruoyi/account/service/impl/sales/AccountInvoiceApplicationServiceImpl.java         |    5 
 .gitignore                                                                                           |    4 
 src/main/java/com/ruoyi/common/utils/DateUtils.java                                                  |   21 
 src/main/java/com/ruoyi/home/controller/HomeController.java                                          |   38 
 src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceRecordsServiceImpl.java                 |   14 
 src/main/java/com/ruoyi/account/mapper/sales/AccountInvoiceApplicationMapper.java                    |    2 
 src/main/java/com/ruoyi/sales/pojo/SalesLedger.java                                                  |    5 
 src/main/resources/application-qlmc-pro.yml                                                          |  268 
 src/main/java/com/ruoyi/purchase/controller/PurchaseReturnOrdersController.java                      |   10 
 src/main/resources/mapper/purchase/PurchaseReturnOrdersMapper.xml                                    |   89 
 src/main/java/com/ruoyi/staff/dto/StaffSalaryCalculateDto.java                                       |   16 
 src/main/java/com/ruoyi/stock/controller/StockOutRecordController.java                               |   11 
 src/main/resources/mapper/staff/SchemeApplicableStaffMapper.xml                                      |   14 
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java                               |   46 
 src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsServiceImpl.java            |    2 
 src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java                            |   10 
 src/main/java/com/ruoyi/purchase/vo/PurchaseReturnOrderProductsDetailVo.java                         |    3 
 src/main/java/com/ruoyi/mock/dto/DataGenerateRequest.java                                            |   33 
 src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java                                            |    8 
 src/main/resources/application-myhb-pro.yml                                                          |  268 
 src/main/resources/mapper/account/sales/AccountSalesCollectionMapper.xml                             |   75 
 src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java                                          |   13 
 src/main/resources/mapper/stock/StockInventoryMapper.xml                                             |    6 
 src/main/java/com/ruoyi/approve/mapper/KnowledgeBaseVectorMapper.java                                |   39 
 src/main/resources/mapper/staff/PersonalShiftMapper.xml                                              |   22 
 src/main/java/com/ruoyi/mock/dto/DataCheckRequest.java                                               |   15 
 src/main/java/com/ruoyi/project/system/domain/SysUser.java                                           |   78 
 src/main/java/com/ruoyi/staff/mapper/StaffSalaryMainMapper.java                                      |    4 
 src/main/resources/mapper/production/ProductionOrderMapper.xml                                       |    4 
 src/main/java/com/ruoyi/account/service/impl/sales/AccountSalesCollectionServiceImpl.java            |   18 
 src/main/java/com/ruoyi/staff/pojo/StaffOnJob.java                                                   |    1 
 src/main/resources/application-hjgc.yml                                                              |  268 
 src/main/java/com/ruoyi/procurementrecord/bean/vo/ShippingProductVo.java                             |    3 
 src/main/java/com/ruoyi/ai/dto/KnowledgeChatRequest.java                                             |   21 
 src/main/java/com/ruoyi/procurementrecord/bean/dto/ReturnManagementDto.java                          |   15 
 src/main/java/com/ruoyi/staff/service/PersonalAttendanceLocationConfigService.java                   |   15 
 src/main/resources/mapper/system/SysDeptMapper.xml                                                   |    3 
 161 files changed, 17,965 insertions(+), 607 deletions(-)

diff --git a/.gitignore b/.gitignore
index d3f800c..8fac07c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,7 +9,9 @@
 !.mvn/wrapper/maven-wrapper.jar
 
 ######################################################################
-# IDE
+# Claude Code
+.claude/
+
 
 ### STS ###
 .apt_generated
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/doc/sql/20260609_knowledge_base_vector.sql b/doc/sql/20260609_knowledge_base_vector.sql
new file mode 100644
index 0000000..7b4323f
--- /dev/null
+++ b/doc/sql/20260609_knowledge_base_vector.sql
@@ -0,0 +1,30 @@
+-- 鐭ヨ瘑搴撳悜閲忔绱㈠姛鑳芥暟鎹簱鍙樻洿
+-- 鎵ц鍓嶈纭繚 knowledge_base 琛ㄥ凡瀛樺湪
+
+-- 1. knowledge_base 琛ㄥ鍔犲瓧娈�
+ALTER TABLE knowledge_base
+ADD COLUMN IF NOT EXISTS file_count INT DEFAULT 0 COMMENT '鏂囦欢鏁伴噺',
+ADD COLUMN IF NOT EXISTS total_chunk_count INT DEFAULT 0 COMMENT '鎬诲垏鐗囨暟閲�',
+ADD COLUMN IF NOT EXISTS description VARCHAR(500) COMMENT '鐭ヨ瘑搴撴弿杩�';
+
+-- 2. 鍒涘缓鐭ヨ瘑搴撴枃浠跺悜閲忚褰曡〃
+CREATE TABLE IF NOT EXISTS knowledge_base_vector (
+    id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '涓婚敭ID',
+    knowledge_base_id BIGINT NOT NULL COMMENT '鍏宠仈鐭ヨ瘑搴揑D',
+    storage_blob_id BIGINT NOT NULL COMMENT '鍏宠仈鏂囦欢blob ID',
+    file_name VARCHAR(255) NOT NULL COMMENT '鏂囦欢鍚嶇О',
+    file_type VARCHAR(50) NOT NULL COMMENT '鏂囦欢绫诲瀷(docx/pdf/xlsx/txt绛�)',
+    vector_status TINYINT DEFAULT 0 COMMENT '鍚戦噺鍖栫姸鎬�: 0-寰呭鐞�, 1-澶勭悊涓�, 2-宸插畬鎴�, 3-澶辫触',
+    vector_error VARCHAR(500) COMMENT '鍚戦噺鍖栧け璐ュ師鍥�',
+    chunk_count INT DEFAULT 0 COMMENT '鍒囩墖鏁伴噺',
+    namespace VARCHAR(100) COMMENT '鍚戦噺鍛藉悕绌洪棿',
+    create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+    create_user INT COMMENT '鍒涘缓浜�',
+    update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+    update_user INT COMMENT '鏇存柊浜�',
+    tenant_id BIGINT COMMENT '绉熸埛ID',
+    dept_id BIGINT COMMENT '閮ㄩ棬ID',
+    INDEX idx_knowledge_base_id (knowledge_base_id),
+    INDEX idx_storage_blob_id (storage_blob_id),
+    INDEX idx_vector_status (vector_status)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='鐭ヨ瘑搴撴枃浠跺悜閲忚褰曡〃';
\ No newline at end of file
diff --git "a/doc/\347\237\245\350\257\206\345\272\223RAG\345\212\237\350\203\275\345\256\236\347\216\260\346\226\207\346\241\243.md" "b/doc/\347\237\245\350\257\206\345\272\223RAG\345\212\237\350\203\275\345\256\236\347\216\260\346\226\207\346\241\243.md"
new file mode 100644
index 0000000..4a94cc5
--- /dev/null
+++ "b/doc/\347\237\245\350\257\206\345\272\223RAG\345\212\237\350\203\275\345\256\236\347\216\260\346\226\207\346\241\243.md"
@@ -0,0 +1,1034 @@
+# 鐭ヨ瘑搴揜AG鍚戦噺妫�绱㈠姛鑳藉疄鐜版枃妗�
+
+## 涓�銆佸姛鑳芥杩�
+
+鍩轰簬 RAG锛圧etrieval-Augmented Generation锛夋妧鏈疄鐜扮煡璇嗗簱闂瓟鍔熻兘锛屾敮鎸侊細
+- 鐭ヨ瘑搴撶鐞嗭紙CRUD锛�
+- 鏂囦欢涓婁紶涓庡悜閲忓寲澶勭悊
+- 鍩轰簬鍚戦噺妫�绱㈢殑鏅鸿兘闂瓟
+- 澶氱鏂囦欢鏍煎紡鏀寔锛坱xt銆乵d銆乨ocx銆亁lsx銆亁ls銆乸df锛�
+
+## 浜屻�佹妧鏈灦鏋�
+
+### 2.1 鎶�鏈爤
+| 缁勪欢 | 鎶�鏈� |
+|------|------|
+| 鍚戦噺鏁版嵁搴� | Pinecone |
+| Embedding妯″瀷 | 闃块噷浜� DashScope text-embedding-v3 |
+| LLM | 闃块噷浜戦�氫箟鍗冮棶 qwen-max |
+| 妗嗘灦 | langchain4j |
+| ORM | MyBatis-Plus |
+
+### 2.2 鏋舵瀯鍥�
+
+```
+鈹屸攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+鈹�                        鍓嶇搴旂敤                              鈹�
+鈹斺攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+                              鈹�
+                              鈻�
+鈹屸攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+鈹�                     Controller Layer                         鈹�
+鈹�  鈹屸攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�  鈹屸攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�   鈹�
+鈹�  鈹� KnowledgeBaseCtrl   鈹�  鈹� KnowledgeChatController     鈹�   鈹�
+鈹�  鈹� (鐭ヨ瘑搴撶鐞�)         鈹�  鈹� (鐭ヨ瘑搴撻棶绛�)                 鈹�   鈹�
+鈹�  鈹斺攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�  鈹斺攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�   鈹�
+鈹斺攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+                              鈹�
+                              鈻�
+鈹屸攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+鈹�                      Service Layer                           鈹�
+鈹�  鈹屸攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�  鈹屸攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�   鈹�
+鈹�  鈹侹nowledgeBaseService 鈹�  鈹� KnowledgeRagService         鈹�   鈹�
+鈹�  鈹� (鐭ヨ瘑搴揅RUD)         鈹�  鈹� (鍚戦噺鍖�/妫�绱�)                鈹�   鈹�
+鈹�  鈹斺攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�  鈹斺攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�   鈹�
+鈹斺攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+                              鈹�
+                              鈻�
+鈹屸攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+鈹�                      AI Layer                                鈹�
+鈹�  鈹屸攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�  鈹屸攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�   鈹�
+鈹�  鈹� KnowledgeChatAgent  鈹�  鈹� EmbeddingStore (Pinecone)   鈹�   鈹�
+鈹�  鈹� (闂瓟Agent)          鈹�  鈹� (鍚戦噺瀛樺偍)                   鈹�   鈹�
+鈹�  鈹斺攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�  鈹斺攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�   鈹�
+鈹斺攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+```
+
+---
+
+## 涓夈�佸悗绔疄鐜�
+
+### 3.1 鏁版嵁搴撹璁�
+
+#### 3.1.1 鐭ヨ瘑搴撹〃锛坘nowledge_base锛�
+
+```sql
+CREATE TABLE knowledge_base (
+    id BIGINT AUTO_INCREMENT PRIMARY KEY,
+    title VARCHAR(255) COMMENT '鐭ヨ瘑鏍囬',
+    type VARCHAR(50) COMMENT '鐭ヨ瘑绫诲瀷',
+    scenario VARCHAR(255) COMMENT '閫傜敤鍦烘櫙',
+    efficiency VARCHAR(20) COMMENT '瑙e喅鏁堢巼',
+    problem TEXT COMMENT '闂鎻忚堪',
+    solution TEXT COMMENT '瑙e喅鏂规',
+    key_points TEXT COMMENT '鍏抽敭瑕佺偣',
+    creator VARCHAR(100) COMMENT '鍒涘缓浜�',
+    usage_count INT DEFAULT 0 COMMENT '浣跨敤娆℃暟',
+    file_count INT DEFAULT 0 COMMENT '鏂囦欢鏁伴噺',
+    total_chunk_count INT DEFAULT 0 COMMENT '鎬诲垏鐗囨暟閲�',
+    description VARCHAR(500) COMMENT '鐭ヨ瘑搴撴弿杩�',
+    create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
+    update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    create_user INT,
+    update_user INT,
+    tenant_id BIGINT,
+    dept_id BIGINT
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='鐭ヨ瘑搴撹〃';
+```
+
+#### 3.1.2 鐭ヨ瘑搴撳悜閲忚褰曡〃锛坘nowledge_base_vector锛�
+
+```sql
+CREATE TABLE knowledge_base_vector (
+    id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '涓婚敭ID',
+    knowledge_base_id BIGINT NOT NULL COMMENT '鍏宠仈鐭ヨ瘑搴揑D',
+    storage_blob_id BIGINT NOT NULL COMMENT '鍏宠仈鏂囦欢blob ID',
+    file_name VARCHAR(255) NOT NULL COMMENT '鏂囦欢鍚嶇О',
+    file_type VARCHAR(50) NOT NULL COMMENT '鏂囦欢绫诲瀷',
+    vector_status TINYINT DEFAULT 0 COMMENT '鍚戦噺鍖栫姸鎬�: 0-寰呭鐞�, 1-澶勭悊涓�, 2-宸插畬鎴�, 3-澶辫触',
+    vector_error VARCHAR(500) COMMENT '鍚戦噺鍖栧け璐ュ師鍥�',
+    chunk_count INT DEFAULT 0 COMMENT '鍒囩墖鏁伴噺',
+    namespace VARCHAR(100) COMMENT '鍚戦噺鍛藉悕绌洪棿',
+    create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
+    create_user INT,
+    update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    update_user INT,
+    tenant_id BIGINT,
+    dept_id BIGINT,
+    INDEX idx_knowledge_base_id (knowledge_base_id),
+    INDEX idx_storage_blob_id (storage_blob_id),
+    INDEX idx_vector_status (vector_status)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='鐭ヨ瘑搴撴枃浠跺悜閲忚褰曡〃';
+```
+
+### 3.2 Maven渚濊禆
+
+```xml
+<!-- langchain4j BOM -->
+<dependencyManagement>
+    <dependencies>
+        <dependency>
+            <groupId>dev.langchain4j</groupId>
+            <artifactId>langchain4j-bom</artifactId>
+            <version>1.0.0-beta3</version>
+            <type>pom</type>
+            <scope>import</scope>
+        </dependency>
+    </dependencies>
+</dependencyManagement>
+
+<dependencies>
+    <!-- langchain4j 鏍稿績 -->
+    <dependency>
+        <groupId>dev.langchain4j</groupId>
+        <artifactId>langchain4j-spring-boot-starter</artifactId>
+    </dependency>
+
+    <!-- Pinecone 鍚戦噺鏁版嵁搴� -->
+    <dependency>
+        <groupId>dev.langchain4j</groupId>
+        <artifactId>langchain4j-pinecone</artifactId>
+    </dependency>
+
+    <!-- 闃块噷浜� DashScope -->
+    <dependency>
+        <groupId>dev.langchain4j</groupId>
+        <artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
+    </dependency>
+</dependencies>
+```
+
+### 3.3 閰嶇疆鏂囦欢锛坅pplication.yml锛�
+
+```yaml
+# Pinecone 鍚戦噺鏁版嵁搴撻厤缃�
+pinecone:
+  api-key: your-pinecone-api-key
+  index: your-index-name
+  namespace: knowledge-base
+
+# langchain4j 閰嶇疆
+langchain4j:
+  community:
+    dashscope:
+      streaming-chat-model:
+        api-key: your-dashscope-api-key
+        model-name: "qwen-max"
+      embedding-model:
+        api-key: your-dashscope-api-key
+        model-name: "text-embedding-v3"
+```
+
+### 3.4 鏍稿績浠g爜瀹炵幇
+
+#### 3.4.1 瀹炰綋绫�
+
+**KnowledgeBase.java**
+```java
+@Data
+@TableName("knowledge_base")
+public class KnowledgeBase implements Serializable {
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    private String title;
+    private String type;
+    private String scenario;
+    private String efficiency;
+    private String problem;
+    private String solution;
+    private String keyPoints;
+    private String creator;
+    private Integer usageCount;
+    private Integer fileCount;
+    private Integer totalChunkCount;
+    private String description;
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+    @TableField(fill = FieldFill.INSERT)
+    private Integer createUser;
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Integer updateUser;
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+    @TableField(fill = FieldFill.INSERT)
+    private Long deptId;
+}
+```
+
+**KnowledgeBaseVector.java**
+```java
+@Data
+@TableName("knowledge_base_vector")
+public class KnowledgeBaseVector implements Serializable {
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    private Long knowledgeBaseId;
+    private Long storageBlobId;
+    private String fileName;
+    private String fileType;
+    private Integer vectorStatus;
+    private String vectorError;
+    private Integer chunkCount;
+    private String namespace;
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+    @TableField(fill = FieldFill.INSERT)
+    private Integer createUser;
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Integer updateUser;
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+    @TableField(fill = FieldFill.INSERT)
+    private Long deptId;
+
+    // 鍚戦噺鍖栫姸鎬佸父閲�
+    public static final int STATUS_PENDING = 0;
+    public static final int STATUS_PROCESSING = 1;
+    public static final int STATUS_COMPLETED = 2;
+    public static final int STATUS_FAILED = 3;
+}
+```
+
+#### 3.4.2 EmbeddingStore閰嶇疆
+
+**EmbeddingStoreConfig.java**
+```java
+@Configuration
+public class EmbeddingStoreConfig {
+
+    @Value("${pinecone.api-key}")
+    private String pineconeApiKey;
+
+    @Value("${pinecone.index}")
+    private String indexName;
+
+    @Value("${pinecone.namespace}")
+    private String namespace;
+
+    @Bean
+    public Pinecone pinecone() {
+        return new Pinecone.Builder(pineconeApiKey).build();
+    }
+
+    @Bean
+    public Index pineconeIndex(Pinecone pinecone) {
+        return pinecone.getIndexConnection(indexName);
+    }
+
+    @Bean
+    public EmbeddingStore<TextSegment> embeddingStore(EmbeddingModel embeddingModel) {
+        return PineconeEmbeddingStore.builder()
+                .apiKey(pineconeApiKey)
+                .index(indexName)
+                .nameSpace(namespace)
+                .createIndex(PineconeServerlessIndexConfig.builder()
+                        .cloud("AWS")
+                        .region("us-east-1")
+                        .dimension(embeddingModel.dimension())
+                        .build())
+                .build();
+    }
+}
+```
+
+#### 3.4.3 RAG鏈嶅姟瀹炵幇
+
+**KnowledgeRagService.java**
+```java
+public interface KnowledgeRagService {
+    void processVectorAsync(Long vectorId);
+    void processVector(Long vectorId);
+    List<String> searchRelevantContent(String namespace, String query, int maxResults);
+    void deleteEmbeddings(String namespace, Long storageBlobId);
+}
+```
+
+**KnowledgeRagServiceImpl.java**锛堟牳蹇冨疄鐜帮級
+```java
+@Slf4j
+@Service
+public class KnowledgeRagServiceImpl implements KnowledgeRagService {
+
+    private final KnowledgeBaseVectorService knowledgeBaseVectorService;
+    private final StorageBlobService storageBlobService;
+    private final EmbeddingModel embeddingModel;
+    private final EmbeddingStore<TextSegment> embeddingStore;
+    private final FileProperties fileProperties;
+    private final Index pineconeIndex;
+
+    @Value("${pinecone.namespace}")
+    private String namespace;
+
+    private static final int CHUNK_SIZE = 500;
+    private static final int CHUNK_OVERLAP = 100;
+    private static final long CHUNK_THRESHOLD_BYTES = 80L * 1024 * 1024;
+    private static final int EMBEDDING_MAX_LENGTH = 8000;
+
+    @Override
+    @Async("threadPoolTaskExecutor")
+    public void processVectorAsync(Long vectorId) {
+        processVector(vectorId);
+    }
+
+    @Override
+    public void processVector(Long vectorId) {
+        KnowledgeBaseVector vector = knowledgeBaseVectorService.getById(vectorId);
+        if (vector == null) return;
+
+        try {
+            // 鏇存柊鐘舵�佷负澶勭悊涓�
+            knowledgeBaseVectorService.updateVectorStatus(vectorId, STATUS_PROCESSING, null, null);
+
+            // 鑾峰彇鏂囦欢鍐呭
+            StorageBlob blob = storageBlobService.getById(vector.getStorageBlobId());
+            File file = getFile(blob);
+            String content = extractFileContent(file, vector.getFileName());
+
+            if (content == null || content.trim().isEmpty()) {
+                throw new RuntimeException("鏂囦欢鍐呭涓虹┖");
+            }
+
+            // 鏂囨湰鍒囩墖
+            List<TextSegment> chunks;
+            boolean needChunk = file.length() > CHUNK_THRESHOLD_BYTES || content.length() > EMBEDDING_MAX_LENGTH;
+            if (needChunk) {
+                chunks = splitText(content, vector);
+            } else {
+                Map<String, Object> metadata = buildMetadata(vector);
+                chunks = List.of(TextSegment.from(content, new Metadata(metadata)));
+            }
+
+            // 鐢熸垚宓屽叆鍚戦噺骞跺瓨鍌�
+            int chunkCount = 0;
+            for (TextSegment chunk : chunks) {
+                Embedding embedding = embeddingModel.embed(chunk).content();
+                embeddingStore.add(embedding, chunk);
+                chunkCount++;
+            }
+
+            // 鏇存柊鐘舵�佷负瀹屾垚
+            knowledgeBaseVectorService.updateVectorStatus(vectorId, STATUS_COMPLETED, chunkCount, null);
+
+        } catch (Exception e) {
+            log.error("鍚戦噺鍖栧鐞嗗け璐�", e);
+            knowledgeBaseVectorService.updateVectorStatus(vectorId, STATUS_FAILED, null, e.getMessage());
+        }
+    }
+
+    @Override
+    public List<String> searchRelevantContent(String namespace, String query, int maxResults) {
+        Embedding queryEmbedding = embeddingModel.embed(query).content();
+        EmbeddingSearchRequest searchRequest = EmbeddingSearchRequest.builder()
+                .queryEmbedding(queryEmbedding)
+                .maxResults(maxResults)
+                .minScore(0.7)
+                .build();
+        EmbeddingSearchResult<TextSegment> searchResult = embeddingStore.search(searchRequest);
+        return searchResult.matches().stream()
+                .map(match -> match.embedded().text())
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public void deleteEmbeddings(String namespace, Long storageBlobId) {
+        Struct filter = Struct.newBuilder()
+                .putFields("storageBlobId", Value.newBuilder()
+                        .setStructValue(Struct.newBuilder()
+                                .putFields("$eq", Value.newBuilder()
+                                        .setNumberValue(storageBlobId.doubleValue())
+                                        .build()))
+                        .build())
+                .build();
+        pineconeIndex.delete(new ArrayList<>(), false, this.namespace, filter);
+    }
+
+    private String extractFileContent(File file, String fileName) throws Exception {
+        String ext = getFileExtension(fileName);
+        if (isPlainText(ext)) {
+            return readFileWithEncoding(file);
+        }
+        if ("docx".equals(ext)) {
+            return extractDocx(file);
+        }
+        if ("xlsx".equals(ext) || "xls".equals(ext)) {
+            return extractExcel(file);
+        }
+        return readFileWithEncoding(file);
+    }
+
+    // ... 鍏朵粬杈呭姪鏂规硶
+}
+```
+
+#### 3.4.4 鐭ヨ瘑搴撻棶绛擜gent
+
+**KnowledgeChatAgent.java**
+```java
+@AiService(
+        wiringMode = EXPLICIT,
+        streamingChatModel = "qwenStreamingChatModel",
+        chatMemoryProvider = "chatMemoryProvider"
+)
+public interface KnowledgeChatAgent {
+
+    @SystemMessage("""
+            浣犳槸浼佷笟鐭ヨ瘑搴撻棶绛斿姪鎵嬨��
+            浣犻渶瑕佸熀浜庢彁渚涚殑鐭ヨ瘑搴撳唴瀹瑰洖绛旂敤鎴烽棶棰樸��
+            閬靛惊浠ヤ笅瑙勫垯锛�
+            1. 涓ユ牸鍩轰簬鐭ヨ瘑搴撳唴瀹瑰洖绛旓紝涓嶈缂栭�犱俊鎭�
+            2. 濡傛灉鐭ヨ瘑搴撲腑娌℃湁鐩稿叧淇℃伅锛屾槑纭憡鐭ョ敤鎴�
+            3. 鍥炵瓟瑕佸噯纭�佺畝娲併�佹湁鏉$悊
+            4. 寮曠敤鏉ユ簮鏃舵敞鏄�"鏍规嵁鐭ヨ瘑搴撳唴瀹�"
+            """)
+    Flux<String> chat(@MemoryId String memoryId, @UserMessage String userMessage);
+}
+```
+
+#### 3.4.5 Controller灞�
+
+**KnowledgeBaseController.java**
+```java
+@RestController
+@RequestMapping("/knowledgeBase")
+@Tag(name = "鐭ヨ瘑搴撶鐞�")
+public class KnowledgeBaseController {
+
+    @GetMapping("/getList")
+    public AjaxResult getList(@RequestParam(defaultValue = "1") long current,
+                              @RequestParam(defaultValue = "10") long size,
+                              KnowledgeBase knowledgeBase) {
+        Page page = new Page(current, size);
+        return AjaxResult.success(knowledgeBaseService.listpage(page, knowledgeBase));
+    }
+
+    @PostMapping("/add")
+    public AjaxResult add(@RequestBody KnowledgeBase knowledgeBase) {
+        return AjaxResult.success(knowledgeBaseService.save(knowledgeBase));
+    }
+
+    @PostMapping("/update")
+    public AjaxResult update(@RequestBody KnowledgeBase knowledgeBase) {
+        return AjaxResult.success(knowledgeBaseService.updateById(knowledgeBase));
+    }
+
+    @DeleteMapping("/delete")
+    public AjaxResult delete(@RequestBody List<Long> ids) {
+        return AjaxResult.success(knowledgeBaseService.removeByIds(ids));
+    }
+
+    @GetMapping("/vector/status/{knowledgeBaseId}")
+    @Operation(summary = "鏌ヨ鐭ヨ瘑搴撴枃浠跺悜閲忓寲鐘舵��")
+    public AjaxResult getVectorStatus(@PathVariable Long knowledgeBaseId) {
+        return AjaxResult.success(knowledgeBaseVectorService.getVectorStatusByKnowledgeBaseId(knowledgeBaseId));
+    }
+
+    @PostMapping("/vector/reprocess/{vectorId}")
+    @Operation(summary = "閲嶆柊鍚戦噺鍖栨枃浠�")
+    public AjaxResult reprocessVector(@PathVariable Long vectorId) {
+        knowledgeBaseVectorService.reprocessVector(vectorId);
+        return AjaxResult.success("宸查噸鏂版彁浜ゅ悜閲忓寲浠诲姟");
+    }
+
+    @PostMapping("/file/save")
+    @Operation(summary = "淇濆瓨鐭ヨ瘑搴撴枃浠跺叧鑱�")
+    public AjaxResult saveKnowledgeBaseFiles(@RequestBody KnowledgeBaseFileDTO dto) {
+        // 淇濆瓨闄勪欢鍏宠仈骞惰Е鍙戝悜閲忓寲
+        // ...
+    }
+
+    @DeleteMapping("/file/delete")
+    @Operation(summary = "鍒犻櫎鐭ヨ瘑搴撴枃浠�")
+    public AjaxResult deleteKnowledgeBaseFiles(@RequestBody List<Long> vectorIds) {
+        knowledgeBaseVectorService.deleteVectors(vectorIds);
+        return AjaxResult.success();
+    }
+}
+```
+
+**KnowledgeChatController.java**
+```java
+@RestController
+@RequestMapping("/ai/knowledge")
+@Tag(name = "鐭ヨ瘑搴撻棶绛�")
+public class KnowledgeChatController {
+
+    private final KnowledgeChatAgent knowledgeChatAgent;
+    private final KnowledgeRagService knowledgeRagService;
+    private final KnowledgeBaseService knowledgeBaseService;
+
+    @PostMapping(value = "/chat", produces = "text/stream;charset=utf-8")
+    @Operation(summary = "鐭ヨ瘑搴撻棶绛�")
+    public Flux<String> chat(@RequestBody KnowledgeChatRequest request) {
+        // 妫�绱㈢浉鍏冲唴瀹�
+        String namespace = "kb-" + request.getKnowledgeBaseId();
+        List<String> relevantContents = knowledgeRagService.searchRelevantContent(
+                namespace, request.getQuestion(), 5);
+
+        if (relevantContents.isEmpty()) {
+            return Flux.just("鐭ヨ瘑搴撲腑鏈壘鍒扮浉鍏冲唴瀹�");
+        }
+
+        // 鏋勫缓涓婁笅鏂�
+        StringBuilder context = new StringBuilder();
+        context.append("浠ヤ笅鏄粠鐭ヨ瘑搴撲腑妫�绱㈠埌鐨勭浉鍏冲唴瀹癸細\n\n");
+        for (int i = 0; i < relevantContents.size(); i++) {
+            context.append("銆愬唴瀹�").append(i + 1).append("銆慭n");
+            context.append(relevantContents.get(i)).append("\n\n");
+        }
+        context.append("---\n璇峰熀浜庝互涓婄煡璇嗗簱鍐呭鍥炵瓟锛歕n").append(request.getQuestion());
+
+        return knowledgeChatAgent.chat(request.getMemoryId(), context.toString());
+    }
+
+    @GetMapping("/list")
+    @Operation(summary = "鐭ヨ瘑搴撳垪琛�")
+    public AjaxResult listKnowledgeBases() {
+        return AjaxResult.success(knowledgeBaseService.list());
+    }
+}
+```
+
+---
+
+## 鍥涖�丄PI鎺ュ彛鏂囨。
+
+### 4.1 鐭ヨ瘑搴撶鐞嗘帴鍙�
+
+| 鎺ュ彛 | 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|------|
+| 鑾峰彇鍒楄〃 | GET | /knowledgeBase/getList | 鍒嗛〉鏌ヨ鐭ヨ瘑搴撳垪琛� |
+| 鏂板鐭ヨ瘑搴� | POST | /knowledgeBase/add | 鍒涘缓鐭ヨ瘑搴� |
+| 鏇存柊鐭ヨ瘑搴� | POST | /knowledgeBase/update | 鏇存柊鐭ヨ瘑搴撲俊鎭� |
+| 鍒犻櫎鐭ヨ瘑搴� | DELETE | /knowledgeBase/delete | 鎵归噺鍒犻櫎鐭ヨ瘑搴� |
+| 鏌ヨ鍚戦噺鍖栫姸鎬� | GET | /knowledgeBase/vector/status/{id} | 鏌ヨ鏂囦欢鍚戦噺鍖栫姸鎬� |
+| 閲嶆柊鍚戦噺鍖� | POST | /knowledgeBase/vector/reprocess/{id} | 閲嶆柊澶勭悊澶辫触鐨勬枃浠� |
+| 淇濆瓨鏂囦欢鍏宠仈 | POST | /knowledgeBase/file/save | 涓婁紶鏂囦欢鍚庡叧鑱斿埌鐭ヨ瘑搴� |
+| 鍒犻櫎鏂囦欢 | DELETE | /knowledgeBase/file/delete | 鍒犻櫎鐭ヨ瘑搴撴枃浠� |
+
+### 4.2 鐭ヨ瘑搴撻棶绛旀帴鍙�
+
+| 鎺ュ彛 | 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|------|
+| 鐭ヨ瘑搴撻棶绛� | POST | /ai/knowledge/chat | 娴佸紡杩斿洖闂瓟缁撴灉 |
+| 鐭ヨ瘑搴撳垪琛� | GET | /ai/knowledge/list | 鑾峰彇鍙�夌煡璇嗗簱鍒楄〃 |
+
+### 4.3 鎺ュ彛璇︾粏璇存槑
+
+#### 4.3.1 淇濆瓨鐭ヨ瘑搴撴枃浠跺叧鑱�
+
+**璇锋眰**
+```json
+POST /knowledgeBase/file/save
+{
+    "knowledgeBaseId": 1,
+    "storageBlobIds": [100, 101, 102]
+}
+```
+
+**鍝嶅簲**
+```json
+{
+    "code": 200,
+    "msg": "鎿嶄綔鎴愬姛"
+}
+```
+
+#### 4.3.2 鐭ヨ瘑搴撻棶绛�
+
+**璇锋眰**
+```json
+POST /ai/knowledge/chat
+Content-Type: application/json
+
+{
+    "knowledgeBaseId": 1,
+    "memoryId": "session-uuid",
+    "question": "濡備綍澶勭悊搴撳瓨鐩樼偣宸紓锛�"
+}
+```
+
+**鍝嶅簲**锛圫SE娴佸紡锛�
+```
+鏍规嵁鐭ヨ瘑搴撳唴瀹癸紝搴撳瓨鐩樼偣宸紓鐨勫鐞嗘祦绋嬪涓嬶細
+
+1. 鍙戠幇宸紓鍚庯紝棣栧厛鏍稿鐩樼偣璁板綍...
+2. 妫�鏌ユ槸鍚︽湁婕忕洏鎴栭敊鐩�...
+3. ...
+```
+
+---
+
+## 浜斻�佸墠绔疄鐜�
+
+### 5.1 鐭ヨ瘑搴撶鐞嗛〉闈�
+
+```vue
+<template>
+  <div class="knowledge-base">
+    <!-- 鍒楄〃 -->
+    <el-table :data="tableData" border>
+      <el-table-column prop="title" label="鐭ヨ瘑鏍囬" />
+      <el-table-column prop="type" label="鐭ヨ瘑绫诲瀷" />
+      <el-table-column prop="fileCount" label="鏂囦欢鏁伴噺" />
+      <el-table-column prop="totalChunkCount" label="鍒囩墖鏁伴噺" />
+      <el-table-column label="鎿嶄綔">
+        <template #default="{ row }">
+          <el-button @click="handleEdit(row)">缂栬緫</el-button>
+          <el-button @click="handleFiles(row)">鏂囦欢绠$悊</el-button>
+          <el-button @click="handleChat(row)">闂瓟</el-button>
+          <el-button type="danger" @click="handleDelete(row)">鍒犻櫎</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script setup>
+import { ref, onMounted } from 'vue'
+import { getKnowledgeBaseList, deleteKnowledgeBase } from '@/api/knowledge'
+
+const tableData = ref([])
+
+const loadData = async () => {
+  const res = await getKnowledgeBaseList({ current: 1, size: 10 })
+  tableData.value = res.data.records
+}
+
+onMounted(loadData)
+</script>
+```
+
+### 5.2 鏂囦欢涓婁紶涓庡悜閲忓寲鐘舵��
+
+```vue
+<template>
+  <div class="file-manager">
+    <!-- 鏂囦欢涓婁紶 -->
+    <el-upload
+      :action="uploadUrl"
+      :on-success="handleUploadSuccess"
+      multiple
+    >
+      <el-button type="primary">涓婁紶鏂囦欢</el-button>
+    </el-upload>
+
+    <!-- 鏂囦欢鍒楄〃涓庡悜閲忓寲鐘舵�� -->
+    <el-table :data="fileList">
+      <el-table-column prop="fileName" label="鏂囦欢鍚�" />
+      <el-table-column label="鍚戦噺鍖栫姸鎬�">
+        <template #default="{ row }">
+          <el-tag :type="getStatusType(row.vectorStatus)">
+            {{ getStatusText(row.vectorStatus) }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column prop="chunkCount" label="鍒囩墖鏁�" />
+      <el-table-column label="鎿嶄綔">
+        <template #default="{ row }">
+          <el-button v-if="row.vectorStatus === 3" @click="reprocess(row)">
+            閲嶆柊澶勭悊
+          </el-button>
+          <el-button type="danger" @click="deleteFile(row)">鍒犻櫎</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script setup>
+const uploadUrl = import.meta.env.VITE_APP_BASE_API + '/common/upload'
+
+// 涓婁紶鎴愬姛鍚庝繚瀛樺叧鑱�
+const uploadedBlobIds = ref([])
+
+const handleUploadSuccess = (response, file) => {
+  if (response.code === 200) {
+    uploadedBlobIds.value.push(response.data.id)
+  }
+}
+
+// 淇濆瓨鏂囦欢鍏宠仈
+const saveFiles = async () => {
+  await saveKnowledgeBaseFiles({
+    knowledgeBaseId: props.knowledgeBaseId,
+    storageBlobIds: uploadedBlobIds.value
+  })
+  // 鍒锋柊鏂囦欢鍒楄〃
+  loadFileList()
+}
+
+// 鐘舵�佹枃鏈槧灏�
+const getStatusText = (status) => {
+  const map = {
+    0: '寰呭鐞�',
+    1: '澶勭悊涓�',
+    2: '宸插畬鎴�',
+    3: '澶辫触'
+  }
+  return map[status] || '鏈煡'
+}
+
+const getStatusType = (status) => {
+  const map = {
+    0: 'info',
+    1: 'warning',
+    2: 'success',
+    3: 'danger'
+  }
+  return map[status] || 'info'
+}
+</script>
+```
+
+### 5.3 鐭ヨ瘑搴撻棶绛旂晫闈�
+
+```vue
+<template>
+  <div class="knowledge-chat">
+    <!-- 鐭ヨ瘑搴撻�夋嫨 -->
+    <el-select v-model="selectedKbId" placeholder="閫夋嫨鐭ヨ瘑搴�">
+      <el-option
+        v-for="kb in knowledgeBases"
+        :key="kb.id"
+        :label="kb.title"
+        :value="kb.id"
+      />
+    </el-select>
+
+    <!-- 瀵硅瘽鍖哄煙 -->
+    <div class="chat-messages">
+      <div
+        v-for="(msg, index) in messages"
+        :key="index"
+        :class="['message', msg.role]"
+      >
+        <div class="content">{{ msg.content }}</div>
+      </div>
+    </div>
+
+    <!-- 杈撳叆妗� -->
+    <el-input
+      v-model="inputQuestion"
+      placeholder="璇疯緭鍏ラ棶棰�"
+      @keyup.enter="sendMessage"
+    >
+      <template #append>
+        <el-button @click="sendMessage" :loading="loading">鍙戦��</el-button>
+      </template>
+    </el-input>
+  </div>
+</template>
+
+<script setup>
+import { ref, onMounted } from 'vue'
+import { getKnowledgeBaseList, knowledgeChat } from '@/api/knowledge'
+
+const knowledgeBases = ref([])
+const selectedKbId = ref(null)
+const messages = ref([])
+const inputQuestion = ref('')
+const loading = ref(false)
+const memoryId = ref(crypto.randomUUID())
+
+const sendMessage = async () => {
+  if (!inputQuestion.value.trim()) return
+  if (!selectedKbId.value) {
+    ElMessage.warning('璇烽�夋嫨鐭ヨ瘑搴�')
+    return
+  }
+
+  // 娣诲姞鐢ㄦ埛娑堟伅
+  messages.value.push({
+    role: 'user',
+    content: inputQuestion.value
+  })
+
+  loading.value = true
+
+  try {
+    // 娴佸紡璇锋眰
+    const response = await fetch('/api/ai/knowledge/chat', {
+      method: 'POST',
+      headers: { 'Content-Type': 'application/json' },
+      body: JSON.stringify({
+        knowledgeBaseId: selectedKbId.value,
+        memoryId: memoryId.value,
+        question: inputQuestion.value
+      })
+    })
+
+    // 澶勭悊SSE娴佸紡鍝嶅簲
+    const reader = response.body.getReader()
+    const decoder = new TextDecoder()
+    let aiContent = ''
+
+    messages.value.push({ role: 'assistant', content: '' })
+
+    while (true) {
+      const { done, value } = await reader.read()
+      if (done) break
+
+      const text = decoder.decode(value)
+      aiContent += text
+      messages.value[messages.value.length - 1].content = aiContent
+    }
+  } finally {
+    loading.value = false
+    inputQuestion.value = ''
+  }
+}
+
+onMounted(async () => {
+  const res = await getKnowledgeBaseList()
+  knowledgeBases.value = res.data
+})
+</script>
+```
+
+### 5.4 API灏佽
+
+```javascript
+// api/knowledge.js
+import request from '@/utils/request'
+
+// 鑾峰彇鐭ヨ瘑搴撳垪琛�
+export function getKnowledgeBaseList(params) {
+  return request({
+    url: '/knowledgeBase/getList',
+    method: 'get',
+    params
+  })
+}
+
+// 鏂板鐭ヨ瘑搴�
+export function addKnowledgeBase(data) {
+  return request({
+    url: '/knowledgeBase/add',
+    method: 'post',
+    data
+  })
+}
+
+// 鏇存柊鐭ヨ瘑搴�
+export function updateKnowledgeBase(data) {
+  return request({
+    url: '/knowledgeBase/update',
+    method: 'post',
+    data
+  })
+}
+
+// 鍒犻櫎鐭ヨ瘑搴�
+export function deleteKnowledgeBase(ids) {
+  return request({
+    url: '/knowledgeBase/delete',
+    method: 'delete',
+    data: ids
+  })
+}
+
+// 鑾峰彇鏂囦欢鍚戦噺鍖栫姸鎬�
+export function getVectorStatus(knowledgeBaseId) {
+  return request({
+    url: `/knowledgeBase/vector/status/${knowledgeBaseId}`,
+    method: 'get'
+  })
+}
+
+// 閲嶆柊鍚戦噺鍖�
+export function reprocessVector(vectorId) {
+  return request({
+    url: `/knowledgeBase/vector/reprocess/${vectorId}`,
+    method: 'post'
+  })
+}
+
+// 淇濆瓨鏂囦欢鍏宠仈
+export function saveKnowledgeBaseFiles(data) {
+  return request({
+    url: '/knowledgeBase/file/save',
+    method: 'post',
+    data
+  })
+}
+
+// 鍒犻櫎鏂囦欢
+export function deleteKnowledgeBaseFiles(vectorIds) {
+  return request({
+    url: '/knowledgeBase/file/delete',
+    method: 'delete',
+    data: vectorIds
+  })
+}
+
+// 鐭ヨ瘑搴撻棶绛旓紙娴佸紡锛�
+export async function knowledgeChat(data) {
+  const response = await fetch('/api/ai/knowledge/chat', {
+    method: 'POST',
+    headers: { 'Content-Type': 'application/json' },
+    body: JSON.stringify(data)
+  })
+  return response.body
+}
+
+// 鑾峰彇鐭ヨ瘑搴撳垪琛紙闂瓟鐢級
+export function getKnowledgeBaseListForChat() {
+  return request({
+    url: '/ai/knowledge/list',
+    method: 'get'
+  })
+}
+```
+
+---
+
+## 鍏�佹牳蹇冩祦绋�
+
+### 6.1 鏂囦欢涓婁紶涓庡悜閲忓寲娴佺▼
+
+```
+1. 鍓嶇璋冪敤 /common/upload 涓婁紶鏂囦欢 鈫� 杩斿洖 storageBlobId
+2. 鍓嶇璋冪敤 /knowledgeBase/file/save 鍏宠仈鏂囦欢鍒扮煡璇嗗簱
+3. 鍚庣鍒涘缓 KnowledgeBaseVector 璁板綍锛堢姸鎬侊細寰呭鐞嗭級
+4. 鍚庣寮傛璋冪敤 KnowledgeRagService.processVectorAsync()
+   鈹溾攢鈹� 鏇存柊鐘舵�佷负"澶勭悊涓�"
+   鈹溾攢鈹� 鎻愬彇鏂囦欢鍐呭锛堟敮鎸佸绉嶆牸寮忥級
+   鈹溾攢鈹� 鑷姩妫�娴嬫枃浠剁紪鐮侊紙UTF-8/GBK锛�
+   鈹溾攢鈹� 鏂囨湰鍒囩墖锛堝ぇ鏂囦欢鎴栭暱鍐呭鎵嶅垏鐗囷級
+   鈹溾攢鈹� 鐢熸垚 Embedding 鍚戦噺
+   鈹溾攢鈹� 瀛樺偍鍒� Pinecone
+   鈹斺攢鈹� 鏇存柊鐘舵�佷负"瀹屾垚"鎴�"澶辫触"
+```
+
+### 6.2 鐭ヨ瘑搴撻棶绛旀祦绋�
+
+```
+1. 鐢ㄦ埛閫夋嫨鐭ヨ瘑搴擄紝杈撳叆闂
+2. 鍓嶇璋冪敤 /ai/knowledge/chat锛堟祦寮忔帴鍙o級
+3. 鍚庣澶勭悊锛�
+   鈹溾攢鈹� 鏋勫缓鍛藉悕绌洪棿锛歬b-{knowledgeBaseId}
+   鈹溾攢鈹� 璋冪敤 Embedding 妯″瀷鐢熸垚闂鍚戦噺
+   鈹溾攢鈹� 浠� Pinecone 妫�绱㈢浉鍏冲唴瀹癸紙minScore=0.7, maxResults=5锛�
+   鈹溾攢鈹� 鏋勫缓涓婁笅鏂� Prompt
+   鈹溾攢鈹� 璋冪敤 LLM 鐢熸垚鍥炵瓟
+   鈹斺攢鈹� 娴佸紡杩斿洖缁撴灉
+```
+
+---
+
+## 涓冦�佹敞鎰忎簨椤�
+
+1. **Pinecone 鍛藉悕绌洪棿**锛氫笉鑳戒娇鐢� `__default__`锛屽繀椤讳娇鐢ㄨ嚜瀹氫箟鍛藉悕绌洪棿
+2. **鏂囦欢缂栫爜**锛氳嚜鍔ㄦ娴� UTF-8/GBK锛岄伩鍏嶄贡鐮�
+3. **鍒囩墖绛栫暐**锛�
+   - 鏂囦欢 > 80MB 鎴栧唴瀹� > 8000 瀛楃鏃舵墠鍒囩墖
+   - 鍒囩墖澶у皬 500 瀛楃锛岄噸鍙� 100 瀛楃
+   - 浼樺厛鍦ㄥ彞瀛愯竟鐣屽垏鍒�
+4. **Embedding 闄愬埗**锛氶樋閲屼簯 DashScope 闄愬埗鍗曟杈撳叆鏈�澶� 8192 瀛楃
+5. **鍚戦噺鍒犻櫎**锛氫娇鐢� Pinecone 鍘熺敓瀹㈡埛绔紝閫氳繃 metadata filter 鍒犻櫎
+6. **寮傛澶勭悊**锛氬悜閲忓寲浣跨敤 `@Async` 寮傛鎵ц锛岄伩鍏嶉樆濉炴帴鍙�
+
+---
+
+## 鍏�佹枃浠舵竻鍗�
+
+### 鍚庣鏂囦欢
+```
+src/main/java/com/ruoyi/
+鈹溾攢鈹� approve/
+鈹�   鈹溾攢鈹� controller/
+鈹�   鈹�   鈹斺攢鈹� KnowledgeBaseController.java
+鈹�   鈹溾攢鈹� pojo/
+鈹�   鈹�   鈹溾攢鈹� KnowledgeBase.java
+鈹�   鈹�   鈹斺攢鈹� KnowledgeBaseVector.java
+鈹�   鈹溾攢鈹� service/
+鈹�   鈹�   鈹溾攢鈹� KnowledgeBaseService.java
+鈹�   鈹�   鈹溾攢鈹� KnowledgeBaseVectorService.java
+鈹�   鈹�   鈹斺攢鈹� impl/
+鈹�   鈹�       鈹溾攢鈹� KnowledgeBaseServiceImpl.java
+鈹�   鈹�       鈹斺攢鈹� KnowledgeBaseVectorServiceImpl.java
+鈹�   鈹溾攢鈹� mapper/
+鈹�   鈹�   鈹溾攢鈹� KnowledgeBaseMapper.java
+鈹�   鈹�   鈹斺攢鈹� KnowledgeBaseVectorMapper.java
+鈹�   鈹斺攢鈹� dto/
+鈹�       鈹斺攢鈹� KnowledgeBaseVectorVO.java
+鈹斺攢鈹� ai/
+    鈹溾攢鈹� config/
+    鈹�   鈹溾攢鈹� EmbeddingStoreConfig.java
+    鈹�   鈹斺攢鈹� XiaozhiAgentConfig.java
+    鈹溾攢鈹� controller/
+    鈹�   鈹斺攢鈹� KnowledgeChatController.java
+    鈹溾攢鈹� assistant/
+    鈹�   鈹斺攢鈹� KnowledgeChatAgent.java
+    鈹溾攢鈹� service/
+    鈹�   鈹溾攢鈹� KnowledgeRagService.java
+    鈹�   鈹斺攢鈹� impl/
+    鈹�       鈹斺攢鈹� KnowledgeRagServiceImpl.java
+    鈹斺攢鈹� dto/
+        鈹斺攢鈹� KnowledgeChatRequest.java
+```
+
+### 鍓嶇鏂囦欢
+```
+src/views/knowledge/
+鈹溾攢鈹� index.vue              # 鐭ヨ瘑搴撳垪琛�
+鈹溾攢鈹� form.vue               # 鏂板/缂栬緫琛ㄥ崟
+鈹溾攢鈹� files.vue              # 鏂囦欢绠$悊
+鈹斺攢鈹� chat.vue               # 鐭ヨ瘑搴撻棶绛�
+
+src/api/knowledge.js       # API灏佽
+```
\ No newline at end of file
diff --git a/docs/mock_data_check.md b/docs/mock_data_check.md
new file mode 100644
index 0000000..8c67159
--- /dev/null
+++ b/docs/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/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/sql/product-inventory-management-new-pro.sql b/sql/product-inventory-management-new-pro.sql
new file mode 100644
index 0000000..2752b38
--- /dev/null
+++ b/sql/product-inventory-management-new-pro.sql
@@ -0,0 +1,5814 @@
+/*
+ Navicat Premium Dump SQL
+
+ Source Server         : localhost
+ Source Server Type    : MySQL
+ Source Server Version : 80408 (8.4.8)
+ Source Host           : localhost:3306
+ Source Schema         : product-inventory-management-new-pro
+
+ Target Server Type    : MySQL
+ Target Server Version : 80408 (8.4.8)
+ File Encoding         : 65001
+
+ Date: 16/06/2026 10:13:25
+*/
+
+SET NAMES utf8mb4;
+SET FOREIGN_KEY_CHECKS = 0;
+
+-- ----------------------------
+-- Table structure for account_expense
+-- ----------------------------
+DROP TABLE IF EXISTS `account_expense`;
+CREATE TABLE `account_expense`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `business_id` int NULL DEFAULT NULL COMMENT '涓氬姟id',
+  `business_type` int NULL DEFAULT NULL COMMENT '涓氬姟绫诲瀷 1-浠樻 2-杩樺�熸',
+  `expense_date` date NULL DEFAULT NULL COMMENT '鏀嚭鏃ユ湡',
+  `expense_type` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鏀嚭绫诲瀷',
+  `supplier_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '渚涘簲鍟嗗悕绉�',
+  `expense_money` decimal(18, 2) NULL DEFAULT NULL COMMENT '鏀嚭閲戦',
+  `expense_described` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鏀嚭鎻忚堪',
+  `expense_method` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '浠樻鏂瑰紡',
+  `invoice_number` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鍙戠エ鍙风爜',
+  `note` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `input_user` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '褰曞叆浜哄憳',
+  `input_time` date NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '璐㈠姟绠$悊--鏀嚭绠$悊' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for account_file
+-- ----------------------------
+DROP TABLE IF EXISTS `account_file`;
+CREATE TABLE `account_file`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鏂囦欢鍚嶇О',
+  `url` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鏂囦欢璺緞',
+  `file_size` int NULL DEFAULT NULL COMMENT '鏂囦欢澶у皬',
+  `account_id` bigint NULL DEFAULT NULL COMMENT '璐㈠姟ID',
+  `account_type` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '绫诲瀷(鏀跺叆/鏀嚭)',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 272 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '璐㈠姟绠$悊--闄勪欢' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for account_income
+-- ----------------------------
+DROP TABLE IF EXISTS `account_income`;
+CREATE TABLE `account_income`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `income_date` date NULL DEFAULT NULL COMMENT '鏀跺叆鏃ユ湡',
+  `income_type` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鏀跺叆绫诲瀷',
+  `customer_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '瀹㈡埛鍚嶇О',
+  `income_money` decimal(18, 2) NULL DEFAULT NULL COMMENT '鏀跺叆閲戦',
+  `income_described` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鏀跺叆鎻忚堪',
+  `income_method` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鏀舵鏂瑰紡',
+  `invoice_number` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鍙戠エ鍙风爜',
+  `note` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `input_user` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '褰曞叆浜哄憳',
+  `input_time` date NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `business_id` int NULL DEFAULT NULL COMMENT '涓氬姟id',
+  `business_type` int NULL DEFAULT NULL COMMENT '涓氬姟绫诲瀷 1-鍥炴 2-鍊熸',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 696 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '璐㈠姟绠$悊--鏀跺叆绠$悊' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for account_invoice_application
+-- ----------------------------
+DROP TABLE IF EXISTS `account_invoice_application`;
+CREATE TABLE `account_invoice_application`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `customer_id` int NOT NULL COMMENT '瀹㈡埛id',
+  `stock_out_record_ids` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鍏宠仈鍑哄簱鍗昳d(澶氶��)',
+  `invoice_application_no` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '寮�绁ㄧ敵璇峰崟鍙�',
+  `invoice_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍙戠エ绫诲瀷',
+  `apply_date` date NULL DEFAULT NULL COMMENT '鐢宠鏃ユ湡',
+  `invoice_content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '鍙戠エ鍐呭',
+  `remark` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `status` int NULL DEFAULT 0 COMMENT '瀹℃牳鐘舵��:0寰呭鏍�1瀹℃牳閫氳繃2瀹℃牳涓嶉�氳繃',
+  `invoice_amount` decimal(18, 4) NULL DEFAULT NULL COMMENT '寮�绁ㄩ噾棰�',
+  `tax_rate` decimal(5, 0) NULL DEFAULT NULL COMMENT '绋庣巼',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '璐㈠姟绠$悊--寮�绁ㄧ敵璇�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for account_payment_application
+-- ----------------------------
+DROP TABLE IF EXISTS `account_payment_application`;
+CREATE TABLE `account_payment_application`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `supplier_id` int NOT NULL COMMENT '渚涘簲鍟唅d',
+  `stock_in_record_ids` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '鍏宠仈鍏ュ簱鍗昳d(澶氶��)',
+  `invoice_application_no` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '浠樻鐢宠鍗曞彿',
+  `payment_method` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '浠樻鏂瑰紡',
+  `payment_content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '浠樻浜嬬敱',
+  `apply_date` date NULL DEFAULT NULL COMMENT '鐢宠鏃ユ湡',
+  `remark` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `status` int NULL DEFAULT 0 COMMENT '瀹℃牳鐘舵��:0寰呭鏍�1瀹℃牳閫氳繃2瀹℃牳涓嶉�氳繃',
+  `payment_amount` decimal(15, 4) NULL DEFAULT NULL COMMENT '浠樻閲戦',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '璐㈠姟绠$悊--浠樻鐢宠' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for account_purchase_invoice
+-- ----------------------------
+DROP TABLE IF EXISTS `account_purchase_invoice`;
+CREATE TABLE `account_purchase_invoice`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `invoice_number` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鍙戠エ鍙风爜',
+  `tax_rate` decimal(5, 0) NULL DEFAULT NULL COMMENT '绋庣巼',
+  `invoice_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍙戠エ绫诲瀷',
+  `issue_date` date NULL DEFAULT NULL COMMENT '寮�绁ㄦ棩鏈�',
+  `tax_exclusivel_price` decimal(15, 2) NULL DEFAULT NULL COMMENT '閲戦(涓嶅惈绋�)',
+  `tax_price` decimal(15, 2) NULL DEFAULT NULL COMMENT '绋庨',
+  `tax_inclusive_price` decimal(15, 2) NULL DEFAULT NULL COMMENT '浠风◣鍚堣',
+  `remark` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `invoice_content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '鍙戠エ鍐呭',
+  `supplier_id` int NOT NULL COMMENT '渚涘簲鍟唅d',
+  `storage_attachment_id` int NULL DEFAULT NULL COMMENT '鍏宠仈涓婁紶鐨勫彂绁ㄩ檮浠秈d',
+  `stock_in_record_ids` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '鍏宠仈鍏ュ簱鍗昳d(澶氶��)',
+  `status` int NULL DEFAULT 0 COMMENT '鐘舵�� 0鍚敤 1绂佺敤',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '璐㈠姟绠$悊--杩涢」鍙戠エ' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for account_purchase_payment
+-- ----------------------------
+DROP TABLE IF EXISTS `account_purchase_payment`;
+CREATE TABLE `account_purchase_payment`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `account_payment_application_id` int NOT NULL COMMENT '鍏宠仈浠樻鐢宠id',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `supplier_id` int NOT NULL COMMENT '渚涘簲鍟唅d',
+  `payment_date` date NULL DEFAULT NULL COMMENT '浠樻鏃ユ湡',
+  `payment_method` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '浠樻鏂瑰紡',
+  `payment_amount` decimal(15, 2) NULL DEFAULT NULL COMMENT '浠樻閲戦',
+  `payment_number` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '浠樻鍗曞彿',
+  `remark` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '璐㈠姟绠$悊--浠樻鍗�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for account_sales_collection
+-- ----------------------------
+DROP TABLE IF EXISTS `account_sales_collection`;
+CREATE TABLE `account_sales_collection`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `stock_out_record_ids` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鍏宠仈鍑哄簱鍗昳d(澶氶��)',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `customer_id` int NOT NULL COMMENT '瀹㈡埛id',
+  `collection_date` date NULL DEFAULT NULL COMMENT '鏀舵鏃ユ湡',
+  `collection_amount` decimal(15, 2) NULL DEFAULT NULL COMMENT '鏀舵閲戦',
+  `collection_method` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鏀舵鏂瑰紡',
+  `collection_number` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鏀舵鍗曞彿',
+  `remark` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '璐㈠姟绠$悊--鏀舵鍗�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for account_sales_invoice
+-- ----------------------------
+DROP TABLE IF EXISTS `account_sales_invoice`;
+CREATE TABLE `account_sales_invoice`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `account_invoice_application_id` int NOT NULL COMMENT '鍏宠仈寮�绁ㄧ敵璇穒d',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `invoice_number` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鍙戠エ鍙风爜',
+  `tax_rate` decimal(5, 0) NULL DEFAULT NULL COMMENT '绋庣巼',
+  `invoice_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍙戠エ绫诲瀷',
+  `issue_date` date NULL DEFAULT NULL COMMENT '寮�绁ㄦ棩鏈�',
+  `tax_exclusivel_price` decimal(15, 2) NULL DEFAULT NULL COMMENT '閲戦(涓嶅惈绋�)',
+  `tax_price` decimal(15, 2) NULL DEFAULT NULL COMMENT '绋庨',
+  `tax_inclusive_price` decimal(15, 2) NULL DEFAULT NULL COMMENT '浠风◣鍚堣',
+  `remark` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `invoice_content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '鍙戠エ鍐呭',
+  `customer_id` int NULL DEFAULT NULL COMMENT '瀹㈡埛id',
+  `storage_attachment_id` int NULL DEFAULT NULL COMMENT '鍏宠仈涓婁紶鐨勫彂绁ㄩ檮浠秈d',
+  `status` int NULL DEFAULT 0 COMMENT '鐘舵�� 0鍚敤 1绂佺敤',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '璐㈠姟绠$悊--閿�椤瑰彂绁�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for account_statement
+-- ----------------------------
+DROP TABLE IF EXISTS `account_statement`;
+CREATE TABLE `account_statement`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `customer_id` int NOT NULL COMMENT '瀹㈡埛id',
+  `statement_month` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '瀵硅处鏈堜唤(yyyy-MM)',
+  `account_type` int NOT NULL COMMENT '涓氬姟绫诲瀷(1搴旀敹瀵硅处;2搴斾粯瀵硅处)',
+  `statement_number` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '瀵硅处鍗曞彿',
+  `opening_balance` decimal(15, 2) NULL DEFAULT NULL COMMENT '鏈熷垵浣欓',
+  `current_plan` decimal(15, 2) NULL DEFAULT NULL COMMENT '鏈湡搴旀敹/搴斾粯',
+  `current_actually` decimal(15, 2) NULL DEFAULT NULL COMMENT '鏈湡鏀舵/浠樻',
+  `closing_balance` decimal(15, 2) NULL DEFAULT NULL COMMENT '鏈熸湯浣欓',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '璐㈠姟绠$悊--瀵硅处鍗�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for account_statement_details
+-- ----------------------------
+DROP TABLE IF EXISTS `account_statement_details`;
+CREATE TABLE `account_statement_details`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `account_statement_id` int NOT NULL COMMENT '鍏宠仈瀵硅处鍗昳d',
+  `occurrence_date` date NULL DEFAULT NULL COMMENT '鏁版嵁鏃ユ湡',
+  `receipt_number` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鍗曟嵁缂栧彿',
+  `type` int NULL DEFAULT NULL COMMENT '鏁版嵁绫诲瀷(1鍑哄簱;2鍏ュ簱;3鏀舵;4浠樻;5閫�璐�)',
+  `amount` decimal(15, 2) NULL DEFAULT NULL COMMENT '閲戦',
+  `remark` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 24 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '璐㈠姟绠$悊--瀵硅处鍗曟槑缁�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for account_subject
+-- ----------------------------
+DROP TABLE IF EXISTS `account_subject`;
+CREATE TABLE `account_subject`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `parent_id` bigint NULL DEFAULT NULL COMMENT '鐖剁鐩甀D锛堜负绌鸿〃绀烘牴鑺傜偣锛�',
+  `subject_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '绉戠洰缂栫爜(鍞竴鏍囪瘑)',
+  `subject_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '绉戠洰鍚嶇О',
+  `subject_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '绉戠洰绫诲瀷',
+  `balance_direction` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '浣欓鏂瑰悜',
+  `status` int NULL DEFAULT 0 COMMENT '鐘舵�� 0鍚敤 1绂佺敤',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_account_subject_parent_id`(`parent_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鎬昏处绉戠洰琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for after_sales_near_expiry
+-- ----------------------------
+DROP TABLE IF EXISTS `after_sales_near_expiry`;
+CREATE TABLE `after_sales_near_expiry`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `product_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '涓存湡浜у搧鍚嶇О',
+  `batch_number` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '浜у搧鎵瑰彿',
+  `expire_date` date NULL DEFAULT NULL COMMENT '涓存湡鏃ユ湡',
+  `stock_quantity` int NULL DEFAULT NULL COMMENT '搴撳瓨鏁伴噺',
+  `customer_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '瀹㈡埛鍚嶇О',
+  `dis_res` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '闂鎻忚堪',
+  `status` int NULL DEFAULT NULL COMMENT '澶勭悊鐘舵�� (濡�: 1-寰呭鐞� 2-宸插鐞�)',
+  `dispose_user_id` bigint NULL DEFAULT NULL COMMENT '澶勭悊浜篒D',
+  `dispose_nick_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '澶勭悊浜哄悕绉�',
+  `dis_date` date NULL DEFAULT NULL COMMENT '澶勭悊鏃ユ湡',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `contact_phone` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '鑱旂郴鐢佃瘽',
+  `dispose_result` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '澶勭悊缁撴灉',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '涓存湡鍞悗绠$悊琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for after_sales_service
+-- ----------------------------
+DROP TABLE IF EXISTS `after_sales_service`;
+CREATE TABLE `after_sales_service`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `status` int NULL DEFAULT NULL COMMENT '鐘舵�� 1-寰呭鐞� 2-宸插鐞�',
+  `check_user_id` bigint NULL DEFAULT NULL COMMENT '鐧昏浜�',
+  `check_nick_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '鐧昏浜哄悕绉�',
+  `dispose_user_id` bigint NULL DEFAULT NULL COMMENT '澶勭悊浜�',
+  `dispose_nick_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '澶勭悊浜哄悕绉�',
+  `customer_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '瀹㈡埛鍚嶇О',
+  `dis_res` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '闂鎻忚堪',
+  `pro_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '澶勭悊缁撴灉',
+  `feedback_date` date NULL DEFAULT NULL COMMENT '鍙嶉鏃ユ湡',
+  `dis_date` date NULL DEFAULT NULL COMMENT '澶勭悊鏃ユ湡',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `service_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '鍞悗绫诲瀷',
+  `urgency` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '绱ф�ョ▼搴�',
+  `sales_ledger_id` bigint NULL DEFAULT NULL COMMENT '閿�鍞鍗昳d',
+  `distribution_user_id` bigint NULL DEFAULT NULL COMMENT '鍒嗛厤浜篿d',
+  `product_model_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '鍞悗浜у搧id闆嗗悎',
+  `after_sales_service_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '鍞悗鍗曞彿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '鍞悗鏈嶅姟' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for after_sales_service_file
+-- ----------------------------
+DROP TABLE IF EXISTS `after_sales_service_file`;
+CREATE TABLE `after_sales_service_file`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `service_id` bigint NOT NULL COMMENT '鍞悗鏈嶅姟璁板綍ID',
+  `file_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '鏂囦欢鍚嶇О',
+  `file_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '鏂囦欢璁块棶鍦板潃',
+  `file_size` bigint NULL DEFAULT NULL COMMENT '鏂囦欢澶у皬',
+  `file_suffix` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '鏂囦欢鍚庣紑',
+  `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT '0' COMMENT '鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 1浠h〃鍒犻櫎锛�',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '涓婁紶鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_service_id`(`service_id` ASC) USING BTREE COMMENT '鍞悗ID绱㈠紩'
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '鍞悗鏈嶅姟闄勪欢琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for ai_chat_session
+-- ----------------------------
+DROP TABLE IF EXISTS `ai_chat_session`;
+CREATE TABLE `ai_chat_session`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `memory_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '浼氳瘽ID',
+  `user_id` bigint NOT NULL COMMENT '鐢ㄦ埛ID',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `title` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '浼氳瘽鏍囬',
+  `last_message` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鏈�鍚庝竴鏉℃秷鎭�',
+  `message_count` int NOT NULL DEFAULT 0 COMMENT '娑堟伅鏁伴噺',
+  `last_chat_time` datetime NULL DEFAULT NULL COMMENT '鏈�鍚庤亰澶╂椂闂�',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 32 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'AI鍘嗗彶浼氳瘽鍏冩暟鎹〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for annual_leave_setting
+-- ----------------------------
+DROP TABLE IF EXISTS `annual_leave_setting`;
+CREATE TABLE `annual_leave_setting`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `employee_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍛樺伐绫诲瀷',
+  `work_years` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宸ヤ綔骞撮檺',
+  `annual_days` int NULL DEFAULT NULL COMMENT '骞村亣澶╂暟',
+  `max_carry_over` int NULL DEFAULT NULL COMMENT '鏈�澶х粨杞ぉ鏁�',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐘舵��',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '骞村亣璁剧疆' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for approval_instance
+-- ----------------------------
+DROP TABLE IF EXISTS `approval_instance`;
+CREATE TABLE `approval_instance`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '瀹℃壒瀹炰緥ID',
+  `instance_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瀹℃壒缂栧彿',
+  `template_id` bigint NULL DEFAULT NULL COMMENT '妯℃澘ID',
+  `template_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '妯℃澘鍚嶇О',
+  `business_id` bigint NULL DEFAULT NULL COMMENT '涓氬姟ID',
+  `business_type` int NULL DEFAULT NULL COMMENT '涓氬姟绫诲瀷',
+  `title` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瀹℃壒鏍囬',
+  `status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瀹℃壒鐘舵��',
+  `current_level` int NULL DEFAULT NULL COMMENT '褰撳墠瀹℃壒绾у埆',
+  `applicant_id` bigint NOT NULL COMMENT '鐢宠浜篒D',
+  `applicant_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐢宠浜哄悕绉�',
+  `apply_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鐢宠鏃堕棿',
+  `finish_time` datetime NULL DEFAULT NULL COMMENT '瀹屾垚鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `deleted` tinyint NOT NULL DEFAULT 0 COMMENT '閫昏緫鍒犻櫎',
+  `dept_id` int NULL DEFAULT NULL,
+  `form_config` json NULL,
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_business`(`business_type` ASC, `business_id` ASC) USING BTREE,
+  INDEX `idx_status`(`status` ASC) USING BTREE,
+  INDEX `idx_applicant`(`applicant_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 99 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹℃壒瀹炰緥琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for approval_instance_node
+-- ----------------------------
+DROP TABLE IF EXISTS `approval_instance_node`;
+CREATE TABLE `approval_instance_node`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '鑺傜偣瀹炰緥ID',
+  `instance_id` bigint NOT NULL COMMENT '瀹℃壒瀹炰緥ID',
+  `level_no` int NOT NULL COMMENT '瀹℃壒绾у埆',
+  `approve_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瀹℃壒绫诲瀷',
+  `status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鑺傜偣鐘舵��',
+  `start_time` datetime NULL DEFAULT NULL COMMENT '寮�濮嬫椂闂�',
+  `finish_time` datetime NULL DEFAULT NULL COMMENT '瀹屾垚鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `deleted` tinyint NOT NULL DEFAULT 0 COMMENT '閫昏緫鍒犻櫎',
+  `dept_id` int NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_instance_id`(`instance_id` ASC) USING BTREE,
+  INDEX `idx_instance_level`(`instance_id` ASC, `level_no` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 123 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹℃壒鑺傜偣瀹炰緥琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for approval_record
+-- ----------------------------
+DROP TABLE IF EXISTS `approval_record`;
+CREATE TABLE `approval_record`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '瀹℃壒璁板綍ID',
+  `instance_id` bigint NULL DEFAULT NULL COMMENT '瀹℃壒瀹炰緥ID',
+  `node_id` bigint NULL DEFAULT NULL COMMENT '鑺傜偣瀹炰緥ID',
+  `task_id` bigint NULL DEFAULT NULL COMMENT '瀹℃壒浠诲姟ID',
+  `operator_id` bigint NULL DEFAULT NULL COMMENT '鎿嶄綔浜篒D',
+  `operator_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎿嶄綔浜哄悕绉�',
+  `action` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎿嶄綔绫诲瀷',
+  `comment` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹℃壒鎰忚',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` timestamp NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `deleted` tinyint(1) NULL DEFAULT 0 COMMENT '閫昏緫鍒犻櫎',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 180 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹℃壒璁板綍琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for approval_task
+-- ----------------------------
+DROP TABLE IF EXISTS `approval_task`;
+CREATE TABLE `approval_task`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '瀹℃壒浠诲姟ID',
+  `instance_id` bigint NOT NULL COMMENT '瀹℃壒瀹炰緥ID',
+  `node_id` bigint NOT NULL COMMENT '鑺傜偣瀹炰緥ID',
+  `level_no` int NOT NULL COMMENT '瀹℃壒绾у埆',
+  `approver_id` bigint NOT NULL COMMENT '瀹℃壒浜篒D',
+  `approver_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹℃壒浜哄悕绉�',
+  `task_status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '浠诲姟鐘舵��',
+  `approve_time` datetime NULL DEFAULT NULL COMMENT '瀹℃壒鏃堕棿',
+  `comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹℃壒鎰忚',
+  `is_read` tinyint NOT NULL DEFAULT 0 COMMENT '鏄惁宸茶',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `deleted` tinyint NOT NULL DEFAULT 0 COMMENT '閫昏緫鍒犻櫎',
+  `dept_id` int NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_approver`(`approver_id` ASC, `task_status` ASC) USING BTREE,
+  INDEX `idx_instance`(`instance_id` ASC) USING BTREE,
+  INDEX `idx_node`(`node_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 124 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹℃壒浠诲姟琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for approval_template
+-- ----------------------------
+DROP TABLE IF EXISTS `approval_template`;
+CREATE TABLE `approval_template`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '妯℃澘ID',
+  `template_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '妯℃澘鍚嶇О',
+  `enabled` tinyint NOT NULL DEFAULT 1 COMMENT '鍚敤鐘舵�侊細1鍚敤锛�0鍋滅敤',
+  `description` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '妯℃澘璇存槑',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `deleted` tinyint NOT NULL DEFAULT 0 COMMENT '閫昏緫鍒犻櫎锛�0鍚︼紝1鏄�',
+  `dept_id` int NULL DEFAULT NULL,
+  `form_config` json NULL COMMENT '鍔ㄦ�佽〃鍗曢厤缃甁SON',
+  `template_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '妯℃澘绫诲瀷锛�0绯荤粺鍐呯疆锛�1鑷畾涔�',
+  `business_type` int NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 46 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹℃壒妯℃澘琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for approval_template_node
+-- ----------------------------
+DROP TABLE IF EXISTS `approval_template_node`;
+CREATE TABLE `approval_template_node`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '鑺傜偣ID',
+  `template_id` bigint NOT NULL COMMENT '瀹℃壒妯℃澘ID',
+  `level_no` int NOT NULL COMMENT '瀹℃壒绾у埆锛屼粠1寮�濮�',
+  `approve_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瀹℃壒鏂瑰紡锛欰ND浼氱锛孫R鎴栫',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  `create_user` int NULL DEFAULT NULL,
+  `dept_id` int NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE INDEX `uk_template_level`(`template_id` ASC, `level_no` ASC) USING BTREE,
+  INDEX `idx_template_id`(`template_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 68 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹℃壒妯℃澘鑺傜偣琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for approval_template_node_approver
+-- ----------------------------
+DROP TABLE IF EXISTS `approval_template_node_approver`;
+CREATE TABLE `approval_template_node_approver`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `node_id` bigint NOT NULL COMMENT '瀹℃壒鑺傜偣ID',
+  `template_id` bigint NOT NULL COMMENT '瀹℃壒妯℃澘ID',
+  `approver_id` bigint NOT NULL COMMENT '瀹℃壒浜篒D',
+  `approver_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹℃壒浜哄悕绉板啑浣�',
+  `sort_no` int NOT NULL DEFAULT 1 COMMENT '瀹℃壒浜烘帓搴�',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `dept_id` int NULL DEFAULT NULL,
+  `create_user` int NULL DEFAULT NULL,
+  `deleted` int NOT NULL DEFAULT 0,
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE INDEX `uk_node_approver`(`node_id` ASC, `approver_id` ASC) USING BTREE,
+  INDEX `idx_node_id`(`node_id` ASC) USING BTREE,
+  INDEX `idx_template_id`(`template_id` ASC) USING BTREE,
+  INDEX `idx_approver_id`(`approver_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 76 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹℃壒妯℃澘鑺傜偣瀹℃壒浜鸿〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for approve_log
+-- ----------------------------
+DROP TABLE IF EXISTS `approve_log`;
+CREATE TABLE `approve_log`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `approve_id` bigint NOT NULL COMMENT '瀹℃壒id',
+  `approve_node_order` int NOT NULL COMMENT '瀹℃壒鑺傜偣椤哄簭',
+  `approve_user` bigint NOT NULL COMMENT '瀹℃壒浜篿d',
+  `approve_time` datetime NOT NULL COMMENT '瀹℃壒鏃堕棿',
+  `approve_status` int NOT NULL COMMENT '瀹℃壒鐘舵��',
+  `approve_remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹℃壒澶囨敞',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹℃壒鏃ュ織琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for approve_node
+-- ----------------------------
+DROP TABLE IF EXISTS `approve_node`;
+CREATE TABLE `approve_node`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `approve_process_id` char(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瀹℃壒缂栧彿',
+  `approve_node_order` int NOT NULL COMMENT '瀹℃壒鑺傜偣椤哄簭',
+  `approve_node_user_id` int NULL DEFAULT NULL COMMENT '瀹℃壒鑺傜偣鐢ㄦ埛id',
+  `approve_node_user` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瀹℃壒鑺傜偣鐢ㄦ埛鍚嶅瓧',
+  `approve_node_time` datetime NOT NULL COMMENT '瀹℃壒鑺傜偣鏃堕棿',
+  `approve_node_status` int NOT NULL COMMENT '瀹℃壒鑺傜偣鐘舵��:1鍚屾剰锛�2鎷掔粷锛�0灏氭湭瀹℃牳锛堥粯璁や负0锛�',
+  `tenant_id` bigint NOT NULL COMMENT '绉熸埛id',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `delete_flag` int NOT NULL COMMENT '鍒犻櫎鏍囪:0姝e父锛�1鍒犻櫎',
+  `approve_node_reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹℃壒鑺傜偣鎷掔粷鍘熷洜',
+  `approve_node_remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹℃壒鑺傜偣澶囨敞',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 115 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹℃壒鑺傜偣琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for approve_process
+-- ----------------------------
+DROP TABLE IF EXISTS `approve_process`;
+CREATE TABLE `approve_process`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `approve_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瀹℃壒id',
+  `approve_user` bigint NOT NULL COMMENT '鐢宠浜篿d',
+  `approve_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐢宠浜哄悕绉�',
+  `approve_dept_id` bigint NULL DEFAULT NULL COMMENT '鐢宠閮ㄩ棬id',
+  `approve_dept_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐢宠閮ㄩ棬鍚嶇О',
+  `approve_user_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹℃壒鐢ㄦ埛ids',
+  `approve_user_names` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹℃壒鐢ㄦ埛鍚嶇О',
+  `approve_user_current_id` bigint NULL DEFAULT NULL COMMENT '褰撳墠瀹℃壒鐢ㄦ埛id',
+  `approve_user_current_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '褰撳墠瀹℃壒鐢ㄦ埛鍚嶇О',
+  `approve_reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鐢宠鍘熷洜',
+  `approve_time` datetime NOT NULL COMMENT '鐢宠鏃ユ湡',
+  `approve_over_time` datetime NULL DEFAULT NULL COMMENT '瀹℃壒瀹屾垚鏃堕棿',
+  `approve_status` int NOT NULL COMMENT '瀹℃壒鐘舵�侊細0寰呭鏍革紝1瀹℃牳涓紝2瀹℃牳瀹屾垚',
+  `approve_delete` int NOT NULL COMMENT '瀹℃壒鏄惁鍒犻櫎锛�0姝e父锛�1鍒犻櫎',
+  `tenant_id` bigint NOT NULL COMMENT '绉熸埛id',
+  `approve_type` int NULL DEFAULT NULL COMMENT '瀹℃壒绫诲瀷',
+  `approve_remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹℃壒澶囨敞',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `start_date_time` datetime NULL DEFAULT NULL COMMENT '寮�濮嬫椂闂�',
+  `end_date_time` datetime NULL DEFAULT NULL COMMENT '缁撴潫鏃堕棿',
+  `start_date` date NULL DEFAULT NULL COMMENT '寮�濮嬫棩鏈�',
+  `end_date` date NULL DEFAULT NULL COMMENT '缁撴潫鏃ユ湡',
+  `location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍦扮偣',
+  `price` decimal(10, 2) NULL DEFAULT NULL COMMENT '鎶ラ攢閲戦',
+  `maintenance_price` decimal(10, 2) NULL DEFAULT NULL COMMENT '缁翠慨浠锋牸',
+  `device_repair_id` int NULL DEFAULT NULL COMMENT '璁惧鎶ヤ慨id',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 98 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹℃壒娴佺▼琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for approve_process_config_node
+-- ----------------------------
+DROP TABLE IF EXISTS `approve_process_config_node`;
+CREATE TABLE `approve_process_config_node`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `approve_type` int NULL DEFAULT NULL COMMENT '瀹℃壒绫诲瀷锛�1鍏嚭绠$悊锛�2璇峰亣绠$悊锛�3鍑哄樊绠$悊锛�4鎶ラ攢绠$悊锛�5閲囪喘瀹℃壒锛�6鎶ヤ环瀹℃壒锛�7鍙戣揣瀹℃壒锛�8鍗遍櫓浣滀笟瀹℃壒',
+  `node_order` int NULL DEFAULT NULL COMMENT '鑺傜偣椤哄簭',
+  `approver_id` int NULL DEFAULT NULL COMMENT '瀹℃壒浜篒D',
+  `approver_name` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹℃壒浜哄悕绉�',
+  `timeout_hours` int NULL DEFAULT NULL COMMENT '瓒呮椂鏃堕暱锛堝皬鏃讹級',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛ID',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛ID',
+  `update_time` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '淇敼鏃堕棿',
+  `delete_flag` tinyint(1) NULL DEFAULT 0 COMMENT '鍒犻櫎鏍囪锛�0姝e父锛�1鍒犻櫎',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹℃壒娴佺▼閰嶇疆鑺傜偣琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for bank
+-- ----------------------------
+DROP TABLE IF EXISTS `bank`;
+CREATE TABLE `bank`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `bank_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閾惰鍚嶇О',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '閾惰绠$悊琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for borrow_info
+-- ----------------------------
+DROP TABLE IF EXISTS `borrow_info`;
+CREATE TABLE `borrow_info`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '鍊熸璁板綍涓婚敭ID',
+  `borrower_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍊熸浜哄鍚�',
+  `borrow_amount` decimal(18, 2) NULL DEFAULT NULL COMMENT '鍊熸閲戦锛堝厓锛�',
+  `interest_rate` decimal(5, 2) NULL DEFAULT NULL COMMENT '鍊熸鍒╃巼锛堝锛�5.85 浠h〃5.85%锛�',
+  `borrow_date` date NULL DEFAULT NULL COMMENT '鍊熸鏃ユ湡',
+  `repay_date` date NULL DEFAULT NULL COMMENT '瀹為檯杩樻鏃ユ湡锛堣繕娆惧悗濉厖锛�',
+  `status` tinyint NOT NULL DEFAULT 1 COMMENT '鍊熸鐘舵�侊細1=寰呰繕娆撅紝2=宸茶繕娆�',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞锛堝�熸璇存槑锛�',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓鑰匢D',
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '淇敼鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鑰匢D',
+  `tenant_id` bigint NOT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍊熸淇℃伅琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for common_file
+-- ----------------------------
+DROP TABLE IF EXISTS `common_file`;
+CREATE TABLE `common_file`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `common_id` int NOT NULL COMMENT '鍏宠仈閿�鍞彴璐︿富琛ㄤ富閿�',
+  `type` int NULL DEFAULT NULL COMMENT '鍏宠仈琛ㄧ被鍨�',
+  `url` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '闄勪欢璺緞',
+  `name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '闄勪欢鍚嶇О',
+  `create_time` date NULL DEFAULT NULL,
+  `update_time` date NULL DEFAULT NULL,
+  `file_size` bigint NULL DEFAULT NULL COMMENT '鏂囦欢澶у皬',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '閿�鍞彴璐︽枃浠�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for compensation_performance
+-- ----------------------------
+DROP TABLE IF EXISTS `compensation_performance`;
+CREATE TABLE `compensation_performance`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `staff_id` bigint NOT NULL COMMENT '鍛樺伐id',
+  `pay_date` date NULL DEFAULT NULL COMMENT '钖祫鏈堜唤',
+  `name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '濮撳悕',
+  `should_attended_num` decimal(10, 2) NULL DEFAULT NULL COMMENT '搴斿嚭鍕ゅぉ鏁�',
+  `actual_attended_num` decimal(10, 2) NULL DEFAULT NULL COMMENT '瀹為檯鍑哄嫟澶╂暟',
+  `basic_salary` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍩烘湰宸ヨ祫',
+  `post_salary` decimal(10, 2) NULL DEFAULT NULL COMMENT '宀椾綅宸ヨ祫',
+  `deduction_absenteeism` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍏ョ鑱岀己鍕ゆ墸娆�',
+  `sick_leave_deductions` decimal(10, 2) NULL DEFAULT NULL COMMENT '鐥呭亣鎵f',
+  `deduction_personal_leave` decimal(10, 2) NULL DEFAULT NULL COMMENT '浜嬪亣鎵f',
+  `forget_clock_deduct` decimal(10, 2) NULL DEFAULT NULL COMMENT '蹇樿鎵撳崱鎵f',
+  `performance_score` decimal(10, 2) NULL DEFAULT NULL COMMENT '缁╂晥寰楀垎',
+  `performance_pay` decimal(10, 2) NULL DEFAULT NULL COMMENT '缁╂晥宸ヨ祫',
+  `payable_wages` decimal(10, 2) NULL DEFAULT NULL COMMENT '搴斿彂鍚堣',
+  `social_security_individuals` decimal(10, 2) NULL DEFAULT NULL COMMENT '绀句繚涓汉',
+  `social_security_companies` decimal(10, 2) NULL DEFAULT NULL COMMENT '绀句繚鍏徃',
+  `social_security_total` decimal(10, 2) NULL DEFAULT NULL COMMENT '绀句繚鍚堣',
+  `provident_fund_individuals` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍏Н閲戜釜浜�',
+  `provident_fund_company` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍏Н閲戝叕鍙�',
+  `provident_fund_total` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍏Н閲戝悎璁�',
+  `taxable_waget` decimal(10, 2) NULL DEFAULT NULL COMMENT '搴旂◣宸ヨ祫',
+  `personal_income_tax` decimal(10, 2) NULL DEFAULT NULL COMMENT '涓汉鎵�寰楃◣',
+  `actual_wages` decimal(10, 2) NULL DEFAULT NULL COMMENT '瀹炲彂宸ヨ祫',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '钖叕缁╂晥' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for custom_storage
+-- ----------------------------
+DROP TABLE IF EXISTS `custom_storage`;
+CREATE TABLE `custom_storage`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `item_type` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鐗╁搧绫诲瀷',
+  `inbound_date` date NULL DEFAULT NULL COMMENT '鍏ュ簱鏃堕棿',
+  `inbound_batches` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鍏ュ簱鎵规',
+  `inbound_num` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍏ュ簱鏁伴噺',
+  `supplier_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '渚涘簲鍟嗗悕绉�',
+  `product_category` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '浜у搧澶х被',
+  `specification_model` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '瑙勬牸鍨嬪彿',
+  `unit` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `tax_inclusive_unit_price` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍚◣鍗曚环',
+  `tax_inclusive_total_price` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍚◣鎬讳环',
+  `tax_rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '绋庣巼(%)',
+  `tax_exclusive_total_price` decimal(10, 2) NULL DEFAULT NULL COMMENT '涓嶅惈绋庢�讳环',
+  `create_by` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鍏ュ簱浜�',
+  `create_time` datetime NULL DEFAULT NULL,
+  `update_time` datetime NULL DEFAULT NULL,
+  `create_user` int NULL DEFAULT NULL,
+  `update_user` int NULL DEFAULT NULL,
+  `tenant_id` bigint NULL DEFAULT NULL,
+  `code` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '缂栧彿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for customer
+-- ----------------------------
+DROP TABLE IF EXISTS `customer`;
+CREATE TABLE `customer`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `customer_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瀹㈡埛鍚嶇О',
+  `taxpayer_identification_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '绾崇◣浜鸿瘑鍒彿',
+  `company_address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鍏徃鍦板潃',
+  `company_phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鍏徃鐢佃瘽',
+  `contact_person` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鑱旂郴浜�',
+  `contact_phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鑱旂郴鐢佃瘽',
+  `maintainer` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '缁存姢浜�',
+  `maintenance_time` date NOT NULL COMMENT '缁存姢鏃堕棿',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `basic_bank_account` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閾惰鍩烘湰鎴�',
+  `bank_account` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閾惰璐﹀彿',
+  `bank_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '寮�鎴疯鍙�',
+  `customer_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹㈡埛鍒嗙被锛氶浂鍞鎴凤紝杩涢攢鍟嗗鎴�',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `usage_user` int NULL DEFAULT NULL COMMENT '浣跨敤鐢ㄦ埛',
+  `usage_status` int NULL DEFAULT NULL COMMENT '浣跨敤鐘舵��',
+  `type` smallint NOT NULL DEFAULT 0 COMMENT '绫诲瀷 0 绉佹捣瀹㈡埛 1 鍏捣瀹㈡埛',
+  `is_assigned` tinyint(1) NOT NULL DEFAULT 0 COMMENT '鏄惁琚垎閰嶏細0-鏈垎閰嶏紝1-宸插垎閰�',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 427 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹㈡埛妗f' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for customer_follow_up
+-- ----------------------------
+DROP TABLE IF EXISTS `customer_follow_up`;
+CREATE TABLE `customer_follow_up`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `follow_up_method` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璺熻繘鏂瑰紡',
+  `follow_up_level` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璺熻繘绋嬪害',
+  `follow_up_time` datetime NOT NULL COMMENT '璺熻繘鏃堕棿',
+  `follower_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璺熻繘浜哄鍚�',
+  `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璺熻繘鍐呭',
+  `follower_user_id` bigint NULL DEFAULT NULL COMMENT '璺熻繘浜篒D',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `customer_id` bigint NOT NULL DEFAULT 0,
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_tenant_id`(`tenant_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹㈡埛璺熻繘杩涘害琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for customer_follow_up_file
+-- ----------------------------
+DROP TABLE IF EXISTS `customer_follow_up_file`;
+CREATE TABLE `customer_follow_up_file`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `follow_up_id` int NULL DEFAULT NULL COMMENT '璺熻繘璁板綍ID',
+  `file_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '鏂囦欢鍚嶇О',
+  `file_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '鏂囦欢璁块棶鍦板潃',
+  `file_size` bigint NULL DEFAULT NULL COMMENT '鏂囦欢澶у皬',
+  `file_suffix` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '鏂囦欢鍚庣紑',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '涓婁紶鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_follow_up_id`(`follow_up_id` ASC) USING BTREE COMMENT '璺熻繘璁板綍ID绱㈠紩'
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '瀹㈡埛璺熻繘闄勪欢琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for customer_private
+-- ----------------------------
+DROP TABLE IF EXISTS `customer_private`;
+CREATE TABLE `customer_private`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `customer_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瀹㈡埛鍚嶇О',
+  `taxpayer_identification_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '绾崇◣浜鸿瘑鍒彿',
+  `company_address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鍏徃鍦板潃',
+  `company_phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鍏徃鐢佃瘽',
+  `contact_person` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鑱旂郴浜�',
+  `contact_phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鑱旂郴鐢佃瘽',
+  `maintainer` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '缁存姢浜�',
+  `maintenance_time` date NOT NULL COMMENT '缁存姢鏃堕棿',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `basic_bank_account` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閾惰鍩烘湰鎴�',
+  `bank_account` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閾惰璐﹀彿',
+  `bank_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '寮�鎴疯鍙�',
+  `customer_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹㈡埛鍒嗙被锛氶浂鍞鎴凤紝杩涢攢鍟嗗鎴�',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `usage_user` int NULL DEFAULT NULL,
+  `usage_status` int NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹㈡埛妗f' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for customer_private_pool
+-- ----------------------------
+DROP TABLE IF EXISTS `customer_private_pool`;
+CREATE TABLE `customer_private_pool`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭id',
+  `customer_id` bigint NULL DEFAULT NULL COMMENT '瀹㈡埛id',
+  `bound_id` bigint NULL DEFAULT NULL COMMENT '缁戝畾浜篿d',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `update_user` int NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `create_time` timestamp NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_time` timestamp NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `dept_id` int NULL DEFAULT NULL,
+  `type` int NULL DEFAULT 0 COMMENT '绫诲瀷鍖哄垎鍏捣瀹㈡埛鍜岀娴峰鎴� 榛樿鏄娴峰鎴�0 鍏捣1',
+  `delete_flag` int NULL DEFAULT 0 COMMENT '鍒犻櫎鏍囧織',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '绉佹捣瀹㈡埛' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for customer_return_visit
+-- ----------------------------
+DROP TABLE IF EXISTS `customer_return_visit`;
+CREATE TABLE `customer_return_visit`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `is_enabled` tinyint(1) NULL DEFAULT 1 COMMENT '鎻愰啋寮�鍏� (0:鍏抽棴, 1:寮�鍚�)',
+  `content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '鎻愰啋鍐呭',
+  `reminder_time` datetime NOT NULL COMMENT '鎻愰啋鏃堕棿',
+  `is_completed` tinyint(1) NULL DEFAULT 0 COMMENT '澶勭悊鐘舵�� (0:寰呮彁閱�, 1:宸叉彁閱�)',
+  `remind_user_id` bigint NOT NULL COMMENT '鎺ユ敹鎻愰啋鐨勭敤鎴稩D',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `customer_id` bigint NOT NULL DEFAULT 0,
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_remind_user`(`remind_user_id` ASC, `is_completed` ASC) USING BTREE COMMENT '鐢ㄦ埛寰呭姙鏌ヨ绱㈠紩'
+) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '瀹㈡埛鍥炶鎻愰啋琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for customer_user
+-- ----------------------------
+DROP TABLE IF EXISTS `customer_user`;
+CREATE TABLE `customer_user`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `customer_id` bigint NOT NULL DEFAULT 0 COMMENT '瀹㈡埛id',
+  `user_id` bigint NOT NULL DEFAULT 0 COMMENT '鐢ㄦ埛id',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '绉熸埛id',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for customer_visits
+-- ----------------------------
+DROP TABLE IF EXISTS `customer_visits`;
+CREATE TABLE `customer_visits`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `customer_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹㈡埛鍚嶇О',
+  `contact` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鑱旂郴浜�',
+  `contact_phone` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鑱旂郴鐢佃瘽',
+  `location` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浣嶇疆',
+  `visiting_people` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎷滆浜�',
+  `purpose_visit` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎷滆鐩殑',
+  `purpose_date` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎷滆鏃堕棿',
+  `visit_address` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎷滆鍦板潃',
+  `remark` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '澶囨敞',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰卛d',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鑰卛d',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹㈡埛鎷滆鐧昏' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for device_defect_record
+-- ----------------------------
+DROP TABLE IF EXISTS `device_defect_record`;
+CREATE TABLE `device_defect_record`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `device_ledger_id` bigint NOT NULL COMMENT '璁惧鍙拌处id',
+  `defect_description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎻忚堪',
+  `eliminate_time` datetime NULL DEFAULT NULL COMMENT '娑堢己鏃堕棿',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁惧鐘舵��',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '璁惧缂洪櫡璁板綍琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for device_ledger
+-- ----------------------------
+DROP TABLE IF EXISTS `device_ledger`;
+CREATE TABLE `device_ledger`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `device_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁惧鍚嶇О',
+  `device_model` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瑙勬牸鍨嬪彿',
+  `supplier_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '渚涘簲鍟�',
+  `unit` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `number` decimal(10, 0) NULL DEFAULT NULL COMMENT '鏁伴噺',
+  `tax_including_price_unit` decimal(10, 0) NULL DEFAULT NULL COMMENT '鍚◣鍗曚环',
+  `tax_including_price_total` decimal(10, 0) NULL DEFAULT NULL COMMENT '鍚◣鎬讳环',
+  `tax_rate` decimal(10, 0) NULL DEFAULT NULL COMMENT '绋庣巼',
+  `un_tax_including_price_total` decimal(10, 0) NULL DEFAULT NULL COMMENT '涓嶅惈绋庢�讳环',
+  `create_time` timestamp NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_time` timestamp NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` int NULL DEFAULT NULL COMMENT '褰曞叆浜�',
+  `update_user` int NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁惧鐘舵��',
+  `plan_runtime_time` date NULL DEFAULT NULL COMMENT '璁″垝杩愯鏃堕棿',
+  `start_runtime_time` datetime NULL DEFAULT NULL COMMENT '寮�濮嬭繍琛屾椂闂�',
+  `end_runtime_time` datetime NULL DEFAULT NULL COMMENT '缁撴潫杩愯鏃堕棿',
+  `runtime_duration` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '杩愯鏃堕暱',
+  `device_brand` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁惧鍝佺墝',
+  `storage_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀛樻斁浣嶇疆',
+  `is_depr` int NULL DEFAULT NULL COMMENT '鏄惁鎶樻棫 1-鏄� 2-鍚�',
+  `annual_depreciation_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '姣忓勾鎶樻棫閲戦',
+  `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁惧绫诲瀷',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 18 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for device_maintenance
+-- ----------------------------
+DROP TABLE IF EXISTS `device_maintenance`;
+CREATE TABLE `device_maintenance`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `device_ledger_id` bigint NOT NULL COMMENT '璁惧鍙拌处id',
+  `maintenance_plan_time` timestamp NULL DEFAULT NULL COMMENT '璁″垝淇濆吇鏃ユ湡',
+  `maintenance_actually_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹為檯淇濆吇浜�',
+  `maintenance_actually_time` timestamp NULL DEFAULT NULL COMMENT '瀹為檯淇濆吇鏃ユ湡',
+  `status` int NOT NULL DEFAULT 0 COMMENT '鐘舵�� 0 寰呬繚鍏� 1 瀹岀粨',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` int NOT NULL COMMENT '褰曞叆浜�',
+  `update_user` int NOT NULL COMMENT '鏇存柊浜�',
+  `tenant_id` bigint NOT NULL COMMENT '绉熸埛id',
+  `device_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `device_model` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `maintenance_result` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '淇濆吇缁撴灉',
+  `maintenance_task_id` int NULL DEFAULT NULL COMMENT '淇濆吇浠诲姟id',
+  `frequency_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '棰戞',
+  `frequency_detail` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '棰戞璇︽儏',
+  `next_execution_time` timestamp NULL DEFAULT NULL COMMENT '涓嬫鎵ц鏃堕棿',
+  `last_execution_time` timestamp NULL DEFAULT NULL COMMENT '鏈�鍚庢墽琛屾椂闂�',
+  `spare_parts_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `machinery_category` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 39 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for device_maintenance_file
+-- ----------------------------
+DROP TABLE IF EXISTS `device_maintenance_file`;
+CREATE TABLE `device_maintenance_file`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囦欢鍚嶇О',
+  `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囦欢璺緞',
+  `file_size` int NULL DEFAULT NULL COMMENT '鏂囦欢澶у皬',
+  `device_maintenance_id` int NULL DEFAULT NULL COMMENT '璁惧淇濆吇璁板綍ID',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '璁惧淇濆吇闄勪欢' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for device_repair
+-- ----------------------------
+DROP TABLE IF EXISTS `device_repair`;
+CREATE TABLE `device_repair`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `device_ledger_id` bigint NOT NULL COMMENT '璁惧鍙拌处id',
+  `repair_time` timestamp NULL DEFAULT NULL COMMENT '鎶ヤ慨鏃ユ湡',
+  `repair_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鎶ヤ慨浜�',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '鏁呴殰鐜拌薄',
+  `maintenance_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '缁翠慨浜�',
+  `maintenance_time` timestamp NULL DEFAULT NULL COMMENT '缁翠慨鏃堕棿',
+  `maintenance_result` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '缁翠慨缁撴灉',
+  `status` int NULL DEFAULT 0 COMMENT '鐘舵��',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` int NOT NULL COMMENT '褰曞叆浜�',
+  `update_user` int NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `tenant_id` bigint NOT NULL COMMENT '绉熸埛id',
+  `device_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `device_model` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `maintenance_price` decimal(10, 2) NULL DEFAULT NULL COMMENT '缁翠慨浠锋牸',
+  `approver_id` int NULL DEFAULT NULL COMMENT '瀹℃壒浜篿d',
+  `spare_parts_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `machinery_category` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `acceptance_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '楠屾敹浜�',
+  `acceptance_time` datetime NULL DEFAULT NULL COMMENT '楠屾敹鏃堕棿',
+  `acceptance_remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '楠屾敹澶囨敞',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for device_runtime
+-- ----------------------------
+DROP TABLE IF EXISTS `device_runtime`;
+CREATE TABLE `device_runtime`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `device_ledger_id` bigint NOT NULL COMMENT '璁惧鍙拌处id',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁惧鐘舵��',
+  `plan_runtime_time` datetime NULL DEFAULT NULL COMMENT '璁″垝杩愯鏃堕棿',
+  `start_runtime_time` datetime NULL DEFAULT NULL COMMENT '寮�濮嬭繍琛屾椂闂�',
+  `end_runtime_time` datetime NULL DEFAULT NULL COMMENT '缁撴潫杩愯鏃堕棿',
+  `runtime_duration` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '杩愯鏃堕暱',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '璁惧杩愯琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for document_classification
+-- ----------------------------
+DROP TABLE IF EXISTS `document_classification`;
+CREATE TABLE `document_classification`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `category` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绫诲埆鍚嶇О',
+  `parent_id` bigint NULL DEFAULT NULL COMMENT '鐖剁被id',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鏂囨。鍒嗙被琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for documentation
+-- ----------------------------
+DROP TABLE IF EXISTS `documentation`;
+CREATE TABLE `documentation`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `document_classification_id` bigint NULL DEFAULT NULL COMMENT '绫诲埆鍚嶇Оid',
+  `doc_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囨。鍚嶇О',
+  `doc_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囨。缂栧彿',
+  `year` bigint NULL DEFAULT NULL COMMENT '骞翠唤',
+  `responsible_person` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璐d换浜�',
+  `warehouse_goods_shelves_rowcol_id` bigint NULL DEFAULT NULL COMMENT '鏂囨。鏀剧疆璐ф灦id',
+  `doc_date` datetime NULL DEFAULT NULL COMMENT '鏂囨。鏃ユ湡',
+  `retention_period` bigint NULL DEFAULT NULL COMMENT '淇濈鏈熼檺',
+  `security_level` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '淇濆瘑绾у埆(缁濆瘑锛屼竴鑸�)',
+  `copy_count` bigint NULL DEFAULT NULL COMMENT '浠芥暟',
+  `page_count` bigint NULL DEFAULT NULL COMMENT '椤垫暟',
+  `doc_category` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囨。绫诲埆',
+  `doc_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囨。绉嶇被',
+  `urgency_level` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绱ф�ョ▼搴�(绱ф�ワ紝鏅��)',
+  `doc_status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囨。鐘舵��(鍊熷嚭锛屾甯革紝浣滃簾)',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鏂囨。淇℃伅琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for documentation_borrow_management
+-- ----------------------------
+DROP TABLE IF EXISTS `documentation_borrow_management`;
+CREATE TABLE `documentation_borrow_management`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `documentation_id` bigint NULL DEFAULT NULL COMMENT '鏂囨。id',
+  `borrower` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍊熼槄浜�',
+  `borrow_purpose` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍊熼槄鐩殑',
+  `borrow_date` datetime NULL DEFAULT NULL COMMENT '鍊熼槄鏃ユ湡',
+  `due_return_date` datetime NULL DEFAULT NULL COMMENT '搴斿綊杩樻棩鏈�',
+  `returner` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '褰掕繕浜�',
+  `return_date` datetime NULL DEFAULT NULL COMMENT '瀹為檯褰掕繕鏃ユ湡',
+  `borrow_status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍊熼槄鐘舵�侊紙鍊熼槄)',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鏂囨。鍊熼槄琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for documentation_file
+-- ----------------------------
+DROP TABLE IF EXISTS `documentation_file`;
+CREATE TABLE `documentation_file`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囦欢鍚嶇О',
+  `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囦欢璺緞',
+  `file_size` bigint NULL DEFAULT NULL COMMENT '鏂囦欢澶у皬',
+  `documentation_id` bigint NULL DEFAULT NULL COMMENT '鏂囨。ID',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鏂囨。--闄勪欢' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for documentation_return_management
+-- ----------------------------
+DROP TABLE IF EXISTS `documentation_return_management`;
+CREATE TABLE `documentation_return_management`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `documentation_id` bigint NULL DEFAULT NULL COMMENT '鏂囨。id',
+  `borrow_id` bigint NULL DEFAULT NULL COMMENT '鍊熼槄id',
+  `borrower` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍊熼槄浜�',
+  `borrow_purpose` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍊熼槄鐩殑',
+  `borrow_date` datetime NULL DEFAULT NULL COMMENT '鍊熼槄鏃ユ湡',
+  `due_return_date` datetime NULL DEFAULT NULL COMMENT '搴斿綊杩樻棩鏈�',
+  `returner` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '褰掕繕浜�',
+  `return_date` datetime NULL DEFAULT NULL COMMENT '瀹為檯褰掕繕鏃ユ湡',
+  `borrow_status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍊熼槄鐘舵��(褰掕繕)',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鏂囨。褰掕繕琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for duty_plan
+-- ----------------------------
+DROP TABLE IF EXISTS `duty_plan`;
+CREATE TABLE `duty_plan`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁″垝鏍囬',
+  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁″垝鎻忚堪',
+  `level` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁″垝绾у埆',
+  `period` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏃堕棿鍛ㄦ湡',
+  `start_date` datetime NULL DEFAULT NULL COMMENT '寮�濮嬫椂闂�',
+  `end_date` datetime NULL DEFAULT NULL COMMENT '缁撴潫鏃堕棿',
+  `assignee` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璐熻矗浜�',
+  `priority` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浼樺厛绾�',
+  `tags` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏍囩',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐘舵��',
+  `progress` int NULL DEFAULT NULL COMMENT '瀹屾垚搴�',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍊肩彮涓庤鍒�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for electricity_consumption_area
+-- ----------------------------
+DROP TABLE IF EXISTS `electricity_consumption_area`;
+CREATE TABLE `electricity_consumption_area`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `area_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍖哄煙鍚嶇О',
+  `area_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍖哄煙绫诲瀷',
+  `sort` bigint NULL DEFAULT NULL COMMENT '鎺掑簭',
+  `fu_id` int NULL DEFAULT NULL COMMENT '鐖剁被id',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢ㄧ數鍖哄煙' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for energy_period
+-- ----------------------------
+DROP TABLE IF EXISTS `energy_period`;
+CREATE TABLE `energy_period`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `date` date NULL DEFAULT NULL COMMENT '鏃ユ湡',
+  `price` decimal(10, 2) NULL DEFAULT NULL COMMENT '鏃舵鍗曚环 (鍏� / 搴�)',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `peak` decimal(10, 2) NULL DEFAULT NULL COMMENT '宄版',
+  `flat` decimal(10, 2) NULL DEFAULT NULL COMMENT '骞虫',
+  `valley` decimal(10, 2) NULL DEFAULT NULL COMMENT '璋锋',
+  `sharp` decimal(10, 2) NULL DEFAULT NULL COMMENT '灏栨',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢ㄧ數鏃舵琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for enterprise_news
+-- ----------------------------
+DROP TABLE IF EXISTS `enterprise_news`;
+CREATE TABLE `enterprise_news`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '缂栧彿',
+  `title` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '鏍囬',
+  `summary` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '鎽樿',
+  `content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '姝f枃',
+  `category` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍒嗙被',
+  `read_scope` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'all' COMMENT '闃呰鑼冨洿 all鍏ㄥ憳 dept閮ㄩ棬 custom鑷畾涔�',
+  `is_required` tinyint NOT NULL DEFAULT 0 COMMENT '鏄惁蹇呰 0鍚� 1鏄�',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '鐘舵�� 0鑽夌 1宸插彂甯� 2宸蹭笅绾�',
+  `required_read_count` int NOT NULL DEFAULT 0 COMMENT '闇�瑕侀槄璇荤殑鏁伴噺',
+  `read_count` int NOT NULL DEFAULT 0 COMMENT '宸茬粡闃呰鐨勬暟閲�',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_enterprise_news_status`(`status` ASC) USING BTREE,
+  INDEX `idx_enterprise_news_category`(`category` ASC) USING BTREE,
+  INDEX `idx_enterprise_news_dept_id`(`dept_id` ASC) USING BTREE,
+  INDEX `idx_enterprise_news_create_time`(`create_time` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '浼佷笟鏂伴椈琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for enterprise_news_scope_dept
+-- ----------------------------
+DROP TABLE IF EXISTS `enterprise_news_scope_dept`;
+CREATE TABLE `enterprise_news_scope_dept`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '缂栧彿',
+  `news_id` bigint NOT NULL COMMENT '浼佷笟鏂伴椈ID',
+  `dept_id` bigint NOT NULL COMMENT '閮ㄩ棬ID',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE INDEX `uk_enterprise_news_scope_dept`(`news_id` ASC, `dept_id` ASC) USING BTREE,
+  INDEX `idx_enterprise_news_scope_dept_dept_id`(`dept_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '浼佷笟鏂伴椈闃呰鑼冨洿閮ㄩ棬琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for enterprise_news_scope_user
+-- ----------------------------
+DROP TABLE IF EXISTS `enterprise_news_scope_user`;
+CREATE TABLE `enterprise_news_scope_user`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '缂栧彿',
+  `news_id` bigint NOT NULL COMMENT '浼佷笟鏂伴椈ID',
+  `user_id` bigint NOT NULL COMMENT '鐢ㄦ埛ID',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE INDEX `uk_enterprise_news_scope_user`(`news_id` ASC, `user_id` ASC) USING BTREE,
+  INDEX `idx_enterprise_news_scope_user_user_id`(`user_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '浼佷笟鏂伴椈闃呰鑼冨洿鐢ㄦ埛琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for equipment_energy_consumption
+-- ----------------------------
+DROP TABLE IF EXISTS `equipment_energy_consumption`;
+CREATE TABLE `equipment_energy_consumption`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '璁惧缂栧彿',
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '璁惧鍚嶇О',
+  `power_rating` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '棰濆畾鍔熺巼',
+  `power_actual` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '瀹為檯鍔熺巼',
+  `day_num` decimal(18, 2) NULL DEFAULT 0.00 COMMENT '褰撴棩鐢ㄧ數閲�',
+  `sum_num` decimal(18, 2) NULL DEFAULT 0.00 COMMENT '绱鐢ㄧ數閲�',
+  `every_num` decimal(18, 2) NULL DEFAULT 0.00 COMMENT '姣忔棩闄愬埗鐢甸噺',
+  `run_date` date NULL DEFAULT NULL COMMENT '杩愯鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `electricity_consumption_area_id` bigint NULL DEFAULT NULL COMMENT '鍖哄煙id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '璁惧鑳借��' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for file_sharing
+-- ----------------------------
+DROP TABLE IF EXISTS `file_sharing`;
+CREATE TABLE `file_sharing`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍏变韩鏍囬',
+  `departments` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎺ユ敹閮ㄩ棬',
+  `files` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '涓婁紶鏂囦欢',
+  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍏变韩鎻忚堪',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '琛屾斂绠$悊-閫氱煡绠$悊-鏂囦欢鍏变韩' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for fin_fixed_asset
+-- ----------------------------
+DROP TABLE IF EXISTS `fin_fixed_asset`;
+CREATE TABLE `fin_fixed_asset`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `asset_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '璧勪骇缂栧彿',
+  `asset_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '璧勪骇鍚嶇О',
+  `category` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '璧勪骇绫诲埆',
+  `specification` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '瑙勬牸鍨嬪彿',
+  `purchase_date` date NOT NULL COMMENT '璐疆鏃ユ湡',
+  `original_value` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '璧勪骇鍘熷��',
+  `useful_life` int NOT NULL DEFAULT 1 COMMENT '浣跨敤骞撮檺(骞�)',
+  `residual_rate` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '娈嬪�肩巼(%)',
+  `accumulated_depreciation` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '绱鎶樻棫',
+  `net_value` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '鍑�鍊�',
+  `location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '瀛樻斁鍦扮偣',
+  `department` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '浣跨敤閮ㄩ棬',
+  `keeper` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '淇濈浜�',
+  `status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'in_use' COMMENT '鐘舵��: in_use/idle/repair/scrapped',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE INDEX `uk_fin_fixed_asset_code`(`asset_code` ASC) USING BTREE,
+  INDEX `idx_fin_fixed_asset_status`(`status` ASC) USING BTREE,
+  INDEX `idx_fin_fixed_asset_category`(`category` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '鍥哄畾璧勪骇' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for fin_intangible_asset
+-- ----------------------------
+DROP TABLE IF EXISTS `fin_intangible_asset`;
+CREATE TABLE `fin_intangible_asset`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `asset_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '璧勪骇缂栧彿',
+  `asset_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '璧勪骇鍚嶇О',
+  `category` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '璧勪骇绫诲埆',
+  `certificate_no` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '璇佷功缂栧彿',
+  `acquisition_date` date NOT NULL COMMENT '鍙栧緱鏃ユ湡',
+  `original_value` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '璧勪骇鍘熷��',
+  `amortization_period` int NOT NULL DEFAULT 1 COMMENT '鎽婇攢骞撮檺(骞�)',
+  `residual_rate` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '娈嬪�肩巼(%)',
+  `accumulated_amortization` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '绱鎽婇攢',
+  `net_value` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '鍑�鍊�',
+  `validity_date` date NULL DEFAULT NULL COMMENT '鏈夋晥鏈熻嚦',
+  `status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'in_use' COMMENT '鐘舵��: in_use/expired/amortized',
+  `description` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '璧勪骇鎻忚堪',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE INDEX `uk_fin_intangible_asset_code`(`asset_code` ASC) USING BTREE,
+  INDEX `idx_fin_intangible_asset_status`(`status` ASC) USING BTREE,
+  INDEX `idx_fin_intangible_asset_category`(`category` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '鏃犲舰璧勪骇' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for fin_reimbursement
+-- ----------------------------
+DROP TABLE IF EXISTS `fin_reimbursement`;
+CREATE TABLE `fin_reimbursement`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `bill_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '鎶ラ攢鍗曞彿',
+  `reimbursement_type` tinyint NOT NULL COMMENT '鎶ラ攢绫诲瀷锛�1-宸梾鎶ラ攢锛�2-璐圭敤鎶ラ攢',
+  `expense_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '璐圭敤绫诲瀷锛氬樊鏃呰垂/鍔炲叕閲囪喘/涓氬姟鎷涘緟/浜ら�氳垂/閫氳璐�/鍏朵粬',
+  `applicant_id` bigint NOT NULL COMMENT '鐢宠浜篒D',
+  `applicant_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍛樺伐缂栧彿',
+  `applicant_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '鍛樺伐濮撳悕',
+  `applicant_dept_id` bigint NULL DEFAULT NULL COMMENT '鐢宠閮ㄩ棬ID',
+  `applicant_dept_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鐢宠閮ㄩ棬鍚嶇О',
+  `reason` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鎶ラ攢鍘熷洜',
+  `apply_amount` decimal(18, 4) NOT NULL DEFAULT 0.0000 COMMENT '鐢宠閲戦',
+  `detail_total_amount` decimal(18, 4) NOT NULL DEFAULT 0.0000 COMMENT '鏄庣粏姹囨�婚噾棰�',
+  `payee_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '鏀舵浜�',
+  `payee_account` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鏀舵璐﹀彿',
+  `payee_bank` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '寮�鎴锋敮琛�',
+  `approval_instance_id` bigint NULL DEFAULT NULL COMMENT '瀹℃壒瀹炰緥ID锛屽搴� approval_instance.id',
+  `approve_process_id` bigint NULL DEFAULT NULL COMMENT '瀹℃壒娴佺▼ID锛屽搴� approve_process.id',
+  `bill_status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'DRAFT' COMMENT '鍗曟嵁鐘舵�侊細DRAFT-鑽夌锛孖N_APPROVAL-瀹℃壒涓紝APPROVED-瀹℃壒閫氳繃锛孯EJECTED-瀹℃壒椹冲洖锛學ITHDRAWN-宸叉挙鍥烇紝PAID-宸蹭粯娆�',
+  `approved_time` datetime NULL DEFAULT NULL COMMENT '瀹℃壒閫氳繃鏃堕棿',
+  `paid_time` datetime NULL DEFAULT NULL COMMENT '浠樻鏃堕棿',
+  `account_expense_id` bigint NULL DEFAULT NULL COMMENT '鐢熸垚鐨勮储鍔℃敮鍑鸿褰旾D锛屽搴� account_expense.id',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '褰掑睘閮ㄩ棬ID',
+  `deleted` tinyint NOT NULL DEFAULT 0 COMMENT '閫昏緫鍒犻櫎锛�0-鍚︼紝1-鏄�',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE INDEX `uk_fin_reimbursement_bill_no`(`bill_no` ASC) USING BTREE,
+  INDEX `idx_fin_reimbursement_type_status`(`reimbursement_type` ASC, `bill_status` ASC) USING BTREE,
+  INDEX `idx_fin_reimbursement_applicant`(`applicant_id` ASC) USING BTREE,
+  INDEX `idx_fin_reimbursement_approval_instance`(`approval_instance_id` ASC) USING BTREE,
+  INDEX `idx_fin_reimbursement_apply_amount`(`apply_amount` ASC) USING BTREE,
+  INDEX `idx_fin_reimbursement_create_time`(`create_time` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '鎶ラ攢鍗曚富琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for fin_reimbursement_detail
+-- ----------------------------
+DROP TABLE IF EXISTS `fin_reimbursement_detail`;
+CREATE TABLE `fin_reimbursement_detail`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `reimbursement_id` bigint NOT NULL COMMENT '鎶ラ攢鍗旾D锛屽搴� fin_reimbursement.id',
+  `row_no` int NOT NULL DEFAULT 1 COMMENT '鏄庣粏琛屽彿',
+  `invoice_date` date NULL DEFAULT NULL COMMENT '鍙戠エ鏃ユ湡',
+  `expense_category` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '璐圭敤绉戠洰',
+  `amount` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '閲戦',
+  `description` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鎻忚堪',
+  `invoice_no` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍙戠エ鍙风爜',
+  `invoice_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍙戠エ绫诲瀷',
+  `invoice_amount` decimal(18, 2) NULL DEFAULT NULL COMMENT '绁ㄩ潰閲戦',
+  `tax_rate` decimal(8, 2) NULL DEFAULT NULL COMMENT '绋庣巼',
+  `tax_amount` decimal(18, 2) NULL DEFAULT NULL COMMENT '绋庨',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '褰掑睘閮ㄩ棬ID',
+  `deleted` tinyint NOT NULL DEFAULT 0 COMMENT '閫昏緫鍒犻櫎锛�0-鍚︼紝1-鏄�',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_fin_reimbursement_detail_reimbursement`(`reimbursement_id` ASC) USING BTREE,
+  INDEX `idx_fin_reimbursement_detail_category`(`expense_category` ASC) USING BTREE,
+  INDEX `idx_fin_reimbursement_detail_invoice_date`(`invoice_date` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 19 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '鎶ラ攢鍗曟槑缁嗚〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for fin_reimbursement_travel
+-- ----------------------------
+DROP TABLE IF EXISTS `fin_reimbursement_travel`;
+CREATE TABLE `fin_reimbursement_travel`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `reimbursement_id` bigint NOT NULL COMMENT '鎶ラ攢鍗旾D锛屽搴� fin_reimbursement.id',
+  `start_time` datetime NOT NULL COMMENT '鍑哄樊寮�濮嬫椂闂�',
+  `end_time` datetime NOT NULL COMMENT '鍑哄樊缁撴潫鏃堕棿',
+  `travel_days` decimal(8, 2) NULL DEFAULT NULL COMMENT '鍑哄樊澶╂暟',
+  `departure_city` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '鍑哄樊鍦�/鍑哄彂鍩庡競',
+  `destination_city` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '鐩殑鍦�/鐩殑鍩庡競',
+  `hotel_standard` decimal(18, 4) NULL DEFAULT 0.0000 COMMENT '閰掑簵鏍囧噯',
+  `lodging_days` decimal(8, 4) NULL DEFAULT 0.0000 COMMENT '浣忓澶╂暟',
+  `meal_allowance` decimal(18, 4) NULL DEFAULT 0.0000 COMMENT '鐢熸椿琛ヨ创',
+  `transport_allowance` decimal(18, 4) NULL DEFAULT 0.0000 COMMENT '浜ら�氳ˉ璐�',
+  `lodging_limit` decimal(18, 4) NULL DEFAULT 0.0000 COMMENT '浣忓闄愰',
+  `standard_tag` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鐗规壒鏍囪鏂囨湰锛屽鍦ㄦ爣鍑嗚寖鍥村唴/瓒呮爣鐗规壒',
+  `within_standard` tinyint NOT NULL DEFAULT 1 COMMENT '鏄惁鍦ㄦ爣鍑嗗唴锛�1-鏄紝0-鍚�',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '褰掑睘閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE INDEX `uk_fin_reimbursement_travel_reimbursement`(`reimbursement_id` ASC) USING BTREE,
+  INDEX `idx_fin_reimbursement_travel_start_end`(`start_time` ASC, `end_time` ASC) USING BTREE,
+  INDEX `idx_fin_reimbursement_travel_city`(`departure_city` ASC, `destination_city` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '宸梾鎶ラ攢鎵╁睍琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for fin_voucher
+-- ----------------------------
+DROP TABLE IF EXISTS `fin_voucher`;
+CREATE TABLE `fin_voucher`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `voucher_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '鍑瘉瀛楀彿',
+  `voucher_date` date NOT NULL COMMENT '鍑瘉鏃ユ湡',
+  `summary` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鎽樿',
+  `debit` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '鍊熸柟鍚堣',
+  `credit` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '璐锋柟鍚堣',
+  `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍒跺崟浜�',
+  `status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'unposted' COMMENT '鐘舵��: unposted/posted/cancelled',
+  `attachment_count` int NOT NULL DEFAULT 0 COMMENT '闄勪欢寮犳暟',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE INDEX `uk_fin_voucher_no`(`voucher_no` ASC) USING BTREE,
+  INDEX `idx_fin_voucher_date`(`voucher_date` ASC) USING BTREE,
+  INDEX `idx_fin_voucher_status`(`status` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '鍑瘉涓昏〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for fin_voucher_entry
+-- ----------------------------
+DROP TABLE IF EXISTS `fin_voucher_entry`;
+CREATE TABLE `fin_voucher_entry`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `voucher_id` bigint NOT NULL COMMENT '鍑瘉ID',
+  `row_no` int NOT NULL DEFAULT 1 COMMENT '琛屽彿',
+  `subject_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '绉戠洰缂栫爜',
+  `subject_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '绉戠洰鍚嶇О',
+  `summary` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鎽樿',
+  `debit` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '鍊熸柟閲戦',
+  `credit` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '璐锋柟閲戦',
+  `auxiliary_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '杈呭姪鏍哥畻绫诲瀷',
+  `auxiliary_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '杈呭姪鏍哥畻瀵硅薄ID',
+  `auxiliary_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '杈呭姪鏍哥畻瀵硅薄鍚嶇О',
+  `create_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_fin_voucher_entry_voucher`(`voucher_id` ASC) USING BTREE,
+  INDEX `idx_fin_voucher_entry_subject`(`subject_code` ASC) USING BTREE,
+  INDEX `idx_fin_voucher_entry_aux`(`auxiliary_type` ASC, `auxiliary_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '鍑瘉鍒嗗綍' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for gas_tank_warning
+-- ----------------------------
+DROP TABLE IF EXISTS `gas_tank_warning`;
+CREATE TABLE `gas_tank_warning`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `tank_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍌ㄦ皵缃愮紪鐮�',
+  `tank_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍌ㄦ皵缃愬悕绉�',
+  `tank_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍌ㄦ皵缃愮被鍨�',
+  `specification_model` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瑙勬牸鍨嬪彿',
+  `volume` bigint NULL DEFAULT NULL COMMENT '瀹圭Н(m鲁)',
+  `current_gas_level` bigint NULL DEFAULT NULL COMMENT '褰撳墠姘斾綋閲�',
+  `safety_gas_level` bigint NULL DEFAULT NULL COMMENT '瀹夊叏姘斾綋閲�',
+  `min_gas_level` bigint NULL DEFAULT NULL COMMENT '鏈�浣庢皵浣撻噺',
+  `max_gas_level` bigint NULL DEFAULT NULL COMMENT '鏈�楂樻皵浣撻噺',
+  `current_pressure` decimal(10, 1) NULL DEFAULT NULL COMMENT '褰撳墠鍘嬪姏(MPa)',
+  `warning_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '棰勮绫诲瀷',
+  `warning_level` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '棰勮绾у埆',
+  `warning_threshold` bigint NULL DEFAULT NULL COMMENT '棰勮闃堝��',
+  `is_enabled` int NULL DEFAULT NULL COMMENT '鏄惁鍚敤',
+  `warning_time` datetime NULL DEFAULT NULL COMMENT '棰勮鏃堕棿',
+  `warning_duration` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '棰勮鎸佺画澶╂暟',
+  `last_update_time` datetime NULL DEFAULT NULL COMMENT '鏈�鍚庢洿鏂版椂闂�',
+  `expected_refill_time` datetime NULL DEFAULT NULL COMMENT '棰勮鍏呰鏃堕棿',
+  `expected_shortage_time` datetime NULL DEFAULT NULL COMMENT '棰勮缂烘皵鏃堕棿',
+  `warning_rule` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '褰�???鏃惰Е鍙戦璀�-棰勮瑙勫垯',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '搴撳瓨棰勮-姘旂綈璀﹀憡' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for gen_table
+-- ----------------------------
+DROP TABLE IF EXISTS `gen_table`;
+CREATE TABLE `gen_table`  (
+  `table_id` bigint NOT NULL AUTO_INCREMENT COMMENT '缂栧彿',
+  `table_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '琛ㄥ悕绉�',
+  `table_comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '琛ㄦ弿杩�',
+  `sub_table_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍏宠仈瀛愯〃鐨勮〃鍚�',
+  `sub_table_fk_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀛愯〃鍏宠仈鐨勫閿悕',
+  `class_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '瀹炰綋绫诲悕绉�',
+  `tpl_category` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'crud' COMMENT '浣跨敤鐨勬ā鏉匡紙crud鍗曡〃鎿嶄綔 tree鏍戣〃鎿嶄綔锛�',
+  `tpl_web_type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鍓嶇妯℃澘绫诲瀷锛坋lement-ui妯$増 element-plus妯$増锛�',
+  `package_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐢熸垚鍖呰矾寰�',
+  `module_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐢熸垚妯″潡鍚�',
+  `business_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐢熸垚涓氬姟鍚�',
+  `function_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐢熸垚鍔熻兘鍚�',
+  `function_author` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐢熸垚鍔熻兘浣滆��',
+  `gen_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '鐢熸垚浠g爜鏂瑰紡锛�0zip鍘嬬缉鍖� 1鑷畾涔夎矾寰勶級',
+  `gen_path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '/' COMMENT '鐢熸垚璺緞锛堜笉濉粯璁ら」鐩矾寰勶級',
+  `options` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍏跺畠鐢熸垚閫夐」',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鏇存柊鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`table_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浠g爜鐢熸垚涓氬姟琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for gen_table_column
+-- ----------------------------
+DROP TABLE IF EXISTS `gen_table_column`;
+CREATE TABLE `gen_table_column`  (
+  `column_id` bigint NOT NULL AUTO_INCREMENT COMMENT '缂栧彿',
+  `table_id` bigint NULL DEFAULT NULL COMMENT '褰掑睘琛ㄧ紪鍙�',
+  `column_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍒楀悕绉�',
+  `column_comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍒楁弿杩�',
+  `column_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍒楃被鍨�',
+  `java_type` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'JAVA绫诲瀷',
+  `java_field` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'JAVA瀛楁鍚�',
+  `is_pk` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏄惁涓婚敭锛�1鏄級',
+  `is_increment` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏄惁鑷锛�1鏄級',
+  `is_required` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏄惁蹇呭~锛�1鏄級',
+  `is_insert` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏄惁涓烘彃鍏ュ瓧娈碉紙1鏄級',
+  `is_edit` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏄惁缂栬緫瀛楁锛�1鏄級',
+  `is_list` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏄惁鍒楄〃瀛楁锛�1鏄級',
+  `is_query` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏄惁鏌ヨ瀛楁锛�1鏄級',
+  `query_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'EQ' COMMENT '鏌ヨ鏂瑰紡锛堢瓑浜庛�佷笉绛変簬銆佸ぇ浜庛�佸皬浜庛�佽寖鍥达級',
+  `html_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏄剧ず绫诲瀷锛堟枃鏈銆佹枃鏈煙銆佷笅鎷夋銆佸閫夋銆佸崟閫夋銆佹棩鏈熸帶浠讹級',
+  `dict_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '瀛楀吀绫诲瀷',
+  `sort` int NULL DEFAULT NULL COMMENT '鎺掑簭',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鏇存柊鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`column_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浠g爜鐢熸垚涓氬姟琛ㄥ瓧娈�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for holiday_application
+-- ----------------------------
+DROP TABLE IF EXISTS `holiday_application`;
+CREATE TABLE `holiday_application`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `staff_id` int NULL DEFAULT NULL COMMENT '鍛樺伐id',
+  `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍋囨湡绫诲瀷',
+  `start_date` datetime NULL DEFAULT NULL COMMENT '寮�濮嬫棩鏈�',
+  `end_date` datetime NULL DEFAULT NULL COMMENT '缁撴潫鏃ユ湡',
+  `days` int NULL DEFAULT NULL COMMENT '澶╂暟',
+  `reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐢宠鍘熷洜',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐘舵��',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍋囨湡鐢宠' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for holiday_settings
+-- ----------------------------
+DROP TABLE IF EXISTS `holiday_settings`;
+CREATE TABLE `holiday_settings`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍋囨湡鍚嶇О',
+  `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍋囨湡绫诲瀷',
+  `start_date` datetime NULL DEFAULT NULL COMMENT '寮�濮嬫棩鏈�',
+  `end_date` datetime NULL DEFAULT NULL COMMENT '缁撴潫鏃ユ湡',
+  `days` int NULL DEFAULT NULL COMMENT '澶╂暟',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐘舵��',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍋囨湡璁剧疆' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for inbound_management
+-- ----------------------------
+DROP TABLE IF EXISTS `inbound_management`;
+CREATE TABLE `inbound_management`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '搴忓彿',
+  `order_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁㈠崟鍙�',
+  `arrival_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍒拌揣鍗曞彿',
+  `supplier_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '渚涘簲鍟嗗悕绉�',
+  `status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍒拌揣鐘舵��',
+  `arrival_time` datetime NULL DEFAULT NULL COMMENT '鍒拌揣鏃堕棿',
+  `arrival_quantity` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍒拌揣鏁伴噺',
+  `remark` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '澶囨敞',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '淇敼鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '閲囪喘鍒拌揣琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for inspection_task
+-- ----------------------------
+DROP TABLE IF EXISTS `inspection_task`;
+CREATE TABLE `inspection_task`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '宸℃浠诲姟鍞竴鏍囪瘑',
+  `task_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁惧鍚嶇О',
+  `inspection_project` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宸℃椤圭洰',
+  `task_id` int NULL DEFAULT NULL COMMENT '璁惧id',
+  `inspector_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `inspector` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎵ц宸℃鐨勪汉鍛樺鍚�',
+  `remarks` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '浠诲姟闄勫姞璇存槑鎴栫壒娈婃儏鍐佃褰�',
+  `inspection_result` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宸℃缁撴灉 0寮傚父 1姝e父',
+  `abnormal_description` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '寮傚父鎻忚堪',
+  `device_repair_id` bigint NULL DEFAULT NULL COMMENT '鍏宠仈缁翠慨鍗旾D',
+  `acceptance_user_id` bigint NULL DEFAULT NULL COMMENT '楠屾敹浜篒D',
+  `acceptance_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '楠屾敹浜�',
+  `registrant_id` bigint NULL DEFAULT NULL,
+  `registrant` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浠诲姟鐧昏浜哄鍚�',
+  `frequency_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '棰戞',
+  `inspection_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宸℃鍦扮偣璇︾粏鎻忚堪',
+  `frequency_detail` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏃堕棿缁嗚妭',
+  `deleted` int NOT NULL DEFAULT 0 COMMENT '杞垹闄ゆ爣蹇楋紝0=鏈垹闄わ紝1=宸插垹闄�',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓璇ヨ褰曠殑鐢ㄦ埛',
+  `create_time` datetime(6) NULL DEFAULT NULL COMMENT '璁板綍鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '鏈�鍚庝慨鏀硅璁板綍鐨勭敤鎴�',
+  `update_time` datetime(6) NULL DEFAULT NULL COMMENT '璁板綍鏈�鍚庢洿鏂版椂闂�',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_inspection_task_device_repair_id`(`device_repair_id` ASC) USING BTREE,
+  INDEX `idx_inspection_task_inspection_result`(`inspection_result` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 22 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '宸℃浠诲姟琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for invoice_ledger
+-- ----------------------------
+DROP TABLE IF EXISTS `invoice_ledger`;
+CREATE TABLE `invoice_ledger`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `invoice_registration_product_id` bigint NULL DEFAULT NULL COMMENT '浜у搧寮�绁ㄧ櫥璁拌褰曡〃涓婚敭',
+  `invoice_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍙戠エ鍙�',
+  `invoice_total` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍙戠エ閲戦',
+  `invoice_person` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '寮�绁ㄤ汉',
+  `invoice_date` datetime NULL DEFAULT NULL COMMENT '寮�绁ㄦ棩鏈�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 666 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '寮�绁ㄥ彴璐�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for invoice_ledger_file
+-- ----------------------------
+DROP TABLE IF EXISTS `invoice_ledger_file`;
+CREATE TABLE `invoice_ledger_file`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囦欢鍚嶇О',
+  `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囦欢璺緞',
+  `file_size` int NULL DEFAULT NULL COMMENT '鏂囦欢澶у皬',
+  `invoice_ledger_id` bigint NULL DEFAULT NULL COMMENT '寮�绁ㄥ彴璐D',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 49 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '寮�绁ㄥ彴璐﹂檮浠惰〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for invoice_purchase
+-- ----------------------------
+DROP TABLE IF EXISTS `invoice_purchase`;
+CREATE TABLE `invoice_purchase`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `purchase_contract_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '閲囪喘鍚堝悓鍙�',
+  `sales_contract_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '閿�鍞悎鍚屽彿',
+  `supplier_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '渚涘簲鍟嗗悕绉�',
+  `invoice_number` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鍙戠エ鍙�',
+  `invoice_amount` decimal(10, 2) NOT NULL COMMENT '鍙戠エ閲戦锛堝厓锛�',
+  `tax_rate` decimal(5, 2) NOT NULL COMMENT '绋庣巼',
+  `iss_uer_id` int NULL DEFAULT NULL,
+  `iss_uer` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '寮�绁ㄤ汉',
+  `issue_date` date NOT NULL COMMENT '寮�绁ㄦ棩鏈�',
+  `invoice_file` longblob NULL COMMENT '鍙戠エ鏂囦欢锛圥DF鏍煎紡锛�',
+  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `purchase_ledger_id` int NULL DEFAULT NULL,
+  `sales_ledger_id` int NULL DEFAULT NULL COMMENT '鍏宠仈閿�鍞彴璐︿富琛ㄤ富閿�',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍙戠エ淇℃伅琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for invoice_registration
+-- ----------------------------
+DROP TABLE IF EXISTS `invoice_registration`;
+CREATE TABLE `invoice_registration`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `sales_ledger_id` bigint NULL DEFAULT NULL COMMENT '閿�鍞彴璐ales_ledger涓婚敭',
+  `sales_contract_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閿�鍞悎鍚屽彿',
+  `customer_id` bigint NULL DEFAULT NULL COMMENT '瀹㈡埛鍚嶇ОID',
+  `salesman` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '涓氬姟鍛�',
+  `project_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '椤圭洰鍚嶇О',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 503 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '寮�绁ㄧ櫥璁拌褰曡〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for invoice_registration_product
+-- ----------------------------
+DROP TABLE IF EXISTS `invoice_registration_product`;
+CREATE TABLE `invoice_registration_product`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `sales_ledger_id` bigint NOT NULL COMMENT '鍏宠仈閿�鍞彴璐︿富琛ㄤ富閿�',
+  `sales_ledger_product_id` bigint NULL DEFAULT NULL COMMENT '鍏宠仈sales_ledger_product涓婚敭',
+  `invoice_registration_id` bigint NULL DEFAULT NULL COMMENT '寮�绁ㄧ櫥璁拌〃invoice_registration涓婚敭',
+  `product_category` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浜у搧澶х被',
+  `specification_model` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瑙勬牸鍨嬪彿',
+  `unit` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `quantity` decimal(18, 2) NOT NULL COMMENT '鏁伴噺',
+  `tax_rate` decimal(5, 2) NOT NULL COMMENT '绋庣巼',
+  `tax_inclusive_unit_price` decimal(18, 2) NOT NULL COMMENT '鍚◣鍗曚环',
+  `tax_inclusive_total_price` decimal(18, 2) NOT NULL COMMENT '鍚◣鎬讳环',
+  `tax_exclusive_total_price` decimal(18, 2) NOT NULL COMMENT '涓嶅惈绋庢�讳环',
+  `invoice_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍙戠エ绫诲瀷',
+  `invoice_num` decimal(10, 2) NULL DEFAULT NULL COMMENT '寮�绁ㄦ暟',
+  `invoice_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '寮�绁ㄩ噾棰�',
+  `no_invoice_num` decimal(10, 2) NULL DEFAULT NULL COMMENT '鏈紑绁ㄦ暟',
+  `no_invoice_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '鏈紑绁ㄩ噾棰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 666 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浜у搧寮�绁ㄧ櫥璁拌褰曡〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for knowledge_base
+-- ----------------------------
+DROP TABLE IF EXISTS `knowledge_base`;
+CREATE TABLE `knowledge_base`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐭ヨ瘑鏍囬',
+  `type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐭ヨ瘑绫诲瀷',
+  `scenario` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閫傜敤鍦烘櫙',
+  `efficiency` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瑙e喅鏁堢巼',
+  `problem` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '闂鎻忚堪',
+  `solution` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '瑙e喅鏂规',
+  `key_points` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '鍏抽敭瑕佺偣',
+  `creator` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `usage_count` int NULL DEFAULT 0 COMMENT '浣跨敤娆℃暟',
+  `file_count` int NULL DEFAULT 0 COMMENT '鏂囦欢鏁伴噺',
+  `total_chunk_count` int NULL DEFAULT 0 COMMENT '鎬诲垏鐗囨暟閲�',
+  `description` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐭ヨ瘑搴撴弿杩�',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP,
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  `create_user` int NULL DEFAULT NULL,
+  `update_user` int NULL DEFAULT NULL,
+  `tenant_id` bigint NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐭ヨ瘑搴撹〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for knowledge_base_vector
+-- ----------------------------
+DROP TABLE IF EXISTS `knowledge_base_vector`;
+CREATE TABLE `knowledge_base_vector`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `knowledge_base_id` bigint NOT NULL COMMENT '鍏宠仈鐭ヨ瘑搴揑D',
+  `storage_blob_id` bigint NOT NULL COMMENT '鍏宠仈鏂囦欢blob ID',
+  `file_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鏂囦欢鍚嶇О',
+  `file_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鏂囦欢绫诲瀷',
+  `vector_status` tinyint NULL DEFAULT 0 COMMENT '鍚戦噺鍖栫姸鎬�: 0-寰呭鐞�, 1-澶勭悊涓�, 2-宸插畬鎴�, 3-澶辫触',
+  `vector_error` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍚戦噺鍖栧け璐ュ師鍥�',
+  `chunk_count` int NULL DEFAULT 0 COMMENT '鍒囩墖鏁伴噺',
+  `namespace` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍚戦噺鍛藉悕绌洪棿',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP,
+  `create_user` int NULL DEFAULT NULL,
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  `update_user` int NULL DEFAULT NULL,
+  `tenant_id` bigint NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_knowledge_base_id`(`knowledge_base_id` ASC) USING BTREE,
+  INDEX `idx_storage_blob_id`(`storage_blob_id` ASC) USING BTREE,
+  INDEX `idx_vector_status`(`vector_status` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐭ヨ瘑搴撴枃浠跺悜閲忚褰曡〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for labor_issue
+-- ----------------------------
+DROP TABLE IF EXISTS `labor_issue`;
+CREATE TABLE `labor_issue`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `order_no` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '鍔充繚鍗曞彿',
+  `staff_id` bigint NULL DEFAULT NULL COMMENT '鍛樺伐id',
+  `dict_type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '鍔充繚绫诲瀷锛堝瓧鍏革級',
+  `dict_id` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '瀛楀吀id',
+  `num` bigint NULL DEFAULT NULL COMMENT '鍙戞斁鏁伴噺',
+  `factory_date` date NULL DEFAULT NULL COMMENT '杩涘巶鏃ユ湡',
+  `Issue_date` date NULL DEFAULT NULL COMMENT '鍙戞斁鏃ユ湡',
+  `adopted_date` date NULL DEFAULT NULL COMMENT '棰嗙敤鏃ユ湡',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '鍔充繚鍙戞斁琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for loss
+-- ----------------------------
+DROP TABLE IF EXISTS `loss`;
+CREATE TABLE `loss`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `rate` decimal(10, 2) NULL DEFAULT NULL,
+  `tenant_id` int NULL DEFAULT NULL,
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for maintenance_task
+-- ----------------------------
+DROP TABLE IF EXISTS `maintenance_task`;
+CREATE TABLE `maintenance_task`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `task_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璁惧鍚嶇О',
+  `task_id` int NULL DEFAULT NULL COMMENT '璁惧id',
+  `frequency_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '棰戞',
+  `frequency_detail` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `next_execution_time` datetime(6) NULL DEFAULT NULL,
+  `last_execution_time` datetime(6) NULL DEFAULT NULL,
+  `is_active` tinyint(1) NULL DEFAULT NULL,
+  `remarks` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '澶囨敞',
+  `registrant_id` bigint NULL DEFAULT NULL COMMENT '褰曞叆浜篿d',
+  `registrant` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '褰曞叆浜�',
+  `registration_date` date NOT NULL COMMENT '褰曞叆鏃ユ湡',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `deleted` int NOT NULL DEFAULT 0 COMMENT '杞垹闄ゆ爣蹇楋紝0=鏈垹闄わ紝1=宸插垹闄�',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓璇ヨ褰曠殑鐢ㄦ埛',
+  `create_time` datetime(6) NULL DEFAULT NULL COMMENT '璁板綍鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '鏈�鍚庝慨鏀硅璁板綍鐨勭敤鎴�',
+  `update_time` datetime(6) NULL DEFAULT NULL COMMENT '璁板綍鏈�鍚庢洿鏂版椂闂�',
+  `tenant_id` int NULL DEFAULT NULL,
+  `device_model` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `machinery_category` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁惧椤圭洰',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `maintenance_person` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '淇濆吇浜�',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹氭椂淇濆吇浠诲姟琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for measuring_instrument_ledger
+-- ----------------------------
+DROP TABLE IF EXISTS `measuring_instrument_ledger`;
+CREATE TABLE `measuring_instrument_ledger`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `user_id` bigint NULL DEFAULT NULL COMMENT '褰曞叆浜篿d',
+  `user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '褰曞叆浜哄悕绉�',
+  `code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '璁¢噺鍣ㄥ叿缂栧彿',
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '璁¢噺鍣ㄥ叿鍚嶇О',
+  `model` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '瑙勬牸鍨嬪彿',
+  `most_date` date NULL DEFAULT NULL COMMENT '鏈�杩戜竴娆℃瀹氭棩鏈�',
+  `valid` int NULL DEFAULT NULL COMMENT '妫�瀹氭湁鏁堟湡锛堝崟浣嶅ぉ锛�',
+  `next_date` date NULL DEFAULT NULL COMMENT '棰勮涓嬫妫�瀹氭棩鏈�',
+  `record_date` date NULL DEFAULT NULL COMMENT '褰曞叆鏃ユ湡',
+  `status` int NULL DEFAULT NULL COMMENT '鐘舵�侊紙1-鏈夋晥 2-閫炬湡锛�',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `instation_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '瀹夎浣嶇疆',
+  `unit` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '妫�瀹氬崟浣�',
+  `cycle` int NULL DEFAULT NULL COMMENT '妫�瀹氬懆鏈燂紙澶╋級',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '璁¢噺鍣ㄥ叿鍙拌处' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for measuring_instrument_ledger_record
+-- ----------------------------
+DROP TABLE IF EXISTS `measuring_instrument_ledger_record`;
+CREATE TABLE `measuring_instrument_ledger_record`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `measuring_instrument_ledger_id` bigint NULL DEFAULT NULL COMMENT '璁¢噺鍣ㄥ叿鍙拌处id',
+  `user_id` bigint NULL DEFAULT NULL COMMENT '妫�瀹歩d',
+  `user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '妫�瀹氫汉鍚嶇О',
+  `record_date` date NULL DEFAULT NULL COMMENT '妫�瀹氭棩鏈�',
+  `entry_date` date NULL DEFAULT NULL COMMENT '褰曞叆鏃ユ湡',
+  `valid` int NULL DEFAULT NULL COMMENT '妫�瀹氭湁鏁堟湡锛堝崟浣嶅ぉ锛�',
+  `status` int NULL DEFAULT NULL COMMENT '鐘舵�侊紙1-鏈夋晥 2-閫炬湡锛�',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '璁¢噺鍣ㄥ叿鍙拌处璁板綍' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for meet_application
+-- ----------------------------
+DROP TABLE IF EXISTS `meet_application`;
+CREATE TABLE `meet_application`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '鐢宠ID',
+  `title` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '浼氳涓婚',
+  `room_id` bigint NOT NULL COMMENT '浼氳瀹D',
+  `host` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '涓绘寔浜�',
+  `meeting_date` date NOT NULL COMMENT '浼氳鏃ユ湡',
+  `start_time` datetime NOT NULL COMMENT '寮�濮嬫椂闂�',
+  `end_time` datetime NOT NULL COMMENT '缁撴潫鏃堕棿',
+  `participants` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '鍙備細浜哄憳锛圝SON鏍煎紡瀛樺偍ID鏁扮粍锛�',
+  `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '浼氳璇存槑',
+  `application_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'approval' COMMENT '鐢宠绫诲瀷锛坅pproval:瀹℃壒娴佺▼, department:閮ㄩ棬绾�, notification:閫氱煡鍙戝竷锛�',
+  `status` tinyint NOT NULL DEFAULT 0 COMMENT '鐘舵�侊紙0:寰呭鎵�, 1:宸查�氳繃, 2:宸叉嫆缁�, 3:宸插彇娑堬級',
+  `applicant` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '鐢宠浜�',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊鑰�',
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `publish_status` int NULL DEFAULT 0 COMMENT '鍙戝竷鐘舵��',
+  `publish_comment` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '鍙戝竷璇勮',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_title`(`title` ASC) USING BTREE,
+  INDEX `idx_meeting_date`(`meeting_date` ASC) USING BTREE,
+  INDEX `idx_applicant`(`applicant` ASC) USING BTREE,
+  INDEX `idx_status`(`status` ASC) USING BTREE,
+  INDEX `idx_create_time`(`create_time` ASC) USING BTREE,
+  INDEX `idx_tenant_id`(`tenant_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '浼氳鐢宠琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for meet_draft
+-- ----------------------------
+DROP TABLE IF EXISTS `meet_draft`;
+CREATE TABLE `meet_draft`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '鑽夌ID',
+  `room_id` bigint NOT NULL COMMENT '浼氳缂栧彿',
+  `title` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '浼氳涓婚',
+  `host` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '涓绘寔浜�',
+  `meeting_date` date NOT NULL COMMENT '浼氳鏃ユ湡',
+  `start_time` datetime NOT NULL COMMENT '寮�濮嬫椂闂�',
+  `end_time` datetime NOT NULL COMMENT '缁撴潫鏃堕棿',
+  `participants` int NOT NULL DEFAULT 0 COMMENT '鍙備細浜烘暟',
+  `participant_list` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '鍙備細浜哄憳鍒楄〃',
+  `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '浼氳璇存槑',
+  `creator` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '鍒涘缓浜�',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊鑰�',
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '浼氳鑽夌琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for meeting_minutes
+-- ----------------------------
+DROP TABLE IF EXISTS `meeting_minutes`;
+CREATE TABLE `meeting_minutes`  (
+  `id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '绾ID',
+  `meeting_id` bigint UNSIGNED NOT NULL COMMENT '鍏宠仈鐨勪細璁甀D',
+  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '绾鏍囬',
+  `content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '绾鍐呭锛堝瘜鏂囨湰锛�',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊鑰�',
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_meeting_id`(`meeting_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浼氳绾琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for meeting_room
+-- ----------------------------
+DROP TABLE IF EXISTS `meeting_room`;
+CREATE TABLE `meeting_room`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '浼氳瀹D',
+  `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '浼氳瀹ゅ悕绉�',
+  `location` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '浣嶇疆',
+  `capacity` int NOT NULL DEFAULT 10 COMMENT '瀹圭撼浜烘暟',
+  `equipment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '璁惧閰嶇疆锛堥�楀彿鍒嗛殧锛�',
+  `status` tinyint NOT NULL DEFAULT 1 COMMENT '鐘舵�侊紙1:鍚敤 0:绂佺敤锛�',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊鑰�',
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '浼氳瀹よ〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for notice
+-- ----------------------------
+DROP TABLE IF EXISTS `notice`;
+CREATE TABLE `notice`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '鍏憡ID',
+  `title` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '鍏憡鏍囬',
+  `type` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '1' COMMENT '鍏憡绫诲瀷锛�1鏀惧亣閫氱煡 2璁惧缁翠慨閫氱煡锛�',
+  `status` tinyint NOT NULL DEFAULT 0 COMMENT '鐘舵�侊紙0鑽夌 1鍙戝竷 2宸蹭笅绾匡級',
+  `content` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL COMMENT '鍏憡鍐呭',
+  `priority` tinyint NOT NULL DEFAULT 0 COMMENT '浼樺厛绾�(1鏅�� 2閲嶈 3绱ф��)',
+  `create_user` bigint NOT NULL COMMENT '鍒涘缓鑰�',
+  `create_time` timestamp NOT NULL COMMENT '鍒涘缓鏃堕棿',
+  `remark` varchar(500) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '绉熸埛id',
+  `expiration_date` date NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '閫氱煡鍏憡琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for notice_type
+-- ----------------------------
+DROP TABLE IF EXISTS `notice_type`;
+CREATE TABLE `notice_type`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `notice_type` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '閫氱煡鍏憡鐨勫叕鍛婄被鍨�',
+  `tenant_id` int NULL DEFAULT NULL,
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '閫氱煡鍏憡鐨勫叕鍛婄被鍨嬬淮鎶�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for notification_management
+-- ----------------------------
+DROP TABLE IF EXISTS `notification_management`;
+CREATE TABLE `notification_management`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閫氱煡鏍囬',
+  `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閫氱煡绫诲瀷',
+  `priority` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浼樺厛绾�',
+  `expire_date` datetime NULL DEFAULT NULL COMMENT '鏈夋晥鏈熸椂闂�',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐘舵��',
+  `departments` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎺ユ敹閮ㄩ棬',
+  `sync_methods` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍚屾鏂瑰紡',
+  `content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閫氱煡鍐呭',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '琛屾斂绠$悊-閫氱煡绠$悊' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for office_supplies
+-- ----------------------------
+DROP TABLE IF EXISTS `office_supplies`;
+CREATE TABLE `office_supplies`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '娉ㄨВ',
+  `code` varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '缂栧彿',
+  `applicant` varchar(15) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鐢宠浜�',
+  `item_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鐗╁搧鍚嶇О',
+  `dept` varchar(15) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '閮ㄩ棬',
+  `material_type` int NULL DEFAULT NULL COMMENT '鐗╄祫绫诲瀷锛�1-鍏朵粬 2-娓呮磥鐢ㄥ搧 3-鐢靛瓙鐢ㄥ搧 4-鐢靛瓙璁惧锛�',
+  `apply_num` int NULL DEFAULT NULL COMMENT '鐢宠鏁伴噺',
+  `approval_opinions` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '瀹℃壒鎰忚',
+  `reason` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鐢宠鍘熷洜',
+  `urgency` int NULL DEFAULT NULL COMMENT '绱ф�ョ▼搴︼紙1-鏅�� 2-绱ф�� 3-闈炲父绱ф�ワ級',
+  `status` int NULL DEFAULT NULL COMMENT '鐘舵�侊紙1-寰呭鎵� 2-宸叉嫆缁� 3-宸查�氳繃 4-宸插彂鏀撅級',
+  `apply_time` datetime NULL DEFAULT NULL COMMENT '鐢宠鏃堕棿',
+  `approval` varchar(15) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '瀹℃壒浜�',
+  `approval_time` datetime NULL DEFAULT NULL COMMENT '瀹℃壒鏃堕棿',
+  `issue_user` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '鍙戞斁浜�',
+  `issue_time` datetime NULL DEFAULT NULL COMMENT '鍙戞斁鏃堕棿',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for online_meeting
+-- ----------------------------
+DROP TABLE IF EXISTS `online_meeting`;
+CREATE TABLE `online_meeting`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浼氳鏍囬',
+  `start_time` datetime NULL DEFAULT NULL COMMENT '寮�濮嬫椂闂�',
+  `duration` int NULL DEFAULT NULL COMMENT '浼氳鏃堕暱',
+  `platform` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浼氳骞冲彴',
+  `participants` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍙備細浜哄憳',
+  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浼氳鎻忚堪',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '琛屾斂绠$悊-閫氱煡绠$悊-鍦ㄧ嚎浼氳' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for overtime_setting
+-- ----------------------------
+DROP TABLE IF EXISTS `overtime_setting`;
+CREATE TABLE `overtime_setting`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍔犵彮瑙勫垯鍚嶇О',
+  `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍔犵彮绫诲瀷',
+  `start_time` time NULL DEFAULT NULL COMMENT '寮�濮嬫椂闂�',
+  `end_time` time NULL DEFAULT NULL COMMENT '缁撴潫鏃堕棿',
+  `rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍊嶇巼',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐘舵��',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍔犵彮璁剧疆' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for payment_registration
+-- ----------------------------
+DROP TABLE IF EXISTS `payment_registration`;
+CREATE TABLE `payment_registration`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `sale_ledger_id` bigint NULL DEFAULT 0 COMMENT '閿�鍞彴璐d',
+  `sales_ledger_product_id` int NULL DEFAULT NULL COMMENT '閿�鍞骇鍝乮d',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `purchase_ledger_id` bigint NOT NULL DEFAULT 0 COMMENT '閲囪喘鍙拌处id',
+  `supplier_id` bigint NOT NULL DEFAULT 0 COMMENT '渚涘簲鍟唅d',
+  `ticket_registration_id` bigint NOT NULL DEFAULT 0 COMMENT '鍙戠エid',
+  `current_payment_amount` decimal(12, 2) NOT NULL COMMENT '鏈浠樻閲戦',
+  `payment_method` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浠樻褰㈠紡',
+  `registrant_id` bigint NOT NULL DEFAULT 0 COMMENT '鐧昏浜�',
+  `payment_date` date NOT NULL COMMENT '浠樻鏃ユ湡',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `registrationt_date` date NULL DEFAULT NULL COMMENT '鐧昏鏃ユ湡',
+  `tax_rate` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绋庣巼',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 45 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浠樻鐧昏琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for pda_version
+-- ----------------------------
+DROP TABLE IF EXISTS `pda_version`;
+CREATE TABLE `pda_version`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍚嶇О',
+  `version` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐗堟湰',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `update_user` int NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'PDA鐗堟湰淇℃伅琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for personal_attendance_location_config
+-- ----------------------------
+DROP TABLE IF EXISTS `personal_attendance_location_config`;
+CREATE TABLE `personal_attendance_location_config`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `sys_dept_id` int NOT NULL DEFAULT 0 COMMENT '閮ㄩ棬id',
+  `location_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍦扮偣鍚嶇О',
+  `longitude` double NULL DEFAULT NULL COMMENT '缁忓害',
+  `latitude` double NULL DEFAULT NULL COMMENT '绾害',
+  `radius` double NULL DEFAULT NULL COMMENT '鎵撳崱鑼冨洿',
+  `start_at` time NULL DEFAULT NULL COMMENT '涓婄彮鏃堕棿',
+  `end_at` time NULL DEFAULT NULL COMMENT '涓嬬彮鏃堕棿',
+  `shift` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐝',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE INDEX `shift`(`shift` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浜哄憳鎵撳崱瑙勫垯閰嶇疆' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for personal_attendance_records
+-- ----------------------------
+DROP TABLE IF EXISTS `personal_attendance_records`;
+CREATE TABLE `personal_attendance_records`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `staff_on_job_id` bigint NOT NULL DEFAULT 0 COMMENT '鍛樺伐鍦ㄨ亴id',
+  `date` date NOT NULL COMMENT '鏃ユ湡',
+  `work_start_at` datetime NULL DEFAULT NULL COMMENT '宸ヤ綔寮�濮嬫椂闂�',
+  `work_end_at` datetime NULL DEFAULT NULL COMMENT '宸ヤ綔缁撴潫鏃堕棿',
+  `work_hours` decimal(5, 2) NULL DEFAULT NULL COMMENT '宸ヤ綔鏃堕暱',
+  `status` tinyint NOT NULL DEFAULT 0 COMMENT '鐘舵�� 0姝e父 1杩熷埌 2鏃╅��',
+  `remark` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '澶囨敞',
+  `tenant_id` bigint NOT NULL COMMENT '绉熸埛id',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 65 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '涓汉鑰冨嫟璁板綍琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for personal_shift
+-- ----------------------------
+DROP TABLE IF EXISTS `personal_shift`;
+CREATE TABLE `personal_shift`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `personal_attendance_location_config_id` int NULL DEFAULT NULL COMMENT '鐝(鎵撳崱瑙勫垯id)',
+  `staff_on_job_id` bigint NOT NULL DEFAULT 0 COMMENT '鍛樺伐鍦ㄨ亴id',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `work_time` datetime NULL DEFAULT NULL COMMENT '鎺掔彮鏃ユ湡',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 123 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for procurement_exception_record
+-- ----------------------------
+DROP TABLE IF EXISTS `procurement_exception_record`;
+CREATE TABLE `procurement_exception_record`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `purchase_ledger_id` int NOT NULL COMMENT '閲囪喘鍙拌处id',
+  `exception_reason` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '寮傚父鍘熷洜',
+  `exception_num` decimal(18, 2) NULL DEFAULT NULL COMMENT '寮傚父鏁伴噺',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰卛d',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鑰卛d',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '閲囪喘寮傚父璁板綍-涓嶅悎鏍肩墿鍝�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for procurement_plan
+-- ----------------------------
+DROP TABLE IF EXISTS `procurement_plan`;
+CREATE TABLE `procurement_plan`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `code` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '缂栫爜',
+  `plan_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鍚嶇О',
+  `description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鎻忚堪',
+  `status` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鐘舵��',
+  `is_system_preset` tinyint(1) NULL DEFAULT NULL COMMENT '鏄惁绯荤粺棰勭疆',
+  `consider_existing_stock` tinyint(1) NULL DEFAULT NULL,
+  `warehouse_control` tinyint(1) NULL DEFAULT NULL,
+  `calculate_total_demand` tinyint(1) NULL DEFAULT NULL,
+  `consider_safety_stock` tinyint(1) NULL DEFAULT NULL,
+  `consider_locked_stock` tinyint(1) NULL DEFAULT NULL,
+  `not_consider_material_aux` tinyint(1) NULL DEFAULT NULL,
+  `negative_stock_as_demand` tinyint(1) NULL DEFAULT NULL,
+  `summary_material` tinyint(1) NULL DEFAULT NULL,
+  `summary_aux_attributes` tinyint(1) NULL DEFAULT NULL,
+  `summary_demand_date` tinyint(1) NULL DEFAULT NULL,
+  `formula` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '璁$畻鍏紡',
+  `create_time` datetime NULL DEFAULT NULL,
+  `create_user` int NULL DEFAULT NULL,
+  `update_time` datetime NULL DEFAULT NULL,
+  `update_user` int NULL DEFAULT NULL,
+  `tenant_id` int NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_bin COMMENT = '閲囪喘璁″垝琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for procurement_price_management
+-- ----------------------------
+DROP TABLE IF EXISTS `procurement_price_management`;
+CREATE TABLE `procurement_price_management`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `product_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鍟嗗搧鍚嶇О',
+  `specification` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '瑙勬牸鍨嬪彿',
+  `product_code` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鍟嗗搧缂栫爜',
+  `supplier_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '渚涘簲鍟�',
+  `base_price` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍩虹浠锋牸',
+  `unit` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `discount_type` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鎶樻墸绫诲瀷',
+  `discount_value` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鎶樻墸鍊�',
+  `discount_end_time` datetime NULL DEFAULT NULL COMMENT '鎶樻墸鏈夋晥鏈�',
+  `min_price` decimal(10, 2) NULL DEFAULT NULL COMMENT '鏈�浣庝环鏍�',
+  `max_price` decimal(10, 2) NULL DEFAULT NULL COMMENT '鏈�楂樹环鏍�',
+  `warning_threshold` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '棰勮闃堝��(%)',
+  `effective_time` datetime NULL DEFAULT NULL COMMENT '鐢熸晥鏃堕棿',
+  `expire_time` datetime NULL DEFAULT NULL COMMENT '澶辨晥鏃堕棿',
+  `reason` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '璋冧环鍘熷洜',
+  `remark` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_bin COMMENT = '閲囪喘浠锋牸绠$悊' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for procurement_record_out
+-- ----------------------------
+DROP TABLE IF EXISTS `procurement_record_out`;
+CREATE TABLE `procurement_record_out`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `sales_ledger_product_id` int NOT NULL DEFAULT 0 COMMENT '浜у搧淇℃伅琛╥d',
+  `procurement_record_storage_id` int NOT NULL COMMENT '鍏ュ簱璁板綍琛╥d',
+  `inbound_batches` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍑哄簱鎵规',
+  `inbound_num` decimal(18, 2) NULL DEFAULT NULL COMMENT '鍑哄簱鏁伴噺',
+  `create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍑哄簱鐢ㄦ埛鍚嶇О',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓鑰卛d',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鑰卛d',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `code` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '缂栧彿',
+  `type` int NULL DEFAULT NULL,
+  `product_model_id` bigint NULL DEFAULT NULL COMMENT '浜у搧瑙勬牸id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '閲囪喘鍑哄簱璁板綍' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for procurement_record_storage
+-- ----------------------------
+DROP TABLE IF EXISTS `procurement_record_storage`;
+CREATE TABLE `procurement_record_storage`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `sales_ledger_product_id` int NOT NULL COMMENT '浜у搧淇℃伅琛╥d',
+  `inbound_batches` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍏ュ簱鎵规',
+  `total_price` decimal(10, 2) NULL DEFAULT NULL COMMENT '鎬讳环',
+  `unit_price` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍗曚环',
+  `inbound_num` decimal(18, 2) NULL DEFAULT NULL COMMENT '鍏ュ簱鏁伴噺',
+  `create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍏ュ簱鐢ㄦ埛鍚嶇О',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰卛d',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鑰卛d',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `warn_num` decimal(10, 2) NULL DEFAULT NULL,
+  `type` int NULL DEFAULT 1,
+  `product_model_id` bigint NULL DEFAULT NULL COMMENT '浜у搧瑙勬牸id',
+  `quality_inspect_id` bigint NULL DEFAULT NULL COMMENT '璐ㄦid',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '閲囪喘鍏ュ簱璁板綍' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for product
+-- ----------------------------
+DROP TABLE IF EXISTS `product`;
+CREATE TABLE `product`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `parent_id` int NULL DEFAULT NULL COMMENT '鐖秈d',
+  `product_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浜у搧',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 409 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浜у搧' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for product_borrow
+-- ----------------------------
+DROP TABLE IF EXISTS `product_borrow`;
+CREATE TABLE `product_borrow`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `borrow_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '棰嗙敤鍗曞彿',
+  `product_model_id` bigint NOT NULL COMMENT '浜у搧瑙勬牸ID',
+  `batch_no` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎵瑰彿',
+  `borrow_quantity` decimal(18, 4) NOT NULL COMMENT '棰嗙敤鏁伴噺',
+  `returned_quantity` decimal(18, 4) NULL DEFAULT 0.0000 COMMENT '宸插綊杩樻暟閲�',
+  `borrower_id` bigint NULL DEFAULT NULL COMMENT '棰嗙敤浜篒D',
+  `borrower_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '棰嗙敤浜哄鍚�',
+  `borrow_time` datetime NOT NULL COMMENT '棰嗙敤鏃堕棿',
+  `expected_return_time` datetime NULL DEFAULT NULL COMMENT '棰勮褰掕繕鏃堕棿',
+  `approval_status` tinyint NULL DEFAULT 0 COMMENT '瀹℃壒鐘舵�侊紙0-寰呭鎵癸紝1-宸查�氳繃锛�2-宸查┏鍥烇級',
+  `status` tinyint NULL DEFAULT 0 COMMENT '褰掕繕鐘舵�侊紙0-鏈綊杩橈紝1-閮ㄥ垎褰掕繕锛�2-宸插叏閮ㄥ綊杩橈級',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_borrow_no`(`borrow_no` ASC) USING BTREE,
+  INDEX `idx_product_model_id`(`product_model_id` ASC) USING BTREE,
+  INDEX `idx_borrower_id`(`borrower_id` ASC) USING BTREE,
+  INDEX `idx_approval_status`(`approval_status` ASC) USING BTREE,
+  INDEX `idx_status`(`status` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浜у搧棰嗙敤琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for product_borrow_return
+-- ----------------------------
+DROP TABLE IF EXISTS `product_borrow_return`;
+CREATE TABLE `product_borrow_return`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `borrow_id` bigint NOT NULL COMMENT '棰嗙敤璁板綍ID',
+  `product_model_id` bigint NOT NULL COMMENT '浜у搧瑙勬牸ID',
+  `batch_no` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎵瑰彿',
+  `return_quantity` decimal(18, 4) NOT NULL COMMENT '褰掕繕鏁伴噺',
+  `returner_id` bigint NULL DEFAULT NULL COMMENT '褰掕繕浜篒D',
+  `returner_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '褰掕繕浜哄鍚�',
+  `return_time` datetime NOT NULL COMMENT '褰掕繕鏃堕棿',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_borrow_id`(`borrow_id` ASC) USING BTREE,
+  INDEX `idx_product_model_id`(`product_model_id` ASC) USING BTREE,
+  INDEX `idx_returner_id`(`returner_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浜у搧褰掕繕璁板綍琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for product_model
+-- ----------------------------
+DROP TABLE IF EXISTS `product_model`;
+CREATE TABLE `product_model`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `product_id` int NULL DEFAULT NULL COMMENT '鍏宠仈浜у搧id',
+  `model` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瑙勬牸淇″彿',
+  `unit` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `product_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 386 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浜у搧鍨嬪彿琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for product_record
+-- ----------------------------
+DROP TABLE IF EXISTS `product_record`;
+CREATE TABLE `product_record`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `ticket_registration_id` int NULL DEFAULT NULL COMMENT '鏉ョエ鐧昏id',
+  `purchase_ledger_id` int NULL DEFAULT NULL COMMENT '閲囪喘鍙拌处id',
+  `product_category` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浜у搧澶х被',
+  `specification_model` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瑙勬牸鍨嬪彿',
+  `unit` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `quantity` decimal(18, 0) NOT NULL COMMENT '鏁伴噺',
+  `tax_rate` decimal(5, 0) NOT NULL COMMENT '绋庣巼',
+  `tax_inclusive_unit_price` decimal(18, 2) NOT NULL COMMENT '鍚◣鍗曚环',
+  `tax_inclusive_total_price` decimal(18, 2) NOT NULL COMMENT '鍚◣鎬讳环',
+  `tax_exclusive_total_price` decimal(18, 2) NOT NULL COMMENT '涓嶅惈绋庢�讳环',
+  `invoice_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍙戠エ绫诲瀷',
+  `type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '1.閿�鍞彴璐︼紝2.閲囪喘鍙拌处',
+  `tickets_num` decimal(10, 2) NULL DEFAULT NULL COMMENT '鏈鏉ョエ鏁�',
+  `tickets_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '鏈鏉ョエ閲戦(鍏�)',
+  `future_tickets` decimal(10, 2) NULL DEFAULT NULL COMMENT '鏈潵绁ㄦ暟',
+  `future_tickets_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '鏈潵绁ㄩ噾棰�(鍏�)',
+  `product_id` int NULL DEFAULT NULL COMMENT '浜у搧id',
+  `product_model_id` int NULL DEFAULT NULL COMMENT '鍨嬪彿id',
+  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `sale_ledger_project_id` int NULL DEFAULT NULL COMMENT 'sale_ledger_projectI_id',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '閲囪喘鍙拌处浜у搧寮�绁ㄨ褰�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for production_account
+-- ----------------------------
+DROP TABLE IF EXISTS `production_account`;
+CREATE TABLE `production_account`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `sales_ledger_id` bigint NULL DEFAULT NULL COMMENT '閿�鍞彴璐d',
+  `sales_ledger_product_id` bigint NULL DEFAULT NULL COMMENT '閿�鍞骇鍝佽鏍糹d',
+  `production_product_main_id` bigint NULL DEFAULT NULL COMMENT '鎶ュ伐琛╥d',
+  `scheduling_user_id` bigint NULL DEFAULT NULL COMMENT '鐢熶骇浜篿d',
+  `scheduling_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '鐢熶骇浜哄悕绉�',
+  `finished_num` decimal(18, 2) NULL DEFAULT 0.00 COMMENT '鐢熶骇鏁伴噺',
+  `work_hours` decimal(18, 2) NULL DEFAULT 0.00 COMMENT '宸ユ椂瀹氶',
+  `technology_operation_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '宸ュ簭鍚嶇О',
+  `scheduling_date` timestamp NULL DEFAULT NULL COMMENT '鐢熶骇鏃ユ湡',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 42 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '鐢熶骇鏍哥畻琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for production_bom_structure
+-- ----------------------------
+DROP TABLE IF EXISTS `production_bom_structure`;
+CREATE TABLE `production_bom_structure`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `parent_id` bigint NULL DEFAULT NULL COMMENT '鐖惰妭鐐笽D',
+  `production_order_id` bigint NULL DEFAULT NULL COMMENT '鐢熶骇璁㈠崟id',
+  `product_model_id` bigint NOT NULL COMMENT '浜у搧瑙勬牸id',
+  `technology_operation_id` bigint NULL DEFAULT NULL COMMENT '宸ュ簭id',
+  `production_order_bom_id` bigint NULL DEFAULT NULL COMMENT '鐢熶骇璁㈠崟BOMid',
+  `unit_quantity` decimal(16, 4) NOT NULL COMMENT '鍗曚綅浜у嚭闇�瑕佹暟閲�',
+  `demanded_quantity` decimal(16, 4) NULL DEFAULT NULL COMMENT '闇�姹傛暟閲�',
+  `unit` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 327 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢熶骇璁㈠崟BOM浜у搧缁撴瀯' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for production_operation_main_param
+-- ----------------------------
+DROP TABLE IF EXISTS `production_operation_main_param`;
+CREATE TABLE `production_operation_main_param`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `technology_routing_operation_param_id` bigint NOT NULL COMMENT '宸ヨ壓璺嚎宸ュ簭鍙傛暟琛╥d',
+  `param_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '鍙傛暟缂栫爜(鍞竴鏍囪瘑)',
+  `param_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '鍙傛暟鍚嶇О',
+  `param_type` tinyint NOT NULL COMMENT '鍙傛暟绫诲瀷(1鏁板瓧 2鏂囨湰 3涓嬫媺閫夋嫨 4鏃堕棿)',
+  `param_format` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍙傛暟鏍煎紡',
+  `unit` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `is_required` tinyint NULL DEFAULT 0 COMMENT '鏄惁蹇呭~',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `technology_param_id` bigint NULL DEFAULT NULL COMMENT '鍩虹鍙傛暟ID',
+  `technology_operation_id` bigint NULL DEFAULT NULL COMMENT '宸ュ簭id',
+  `technology_operation_param_id` bigint NULL DEFAULT NULL COMMENT '宸ュ簭鍙傛暟ID',
+  `technology_routing_operation_id` bigint NULL DEFAULT NULL COMMENT '宸ヨ壓璺嚎宸ュ簭ID',
+  `standard_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鏍囧噯鍊�',
+  `value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '杈撳叆鍊�',
+  `production_order_routing_operation_param_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鐢熶骇璁㈠崟宸ヨ壓璺嚎宸ュ簭鍙傛暟ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '鐢熶骇宸ュ崟鎶ュ伐鍙傛暟琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for production_operation_task
+-- ----------------------------
+DROP TABLE IF EXISTS `production_operation_task`;
+CREATE TABLE `production_operation_task`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `production_order_routing_operation_id` bigint NOT NULL DEFAULT 0 COMMENT '鐢熶骇宸ヨ壓璺嚎宸ュ簭琛╥d',
+  `technology_routing_operation_id` bigint NOT NULL DEFAULT 0 COMMENT '宸ヨ壓璺嚎宸ュ簭琛╥d',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `work_order_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '宸ュ崟缂栧彿',
+  `plan_start_time` date NULL DEFAULT NULL COMMENT '璁″垝寮�濮嬫椂闂�',
+  `plan_end_time` date NULL DEFAULT NULL COMMENT '璁″垝缁撴潫鏃堕棿',
+  `actual_start_time` date NULL DEFAULT NULL COMMENT '瀹為檯寮�濮嬫椂闂�',
+  `actual_end_time` date NULL DEFAULT NULL COMMENT '瀹為檯缁撴潫鏃堕棿',
+  `status` int NOT NULL DEFAULT 0 COMMENT '鐘舵�� 1 寰呯‘璁� 2 寰呯敓浜� 3鐢熶骇涓� 4宸茬敓浜�',
+  `production_order_id` bigint NOT NULL DEFAULT 0 COMMENT '鐢熶骇璁㈠崟id',
+  `plan_quantity` decimal(16, 4) NULL DEFAULT NULL COMMENT '璁″垝鏁伴噺',
+  `complete_quantity` decimal(18, 2) NULL DEFAULT 0.00 COMMENT '瀹屾垚鏁伴噺',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `user_ids` json NULL COMMENT '鏉冮檺鐢ㄦ埛锛屾牸寮忥細[1,2,3]',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 238 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '鐢熶骇宸ュ崟琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for production_order
+-- ----------------------------
+DROP TABLE IF EXISTS `production_order`;
+CREATE TABLE `production_order`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `production_plan_ids` json NULL COMMENT '鐢熶骇璁″垝ID鍒楄〃锛屾牸寮忥細[1,2,3]',
+  `product_model_id` bigint NOT NULL DEFAULT 0 COMMENT '浜у搧瑙勬牸id',
+  `technology_routing_id` bigint NOT NULL DEFAULT 0 COMMENT '宸ヨ壓璺嚎id',
+  `nps_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '鐢熶骇璁㈠崟鍙�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `quantity` decimal(18, 2) NOT NULL COMMENT '闇�姹傛暟閲�',
+  `complete_quantity` decimal(18, 2) NULL DEFAULT NULL COMMENT '瀹屾垚鏁伴噺',
+  `start_time` datetime NULL DEFAULT NULL COMMENT '寮�濮嬫棩鏈�',
+  `end_time` datetime NULL DEFAULT NULL COMMENT '缁撴潫鏃ユ湡',
+  `plan_complete_time` date NULL DEFAULT NULL COMMENT '璁″垝瀹屾垚鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `status` int NULL DEFAULT 1 COMMENT '鐘舵�侊紙1.寰呭紑濮嬨��2.杩涜涓��3.宸插畬鎴愩��4.宸插彇娑堬級',
+  `is_end_order` tinyint(1) NULL DEFAULT 0 COMMENT '鏄惁缁撴潫',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 64 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢熶骇璁㈠崟琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for production_order_bom
+-- ----------------------------
+DROP TABLE IF EXISTS `production_order_bom`;
+CREATE TABLE `production_order_bom`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `production_order_id` bigint NULL DEFAULT NULL COMMENT '鐢熶骇璁㈠崟id',
+  `product_model_id` bigint NOT NULL COMMENT '浜у搧瑙勬牸id',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `version` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐗堟湰鍙�',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `bom_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'BOM缂栧彿',
+  `bom_id` bigint NOT NULL COMMENT 'bom鐨刬d',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 75 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢熶骇璁㈠崟BOM' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for production_order_pick
+-- ----------------------------
+DROP TABLE IF EXISTS `production_order_pick`;
+CREATE TABLE `production_order_pick`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭id',
+  `product_model_id` int NULL DEFAULT NULL COMMENT '浜у搧瑙勬牸id',
+  `quantity` decimal(16, 2) NULL DEFAULT NULL COMMENT '鏁伴噺',
+  `batch_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎵瑰彿',
+  `create_time` timestamp NULL DEFAULT NULL,
+  `update_time` timestamp NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `production_order_id` bigint NOT NULL DEFAULT 0 COMMENT '鐢熶骇璁㈠崟id',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `operation_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宸ュ簭鍚嶇О',
+  `technology_operation_id` bigint NULL DEFAULT NULL COMMENT '宸ュ簭id\r\n',
+  `demanded_quantity` decimal(16, 2) NULL DEFAULT NULL COMMENT '闇�姹傛暟閲�',
+  `is_bom` tinyint(1) NULL DEFAULT NULL COMMENT '鏄惁bom棰嗘枡',
+  `is_returned` tinyint(1) NULL DEFAULT 0 COMMENT '鏄惁宸查��鏂�',
+  `feeding_qty` decimal(20, 2) NULL DEFAULT NULL COMMENT '琛ユ枡鎬婚噺',
+  `return_qty` decimal(20, 2) NULL DEFAULT NULL COMMENT '閫�鏂欐暟閲�',
+  `actual_qty` decimal(20, 2) NULL DEFAULT NULL COMMENT '瀹為檯鏁伴噺',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 81 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '璁㈠崟棰嗘枡绾胯竟浠�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for production_order_pick_record
+-- ----------------------------
+DROP TABLE IF EXISTS `production_order_pick_record`;
+CREATE TABLE `production_order_pick_record`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭id',
+  `pick_id` bigint NOT NULL DEFAULT 0 COMMENT '鍏宠仈棰嗘枡鍗昳d锛坧roduction_order_pick.id锛�',
+  `production_order_id` bigint NULL DEFAULT 0 COMMENT '鐢熶骇璁㈠崟id',
+  `production_operation_task_id` bigint NULL DEFAULT 0 COMMENT '鐢熶骇宸ュ崟id',
+  `product_model_id` int NULL DEFAULT NULL COMMENT '浜у搧瑙勬牸id',
+  `batch_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎵瑰彿',
+  `pick_quantity` decimal(16, 4) NULL DEFAULT NULL COMMENT '棰嗘枡鏁伴噺',
+  `before_quantity` decimal(16, 4) NULL DEFAULT NULL COMMENT '棰嗘枡鍓嶆暟閲�',
+  `after_quantity` decimal(16, 4) NULL DEFAULT NULL COMMENT '棰嗘枡鍚庡墿浣欐暟閲�',
+  `pick_type` tinyint NULL DEFAULT 1 COMMENT '棰嗘枡绫诲瀷锛�1姝e父棰嗘枡  2琛ユ枡',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `feeding_reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '琛ユ枡鍘熷洜',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_pick_id`(`pick_id` ASC) USING BTREE,
+  INDEX `idx_production_order_id`(`production_order_id` ASC) USING BTREE,
+  INDEX `idx_batch_no`(`batch_no` ASC) USING BTREE,
+  INDEX `idx_create_time`(`create_time` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 105 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '绾胯竟浠撳嚭鍏ュ簱璁板綍' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for production_order_routing
+-- ----------------------------
+DROP TABLE IF EXISTS `production_order_routing`;
+CREATE TABLE `production_order_routing`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `product_model_id` bigint NOT NULL DEFAULT 0 COMMENT '浜у搧瑙勬牸id',
+  `production_order_id` bigint NOT NULL DEFAULT 0 COMMENT '鐢熶骇璁㈠崟id',
+  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '鎻忚堪',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `technology_routing_id` bigint NOT NULL DEFAULT 0 COMMENT '宸ヨ壓璺嚎id',
+  `process_route_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宸ヨ壓璺嚎缂栫爜',
+  `bom_id` int NULL DEFAULT NULL COMMENT '鍏宠仈bom鐨刬d',
+  `order_bom_id` int NULL DEFAULT NULL COMMENT '鍏宠仈璁㈠崟bom鐨刬d',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 74 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢熶骇璁㈠崟宸ヨ壓璺嚎琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for production_order_routing_operation
+-- ----------------------------
+DROP TABLE IF EXISTS `production_order_routing_operation`;
+CREATE TABLE `production_order_routing_operation`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `production_order_id` bigint NOT NULL DEFAULT 0 COMMENT '鐢熶骇璁㈠崟id',
+  `technology_routing_operation_id` bigint NULL DEFAULT NULL COMMENT '宸ヨ壓璺嚎宸ュ簭琛╥d',
+  `technology_operation_id` bigint NULL DEFAULT NULL COMMENT '宸ュ簭琛╥d',
+  `order_routing_id` int NULL DEFAULT NULL COMMENT '鍏宠仈璁㈠崟宸ヨ壓璺嚎鐨刬d',
+  `operation_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '宸ュ簭鍚嶇О',
+  `product_model_id` bigint NOT NULL DEFAULT 0 COMMENT '浜у搧瑙勬牸id',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `drag_sort` int NULL DEFAULT NULL COMMENT '鎷栧姩鎺掑簭',
+  `is_quality` tinyint(1) NULL DEFAULT 1 COMMENT '鏄惁璐ㄦ宸ュ簭',
+  `is_production` tinyint(1) NULL DEFAULT 1 COMMENT '鏄惁鐢熶骇',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `type` int NULL DEFAULT NULL COMMENT '绫诲瀷 鍖哄垎璁℃椂鍜岃浠�(0璁℃椂1璁′欢)',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 260 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢熶骇璁㈠崟宸ヨ壓璺嚎宸ュ簭琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for production_order_routing_operation_param
+-- ----------------------------
+DROP TABLE IF EXISTS `production_order_routing_operation_param`;
+CREATE TABLE `production_order_routing_operation_param`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `production_order_id` bigint NULL DEFAULT NULL COMMENT '鐢熶骇璁㈠崟id',
+  `technology_routing_operation_param_id` bigint NULL DEFAULT NULL COMMENT '宸ヨ壓璺嚎宸ュ簭鍙傛暟琛╥d',
+  `param_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '鍙傛暟缂栫爜(鍞竴鏍囪瘑)',
+  `param_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '鍙傛暟鍚嶇О',
+  `param_type` tinyint NOT NULL COMMENT '鍙傛暟绫诲瀷(1鏁板瓧 2鏂囨湰 3涓嬫媺閫夋嫨 4鏃堕棿)',
+  `param_format` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍙傛暟鏍煎紡',
+  `unit` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `is_required` tinyint NULL DEFAULT 0 COMMENT '鏄惁蹇呭~',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `param_id` bigint NULL DEFAULT NULL COMMENT '鍩虹鍙傛暟ID',
+  `technology_operation_id` bigint NULL DEFAULT NULL COMMENT '宸ュ簭id',
+  `technology_operation_param_id` bigint NULL DEFAULT NULL COMMENT '宸ュ簭鍙傛暟ID',
+  `production_order_routing_operation_id` bigint NOT NULL COMMENT '鐢熶骇璁㈠崟宸ヨ壓璺嚎宸ュ簭ID',
+  `standard_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鏍囧噯鍊�',
+  `input_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '杈撳叆鍊�',
+  `production_product_main_id` bigint NULL DEFAULT NULL COMMENT '鎶ュ伐id',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 334 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '鐢熶骇璁㈠崟宸ヨ壓璺嚎宸ュ簭鍙傛暟琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for production_plan
+-- ----------------------------
+DROP TABLE IF EXISTS `production_plan`;
+CREATE TABLE `production_plan`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `sales_ledger_id` bigint NULL DEFAULT 0 COMMENT '閿�鍞彴璐d',
+  `sales_ledger_product_id` bigint NULL DEFAULT NULL COMMENT '閿�鍞骇鍝佽鏍糹d',
+  `mps_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '涓荤敓浜ц鍒掑彿',
+  `required_date` datetime(6) NULL DEFAULT NULL COMMENT '闇�姹傛棩鏈�',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_time` datetime(6) NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_time` datetime(6) NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `product_model_id` bigint NULL DEFAULT NULL COMMENT '浜у搧鍨嬪彿id',
+  `qty_required` decimal(12, 6) NULL DEFAULT NULL COMMENT '闇�姹傛暟閲�',
+  `status` int NULL DEFAULT NULL COMMENT '鐘舵�� 0鏈笅鍙� 1閮ㄥ垎涓嬪彂 2宸蹭笅鍙�',
+  `source` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏉ユ簮',
+  `promised_delivery_date` datetime(6) NULL DEFAULT NULL COMMENT '鎵胯鏃ユ湡',
+  `quantity_issued` decimal(12, 6) NULL DEFAULT NULL COMMENT '宸蹭笅鍙戞暟閲�',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 70 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢熶骇璁″垝琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for production_product_input
+-- ----------------------------
+DROP TABLE IF EXISTS `production_product_input`;
+CREATE TABLE `production_product_input`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `input_quantity` decimal(18, 6) NOT NULL COMMENT '鎶曞叆鏁伴噺',
+  `production_product_main_id` bigint NOT NULL COMMENT '鎶ュ伐琛╥d',
+  `product_model_id` bigint NULL DEFAULT NULL COMMENT '浜у搧鍨嬪彿id',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊鐢ㄦ埛',
+  `product_main_id` bigint NULL DEFAULT NULL COMMENT '鐢熶骇鎶ュ伐琛╥d',
+  `quantity` decimal(18, 2) NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_product_main_id`(`production_product_main_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 52 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢熶骇鎶ュ伐鎶曞叆琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for production_product_main
+-- ----------------------------
+DROP TABLE IF EXISTS `production_product_main`;
+CREATE TABLE `production_product_main`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `product_no` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎶ュ伐鍗曞彿',
+  `user_id` bigint NULL DEFAULT NULL COMMENT '鎶ュ伐浜哄憳id',
+  `user_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎶ュ伐浜哄憳',
+  `production_operation_task_id` bigint NULL DEFAULT NULL COMMENT '宸ュ崟id',
+  `status` int NULL DEFAULT NULL COMMENT '鎶ュ伐鐘舵��',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊鐢ㄦ埛',
+  `work_hour` decimal(10, 2) NULL DEFAULT NULL COMMENT '宸ユ椂',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 45 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢熶骇鎶ュ伐琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for production_product_output
+-- ----------------------------
+DROP TABLE IF EXISTS `production_product_output`;
+CREATE TABLE `production_product_output`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `production_product_main_id` bigint NOT NULL COMMENT '鎶ュ伐鍗昳d',
+  `product_model_id` bigint NOT NULL COMMENT '浜у搧瑙勬牸id',
+  `quantity` decimal(16, 4) NOT NULL DEFAULT 0.0000 COMMENT '鎶ュ伐鏁伴噺',
+  `scrap_qty` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '鎶ュ簾鏁伴噺',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊鐢ㄦ埛',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `product_main_id` bigint NULL DEFAULT NULL COMMENT '鐢熶骇鎶ュ伐琛╥d',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 45 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢熶骇鎶ュ伐浜у嚭琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for project_management_contract_info
+-- ----------------------------
+DROP TABLE IF EXISTS `project_management_contract_info`;
+CREATE TABLE `project_management_contract_info`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍚嶇О',
+  `sex` varchar(25) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎬у埆',
+  `birthday` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐢熸棩',
+  `department` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閮ㄩ棬',
+  `job` varchar(25) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鑱屽姟',
+  `phone_number` varchar(25) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎵嬫満鍙�',
+  `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閭',
+  `qq` varchar(25) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'QQ',
+  `linea_fissa` varchar(25) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍥哄畾鍙风爜',
+  `wx` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '寰俊',
+  `origine_etnica` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绫嶈疮',
+  `rappresentante_legale` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '娉曚汉浠h〃',
+  `project_management_info_id` bigint NULL DEFAULT NULL COMMENT '瀵瑰簲椤圭洰绠$悊淇℃伅id',
+  `is_delete` int NOT NULL DEFAULT 0,
+  `create_user` bigint NULL DEFAULT NULL,
+  `update_user` bigint NULL DEFAULT NULL,
+  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `update_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `create_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '椤圭洰鑱旂郴淇℃伅' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for project_management_info
+-- ----------------------------
+DROP TABLE IF EXISTS `project_management_info`;
+CREATE TABLE `project_management_info`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '椤圭洰缂栧彿',
+  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '涓婚',
+  `client_id` bigint NULL DEFAULT NULL COMMENT '瀹㈡埛id',
+  `client_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹㈡埛鍚嶇О',
+  `project_management_info_parent_id` bigint NULL DEFAULT NULL COMMENT '绱㈠紩鐨勭埗椤圭洰id',
+  `establish_time` date NULL DEFAULT NULL COMMENT '绔嬮」鏃堕棿',
+  `project_management_plan_id` bigint NOT NULL COMMENT '椤圭洰闃舵id',
+  `source` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏉ユ簮',
+  `manager_id` bigint NULL DEFAULT NULL COMMENT '椤圭洰缁忕悊id',
+  `manager_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '椤圭洰缁忕悊鍚嶅瓧',
+  `salesman_id` bigint NULL DEFAULT NULL COMMENT '涓氬姟鍛榠d',
+  `salesman_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '涓氬姟鍛樺悕瀛�',
+  `is_delete` int NOT NULL DEFAULT 0,
+  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `create_user` int NULL DEFAULT NULL,
+  `update_user` int NULL DEFAULT NULL,
+  `plan_start_time` date NULL DEFAULT NULL COMMENT '璁″垝寮�濮嬫椂闂�',
+  `plan_end_time` date NULL DEFAULT NULL COMMENT '璁″垝缁撴潫鏃堕棿',
+  `actual_start_time` date NULL DEFAULT NULL COMMENT '瀹為檯寮�濮嬫椂闂�',
+  `actual_end_time` date NULL DEFAULT NULL COMMENT '瀹為檯缁撴潫鏃ユ湡',
+  `review_status` int NULL DEFAULT NULL COMMENT '瀹℃牳鐘舵��',
+  `status` int NULL DEFAULT NULL COMMENT '椤圭洰鐘舵��',
+  `department_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬id',
+  `department_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閮ㄩ棬鍚嶅瓧',
+  `order_date` timestamp NULL DEFAULT NULL COMMENT '璁㈠崟鏃ユ湡',
+  `order_amount` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁㈠崟閲戦',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `attachment` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '闄勪欢',
+  `plan_stage` json NULL COMMENT '椤圭洰闃舵 json',
+  `team` json NULL COMMENT '鍥㈤槦',
+  `create_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `update_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '椤圭洰绠$悊淇℃伅' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for project_management_info_stage
+-- ----------------------------
+DROP TABLE IF EXISTS `project_management_info_stage`;
+CREATE TABLE `project_management_info_stage`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `project_management_plan_node_id` bigint NOT NULL COMMENT '瀵瑰簲璁″垝鑺傜偣id',
+  `project_management_info_id` bigint NOT NULL COMMENT '瀵瑰簲椤圭洰id',
+  `description` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎻忚堪',
+  `actual_leader_id` bigint NULL DEFAULT NULL COMMENT '瀹為檯璐熻矗浜篿d',
+  `actual_leader_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹為檯璐熻矗浜哄悕绉�',
+  `estimated_duration` int NULL DEFAULT NULL COMMENT '棰勮宸ユ湡',
+  `plan_start_time` date NULL DEFAULT NULL COMMENT '璁″垝寮�濮�',
+  `plan_end_time` date NULL DEFAULT NULL COMMENT '璁″垝缁撴潫',
+  `progress` int NOT NULL DEFAULT 0 COMMENT '杩涘害',
+  `actual_start_time` date NULL DEFAULT NULL COMMENT '瀹為檯寮�濮嬫椂闂�',
+  `actual_end_time` date NULL DEFAULT NULL COMMENT '瀹為檯缁撴潫鏃堕棿',
+  `attachment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '闄勪欢',
+  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
+  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
+  `is_delete` int NOT NULL DEFAULT 0,
+  `create_user` bigint NULL DEFAULT NULL,
+  `update_user` bigint NULL DEFAULT NULL,
+  `create_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `update_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '椤圭洰闃舵' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for project_management_plan
+-- ----------------------------
+DROP TABLE IF EXISTS `project_management_plan`;
+CREATE TABLE `project_management_plan`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璁″垝鍚嶇О',
+  `description` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁″垝鎻忚堪',
+  `attachment` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '闄勪欢 ,杩涜鍒嗗壊',
+  `is_delete` int NOT NULL DEFAULT 0,
+  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
+  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
+  `create_user` int NULL DEFAULT NULL,
+  `update_user` int NULL DEFAULT NULL,
+  `create_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `update_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '椤圭洰绠$悊璁″垝琛�(椤圭洰绠$悊绫诲瀷)' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for project_management_plan_node
+-- ----------------------------
+DROP TABLE IF EXISTS `project_management_plan_node`;
+CREATE TABLE `project_management_plan_node`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `project_management_plan_id` bigint NOT NULL COMMENT '瀵瑰簲id',
+  `sort` int NOT NULL COMMENT '鎺掑簭',
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '闃舵鍚嶇О',
+  `leader_id` bigint NULL DEFAULT NULL COMMENT '璐熻矗浠籌D',
+  `leader_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璐熻矗浠诲悕绉�',
+  `estimated_duration` int NULL DEFAULT NULL COMMENT '棰勮宸ユ湡(澶�)',
+  `hourly_rate` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `work_content` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浣滀笟鍐呭',
+  `is_delete` int NOT NULL DEFAULT 0,
+  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
+  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
+  `create_user` int NULL DEFAULT NULL,
+  `update_user` int NULL DEFAULT NULL,
+  `create_user_name` varchar(25) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `update_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '璁″垝鑺傜偣' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for project_management_roles
+-- ----------------------------
+DROP TABLE IF EXISTS `project_management_roles`;
+CREATE TABLE `project_management_roles`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT 'id',
+  `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '鍚嶇О',
+  `status` tinyint NOT NULL DEFAULT 1 COMMENT '鐘舵��(1:鍚敤, 0:绂佺敤)',
+  `create_time` timestamp NOT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `update_time` timestamp NOT NULL COMMENT '鏇存柊鏃堕棿',
+  `update_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `create_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `update_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '椤圭洰瑙掕壊' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for project_management_shipping_address
+-- ----------------------------
+DROP TABLE IF EXISTS `project_management_shipping_address`;
+CREATE TABLE `project_management_shipping_address`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `consignee` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏀惰揣浜�',
+  `contract` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鑱旂郴鏂瑰紡',
+  `address` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍦板潃',
+  `is_delete` int NOT NULL DEFAULT 0,
+  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `create_user` bigint NULL DEFAULT NULL,
+  `update_user` bigint NULL DEFAULT NULL,
+  `project_management_info_id` bigint NULL DEFAULT NULL COMMENT '瀵瑰簲椤圭洰淇℃伅id',
+  `update_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `create_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鏀惰揣鍦板潃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for purchase_ledger
+-- ----------------------------
+DROP TABLE IF EXISTS `purchase_ledger`;
+CREATE TABLE `purchase_ledger`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT '鑷涓婚敭ID',
+  `purchase_contract_number` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '閲囪喘鍚堝悓鍙�',
+  `supplier_id` int NULL DEFAULT NULL COMMENT '渚涘簲鍟嗗悕绉癷d',
+  `supplier_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '渚涘簲鍟嗗悕绉�',
+  `recorder_id` int NULL DEFAULT NULL COMMENT '褰曞叆浜篿d\r\n',
+  `recorder_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '褰曞叆浜哄鍚�',
+  `sales_contract_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閿�鍞悎鍚屽彿',
+  `project_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '椤圭洰鍚嶇О',
+  `entry_date` date NOT NULL COMMENT '褰曞叆鏃ユ湡',
+  `remarks` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '澶囨敞',
+  `attachment_materials` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '闄勪欢鏉愭枡璺緞鎴栧悕绉�',
+  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '璁板綍鍒涘缓鏃堕棿',
+  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '璁板綍鏈�鍚庢洿鏂版椂闂�',
+  `sales_ledger_id` int NULL DEFAULT NULL COMMENT '鍏宠仈閿�鍞彴璐︿富琛ㄤ富閿�',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `contract_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍚堝悓閲戦',
+  `business_person` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '涓氬姟鍛�',
+  `business_person_id` int NULL DEFAULT NULL COMMENT '涓氬姟鍛榠d',
+  `phone_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '褰曞叆浜虹數璇�',
+  `payment_method` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `execution_date` datetime NULL DEFAULT NULL,
+  `approval_status` bigint NULL DEFAULT 1 COMMENT '1-寰呭鏍革紝2-瀹℃壒涓紝3-瀹℃壒閫氳繃锛�4-瀹℃壒澶辫触',
+  `template_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '妯℃澘鍚嶇О',
+  `approve_user_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹℃壒浜篿d',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `template_id` int NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 44 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '閲囪喘鍙拌处' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for purchase_ledger_template
+-- ----------------------------
+DROP TABLE IF EXISTS `purchase_ledger_template`;
+CREATE TABLE `purchase_ledger_template`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT '鑷涓婚敭ID',
+  `purchase_contract_number` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閲囪喘鍚堝悓鍙�',
+  `supplier_id` int NULL DEFAULT NULL COMMENT '渚涘簲鍟嗗悕绉癷d',
+  `supplier_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '渚涘簲鍟嗗悕绉�',
+  `recorder_id` int NULL DEFAULT NULL COMMENT '褰曞叆浜篿d\r\n',
+  `recorder_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '褰曞叆浜哄鍚�',
+  `sales_contract_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閿�鍞悎鍚屽彿',
+  `project_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '椤圭洰鍚嶇О',
+  `entry_date` date NULL DEFAULT NULL COMMENT '褰曞叆鏃ユ湡',
+  `remarks` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '澶囨敞',
+  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '璁板綍鍒涘缓鏃堕棿',
+  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '璁板綍鏈�鍚庢洿鏂版椂闂�',
+  `sales_ledger_id` int NULL DEFAULT NULL COMMENT '鍏宠仈閿�鍞彴璐︿富琛ㄤ富閿�',
+  `contract_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍚堝悓閲戦',
+  `business_person` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '涓氬姟鍛�',
+  `business_person_id` int NULL DEFAULT NULL COMMENT '涓氬姟鍛榠d',
+  `phone_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '褰曞叆浜虹數璇�',
+  `payment_method` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `execution_date` datetime NULL DEFAULT NULL,
+  `template_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '妯℃澘鍚嶇О',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '閲囪喘鍙拌处妯℃澘' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for purchase_return_order_products
+-- ----------------------------
+DROP TABLE IF EXISTS `purchase_return_order_products`;
+CREATE TABLE `purchase_return_order_products`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `purchase_return_order_id` bigint NOT NULL DEFAULT 0 COMMENT '閫�璐у崟id',
+  `sales_ledger_product_id` bigint NOT NULL DEFAULT 0 COMMENT '閲囪喘浜у搧id',
+  `return_quantity` decimal(16, 4) NOT NULL DEFAULT 0.0000 COMMENT '閫�璐ф暟閲�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `stock_in_record_id` bigint NOT NULL COMMENT '鍏宠仈鍏ュ簱鍗昳d',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_purchase_return_order_id`(`purchase_return_order_id` ASC) USING BTREE,
+  INDEX `idx_sales_ledger_product_id`(`sales_ledger_product_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '閲囪喘閫�璐т骇鍝佽〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for purchase_return_orders
+-- ----------------------------
+DROP TABLE IF EXISTS `purchase_return_orders`;
+CREATE TABLE `purchase_return_orders`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閫�璐у崟缂栧彿',
+  `return_type` tinyint NOT NULL DEFAULT 0 COMMENT '閫�璐ф柟寮� 0閫�璐ч��娆� 1鎷掓敹',
+  `supplier_id` bigint NOT NULL DEFAULT 0 COMMENT '渚涘簲鍟唅d',
+  `shipping_type` tinyint NULL DEFAULT NULL COMMENT '鍙戣揣绫诲瀷 1璐ц溅 2蹇��',
+  `truck_plate_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍙戣揣杞︾墝鍙�',
+  `express_company` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '蹇�掑叕鍙�',
+  `express_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '蹇�掑崟鍙�',
+  `project_id` bigint NOT NULL DEFAULT 0 COMMENT '椤圭洰id',
+  `project_phase` tinyint NOT NULL DEFAULT 0 COMMENT '椤圭洰闃舵',
+  `prepared_at` datetime NULL DEFAULT NULL COMMENT '鍒跺崟鏃ユ湡',
+  `prepared_user_id` bigint NOT NULL DEFAULT 0 COMMENT '鍒跺崟浜篿d',
+  `return_user_id` bigint NOT NULL DEFAULT 0 COMMENT '閫�鏂欎汉id',
+  `purchase_ledger_id` bigint NOT NULL DEFAULT 0 COMMENT '閲囪喘璁㈠崟id',
+  `total_discount_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '鏁村崟鎶樻墸棰�',
+  `total_discount_rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '鏁村崟鎶樻墸鐜�',
+  `total_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '鎴愪氦閲戦',
+  `remark` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '澶囨敞',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `income_type` int NULL DEFAULT NULL COMMENT '鏀跺叆绫诲瀷',
+  `prepared_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍒跺崟浜哄悕绉�',
+  `return_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閫�鏂欎汉鍚嶇О',
+  `create_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `create_user` int NULL DEFAULT NULL,
+  `update_user` int NULL DEFAULT NULL,
+  `update_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_supplier_id`(`supplier_id` ASC) USING BTREE,
+  INDEX `idx_purchase_ledger_id`(`purchase_ledger_id` ASC) USING BTREE,
+  INDEX `idx_project_id`(`project_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '閲囪喘閫�璐у崟琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for qr_code
+-- ----------------------------
+DROP TABLE IF EXISTS `qr_code`;
+CREATE TABLE `qr_code`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '浜岀淮鐮佸敮涓�鏍囪瘑',
+  `device_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁惧鍚嶇О',
+  `location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎵�鍦ㄤ綅缃弿杩�',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛ID锛岀敤浜庡绉熸埛闅旂',
+  `deleted` int NOT NULL DEFAULT 0 COMMENT '杞垹闄ゆ爣蹇楋紝0=鏈垹闄わ紝1=宸插垹闄�',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓璇ヨ褰曠殑鐢ㄦ埛',
+  `create_time` datetime(6) NULL DEFAULT NULL COMMENT '璁板綍鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '鏈�鍚庝慨鏀硅璁板綍鐨勭敤鎴�',
+  `update_time` datetime(6) NULL DEFAULT NULL COMMENT '璁板綍鏈�鍚庢洿鏂版椂闂�',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浜岀淮鐮佺鐞嗚〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for qr_code_scan_record
+-- ----------------------------
+DROP TABLE IF EXISTS `qr_code_scan_record`;
+CREATE TABLE `qr_code_scan_record`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '鎵爜璁板綍鍞竴鏍囪瘑',
+  `qr_code_id` bigint NULL DEFAULT NULL COMMENT '鍏宠仈鐨勪簩缁寸爜ID',
+  `scanner_id` bigint NULL DEFAULT NULL COMMENT '鎵爜浜虹敤鎴稩D',
+  `device_id` int NULL DEFAULT NULL COMMENT '璁惧id',
+  `device_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁惧鍚嶇О',
+  `scan_time` datetime(6) NULL DEFAULT NULL COMMENT '瀹為檯鎵爜鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛ID锛岀敤浜庡绉熸埛闅旂',
+  `deleted` int NOT NULL DEFAULT 0 COMMENT '杞垹闄ゆ爣蹇楋紝0=鏈垹闄わ紝1=宸插垹闄�',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓璇ヨ褰曠殑鐢ㄦ埛',
+  `create_time` datetime(6) NULL DEFAULT NULL COMMENT '璁板綍鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '鏈�鍚庝慨鏀硅璁板綍鐨勭敤鎴�',
+  `update_time` datetime(6) NULL DEFAULT NULL COMMENT '璁板綍鏈�鍚庢洿鏂版椂闂�',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浜岀淮鐮佹壂鐮佽褰曡〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for qrtz_blob_triggers
+-- ----------------------------
+DROP TABLE IF EXISTS `qrtz_blob_triggers`;
+CREATE TABLE `qrtz_blob_triggers`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璋冨害鍚嶇О',
+  `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers琛╰rigger_name鐨勫閿�',
+  `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers琛╰rigger_group鐨勫閿�',
+  `blob_data` blob NULL COMMENT '瀛樻斁鎸佷箙鍖朤rigger瀵硅薄',
+  PRIMARY KEY (`sched_name`, `trigger_name`, `trigger_group`) USING BTREE,
+  CONSTRAINT `qrtz_blob_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'Blob绫诲瀷鐨勮Е鍙戝櫒琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for qrtz_calendars
+-- ----------------------------
+DROP TABLE IF EXISTS `qrtz_calendars`;
+CREATE TABLE `qrtz_calendars`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璋冨害鍚嶇О',
+  `calendar_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鏃ュ巻鍚嶇О',
+  `calendar` blob NOT NULL COMMENT '瀛樻斁鎸佷箙鍖朿alendar瀵硅薄',
+  PRIMARY KEY (`sched_name`, `calendar_name`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鏃ュ巻淇℃伅琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for qrtz_cron_triggers
+-- ----------------------------
+DROP TABLE IF EXISTS `qrtz_cron_triggers`;
+CREATE TABLE `qrtz_cron_triggers`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璋冨害鍚嶇О',
+  `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers琛╰rigger_name鐨勫閿�',
+  `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers琛╰rigger_group鐨勫閿�',
+  `cron_expression` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'cron琛ㄨ揪寮�',
+  `time_zone_id` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏃跺尯',
+  PRIMARY KEY (`sched_name`, `trigger_name`, `trigger_group`) USING BTREE,
+  CONSTRAINT `qrtz_cron_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'Cron绫诲瀷鐨勮Е鍙戝櫒琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for qrtz_fired_triggers
+-- ----------------------------
+DROP TABLE IF EXISTS `qrtz_fired_triggers`;
+CREATE TABLE `qrtz_fired_triggers`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璋冨害鍚嶇О',
+  `entry_id` varchar(95) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璋冨害鍣ㄥ疄渚媔d',
+  `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers琛╰rigger_name鐨勫閿�',
+  `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers琛╰rigger_group鐨勫閿�',
+  `instance_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璋冨害鍣ㄥ疄渚嬪悕',
+  `fired_time` bigint NOT NULL COMMENT '瑙﹀彂鐨勬椂闂�',
+  `sched_time` bigint NOT NULL COMMENT '瀹氭椂鍣ㄥ埗瀹氱殑鏃堕棿',
+  `priority` int NOT NULL COMMENT '浼樺厛绾�',
+  `state` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鐘舵��',
+  `job_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浠诲姟鍚嶇О',
+  `job_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浠诲姟缁勫悕',
+  `is_nonconcurrent` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏄惁骞跺彂',
+  `requests_recovery` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏄惁鎺ュ彈鎭㈠鎵ц',
+  PRIMARY KEY (`sched_name`, `entry_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '宸茶Е鍙戠殑瑙﹀彂鍣ㄨ〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for qrtz_job_details
+-- ----------------------------
+DROP TABLE IF EXISTS `qrtz_job_details`;
+CREATE TABLE `qrtz_job_details`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璋冨害鍚嶇О',
+  `job_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '浠诲姟鍚嶇О',
+  `job_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '浠诲姟缁勫悕',
+  `description` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐩稿叧浠嬬粛',
+  `job_class_name` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鎵ц浠诲姟绫诲悕绉�',
+  `is_durable` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鏄惁鎸佷箙鍖�',
+  `is_nonconcurrent` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鏄惁骞跺彂',
+  `is_update_data` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鏄惁鏇存柊鏁版嵁',
+  `requests_recovery` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鏄惁鎺ュ彈鎭㈠鎵ц',
+  `job_data` blob NULL COMMENT '瀛樻斁鎸佷箙鍖杍ob瀵硅薄',
+  PRIMARY KEY (`sched_name`, `job_name`, `job_group`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浠诲姟璇︾粏淇℃伅琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for qrtz_locks
+-- ----------------------------
+DROP TABLE IF EXISTS `qrtz_locks`;
+CREATE TABLE `qrtz_locks`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璋冨害鍚嶇О',
+  `lock_name` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鎮茶閿佸悕绉�',
+  PRIMARY KEY (`sched_name`, `lock_name`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀛樺偍鐨勬偛瑙傞攣淇℃伅琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for qrtz_paused_trigger_grps
+-- ----------------------------
+DROP TABLE IF EXISTS `qrtz_paused_trigger_grps`;
+CREATE TABLE `qrtz_paused_trigger_grps`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璋冨害鍚嶇О',
+  `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers琛╰rigger_group鐨勫閿�',
+  PRIMARY KEY (`sched_name`, `trigger_group`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鏆傚仠鐨勮Е鍙戝櫒琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for qrtz_scheduler_state
+-- ----------------------------
+DROP TABLE IF EXISTS `qrtz_scheduler_state`;
+CREATE TABLE `qrtz_scheduler_state`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璋冨害鍚嶇О',
+  `instance_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瀹炰緥鍚嶇О',
+  `last_checkin_time` bigint NOT NULL COMMENT '涓婃妫�鏌ユ椂闂�',
+  `checkin_interval` bigint NOT NULL COMMENT '妫�鏌ラ棿闅旀椂闂�',
+  PRIMARY KEY (`sched_name`, `instance_name`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '璋冨害鍣ㄧ姸鎬佽〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for qrtz_simple_triggers
+-- ----------------------------
+DROP TABLE IF EXISTS `qrtz_simple_triggers`;
+CREATE TABLE `qrtz_simple_triggers`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璋冨害鍚嶇О',
+  `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers琛╰rigger_name鐨勫閿�',
+  `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers琛╰rigger_group鐨勫閿�',
+  `repeat_count` bigint NOT NULL COMMENT '閲嶅鐨勬鏁扮粺璁�',
+  `repeat_interval` bigint NOT NULL COMMENT '閲嶅鐨勯棿闅旀椂闂�',
+  `times_triggered` bigint NOT NULL COMMENT '宸茬粡瑙﹀彂鐨勬鏁�',
+  PRIMARY KEY (`sched_name`, `trigger_name`, `trigger_group`) USING BTREE,
+  CONSTRAINT `qrtz_simple_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '绠�鍗曡Е鍙戝櫒鐨勪俊鎭〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for qrtz_simprop_triggers
+-- ----------------------------
+DROP TABLE IF EXISTS `qrtz_simprop_triggers`;
+CREATE TABLE `qrtz_simprop_triggers`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璋冨害鍚嶇О',
+  `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers琛╰rigger_name鐨勫閿�',
+  `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers琛╰rigger_group鐨勫閿�',
+  `str_prop_1` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'String绫诲瀷鐨則rigger鐨勭涓�涓弬鏁�',
+  `str_prop_2` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'String绫诲瀷鐨則rigger鐨勭浜屼釜鍙傛暟',
+  `str_prop_3` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'String绫诲瀷鐨則rigger鐨勭涓変釜鍙傛暟',
+  `int_prop_1` int NULL DEFAULT NULL COMMENT 'int绫诲瀷鐨則rigger鐨勭涓�涓弬鏁�',
+  `int_prop_2` int NULL DEFAULT NULL COMMENT 'int绫诲瀷鐨則rigger鐨勭浜屼釜鍙傛暟',
+  `long_prop_1` bigint NULL DEFAULT NULL COMMENT 'long绫诲瀷鐨則rigger鐨勭涓�涓弬鏁�',
+  `long_prop_2` bigint NULL DEFAULT NULL COMMENT 'long绫诲瀷鐨則rigger鐨勭浜屼釜鍙傛暟',
+  `dec_prop_1` decimal(13, 4) NULL DEFAULT NULL COMMENT 'decimal绫诲瀷鐨則rigger鐨勭涓�涓弬鏁�',
+  `dec_prop_2` decimal(13, 4) NULL DEFAULT NULL COMMENT 'decimal绫诲瀷鐨則rigger鐨勭浜屼釜鍙傛暟',
+  `bool_prop_1` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'Boolean绫诲瀷鐨則rigger鐨勭涓�涓弬鏁�',
+  `bool_prop_2` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'Boolean绫诲瀷鐨則rigger鐨勭浜屼釜鍙傛暟',
+  PRIMARY KEY (`sched_name`, `trigger_name`, `trigger_group`) USING BTREE,
+  CONSTRAINT `qrtz_simprop_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍚屾鏈哄埗鐨勮閿佽〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for qrtz_triggers
+-- ----------------------------
+DROP TABLE IF EXISTS `qrtz_triggers`;
+CREATE TABLE `qrtz_triggers`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璋冨害鍚嶇О',
+  `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瑙﹀彂鍣ㄧ殑鍚嶅瓧',
+  `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瑙﹀彂鍣ㄦ墍灞炵粍鐨勫悕瀛�',
+  `job_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_job_details琛╦ob_name鐨勫閿�',
+  `job_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_job_details琛╦ob_group鐨勫閿�',
+  `description` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐩稿叧浠嬬粛',
+  `next_fire_time` bigint NULL DEFAULT NULL COMMENT '涓婁竴娆¤Е鍙戞椂闂达紙姣锛�',
+  `prev_fire_time` bigint NULL DEFAULT NULL COMMENT '涓嬩竴娆¤Е鍙戞椂闂达紙榛樿涓�-1琛ㄧず涓嶈Е鍙戯級',
+  `priority` int NULL DEFAULT NULL COMMENT '浼樺厛绾�',
+  `trigger_state` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瑙﹀彂鍣ㄧ姸鎬�',
+  `trigger_type` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瑙﹀彂鍣ㄧ殑绫诲瀷',
+  `start_time` bigint NOT NULL COMMENT '寮�濮嬫椂闂�',
+  `end_time` bigint NULL DEFAULT NULL COMMENT '缁撴潫鏃堕棿',
+  `calendar_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏃ョ▼琛ㄥ悕绉�',
+  `misfire_instr` smallint NULL DEFAULT NULL COMMENT '琛ュ伩鎵ц鐨勭瓥鐣�',
+  `job_data` blob NULL COMMENT '瀛樻斁鎸佷箙鍖杍ob瀵硅薄',
+  PRIMARY KEY (`sched_name`, `trigger_name`, `trigger_group`) USING BTREE,
+  INDEX `sched_name`(`sched_name` ASC, `job_name` ASC, `job_group` ASC) USING BTREE,
+  CONSTRAINT `qrtz_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `job_name`, `job_group`) REFERENCES `qrtz_job_details` (`sched_name`, `job_name`, `job_group`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瑙﹀彂鍣ㄨ缁嗕俊鎭〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for quality_inspect
+-- ----------------------------
+DROP TABLE IF EXISTS `quality_inspect`;
+CREATE TABLE `quality_inspect`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `inspect_type` int NULL DEFAULT NULL COMMENT '绫诲埆(0:鍘熸潗鏂欐楠�;1:杩囩▼妫�楠�;2:鍑哄巶妫�楠�)',
+  `check_time` date NULL DEFAULT NULL COMMENT '妫�娴嬫棩鏈�',
+  `supplier` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '渚涘簲鍟嗗悕绉�(鍘熸潗鏂欐楠�)',
+  `customer` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹㈡埛鍚嶇О(杩囩▼妫�楠�/鍑哄巶妫�楠�)',
+  `process` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宸ュ簭(杩囩▼妫�楠�)',
+  `check_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '妫�楠屽憳',
+  `product_id` bigint NULL DEFAULT NULL COMMENT '浜у搧ID',
+  `product_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浜у搧鍚嶇О',
+  `model` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瑙勬牸鍨嬪彿',
+  `unit` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `quantity` decimal(18, 2) NULL DEFAULT NULL COMMENT '鍏ㄩ儴鏁伴噺',
+  `qualified_quantity` decimal(18, 2) NULL DEFAULT NULL COMMENT '鍚堟牸鐨勬暟閲�',
+  `unqualified_quantity` decimal(18, 2) NULL DEFAULT NULL COMMENT '涓嶅悎鏍肩殑鏁伴噺',
+  `check_company` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '妫�娴嬪崟浣�',
+  `check_result` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '妫�娴嬬粨鏋�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `inspect_state` int NULL DEFAULT NULL COMMENT '绫诲埆锛�0-鏈彁浜� 1-宸叉彁浜わ級',
+  `purchase_ledger_id` int NULL DEFAULT NULL COMMENT '閲囪喘璁㈠崟id',
+  `product_main_id` bigint NULL DEFAULT NULL COMMENT '鎶ュ伐鍗昳d',
+  `defective_phenomena` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '涓嶅悎鏍肩幇璞℃弿杩�',
+  `product_model_id` bigint NULL DEFAULT NULL COMMENT '浜у搧瑙勬牸id',
+  `test_standard_id` int NULL DEFAULT NULL COMMENT '鍏宠仈妫�娴嬫爣鍑嗕富琛╥d',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 71 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '璐ㄩ噺绠$悊--鍘熸潗鏂�/杩囩▼/鍑哄巶妫�楠�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for quality_inspect_file
+-- ----------------------------
+DROP TABLE IF EXISTS `quality_inspect_file`;
+CREATE TABLE `quality_inspect_file`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囦欢鍚嶇О',
+  `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囦欢璺緞',
+  `file_size` int NULL DEFAULT NULL COMMENT '鏂囦欢澶у皬',
+  `inspect_id` bigint NULL DEFAULT NULL COMMENT '妫�楠孖D',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '璐ㄩ噺绠$悊--妫�楠岄檮浠�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for quality_inspect_param
+-- ----------------------------
+DROP TABLE IF EXISTS `quality_inspect_param`;
+CREATE TABLE `quality_inspect_param`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `parameter_item` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎸囨爣',
+  `unit` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `standard_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏍囧噯鍊�',
+  `control_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍐呮帶鍊�',
+  `test_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '妫�楠屽��',
+  `inspect_id` bigint NULL DEFAULT NULL COMMENT '妫�楠孖D',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 30 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '璐ㄩ噺绠$悊--妫�楠岃褰�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for quality_test_standard
+-- ----------------------------
+DROP TABLE IF EXISTS `quality_test_standard`;
+CREATE TABLE `quality_test_standard`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `standard_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏍囧噯缂栧彿鎸囨爣',
+  `standard_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏍囧噯鍚嶇О',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `state` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐘舵��',
+  `process_id` int NULL DEFAULT NULL COMMENT '鍏宠仈宸ュ簭id',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `inspect_type` int NULL DEFAULT NULL COMMENT '绫诲埆(0:鍘熸潗鏂欐楠�;1:杩囩▼妫�楠�;2:鍑哄巶妫�楠�)',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '璐ㄩ噺绠$悊--妫�娴嬫寚鏍囩淮鎶�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for quality_test_standard_binding
+-- ----------------------------
+DROP TABLE IF EXISTS `quality_test_standard_binding`;
+CREATE TABLE `quality_test_standard_binding`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `product_id` bigint NULL DEFAULT NULL COMMENT '浜у搧ID',
+  `test_standard_id` int NULL DEFAULT NULL COMMENT '鍏宠仈妫�娴嬫爣鍑嗕富琛╥d',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 19 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '妫�娴嬫爣鍑嗕富琛ㄤ笌浜у搧鍏宠仈琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for quality_test_standard_param
+-- ----------------------------
+DROP TABLE IF EXISTS `quality_test_standard_param`;
+CREATE TABLE `quality_test_standard_param`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `parameter_item` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍙傛暟椤�',
+  `unit` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `standard_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏍囧噯鍊�',
+  `control_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍐呮帶鍊�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `test_standard_id` int NULL DEFAULT NULL COMMENT '鍏宠仈妫�娴嬫爣鍑嗕富琛╥d',
+  `default_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '榛樿鍊�',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '妫�娴嬫爣鍑嗗弬鏁�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for quality_unqualified
+-- ----------------------------
+DROP TABLE IF EXISTS `quality_unqualified`;
+CREATE TABLE `quality_unqualified`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `inspect_type` int NULL DEFAULT NULL COMMENT '绫诲埆(0:鍘熸潗鏂欐楠�;1:杩囩▼妫�楠�;2:鍑哄巶妫�楠�)',
+  `inspect_state` int NULL DEFAULT NULL COMMENT '鐘舵��(0:寰呭鐞�;1:宸插鐞�)',
+  `check_time` date NULL DEFAULT NULL COMMENT '妫�娴嬫棩鏈�',
+  `check_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '妫�楠屽憳',
+  `product_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浜у搧鍚嶇О',
+  `model` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瑙勬牸鍨嬪彿',
+  `unit` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `quantity` decimal(18, 2) NULL DEFAULT NULL COMMENT '鏁伴噺',
+  `defective_phenomena` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '涓嶅悎鏍肩幇璞�',
+  `deal_result` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶勭悊缁撴灉',
+  `deal_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶勭悊浜�',
+  `deal_time` date NULL DEFAULT NULL COMMENT '澶勭悊鏃ユ湡',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `product_id` bigint NULL DEFAULT NULL COMMENT '浜у搧ID',
+  `inspect_id` int NULL DEFAULT NULL COMMENT '鍏宠仈妫�楠宨d',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `product_model_id` int NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 52 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '璐ㄩ噺绠$悊--涓嶅悎鏍煎搧绠$悊' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for reading_status
+-- ----------------------------
+DROP TABLE IF EXISTS `reading_status`;
+CREATE TABLE `reading_status`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `rule_id` int NULL DEFAULT NULL COMMENT '鐢ㄥ嵃绠$悊-瑙勭珷鍒跺害id',
+  `employee` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍛樺伐濮撳悕',
+  `department` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎵�灞為儴闂�',
+  `confirm_time` datetime NULL DEFAULT NULL COMMENT '纭鏃堕棿',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐘舵��',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '闃呰鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢ㄥ嵃绠$悊-瑙勭珷鍒跺害-闃呰鐘舵��' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for receipt_payment
+-- ----------------------------
+DROP TABLE IF EXISTS `receipt_payment`;
+CREATE TABLE `receipt_payment`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `sales_ledger_id` int NULL DEFAULT NULL COMMENT '閿�鍞彴璐d',
+  `sales_ledger_product_id` int NULL DEFAULT NULL COMMENT '閿�鍞骇鍝乮d',
+  `invoice_ledger_id` bigint NULL DEFAULT NULL COMMENT 'invoice_ledger寮�绁ㄥ彴璐﹁〃涓婚敭ID',
+  `receipt_payment_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍥炴褰㈠紡 0鐢垫眹1鎵垮厬',
+  `receipt_payment_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍥炴閲戦',
+  `registrant` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐧昏浜�',
+  `receipt_payment_date` datetime NULL DEFAULT NULL COMMENT '鏉ユ鏃ユ湡',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 286 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍥炴鐧昏琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for return_management
+-- ----------------------------
+DROP TABLE IF EXISTS `return_management`;
+CREATE TABLE `return_management`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '搴忓彿',
+  `return_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閫�璐у崟鍙�',
+  `customer_id` bigint NULL DEFAULT NULL COMMENT '瀹㈡埛 id',
+  `shipping_id` bigint NULL DEFAULT NULL COMMENT '鍏宠仈鍙戣揣鍗曞彿',
+  `shipping_type` tinyint NULL DEFAULT NULL COMMENT '鍙戣揣绫诲瀷 1璐ц溅 2蹇��',
+  `truck_plate_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍙戣揣杞︾墝鍙�',
+  `express_company` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '蹇�掑叕鍙�',
+  `express_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '蹇�掑崟鍙�',
+  `project_stage` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '椤圭洰闃舵',
+  `maker` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍒跺崟浜�',
+  `make_time` timestamp NULL DEFAULT NULL COMMENT '鍒跺崟鏃堕棿',
+  `settler` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '缁撶畻浜�',
+  `status` int NOT NULL DEFAULT 0,
+  `project_id` int NULL DEFAULT NULL COMMENT '椤圭洰id',
+  `create_time` timestamp NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_time` timestamp NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `return_reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閫�璐у師鍥�',
+  `refund_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '閫�娆炬�婚',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '閫�璐х鐞嗚〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for return_sale_product
+-- ----------------------------
+DROP TABLE IF EXISTS `return_sale_product`;
+CREATE TABLE `return_sale_product`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭id',
+  `return_management_id` int NULL DEFAULT NULL COMMENT '閫�璐у崟id',
+  `stock_out_record_id` bigint NULL DEFAULT NULL COMMENT '鍏宠仈鍑哄簱鍗昳d',
+  `num` decimal(16, 3) NOT NULL COMMENT '閫�璐т骇鍝佹暟閲�',
+  `status` int NULL DEFAULT NULL COMMENT '閫�璐х姸鎬�',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `is_quality` int NULL DEFAULT NULL COMMENT '鏄惁鏈夎川閲忛棶棰�(1-鏄� 2-鍚�)',
+  `price` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍗曚环',
+  `amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '閲戦',
+  `product_model_id` bigint NULL DEFAULT NULL COMMENT '浜у搧瑙勬牸id',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '閫�璐т骇鍝佽〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for rpa_process_automation
+-- ----------------------------
+DROP TABLE IF EXISTS `rpa_process_automation`;
+CREATE TABLE `rpa_process_automation`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `program_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绋嬪簭鍚�',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎵ц鐘舵��',
+  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎻忚堪',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'RPA娴佺▼鑷姩鍖�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for rules_regulations_management
+-- ----------------------------
+DROP TABLE IF EXISTS `rules_regulations_management`;
+CREATE TABLE `rules_regulations_management`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `regulation_num` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍒跺害缂栧彿',
+  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍒跺害鏍囬',
+  `category` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍒跺害鍒嗙被',
+  `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '鍒跺害鍐呭',
+  `effective_time` datetime NULL DEFAULT NULL COMMENT '鐢熸晥鏃堕棿',
+  `scope` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閫傜敤鑼冨洿',
+  `require_confirm` int NULL DEFAULT NULL COMMENT '鏄惁闇�瑕佺‘璁�',
+  `version` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐗堟湰',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐘舵��',
+  `read_count` int NULL DEFAULT NULL COMMENT '宸茶浜烘暟',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瑙勭珷鍒跺害绠$悊' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for rules_regulations_management_file
+-- ----------------------------
+DROP TABLE IF EXISTS `rules_regulations_management_file`;
+CREATE TABLE `rules_regulations_management_file`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囦欢鍚嶇О',
+  `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囦欢璺緞',
+  `file_size` int NULL DEFAULT NULL COMMENT '鏂囦欢澶у皬',
+  `rules_regulations_management_id` int NULL DEFAULT NULL COMMENT '瑙勭珷鍒跺害ID',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '瑙勭珷鍒跺害绠$悊--闄勪欢' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for rygl_add_employee
+-- ----------------------------
+DROP TABLE IF EXISTS `rygl_add_employee`;
+CREATE TABLE `rygl_add_employee`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT '搴忓彿',
+  `status` int NULL DEFAULT NULL COMMENT '1鍏ヨ亴2绂昏亴',
+  `employee_number` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍛樺伐缂栧彿',
+  `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '濮撳悕',
+  `sex` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎬у埆',
+  `native_place` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绫嶈疮',
+  `post` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宀椾綅',
+  `home_address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹跺涵浣忓潃',
+  `first_degree` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绗竴瀛﹀巻',
+  `major` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '涓撲笟',
+  `id_number` int NULL DEFAULT NULL COMMENT '韬唤璇佸彿',
+  `age` int NULL DEFAULT NULL COMMENT '骞撮緞',
+  `contact_number` int NULL DEFAULT NULL COMMENT '鑱旂郴鐢佃瘽',
+  `emergency_contact` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绱ф�ヨ仈绯讳汉',
+  `emergency_contact_number` int NULL DEFAULT NULL COMMENT '绱ф�ヨ仈绯荤數璇�',
+  `contract_term` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍚堝悓骞撮檺',
+  `contract_start_date` datetime NULL DEFAULT NULL COMMENT '鍚堝悓寮�濮嬫棩鏈�',
+  `contract_end_date` datetime NULL DEFAULT NULL COMMENT '鍚堝悓缁撴潫鏃ユ湡',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for safe_accident
+-- ----------------------------
+DROP TABLE IF EXISTS `safe_accident`;
+CREATE TABLE `safe_accident`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `accident_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浜嬫晠缂栧彿',
+  `accident_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浜嬫晠鍚嶇О',
+  `accident_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浜嬫晠绫诲瀷',
+  `happen_time` datetime NULL DEFAULT NULL COMMENT '浜嬫晠鍙戠敓鏃堕棿',
+  `happen_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浜嬫晠鍙戠敓浣嶇疆',
+  `accident_grade` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浜嬫晠绛夌骇',
+  `accident_cause` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '浜嬫晠鐩存帴鍘熷洜',
+  `root_cause` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '浜嬫晠鏍规湰鍘熷洜',
+  `person_loss` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浜哄憳鎹熷け鎯呭喌',
+  `asset_loss` decimal(10, 2) NULL DEFAULT NULL COMMENT '鐩存帴璐骇鎹熷け锛堝厓锛�	',
+  `production_loss` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐢熶骇褰卞搷鎯呭喌',
+  `handle_measures` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '鐜板満搴旀�ュ缃帾鏂�',
+  `responsible_person` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浜嬫晠璐d换浜�',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_time` timestamp NULL DEFAULT NULL COMMENT '涓婃姤鏃堕棿',
+  `create_user` int NULL DEFAULT NULL COMMENT '涓婃姤浜篿d',
+  `update_time` timestamp NULL DEFAULT NULL,
+  `update_user` int NULL DEFAULT NULL,
+  `tenant_id` int NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹夊叏鐢熶骇--浜嬫晠涓婃姤璁板綍' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for safe_certification
+-- ----------------------------
+DROP TABLE IF EXISTS `safe_certification`;
+CREATE TABLE `safe_certification`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瑙勭▼璧勮川鍚嶇О',
+  `code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瑙勭▼璧勮川缂栧彿',
+  `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瑙勭▼璧勮川绫诲瀷',
+  `version` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐗堟湰鍙�',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `effective_time` date NULL DEFAULT NULL COMMENT '鏈夋晥鏈�',
+  `create_time` timestamp NULL DEFAULT NULL,
+  `create_user` int NULL DEFAULT NULL,
+  `update_time` timestamp NULL DEFAULT NULL,
+  `update_user` int NULL DEFAULT NULL,
+  `tenant_id` int NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹夊叏鐢熶骇--瀹夊叏瑙勭▼涓庤祫璐ㄧ鐞�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for safe_certification_file
+-- ----------------------------
+DROP TABLE IF EXISTS `safe_certification_file`;
+CREATE TABLE `safe_certification_file`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `safe_certification_id` int NULL DEFAULT NULL COMMENT '鍏宠仈瀹夊叏鐢熶骇璧勮川id',
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `file_size` double NULL DEFAULT NULL,
+  `create_time` timestamp NULL DEFAULT NULL,
+  `create_user` int NULL DEFAULT NULL,
+  `update_time` timestamp NULL DEFAULT NULL,
+  `update_user` int NULL DEFAULT NULL,
+  `tenant_id` int NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹夊叏鐢熶骇--瀹夊叏瑙勭▼涓庤祫璐ㄧ鐞�--闄勪欢' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for safe_contingency_plan
+-- ----------------------------
+DROP TABLE IF EXISTS `safe_contingency_plan`;
+CREATE TABLE `safe_contingency_plan`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `plan_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '搴旀�ラ妗堢紪鐮�',
+  `plan_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '搴旀�ラ妗堝悕绉�',
+  `plan_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '棰勬绫诲瀷',
+  `apply_scope` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閫傜敤鑼冨洿',
+  `core_responsor_user_id` int NULL DEFAULT NULL COMMENT '鏍稿績璐d换浜�',
+  `exec_steps` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '搴旀�ュ缃楠�',
+  `publish_time` date NULL DEFAULT NULL COMMENT '鍙戝竷鐢熸晥鏃堕棿',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_time` timestamp NULL DEFAULT NULL,
+  `create_user` int NULL DEFAULT NULL,
+  `update_time` timestamp NULL DEFAULT NULL COMMENT '鏈�鍚庝慨璁㈡椂闂�',
+  `update_user` int NULL DEFAULT NULL,
+  `tenant_id` int NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹夊叏鐢熶骇--搴旀�ラ妗堟煡闃�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for safe_hazard
+-- ----------------------------
+DROP TABLE IF EXISTS `safe_hazard`;
+CREATE TABLE `safe_hazard`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍗遍櫓婧愬悕绉�',
+  `code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍗遍櫓婧愮紪鐮�',
+  `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍗遍櫓婧愮被鍨�',
+  `risk_level` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '椋庨櫓绛夌骇',
+  `location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎵�鍦ㄤ綅缃�',
+  `spec_info` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瑙勬牸 / 椋庨櫓鎻忚堪',
+  `control_measures` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绠℃帶鎺柦',
+  `principal_user_id` int NULL DEFAULT NULL COMMENT '绠℃帶璐d换浜� ID',
+  `principal_mobile` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璐d换浜鸿仈绯荤數璇�',
+  `stock_qty` decimal(10, 2) NULL DEFAULT NULL COMMENT '搴撳瓨鏁伴噺',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_time` timestamp NULL DEFAULT NULL,
+  `create_user` int NULL DEFAULT NULL,
+  `update_time` timestamp NULL DEFAULT NULL,
+  `update_user` int NULL DEFAULT NULL,
+  `tenant_id` int NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹夊叏鐢熶骇--鍗遍櫓婧愬彴璐�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for safe_hazard_record
+-- ----------------------------
+DROP TABLE IF EXISTS `safe_hazard_record`;
+CREATE TABLE `safe_hazard_record`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `material_record_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍗曞彿',
+  `safe_hazard_id` int NULL DEFAULT NULL COMMENT '鍏宠仈鍗遍櫓婧愬彴璐� ID',
+  `apply_user_id` int NULL DEFAULT NULL COMMENT '棰嗙敤浜� ID',
+  `apply_time` date NULL DEFAULT NULL COMMENT '棰嗙敤鏃堕棿',
+  `apply_qty` decimal(10, 2) NULL DEFAULT NULL COMMENT '棰嗙敤鏁伴噺',
+  `apply_purpose` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '棰嗙敤鐢ㄩ��',
+  `return_user_id` int NULL DEFAULT NULL COMMENT '褰掕繕浜� ID',
+  `return_time` date NULL DEFAULT NULL COMMENT '褰掕繕鏃堕棿',
+  `return_remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '褰掕繕鎯呭喌璇存槑',
+  `create_time` timestamp NULL DEFAULT NULL,
+  `create_user` int NULL DEFAULT NULL,
+  `update_time` timestamp NULL DEFAULT NULL,
+  `update_user` int NULL DEFAULT NULL,
+  `tenant_id` int NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹夊叏鐢熶骇--鍗遍櫓鐗╂枡绠℃帶' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for safe_hidden
+-- ----------------------------
+DROP TABLE IF EXISTS `safe_hidden`;
+CREATE TABLE `safe_hidden`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `hidden_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '闅愭偅缂栧彿',
+  `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '闅愭偅绫诲瀷',
+  `risk_level` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '闅愭偅椋庨櫓绛夌骇',
+  `location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '闅愭偅鍏蜂綋浣嶇疆',
+  `hidden_desc` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '闅愭偅鎻忚堪',
+  `rectify_user_id` int NULL DEFAULT NULL COMMENT '鏁存敼璐d换浜� ID',
+  `rectify_user_mobile` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏁存敼浜鸿仈绯荤數璇�',
+  `rectify_time` date NULL DEFAULT NULL COMMENT '鏁存敼瀹屾垚鏈熼檺(鏃ユ湡)',
+  `rectify_measures` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '鏁存敼鍏蜂綋鎺柦',
+  `rectify_actual_time` date NULL DEFAULT NULL COMMENT '瀹為檯鏁存敼瀹屾垚鏃堕棿',
+  `verify_user_id` int NULL DEFAULT NULL COMMENT '楠屾敹浜� ID',
+  `verify_result` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '楠屾敹缁撴灉',
+  `verify_remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '楠屾敹鎰忚',
+  `verify_time` date NULL DEFAULT NULL COMMENT '楠屾敹鏃堕棿',
+  `create_time` timestamp NULL DEFAULT NULL COMMENT '涓婃姤鏃堕棿',
+  `create_user` int NULL DEFAULT NULL COMMENT '涓婃姤浜篿d',
+  `update_time` timestamp NULL DEFAULT NULL,
+  `update_user` int NULL DEFAULT NULL,
+  `tenant_id` int NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹夊叏鐢熶骇--闅愭偅鎺掓煡涓婃姤' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for safe_hidden_file
+-- ----------------------------
+DROP TABLE IF EXISTS `safe_hidden_file`;
+CREATE TABLE `safe_hidden_file`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `safe_hidden_id` int NULL DEFAULT NULL COMMENT '鍏宠仈闅愭偅鎺掓煡涓婃姤id',
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `file_size` double NULL DEFAULT NULL,
+  `create_time` timestamp NULL DEFAULT NULL,
+  `create_user` int NULL DEFAULT NULL,
+  `update_time` timestamp NULL DEFAULT NULL,
+  `update_user` int NULL DEFAULT NULL,
+  `tenant_id` int NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹夊叏鐢熶骇--闅愭偅鎺掓煡涓婃姤--闄勪欢' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for safe_training
+-- ----------------------------
+DROP TABLE IF EXISTS `safe_training`;
+CREATE TABLE `safe_training`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `course_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '璇剧▼缂栧彿',
+  `training_objectives` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍩硅鐩爣',
+  `training_content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍩硅鍐呭',
+  `training_mode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍩硅鏂瑰紡',
+  `state` int NULL DEFAULT NULL COMMENT '鐘舵��(0锛氭湭寮�濮�1锛氳繘琛屼腑锛�2锛氬凡缁撴潫)',
+  `participants` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍙傚姞瀵硅薄',
+  `place_training` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍩硅鍦扮偣',
+  `training_lecturer` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍩硅璁插笀',
+  `training_date` date NULL DEFAULT NULL COMMENT '鍩硅鏃ユ湡',
+  `opening_time` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '寮�濮嬫椂闂�(鏃跺垎绉�)',
+  `end_time` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '缁撴潫鏃堕棿(鏃跺垎绉�)',
+  `project_credits` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '璇鹃瀛﹀垎',
+  `class_hour` double NULL DEFAULT NULL COMMENT '璇炬椂',
+  `assessment_method` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鑰冩牳鏂瑰紡',
+  `comprehensive_assessment` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鏈鍩硅缁煎悎璇勪环',
+  `remarks` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `assessment_user_id` int NULL DEFAULT NULL COMMENT '璇勪环浜篿d',
+  `assessment_date` date NULL DEFAULT NULL COMMENT '璇勪环鏃堕棿',
+  `training_abstract` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍩硅鎽樿',
+  `create_time` timestamp NULL DEFAULT NULL,
+  `create_user` int NULL DEFAULT NULL,
+  `update_time` timestamp NULL DEFAULT NULL,
+  `update_user` int NULL DEFAULT NULL,
+  `tenant_id` int NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹夊叏鐢熶骇--瀹夊叏鍩硅鑰冩牳' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for safe_training_details
+-- ----------------------------
+DROP TABLE IF EXISTS `safe_training_details`;
+CREATE TABLE `safe_training_details`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `user_id` int NULL DEFAULT NULL COMMENT '鐢ㄦ埛琛ㄦ牸锛坲ser锛変富閿�',
+  `safe_training_id` int NULL DEFAULT NULL COMMENT '鍏宠仈瀹夊叏鍩硅鑰冩牳id',
+  `examination_results` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鑰冩牳缁撴灉',
+  `create_time` timestamp NULL DEFAULT NULL,
+  `create_user` int NULL DEFAULT NULL,
+  `update_time` timestamp NULL DEFAULT NULL,
+  `update_user` int NULL DEFAULT NULL,
+  `tenant_id` int NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹夊叏鐢熶骇--瀹夊叏鍩硅鑰冩牳--璁板綍璇︽儏' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for safe_training_file
+-- ----------------------------
+DROP TABLE IF EXISTS `safe_training_file`;
+CREATE TABLE `safe_training_file`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `safe_training_id` int NULL DEFAULT NULL COMMENT '鍏宠仈瀹夊叏鍩硅鑰冩牳id',
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `file_size` double NULL DEFAULT NULL,
+  `create_time` timestamp NULL DEFAULT NULL,
+  `create_user` int NULL DEFAULT NULL,
+  `update_time` timestamp NULL DEFAULT NULL,
+  `update_user` int NULL DEFAULT NULL,
+  `tenant_id` int NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹夊叏鐢熶骇--瀹夊叏鍩硅鑰冩牳--闄勪欢' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sales_ledger
+-- ----------------------------
+DROP TABLE IF EXISTS `sales_ledger`;
+CREATE TABLE `sales_ledger`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT '閿�鍞彴璐︿富閿�',
+  `sales_contract_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '閿�鍞悎鍚屽彿',
+  `customer_contract_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹㈡埛鍚堝悓鍙�',
+  `project_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '椤圭洰鍚嶇О',
+  `entry_date` date NULL DEFAULT NULL COMMENT '褰曞叆鏃ユ湡',
+  `salesman` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '涓氬姟鍛�',
+  `customer_id` int NULL DEFAULT NULL COMMENT '瀹㈡埛鍚嶇Оid',
+  `customer_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹㈡埛鍚嶇О',
+  `entry_person` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '褰曞叆浜�',
+  `remarks` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '澶囨敞',
+  `attachment_materials` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '闄勪欢鏉愭枡锛屽瓨鍌ㄦ枃浠跺悕绛夌浉鍏充俊鎭�',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `contract_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍚堝悓閲戦锛堜骇鍝佸惈绋庢�讳环锛�',
+  `execution_date` datetime NULL DEFAULT NULL COMMENT '绛捐鏃ユ湡',
+  `payment_method` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `delivery_date` timestamp NULL DEFAULT NULL COMMENT '浜よ揣鏃ユ湡',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_sales_entry_person`(`entry_person` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 57 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '閿�鍞彴璐�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sales_ledger_product
+-- ----------------------------
+DROP TABLE IF EXISTS `sales_ledger_product`;
+CREATE TABLE `sales_ledger_product`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT '浜у搧淇℃伅涓婚敭',
+  `sales_ledger_id` int NOT NULL COMMENT '鍏宠仈鍙拌处涓昏〃涓婚敭',
+  `product_category` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浜у搧澶х被',
+  `specification_model` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瑙勬牸鍨嬪彿',
+  `unit` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `quantity` decimal(18, 2) NOT NULL COMMENT '鏁伴噺',
+  `min_stock` decimal(10, 2) NULL DEFAULT NULL COMMENT '鏈�浣庡簱瀛�',
+  `tax_rate` decimal(5, 0) NOT NULL COMMENT '绋庣巼',
+  `tax_inclusive_unit_price` decimal(18, 2) NOT NULL COMMENT '鍚◣鍗曚环',
+  `tax_inclusive_total_price` decimal(18, 2) NOT NULL COMMENT '鍚◣鎬讳环',
+  `tax_exclusive_total_price` decimal(18, 2) NOT NULL COMMENT '涓嶅惈绋庢�讳环',
+  `invoice_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍙戠エ绫诲瀷',
+  `type` int NULL DEFAULT NULL COMMENT '1.閿�鍞彴璐︼紝2.閲囪喘鍙拌处',
+  `product_id` int NULL DEFAULT NULL COMMENT '浜у搧id',
+  `product_model_id` int NULL DEFAULT NULL COMMENT '鍨嬪彿id',
+  `register` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐧昏浜�',
+  `register_date` datetime NULL DEFAULT NULL COMMENT '鐧昏鏃ユ湡',
+  `warn_num` decimal(10, 2) NULL DEFAULT NULL COMMENT '棰勮鏁伴噺',
+  `approve_status` int NULL DEFAULT 0 COMMENT '瀹℃壒鐘舵�侊細0鏈嚭搴�,1宸插嚭搴�,2寰呭鏍�(瀹℃牳涓�),3瀹℃牳瀹屾垚,4瀹℃牳澶辫触',
+  `is_checked` tinyint(1) NOT NULL DEFAULT 1 COMMENT '鏄惁鎺ㄩ�佽川妫�',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `is_production` tinyint(1) NULL DEFAULT 0 COMMENT '鏄惁鐢熶骇',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 105 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浜у搧淇℃伅' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sales_ledger_product_template
+-- ----------------------------
+DROP TABLE IF EXISTS `sales_ledger_product_template`;
+CREATE TABLE `sales_ledger_product_template`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT '浜у搧淇℃伅涓婚敭',
+  `sales_ledger_id` int NOT NULL COMMENT '鍏宠仈鍙拌处妯℃澘涓昏〃涓婚敭',
+  `product_category` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浜у搧澶х被',
+  `specification_model` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瑙勬牸鍨嬪彿',
+  `unit` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `quantity` decimal(18, 2) NULL DEFAULT NULL COMMENT '鏁伴噺',
+  `min_stock` decimal(10, 2) NULL DEFAULT NULL COMMENT '鏈�浣庡簱瀛�',
+  `tax_rate` decimal(5, 0) NULL DEFAULT NULL COMMENT '绋庣巼',
+  `tax_inclusive_unit_price` decimal(18, 2) NULL DEFAULT NULL COMMENT '鍚◣鍗曚环',
+  `tax_inclusive_total_price` decimal(18, 2) NULL DEFAULT NULL COMMENT '鍚◣鎬讳环',
+  `tax_exclusive_total_price` decimal(18, 2) NULL DEFAULT NULL COMMENT '涓嶅惈绋庢�讳环',
+  `invoice_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍙戠エ绫诲瀷',
+  `type` int NULL DEFAULT NULL COMMENT '1.閿�鍞彴璐︼紝2.閲囪喘鍙拌处',
+  `product_id` bigint NULL DEFAULT NULL COMMENT '浜у搧id',
+  `product_model_id` bigint NULL DEFAULT NULL COMMENT '鍨嬪彿id',
+  `register` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `register_date` datetime NULL DEFAULT NULL,
+  `warn_num` decimal(10, 2) NULL DEFAULT NULL,
+  `is_checked` tinyint NULL DEFAULT 1 COMMENT '鏄惁鎺ㄩ�佽川妫�',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浜у搧淇℃伅妯℃澘' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sales_quotation
+-- ----------------------------
+DROP TABLE IF EXISTS `sales_quotation`;
+CREATE TABLE `sales_quotation`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `quotation_no` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鎶ヤ环鍗曞彿',
+  `customer_id` bigint NOT NULL DEFAULT 0 COMMENT '瀹㈡埛id',
+  `salesperson` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '涓氬姟鍛�',
+  `quotation_date` date NULL DEFAULT NULL COMMENT '鎶ヤ环鏃ユ湡',
+  `valid_date` date NULL DEFAULT NULL COMMENT '鏈夋晥鏈熻嚦',
+  `total_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '鎶ヤ环閲戦',
+  `payment_method` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '浠樻鏂瑰紡',
+  `delivery_period` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '浜よ揣鏈�,澶╂暟',
+  `status` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鎶ヤ环鐘舵��',
+  `remark` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `customer` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 49 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_bin COMMENT = '閿�鍞�/鎶ヤ环' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sales_quotation_product
+-- ----------------------------
+DROP TABLE IF EXISTS `sales_quotation_product`;
+CREATE TABLE `sales_quotation_product`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `sales_quotation_id` int NULL DEFAULT NULL COMMENT '閿�鍞姤浠峰崟id',
+  `product` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '浜у搧鍚嶇О',
+  `product_id` bigint NULL DEFAULT NULL COMMENT '浜у搧Id',
+  `specification` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '瑙勬牸鍨嬪彿',
+  `quantity` int NULL DEFAULT NULL COMMENT '鏁伴噺',
+  `unit` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `unit_price` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍗曚环',
+  `amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '閲戦',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `product_model_id` bigint NULL DEFAULT NULL COMMENT '浜у搧瑙勬牸Id',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 55 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_bin COMMENT = '閿�鍞姤浠蜂骇鍝佽〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sales_receipt_return
+-- ----------------------------
+DROP TABLE IF EXISTS `sales_receipt_return`;
+CREATE TABLE `sales_receipt_return`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭 ID',
+  `refund_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '閫�娆惧崟鍙�',
+  `payment_account` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浠樻璐﹀彿',
+  `payment_account_name` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浠樻璐﹀彿鍚嶇О',
+  `payment_method` tinyint NULL DEFAULT NULL COMMENT '浠樻鏂瑰紡',
+  `actual_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '瀹為檯浠樻閲戦',
+  `fee` decimal(10, 2) NULL DEFAULT NULL COMMENT '鎵嬬画璐�',
+  `transaction_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浜ゆ槗鍙�',
+  `discount_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '浼樻儬閲戦',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鏀舵閫�璐ц〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sales_refund_amount_order
+-- ----------------------------
+DROP TABLE IF EXISTS `sales_refund_amount_order`;
+CREATE TABLE `sales_refund_amount_order`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `return_management_id` bigint NULL DEFAULT NULL COMMENT '閫�璐у崟鍙穒d',
+  `status` int NULL DEFAULT NULL COMMENT '鐘舵�� 0:寰呭鏍� 1:寰呴��娆� 2锛氬凡閫�娆�',
+  `refund_amount` decimal(16, 3) NULL DEFAULT NULL COMMENT '搴旈��娆鹃噾棰�',
+  `refunded_amount` decimal(16, 3) NULL DEFAULT NULL COMMENT '宸查��娆鹃噾棰�',
+  `not_refunded_amount` decimal(16, 3) NULL DEFAULT NULL COMMENT '鏈��娆鹃噾棰�',
+  `create_time` timestamp NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_time` timestamp NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篿d',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊浜篿d',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '閿�鍞鐞�--閫�娆惧崟' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for salesperson_management
+-- ----------------------------
+DROP TABLE IF EXISTS `salesperson_management`;
+CREATE TABLE `salesperson_management`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '濮撳悕',
+  `phone` varchar(15) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鑱旂郴鐢佃瘽',
+  `email` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '閭',
+  `department` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '閮ㄩ棬',
+  `position` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鑱屼綅',
+  `hire_date` datetime NULL DEFAULT NULL COMMENT '鍏ヨ亴鏃ユ湡',
+  `permissions` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鏉冮檺',
+  `status` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鐘舵��',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃ユ湡',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_bin COMMENT = '涓氬姟鍛樼鐞嗚〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for scheme_applicable_staff
+-- ----------------------------
+DROP TABLE IF EXISTS `scheme_applicable_staff`;
+CREATE TABLE `scheme_applicable_staff`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏍囬',
+  `dept_ids` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閮ㄩ棬ids',
+  `staff_names` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浜哄憳鍚嶇О,澶氫釜浣跨敤,闅斿紑',
+  `staff_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浜哄憳id,澶氫釜浣跨敤,闅斿紑',
+  `insurance_types` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '淇濋櫓绫诲瀷鍚嶇О澶氫釜浣跨敤,闅斿紑',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_time` timestamp NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_time` timestamp NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `update_user` int NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '绀句繚鏂规閫傜敤浜哄憳琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for scheme_insurance_detail
+-- ----------------------------
+DROP TABLE IF EXISTS `scheme_insurance_detail`;
+CREATE TABLE `scheme_insurance_detail`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '鏄庣粏ID锛堜富閿級',
+  `scheme_id` bigint NULL DEFAULT NULL COMMENT '鍏宠仈鐨勭ぞ淇濇柟妗圛D',
+  `insurance_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '淇濋櫓绫诲瀷锛堝鍖荤枟淇濋櫓銆佸吇鑰佷繚闄╃瓑锛�',
+  `payment_base` decimal(10, 2) NULL DEFAULT NULL COMMENT '缂磋垂鍩烘暟',
+  `use_basic_salary` int NULL DEFAULT 1 COMMENT '鏄惁璋冪敤鍩烘湰宸ヨ祫锛�1-鍚︼紝2-鏄�',
+  `personal_ratio` decimal(5, 2) NULL DEFAULT 0.00 COMMENT '涓汉缂磋垂姣斾緥锛�%锛�',
+  `personal_fixed` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '涓汉鍥哄畾缂磋垂閲戦',
+  `create_time` timestamp NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_time` timestamp NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `update_user` int NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '绀句繚鏂规淇濋櫓绂忓埄鏄庣粏琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for seal_application_management
+-- ----------------------------
+DROP TABLE IF EXISTS `seal_application_management`;
+CREATE TABLE `seal_application_management`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `application_num` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐢宠缂栧彿',
+  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐢宠鏍囬',
+  `seal_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐢ㄥ嵃绫诲瀷',
+  `reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐢宠鐢ㄥ嵃鍘熷洜',
+  `urgency` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绱ф�ョ▼搴�',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐘舵��',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�-鐢宠浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿-鐢宠鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `approve_user_id` int NULL DEFAULT NULL COMMENT '瀹℃壒浜篿d',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢ㄥ嵃鐢宠绠$悊' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for shipping_info
+-- ----------------------------
+DROP TABLE IF EXISTS `shipping_info`;
+CREATE TABLE `shipping_info`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `sales_ledger_id` bigint NULL DEFAULT NULL COMMENT '閿�鍞彴璐d',
+  `shipping_date` datetime NULL DEFAULT NULL COMMENT '鍙戣揣鏃ユ湡',
+  `shipping_car_number` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鍙戣揣杞︾墝鍙�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `sales_ledger_product_id` int NULL DEFAULT NULL COMMENT '閿�鍞彴璐︿骇鍝佽〃id',
+  `shipping_no` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鍙戣揣缂栧彿',
+  `express_number` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '蹇�掑崟鍙�',
+  `express_company` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '蹇�掑叕鍙�',
+  `type` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鍙戣揣绫诲瀷',
+  `status` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鐘舵��',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_shipping_sales_ledger_status`(`sales_ledger_id` ASC, `status` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 68 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_bin COMMENT = '鍙戣揣淇℃伅琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for shipping_product_detail
+-- ----------------------------
+DROP TABLE IF EXISTS `shipping_product_detail`;
+CREATE TABLE `shipping_product_detail`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭id',
+  `stock_inventory_id` bigint NULL DEFAULT NULL COMMENT '搴撳瓨琛╥d',
+  `batch_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎵规鍙�',
+  `quantity` decimal(16, 4) NULL DEFAULT NULL COMMENT '鍙戣揣鐨勬暟閲�',
+  `shipping_info_id` bigint NULL DEFAULT NULL COMMENT '鍙戣揣鍙拌处id',
+  `product_model_id` bigint NULL DEFAULT NULL COMMENT '浜у搧id',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 80 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍙戣揣鍙拌处璇︽儏琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for spare_parts
+-- ----------------------------
+DROP TABLE IF EXISTS `spare_parts`;
+CREATE TABLE `spare_parts`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囦欢鍒嗙被鍚嶇О',
+  `parent_id` int NULL DEFAULT NULL COMMENT '澶囦欢鍒嗙被鐖秈d',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐘舵��',
+  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎻忚堪',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `price` decimal(10, 2) NULL DEFAULT NULL COMMENT '浠锋牸',
+  `quantity` decimal(10, 2) NULL DEFAULT NULL COMMENT '鏁伴噺',
+  `device_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁惧id闆嗗悎锛堝瓧绗︿覆,闅斿紑锛�',
+  `spare_parts_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '璁惧绠$悊-澶囦欢绠$悊' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for spare_parts_requisition_record
+-- ----------------------------
+DROP TABLE IF EXISTS `spare_parts_requisition_record`;
+CREATE TABLE `spare_parts_requisition_record`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `source_type` smallint NULL DEFAULT NULL COMMENT '鏉ユ簮绫诲瀷(0 缁翠慨 1 淇濆吇)',
+  `source_id` bigint NOT NULL DEFAULT 0 COMMENT '鏉ユ簮id',
+  `device_ledger_id` bigint NOT NULL DEFAULT 0 COMMENT '璁惧id',
+  `spare_parts_id` bigint NOT NULL DEFAULT 0 COMMENT '澶囦欢id',
+  `quantity` int NOT NULL DEFAULT 0 COMMENT '鏁伴噺',
+  `create_user` bigint NOT NULL DEFAULT 0 COMMENT '鍒涘缓浜�',
+  `tenant_id` bigint NOT NULL COMMENT '绉熸埛id',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '璁惧鎶ヤ慨淇濆吇鐨勫浠堕浣跨敤琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for staff_contacts_personal
+-- ----------------------------
+DROP TABLE IF EXISTS `staff_contacts_personal`;
+CREATE TABLE `staff_contacts_personal`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `contact_id` int NULL DEFAULT NULL COMMENT '鍛樺伐ID',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_bin COMMENT = '涓汉閫氳褰�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for staff_contract
+-- ----------------------------
+DROP TABLE IF EXISTS `staff_contract`;
+CREATE TABLE `staff_contract`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `staff_on_job_id` bigint NOT NULL DEFAULT 0 COMMENT '鍛樺伐鍦ㄨ亴id',
+  `contract_start_time` datetime NULL DEFAULT NULL COMMENT '鍚堝悓寮�濮嬫椂闂�',
+  `contract_end_time` datetime NULL DEFAULT NULL COMMENT '鍚堝悓缁撴潫鏃堕棿',
+  `contract_term` int NOT NULL DEFAULT 0 COMMENT '鍚堝悓鏈熼檺',
+  `tenant_id` bigint NOT NULL COMMENT '绉熸埛id',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 23 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for staff_education
+-- ----------------------------
+DROP TABLE IF EXISTS `staff_education`;
+CREATE TABLE `staff_education`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `staff_on_job_id` bigint NOT NULL COMMENT '鍏宠仈staff_on_job琛ㄤ富閿甀D',
+  `education` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀛﹀巻',
+  `school_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '姣曚笟闄㈡牎',
+  `enroll_time` date NULL DEFAULT NULL COMMENT '鍏ュ鏃堕棿',
+  `graduate_time` date NULL DEFAULT NULL COMMENT '姣曚笟鏃堕棿',
+  `major` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '涓撲笟',
+  `degree` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀛︿綅',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍛樺伐鏁欒偛缁忓巻琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for staff_emergency_contact
+-- ----------------------------
+DROP TABLE IF EXISTS `staff_emergency_contact`;
+CREATE TABLE `staff_emergency_contact`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `staff_on_job_id` bigint NOT NULL COMMENT '鍏宠仈staff_on_job琛ㄤ富閿甀D',
+  `contact_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绱ф�ヨ仈绯讳汉濮撳悕',
+  `contact_relation` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绱ф�ヨ仈绯讳汉鍏崇郴',
+  `contact_phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绱ф�ヨ仈绯讳汉鎵嬫満',
+  `contact_address` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绱ф�ヨ仈绯讳汉浣忓潃',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍛樺伐绱ф�ヨ仈绯讳汉琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for staff_join_leave_record
+-- ----------------------------
+DROP TABLE IF EXISTS `staff_join_leave_record`;
+CREATE TABLE `staff_join_leave_record`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `staff_state` int NULL DEFAULT NULL COMMENT '鐘舵��(0:绂昏亴;1:鍏ヨ亴)',
+  `staff_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍛樺伐缂栧彿',
+  `leave_date` date NULL DEFAULT NULL COMMENT '绂昏亴鏃ユ湡',
+  `staff_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍛樺伐濮撳悕',
+  `sex` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎬у埆',
+  `native_place` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绫嶈疮',
+  `post_job` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宀椾綅',
+  `adress` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹跺涵浣忓潃',
+  `first_study` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绗竴瀛﹀巻',
+  `profession` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '涓撲笟',
+  `identity_card` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '韬唤璇佸彿鐮�',
+  `age` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '骞撮緞',
+  `phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鑱旂郴鐢佃瘽',
+  `emergency_contact` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绱ф�ヨ仈绯讳汉',
+  `emergency_contact_phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绱ф�ヨ仈绯讳汉鐢佃瘽',
+  `contract_term` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍚堝悓骞撮檺',
+  `contract_start_time` date NULL DEFAULT NULL COMMENT '鍚堝悓寮�濮嬫棩鏈�',
+  `contract_end_time` date NULL DEFAULT NULL COMMENT '鍚堝悓缁撴潫鏃ユ湡',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `probation_period` int NULL DEFAULT NULL COMMENT '璇曠敤鏈燂紙鏈堬級',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浜哄憳绠$悊--鏂板鍏ヨ亴/绂昏亴' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for staff_leave
+-- ----------------------------
+DROP TABLE IF EXISTS `staff_leave`;
+CREATE TABLE `staff_leave`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `staff_on_job_id` bigint NOT NULL DEFAULT 0 COMMENT '鍛樺伐鍦ㄨ亴id',
+  `reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绂昏亴鍘熷洜',
+  `remark` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '绂昏亴澶囨敞',
+  `tenant_id` bigint NOT NULL COMMENT '绉熸埛id',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `leave_date` date NULL DEFAULT NULL COMMENT '绂昏亴鏃ユ湡',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for staff_on_job
+-- ----------------------------
+DROP TABLE IF EXISTS `staff_on_job`;
+CREATE TABLE `staff_on_job`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `staff_state` int NULL DEFAULT NULL COMMENT '鐘舵��(0:绂昏亴;1:鍦ㄨ亴)',
+  `staff_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍛樺伐缂栧彿',
+  `staff_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍛樺伐濮撳悕',
+  `sex` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎬у埆',
+  `native_place` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绫嶈疮',
+  `adress` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹跺涵浣忓潃',
+  `first_study` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绗竴瀛﹀巻',
+  `profession` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '涓撲笟',
+  `identity_card` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '韬唤璇佸彿鐮�',
+  `age` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '骞撮緞',
+  `phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鑱旂郴鐢佃瘽',
+  `emergency_contact` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绱ф�ヨ仈绯讳汉',
+  `emergency_contact_phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绱ф�ヨ仈绯讳汉鐢佃瘽',
+  `contract_term` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍚堝悓骞撮檺',
+  `contract_expire_time` date NULL DEFAULT NULL COMMENT '鍚堝悓鍒版湡鏃ユ湡',
+  `trial_end_date` date NULL DEFAULT NULL COMMENT '缁撴潫璇曠敤鏃堕棿',
+  `trial_start_date` date NULL DEFAULT NULL COMMENT '寮�濮嬭瘯鐢ㄦ椂闂�',
+  `salary_select` char(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宸ヨ祫鎶ラ叕閫夋嫨鏉℃',
+  `pro_salary` decimal(10, 2) NULL DEFAULT NULL COMMENT '璇曠敤鏈熷伐璧�',
+  `date_select` char(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍔冲姩鍚堝悓鏈熼檺閫夋嫨',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '鏃�' COMMENT '澶囨敞锛堢鍒╁緟閬囷級',
+  `sign_date` date NULL DEFAULT NULL COMMENT '绛捐鏃ユ湡',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `sys_post_id` bigint NOT NULL DEFAULT 0 COMMENT '宀椾綅id',
+  `sys_dept_id` bigint NOT NULL DEFAULT 0 COMMENT '閮ㄩ棬id',
+  `role_id` bigint NULL DEFAULT NULL COMMENT '瑙掕壊id',
+  `alias` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍒悕',
+  `birth_date` date NULL DEFAULT NULL COMMENT '鍑虹敓鏃ユ湡',
+  `nation` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '姹夋棌' COMMENT '姘戞棌',
+  `marital_status` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '鏈' COMMENT '濠氬Щ鐘跺喌',
+  `pro_term` int NULL DEFAULT 3 COMMENT '璇曠敤鏈燂紙鏈堬級',
+  `positive_date` date NULL DEFAULT NULL COMMENT '杞鏃ユ湡',
+  `basic_salary` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '鍩烘湰宸ヨ祫',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE INDEX `staff_no`(`staff_no` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 27 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浜哄憳绠$悊--鍛樺伐鍙拌处/鍚堝悓绠$悊' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for staff_salary_detail
+-- ----------------------------
+DROP TABLE IF EXISTS `staff_salary_detail`;
+CREATE TABLE `staff_salary_detail`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `main_id` bigint NOT NULL COMMENT '鍏宠仈宸ヨ祫涓昏〃ID',
+  `staff_on_job_id` bigint NOT NULL COMMENT '鍏宠仈staff_on_job琛ㄤ富閿甀D',
+  `staff_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍛樺伐濮撳悕',
+  `post_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鑱屼綅鍚嶇О',
+  `dept_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閮ㄩ棬鍚嶇О',
+  `basic_salary` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '鍩烘湰宸ヨ祫',
+  `piece_salary` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '璁′欢宸ヨ祫',
+  `hourly_salary` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '璁℃椂宸ヨ祫',
+  `other_income` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '鍏朵粬鏀跺叆',
+  `social_personal` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '绀句繚涓汉',
+  `fund_personal` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '鍏Н閲戜釜浜�',
+  `other_deduct` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '鍏朵粬鏀嚭',
+  `salary_tax` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '宸ヨ祫涓◣',
+  `gross_salary` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '搴斿彂宸ヨ祫',
+  `deduct_salary` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '搴旀墸宸ヨ祫',
+  `net_salary` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '瀹炲彂宸ヨ祫',
+  `remark` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `social_supplement_amount` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '绀句繚琛ョ即',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 185 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍛樺伐宸ヨ祫鏄庣粏琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for staff_salary_main
+-- ----------------------------
+DROP TABLE IF EXISTS `staff_salary_main`;
+CREATE TABLE `staff_salary_main`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `audit_user_id` bigint NULL DEFAULT NULL COMMENT '瀹℃牳浜篿d',
+  `audit_user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹℃牳浜哄悕绉�',
+  `salary_title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宸ヨ祫涓婚',
+  `dept_ids` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍏宠仈閮ㄩ棬ID锛屽涓敤閫楀彿鍒嗛殧',
+  `salary_month` varchar(7) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宸ヨ祫鏈堜唤锛屾牸寮忥細yyyy-MM',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `status` tinyint NOT NULL DEFAULT 0 COMMENT '鐘舵�侊細1-鑽夌 2-瀹℃牳鏈�氳繃 3-寰呭鏍� 4-寰呭彂鏀� 5-宸插彂鏀�',
+  `total_salary` decimal(12, 2) NULL DEFAULT NULL COMMENT '宸ヨ祫鎬婚',
+  `pay_bank` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏀粯閾惰',
+  `pay_time` datetime NULL DEFAULT NULL COMMENT '鍙戞斁鏃堕棿',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍛樺伐宸ヨ祫涓昏〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for staff_scheduling
+-- ----------------------------
+DROP TABLE IF EXISTS `staff_scheduling`;
+CREATE TABLE `staff_scheduling`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `staff_id` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鍛樺伐ID',
+  `department` int NULL DEFAULT NULL COMMENT '閮ㄩ棬',
+  `shift_type` int NULL DEFAULT NULL COMMENT '鎺掔彮绫诲瀷',
+  `work_date` date NULL DEFAULT NULL COMMENT '宸ヤ綔鏃ユ湡',
+  `work_start_time` timestamp NULL DEFAULT NULL COMMENT '寮�濮嬪伐浣滄椂闂�',
+  `lunch_time` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '鍗堜紤鏃堕棿',
+  `work_end_time` timestamp NULL DEFAULT NULL COMMENT '缁撴潫宸ヤ綔鏃堕棿',
+  `work_hours` decimal(10, 2) NULL DEFAULT NULL COMMENT '宸ヤ綔鏃堕暱',
+  `status` int NULL DEFAULT NULL COMMENT '鐘舵��',
+  `staff_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL,
+  `remark` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_bin ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for staff_work_experience
+-- ----------------------------
+DROP TABLE IF EXISTS `staff_work_experience`;
+CREATE TABLE `staff_work_experience`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `staff_on_job_id` bigint NOT NULL COMMENT '鍏宠仈staff_on_job琛ㄤ富閿甀D',
+  `former_company` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍓嶅叕鍙�',
+  `former_dept` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍓嶅叕鍙搁儴闂�',
+  `former_position` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍓嶅叕鍙歌亴浣�',
+  `start_date` date NULL DEFAULT NULL COMMENT '寮�濮嬫棩鏈�',
+  `end_date` date NULL DEFAULT NULL COMMENT '缁撴潫鏃ユ湡',
+  `work_desc` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宸ヤ綔鎻忚堪',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍛樺伐宸ヤ綔缁忓巻琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for stock_in_record
+-- ----------------------------
+DROP TABLE IF EXISTS `stock_in_record`;
+CREATE TABLE `stock_in_record`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `inbound_batches` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍏ュ簱鎵规',
+  `batch_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎵瑰彿',
+  `stock_in_num` decimal(16, 4) NULL DEFAULT NULL COMMENT '鍏ュ簱鏁伴噺',
+  `record_id` int NULL DEFAULT NULL COMMENT '鍏ュ簱鏉ユ簮id',
+  `record_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍏ュ簱绫诲瀷',
+  `product_model_id` int NULL DEFAULT NULL COMMENT '浜у搧瑙勬牸id',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_time` timestamp NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_time` timestamp NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `update_user` int NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '0鍚堟牸鍏ュ簱1涓嶅悎鏍煎叆搴�',
+  `weighing_date` datetime NULL DEFAULT NULL COMMENT '杩囩鏃ユ湡',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `approval_status` int NULL DEFAULT 0,
+  `warn_num` decimal(16, 4) NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 153 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍏ュ簱璁板綍琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for stock_inventory
+-- ----------------------------
+DROP TABLE IF EXISTS `stock_inventory`;
+CREATE TABLE `stock_inventory`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭id',
+  `product_model_id` int NULL DEFAULT NULL COMMENT '瑙勬牸id',
+  `batch_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎵瑰彿',
+  `qualitity` decimal(16, 4) NULL DEFAULT NULL COMMENT '鏁伴噺',
+  `create_time` timestamp NULL DEFAULT NULL,
+  `update_time` timestamp NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `version` int NULL DEFAULT NULL COMMENT '鐗堟湰鍙�',
+  `locked_quantity` decimal(16, 4) NULL DEFAULT 0.0000 COMMENT '琚鍗曢攣瀹氭暟閲�',
+  `warn_num` decimal(16, 4) NULL DEFAULT NULL COMMENT '棰勮鏁伴噺',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 72 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '搴撳瓨琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for stock_out_record
+-- ----------------------------
+DROP TABLE IF EXISTS `stock_out_record`;
+CREATE TABLE `stock_out_record`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `outbound_batches` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍏ュ簱鎵规',
+  `batch_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎵瑰彿',
+  `stock_out_num` decimal(16, 4) NULL DEFAULT NULL COMMENT '鍏ュ簱鏁伴噺',
+  `record_id` int NULL DEFAULT NULL COMMENT '鍏ュ簱鏉ユ簮id',
+  `record_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍏ュ簱绫诲瀷',
+  `product_model_id` int NULL DEFAULT NULL COMMENT '浜у搧瑙勬牸id',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_time` timestamp NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_time` timestamp NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `update_user` int NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+  `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '0鍚堟牸鍑哄簱1涓嶅悎鏍煎嚭搴�',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `approval_status` int NULL DEFAULT 0 COMMENT '瀹℃壒鐘舵��  0-寰呭鎵� 1-閫氳繃 2-椹冲洖 3-閿�鍞嚭搴撳緟纭',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 157 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍑哄簱璁板綍琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for stock_uninventory
+-- ----------------------------
+DROP TABLE IF EXISTS `stock_uninventory`;
+CREATE TABLE `stock_uninventory`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭id',
+  `product_model_id` int NULL DEFAULT NULL COMMENT '瑙勬牸id',
+  `batch_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鎵瑰彿',
+  `qualitity` decimal(16, 4) NULL DEFAULT NULL COMMENT '鏁伴噺',
+  `create_time` timestamp NULL DEFAULT NULL,
+  `update_time` timestamp NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `version` int NULL DEFAULT NULL COMMENT '鐗堟湰鍙�',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `locked_quantity` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍐荤粨鏁伴噺',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '涓嶅悎鏍煎簱瀛樿〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for storage_attachment
+-- ----------------------------
+DROP TABLE IF EXISTS `storage_attachment`;
+CREATE TABLE `storage_attachment`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `deleted` bigint NOT NULL DEFAULT 0 COMMENT '閫昏緫鍒犻櫎锛�0姝e父锛�',
+  `record_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍏宠仈鐨勮褰曠被鍨�',
+  `record_id` bigint NULL DEFAULT NULL COMMENT '鍏宠仈鐨勮褰旾D',
+  `application` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囦欢鐢ㄩ�旓紝濡� file/avatar',
+  `storage_blob_id` bigint NULL DEFAULT NULL COMMENT '鍏宠仈storage_blob璁板綍ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 215 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鏂囦欢鍏宠仈琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for storage_blob
+-- ----------------------------
+DROP TABLE IF EXISTS `storage_blob`;
+CREATE TABLE `storage_blob`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `resource_key` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璧勬簮鍞竴鏍囪瘑锛堝瀵硅薄瀛樺偍key锛�',
+  `content_type` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璧勬簮绫诲瀷锛屽 image/jpeg',
+  `original_filename` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍘熸枃浠跺悕',
+  `uid_filename` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鍞竴鏂囦欢鍚�',
+  `byte_size` bigint NULL DEFAULT NULL COMMENT '鏂囦欢澶у皬锛堝瓧鑺傦級',
+  `path` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囦欢璺緞锛堟湰鍦版垨URL锛�',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 195 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鏂囦欢琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for supplier_manage
+-- ----------------------------
+DROP TABLE IF EXISTS `supplier_manage`;
+CREATE TABLE `supplier_manage`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `supplier_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '渚涘簲鍟嗗悕绉�',
+  `taxpayer_identification_num` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '绾崇◣浜鸿瘑鍒彿',
+  `company_address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍏徃鍦板潃',
+  `supplier_type` varchar(25) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '渚涘簲鍟嗙被鍨�',
+  `company_phone` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍏徃鐢佃瘽',
+  `bank_account_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '寮�鎴疯',
+  `bank_account_num` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璐﹀彿',
+  `contact_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鑱旂郴浜�',
+  `contact_user_phone` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鑱旂郴鐢佃瘽',
+  `maintain_user_id` bigint NULL DEFAULT NULL COMMENT '缁存姢浜篒D',
+  `maintain_time` datetime NULL DEFAULT NULL COMMENT '缁存姢鏃堕棿',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `is_white` bigint NULL DEFAULT 0 COMMENT '鏄惁鐧藉悕鍗曪紙0鏄� 1鍚︼級',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 223 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '渚涘簲鍟嗙鐞�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for supplier_manage_file
+-- ----------------------------
+DROP TABLE IF EXISTS `supplier_manage_file`;
+CREATE TABLE `supplier_manage_file`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囦欢鍚嶇О',
+  `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏂囦欢璺緞',
+  `file_size` int NULL DEFAULT NULL COMMENT '鏂囦欢澶у皬',
+  `supplier_id` bigint NULL DEFAULT NULL COMMENT '渚涘簲鍟咺D',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '渚涘簲鍟嗙鐞�--璧勮川闄勪欢' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_config
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_config`;
+CREATE TABLE `sys_config`  (
+  `config_id` int NOT NULL AUTO_INCREMENT COMMENT '鍙傛暟涓婚敭',
+  `config_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鍙傛暟鍚嶇О',
+  `config_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鍙傛暟閿悕',
+  `config_value` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鍙傛暟閿��',
+  `config_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'N' COMMENT '绯荤粺鍐呯疆锛圷鏄� N鍚︼級',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鏇存柊鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  PRIMARY KEY (`config_id`) USING BTREE,
+  INDEX `idx_config_key`(`config_key` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍙傛暟閰嶇疆琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_dept
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_dept`;
+CREATE TABLE `sys_dept`  (
+  `dept_id` bigint NOT NULL AUTO_INCREMENT COMMENT '閮ㄩ棬id',
+  `parent_id` bigint NULL DEFAULT 0 COMMENT '鐖堕儴闂╥d',
+  `ancestors` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '绁栫骇鍒楄〃',
+  `dept_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '閮ㄩ棬鍚嶇О',
+  `order_num` int NULL DEFAULT 0 COMMENT '鏄剧ず椤哄簭',
+  `leader` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璐熻矗浜�',
+  `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鑱旂郴鐢佃瘽',
+  `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閭',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '閮ㄩ棬鐘舵�侊紙0姝e父 1鍋滅敤锛�',
+  `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鏇存柊鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `dept_nick` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閮ㄩ棬缂栧彿',
+  PRIMARY KEY (`dept_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 213 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '閮ㄩ棬琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_dict_data
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_dict_data`;
+CREATE TABLE `sys_dict_data`  (
+  `dict_code` bigint NOT NULL AUTO_INCREMENT COMMENT '瀛楀吀缂栫爜',
+  `dict_sort` int NULL DEFAULT 0 COMMENT '瀛楀吀鎺掑簭',
+  `dict_label` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '瀛楀吀鏍囩',
+  `dict_value` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '瀛楀吀閿��',
+  `dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '瀛楀吀绫诲瀷',
+  `css_class` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏍峰紡灞炴�э紙鍏朵粬鏍峰紡鎵╁睍锛�',
+  `list_class` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '琛ㄦ牸鍥炴樉鏍峰紡',
+  `is_default` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'N' COMMENT '鏄惁榛樿锛圷鏄� N鍚︼級',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '鐘舵�侊紙0姝e父 1鍋滅敤锛�',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鏇存柊鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  PRIMARY KEY (`dict_code`) USING BTREE,
+  INDEX `idx_dict_type_status`(`dict_type` ASC, `status` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 260 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀛楀吀鏁版嵁琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_dict_type
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_dict_type`;
+CREATE TABLE `sys_dict_type`  (
+  `dict_id` bigint NOT NULL AUTO_INCREMENT COMMENT '瀛楀吀涓婚敭',
+  `dict_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '瀛楀吀鍚嶇О',
+  `dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '瀛楀吀绫诲瀷',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '鐘舵�侊紙0姝e父 1鍋滅敤锛�',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鏇存柊鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  PRIMARY KEY (`dict_id`) USING BTREE,
+  UNIQUE INDEX `dict_type`(`dict_type` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 137 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀛楀吀绫诲瀷琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_job
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_job`;
+CREATE TABLE `sys_job`  (
+  `job_id` bigint NOT NULL AUTO_INCREMENT COMMENT '浠诲姟ID',
+  `job_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '浠诲姟鍚嶇О',
+  `job_group` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'DEFAULT' COMMENT '浠诲姟缁勫悕',
+  `invoke_target` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璋冪敤鐩爣瀛楃涓�',
+  `cron_expression` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT 'cron鎵ц琛ㄨ揪寮�',
+  `misfire_policy` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '3' COMMENT '璁″垝鎵ц閿欒绛栫暐锛�1绔嬪嵆鎵ц 2鎵ц涓�娆� 3鏀惧純鎵ц锛�',
+  `concurrent` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '1' COMMENT '鏄惁骞跺彂鎵ц锛�0鍏佽 1绂佹锛�',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '鐘舵�侊紙0姝e父 1鏆傚仠锛�',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鏇存柊鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '澶囨敞淇℃伅',
+  PRIMARY KEY (`job_id`, `job_name`, `job_group`) USING BTREE,
+  INDEX `idx_job_status`(`status` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹氭椂浠诲姟璋冨害琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_job_log
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_job_log`;
+CREATE TABLE `sys_job_log`  (
+  `job_log_id` bigint NOT NULL AUTO_INCREMENT COMMENT '浠诲姟鏃ュ織ID',
+  `job_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '浠诲姟鍚嶇О',
+  `job_group` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '浠诲姟缁勫悕',
+  `invoke_target` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璋冪敤鐩爣瀛楃涓�',
+  `job_message` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏃ュ織淇℃伅',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '鎵ц鐘舵�侊紙0姝e父 1澶辫触锛�',
+  `exception_info` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '寮傚父淇℃伅',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  PRIMARY KEY (`job_log_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹氭椂浠诲姟璋冨害鏃ュ織琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_logininfor
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_logininfor`;
+CREATE TABLE `sys_logininfor`  (
+  `info_id` bigint NOT NULL AUTO_INCREMENT COMMENT '璁块棶ID',
+  `user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鐢ㄦ埛璐﹀彿',
+  `ipaddr` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鐧诲綍IP鍦板潃',
+  `login_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鐧诲綍鍦扮偣',
+  `browser` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '娴忚鍣ㄧ被鍨�',
+  `os` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鎿嶄綔绯荤粺',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '鐧诲綍鐘舵�侊紙0鎴愬姛 1澶辫触锛�',
+  `msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鎻愮ず娑堟伅',
+  `login_time` datetime NULL DEFAULT NULL COMMENT '璁块棶鏃堕棿',
+  PRIMARY KEY (`info_id`) USING BTREE,
+  INDEX `idx_sys_logininfor_s`(`status` ASC) USING BTREE,
+  INDEX `idx_sys_logininfor_lt`(`login_time` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 4498 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '绯荤粺璁块棶璁板綍' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_menu
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_menu`;
+CREATE TABLE `sys_menu`  (
+  `menu_id` bigint NOT NULL AUTO_INCREMENT COMMENT '鑿滃崟ID',
+  `menu_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鑿滃崟鍚嶇О',
+  `parent_id` bigint NULL DEFAULT 0 COMMENT '鐖惰彍鍗旾D',
+  `order_num` int NULL DEFAULT 0 COMMENT '鏄剧ず椤哄簭',
+  `path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '璺敱鍦板潃',
+  `component` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '缁勪欢璺緞',
+  `query` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璺敱鍙傛暟',
+  `route_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '璺敱鍚嶇О',
+  `is_frame` int NULL DEFAULT 1 COMMENT '鏄惁涓哄閾撅紙0鏄� 1鍚︼級',
+  `is_cache` int NULL DEFAULT 0 COMMENT '鏄惁缂撳瓨锛�0缂撳瓨 1涓嶇紦瀛橈級',
+  `menu_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鑿滃崟绫诲瀷锛圡鐩綍 C鑿滃崟 F鎸夐挳锛�',
+  `visible` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '鑿滃崟鐘舵�侊紙0鏄剧ず 1闅愯棌锛�',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '鑿滃崟鐘舵�侊紙0姝e父 1鍋滅敤锛�',
+  `perms` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏉冮檺鏍囪瘑',
+  `icon` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '#' COMMENT '鑿滃崟鍥炬爣',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鏇存柊鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '澶囨敞',
+  `app_component` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'app缁勪欢璺緞',
+  PRIMARY KEY (`menu_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 2348 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鑿滃崟鏉冮檺琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_notice
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_notice`;
+CREATE TABLE `sys_notice`  (
+  `notice_id` int NOT NULL AUTO_INCREMENT COMMENT '鍏憡ID',
+  `notice_title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鍏憡鏍囬',
+  `notice_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鍏憡绫诲瀷锛�1閫氱煡 2鍏憡锛�',
+  `notice_content` longblob NULL COMMENT '鍏憡鍐呭',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '鍏憡鐘舵�侊紙0姝e父 1鍏抽棴锛�',
+  `consignee_id` bigint NULL DEFAULT NULL COMMENT '鍙戦�佷汉id',
+  `sender_id` bigint NULL DEFAULT NULL COMMENT '鏀朵欢浜篿d',
+  `jump_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璺宠浆璺緞',
+  `app_jump_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'APP璺宠浆璺緞',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鏇存柊鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `tenant_id` int NULL DEFAULT NULL,
+  PRIMARY KEY (`notice_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1296 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '閫氱煡鍏憡琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_oper_log
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_oper_log`;
+CREATE TABLE `sys_oper_log`  (
+  `oper_id` bigint NOT NULL AUTO_INCREMENT COMMENT '鏃ュ織涓婚敭',
+  `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '妯″潡鏍囬',
+  `business_type` int NULL DEFAULT 0 COMMENT '涓氬姟绫诲瀷锛�0鍏跺畠 1鏂板 2淇敼 3鍒犻櫎锛�',
+  `method` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鏂规硶鍚嶇О',
+  `request_method` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '璇锋眰鏂瑰紡',
+  `operator_type` int NULL DEFAULT 0 COMMENT '鎿嶄綔绫诲埆锛�0鍏跺畠 1鍚庡彴鐢ㄦ埛 2鎵嬫満绔敤鎴凤級',
+  `oper_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鎿嶄綔浜哄憳',
+  `dept_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '閮ㄩ棬鍚嶇О',
+  `oper_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '璇锋眰URL',
+  `oper_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '涓绘満鍦板潃',
+  `oper_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鎿嶄綔鍦扮偣',
+  `oper_param` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '璇锋眰鍙傛暟',
+  `json_result` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '杩斿洖鍙傛暟',
+  `status` int NULL DEFAULT 0 COMMENT '鎿嶄綔鐘舵�侊紙0姝e父 1寮傚父锛�',
+  `error_msg` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '閿欒娑堟伅',
+  `oper_time` datetime NULL DEFAULT NULL COMMENT '鎿嶄綔鏃堕棿',
+  `cost_time` bigint NULL DEFAULT 0 COMMENT '娑堣�楁椂闂�',
+  PRIMARY KEY (`oper_id`) USING BTREE,
+  INDEX `idx_sys_oper_log_bt`(`business_type` ASC) USING BTREE,
+  INDEX `idx_sys_oper_log_s`(`status` ASC) USING BTREE,
+  INDEX `idx_sys_oper_log_ot`(`oper_time` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 119789 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鎿嶄綔鏃ュ織璁板綍' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_post
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_post`;
+CREATE TABLE `sys_post`  (
+  `post_id` bigint NOT NULL AUTO_INCREMENT COMMENT '宀椾綅ID',
+  `post_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '宀椾綅缂栫爜',
+  `post_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '宀椾綅鍚嶇О',
+  `post_sort` int NOT NULL COMMENT '鏄剧ず椤哄簭',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鐘舵�侊紙0姝e父 1鍋滅敤锛�',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鏇存柊鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  PRIMARY KEY (`post_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 26 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '宀椾綅淇℃伅琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_role
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_role`;
+CREATE TABLE `sys_role`  (
+  `role_id` bigint NOT NULL AUTO_INCREMENT COMMENT '瑙掕壊ID',
+  `role_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瑙掕壊鍚嶇О',
+  `role_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瑙掕壊鏉冮檺瀛楃涓�',
+  `role_sort` int NOT NULL COMMENT '鏄剧ず椤哄簭',
+  `data_scope` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '1' COMMENT '鏁版嵁鑼冨洿锛�1锛氬叏閮ㄦ暟鎹潈闄� 2锛氳嚜瀹氭暟鎹潈闄� 3锛氭湰閮ㄩ棬鏁版嵁鏉冮檺 4锛氭湰閮ㄩ棬鍙婁互涓嬫暟鎹潈闄愶級',
+  `menu_check_strictly` tinyint(1) NULL DEFAULT 1 COMMENT '鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�',
+  `dept_check_strictly` tinyint(1) NULL DEFAULT 1 COMMENT '閮ㄩ棬鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '瑙掕壊鐘舵�侊紙0姝e父 1鍋滅敤锛�',
+  `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鏇存柊鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  PRIMARY KEY (`role_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 112 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瑙掕壊淇℃伅琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_role_dept
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_role_dept`;
+CREATE TABLE `sys_role_dept`  (
+  `role_id` bigint NOT NULL COMMENT '瑙掕壊ID',
+  `dept_id` bigint NOT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`role_id`, `dept_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瑙掕壊鍜岄儴闂ㄥ叧鑱旇〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_role_menu
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_role_menu`;
+CREATE TABLE `sys_role_menu`  (
+  `role_id` bigint NOT NULL COMMENT '瑙掕壊ID',
+  `menu_id` bigint NOT NULL COMMENT '鑿滃崟ID',
+  PRIMARY KEY (`role_id`, `menu_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瑙掕壊鍜岃彍鍗曞叧鑱旇〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_user
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_user`;
+CREATE TABLE `sys_user`  (
+  `user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '鐢ㄦ埛ID',
+  `user_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鐢ㄦ埛璐﹀彿',
+  `nick_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鐢ㄦ埛鏄电О',
+  `user_type` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '00' COMMENT '鐢ㄦ埛绫诲瀷锛�00绯荤粺鐢ㄦ埛锛�',
+  `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鐢ㄦ埛閭',
+  `phonenumber` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鎵嬫満鍙风爜',
+  `sex` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '鐢ㄦ埛鎬у埆锛�0鐢� 1濂� 2鏈煡锛�',
+  `avatar` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '澶村儚鍦板潃',
+  `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '瀵嗙爜',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '璐﹀彿鐘舵�侊紙0姝e父 1鍋滅敤锛�',
+  `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�',
+  `login_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鏈�鍚庣櫥褰旾P',
+  `login_date` datetime NULL DEFAULT NULL COMMENT '鏈�鍚庣櫥褰曟椂闂�',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '鏇存柊鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `ai_enabled` tinyint(1) NOT NULL DEFAULT 0 COMMENT '鏄惁寮�閫欰I鍔熻兘锛�0鍚� 1鏄級',
+  PRIMARY KEY (`user_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 262 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢ㄦ埛淇℃伅琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_user_client
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_user_client`;
+CREATE TABLE `sys_user_client`  (
+  `user_id` bigint NOT NULL COMMENT '鐢ㄦ埛ID',
+  `cid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '涓帹CID',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏈�鍚庢椿璺冩椂闂�',
+  PRIMARY KEY (`user_id`) USING BTREE,
+  UNIQUE INDEX `uk_cid`(`cid` ASC) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢ㄦ埛瀹夊崜璁惧' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_user_dept
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_user_dept`;
+CREATE TABLE `sys_user_dept`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `user_id` bigint NULL DEFAULT NULL COMMENT 'sys_user琛ㄤ富閿�',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT 'sys_dept琛ㄤ富閿�',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 648 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_user_post
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_user_post`;
+CREATE TABLE `sys_user_post`  (
+  `user_id` bigint NOT NULL COMMENT '鐢ㄦ埛ID',
+  `post_id` bigint NOT NULL COMMENT '宀椾綅ID',
+  PRIMARY KEY (`user_id`, `post_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢ㄦ埛涓庡矖浣嶅叧鑱旇〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for sys_user_role
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_user_role`;
+CREATE TABLE `sys_user_role`  (
+  `user_id` bigint NOT NULL COMMENT '鐢ㄦ埛ID',
+  `role_id` bigint NOT NULL COMMENT '瑙掕壊ID',
+  PRIMARY KEY (`user_id`, `role_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢ㄦ埛鍜岃鑹插叧鑱旇〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for technology_bom
+-- ----------------------------
+DROP TABLE IF EXISTS `technology_bom`;
+CREATE TABLE `technology_bom`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `product_model_id` bigint NOT NULL COMMENT '浜у搧瑙勬牸id',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `version` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐗堟湰鍙�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '鏇存柊鑰�',
+  `bom_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'BOM缂栧彿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'BOM琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for technology_bom_structure
+-- ----------------------------
+DROP TABLE IF EXISTS `technology_bom_structure`;
+CREATE TABLE `technology_bom_structure`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `parent_id` bigint NULL DEFAULT NULL COMMENT '鐖惰妭鐐笽D',
+  `product_model_id` bigint NOT NULL COMMENT '浜у搧id',
+  `operation_id` bigint NULL DEFAULT NULL COMMENT '宸ュ簭id',
+  `unit_quantity` decimal(16, 4) NOT NULL COMMENT '鍗曚綅浜у嚭闇�瑕佹暟閲�',
+  `demanded_quantity` decimal(16, 4) NULL DEFAULT NULL COMMENT '闇�姹傛暟閲�',
+  `unit` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `bom_id` bigint NOT NULL COMMENT 'bom鐨刬d',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 61 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'BOM浜у搧缁撴瀯琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for technology_operation
+-- ----------------------------
+DROP TABLE IF EXISTS `technology_operation`;
+CREATE TABLE `technology_operation`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '宸ヨ壓鍚嶇О',
+  `no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '宸ヨ壓缂栧彿',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '澶囨敞',
+  `salary_quota` decimal(16, 3) NULL DEFAULT NULL COMMENT '宸ヨ祫瀹氶',
+  `is_quality` tinyint(1) NULL DEFAULT 1 COMMENT '鏄惁璐ㄦ宸ュ簭',
+  `is_production` tinyint(1) NULL DEFAULT 1 COMMENT '鏄惁鐢熶骇',
+  `type` int NULL DEFAULT NULL COMMENT '绫诲瀷 鍖哄垎璁℃椂鍜岃浠�(0璁℃椂1璁′欢)',
+  `device_ledger_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁惧id',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 18 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '宸ュ簭琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for technology_operation_param
+-- ----------------------------
+DROP TABLE IF EXISTS `technology_operation_param`;
+CREATE TABLE `technology_operation_param`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `technology_param_id` bigint NULL DEFAULT NULL COMMENT '鍩虹鍙傛暟琛╥d',
+  `technology_operation_id` bigint NULL DEFAULT NULL COMMENT '宸ュ簭id',
+  `standard_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '鏍囧噯鍊�',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '宸ュ簭鍙傛暟' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for technology_param
+-- ----------------------------
+DROP TABLE IF EXISTS `technology_param`;
+CREATE TABLE `technology_param`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `param_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鍙傛暟缂栫爜(鍞竴鏍囪瘑)',
+  `param_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鍙傛暟鍚嶇О',
+  `param_type` tinyint NOT NULL COMMENT '鍙傛暟绫诲瀷(1鏁板瓧 2鏂囨湰 3涓嬫媺閫夋嫨 4鏃堕棿)',
+  `param_format` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍙傛暟鏍煎紡',
+  `unit` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `is_required` tinyint NULL DEFAULT 0 COMMENT '鏄惁蹇呭~',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 38 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鍩虹鍙傛暟琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for technology_routing
+-- ----------------------------
+DROP TABLE IF EXISTS `technology_routing`;
+CREATE TABLE `technology_routing`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `product_model_id` bigint NOT NULL DEFAULT 0 COMMENT '浜у搧id',
+  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '鎻忚堪',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `process_route_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宸ヨ壓璺嚎缂栫爜',
+  `bom_id` int NULL DEFAULT NULL COMMENT '鍏宠仈bom鐨刬d',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '宸ヨ壓璺嚎琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for technology_routing_operation
+-- ----------------------------
+DROP TABLE IF EXISTS `technology_routing_operation`;
+CREATE TABLE `technology_routing_operation`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `technology_routing_id` bigint NOT NULL DEFAULT 0 COMMENT '宸ヨ壓璺嚎id',
+  `product_model_id` bigint NOT NULL DEFAULT 0 COMMENT '浜у搧id',
+  `technology_operation_id` bigint NOT NULL DEFAULT 0 COMMENT '宸ュ簭id',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '褰曞叆鏃堕棿',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `drag_sort` int NULL DEFAULT NULL COMMENT '鎷栧姩鎺掑簭',
+  `is_quality` tinyint(1) NULL DEFAULT 1 COMMENT '鏄惁璐ㄦ宸ュ簭',
+  `is_production` tinyint(1) NULL DEFAULT 1 COMMENT '鏄惁鐢熶骇',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `type` int NULL DEFAULT NULL COMMENT '绫诲瀷 鍖哄垎璁℃椂鍜岃浠�(0璁℃椂1璁′欢)',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 42 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '宸ヨ壓璺嚎宸ュ簭琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for technology_routing_operation_param
+-- ----------------------------
+DROP TABLE IF EXISTS `technology_routing_operation_param`;
+CREATE TABLE `technology_routing_operation_param`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `param_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '鍙傛暟缂栫爜(鍞竴鏍囪瘑)',
+  `param_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '鍙傛暟鍚嶇О',
+  `param_type` tinyint NOT NULL COMMENT '鍙傛暟绫诲瀷(1鏁板瓧 2鏂囨湰 3涓嬫媺閫夋嫨 4鏃堕棿)',
+  `param_format` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍙傛暟鏍煎紡',
+  `unit` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍗曚綅',
+  `is_required` tinyint NULL DEFAULT 0 COMMENT '鏄惁蹇呭~',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `create_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '淇敼浜�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  `param_id` bigint NULL DEFAULT NULL COMMENT '鍩虹鍙傛暟ID',
+  `technology_operation_id` bigint NULL DEFAULT NULL COMMENT '宸ュ簭id',
+  `technology_operation_param_id` bigint NULL DEFAULT NULL COMMENT '宸ュ簭鍙傛暟ID',
+  `technology_routing_operation_id` bigint NULL DEFAULT NULL COMMENT '宸ヨ壓璺嚎宸ュ簭ID',
+  `standard_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鏍囧噯鍊�',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 79 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '宸ヨ壓璺嚎宸ュ簭鍙傛暟琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for temp_file
+-- ----------------------------
+DROP TABLE IF EXISTS `temp_file`;
+CREATE TABLE `temp_file`  (
+  `temp_id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '涓存椂鏂囦欢ID',
+  `original_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鍘熷鏂囦欢鍚�',
+  `temp_path` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '涓存椂瀛樺偍璺緞',
+  `expire_time` datetime NOT NULL COMMENT '杩囨湡鏃堕棿',
+  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `status` tinyint NULL DEFAULT 0 COMMENT '鐘舵�侊細0=涓存椂锛�1=宸茬‘璁わ紝2=宸茶繃鏈�',
+  `type` int NULL DEFAULT NULL,
+  `file_size` bigint NULL DEFAULT NULL COMMENT '鏂囦欢澶у皬',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`temp_id`) USING BTREE,
+  INDEX `idx_expire_time`(`expire_time` ASC) USING BTREE COMMENT '鐢ㄤ簬杩囨湡鏂囦欢娓呯悊鐨勭储寮�',
+  INDEX `idx_status`(`status` ASC) USING BTREE COMMENT '鐢ㄤ簬鐘舵�佹煡璇㈢殑绱㈠紩'
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '涓存椂鏂囦欢璁板綍琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for ticket_registration
+-- ----------------------------
+DROP TABLE IF EXISTS `ticket_registration`;
+CREATE TABLE `ticket_registration`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `purchase_contract_number` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '閲囪喘鍚堝悓鍙�',
+  `sales_contract_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閿�鍞悎鍚屽彿',
+  `customer_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹㈡埛鍚嶇О',
+  `business_person` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '涓氬姟鍛�',
+  `project_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '椤圭洰鍚嶇О',
+  `product_id` int NULL DEFAULT NULL COMMENT '浜у搧淇℃伅',
+  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+  `purchase_ledger_id` int NULL DEFAULT NULL COMMENT '閲囪喘鍙拌处id',
+  `supplier_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '渚涘簲鍟嗗悕绉�',
+  `sales_ledger_id` int NULL DEFAULT NULL COMMENT '鍏宠仈閿�鍞彴璐︿富琛ㄤ富閿�',
+  `business_person_id` int NULL DEFAULT NULL COMMENT '涓氬姟鍛榠d',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `contract_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '鍚堝悓閲戦',
+  `invoice_number` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '鍙戠エ鍙�',
+  `invoice_amount` decimal(10, 2) NOT NULL COMMENT '鍙戠エ閲戦锛堝厓锛�',
+  `iss_uer_id` int NULL DEFAULT NULL COMMENT '寮�绁ㄤ汉id',
+  `iss_uer` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '寮�绁ㄤ汉',
+  `issue_date` date NULL DEFAULT NULL COMMENT '寮�绁ㄦ棩鏈�',
+  `enter_date` timestamp NULL DEFAULT NULL,
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓浜篒D',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 158 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鏉ョエ鐧昏琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for timing_task
+-- ----------------------------
+DROP TABLE IF EXISTS `timing_task`;
+CREATE TABLE `timing_task`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+  `task_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '璁惧鍚嶇О',
+  `inspection_project` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宸℃椤圭洰',
+  `task_id` int NULL DEFAULT NULL COMMENT '璁惧id',
+  `inspector_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '宸℃浜�',
+  `inspection_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宸℃鍦扮偣',
+  `frequency_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '棰戞',
+  `frequency_detail` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `next_execution_time` datetime(6) NULL DEFAULT NULL,
+  `last_execution_time` datetime(6) NULL DEFAULT NULL,
+  `is_active` tinyint(1) NULL DEFAULT NULL,
+  `is_enabled` tinyint(1) NOT NULL DEFAULT 1 COMMENT '鏄惁鍚敤 0鍚� 1鏄�',
+  `remarks` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '澶囨敞',
+  `registrant_id` bigint NULL DEFAULT NULL COMMENT '鐧昏浜篿d',
+  `registrant` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐧昏浜�',
+  `registration_date` date NOT NULL COMMENT '鐧昏鏃ユ湡',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+  `deleted` int NOT NULL DEFAULT 0 COMMENT '杞垹闄ゆ爣蹇楋紝0=鏈垹闄わ紝1=宸插垹闄�',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓璇ヨ褰曠殑鐢ㄦ埛',
+  `create_time` datetime(6) NULL DEFAULT NULL COMMENT '璁板綍鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '鏈�鍚庝慨鏀硅璁板綍鐨勭敤鎴�',
+  `update_time` datetime(6) NULL DEFAULT NULL COMMENT '璁板綍鏈�鍚庢洿鏂版椂闂�',
+  `tenant_id` int NULL DEFAULT NULL,
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_timing_task_is_enabled`(`is_enabled` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '瀹氭椂宸℃浠诲姟琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for warehouse
+-- ----------------------------
+DROP TABLE IF EXISTS `warehouse`;
+CREATE TABLE `warehouse`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `warehouse_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '浠撳簱鍚嶇О',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浠撳簱琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for warehouse_goods_shelves
+-- ----------------------------
+DROP TABLE IF EXISTS `warehouse_goods_shelves`;
+CREATE TABLE `warehouse_goods_shelves`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璐ф灦鍚嶇О',
+  `row` bigint NULL DEFAULT NULL COMMENT '灞傛暟',
+  `col` bigint NULL DEFAULT NULL COMMENT '鍒楁暟',
+  `warehouse_id` bigint NULL DEFAULT NULL COMMENT '浠撳簱id',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浠撳簱璐ф灦琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for warehouse_goods_shelves_rowcol
+-- ----------------------------
+DROP TABLE IF EXISTS `warehouse_goods_shelves_rowcol`;
+CREATE TABLE `warehouse_goods_shelves_rowcol`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `row` bigint NULL DEFAULT NULL COMMENT '灞傛暟',
+  `col` bigint NULL DEFAULT NULL COMMENT '鍒楁暟',
+  `warehouse_goods_shelves_id` bigint NULL DEFAULT NULL COMMENT '璐ф灦id',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鐢ㄦ埛',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鐢ㄦ埛',
+  `tenant_id` bigint NULL DEFAULT NULL COMMENT '绉熸埛ID',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '澶囨敞',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 101 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '浠撳簱璐ф灦灞傦紝鍒楄〃' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for water_record
+-- ----------------------------
+DROP TABLE IF EXISTS `water_record`;
+CREATE TABLE `water_record`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `device_model` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璁惧瑙勬牸鍨嬪彿',
+  `type` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐢ㄦ按绫诲瀷',
+  `rated_rate` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '棰濆畾娴侀噺',
+  `actual_traffic` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '瀹為檯娴侀噺',
+  `run_time` date NULL DEFAULT NULL COMMENT '杩愯鏃堕棿',
+  `water_day` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '褰撴棩鐢ㄦ按閲�',
+  `water_day_limit` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '姣忔棩闄愬埗姘撮噺',
+  `water_price` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '姘磋垂鍗曚环',
+  `remarks` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '澶囨敞',
+  `create_user` bigint NULL DEFAULT NULL COMMENT '鍒涘缓鑰�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` bigint NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '鐢ㄦ按璁板綍' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for work_report
+-- ----------------------------
+DROP TABLE IF EXISTS `work_report`;
+CREATE TABLE `work_report`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `plan_id` int NULL DEFAULT NULL COMMENT '鎵�灞炶鍒扞D锛屽叧鑱攄uty_plan琛�',
+  `report_title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '姹囨姤鏍囬',
+  `progress` int NULL DEFAULT NULL COMMENT '宸ヤ綔杩涘害鐧惧垎姣�',
+  `content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宸ヤ綔鍐呭',
+  `issues` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閬囧埌鐨勯棶棰�',
+  `next_plan` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '涓嬩竴姝ヨ鍒�',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '宸ヤ綔姹囨姤琛�' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Table structure for working_hours_setting
+-- ----------------------------
+DROP TABLE IF EXISTS `working_hours_setting`;
+CREATE TABLE `working_hours_setting`  (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鏃堕棿娈靛悕绉�',
+  `start_time` time NULL DEFAULT NULL COMMENT '涓婄彮鏃堕棿',
+  `end_time` time NULL DEFAULT NULL COMMENT '涓嬬彮鏃堕棿',
+  `flexible_start` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '寮规�т笂鐝�',
+  `flexible_minutes` int NULL DEFAULT NULL COMMENT '寮规�ф椂闂�(鍒嗛挓)',
+  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鐘舵��',
+  `create_user` int NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_user` int NULL DEFAULT NULL COMMENT '淇敼鑰�',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '淇敼鏃堕棿',
+  `tenant_id` int NULL DEFAULT NULL COMMENT '绉熸埛id',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '閮ㄩ棬ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '涓婄彮鏃堕棿璁剧疆' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Procedure structure for add_create_user_to_all_tables
+-- ----------------------------
+DROP PROCEDURE IF EXISTS `add_create_user_to_all_tables`;
+delimiter ;;
+CREATE PROCEDURE `add_create_user_to_all_tables`()
+BEGIN
+    DECLARE v_table_name VARCHAR(255);
+    DECLARE col_exists INT;
+    DECLARE done INT DEFAULT 0;
+
+    -- 娓告爣锛氳幏鍙栨墍鏈夐渶瑕佸鐞嗙殑琛紙鏄庣‘鎸囧畾琛ㄥ埆鍚嶏級
+    DECLARE table_cursor CURSOR FOR
+        SELECT t.TABLE_NAME
+        FROM information_schema.TABLES t
+        WHERE t.TABLE_SCHEMA = DATABASE()
+          AND t.TABLE_TYPE = 'BASE TABLE'
+          AND t.TABLE_NAME NOT LIKE 'sys_%'
+          AND t.TABLE_NAME NOT LIKE 'qrtz_%';
+
+    -- 娓告爣缁撴潫澶勭悊
+    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
+
+    OPEN table_cursor;
+
+    table_loop: LOOP
+        FETCH table_cursor INTO v_table_name;
+        IF done = 1 THEN
+            LEAVE table_loop;
+        END IF;
+
+        -- 妫�鏌ュ瓧娈垫槸鍚﹀瓨鍦紙鏄庣‘鍒悕锛屽交搴曡В鍐� 1052 閿欒锛�
+        SELECT COUNT(*) INTO col_exists
+        FROM information_schema.COLUMNS c
+        WHERE c.TABLE_SCHEMA = DATABASE()
+          AND c.TABLE_NAME = v_table_name
+          AND c.COLUMN_NAME = 'create_user';
+
+        -- 涓嶅瓨鍦ㄥ垯娣诲姞
+        IF col_exists = 0 THEN
+            SET @sql = CONCAT('ALTER TABLE `', v_table_name, '` ADD COLUMN create_user BIGINT NULL COMMENT \'鍒涘缓浜篒D\'');
+            PREPARE stmt FROM @sql;
+            EXECUTE stmt;
+            DEALLOCATE PREPARE stmt;
+        END IF;
+
+    END LOOP table_loop;
+
+    CLOSE table_cursor;
+    SELECT '鎵ц瀹屾垚锛佹墍鏈夎〃宸叉坊鍔� create_user 瀛楁' AS result;
+END
+;;
+delimiter ;
+
+-- ----------------------------
+-- Procedure structure for add_dept_id_to_all_tables
+-- ----------------------------
+DROP PROCEDURE IF EXISTS `add_dept_id_to_all_tables`;
+delimiter ;;
+CREATE PROCEDURE `add_dept_id_to_all_tables`()
+BEGIN
+    DECLARE v_table_name VARCHAR(255);
+    DECLARE col_exists INT;
+    DECLARE done INT DEFAULT 0;
+
+    -- 娓告爣锛氳幏鍙栨墍鏈夐渶瑕佸鐞嗙殑琛紙鏄庣‘鎸囧畾琛ㄥ埆鍚嶏級
+    DECLARE table_cursor CURSOR FOR
+        SELECT t.TABLE_NAME
+        FROM information_schema.TABLES t
+        WHERE t.TABLE_SCHEMA = DATABASE()
+          AND t.TABLE_TYPE = 'BASE TABLE'
+          AND t.TABLE_NAME NOT LIKE 'sys_%'
+          AND t.TABLE_NAME NOT LIKE 'qrtz_%';
+
+    -- 娓告爣缁撴潫澶勭悊
+    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
+
+    OPEN table_cursor;
+
+    table_loop: LOOP
+        FETCH table_cursor INTO v_table_name;
+        IF done = 1 THEN
+            LEAVE table_loop;
+        END IF;
+
+        -- 妫�鏌ュ瓧娈垫槸鍚﹀瓨鍦紙鏄庣‘鍒悕锛屽交搴曡В鍐� 1052 閿欒锛�
+        SELECT COUNT(*) INTO col_exists
+        FROM information_schema.COLUMNS c
+        WHERE c.TABLE_SCHEMA = DATABASE()
+          AND c.TABLE_NAME = v_table_name
+          AND c.COLUMN_NAME = 'dept_id';
+
+        -- 涓嶅瓨鍦ㄥ垯娣诲姞
+        IF col_exists = 0 THEN
+            SET @sql = CONCAT('ALTER TABLE `', v_table_name, '` ADD COLUMN dept_id BIGINT NULL COMMENT \'閮ㄩ棬ID\'');
+            PREPARE stmt FROM @sql;
+            EXECUTE stmt;
+            DEALLOCATE PREPARE stmt;
+        END IF;
+
+    END LOOP table_loop;
+
+    CLOSE table_cursor;
+    SELECT '鎵ц瀹屾垚锛佹墍鏈夎〃宸叉坊鍔� dept_id 瀛楁' AS result;
+END
+;;
+delimiter ;
+
+-- ----------------------------
+-- Procedure structure for truncate_non_sys_tables
+-- ----------------------------
+DROP PROCEDURE IF EXISTS `truncate_non_sys_tables`;
+delimiter ;;
+CREATE PROCEDURE `truncate_non_sys_tables`()
+BEGIN
+    DECLARE done INT DEFAULT FALSE;
+    DECLARE tbl_name VARCHAR(255);
+
+    DECLARE cur CURSOR FOR 
+        SELECT TABLE_NAME 
+        FROM INFORMATION_SCHEMA.TABLES 
+        WHERE TABLE_SCHEMA = DATABASE() 
+        AND (
+            TABLE_NAME NOT LIKE 'sys\\_%' 
+            OR TABLE_NAME IN (
+                'sys_oper_log',
+                'sys_logininfor',
+                'sys_notice',
+                'sys_job',
+                'sys_job_log'
+            )
+        )
+        -- 涓嶆竻鐞唒roduct琛�
+        AND TABLE_NAME <> 'product'
+        AND TABLE_TYPE = 'BASE TABLE';
+
+    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
+
+    -- 涓存椂绂佺敤澶栭敭绾︽潫
+    SET FOREIGN_KEY_CHECKS = 0;
+    SET AUTOCOMMIT = 0;
+
+    OPEN cur;
+
+    read_loop: LOOP
+        FETCH cur INTO tbl_name;
+
+        IF done THEN
+            LEAVE read_loop;
+        END IF;
+
+        SET @sql = CONCAT('DELETE FROM `', tbl_name, '`');
+
+        PREPARE stmt FROM @sql;
+        EXECUTE stmt;
+        DEALLOCATE PREPARE stmt;
+
+        SELECT CONCAT('宸叉竻鐞嗚〃: ', tbl_name) AS message;
+    END LOOP;
+
+    CLOSE cur;
+
+    -- 鎭㈠閰嶇疆
+    SET FOREIGN_KEY_CHECKS = 1;
+    SET AUTOCOMMIT = 1;
+
+    SELECT '鎵�鏈夌洰鏍囪〃宸叉竻绌哄畬鎴愶紙宸叉帓闄roduct琛級锛�' AS final_message;
+END
+;;
+delimiter ;
+
+SET FOREIGN_KEY_CHECKS = 1;
diff --git a/src/main/java/com/ruoyi/account/bean/vo/purchase/PurchaseReturnVo.java b/src/main/java/com/ruoyi/account/bean/vo/purchase/PurchaseReturnVo.java
index 82a90a3..4c21ac5 100644
--- a/src/main/java/com/ruoyi/account/bean/vo/purchase/PurchaseReturnVo.java
+++ b/src/main/java/com/ruoyi/account/bean/vo/purchase/PurchaseReturnVo.java
@@ -29,6 +29,22 @@
     @Excel(name = "鍏宠仈鍏ュ簱鍗曞彿")
     private String inboundBatches;
 
+    @Schema(description = "鍙戣揣绫诲瀷")
+    @Excel(name = "鍙戣揣绫诲瀷")
+    private Integer shippingType;
+
+    @Schema(description = "鍙戣揣杞︾墝鍙�")
+    @Excel(name = "鍙戣揣杞︾墝鍙�")
+    private String truckPlateNo;
+
+    @Schema(description = "蹇�掑叕鍙�")
+    @Excel(name = "蹇�掑叕鍙�")
+    private String expressCompany;
+
+    @Schema(description = "蹇�掑崟鍙�")
+    @Excel(name = "蹇�掑崟鍙�")
+    private String expressNo;
+
     @Schema(description = "閫�璐ф棩鏈�")
     @Excel(name = "閫�璐ф棩鏈�")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
diff --git a/src/main/java/com/ruoyi/account/bean/vo/sales/SalesOutboundVo.java b/src/main/java/com/ruoyi/account/bean/vo/sales/SalesOutboundVo.java
index 13c1b27..66d364f 100644
--- a/src/main/java/com/ruoyi/account/bean/vo/sales/SalesOutboundVo.java
+++ b/src/main/java/com/ruoyi/account/bean/vo/sales/SalesOutboundVo.java
@@ -1,5 +1,6 @@
 package com.ruoyi.account.bean.vo.sales;
 
+import com.alibaba.excel.annotation.ExcelIgnore;
 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.ruoyi.framework.aspectj.lang.annotation.Excel;
@@ -52,4 +53,8 @@
     @Schema(description = "閿�鍞鍗曞彿")
     @Excel(name = "閿�鍞鍗曞彿")
     private String salesContractNo;
+
+    @Schema(description = "宸叉敹娆鹃噾棰�")
+    @ExcelIgnore
+    private BigDecimal amountReceived;
 }
diff --git a/src/main/java/com/ruoyi/account/bean/vo/sales/SalesReturnVo.java b/src/main/java/com/ruoyi/account/bean/vo/sales/SalesReturnVo.java
index 980d7f8..36f65c4 100644
--- a/src/main/java/com/ruoyi/account/bean/vo/sales/SalesReturnVo.java
+++ b/src/main/java/com/ruoyi/account/bean/vo/sales/SalesReturnVo.java
@@ -29,6 +29,22 @@
     @Excel(name = "鍏宠仈鍙戣揣鍗曞彿")
     private String shippingNo;
 
+    @Schema(description = "鍙戣揣绫诲瀷")
+    @Excel(name = "鍙戣揣绫诲瀷")
+    private Integer shippingType;
+
+    @Schema(description = "鍙戣揣杞︾墝鍙�")
+    @Excel(name = "鍙戣揣杞︾墝鍙�")
+    private String truckPlateNo;
+
+    @Schema(description = "蹇�掑叕鍙�")
+    @Excel(name = "蹇�掑叕鍙�")
+    private String expressCompany;
+
+    @Schema(description = "蹇�掑崟鍙�")
+    @Excel(name = "蹇�掑崟鍙�")
+    private String expressNo;
+
     @Schema(description = "閫�璐ф棩鏈�")
     @Excel(name = "閫�璐ф棩鏈�")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
diff --git a/src/main/java/com/ruoyi/account/controller/sales/AccountInvoiceApplicationController.java b/src/main/java/com/ruoyi/account/controller/sales/AccountInvoiceApplicationController.java
index 00b490f..699f57c 100644
--- a/src/main/java/com/ruoyi/account/controller/sales/AccountInvoiceApplicationController.java
+++ b/src/main/java/com/ruoyi/account/controller/sales/AccountInvoiceApplicationController.java
@@ -16,6 +16,7 @@
 import org.springframework.web.bind.annotation.*;
 
 import java.util.Arrays;
+import java.util.List;
 
 /**
  * <p>
@@ -41,6 +42,13 @@
         return R.ok(listPage);
     }
 
+    @GetMapping("/getAccountInvoiceApplicationList")
+    @Log(title = "鏍规嵁瀹㈡埛id鏌ヨ寮�绁ㄧ敵璇峰彴璐�", businessType = BusinessType.OTHER)
+    @Operation(summary = "璐㈠姟绠$悊--寮�绁ㄧ敵璇峰彴璐�")
+    public R<List<AccountInvoiceApplicationVo>> getAccountInvoiceApplicationList(@RequestParam Integer customerId){
+        return R.ok(accountInvoiceApplicationService.getAccountInvoiceApplicationList(customerId));
+    }
+
     @GetMapping("/getOutboundBatchesByCustomer")
     @Log(title = "鏍规嵁瀹㈡埛鏌ヨ鍑哄簱鍗曞彿(寮�绁ㄧ敵璇�)", businessType = BusinessType.OTHER)
     @Operation(summary = "璐㈠姟绠$悊--鏍规嵁瀹㈡埛鏌ヨ鍑哄簱鍗曞彿(寮�绁ㄧ敵璇�)")
diff --git a/src/main/java/com/ruoyi/account/mapper/sales/AccountInvoiceApplicationMapper.java b/src/main/java/com/ruoyi/account/mapper/sales/AccountInvoiceApplicationMapper.java
index 463f178..c37a31f 100644
--- a/src/main/java/com/ruoyi/account/mapper/sales/AccountInvoiceApplicationMapper.java
+++ b/src/main/java/com/ruoyi/account/mapper/sales/AccountInvoiceApplicationMapper.java
@@ -29,4 +29,6 @@
 
     //鍒ゆ柇璇ュ嚭搴撹褰曟槸鍚︽湁寮�绁ㄧ敵璇�
     boolean existsByStockOutRecordId(@Param("stockOutRecordIds") List<Long> stockOutRecordIds);
+
+    List<AccountInvoiceApplicationVo> selectAccountInvoiceApplicationList(@Param("customerId") Integer customerId);
 }
diff --git a/src/main/java/com/ruoyi/account/service/impl/sales/AccountInvoiceApplicationServiceImpl.java b/src/main/java/com/ruoyi/account/service/impl/sales/AccountInvoiceApplicationServiceImpl.java
index 74cec42..c88ede2 100644
--- a/src/main/java/com/ruoyi/account/service/impl/sales/AccountInvoiceApplicationServiceImpl.java
+++ b/src/main/java/com/ruoyi/account/service/impl/sales/AccountInvoiceApplicationServiceImpl.java
@@ -91,6 +91,11 @@
         return removeBatchByIds(ids);
     }
 
+    @Override
+    public List<AccountInvoiceApplicationVo> getAccountInvoiceApplicationList(Integer customerId) {
+        return accountInvoiceApplicationMapper.selectAccountInvoiceApplicationList(customerId);
+    }
+
     private String genInvoiceApplicationNo() {
         return "KP" + LocalDateTime.now().format(CODE_TIME_FORMATTER) + new Random().nextInt(10);
     }
diff --git a/src/main/java/com/ruoyi/account/service/impl/sales/AccountSalesCollectionServiceImpl.java b/src/main/java/com/ruoyi/account/service/impl/sales/AccountSalesCollectionServiceImpl.java
index 5f328bc..45900d7 100644
--- a/src/main/java/com/ruoyi/account/service/impl/sales/AccountSalesCollectionServiceImpl.java
+++ b/src/main/java/com/ruoyi/account/service/impl/sales/AccountSalesCollectionServiceImpl.java
@@ -53,15 +53,15 @@
         if (StringUtils.isEmpty(accountSalesCollection.getCollectionNumber())) {
             accountSalesCollection.setCollectionNumber(genAccountSalesCollectionNo());
         }
-        String stockOutRecordIds = accountSalesCollection.getStockOutRecordIds();
-        if (stockOutRecordIds != null && !stockOutRecordIds.isEmpty()) {
-            List<Long> ids = Arrays.stream(stockOutRecordIds.split(","))
-                    .map(Long::valueOf)
-                    .toList();
-            if (accountSalesCollectionMapper.existsByStockOutRecordId(ids)){
-                throw new ServiceException("瀛樺湪閲嶅鐨勫嚭搴撳崟");
-            }
-        }
+//        String stockOutRecordIds = accountSalesCollection.getStockOutRecordIds();
+//        if (stockOutRecordIds != null && !stockOutRecordIds.isEmpty()) {
+//            List<Long> ids = Arrays.stream(stockOutRecordIds.split(","))
+//                    .map(Long::valueOf)
+//                    .toList();
+//            if (accountSalesCollectionMapper.existsByStockOutRecordId(ids)){
+//                throw new ServiceException("瀛樺湪閲嶅鐨勫嚭搴撳崟");
+//            }
+//        }
         return save(accountSalesCollection);
     }
 
diff --git a/src/main/java/com/ruoyi/account/service/sales/AccountInvoiceApplicationService.java b/src/main/java/com/ruoyi/account/service/sales/AccountInvoiceApplicationService.java
index 7f55ba5..d2cefc1 100644
--- a/src/main/java/com/ruoyi/account/service/sales/AccountInvoiceApplicationService.java
+++ b/src/main/java/com/ruoyi/account/service/sales/AccountInvoiceApplicationService.java
@@ -30,4 +30,6 @@
     void exportAccountInvoiceApplication(HttpServletResponse response, AccountInvoiceApplicationDto accountInvoiceApplicationDto);
 
     boolean deleteAccountInvoiceApplication(List<Long> ids);
+
+    List<AccountInvoiceApplicationVo> getAccountInvoiceApplicationList(Integer customerId);
 }
diff --git a/src/main/java/com/ruoyi/ai/assistant/KnowledgeChatAgent.java b/src/main/java/com/ruoyi/ai/assistant/KnowledgeChatAgent.java
new file mode 100644
index 0000000..2d4072c
--- /dev/null
+++ b/src/main/java/com/ruoyi/ai/assistant/KnowledgeChatAgent.java
@@ -0,0 +1,35 @@
+package com.ruoyi.ai.assistant;
+
+import dev.langchain4j.service.MemoryId;
+import dev.langchain4j.service.SystemMessage;
+import dev.langchain4j.service.UserMessage;
+import dev.langchain4j.service.spring.AiService;
+import reactor.core.publisher.Flux;
+
+import static dev.langchain4j.service.spring.AiServiceWiringMode.EXPLICIT;
+
+/**
+ * 鐭ヨ瘑搴撻棶绛擜gent
+ * 鍩轰簬RAG妫�绱㈠寮虹敓鎴�
+ */
+@AiService(
+        wiringMode = EXPLICIT,
+        streamingChatModel = "qwenStreamingChatModel",
+        chatMemoryProvider = "chatMemoryProviderXiaozhi"
+)
+public interface KnowledgeChatAgent {
+
+    @SystemMessage("""
+            浣犳槸浼佷笟鐭ヨ瘑搴撻棶绛斿姪鎵嬨��
+
+            浣犻渶瑕佸熀浜庢彁渚涚殑鐭ヨ瘑搴撳唴瀹瑰洖绛旂敤鎴烽棶棰樸��
+
+            閬靛惊浠ヤ笅瑙勫垯锛�
+            1. 涓ユ牸鍩轰簬鐭ヨ瘑搴撳唴瀹瑰洖绛旓紝涓嶈缂栭�犱俊鎭�
+            2. 濡傛灉鐭ヨ瘑搴撲腑娌℃湁鐩稿叧淇℃伅锛屾槑纭憡鐭ョ敤鎴�
+            3. 鍥炵瓟瑕佸噯纭�佺畝娲併�佹湁鏉$悊
+            4. 濡傛灉鍐呭杈冨锛屼娇鐢ㄥ垎鐐瑰垪琛ㄥ舰寮�
+            5. 寮曠敤鏉ユ簮鏃舵敞鏄�"鏍规嵁鐭ヨ瘑搴撳唴瀹�"
+            """)
+    Flux<String> chat(@MemoryId String memoryId, @UserMessage String userMessage);
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/ai/config/EmbeddingStoreConfig.java b/src/main/java/com/ruoyi/ai/config/EmbeddingStoreConfig.java
index ca5156d..eaa487c 100644
--- a/src/main/java/com/ruoyi/ai/config/EmbeddingStoreConfig.java
+++ b/src/main/java/com/ruoyi/ai/config/EmbeddingStoreConfig.java
@@ -5,32 +5,48 @@
 import dev.langchain4j.store.embedding.EmbeddingStore;
 import dev.langchain4j.store.embedding.pinecone.PineconeEmbeddingStore;
 import dev.langchain4j.store.embedding.pinecone.PineconeServerlessIndexConfig;
-import org.springframework.beans.factory.annotation.Autowired;
+import io.pinecone.clients.Index;
+import io.pinecone.clients.Pinecone;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
 /**
- * @author :yys
- * @date : 2025/5/2 21:07
+ * 鍚戦噺瀛樺偍閰嶇疆
  */
 @Configuration
 public class EmbeddingStoreConfig {
 
-    @Autowired
-    private EmbeddingModel embeddingModel;
+    @Value("${pinecone.api-key:pcsk_4SJLnh_tNB3wSLJU8tc4E5P28PcXX8eCLdURqZpVhg1FMV8CRYxjneWdzqRdB5Ftqooi9}")
+    private String pineconeApiKey;
+
+    @Value("${pinecone.index:xiaozhi-index}")
+    private String indexName;
+
+    @Value("${pinecone.namespace:knowledge-base}")
+    private String namespace;
 
     @Bean
-    public EmbeddingStore<TextSegment> embeddingStore() {
-        //鍒涘缓鍚戦噺瀛樺偍
+    public Pinecone pinecone() {
+        return new Pinecone.Builder(pineconeApiKey).build();
+    }
+
+    @Bean
+    public Index pineconeIndex(Pinecone pinecone) {
+        return pinecone.getIndexConnection(indexName);
+    }
+
+    @Bean
+    public EmbeddingStore<TextSegment> embeddingStore(EmbeddingModel embeddingModel) {
         return PineconeEmbeddingStore.builder()
-                .apiKey("pcsk_4SJLnh_tNB3wSLJU8tc4E5P28PcXX8eCLdURqZpVhg1FMV8CRYxjneWdzqRdB5Ftqooi9")
-                .index("xiaozhi-index")//濡傛灉鎸囧畾鐨勭储寮曚笉瀛樺湪锛屽皢鍒涘缓涓�涓柊鐨勭储寮�
-                .nameSpace("xiaozhi-namespace") //濡傛灉鎸囧畾鐨勫悕绉扮┖闂翠笉瀛樺湪锛屽皢鍒涘缓涓�涓柊鐨勫悕绉� 绌洪棿
+                .apiKey(pineconeApiKey)
+                .index(indexName)
+                .nameSpace(namespace)
                 .createIndex(PineconeServerlessIndexConfig.builder()
-                        .cloud("AWS") //鎸囧畾绱㈠紩閮ㄧ讲鍦� AWS 浜戞湇鍔′笂銆�
-                        .region("us-east-1") //鎸囧畾绱㈠紩鎵�鍦ㄧ殑 AWS 鍖哄煙涓� us-east-1銆�
-                        .dimension(embeddingModel.dimension()) //鎸囧畾绱㈠紩鐨勫悜閲忕淮搴︼紝璇ョ淮搴︿笌 embeddedModel 鐢熸垚鐨勫悜閲忕淮搴︾浉鍚屻��
+                        .cloud("AWS")
+                        .region("us-east-1")
+                        .dimension(embeddingModel.dimension())
                         .build())
                 .build();
     }
-}
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/ai/controller/KnowledgeChatController.java b/src/main/java/com/ruoyi/ai/controller/KnowledgeChatController.java
new file mode 100644
index 0000000..2738439
--- /dev/null
+++ b/src/main/java/com/ruoyi/ai/controller/KnowledgeChatController.java
@@ -0,0 +1,85 @@
+package com.ruoyi.ai.controller;
+
+import com.ruoyi.ai.assistant.KnowledgeChatAgent;
+import com.ruoyi.ai.dto.KnowledgeChatRequest;
+import com.ruoyi.ai.service.KnowledgeRagService;
+import com.ruoyi.approve.pojo.KnowledgeBase;
+import com.ruoyi.approve.service.KnowledgeBaseService;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Flux;
+
+import java.util.List;
+
+/**
+ * 鐭ヨ瘑搴撻棶绛擟ontroller
+ */
+@Slf4j
+@RestController
+@RequestMapping("/ai/knowledge")
+@RequiredArgsConstructor
+@Tag(name = "鐭ヨ瘑搴撻棶绛�")
+public class KnowledgeChatController {
+
+    private final KnowledgeChatAgent knowledgeChatAgent;
+    private final KnowledgeRagService knowledgeRagService;
+    private final KnowledgeBaseService knowledgeBaseService;
+
+    /**
+     * 鐭ヨ瘑搴撻棶绛旓紙娴佸紡杩斿洖锛�
+     */
+    @PostMapping(value = "/chat", produces = "text/stream;charset=utf-8")
+    @Operation(summary = "鐭ヨ瘑搴撻棶绛�")
+    public Flux<String> chat(@RequestBody KnowledgeChatRequest request) {
+        if (request.getKnowledgeBaseId() == null) {
+            return Flux.just("鐭ヨ瘑搴揑D涓嶈兘涓虹┖");
+        }
+        if (!StringUtils.hasText(request.getMemoryId())) {
+            return Flux.just("浼氳瘽ID涓嶈兘涓虹┖");
+        }
+        if (!StringUtils.hasText(request.getQuestion())) {
+            return Flux.just("闂涓嶈兘涓虹┖");
+        }
+
+        KnowledgeBase knowledgeBase = knowledgeBaseService.getById(request.getKnowledgeBaseId());
+        if (knowledgeBase == null) {
+            return Flux.just("鐭ヨ瘑搴撲笉瀛樺湪");
+        }
+
+        String namespace = "kb-" + request.getKnowledgeBaseId();
+
+        List<String> relevantContents = knowledgeRagService.searchRelevantContent(
+                namespace, request.getQuestion(), 5);
+
+        if (relevantContents.isEmpty()) {
+            return Flux.just("鐭ヨ瘑搴撲腑鏈壘鍒扮浉鍏冲唴瀹癸紝璇峰厛涓婁紶鐩稿叧鏂囨。銆�");
+        }
+
+        StringBuilder contextBuilder = new StringBuilder();
+        contextBuilder.append("浠ヤ笅鏄粠鐭ヨ瘑搴撲腑妫�绱㈠埌鐨勭浉鍏冲唴瀹癸細\n\n");
+        for (int i = 0; i < relevantContents.size(); i++) {
+            contextBuilder.append("銆愬唴瀹�").append(i + 1).append("銆慭n");
+            contextBuilder.append(relevantContents.get(i)).append("\n\n");
+        }
+        contextBuilder.append("---\n");
+        contextBuilder.append("璇峰熀浜庝互涓婄煡璇嗗簱鍐呭鍥炵瓟鐢ㄦ埛闂锛歕n");
+        contextBuilder.append(request.getQuestion());
+
+        return knowledgeChatAgent.chat(request.getMemoryId(), contextBuilder.toString());
+    }
+
+    /**
+     * 鐭ヨ瘑搴撳垪琛紙鐢ㄤ簬閫夋嫨鐭ヨ瘑搴擄級
+     */
+    @GetMapping("/list")
+    @Operation(summary = "鐭ヨ瘑搴撳垪琛�")
+    public AjaxResult listKnowledgeBases() {
+        List<KnowledgeBase> list = knowledgeBaseService.list();
+        return AjaxResult.success(list);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/ai/dto/KnowledgeChatRequest.java b/src/main/java/com/ruoyi/ai/dto/KnowledgeChatRequest.java
new file mode 100644
index 0000000..134c2c8
--- /dev/null
+++ b/src/main/java/com/ruoyi/ai/dto/KnowledgeChatRequest.java
@@ -0,0 +1,21 @@
+package com.ruoyi.ai.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 鐭ヨ瘑搴撻棶绛旇姹�
+ */
+@Data
+@Schema(description = "鐭ヨ瘑搴撻棶绛旇姹�")
+public class KnowledgeChatRequest {
+
+    @Schema(description = "鐭ヨ瘑搴揑D", required = true)
+    private Long knowledgeBaseId;
+
+    @Schema(description = "浼氳瘽ID锛岀敤浜庝繚鎸佷笂涓嬫枃", required = true)
+    private String memoryId;
+
+    @Schema(description = "鐢ㄦ埛鎻愰棶鍐呭", required = true)
+    private String question;
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/ai/service/KnowledgeRagService.java b/src/main/java/com/ruoyi/ai/service/KnowledgeRagService.java
new file mode 100644
index 0000000..44d5f87
--- /dev/null
+++ b/src/main/java/com/ruoyi/ai/service/KnowledgeRagService.java
@@ -0,0 +1,34 @@
+package com.ruoyi.ai.service;
+
+import java.util.List;
+
+/**
+ * 鐭ヨ瘑搴揜AG鏈嶅姟
+ * 璐熻矗鏂囦欢鍚戦噺鍖栧鐞嗗拰妫�绱�
+ */
+public interface KnowledgeRagService {
+
+    /**
+     * 寮傛澶勭悊鍚戦噺鍖�
+     */
+    void processVectorAsync(Long vectorId);
+
+    /**
+     * 鍚屾澶勭悊鍚戦噺鍖�
+     */
+    void processVector(Long vectorId);
+
+    /**
+     * 妫�绱㈢浉鍏冲唴瀹�
+     * @param namespace 鍛藉悕绌洪棿
+     * @param query 鏌ヨ鏂囨湰
+     * @param maxResults 鏈�澶х粨鏋滄暟
+     * @return 鐩稿叧鍐呭鍒楄〃
+     */
+    List<String> searchRelevantContent(String namespace, String query, int maxResults);
+
+    /**
+     * 鍒犻櫎鎸囧畾鏂囦欢鐨勫悜閲忔暟鎹�
+     */
+    void deleteEmbeddings(String namespace, Long storageBlobId);
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/ai/service/impl/KnowledgeRagServiceImpl.java b/src/main/java/com/ruoyi/ai/service/impl/KnowledgeRagServiceImpl.java
new file mode 100644
index 0000000..db8f308
--- /dev/null
+++ b/src/main/java/com/ruoyi/ai/service/impl/KnowledgeRagServiceImpl.java
@@ -0,0 +1,342 @@
+package com.ruoyi.ai.service.impl;
+
+import com.ruoyi.ai.service.KnowledgeRagService;
+import com.ruoyi.approve.pojo.KnowledgeBaseVector;
+import com.ruoyi.approve.service.KnowledgeBaseVectorService;
+import com.ruoyi.basic.pojo.StorageBlob;
+import com.ruoyi.basic.service.StorageBlobService;
+import com.ruoyi.common.config.FileProperties;
+import com.google.protobuf.Struct;
+import com.google.protobuf.Value;
+import dev.langchain4j.data.embedding.Embedding;
+import dev.langchain4j.data.segment.TextSegment;
+import dev.langchain4j.model.embedding.EmbeddingModel;
+import dev.langchain4j.store.embedding.EmbeddingSearchRequest;
+import dev.langchain4j.store.embedding.EmbeddingSearchResult;
+import dev.langchain4j.store.embedding.EmbeddingStore;
+import io.pinecone.clients.Index;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import java.io.File;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 鐭ヨ瘑搴揜AG鏈嶅姟瀹炵幇
+ */
+@Slf4j
+@Service
+public class KnowledgeRagServiceImpl implements KnowledgeRagService {
+
+    private final KnowledgeBaseVectorService knowledgeBaseVectorService;
+    private final StorageBlobService storageBlobService;
+    private final EmbeddingModel embeddingModel;
+    private final EmbeddingStore<TextSegment> embeddingStore;
+    private final FileProperties fileProperties;
+    private final Index pineconeIndex;
+
+    @org.springframework.beans.factory.annotation.Value("${pinecone.namespace:knowledge-base}")
+    private String namespace;
+
+    public KnowledgeRagServiceImpl(
+            KnowledgeBaseVectorService knowledgeBaseVectorService,
+            StorageBlobService storageBlobService,
+            EmbeddingModel embeddingModel,
+            EmbeddingStore<TextSegment> embeddingStore,
+            FileProperties fileProperties,
+            Index pineconeIndex) {
+        this.knowledgeBaseVectorService = knowledgeBaseVectorService;
+        this.storageBlobService = storageBlobService;
+        this.embeddingModel = embeddingModel;
+        this.embeddingStore = embeddingStore;
+        this.fileProperties = fileProperties;
+        this.pineconeIndex = pineconeIndex;
+    }
+
+    private static final int CHUNK_SIZE = 500;
+    private static final int CHUNK_OVERLAP = 100;
+    private static final long CHUNK_THRESHOLD_BYTES = 80L * 1024 * 1024;
+    private static final int EMBEDDING_MAX_LENGTH = 8000;
+
+    @Override
+    @Async("threadPoolTaskExecutor")
+    public void processVectorAsync(Long vectorId) {
+        log.info("寮�濮嬪紓姝ュ悜閲忓寲澶勭悊: vectorId={}, thread={}", vectorId, Thread.currentThread().getName());
+        processVector(vectorId);
+    }
+
+    @Override
+    public void processVector(Long vectorId) {
+        log.info("寮�濮嬪鐞嗗悜閲忓寲: vectorId={}", vectorId);
+        KnowledgeBaseVector vector = knowledgeBaseVectorService.getById(vectorId);
+        if (vector == null) {
+            log.error("鍚戦噺璁板綍涓嶅瓨鍦�: {}", vectorId);
+            return;
+        }
+
+        try {
+            knowledgeBaseVectorService.updateVectorStatus(vectorId,
+                    KnowledgeBaseVector.STATUS_PROCESSING, null, null);
+
+            StorageBlob blob = storageBlobService.getById(vector.getStorageBlobId());
+            if (blob == null) {
+                throw new RuntimeException("鏂囦欢涓嶅瓨鍦�: " + vector.getStorageBlobId());
+            }
+
+            File file = getFile(blob);
+            log.info("鏂囦欢璺緞: {}, 鏄惁瀛樺湪: {}", file.getAbsolutePath(), file.exists());
+            long fileSize = file.length();
+
+            String content = extractFileContent(file, vector.getFileName());
+            log.info("鏂囦欢鍐呭闀垮害: {}", content != null ? content.length() : 0);
+
+            if (content == null || content.trim().isEmpty()) {
+                throw new RuntimeException("鏂囦欢鍐呭涓虹┖");
+            }
+
+            List<TextSegment> chunks;
+            boolean needChunk = fileSize > CHUNK_THRESHOLD_BYTES || content.length() > EMBEDDING_MAX_LENGTH;
+            if (needChunk) {
+                log.info("寮�濮嬪垏鐗�: fileSize={}, contentLength={}", fileSize, content.length());
+                chunks = splitText(content, vector);
+                log.info("鍒囩墖瀹屾垚锛屽叡 {} 涓潡", chunks.size());
+            } else {
+                log.info("鏂囦欢杈冨皬锛屼笉杩涜鍒囩墖");
+                Map<String, Object> metadata = buildMetadata(vector);
+                chunks = List.of(TextSegment.from(content, new dev.langchain4j.data.document.Metadata(metadata)));
+            }
+
+            int chunkCount = 0;
+            for (TextSegment chunk : chunks) {
+                Embedding embedding = embeddingModel.embed(chunk).content();
+                embeddingStore.add(embedding, chunk);
+                chunkCount++;
+            }
+
+            knowledgeBaseVectorService.updateVectorStatus(vectorId,
+                    KnowledgeBaseVector.STATUS_COMPLETED, chunkCount, null);
+
+            log.info("鍚戦噺鍖栧鐞嗗畬鎴�: vectorId={}, chunkCount={}", vectorId, chunkCount);
+
+        } catch (Exception e) {
+            log.error("鍚戦噺鍖栧鐞嗗け璐�: vectorId={}", vectorId, e);
+            knowledgeBaseVectorService.updateVectorStatus(vectorId,
+                    KnowledgeBaseVector.STATUS_FAILED, null, e.getMessage());
+        }
+    }
+
+    @Override
+    public List<String> searchRelevantContent(String namespace, String query, int maxResults) {
+        try {
+            Embedding queryEmbedding = embeddingModel.embed(query).content();
+
+            EmbeddingSearchRequest searchRequest = EmbeddingSearchRequest.builder()
+                    .queryEmbedding(queryEmbedding)
+                    .maxResults(maxResults)
+                    .minScore(0.7)
+                    .build();
+
+            EmbeddingSearchResult<TextSegment> searchResult = embeddingStore.search(searchRequest);
+
+            return searchResult.matches().stream()
+                    .map(match -> match.embedded().text())
+                    .collect(Collectors.toList());
+
+        } catch (Exception e) {
+            log.error("鍚戦噺妫�绱㈠け璐�: namespace={}", namespace, e);
+            return new ArrayList<>();
+        }
+    }
+
+    @Override
+    public void deleteEmbeddings(String namespace, Long storageBlobId) {
+        log.info("鍒犻櫎鍚戦噺鏁版嵁: namespace={}, storageBlobId={}", namespace, storageBlobId);
+        try {
+            Struct filter = Struct.newBuilder()
+                    .putFields("storageBlobId", Value.newBuilder()
+                            .setStructValue(Struct.newBuilder()
+                                    .putFields("$eq", Value.newBuilder()
+                                            .setNumberValue(storageBlobId.doubleValue())
+                                            .build()))
+                            .build())
+                    .build();
+
+            List<String> emptyIds = new ArrayList<>();
+            pineconeIndex.delete(emptyIds, false, this.namespace, filter);
+            log.info("鍚戦噺鍒犻櫎瀹屾垚: storageBlobId={}", storageBlobId);
+        } catch (Exception e) {
+            log.error("鍒犻櫎鍚戦噺鏁版嵁澶辫触: namespace={}, storageBlobId={}", namespace, storageBlobId, e);
+        }
+    }
+
+    private File getFile(StorageBlob blob) {
+        String path = blob.getPath();
+        if (path != null && !path.isEmpty()) {
+            return new File(new File(fileProperties.getPath(), path), blob.getUidFilename());
+        }
+        return new File(fileProperties.getPath(), blob.getUidFilename());
+    }
+
+    private String extractFileContent(File file, String fileName) throws Exception {
+        String ext = getFileExtension(fileName);
+
+        if (isPlainText(ext)) {
+            return readFileWithEncoding(file);
+        }
+
+        if ("docx".equals(ext)) {
+            return extractDocx(file);
+        }
+
+        if ("xlsx".equals(ext)) {
+            return extractXlsx(file);
+        }
+
+        if ("xls".equals(ext)) {
+            return extractXls(file);
+        }
+
+        return readFileWithEncoding(file);
+    }
+
+    private String readFileWithEncoding(File file) throws Exception {
+        byte[] bytes = Files.readAllBytes(file.toPath());
+
+        String utf8Content = new String(bytes, StandardCharsets.UTF_8);
+        if (isValidUtf8(utf8Content)) {
+            log.debug("鏂囦欢缂栫爜: UTF-8");
+            return utf8Content;
+        }
+
+        try {
+            Charset gbk = Charset.forName("GBK");
+            String gbkContent = new String(bytes, gbk);
+            log.debug("鏂囦欢缂栫爜: GBK");
+            return gbkContent;
+        } catch (Exception e) {
+            log.warn("缂栫爜妫�娴嬪け璐ワ紝浣跨敤 UTF-8");
+            return utf8Content;
+        }
+    }
+
+    private boolean isValidUtf8(String decoded) {
+        // 妫�鏌ユ浛鎹㈠瓧绗� U+FFFD (UTF-8 瑙g爜澶辫触鏃跺嚭鐜�)
+        if (decoded.contains("锟�")) {
+            return false;
+        }
+        int invalidCount = 0;
+        int checkLen = Math.min(decoded.length(), 1000);
+        for (int i = 0; i < checkLen; i++) {
+            char c = decoded.charAt(i);
+            // 妫�鏌ョ鏈変娇鐢ㄥ尯鍩� (U+E000-U+F8FF) 鎴栧紓甯告帶鍒跺瓧绗�
+            if ((c >= '顎�' && c <= '铮�') || (c < ' ' && c != '\n' && c != '\r' && c != '\t')) {
+                invalidCount++;
+            }
+        }
+        return invalidCount < checkLen * 0.05;
+    }
+
+    private String getFileExtension(String fileName) {
+        if (fileName == null || !fileName.contains(".")) {
+            return "";
+        }
+        return fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
+    }
+
+    private boolean isPlainText(String ext) {
+        return "txt".equals(ext) || "md".equals(ext) || "json".equals(ext)
+                || "csv".equals(ext) || "xml".equals(ext) || "yaml".equals(ext)
+                || "yml".equals(ext);
+    }
+
+    private String extractDocx(File file) throws Exception {
+        try (var doc = new org.apache.poi.xwpf.usermodel.XWPFDocument(new java.io.FileInputStream(file));
+             var extractor = new org.apache.poi.xwpf.extractor.XWPFWordExtractor(doc)) {
+            return extractor.getText();
+        }
+    }
+
+    private String extractXlsx(File file) throws Exception {
+        try (var workbook = new org.apache.poi.xssf.usermodel.XSSFWorkbook(file)) {
+            return extractWorkbook(workbook);
+        }
+    }
+
+    private String extractXls(File file) throws Exception {
+        try (var workbook = new org.apache.poi.hssf.usermodel.HSSFWorkbook(new java.io.FileInputStream(file))) {
+            return extractWorkbook(workbook);
+        }
+    }
+
+    private String extractWorkbook(org.apache.poi.ss.usermodel.Workbook workbook) {
+        StringBuilder text = new StringBuilder();
+        var formatter = new org.apache.poi.ss.usermodel.DataFormatter();
+        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
+            var sheet = workbook.getSheetAt(i);
+            text.append("Sheet: ").append(sheet.getSheetName()).append("\n");
+            for (var row : sheet) {
+                for (var cell : row) {
+                    text.append(formatter.formatCellValue(cell)).append("\t");
+                }
+                text.append("\n");
+            }
+        }
+        return text.toString();
+    }
+
+    private List<TextSegment> splitText(String content, KnowledgeBaseVector vector) {
+        List<TextSegment> chunks = new ArrayList<>();
+
+        if (content.length() <= CHUNK_SIZE) {
+            Map<String, Object> metadata = buildMetadata(vector);
+            chunks.add(TextSegment.from(content, new dev.langchain4j.data.document.Metadata(metadata)));
+            return chunks;
+        }
+
+        int start = 0;
+        int chunkIndex = 0;
+        while (start < content.length()) {
+            int end = Math.min(start + CHUNK_SIZE, content.length());
+
+            if (end < content.length()) {
+                int lastPeriod = content.lastIndexOf('銆�', end);
+                int lastNewline = content.lastIndexOf('\n', end);
+                int boundary = Math.max(lastPeriod, lastNewline);
+                if (boundary > start + CHUNK_SIZE / 2) {
+                    end = boundary + 1;
+                }
+            }
+
+            String chunkText = content.substring(start, end).trim();
+            if (!chunkText.isEmpty()) {
+                Map<String, Object> metadata = buildMetadata(vector);
+                metadata.put("chunkIndex", chunkIndex);
+                chunks.add(TextSegment.from(chunkText, new dev.langchain4j.data.document.Metadata(metadata)));
+                chunkIndex++;
+            }
+
+            start = end - CHUNK_OVERLAP;
+            if (start < 0) start = 0;
+            if (start >= content.length() - CHUNK_OVERLAP) break;
+        }
+
+        return chunks;
+    }
+
+    private Map<String, Object> buildMetadata(KnowledgeBaseVector vector) {
+        Map<String, Object> metadata = new HashMap<>();
+        metadata.put("knowledgeBaseId", vector.getKnowledgeBaseId());
+        metadata.put("storageBlobId", vector.getStorageBlobId());
+        metadata.put("fileName", vector.getFileName());
+        metadata.put("namespace", vector.getNamespace());
+        return metadata;
+    }
+}
diff --git a/src/main/java/com/ruoyi/approve/controller/KnowledgeBaseController.java b/src/main/java/com/ruoyi/approve/controller/KnowledgeBaseController.java
index 3ebb782..ba93fb4 100644
--- a/src/main/java/com/ruoyi/approve/controller/KnowledgeBaseController.java
+++ b/src/main/java/com/ruoyi/approve/controller/KnowledgeBaseController.java
@@ -2,16 +2,25 @@
 
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.approve.dto.KnowledgeBaseVectorVO;
 import com.ruoyi.approve.pojo.KnowledgeBase;
+import com.ruoyi.approve.pojo.KnowledgeBaseVector;
 import com.ruoyi.approve.service.KnowledgeBaseService;
+import com.ruoyi.approve.service.KnowledgeBaseVectorService;
+import com.ruoyi.basic.dto.StorageAttachmentDTO;
+import com.ruoyi.basic.dto.StorageBlobDTO;
+import com.ruoyi.basic.pojo.StorageBlob;
+import com.ruoyi.basic.service.StorageAttachmentService;
+import com.ruoyi.basic.service.StorageBlobService;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.framework.web.domain.AjaxResult;
-import io.swagger.v3.oas.annotations.tags.Tag;
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.servlet.http.HttpServletResponse;
 import lombok.AllArgsConstructor;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.ArrayList;
 import java.util.List;
 
 @RestController
@@ -20,40 +29,42 @@
 @Tag(name = "鐭ヨ瘑搴撶鐞�")
 public class KnowledgeBaseController {
     private KnowledgeBaseService knowledgeBaseService;
+    private KnowledgeBaseVectorService knowledgeBaseVectorService;
+    private StorageAttachmentService storageAttachmentService;
+    private StorageBlobService storageBlobService;
 
-    /**銆�
+    /**
      * 鑾峰彇鍒楄〃
-     * @return
      */
     @GetMapping("/getList")
     public AjaxResult getList(@RequestParam(defaultValue = "1") long current,
                               @RequestParam(defaultValue = "10") long size, KnowledgeBase knowledgeBase) {
         Page page = new Page(current, size);
-        return AjaxResult.success(knowledgeBaseService.listpage(page,knowledgeBase));
+        return AjaxResult.success(knowledgeBaseService.listpage(page, knowledgeBase));
     }
-    /**銆�
-     * 澧炴坊
-     * @return
+
+    /**
+     * 鏂板鐭ヨ瘑搴�
      */
     @PostMapping("/add")
-    public AjaxResult add(@RequestBody KnowledgeBase knowledgeBase){
+    public AjaxResult add(@RequestBody KnowledgeBase knowledgeBase) {
         return AjaxResult.success(knowledgeBaseService.save(knowledgeBase));
     }
+
     /**
-     * 鏇存柊
-     * @return
+     * 鏇存柊鐭ヨ瘑搴�
      */
     @PostMapping("/update")
-    public AjaxResult update(@RequestBody KnowledgeBase knowledgeBase){
+    public AjaxResult update(@RequestBody KnowledgeBase knowledgeBase) {
         return AjaxResult.success(knowledgeBaseService.updateById(knowledgeBase));
     }
+
     /**
-     * 鍒犻櫎
-     * @return
+     * 鍒犻櫎鐭ヨ瘑搴�
      */
     @DeleteMapping("/delete")
-    public AjaxResult delete(@RequestBody List<Long> ids){
-        if(CollectionUtils.isEmpty(ids)) return AjaxResult.error("璇蜂紶鍏ヨ鍒犻櫎鐨処D");
+    public AjaxResult delete(@RequestBody List<Long> ids) {
+        if (CollectionUtils.isEmpty(ids)) return AjaxResult.error("璇蜂紶鍏ヨ鍒犻櫎鐨処D");
         return AjaxResult.success(knowledgeBaseService.removeByIds(ids));
     }
 
@@ -65,4 +76,101 @@
         util.exportExcel(response, accountExpenses, "鐭ヨ瘑搴撶鐞嗗鍑�");
     }
 
-}
+    /**
+     * 鏌ヨ鐭ヨ瘑搴撴枃浠跺悜閲忓寲鐘舵��
+     */
+    @GetMapping("/vector/status/{knowledgeBaseId}")
+    @Operation(summary = "鏌ヨ鐭ヨ瘑搴撴枃浠跺悜閲忓寲鐘舵��")
+    public AjaxResult getVectorStatus(@PathVariable Long knowledgeBaseId) {
+        List<KnowledgeBaseVectorVO> list = knowledgeBaseVectorService.getVectorStatusByKnowledgeBaseId(knowledgeBaseId);
+        return AjaxResult.success(list);
+    }
+
+    /**
+     * 閲嶆柊鍚戦噺鍖栨枃浠�
+     */
+    @PostMapping("/vector/reprocess/{vectorId}")
+    @Operation(summary = "閲嶆柊鍚戦噺鍖栨枃浠�")
+    public AjaxResult reprocessVector(@PathVariable Long vectorId) {
+        knowledgeBaseVectorService.reprocessVector(vectorId);
+        return AjaxResult.success("宸查噸鏂版彁浜ゅ悜閲忓寲浠诲姟");
+    }
+
+    /**
+     * 淇濆瓨鐭ヨ瘑搴撴枃浠跺叧鑱旓紙鏂囦欢涓婁紶鍚庤皟鐢級
+     * 涓婁紶娴佺▼锛�
+     * 1. 鍏堣皟鐢� /common/upload 涓婁紶鏂囦欢锛岃幏鍙� storageBlobDTOs
+     * 2. 鍐嶈皟鐢ㄦ鎺ュ彛鍏宠仈鏂囦欢鍒扮煡璇嗗簱骞惰Е鍙戝悜閲忓寲
+     */
+    @PostMapping("/file/save")
+    @Operation(summary = "淇濆瓨鐭ヨ瘑搴撴枃浠跺叧鑱�")
+    public AjaxResult saveKnowledgeBaseFiles(@RequestBody KnowledgeBaseFileDTO dto) {
+        if (dto.getKnowledgeBaseId() == null) {
+            return AjaxResult.error("鐭ヨ瘑搴揑D涓嶈兘涓虹┖");
+        }
+        if (CollectionUtils.isEmpty(dto.getStorageBlobIds())) {
+            return AjaxResult.error("鏂囦欢ID涓嶈兘涓虹┖");
+        }
+
+        // 淇濆瓨闄勪欢鍏宠仈
+        StorageAttachmentDTO attachmentDTO = new StorageAttachmentDTO();
+        attachmentDTO.setRecordType("knowledge_base");
+        attachmentDTO.setRecordId(dto.getKnowledgeBaseId());
+        attachmentDTO.setApplication("rag_file");
+        List<StorageBlobDTO> blobDTOs = new ArrayList<>();
+        for (Long blobId : dto.getStorageBlobIds()) {
+            StorageBlobDTO blobDTO = new StorageBlobDTO();
+            blobDTO.setId(blobId);
+            blobDTOs.add(blobDTO);
+        }
+        attachmentDTO.setStorageBlobDTOs(blobDTOs);
+        storageAttachmentService.saveStorageAttachment(attachmentDTO);
+
+        // 鍒涘缓鍚戦噺璁板綍骞惰Е鍙戝悜閲忓寲
+        for (Long blobId : dto.getStorageBlobIds()) {
+            StorageBlob blob = storageBlobService.getById(blobId);
+            if (blob != null) {
+                String fileName = blob.getOriginalFilename();
+                String fileType = getFileExtension(fileName);
+
+                knowledgeBaseVectorService.createVectorRecord(
+                        dto.getKnowledgeBaseId(),
+                        blobId,
+                        fileName,
+                        fileType
+                );
+            }
+        }
+
+        return AjaxResult.success();
+    }
+
+    private String getFileExtension(String fileName) {
+        if (fileName == null || !fileName.contains(".")) {
+            return "unknown";
+        }
+        return fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
+    }
+
+    /**
+     * 鍒犻櫎鐭ヨ瘑搴撴枃浠�
+     */
+    @DeleteMapping("/file/delete")
+    @Operation(summary = "鍒犻櫎鐭ヨ瘑搴撴枃浠�")
+    public AjaxResult deleteKnowledgeBaseFiles(@RequestBody List<Long> vectorIds) {
+        if (CollectionUtils.isEmpty(vectorIds)) {
+            return AjaxResult.error("璇烽�夋嫨瑕佸垹闄ょ殑鏂囦欢");
+        }
+        knowledgeBaseVectorService.deleteVectors(vectorIds);
+        return AjaxResult.success();
+    }
+
+    /**
+     * 鐭ヨ瘑搴撴枃浠禗TO
+     */
+    @lombok.Data
+    public static class KnowledgeBaseFileDTO {
+        private Long knowledgeBaseId;
+        private List<Long> storageBlobIds;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/approve/dto/KnowledgeBaseVectorVO.java b/src/main/java/com/ruoyi/approve/dto/KnowledgeBaseVectorVO.java
new file mode 100644
index 0000000..9cfb721
--- /dev/null
+++ b/src/main/java/com/ruoyi/approve/dto/KnowledgeBaseVectorVO.java
@@ -0,0 +1,21 @@
+package com.ruoyi.approve.dto;
+
+import com.ruoyi.approve.pojo.KnowledgeBaseVector;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 鐭ヨ瘑搴撴枃浠跺悜閲忕姸鎬乂O
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Schema(description = "鐭ヨ瘑搴撴枃浠跺悜閲忕姸鎬乂O")
+public class KnowledgeBaseVectorVO extends KnowledgeBaseVector {
+
+    @Schema(description = "鏂囦欢棰勮URL")
+    private String previewUrl;
+
+    @Schema(description = "鏂囦欢涓嬭浇URL")
+    private String downloadUrl;
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/approve/mapper/KnowledgeBaseVectorMapper.java b/src/main/java/com/ruoyi/approve/mapper/KnowledgeBaseVectorMapper.java
new file mode 100644
index 0000000..5fb19fe
--- /dev/null
+++ b/src/main/java/com/ruoyi/approve/mapper/KnowledgeBaseVectorMapper.java
@@ -0,0 +1,39 @@
+package com.ruoyi.approve.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.approve.dto.KnowledgeBaseVectorVO;
+import com.ruoyi.approve.pojo.KnowledgeBaseVector;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+/**
+ * 鐭ヨ瘑搴撴枃浠跺悜閲忚褰� Mapper
+ */
+@Mapper
+public interface KnowledgeBaseVectorMapper extends BaseMapper<KnowledgeBaseVector> {
+
+    /**
+     * 鏌ヨ鐭ヨ瘑搴撶殑鏂囦欢鍚戦噺鐘舵�佸垪琛�
+     */
+    @Select("SELECT v.*, b.path as previewUrl " +
+            "FROM knowledge_base_vector v " +
+            "LEFT JOIN storage_blob b ON v.storage_blob_id = b.id " +
+            "WHERE v.knowledge_base_id = #{knowledgeBaseId} " +
+            "ORDER BY v.create_time DESC")
+    List<KnowledgeBaseVectorVO> selectByKnowledgeBaseId(@Param("knowledgeBaseId") Long knowledgeBaseId);
+
+    /**
+     * 缁熻鐭ヨ瘑搴撶殑鏂囦欢鏁伴噺
+     */
+    @Select("SELECT COUNT(*) FROM knowledge_base_vector WHERE knowledge_base_id = #{knowledgeBaseId}")
+    int countByKnowledgeBaseId(@Param("knowledgeBaseId") Long knowledgeBaseId);
+
+    /**
+     * 缁熻鐭ヨ瘑搴撶殑鎬诲垏鐗囨暟閲�
+     */
+    @Select("SELECT COALESCE(SUM(chunk_count), 0) FROM knowledge_base_vector WHERE knowledge_base_id = #{knowledgeBaseId} AND vector_status = 2")
+    int sumChunkCountByKnowledgeBaseId(@Param("knowledgeBaseId") Long knowledgeBaseId);
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/approve/pojo/KnowledgeBase.java b/src/main/java/com/ruoyi/approve/pojo/KnowledgeBase.java
index 06dec8e..b15da7a 100644
--- a/src/main/java/com/ruoyi/approve/pojo/KnowledgeBase.java
+++ b/src/main/java/com/ruoyi/approve/pojo/KnowledgeBase.java
@@ -91,4 +91,19 @@
     @TableField(fill = FieldFill.INSERT)
     private Long deptId;
 
+    /**
+     * 鏂囦欢鏁伴噺
+     */
+    private Integer fileCount;
+
+    /**
+     * 鎬诲垏鐗囨暟閲�
+     */
+    private Integer totalChunkCount;
+
+    /**
+     * 鐭ヨ瘑搴撴弿杩�
+     */
+    private String description;
+
 }
diff --git a/src/main/java/com/ruoyi/approve/pojo/KnowledgeBaseVector.java b/src/main/java/com/ruoyi/approve/pojo/KnowledgeBaseVector.java
new file mode 100644
index 0000000..1db31fc
--- /dev/null
+++ b/src/main/java/com/ruoyi/approve/pojo/KnowledgeBaseVector.java
@@ -0,0 +1,80 @@
+package com.ruoyi.approve.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 鐭ヨ瘑搴撴枃浠跺悜閲忚褰曡〃
+ * knowledge_base_vector
+ */
+@Data
+@TableName("knowledge_base_vector")
+@Schema(description = "鐭ヨ瘑搴撴枃浠跺悜閲忚褰�")
+public class KnowledgeBaseVector implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @TableId(type = IdType.AUTO)
+    @Schema(description = "涓婚敭ID")
+    private Long id;
+
+    @Schema(description = "鍏宠仈鐭ヨ瘑搴揑D")
+    private Long knowledgeBaseId;
+
+    @Schema(description = "鍏宠仈鏂囦欢blob ID")
+    private Long storageBlobId;
+
+    @Schema(description = "鏂囦欢鍚嶇О")
+    private String fileName;
+
+    @Schema(description = "鏂囦欢绫诲瀷(docx/pdf/xlsx/txt绛�)")
+    private String fileType;
+
+    @Schema(description = "鍚戦噺鍖栫姸鎬�: 0-寰呭鐞�, 1-澶勭悊涓�, 2-宸插畬鎴�, 3-澶辫触")
+    private Integer vectorStatus;
+
+    @Schema(description = "鍚戦噺鍖栧け璐ュ師鍥�")
+    private String vectorError;
+
+    @Schema(description = "鍒囩墖鏁伴噺")
+    private Integer chunkCount;
+
+    @Schema(description = "鍚戦噺鍛藉悕绌洪棿")
+    private String namespace;
+
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Schema(description = "鍒涘缓鏃堕棿")
+    private LocalDateTime createTime;
+
+    @TableField(fill = FieldFill.INSERT)
+    @Schema(description = "鍒涘缓浜�")
+    private Integer createUser;
+
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Schema(description = "鏇存柊鏃堕棿")
+    private LocalDateTime updateTime;
+
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @Schema(description = "鏇存柊浜�")
+    private Integer updateUser;
+
+    @TableField(fill = FieldFill.INSERT)
+    @Schema(description = "绉熸埛ID")
+    private Long tenantId;
+
+    @TableField(fill = FieldFill.INSERT)
+    @Schema(description = "閮ㄩ棬ID")
+    private Long deptId;
+
+    // 鍚戦噺鍖栫姸鎬佸父閲�
+    public static final int STATUS_PENDING = 0;
+    public static final int STATUS_PROCESSING = 1;
+    public static final int STATUS_COMPLETED = 2;
+    public static final int STATUS_FAILED = 3;
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/approve/service/KnowledgeBaseVectorService.java b/src/main/java/com/ruoyi/approve/service/KnowledgeBaseVectorService.java
new file mode 100644
index 0000000..10f2ca9
--- /dev/null
+++ b/src/main/java/com/ruoyi/approve/service/KnowledgeBaseVectorService.java
@@ -0,0 +1,43 @@
+package com.ruoyi.approve.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.approve.dto.KnowledgeBaseVectorVO;
+import com.ruoyi.approve.pojo.KnowledgeBaseVector;
+
+import java.util.List;
+
+/**
+ * 鐭ヨ瘑搴撴枃浠跺悜閲忚褰� Service
+ */
+public interface KnowledgeBaseVectorService extends IService<KnowledgeBaseVector> {
+
+    /**
+     * 鏌ヨ鐭ヨ瘑搴撶殑鏂囦欢鍚戦噺鐘舵�佸垪琛�
+     */
+    List<KnowledgeBaseVectorVO> getVectorStatusByKnowledgeBaseId(Long knowledgeBaseId);
+
+    /**
+     * 鍒涘缓鍚戦噺璁板綍骞惰Е鍙戝紓姝ュ悜閲忓寲
+     */
+    KnowledgeBaseVector createVectorRecord(Long knowledgeBaseId, Long storageBlobId, String fileName, String fileType);
+
+    /**
+     * 鏇存柊鍚戦噺鐘舵��
+     */
+    void updateVectorStatus(Long id, Integer status, Integer chunkCount, String error);
+
+    /**
+     * 閲嶆柊澶勭悊鍚戦噺鍖�
+     */
+    void reprocessVector(Long id);
+
+    /**
+     * 鍒犻櫎鍚戦噺璁板綍鍙婄浉鍏冲悜閲忔暟鎹�
+     */
+    void deleteVector(Long id);
+
+    /**
+     * 鎵归噺鍒犻櫎鍚戦噺璁板綍
+     */
+    void deleteVectors(List<Long> ids);
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java b/src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java
index 5da3984..62d083d 100644
--- a/src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java
+++ b/src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java
@@ -111,7 +111,6 @@
                 if (TypeEnums.PURCHASE_APPROVAL.getCode().equals(vo.getBusinessType())) {
                     // 閲囪喘瀹℃壒 - 鏌ヨ閲囪喘鍗曞彿
                     PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(vo.getBusinessId());
-                    System.out.println("涓氬姟绫诲瀷锛�" + purchaseLedger.getPurchaseContractNumber());
                     if (purchaseLedger != null) {
                         vo.setPurchaseContractNumber(purchaseLedger.getPurchaseContractNumber());
                     }
@@ -420,20 +419,8 @@
         instance.setStatus("REJECTED");
         instance.setFinishTime(now);
         this.updateById(instance);
-        // 椹冲洖瀵瑰簲鐨勪紒涓氭柊闂伙紝 宸梾鎶ラ攢
-        if (instance.getBusinessType().equals(TypeEnums.ENTERPRISE_NEWS_APPROVAL.getCode())) {
-            enterpriseNewsMapper.update(
-                    new LambdaUpdateWrapper<EnterpriseNews>()
-                            .eq(EnterpriseNews::getId, instance.getBusinessId())
-                            .set(EnterpriseNews::getStatus, "REJECTED")
-            );
-        }else if (instance.getBusinessType().equals(TypeEnums.TRAVEL_REIMBURSEMENT_APPROVAL.getCode())||instance.getBusinessType().equals(TypeEnums.EXPENSE_APPROVAL.getCode())) {
-            finReimbursementMapper.update(
-                    new LambdaUpdateWrapper<FinReimbursement>()
-                            .eq(FinReimbursement::getId, instance.getBusinessId())
-                            .set(FinReimbursement::getBillStatus, "REJECTED")
-            );
-        }
+        // 缁熶竴澶勭悊涓氬姟鐘舵�佹洿鏂�
+        handleBusinessAfterApprovalFinished(instance);
         return R.ok("瀹℃壒宸查┏鍥�");
     }
 
@@ -682,7 +669,7 @@
     private void handleShippingApprovalFinished(ApprovalInstance instance, String status) {
         ShippingInfo shippingInfo = shippingInfoMapper.selectOne(
                 new LambdaQueryWrapper<ShippingInfo>()
-                        .eq(ShippingInfo::getId, instance.getTitle())
+                        .eq(ShippingInfo::getShippingNo, instance.getTitle())
                         .orderByDesc(ShippingInfo::getCreateTime)
                         .last("limit 1")
         );
@@ -757,10 +744,29 @@
 
         String title = StringUtils.hasText(instance.getTemplateName()) ? instance.getTemplateName() : "瀹℃壒鎻愰啋";
         String message = "瀹℃壒鍗曞彿 " + instance.getInstanceNo() + " 闇�瑕佹偍瀹℃壒";
-        String jumpPath = "/officeProcessAutomation/ApproveManage/approve-list?id=" + instance.getId();
+        String jumpPath = getJumpPathByBusinessType(instance.getBusinessType(), instance.getId());
         sysNoticeService.simpleNoticeByUser(title, message, approverIds, jumpPath);
     }
 
+    private String getJumpPathByBusinessType(Long businessType, Long instanceId) {
+        if (businessType == null) {
+            return "/collaborativeApproval/approve-list?id=" + instanceId;
+        }
+        if (TypeEnums.LEAVE_APPROVAL.getCode().equals(businessType)) {
+            return "/collaborativeApproval/AttendManage/leave-apply?id=" + instanceId;
+        }
+        if (TypeEnums.OVERTIME_APPROVAL.getCode().equals(businessType)) {
+            return "/collaborativeApproval/AttendManage/overtime-apply?id=" + instanceId;
+        }
+        if (TypeEnums.TRAVEL_REIMBURSEMENT_APPROVAL.getCode().equals(businessType)) {
+            return "/collaborativeApproval/ReimburseManage/travel-reimburse?id=" + instanceId;
+        }
+        if (TypeEnums.EXPENSE_APPROVAL.getCode().equals(businessType)) {
+            return "/collaborativeApproval/ReimburseManage/cost-reimburse?id=" + instanceId;
+        }
+        return "/collaborativeApproval/approve-list?id=" + instanceId;
+    }
+
     private void sendEnterpriseNewsNotice(Long newsId) {
         EnterpriseNews enterpriseNews = enterpriseNewsMapper.selectById(newsId);
         if (enterpriseNews == null) {
diff --git a/src/main/java/com/ruoyi/approve/service/impl/ApprovalTemplateServiceImpl.java b/src/main/java/com/ruoyi/approve/service/impl/ApprovalTemplateServiceImpl.java
index a0b07d5..9a5f0b8 100644
--- a/src/main/java/com/ruoyi/approve/service/impl/ApprovalTemplateServiceImpl.java
+++ b/src/main/java/com/ruoyi/approve/service/impl/ApprovalTemplateServiceImpl.java
@@ -13,6 +13,8 @@
 import com.ruoyi.approve.bean.vo.ApprovalTemplateVo;
 import com.ruoyi.approve.mapper.ApprovalTemplateMapper;
 import com.ruoyi.approve.mapper.ApprovalTemplateNodeApproverMapper;
+import com.ruoyi.approve.mapper.ApprovalInstanceMapper;
+import com.ruoyi.approve.pojo.ApprovalInstance;
 import com.ruoyi.approve.pojo.ApprovalTemplate;
 import com.ruoyi.approve.pojo.ApprovalTemplateNode;
 import com.ruoyi.approve.pojo.ApprovalTemplateNodeApprover;
@@ -48,6 +50,7 @@
     private final ApprovalTemplateMapper approvalTemplateMapper;
     private final ApprovalTemplateNodeService approvalTemplateNodeService;
     private final ApprovalTemplateNodeApproverMapper approvalTemplateNodeApproverMapper;
+    private final ApprovalInstanceMapper approvalInstanceMapper;
     private final FileUtil fileUtil;
 
     @Override
@@ -82,6 +85,10 @@
 
     @Override
     public Boolean updateApprovalTemplateDto(ApprovalTemplateDto approvalTemplateDto) {
+        // 妫�鏌ユā鏉挎槸鍚﹁瀹℃壒瀹炰緥寮曠敤
+        if (isTemplateReferenced(approvalTemplateDto.getId())) {
+            throw new RuntimeException("璇ュ鎵规ā鏉垮凡琚鎵规祦绋嬪紩鐢紝鏃犳硶缂栬緫");
+        }
         approvalTemplateMapper.updateById(approvalTemplateDto);
         approvalTemplateNodeService.remove(
                 new LambdaQueryWrapper<ApprovalTemplateNode>()
@@ -111,6 +118,12 @@
     public Boolean delete(List<Long> ids) {
         if (ids == null || ids.isEmpty()) {
             return false;
+        }
+        // 妫�鏌ユā鏉挎槸鍚﹁瀹℃壒瀹炰緥寮曠敤
+        for (Long id : ids) {
+            if (isTemplateReferenced(id)) {
+                throw new RuntimeException("瀹℃壒妯℃澘锛圛D: " + id + "锛夊凡琚鎵规祦绋嬪紩鐢紝鏃犳硶鍒犻櫎");
+            }
         }
         ApprovalTemplate updateEntity = new ApprovalTemplate();
         updateEntity.setDeleted(1);
@@ -275,4 +288,21 @@
         BeanUtils.copyProperties(approver, approverVo);
         return approverVo;
     }
+
+    /**
+     * 妫�鏌ュ鎵规ā鏉挎槸鍚﹁瀹℃壒瀹炰緥寮曠敤
+     * @param templateId 妯℃澘ID
+     * @return true 琛ㄧず琚紩鐢紝false 琛ㄧず鏈寮曠敤
+     */
+    private boolean isTemplateReferenced(Long templateId) {
+        if (templateId == null) {
+            return false;
+        }
+        Long count = approvalInstanceMapper.selectCount(
+                new LambdaQueryWrapper<ApprovalInstance>()
+                        .eq(ApprovalInstance::getTemplateId, templateId)
+                        .eq(ApprovalInstance::getDeleted, 0)
+        );
+        return count != null && count > 0;
+    }
 }
diff --git a/src/main/java/com/ruoyi/approve/service/impl/FinReimbursementServiceImpl.java b/src/main/java/com/ruoyi/approve/service/impl/FinReimbursementServiceImpl.java
index 305ea9d..a3d33f4 100644
--- a/src/main/java/com/ruoyi/approve/service/impl/FinReimbursementServiceImpl.java
+++ b/src/main/java/com/ruoyi/approve/service/impl/FinReimbursementServiceImpl.java
@@ -274,6 +274,26 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Boolean delete(List<Long> ids) {
+        if (ids == null || ids.isEmpty()) {
+            throw new ServiceException("鍒犻櫎澶辫触锛岃閫夋嫨瑕佸垹闄ょ殑鏁版嵁");
+        }
+        // 鏌ヨ鎶ラ攢鍗曞叧鑱旂殑瀹℃壒瀹炰緥ID
+        List<FinReimbursement> reimbursements = finReimbursementMapper.selectList(
+                new LambdaQueryWrapper<FinReimbursement>()
+                        .in(FinReimbursement::getId, ids)
+                        .isNotNull(FinReimbursement::getApprovalInstanceId)
+        );
+        List<Long> approvalInstanceIds = reimbursements.stream()
+                .map(FinReimbursement::getApprovalInstanceId)
+                .filter(Objects::nonNull)
+                .distinct()
+                .collect(Collectors.toList());
+
+        // 鍒犻櫎鍏宠仈鐨勫鎵硅褰�
+        if (!approvalInstanceIds.isEmpty()) {
+            approvalInstanceService.delete(approvalInstanceIds);
+        }
+
         fileUtil.deleteStorageAttachmentsByApplicationAndRecordTypeAndRecordIds(ApplicationTypeEnum.FILE, RecordTypeEnum.FIN_REIMBURSEMENT, ids);
         //鍏堝垹闄ゆ槑缁�
         finReimbursementDetailMapper.delete(new LambdaQueryWrapper<FinReimbursementDetail>().in(FinReimbursementDetail::getReimbursementId, ids));
@@ -494,10 +514,20 @@
         }
         String title = "鎶ラ攢瀹℃壒";
         String message = "瀹℃壒鍗曞彿 " + instance.getInstanceNo() + " 闇�瑕佹偍瀹℃壒";
-        String jumpPath = "/approvalInstance?id=" + instance.getId();
+        String jumpPath = getJumpPathByBusinessType(instance.getBusinessType(), instance.getId());
         sysNoticeService.simpleNoticeByUser(title, message, approverIds, jumpPath);
     }
 
+    private String getJumpPathByBusinessType(Long businessType, Long instanceId) {
+        if (TypeEnums.TRAVEL_REIMBURSEMENT_APPROVAL.getCode().equals(businessType)) {
+            return "/collaborativeApproval/ReimburseManage/travel-reimburse?id=" + instanceId;
+        }
+        if (TypeEnums.EXPENSE_APPROVAL.getCode().equals(businessType)) {
+            return "/collaborativeApproval/ReimburseManage/cost-reimburse?id=" + instanceId;
+        }
+        return "/approvalInstance?id=" + instanceId;
+    }
+
     private void resetApprovalFlow(FinReimbursement existing, Long reimbursementId) {
         if (existing == null || existing.getApprovalInstanceId() == null) {
             return;
diff --git a/src/main/java/com/ruoyi/approve/service/impl/KnowledgeBaseVectorServiceImpl.java b/src/main/java/com/ruoyi/approve/service/impl/KnowledgeBaseVectorServiceImpl.java
new file mode 100644
index 0000000..52bc0b5
--- /dev/null
+++ b/src/main/java/com/ruoyi/approve/service/impl/KnowledgeBaseVectorServiceImpl.java
@@ -0,0 +1,144 @@
+package com.ruoyi.approve.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.approve.dto.KnowledgeBaseVectorVO;
+import com.ruoyi.approve.mapper.KnowledgeBaseVectorMapper;
+import com.ruoyi.approve.pojo.KnowledgeBase;
+import com.ruoyi.approve.pojo.KnowledgeBaseVector;
+import com.ruoyi.approve.service.KnowledgeBaseService;
+import com.ruoyi.approve.service.KnowledgeBaseVectorService;
+import com.ruoyi.ai.service.KnowledgeRagService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/**
+ * 鐭ヨ瘑搴撴枃浠跺悜閲忚褰� Service瀹炵幇
+ */
+@Slf4j
+@Service
+public class KnowledgeBaseVectorServiceImpl extends ServiceImpl<KnowledgeBaseVectorMapper, KnowledgeBaseVector>
+        implements KnowledgeBaseVectorService {
+
+    private final KnowledgeBaseService knowledgeBaseService;
+    private final KnowledgeRagService knowledgeRagService;
+
+    public KnowledgeBaseVectorServiceImpl(
+            KnowledgeBaseService knowledgeBaseService,
+            @Lazy KnowledgeRagService knowledgeRagService) {
+        this.knowledgeBaseService = knowledgeBaseService;
+        this.knowledgeRagService = knowledgeRagService;
+    }
+
+    @Override
+    public List<KnowledgeBaseVectorVO> getVectorStatusByKnowledgeBaseId(Long knowledgeBaseId) {
+        return baseMapper.selectByKnowledgeBaseId(knowledgeBaseId);
+    }
+
+    @Override
+    public KnowledgeBaseVector createVectorRecord(Long knowledgeBaseId, Long storageBlobId,
+                                                   String fileName, String fileType) {
+        KnowledgeBase knowledgeBase = knowledgeBaseService.getById(knowledgeBaseId);
+        if (knowledgeBase == null) {
+            throw new RuntimeException("鐭ヨ瘑搴撲笉瀛樺湪: " + knowledgeBaseId);
+        }
+
+        KnowledgeBaseVector vector = new KnowledgeBaseVector();
+        vector.setKnowledgeBaseId(knowledgeBaseId);
+        vector.setStorageBlobId(storageBlobId);
+        vector.setFileName(fileName);
+        vector.setFileType(fileType);
+        vector.setVectorStatus(KnowledgeBaseVector.STATUS_PENDING);
+        vector.setNamespace("kb-" + knowledgeBaseId);
+        vector.setChunkCount(0);
+        save(vector);
+
+        // 寮傛瑙﹀彂鍚戦噺鍖栧鐞�
+        knowledgeRagService.processVectorAsync(vector.getId());
+
+        return vector;
+    }
+
+    @Override
+    public void updateVectorStatus(Long id, Integer status, Integer chunkCount, String error) {
+        KnowledgeBaseVector vector = getById(id);
+        if (vector == null) {
+            return;
+        }
+        vector.setVectorStatus(status);
+        if (chunkCount != null) {
+            vector.setChunkCount(chunkCount);
+        }
+        if (error != null) {
+            vector.setVectorError(error);
+        }
+        updateById(vector);
+
+        // 濡傛灉瀹屾垚锛屾洿鏂扮煡璇嗗簱缁熻
+        if (status == KnowledgeBaseVector.STATUS_COMPLETED) {
+            updateKnowledgeBaseStats(vector.getKnowledgeBaseId());
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void reprocessVector(Long id) {
+        KnowledgeBaseVector vector = getById(id);
+        if (vector == null) {
+            throw new RuntimeException("鍚戦噺璁板綍涓嶅瓨鍦�: " + id);
+        }
+        vector.setVectorStatus(KnowledgeBaseVector.STATUS_PENDING);
+        vector.setVectorError(null);
+        vector.setChunkCount(0);
+        updateById(vector);
+
+        // 寮傛閲嶆柊澶勭悊
+        knowledgeRagService.processVectorAsync(id);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void deleteVector(Long id) {
+        KnowledgeBaseVector vector = getById(id);
+        if (vector == null) {
+            return;
+        }
+
+        // 鍒犻櫎鍚戦噺搴撲腑鐨勬暟鎹�
+        try {
+            knowledgeRagService.deleteEmbeddings(vector.getNamespace(), vector.getStorageBlobId());
+        } catch (Exception e) {
+            log.error("鍒犻櫎鍚戦噺搴撴暟鎹け璐�", e);
+        }
+
+        // 鍒犻櫎璁板綍
+        removeById(id);
+
+        // 鏇存柊鐭ヨ瘑搴撶粺璁�
+        updateKnowledgeBaseStats(vector.getKnowledgeBaseId());
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void deleteVectors(List<Long> ids) {
+        for (Long id : ids) {
+            deleteVector(id);
+        }
+    }
+
+    private void updateKnowledgeBaseStats(Long knowledgeBaseId) {
+        KnowledgeBase knowledgeBase = knowledgeBaseService.getById(knowledgeBaseId);
+        if (knowledgeBase == null) {
+            return;
+        }
+        int fileCount = baseMapper.countByKnowledgeBaseId(knowledgeBaseId);
+        int totalChunkCount = baseMapper.sumChunkCountByKnowledgeBaseId(knowledgeBaseId);
+        knowledgeBase.setFileCount(fileCount);
+        knowledgeBase.setTotalChunkCount(totalChunkCount);
+        knowledgeBaseService.updateById(knowledgeBase);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/basic/enums/ApplicationTypeEnum.java b/src/main/java/com/ruoyi/basic/enums/ApplicationTypeEnum.java
index 8cdf321..8b069a0 100644
--- a/src/main/java/com/ruoyi/basic/enums/ApplicationTypeEnum.java
+++ b/src/main/java/com/ruoyi/basic/enums/ApplicationTypeEnum.java
@@ -5,7 +5,8 @@
     FILE("file"),
     AFTER_FILE("after_file"),
     BEFORE_FILE("before_file"),
-    APK("apk");
+    APK("apk"),
+    RAG_FILE("rag_file");
 
 
     private final String type;
diff --git a/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java b/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
index 92a632b..5a4d19a 100644
--- a/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
+++ b/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
@@ -212,6 +212,7 @@
     public int updateCustomer(Customer customer) {
         LoginUser loginUser = SecurityUtils.getLoginUser();
         Long tenantId = loginUser.getTenantId();
+        validateCustomerEditPermission(customer.getId());
         customer.setTenantId(tenantId);
         return customerMapper.updateById(customer);
     }
@@ -309,18 +310,26 @@
 
     @Override
     public List<Map<String, Object>> customerList(Customer customer) {
-        LambdaQueryWrapper<Customer> queryWrapper = Wrappers.lambdaQuery();
-        queryWrapper.select(Customer::getId, Customer::getCustomerName, Customer::getTaxpayerIdentificationNumber);
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        Long loginUserId = loginUser.getUserId();
+        CustomerDto query = new CustomerDto();
+        if (customer != null) {
+            BeanUtils.copyProperties(customer, query);
+        }
 
-        // 鑾峰彇鍘熷鏌ヨ缁撴灉
-        List<Map<String, Object>> result = customerMapper.selectMaps(queryWrapper);
+        // 澶嶇敤瀹㈡埛鍒楄〃鐨勫彲瑙佹�ц鍒欙紝閬垮厤鎶婂埆浜虹殑绉佹捣瀹㈡埛鏆撮湶缁欏綋鍓嶈处鍙�
+        List<CustomerVo> visibleCustomers = customerMapper.list(query, loginUserId);
+        if (CollectionUtils.isEmpty(visibleCustomers)) {
+            return Collections.emptyList();
+        }
 
-        // 灏嗕笅鍒掔嚎鍛藉悕杞崲涓洪┘宄板懡鍚�
-        return result.stream().map(map -> map.entrySet().stream()
-                .collect(Collectors.toMap(
-                        entry -> underlineToCamel(entry.getKey()),
-                        Map.Entry::getValue))
-        ).collect(Collectors.toList());
+        return visibleCustomers.stream().map(item -> {
+            Map<String, Object> map = new LinkedHashMap<>();
+            map.put("id", item.getId());
+            map.put("customerName", item.getCustomerName());
+            map.put("taxpayerIdentificationNumber", item.getTaxpayerIdentificationNumber());
+            return map;
+        }).collect(Collectors.toList());
     }
 
     // 鍒嗛厤鍏捣瀹㈡埛缁欑娴�
@@ -341,6 +350,7 @@
     public void recycleCustomer(CustomerDto customerDto) {
         Customer customer = customerMapper.selectById(customerDto.getId());
         if (customer.getType() == 1 && customer.getIsAssigned() == 1) {  // 鍏捣涓斿凡鍒嗛厤
+            validatePublicSeaRecyclePermission(customer.getId());
             customer.setIsAssigned(0);
             customer.setUsageStatus(0L);
             customer.setUsageUser(0L);
@@ -403,6 +413,44 @@
         return this.updateById(customer);
     }
 
+    private void validateCustomerEditPermission(Long customerId) {
+        Customer customer = customerMapper.selectById(customerId);
+        if (customer == null) {
+            throw new RuntimeException("瀹㈡埛妗f涓嶅瓨鍦�");
+        }
+        if (!hasSalesModuleReference(customerId)) {
+            return;
+        }
+        if (Objects.equals(customer.getType(), 0)) {
+            throw new RuntimeException("宸茶閿�鍞ā鍧楀紩鐢ㄧ殑绉佹捣瀹㈡埛涓嶈兘缂栬緫");
+        }
+        if (Objects.equals(customer.getType(), 1) && Objects.equals(customer.getIsAssigned(), 1)) {
+            throw new RuntimeException("宸查鐢ㄥ苟涓旇閿�鍞ā鍧楀紩鐢ㄧ殑鍏捣瀹㈡埛涓嶈兘缂栬緫");
+        }
+    }
+
+    private void validatePublicSeaRecyclePermission(Long customerId) {
+        if (hasSalesModuleReference(customerId)) {
+            throw new RuntimeException("宸查鐢ㄥ苟涓旇閿�鍞ā鍧楀紩鐢ㄧ殑鍏捣瀹㈡埛涓嶈兘鍥炴敹");
+        }
+    }
+
+    private boolean hasSalesModuleReference(Long customerId) {
+        Long salesLedgerCount = salesLedgerMapper.selectCount(new QueryWrapper<SalesLedger>().lambda()
+                .eq(SalesLedger::getCustomerId, customerId));
+        if (salesLedgerCount != null && salesLedgerCount > 0) {
+            return true;
+        }
+        Long salesQuotationCount = salesQuotationMapper.selectCount(new QueryWrapper<SalesQuotation>().lambda()
+                .eq(SalesQuotation::getCustomerId, customerId));
+        if (salesQuotationCount != null && salesQuotationCount > 0) {
+            return true;
+        }
+        Long returnManagementCount = returnManagementMapper.selectCount(new QueryWrapper<ReturnManagement>().lambda()
+                .eq(ReturnManagement::getCustomerId, customerId));
+        return returnManagementCount != null && returnManagementCount > 0;
+    }
+
     @Override
     public IPage<CustomerTransactionsVo> customewTransactions(Page page, String customerName) {
         return customerMapper.customewTransactions(page, customerName);
diff --git a/src/main/java/com/ruoyi/basic/vo/CustomerVo.java b/src/main/java/com/ruoyi/basic/vo/CustomerVo.java
index 3d4c8cb..0f72a2f 100644
--- a/src/main/java/com/ruoyi/basic/vo/CustomerVo.java
+++ b/src/main/java/com/ruoyi/basic/vo/CustomerVo.java
@@ -25,4 +25,9 @@
      * 鍏变韩鐢ㄦ埛ID瀛楃涓诧紙SQL鏌ヨ杩斿洖锛岀敤浜庤浆鎹负List锛�
      */
     private String userIdsStr;
+
+    /**
+     * 鏄惁琚攢鍞ā鍧楀紩鐢細0-鍚︼紝1-鏄�
+     */
+    private Integer salesReferenceFlag;
 }
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsServiceImpl.java b/src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsServiceImpl.java
index 4a4d9c1..daa1c89 100644
--- a/src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsServiceImpl.java
+++ b/src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsServiceImpl.java
@@ -403,7 +403,7 @@
 
         String title = StringUtils.isNotEmpty(instance.getTemplateName()) ? instance.getTemplateName() : "瀹℃壒鎻愰啋";
         String message = "瀹℃壒鍗曞彿 " + instance.getInstanceNo() + " 闇�瑕佹偍瀹℃壒";
-        String jumpPath = "/officeProcessAutomation/ApproveManage/approve-list/?id=" + instance.getId();
+        String jumpPath = "/collaborativeApproval/approve-list/?id=" + instance.getId();
         sysNoticeService.simpleNoticeByUser(title, message, approverIds, jumpPath);
     }
 }
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/service/impl/MeetingServiceImpl.java b/src/main/java/com/ruoyi/collaborativeApproval/service/impl/MeetingServiceImpl.java
index 636130a..baa8d02 100644
--- a/src/main/java/com/ruoyi/collaborativeApproval/service/impl/MeetingServiceImpl.java
+++ b/src/main/java/com/ruoyi/collaborativeApproval/service/impl/MeetingServiceImpl.java
@@ -238,9 +238,9 @@
                     .or()
                     .eq(MeetApplication::getApplicationType, "notification");
         });
-        if (Objects.nonNull(vo.getMeetingDate())) {
+        if (Objects.nonNull(vo.getDate())) {
             alWrapper.and(wrapper -> {
-                wrapper.eq(MeetApplication::getMeetingDate, vo.getMeetingDate());
+                wrapper.eq(MeetApplication::getMeetingDate, vo.getDate());
             });
         }
         alWrapper.orderByAsc(MeetApplication::getStartTime);
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/vo/SearchMeetingUseVo.java b/src/main/java/com/ruoyi/collaborativeApproval/vo/SearchMeetingUseVo.java
index a782b19..6676876 100644
--- a/src/main/java/com/ruoyi/collaborativeApproval/vo/SearchMeetingUseVo.java
+++ b/src/main/java/com/ruoyi/collaborativeApproval/vo/SearchMeetingUseVo.java
@@ -16,4 +16,6 @@
     @JsonFormat(pattern = "yyyy-MM-dd")
     @DateTimeFormat(pattern = "yyyy-MM-dd")
     private Date meetingDate;
+
+    private String date;
 }
diff --git a/src/main/java/com/ruoyi/common/enums/StockOutQualifiedRecordTypeEnum.java b/src/main/java/com/ruoyi/common/enums/StockOutQualifiedRecordTypeEnum.java
index ccc6d78..a27680a 100644
--- a/src/main/java/com/ruoyi/common/enums/StockOutQualifiedRecordTypeEnum.java
+++ b/src/main/java/com/ruoyi/common/enums/StockOutQualifiedRecordTypeEnum.java
@@ -7,7 +7,6 @@
 public enum StockOutQualifiedRecordTypeEnum implements BaseEnum<String> {
     CUSTOMIZATION_STOCK_OUT("1", "鍚堟牸鑷畾涔夊嚭搴�"),
     PRODUCTION_REPORT_STOCK_OUT("3", "鐢熶骇鎶ュ伐-鍑哄簱"),
-    SALE_STOCK_OUT("8", "閿�鍞�-鍑哄簱"),
     PURCHASE_RETURN_STOCK_OUT("9", "閲囪喘閫�璐�"),
     CUSTOMIZATION_UNSTOCK_OUT("10", "涓嶅悎鏍艰嚜瀹氫箟鍑哄簱"),
     SALE_SHIP_STOCK_OUT("13", "閿�鍞�-鍙戣揣鍑哄簱"),
diff --git a/src/main/java/com/ruoyi/common/utils/DateUtils.java b/src/main/java/com/ruoyi/common/utils/DateUtils.java
index 0fa7e5a..f0b14f9 100644
--- a/src/main/java/com/ruoyi/common/utils/DateUtils.java
+++ b/src/main/java/com/ruoyi/common/utils/DateUtils.java
@@ -3,17 +3,13 @@
 import java.lang.management.ManagementFactory;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
+import java.time.*;
 import java.util.Date;
 import org.apache.commons.lang3.time.DateFormatUtils;
 
 /**
  * 鏃堕棿宸ュ叿绫�
- * 
+ *
  * @author ruoyi
  */
 public class DateUtils extends org.apache.commons.lang3.time.DateUtils
@@ -29,13 +25,13 @@
     public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
 
     private static String[] parsePatterns = {
-            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", 
+            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
             "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
             "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
 
     /**
      * 鑾峰彇褰撳墠Date鍨嬫棩鏈�
-     * 
+     *
      * @return Date() 褰撳墠鏃ユ湡
      */
     public static Date getNowDate()
@@ -45,16 +41,15 @@
 
     public static LocalDate toLocalDate(Date date){
         if(date == null) return LocalDate.now();
-        // 2. 鎸囧畾鍥哄畾鏃跺尯杞崲锛堝涓滃叓鍖篣TC+8銆乁TC闆舵椂鍖猴級
-        return date.toInstant()
-                .atZone(ZoneId.of("Asia/Shanghai")) // 涓滃叓鍖猴紙鍖椾含/涓婃捣鏃跺尯锛�
-                // .atZone(ZoneId.of("UTC")) // 鍙�夛細UTC闆舵椂鍖�
+        // java.sql.Date.toInstant() 浼氭姏 UnsupportedOperationException锛岄渶鍏堣浆涓� java.util.Date
+        Instant instant = new java.util.Date(date.getTime()).toInstant();
+        return instant.atZone(ZoneId.of("Asia/Shanghai"))
                 .toLocalDate();
     }
 
     /**
      * 鑾峰彇褰撳墠鏃ユ湡, 榛樿鏍煎紡涓簓yyy-MM-dd
-     * 
+     *
      * @return String
      */
     public static String getDate()
diff --git a/src/main/java/com/ruoyi/home/controller/HomeController.java b/src/main/java/com/ruoyi/home/controller/HomeController.java
index 7878d28..35c3954 100644
--- a/src/main/java/com/ruoyi/home/controller/HomeController.java
+++ b/src/main/java/com/ruoyi/home/controller/HomeController.java
@@ -61,7 +61,8 @@
     private static final Integer ORDER_STATUS_WAIT = 1;
     private static final Integer ORDER_STATUS_RUNNING = 2;
     private static final Integer ORDER_STATUS_COMPLETED = 3;
-    private static final Integer ORDER_STATUS_PAUSED = 4;
+    //private static final Integer ORDER_STATUS_END = 4;  // 宸插彇娑�
+    private static final Integer ORDER_STATUS_END = 5;
 
     /********************************************************鍩虹绫�*****************************************************/
     @GetMapping("/todos")
@@ -260,13 +261,14 @@
         }
         Integer statusFromParam = parseOrderStatus(status);
         if (!isBlank(status) && statusFromParam == null && !"all".equalsIgnoreCase(status.trim())) {
-            return R.fail("status鍙傛暟涓嶅悎娉曪紝鍙�夊�硷細all/waiting/inProgress/completed/paused 鎴� 1/2/3/4");
+            return R.fail("status鍙傛暟涓嶅悎娉曪紝鍙�夊�硷細all/waiting/inProgress/completed/end 鎴� 1/2/3/5");
         }
         Integer queryStatus = resolveOrderStatus(status, tab);
 
         long safePageNum = pageNum == null || pageNum < 1 ? 1 : pageNum;
-        long safePageSize = pageSize == null || pageSize < 1 ? 10 : Math.min(pageSize, 50);
-        long offset = (safePageNum - 1) * safePageSize;
+        boolean queryAll = pageSize != null && pageSize == -1;
+        long safePageSize = queryAll ? -1 : (pageSize == null || pageSize < 1 ? 10 : Math.min(pageSize, 50));
+        long offset = queryAll ? 0 : (safePageNum - 1) * safePageSize;
         LocalDateTime startTime = queryDate == null ? null : queryDate.atStartOfDay();
         LocalDateTime endTime = queryDate == null ? null : queryDate.plusDays(1).atStartOfDay();
 
@@ -281,7 +283,7 @@
         long waitingCount = 0L;
         long inProgressCount = 0L;
         long completedCount = 0L;
-        long pausedCount = 0L;
+        long endCount = 0L;
         List<Map<String, Object>> statusCountRows = productionOrderMapper.countHomeOrderProgressByStatus(startTime, endTime);
         if (statusCountRows != null) {
             for (Map<String, Object> countRow : statusCountRows) {
@@ -293,8 +295,8 @@
                     inProgressCount = cnt;
                 } else if (Objects.equals(statusKey, ORDER_STATUS_COMPLETED)) {
                     completedCount = cnt;
-                } else if (Objects.equals(statusKey, ORDER_STATUS_PAUSED)) {
-                    pausedCount = cnt;
+                } else if (Objects.equals(statusKey, ORDER_STATUS_END)) {
+                    endCount = cnt;
                 }
             }
         }
@@ -303,13 +305,13 @@
         result.put("tab", mapOrderTab(queryStatus));
         result.put("status", mapOrderStatus(queryStatus));
         result.put("bizDate", queryDate == null ? null : queryDate.format(DATE_FORMATTER));
-        result.put("total", toLong(productionOrderMapper.countHomeOrderProgress(queryStatus, startTime, endTime)));
+        result.put("total", toLong(productionOrderMapper.countHomeOrderProgress(null, startTime, endTime)));
         result.put("pageNum", safePageNum);
         result.put("pageSize", safePageSize);
         result.put("waitingCount", waitingCount);
         result.put("inProgressCount", inProgressCount);
         result.put("completedCount", completedCount);
-        result.put("pausedCount", pausedCount);
+        result.put("endCount", endCount);
         result.put("records", records);
         return R.ok(result);
     }
@@ -529,8 +531,8 @@
         if ("3".equals(normalized) || "completed".equals(normalized)) {
             return ORDER_STATUS_COMPLETED;
         }
-        if ("4".equals(normalized) || "paused".equals(normalized)) {
-            return ORDER_STATUS_PAUSED;
+        if ("5".equals(normalized) || "end".equals(normalized)) {
+            return ORDER_STATUS_END;
         }
         return null;
     }
@@ -542,8 +544,8 @@
         if (Objects.equals(status, ORDER_STATUS_COMPLETED)) {
             return "completed";
         }
-        if (Objects.equals(status, ORDER_STATUS_PAUSED)) {
-            return "paused";
+        if (Objects.equals(status, ORDER_STATUS_END)) {
+            return "end";
         }
         if (Objects.equals(status, ORDER_STATUS_WAIT)) {
             return "waiting";
@@ -561,8 +563,8 @@
         if (Objects.equals(status, ORDER_STATUS_COMPLETED)) {
             return "completed";
         }
-        if (Objects.equals(status, ORDER_STATUS_PAUSED)) {
-            return "paused";
+        if (Objects.equals(status, ORDER_STATUS_END)) {
+            return "end";
         }
         return "all";
     }
@@ -577,8 +579,8 @@
         if (Objects.equals(status, ORDER_STATUS_COMPLETED)) {
             return "宸插畬鎴�";
         }
-        if (Objects.equals(status, ORDER_STATUS_PAUSED)) {
-            return "宸叉殏鍋�";
+        if (Objects.equals(status, ORDER_STATUS_END)) {
+            return "宸茬粨鏉�";
         }
         return "鏈煡";
     }
@@ -635,7 +637,7 @@
                 .select(ProductionOrder::getQuantity, ProductionOrder::getCompleteQuantity)
                 .ge(ProductionOrder::getCreateTime, day.atStartOfDay())
                 .lt(ProductionOrder::getCreateTime, day.plusDays(1).atStartOfDay())
-                .ne(ProductionOrder::getStatus, ORDER_STATUS_PAUSED));
+                .ne(ProductionOrder::getStatus, ORDER_STATUS_END));
 
         BigDecimal totalQuantity = BigDecimal.ZERO;
         BigDecimal totalCompleteQuantity = BigDecimal.ZERO;
diff --git a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
index d3c21a2..8aa7871 100644
--- a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
+++ b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -18,7 +18,11 @@
 import com.ruoyi.account.pojo.purchase.AccountPurchasePayment;
 import com.ruoyi.account.pojo.sales.AccountSalesCollection;
 import com.ruoyi.approve.mapper.ApproveProcessMapper;
+import com.ruoyi.approve.mapper.ApprovalInstanceMapper;
+import com.ruoyi.approve.mapper.ApprovalTaskMapper;
 import com.ruoyi.approve.pojo.ApproveProcess;
+import com.ruoyi.approve.pojo.ApprovalInstance;
+import com.ruoyi.approve.pojo.ApprovalTask;
 import com.ruoyi.basic.mapper.CustomerMapper;
 import com.ruoyi.basic.mapper.ProductMapper;
 import com.ruoyi.basic.mapper.SupplierManageMapper;
@@ -28,6 +32,7 @@
 import com.ruoyi.collaborativeApproval.mapper.NoticeMapper;
 import com.ruoyi.collaborativeApproval.pojo.Notice;
 import com.ruoyi.common.enums.ApproveTypeEnum;
+import com.ruoyi.common.enums.TypeEnums;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.device.mapper.DeviceRepairMapper;
@@ -97,6 +102,10 @@
     private final QualityInspectMapper qualityStatisticsMapper;
 
     private final ApproveProcessMapper approveProcessMapper;
+
+    private final ApprovalTaskMapper approvalTaskMapper;
+
+    private final ApprovalInstanceMapper approvalInstanceMapper;
 
     private final SysDeptMapper sysDeptMapper;
 
@@ -384,40 +393,58 @@
     @Override
     public List<ApproveProcess> todos() throws ParseException {
         LoginUser loginUser = SecurityUtils.getLoginUser();
+        List<ApproveProcess> approveProcesses = new ArrayList<>();
+
+        // 鏌ヨ鏃у鎵硅〃锛坅pprove_process锛�
         LambdaQueryWrapper<ApproveProcess> approveProcessLambdaQueryWrapper = new LambdaQueryWrapper<>();
         approveProcessLambdaQueryWrapper.eq(ApproveProcess::getApproveDelete, 0)
                 .eq(ApproveProcess::getApproveUserCurrentId, loginUser.getUserId())
                 .ne(ApproveProcess::getApproveStatus, 2);
-        // .eq(ApproveProcess::getTenantId, loginUser.getTenantId());
-        List<ApproveProcess> approveProcesses = approveProcessMapper.selectList(approveProcessLambdaQueryWrapper);
-        if (CollectionUtils.isEmpty(approveProcesses)) {
-            approveProcesses = new ArrayList<>();
+        List<ApproveProcess> oldList = approveProcessMapper.selectList(approveProcessLambdaQueryWrapper);
+        if (!CollectionUtils.isEmpty(oldList)) {
+            oldList.forEach(a -> {
+                if (a.getApproveType() != null) {
+                    a.setApproveTypeName(ApproveTypeEnum.getNameByCode(a.getApproveType()));
+                }
+            });
+            approveProcesses.addAll(oldList);
         }
 
-        approveProcesses.forEach(a -> {
-            if (a.getApproveType() != null) {
-                a.setApproveTypeName(ApproveTypeEnum.getNameByCode(a.getApproveType()));
+        // 鏌ヨ鏂板鎵硅〃锛坅pproval_task + approval_instance锛�
+        List<ApprovalTask> pendingTasks = approvalTaskMapper.selectList(new LambdaQueryWrapper<ApprovalTask>()
+                .eq(ApprovalTask::getApproverId, loginUser.getUserId())
+                .eq(ApprovalTask::getTaskStatus, "PENDING")
+                .eq(ApprovalTask::getDeleted, 0));
+        if (!CollectionUtils.isEmpty(pendingTasks)) {
+            List<Long> instanceIds = pendingTasks.stream()
+                    .map(ApprovalTask::getInstanceId)
+                    .distinct()
+                    .collect(Collectors.toList());
+            List<ApprovalInstance> instances = approvalInstanceMapper.selectList(new LambdaQueryWrapper<ApprovalInstance>()
+                    .in(ApprovalInstance::getId, instanceIds)
+                    .eq(ApprovalInstance::getDeleted, 0));
+            Map<Long, ApprovalInstance> instanceMap = instances.stream()
+                    .collect(Collectors.toMap(ApprovalInstance::getId, i -> i, (a, b) -> a));
+
+            for (ApprovalTask task : pendingTasks) {
+                ApprovalInstance instance = instanceMap.get(task.getInstanceId());
+                if (instance == null) {
+                    continue;
+                }
+                ApproveProcess ap = new ApproveProcess();
+                ap.setId(instance.getId());
+                ap.setApproveId(instance.getInstanceNo());
+                ap.setApproveReason(instance.getTitle());
+                ap.setApproveTime(instance.getApplyTime() != null ? java.sql.Timestamp.valueOf(instance.getApplyTime()) : null);
+                ap.setApproveUserName(instance.getApplicantName());
+                ap.setApproveDeptName(instance.getTemplateName());
+                if (instance.getBusinessType() != null) {
+                    ap.setApproveType(instance.getBusinessType().intValue());
+                    ap.setApproveTypeName(TypeEnums.getLabelByValue(instance.getBusinessType()));
+                }
+                approveProcesses.add(ap);
             }
-        });
-        // // 鏌ヨ鏈鐢ㄥ姵淇濊褰�
-        // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
-        //
-        // LaborIssue laborIssue1 = new LaborIssue();
-        // laborIssue1.setAdoptedDate(new Date());
-        // laborIssue1.setIssueDate(sdf.parse(sdf.format(new Date())));
-        // List<LaborIssue> laborIssues = lavorIssueMapper.list(laborIssue1);
-        // //staff_join_leave_record琛ㄨ鍒犻櫎
-        // if(!CollectionUtils.isEmpty(laborIssues)){
-        // for (LaborIssue laborIssue : laborIssues) {
-        // ApproveProcess approveProcess = new ApproveProcess();
-        // approveProcess.setApproveId(laborIssue.getOrderNo());
-        // approveProcess.setApproveDeptName(sysDeptMapper.selectDeptById(loginUser.getTenantId()).getDeptName());
-        // approveProcess.setApproveTime(laborIssue.getIssueDate());
-        // approveProcess.setApproveReason(laborIssue.getDictTypeName() + "-" +
-        // laborIssue.getDictName() + "瓒呮椂鏈鍙�");
-        // approveProcesses.add(approveProcess);
-        // }
-        // }
+        }
 
         return approveProcesses;
     }
@@ -470,18 +497,23 @@
 
     @Override
     public Map<String, Object> approveAndDeviceTodos() {
-        // 瀹℃壒鍗忓悓寰呭姙
-        Long aLong = approveProcessMapper.selectCount(new LambdaQueryWrapper<ApproveProcess>()
+        // 鏃у鎵硅〃寰呭姙
+        Long oldCount = approveProcessMapper.selectCount(new LambdaQueryWrapper<ApproveProcess>()
                 .eq(ApproveProcess::getApproveUserCurrentId, SecurityUtils.getUserId())
                 .eq(ApproveProcess::getApproveDelete, 0)
                 .in(ApproveProcess::getApproveStatus, 0, 1, 3));
+        // 鏂板鎵硅〃寰呭姙
+        Long newCount = approvalTaskMapper.selectCount(new LambdaQueryWrapper<ApprovalTask>()
+                .eq(ApprovalTask::getApproverId, SecurityUtils.getUserId())
+                .eq(ApprovalTask::getTaskStatus, "PENDING")
+                .eq(ApprovalTask::getDeleted, 0));
         // 璁惧鎶ヤ慨寰呭姙
         Long aLong1 = deviceRepairMapper.selectCount(new LambdaQueryWrapper<DeviceRepair>()
                 .eq(DeviceRepair::getStatus, 0)
                 .eq(DeviceRepair::getRepairName, SecurityUtils.getLoginUser().getNickName()));
         return new HashMap<String, Object>() {
             {
-                put("approveTodo", aLong);
+                put("approveTodo", oldCount + newCount);
                 put("deviceRepairTodo", aLong1);
             }
         };
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..2743445
--- /dev/null
+++ b/src/main/java/com/ruoyi/mock/prompt/MockDataPrompt.java
@@ -0,0 +1,242 @@
+package com.ruoyi.mock.prompt;
+
+import com.ruoyi.project.system.domain.SysUser;
+
+import java.util.List;
+import java.util.Map;
+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. 涓嶈浣跨敤emoji鎴栫壒娈妘nicode瀛楃
+            7. 鏈�閲嶈锛氭棩鏈熷彧浠�"鎸囧畾鏃堕棿鑼冨洿"涓彇锛岀粷瀵逛笉瑕佺敤鍏朵粬骞翠唤锛�
+            8. 浜哄憳瀛楁锛堝entryPerson銆乻alesman绛夛級蹇呴』浠�"绯荤粺鐢ㄦ埛鍒楄〃"涓�夊彇锛屾牴鎹鑹插拰閮ㄩ棬鍖归厤瀵瑰簲妯″潡锛屼笉瑕佺紪閫犱汉鍚嶏紒
+            """;
+    }
+
+    public static String buildUserMessage(List<String> modules, List<String> industries,
+                                           int countMin, int countMax,
+                                           String dateStart, String dateEnd,
+                                           String additionalInfo,
+                                           Map<Long, String> productModelIdToCategory,
+                                           List<SysUser> systemUsers,
+                                           List<String> existingCustomerNames,
+                                           List<String> existingSupplierNames) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("鎸囧畾琛屼笟: ").append(String.join("銆�", industries)).append("\n");
+        sb.append("姣忕瀹炰綋鐢熸垚: ").append(countMin).append("-").append(countMax).append(" 鏉n");
+        sb.append("鎸囧畾鏃堕棿鑼冨洿: ").append(dateStart).append(" 鍒� ").append(dateEnd);
+        sb.append("锛堟墍鏈夋棩鏈熷瓧娈靛繀椤诲湪杩欎釜鑼冨洿鍐咃紒绂佹浣跨敤2023銆�2024銆�2025绛変换浣曡秴鍑鸿寖鍥寸殑骞翠唤锛侊級\n");
+        if (additionalInfo != null && !additionalInfo.isBlank()) {
+            sb.append("琛ュ厖淇℃伅: ").append(additionalInfo).append("\n");
+        }
+        sb.append("\n");
+
+        // 鎸夐《绾т骇鍝佸垎绫伙紙鎴愬搧/鍘熸潗鏂�/鍗婃垚鍝侊級鍒嗙粍鍒楀嚭浜у搧瑙勬牸
+        Map<String, List<Map.Entry<Long, String>>> grouped = productModelIdToCategory.entrySet().stream()
+                .collect(Collectors.groupingBy(
+                        e -> categorize(e.getValue()),
+                        java.util.LinkedHashMap::new,
+                        Collectors.toList()));
+
+        sb.append("=== 浜у搧瑙勬牸鍒楄〃 ===\n");
+        for (Map.Entry<String, List<Map.Entry<Long, String>>> entry : grouped.entrySet()) {
+            String label = entry.getKey();
+            List<Map.Entry<Long, String>> items = entry.getValue();
+            sb.append("銆�").append(label).append("銆�: ");
+            sb.append(items.stream()
+                    .map(e -> e.getKey() + "(" + e.getValue() + ")")
+                    .collect(Collectors.joining(", "))).append("\n");
+        }
+        sb.append("閿�鍞彴璐︾殑productData鍙兘閫夈�愭垚鍝佺被銆戣鏍硷紝閲囪喘鍙拌处鍙兘閫夈�愬師鏉愭枡绫汇�戣鏍笺�俓n\n");
+
+        // 绯荤粺鐢ㄦ埛鍒楄〃锛堝惈瑙掕壊鍜岄儴闂級
+        sb.append("=== 绯荤粺鐢ㄦ埛鍒楄〃锛堜汉鍛樺瓧娈靛繀椤讳粠涓�夊彇锛屼笉瑕佺紪閫犱汉鍚嶏級===\n");
+        for (SysUser u : systemUsers) {
+            String roleNames = u.getRoleNames() != null && !u.getRoleNames().isBlank() ? u.getRoleNames() : "鏃犺鑹�";
+            String deptNames = u.getDeptNames() != null && !u.getDeptNames().isBlank() ? u.getDeptNames() : "鏃犻儴闂�";
+            sb.append(u.getNickName()).append("锛堣鑹�: ").append(roleNames).append(", 閮ㄩ棬: ").append(deptNames).append("锛塡n");
+        }
+        sb.append("閫夋嫨瑙勫垯锛歕n");
+        sb.append("- 閿�鍞ā鍧楃殑浜哄憳(entryPerson銆乻alesman)閫夎鑹叉垨閮ㄩ棬鍚玕"閿�鍞甛"鐨勭敤鎴穃n");
+        sb.append("- 閲囪喘妯″潡鐨勪汉鍛橀�夎鑹叉垨閮ㄩ棬鍚玕"閲囪喘\"鐨勭敤鎴穃n");
+        sb.append("- 鐢熶骇妯″潡鐨勪汉鍛橀�夎鑹叉垨閮ㄩ棬鍚玕"鐢熶骇\"鐨勭敤鎴穃n");
+        sb.append("- 璐ㄩ噺妯″潡鐨勪汉鍛橀�夎鑹叉垨閮ㄩ棬鍚玕"璐ㄩ噺\"鎴朶"璐ㄦ\"鐨勭敤鎴穃n");
+        sb.append("- 浠撳簱妯″潡鐨勪汉鍛橀�夎鑹叉垨閮ㄩ棬鍚玕"浠撳簱\"鎴朶"搴撳瓨\"鐨勭敤鎴穃n\n");
+
+        if (!existingCustomerNames.isEmpty()) {
+            sb.append("=== 宸叉湁瀹㈡埛锛堝彧鑳藉紩鐢紝涓嶈鐢熸垚鏂癱ustomer瀹炰綋锛�===\n");
+            sb.append(String.join("銆�", existingCustomerNames)).append("\n\n");
+        }
+        if (!existingSupplierNames.isEmpty()) {
+            sb.append("=== 宸叉湁渚涘簲鍟嗭紙鍙兘寮曠敤锛屼笉瑕佺敓鎴愭柊supplier瀹炰綋锛�===\n");
+            sb.append(String.join("銆�", existingSupplierNames)).append("\n\n");
+        }
+
+        sb.append("鏁版嵁妯″潡: ").append(String.join("銆�", modules)).append("\n\n");
+
+        if (modules.contains("sales")) {
+            sb.append(buildSalesPrompt(countMin, countMax, dateStart, dateEnd, existingCustomerNames));
+        }
+        if (modules.contains("purchase")) {
+            sb.append(buildPurchasePrompt(countMin, countMax, dateStart, dateEnd, existingSupplierNames));
+        }
+        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璇风洿鎺ヨ緭鍑篔SON鏁扮粍:");
+        return sb.toString();
+    }
+
+    /**
+     * 灏嗛《绾т骇鍝佸悕绉版槧灏勪负鍒嗙被鏍囩
+     */
+    private static String categorize(String rootProductName) {
+        if (rootProductName == null) return "鍏朵粬绫�";
+        if (rootProductName.contains("鎴愬搧") || rootProductName.contains("浜ф垚鍝�")) return "鎴愬搧绫�-閿�鍞紭鍏堥�夎繖浜�";
+        if (rootProductName.contains("鍘熸枡") || rootProductName.contains("鍘熸潗鏂�") || rootProductName.contains("鏉愭枡")) return "鍘熸潗鏂欑被-閲囪喘浼樺厛閫夎繖浜�";
+        if (rootProductName.contains("鍗婃垚鍝�")) return "鍗婃垚鍝佺被";
+        return "鍏朵粬绫�";
+    }
+
+    private static String buildSalesPrompt(int min, int max, String dateStart, String dateEnd,
+                                            List<String> existingCustomerNames) {
+        String namesHint = existingCustomerNames.isEmpty() ? ""
+                : "customerName蹇呴』浠庝互涓嬪凡鏈夊鎴蜂腑閫夋嫨: " + String.join("銆�", existingCustomerNames) + "\n";
+        return """
+            閿�鍞ā鍧楁牸寮忥紙鎵�鏈夋棩鏈熷繀椤诲湪 %s ~ %s 鑼冨洿鍐咃級:
+            %s娉ㄦ剰锛氫笉瑕佺敓鎴恈ustomer瀹炰綋锛屽彧鐢熸垚salesLedger锛�
+            productData涓殑productModelId蹇呴』閫夈�愭垚鍝佺被銆戣鏍糏D锛�
+            entryPerson鍜宻alesman蹇呴』浠庣郴缁熺敤鎴峰垪琛ㄤ腑瑙掕壊鎴栭儴闂ㄥ惈"閿�鍞�"鐨勭敤鎴蜂腑閫夊彇锛�
+            {
+              "entity": "salesLedger",
+              "customerName": "寮曠敤涓婇潰鐢熸垚鐨勫鎴峰悕绉�",
+              "salesContractNo": "XS-YYYYMMDD-001",
+              "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
+              }]
+            }
+            salesContractNo涓璝YYYMMDD鏇挎崲涓篹ntryDate鐨勬棩鏈熴��%d-%d鏉°��
+            """.formatted(dateStart, dateEnd, namesHint, dateStart, dateStart, dateEnd, min, max);
+    }
+
+    private static String buildPurchasePrompt(int min, int max, String dateStart, String dateEnd,
+                                              List<String> existingSupplierNames) {
+        String namesHint = existingSupplierNames.isEmpty() ? ""
+                : "supplierName蹇呴』浠庝互涓嬪凡鏈変緵搴斿晢涓�夋嫨: " + String.join("銆�", existingSupplierNames) + "\n";
+        return """
+            閲囪喘妯″潡鏍煎紡锛堟墍鏈夋棩鏈熷繀椤诲湪 %s ~ %s 鑼冨洿鍐咃級:
+            %s娉ㄦ剰锛氫笉瑕佺敓鎴恠upplier瀹炰綋锛屽彧鐢熸垚purchaseLedger锛�
+            productData涓殑productModelId蹇呴』閫夈�愬師鏉愭枡绫汇�戣鏍糏D锛�
+            浜哄憳瀛楁蹇呴』浠庣郴缁熺敤鎴峰垪琛ㄤ腑瑙掕壊鎴栭儴闂ㄥ惈"閲囪喘"鐨勭敤鎴蜂腑閫夊彇锛�
+            {
+              "entity": "purchaseLedger",
+              "supplierName": "浠庡凡鏈変緵搴斿晢涓�夋嫨",
+              "purchaseContractNumber": "CG-YYYYMMDD-001",
+              "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
+              }]
+            }
+            purchaseContractNumber涓璝YYYMMDD鏇挎崲涓篹ntryDate鐨勬棩鏈熴��%d-%d鏉°��
+            """.formatted(dateStart, dateEnd, namesHint, dateStart, dateStart, min, max);
+    }
+
+    private static String buildQualityPrompt(int min, int max, String dateStart) {
+        return """
+            璐ㄩ噺妯″潡鏍煎紡:
+            {
+              "entity": "qualityTestStandard",
+              "standardNo": "QTS-YYYYMMDD-001",
+              "standardName": "XX浜у搧妫�楠屾爣鍑�",
+              "inspectType": 0,
+              "remark": "閫傜敤浜嶺X琛屼笟鐨勮川閲忔楠屾爣鍑�"
+            }
+            inspectType: 0=鍘熸潗鏂欐楠�, 1=杩囩▼妫�楠�, 2=鍑哄巶妫�楠屻�備笁绉嶇被鍨嬮兘瑕佽鐩栥��
+            standardNo涓璝YYYMMDD鏇挎崲涓� %s銆�%d-%d鏉°��
+            {
+              "entity": "qualityTestStandardBinding",
+              "productId": 1,
+              "testStandardId": 1
+            }
+            %d-%d鏉°��
+            """.formatted(dateStart.replace("-", ""), min, max, 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鐢熸垚"
+            }
+            source鍙��"閿�鍞�"鎴�"鍐呴儴"銆�%d-%d鏉°��
+            """.formatted(dateStart, dateEnd, dateStart, dateEnd, dateEnd, min, max);
+    }
+
+    private static String buildStockPrompt(int min, int max, String dateStart) {
+        return """
+            搴撳瓨妯″潡鏍煎紡:
+            {
+              "entity": "stockInventory",
+              "productModelId": 1,
+              "qualitity": 500,
+              "batchNo": "BATCH-YYYYMMDD-001",
+              "warnNum": 50,
+              "remark": "瀹夊叏搴撳瓨"
+            }
+            batchNo涓璝YYYMMDD鏇挎崲涓� %s銆�%d-%d鏉°��
+            """.formatted(dateStart.replace("-", ""), 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..0fc4718
--- /dev/null
+++ b/src/main/java/com/ruoyi/mock/service/impl/DataCheckServiceImpl.java
@@ -0,0 +1,282 @@
+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.ProductModelMapper;
+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.project.system.domain.SysUser;
+import com.ruoyi.project.system.mapper.SysUserMapper;
+import com.ruoyi.quality.mapper.QualityTestStandardBindingMapper;
+import com.ruoyi.quality.mapper.QualityTestStandardMapper;
+import com.ruoyi.technology.mapper.TechnologyBomMapper;
+import com.ruoyi.technology.mapper.TechnologyBomStructureMapper;
+import com.ruoyi.technology.mapper.TechnologyOperationMapper;
+import com.ruoyi.technology.mapper.TechnologyRoutingMapper;
+import com.ruoyi.technology.mapper.TechnologyRoutingOperationMapper;
+import com.ruoyi.technology.pojo.TechnologyBom;
+import com.ruoyi.technology.pojo.TechnologyBomStructure;
+import com.ruoyi.technology.pojo.TechnologyRouting;
+import com.ruoyi.technology.pojo.TechnologyRoutingOperation;
+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 ProductModelMapper productModelMapper;
+    private final CustomerMapper customerMapper;
+    private final SupplierManageMapper supplierManageMapper;
+    private final ApprovalTemplateMapper approvalTemplateMapper;
+    private final QualityTestStandardMapper qualityTestStandardMapper;
+    private final QualityTestStandardBindingMapper qualityTestStandardBindingMapper;
+    private final TechnologyRoutingMapper technologyRoutingMapper;
+    private final TechnologyRoutingOperationMapper technologyRoutingOperationMapper;
+    private final TechnologyOperationMapper technologyOperationMapper;
+    private final TechnologyBomMapper technologyBomMapper;
+    private final TechnologyBomStructureMapper technologyBomStructureMapper;
+    private final SysUserMapper sysUserMapper;
+
+    @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);
+            addUserChecks(itemMap);
+        }
+
+        for (String module : modules) {
+            switch (module) {
+                case "sales" -> addSalesChecks(itemMap);
+                case "purchase" -> addPurchaseChecks(itemMap);
+                case "quality" -> addQualityChecks(itemMap);
+                case "production" -> addProductionChecks(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 addUserChecks(Map<String, CheckItem> itemMap) {
+        // 1. 绯荤粺鐢ㄦ埛
+        String userKey = "common:绯荤粺鐢ㄦ埛";
+        if (!itemMap.containsKey(userKey)) {
+            List<SysUser> users = sysUserMapper.selectUserListWithDetail();
+            itemMap.put(userKey, buildItem("common", "绯荤粺鐢ㄦ埛", 1, (int) users.size(),
+                    "缂哄皯绯荤粺鐢ㄦ埛锛岃鍏堝湪銆愮郴缁熺鐞�-鐢ㄦ埛绠$悊銆戜腑娣诲姞鐢ㄦ埛"));
+        }
+
+        // 2. 鏈夎鑹茬殑鐢ㄦ埛
+        String userWithRoleKey = "common:鐢ㄦ埛瑙掕壊閰嶇疆";
+        if (!itemMap.containsKey(userWithRoleKey)) {
+            List<SysUser> users = sysUserMapper.selectUserListWithDetail();
+            long withRole = users.stream().filter(u -> u.getRoleNames() != null && !u.getRoleNames().isBlank()).count();
+            itemMap.put(userWithRoleKey, buildItem("common", "鐢ㄦ埛瑙掕壊閰嶇疆", 1, (int) withRole,
+                    "娌℃湁鐢ㄦ埛鍒嗛厤瑙掕壊锛岃鍏堝湪銆愮郴缁熺鐞�-鐢ㄦ埛绠$悊銆戜腑涓虹敤鎴峰垎閰嶈鑹�"));
+        }
+
+        // 3. 鏈夐儴闂ㄧ殑鐢ㄦ埛
+        String userWithDeptKey = "common:鐢ㄦ埛閮ㄩ棬閰嶇疆";
+        if (!itemMap.containsKey(userWithDeptKey)) {
+            List<SysUser> users = sysUserMapper.selectUserListWithDetail();
+            long withDept = users.stream().filter(u -> u.getDeptNames() != null && !u.getDeptNames().isBlank()).count();
+            itemMap.put(userWithDeptKey, buildItem("common", "鐢ㄦ埛閮ㄩ棬閰嶇疆", 1, (int) withDept,
+                    "娌℃湁鐢ㄦ埛鍒嗛厤閮ㄩ棬锛岃鍏堝湪銆愮郴缁熺鐞�-鐢ㄦ埛绠$悊銆戜腑涓虹敤鎴峰垎閰嶉儴闂�"));
+        }
+    }
+
+    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 void addProductionChecks(Map<String, CheckItem> itemMap) {
+        // 1. 浜у搧瑙勬牸
+        String modelKey = "production:浜у搧瑙勬牸";
+        if (!itemMap.containsKey(modelKey)) {
+            long count = productModelMapper.selectCount(null);
+            itemMap.put(modelKey, buildItem("production", "浜у搧瑙勬牸", 1, (int) count,
+                    "缂哄皯浜у搧瑙勬牸锛岃鍏堝湪銆愬熀纭�鏁版嵁-浜у搧绠$悊銆戜腑涓轰骇鍝佹坊鍔犺鏍煎瀷鍙�"));
+        }
+
+        // 2. 宸ュ簭
+        String operationKey = "production:宸ュ簭";
+        if (!itemMap.containsKey(operationKey)) {
+            long count = technologyOperationMapper.selectCount(null);
+            itemMap.put(operationKey, buildItem("production", "宸ュ簭", 1, (int) count,
+                    "缂哄皯宸ュ簭锛岃鍏堝湪銆愬伐鑹鸿璁�-宸ュ簭绠$悊銆戜腑鍒涘缓宸ュ簭"));
+        }
+
+        // 3. BOM
+        String bomKey = "production:BOM";
+        if (!itemMap.containsKey(bomKey)) {
+            long count = technologyBomMapper.selectCount(null);
+            itemMap.put(bomKey, buildItem("production", "BOM", 1, (int) count,
+                    "缂哄皯BOM锛岃鍏堝湪銆愬伐鑹鸿璁�-BOM绠$悊銆戜腑鍒涘缓BOM"));
+        }
+
+        // 4. BOM浜у搧缁撴瀯
+        String bomStructureKey = "production:BOM浜у搧缁撴瀯";
+        if (!itemMap.containsKey(bomStructureKey)) {
+            long count = technologyBomStructureMapper.selectCount(null);
+            itemMap.put(bomStructureKey, buildItem("production", "BOM浜у搧缁撴瀯", 1, (int) count,
+                    "缂哄皯BOM浜у搧缁撴瀯锛岃鍏堝湪銆愬伐鑹鸿璁�-BOM绠$悊銆戜腑涓築OM娣诲姞浜у搧缁撴瀯鑺傜偣"));
+        }
+
+        // 5. 宸ヨ壓璺嚎
+        String routingKey = "production:宸ヨ壓璺嚎";
+        if (!itemMap.containsKey(routingKey)) {
+            long count = technologyRoutingMapper.selectCount(null);
+            itemMap.put(routingKey, buildItem("production", "宸ヨ壓璺嚎", 1, (int) count,
+                    "缂哄皯宸ヨ壓璺嚎锛岃鍏堝湪銆愬伐鑹鸿璁�-宸ヨ壓璺嚎銆戜腑鍒涘缓宸ヨ壓璺嚎"));
+        }
+
+        // 6. 宸ヨ壓璺嚎宸ュ簭
+        String routingOpKey = "production:宸ヨ壓璺嚎宸ュ簭";
+        if (!itemMap.containsKey(routingOpKey)) {
+            long count = technologyRoutingOperationMapper.selectCount(null);
+            itemMap.put(routingOpKey, buildItem("production", "宸ヨ壓璺嚎宸ュ簭", 1, (int) count,
+                    "缂哄皯宸ヨ壓璺嚎宸ュ簭锛岃鍏堝湪銆愬伐鑹鸿璁�-宸ヨ壓璺嚎銆戜腑涓哄伐鑹鸿矾绾挎坊鍔犲伐搴�"));
+        }
+
+        // 7. 鍏宠仈鎬ф娴嬶細鏈変骇鍝佽鏍间絾鏃犲伐鑹鸿矾绾跨殑
+        String linkageKey = "production:浜у搧-宸ヨ壓璺嚎鍏宠仈";
+        if (!itemMap.containsKey(linkageKey)) {
+            long modelCount = productModelMapper.selectCount(null);
+            long routedCount = technologyRoutingMapper.selectCount(
+                    new LambdaQueryWrapper<TechnologyRouting>()
+                            .isNotNull(TechnologyRouting::getProductModelId)
+                            .gt(TechnologyRouting::getProductModelId, 0));
+            itemMap.put(linkageKey, buildItem("production", "浜у搧-宸ヨ壓璺嚎鍏宠仈",
+                    (int) Math.min(modelCount, 1), (int) routedCount,
+                    "閮ㄥ垎浜у搧瑙勬牸鏈叧鑱斿伐鑹鸿矾绾匡紝璇峰厛鍦ㄣ�愬伐鑹鸿璁�-宸ヨ壓璺嚎銆戜腑涓轰骇鍝佽鏍煎垱寤哄伐鑹鸿矾绾�"));
+        }
+
+        // 8. 鍏宠仈鎬ф娴嬶細鏈夊伐鑹鸿矾绾夸絾鏃犲伐搴忕殑
+        String routingOpLinkKey = "production:宸ヨ壓璺嚎-宸ュ簭鍏宠仈";
+        if (!itemMap.containsKey(routingOpLinkKey)) {
+            long routingCount = technologyRoutingMapper.selectCount(null);
+            long routedOpCount = technologyRoutingOperationMapper.selectCount(
+                    new LambdaQueryWrapper<TechnologyRoutingOperation>()
+                            .gt(TechnologyRoutingOperation::getTechnologyRoutingId, 0));
+            itemMap.put(routingOpLinkKey, buildItem("production", "宸ヨ壓璺嚎-宸ュ簭鍏宠仈",
+                    (int) Math.min(routingCount, 1), (int) routedOpCount,
+                    "閮ㄥ垎宸ヨ壓璺嚎鏈坊鍔犲伐搴忥紝璇峰厛鍦ㄣ�愬伐鑹鸿璁�-宸ヨ壓璺嚎銆戜腑涓哄伐鑹鸿矾绾挎坊鍔犲伐搴�"));
+        }
+
+        // 9. 鍏宠仈鎬ф娴嬶細鏈塀OM浣嗘棤浜у搧缁撴瀯鐨�
+        String bomStructureLinkKey = "production:BOM-浜у搧缁撴瀯鍏宠仈";
+        if (!itemMap.containsKey(bomStructureLinkKey)) {
+            long bomCount = technologyBomMapper.selectCount(null);
+            long structureCount = technologyBomStructureMapper.selectCount(
+                    new LambdaQueryWrapper<TechnologyBomStructure>()
+                            .gt(TechnologyBomStructure::getBomId, 0));
+            itemMap.put(bomStructureLinkKey, buildItem("production", "BOM-浜у搧缁撴瀯鍏宠仈",
+                    (int) Math.min(bomCount, 1), (int) structureCount,
+                    "閮ㄥ垎BOM鏈坊鍔犱骇鍝佺粨鏋勶紝璇峰厛鍦ㄣ�愬伐鑹鸿璁�-BOM绠$悊銆戜腑涓築OM娣诲姞浜у搧缁撴瀯鑺傜偣"));
+        }
+    }
+
+    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..92b7cb8
--- /dev/null
+++ b/src/main/java/com/ruoyi/mock/service/impl/DataGenerateServiceImpl.java
@@ -0,0 +1,1745 @@
+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.approve.mapper.ApprovalInstanceMapper;
+import com.ruoyi.approve.mapper.ApprovalInstanceNodeMapper;
+import com.ruoyi.approve.mapper.ApprovalRecordMapper;
+import com.ruoyi.approve.mapper.ApprovalTaskMapper;
+import com.ruoyi.approve.pojo.ApprovalInstance;
+import com.ruoyi.approve.pojo.ApprovalInstanceNode;
+import com.ruoyi.approve.pojo.ApprovalRecord;
+import com.ruoyi.approve.pojo.ApprovalTask;
+import com.ruoyi.approve.service.ApprovalInstanceService;
+import com.ruoyi.basic.mapper.ProductMapper;
+import com.ruoyi.basic.mapper.ProductModelMapper;
+import com.ruoyi.basic.pojo.Customer;
+import com.ruoyi.basic.pojo.Product;
+import com.ruoyi.basic.pojo.ProductModel;
+import com.ruoyi.basic.pojo.SupplierManage;
+import com.ruoyi.basic.service.ICustomerService;
+import com.ruoyi.basic.service.ISupplierService;
+import com.ruoyi.common.enums.ReviewStatusEnum;
+import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
+import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
+import com.ruoyi.common.utils.OrderUtils;
+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.procurementrecord.utils.StockUtils;
+import com.ruoyi.production.bean.dto.ProductionOrderPickDto;
+import com.ruoyi.production.bean.dto.ProductionPlanDto;
+import com.ruoyi.production.bean.dto.ProductionProductMainDto;
+import com.ruoyi.production.bean.vo.ProductionBomStructureVo;
+import com.ruoyi.production.mapper.*;
+import com.ruoyi.production.pojo.*;
+import com.ruoyi.production.service.ProductionOrderPickService;
+import com.ruoyi.production.service.ProductionOrderService;
+import com.ruoyi.production.service.ProductionPlanService;
+import com.ruoyi.production.service.ProductionProductMainService;
+import com.ruoyi.purchase.dto.PurchaseLedgerDto;
+import com.ruoyi.purchase.pojo.PurchaseLedger;
+import com.ruoyi.purchase.service.IPurchaseLedgerService;
+import com.ruoyi.project.system.domain.SysDept;
+import com.ruoyi.project.system.domain.SysUser;
+import com.ruoyi.project.system.mapper.SysDeptMapper;
+import com.ruoyi.project.system.mapper.SysUserDeptMapper;
+import com.ruoyi.project.system.mapper.SysUserMapper;
+import com.ruoyi.quality.mapper.QualityInspectMapper;
+import com.ruoyi.quality.pojo.QualityInspect;
+import com.ruoyi.quality.pojo.QualityTestStandard;
+import com.ruoyi.quality.pojo.QualityTestStandardBinding;
+import com.ruoyi.quality.service.IQualityInspectService;
+import com.ruoyi.quality.service.IQualityTestStandardService;
+import com.ruoyi.quality.service.QualityTestStandardBindingService;
+import com.ruoyi.sales.dto.SalesLedgerDto;
+import com.ruoyi.sales.dto.ShippingInfoDto;
+import com.ruoyi.sales.mapper.SalesLedgerMapper;
+import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
+import com.ruoyi.sales.mapper.ShippingInfoMapper;
+import com.ruoyi.sales.mapper.ShippingProductDetailMapper;
+import com.ruoyi.sales.pojo.SalesLedger;
+import com.ruoyi.sales.pojo.SalesLedgerProduct;
+import com.ruoyi.sales.pojo.ShippingInfo;
+import com.ruoyi.sales.pojo.ShippingProductDetail;
+import com.ruoyi.sales.service.ISalesLedgerService;
+import com.ruoyi.sales.service.ShippingInfoService;
+import com.ruoyi.stock.mapper.StockInRecordMapper;
+import com.ruoyi.stock.mapper.StockInventoryMapper;
+import com.ruoyi.stock.mapper.StockOutRecordMapper;
+import com.ruoyi.stock.pojo.StockInventory;
+import com.ruoyi.stock.pojo.StockOutRecord;
+import com.ruoyi.stock.dto.StockInventoryDto;
+import com.ruoyi.stock.service.StockInRecordService;
+import com.ruoyi.stock.service.StockOutRecordService;
+import com.ruoyi.stock.service.StockInventoryService;
+import com.ruoyi.technology.mapper.TechnologyBomStructureMapper;
+import com.ruoyi.technology.mapper.TechnologyRoutingMapper;
+import com.ruoyi.technology.mapper.TechnologyRoutingOperationMapper;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ThreadLocalRandom;
+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;
+
+    // 閲囪喘瀹屾暣娴佺▼闇�瑕佺殑service
+    private final ApprovalInstanceService approvalInstanceService;
+    private final ApprovalInstanceMapper approvalInstanceMapper;
+    private final ApprovalInstanceNodeMapper approvalInstanceNodeMapper;
+    private final ApprovalTaskMapper approvalTaskMapper;
+    private final ApprovalRecordMapper approvalRecordMapper;
+    private final IQualityInspectService qualityInspectService;
+    private final QualityInspectMapper qualityInspectMapper;
+    private final StockInRecordService stockInRecordService;
+    private final StockInRecordMapper stockInRecordMapper;
+
+    // 閿�鍞畬鏁存祦绋嬮渶瑕佺殑service/mapper
+    private final SalesLedgerMapper salesLedgerMapper;
+    private final SalesLedgerProductMapper salesLedgerProductMapper;
+    private final ProductionPlanMapper productionPlanMapper;
+    private final ProductionOrderMapper productionOrderMapper;
+    private final ProductionOperationTaskMapper productionOperationTaskMapper;
+    private final ProductionProductMainService productionProductMainService;
+    private final ShippingInfoService shippingInfoService;
+    private final ShippingInfoMapper shippingInfoMapper;
+    private final ShippingProductDetailMapper shippingProductDetailMapper;
+    private final StockUtils stockUtils;
+    private final StockOutRecordMapper stockOutRecordMapper;
+    private final StockOutRecordService stockOutRecordService;
+    private final StockInventoryMapper stockInventoryMapper;
+
+    // 宸ヨ壓鏁版嵁妫�娴�
+    private final TechnologyRoutingMapper technologyRoutingMapper;
+    private final TechnologyRoutingOperationMapper technologyRoutingOperationMapper;
+    private final TechnologyBomStructureMapper technologyBomStructureMapper;
+
+    // 棰嗘枡
+    private final ProductionOrderPickService productionOrderPickService;
+    private final ProductionOrderBomMapper productionOrderBomMapper;
+    private final ProductionBomStructureMapper productionBomStructureMapper;
+
+    // 鐢ㄦ埛/瑙掕壊鏌ヨ
+    private final SysUserMapper sysUserMapper;
+    private final SysDeptMapper sysDeptMapper;
+    private final SysUserDeptMapper sysUserDeptMapper;
+
+    @Override
+    public DataGenerateResult generate(DataGenerateRequest request) {
+        DataGenerateResult result = new DataGenerateResult();
+        List<ModuleSummary> summaries = new ArrayList<>();
+        List<String> errors = new ArrayList<>();
+        int totalGenerated = 0;
+
+        try {
+            // 鏋勫缓浜у搧瑙勬牸鍒嗙被锛氶�氳繃Product鏍戞牴鑺傜偣鍒ゆ柇鎴愬搧/鍘熸潗鏂�
+            Map<Long, String> productModelIdToCategory = buildProductModelCategoryMap();
+            List<Long> productModelIds = new ArrayList<>(productModelIdToCategory.keySet());
+
+            // 鍔犺浇宸叉湁瀹㈡埛/渚涘簲鍟嗭紙涓嶆柊澧烇紝浣跨敤宸叉湁鏁版嵁锛�
+            Map<String, Long> customerNameToId = loadExistingCustomers();
+            Map<String, Long> supplierNameToId = loadExistingSuppliers();
+            List<String> existingCustomerNames = new ArrayList<>(customerNameToId.keySet());
+            List<String> existingSupplierNames = new ArrayList<>(supplierNameToId.keySet());
+
+            // 鍔犺浇绯荤粺鐢ㄦ埛淇℃伅锛堟樀绉般�佽鑹层�侀儴闂級
+            List<SysUser> systemUsers = loadSystemUsersWithDetail();
+
+            String systemPrompt = MockDataPrompt.buildSystemPrompt();
+            String userMessage = MockDataPrompt.buildUserMessage(
+                    request.getModules(), request.getIndustries(),
+                    request.getCountMin(), request.getCountMax(),
+                    request.getDateStart(), request.getDateEnd(),
+                    request.getAdditionalInfo(),
+                    productModelIdToCategory,
+                    systemUsers,
+                    existingCustomerNames, existingSupplierNames);
+
+            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;
+            }
+
+            // 淇AI鐢熸垚鐨勬棩鏈熷埌鎸囧畾鏃堕棿鑼冨洿鍐�
+            String dateStart = request.getDateStart();
+            String dateEnd = request.getDateEnd();
+            if (dateStart != null && dateEnd != null) {
+                fixDatesInRange(entities, dateStart, dateEnd);
+            }
+
+            Map<String, List<JSONObject>> grouped = entities.stream()
+                    .collect(Collectors.groupingBy(e -> e.getString("entity")));
+
+            // Tier 0: 鍩虹鏁版嵁锛堝鎴峰拰渚涘簲鍟嗕笉鑷姩鐢熸垚锛屼娇鐢ㄥ凡鏈夋暟鎹級
+            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, request.getDateStart());
+                summaries.add(s);
+                totalGenerated += s.getSuccessCount();
+            }
+            if (grouped.containsKey("purchaseLedger")) {
+                ModuleSummary s = createPurchaseLedgers(grouped.get("purchaseLedger"), supplierNameToId,
+                        request.getAdditionalInfo(), request.getDateStart(), request.getDateEnd());
+                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();
+        }
+    }
+
+    /**
+     * 淇AI鐢熸垚鐨勬棩鏈熷埌鎸囧畾鏃堕棿鑼冨洿鍐呫��
+     * 閬嶅巻鎵�鏈夊疄浣撶殑鎵�鏈夊瓧娈碉紝濡傛灉鍙戠幇鏃ユ湡瀛楃涓诧紙yyyy-MM-dd鏍煎紡锛夎秴鍑鸿寖鍥达紝鏇挎崲涓鸿寖鍥村唴鐨勯殢鏈烘棩鏈熴��
+     */
+    private void fixDatesInRange(List<JSONObject> entities, String dateStart, String dateEnd) {
+        LocalDate start;
+        LocalDate end;
+        try {
+            start = LocalDate.parse(dateStart);
+            end = LocalDate.parse(dateEnd);
+        } catch (Exception e) {
+            log.warn("鏃ユ湡鑼冨洿瑙f瀽澶辫触: {} ~ {}", dateStart, dateEnd);
+            return;
+        }
+        long daysBetween = ChronoUnit.DAYS.between(start, end);
+        if (daysBetween <= 0) {
+            daysBetween = 1;
+        }
+
+        // 鎵�鏈夊凡鐭ョ殑鏃ユ湡瀛楁鍚�
+        java.util.Set<String> dateFields = java.util.Set.of(
+                "entryDate", "executionDate", "deliveryDate", "requiredDate",
+                "promisedDeliveryDate", "planCompleteTime", "maintenanceTime",
+                "checkTime", "registerDate"
+        );
+
+        for (JSONObject entity : entities) {
+            for (String key : dateFields) {
+                String val = entity.getString(key);
+                if (val != null && val.matches("\\d{4}-\\d{2}-\\d{2}")) {
+                    try {
+                        LocalDate d = LocalDate.parse(val);
+                        if (d.isBefore(start) || d.isAfter(end)) {
+                            LocalDate fixed = start.plusDays(ThreadLocalRandom.current().nextLong(daysBetween + 1));
+                            entity.put(key, fixed.toString());
+                            log.debug("淇鏃ユ湡 {}: {} -> {}", key, val, fixed);
+                        }
+                    } catch (Exception ignored) {
+                    }
+                } else if (val != null && !val.matches("\\d{4}-\\d{2}-\\d{2}")) {
+                    // AI杩斿洖浜嗘棤鏁堟棩鏈熸牸寮忥紝鐩存帴鏇挎崲涓鸿寖鍥村唴鐨勯殢鏈烘棩鏈�
+                    LocalDate fixed = start.plusDays(ThreadLocalRandom.current().nextLong(daysBetween + 1));
+                    entity.put(key, fixed.toString());
+                    log.debug("淇鏃犳晥鏃ユ湡 {}: {} -> {}", key, val, fixed);
+                }
+            }
+            // 淇鍚堝悓缂栧彿涓殑鏃ユ湡: CG-20230601-001 -> CG-YYYYMMDD-001
+            for (String key : java.util.Set.of("purchaseContractNumber", "salesContractNo", "standardNo", "batchNo")) {
+                String val = entity.getString(key);
+                if (val != null && val.matches(".*\\d{8}.*")) {
+                    String datePart = val.replaceAll(".*?(\\d{8}).*", "$1");
+                    try {
+                        // 楠岃瘉鎻愬彇鍒扮殑鏄湁鏁堟棩鏈�
+                        String dateStr = datePart.substring(0, 4) + "-" + datePart.substring(4, 6) + "-" + datePart.substring(6, 8);
+                        LocalDate d = LocalDate.parse(dateStr);
+                        if (d.isBefore(start) || d.isAfter(end)) {
+                            LocalDate fixed = start.plusDays(ThreadLocalRandom.current().nextLong(daysBetween + 1));
+                            String newDatePart = fixed.format(java.time.format.DateTimeFormatter.BASIC_ISO_DATE);
+                            String newVal = val.replace(datePart, newDatePart);
+                            entity.put(key, newVal);
+                            log.debug("淇缂栧彿 {}: {} -> {}", key, val, newVal);
+                        }
+                    } catch (Exception ignored) {
+                    }
+                }
+            }
+        }
+    }
+
+    // ---- Tier 0: 鍩虹鏁版嵁 ----
+
+    /**
+     * 浠庢暟鎹簱鍔犺浇宸叉湁瀹㈡埛鍚嶇О鈫扞D鏄犲皠
+     */
+    private Map<String, Long> loadExistingCustomers() {
+        Map<String, Long> map = new HashMap<>();
+        List<Customer> customers = customerService.list();
+        for (Customer c : customers) {
+            if (c.getCustomerName() != null) {
+                map.put(c.getCustomerName(), c.getId());
+            }
+        }
+        return map;
+    }
+
+    /**
+     * 浠庢暟鎹簱鍔犺浇宸叉湁渚涘簲鍟嗗悕绉扳啋ID鏄犲皠
+     */
+    private Map<String, Long> loadExistingSuppliers() {
+        Map<String, Long> map = new HashMap<>();
+        List<SupplierManage> suppliers = supplierService.list();
+        for (SupplierManage s : suppliers) {
+            if (s.getSupplierName() != null) {
+                map.put(s.getSupplierName(), s.getId());
+            }
+        }
+        return map;
+    }
+
+    /**
+     * 鍔犺浇绯荤粺鐢ㄦ埛淇℃伅锛堝惈瑙掕壊鍜岄儴闂ㄥ悕绉帮級
+     */
+    private List<SysUser> loadSystemUsersWithDetail() {
+        return sysUserMapper.selectUserListWithDetail();
+    }
+
+    /**
+     * 鏋勫缓浜у搧瑙勬牸ID鈫掗《绾т骇鍝佸垎绫诲悕绉扮殑鏄犲皠
+     * 閫氳繃Product鏍戝悜涓婃壘鍒版牴鑺傜偣锛屽垽鏂�"鎴愬搧"/"鍘熸潗鏂�"/"鍗婃垚鍝�"
+     */
+    private Map<Long, String> buildProductModelCategoryMap() {
+        // 鍔犺浇鎵�鏈塒roduct鑺傜偣
+        List<Product> allProducts = productMapper.selectList(null);
+        Map<Long, Product> productMap = allProducts.stream()
+                .collect(Collectors.toMap(Product::getId, p -> p, (a, b) -> a));
+
+        // 瀵规瘡涓狿roduct锛屾部parentId鍚戜笂鎵惧埌鏍硅妭鐐瑰悕绉�
+        Map<Long, String> productIdToRootName = new HashMap<>();
+        for (Product p : allProducts) {
+            if (productIdToRootName.containsKey(p.getId())) continue;
+            // 鍚戜笂閬嶅巻鎵炬牴
+            List<Long> chain = new ArrayList<>();
+            Long currentId = p.getId();
+            while (currentId != null) {
+                chain.add(currentId);
+                Product current = productMap.get(currentId);
+                if (current == null || current.getParentId() == null) break;
+                currentId = current.getParentId();
+            }
+            // 鏍硅妭鐐圭殑productName灏辨槸鍒嗙被鍚�
+            Product root = productMap.get(chain.get(chain.size() - 1));
+            String rootName = root != null ? root.getProductName() : "鍏朵粬";
+            for (Long id : chain) {
+                productIdToRootName.put(id, rootName);
+            }
+        }
+
+        // 瀵规瘡涓狿roductModel锛岄�氳繃productId鎵惧埌鍏舵墍灞炲垎绫�
+        List<ProductModel> allModels = productModelMapper.selectList(null);
+        Map<Long, String> result = new HashMap<>();
+        for (ProductModel m : allModels) {
+            String category = m.getProductId() != null
+                    ? productIdToRootName.getOrDefault(m.getProductId(), "鍏朵粬")
+                    : "鍏朵粬";
+            result.put(m.getId(), category);
+        }
+        return result;
+    }
+
+    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.setCompanyPhone(item.getString("companyPhone"));
+                c.setTaxpayerIdentificationNumber(item.getString("taxpayerIdentificationNumber"));
+                c.setMaintainer(item.getString("maintainer"));
+                if (item.containsKey("maintenanceTime")) {
+                    String mtStr = item.getString("maintenanceTime");
+                    if (mtStr != null && mtStr.matches("\\d{4}-\\d{2}-\\d{2}")) {
+                        c.setMaintenanceTime(java.sql.Date.valueOf(mtStr));
+                    }
+                } else {
+                    c.setMaintenanceTime(new java.sql.Date(System.currentTimeMillis()));
+                }
+                if (item.containsKey("bankAccount")) {
+                    c.setBankAccount(item.getString("bankAccount"));
+                }
+                if (item.containsKey("basicBankAccount")) {
+                    c.setBasicBankAccount(item.getString("basicBankAccount"));
+                }
+                if (item.containsKey("bankCode")) {
+                    c.setBankCode(item.getString("bankCode"));
+                }
+                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.setCompanyPhone(item.getString("companyPhone"));
+                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, String dateStart) {
+        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"));
+
+                // 褰曞叆浜猴細浼樺厛鐢ˋI杩斿洖鐨勶紝鍚﹀垯浠�"閿�鍞�"瑙掕壊/閮ㄩ棬闅忔満閫�
+                String entryPerson = item.getString("entryPerson");
+                if (entryPerson == null || entryPerson.isBlank()) {
+                    SysUser salesUser = randomUserByKeyword("閿�鍞�");
+                    entryPerson = salesUser != null ? salesUser.getNickName() : "绯荤粺";
+                }
+                dto.setEntryPerson(entryPerson);
+
+                // 涓氬姟鍛橈細浼樺厛鐢ˋI杩斿洖鐨勶紝鍚﹀垯浠�"閿�鍞�"瑙掕壊/閮ㄩ棬闅忔満閫�
+                String salesman = dto.getSalesman();
+                if (salesman == null || salesman.isBlank()) {
+                    SysUser salesUser = randomUserByKeyword("閿�鍞�");
+                    salesman = salesUser != null ? salesUser.getNickName() : "绯荤粺";
+                    dto.setSalesman(salesman);
+                }
+                // customerId涓簄ull浼氬鑷�"瀹㈡埛涓嶅瓨鍦�"寮傚父锛岃烦杩�
+                if (customerId == null) {
+                    log.warn("璺宠繃閿�鍞彴璐︼紝瀹㈡埛[{}]涓嶅瓨鍦�", customerName);
+                    fail++;
+                    continue;
+                }
+                LocalDate entryDate = null;
+                if (item.containsKey("entryDate")) {
+                    String entryDateStr = item.getString("entryDate");
+                    if (entryDateStr != null && entryDateStr.matches("\\d{4}-\\d{2}-\\d{2}")) {
+                        entryDate = LocalDate.parse(entryDateStr);
+                        dto.setEntryDate(java.sql.Date.valueOf(entryDateStr));
+                    } else {
+                        dto.setEntryDate(java.sql.Date.valueOf(dateStart));
+                    }
+                }
+                if (item.containsKey("executionDate")) {
+                    String execDateStr = item.getString("executionDate");
+                    if (execDateStr != null && execDateStr.matches("\\d{4}-\\d{2}-\\d{2}")) {
+                        dto.setExecutionDate(LocalDate.parse(execDateStr));
+                    } else {
+                        dto.setExecutionDate(LocalDate.parse(dateStart));
+                    }
+                }
+                if (item.containsKey("deliveryDate")) {
+                    String delDateStr = item.getString("deliveryDate");
+                    if (delDateStr != null && delDateStr.matches("\\d{4}-\\d{2}-\\d{2}")) {
+                        dto.setDeliveryDate(LocalDate.parse(delDateStr));
+                    } else {
+                        dto.setDeliveryDate(LocalDate.parse(dateStart));
+                    }
+                }
+                JSONArray productData = item.getJSONArray("productData");
+                boolean hasProduction = false;
+                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"));
+                        if (pd.containsKey("taxExclusiveTotalPrice")) {
+                            slp.setTaxExclusiveTotalPrice(pd.getBigDecimal("taxExclusiveTotalPrice"));
+                        } else if (pd.getBigDecimal("taxInclusiveTotalPrice") != null && pd.getBigDecimal("taxRate") != null) {
+                            slp.setTaxExclusiveTotalPrice(
+                                pd.getBigDecimal("taxInclusiveTotalPrice").divide(
+                                    BigDecimal.ONE.add(pd.getBigDecimal("taxRate").divide(new BigDecimal("100"), 4, RoundingMode.HALF_UP)),
+                                    2, RoundingMode.HALF_UP));
+                        } else {
+                            slp.setTaxExclusiveTotalPrice(BigDecimal.ZERO);
+                        }
+                        slp.setIsProduction(true);
+                        products.add(slp);
+                        hasProduction = true;
+                    }
+                    dto.setProductData(products);
+                }
+                salesLedgerService.addOrUpdateSalesLedger(dto);
+                // addOrUpdateSalesLedger鍐呴儴浼氳嚜鍔ㄧ敓鎴愬悎鍚屽彿骞秈nsert锛屼絾dto涓婃病鏈夊洖鍐�
+                // 鐩存帴鐢╠to鐨別ntryDate鍜宑ustomerId鏌ユ渶鏂板垱寤虹殑璁板綍
+                SalesLedger savedLedger = salesLedgerMapper.selectOne(
+                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<SalesLedger>()
+                                .eq(SalesLedger::getCustomerId, dto.getCustomerId())
+                                .orderByDesc(SalesLedger::getId)
+                                .last("limit 1"));
+                if (savedLedger != null && hasProduction) {
+                    processSalesFullFlow(savedLedger, entryDate);
+                }
+                success++;
+            } catch (Exception e) {
+                log.warn("鍒涘缓閿�鍞彴璐﹀け璐�: {}", e.getMessage(), e);
+                fail++;
+            }
+        }
+        return summary("sales", "閿�鍞彴璐�", items.size(), success, fail);
+    }
+
+    // ==================== 閿�鍞畬鏁存祦绋� ====================
+
+    /**
+     * 閿�鍞畬鏁存祦绋�: 鐢熶骇璁″垝鍚堝苟涓嬪彂 鈫� 棰嗘枡 鈫� 鎶ュ伐 鈫� 璐ㄦ(鍙��) 鈫� 鍏ュ簱 鈫� 鍙戣揣 鈫� 鍑哄簱
+     * 鏃堕棿浠ラ攢鍞綍鍏ユ棩鏈熶负鍩哄噯锛屽悇鐜妭閫掓帹0-3澶�
+     */
+    private void processSalesFullFlow(SalesLedger salesLedger, LocalDate entryDate) {
+        try {
+            LocalDate baseDate = entryDate != null ? entryDate : LocalDate.now();
+
+            // 1. 鏌ヨ閿�鍞彴璐︿骇鍝侊紙鍚敓浜ц鍒掞級
+            List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(
+                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<SalesLedgerProduct>()
+                            .eq(SalesLedgerProduct::getSalesLedgerId, salesLedger.getId())
+                            .eq(SalesLedgerProduct::getIsProduction, true));
+            if (products.isEmpty()) {
+                log.info("閿�鍞彴璐{}]鏃犻渶鐢熶骇锛岃烦杩囩敓浜ф祦绋�", salesLedger.getSalesContractNo());
+                return;
+            }
+
+            // 妫�鏌ヤ骇鍝佹槸鍚﹀叿澶囧畬鏁寸殑宸ヨ壓鏁版嵁锛堝伐鑹鸿矾绾裤�佸伐搴忋�丅OM锛�
+            List<Long> missingTechProductIds = checkTechnologyDataReadiness(products);
+            if (!missingTechProductIds.isEmpty()) {
+                log.warn("閿�鍞彴璐{}]浠ヤ笅浜у搧缂哄皯宸ヨ壓鏁版嵁锛堝伐鑹鸿矾绾�/宸ュ簭/BOM锛夛紝璺宠繃鐢熶骇娴佺▼: {}",
+                        salesLedger.getSalesContractNo(), missingTechProductIds);
+                return;
+            }
+
+            // 2. 鐢熶骇璁″垝鍚堝苟涓嬪彂 鈫� 鐢熶骇璁㈠崟
+            LocalDate planDate = baseDate.plusDays(ThreadLocalRandom.current().nextInt(0, 4));
+            processProductionCombine(salesLedger, planDate);
+
+            // 3. 棰嗘枡锛堢墿鏂欎笉瓒宠嚜鍔ㄥ叆搴撳悗鍐嶉锛�
+            LocalDate pickDate = planDate.plusDays(ThreadLocalRandom.current().nextInt(0, 3));
+            processMaterialPick(salesLedger, pickDate);
+
+            // 4. 鐢熶骇鎶ュ伐
+            LocalDate reportDate = pickDate.plusDays(ThreadLocalRandom.current().nextInt(1, 4));
+            processProductionReport(salesLedger, reportDate);
+
+            // 5. 璐ㄦ鎻愪氦 + 鍏ュ簱瀹℃壒
+            LocalDate qualityDate = reportDate.plusDays(ThreadLocalRandom.current().nextInt(0, 4));
+            processSalesQualityAndStockIn(salesLedger, qualityDate);
+
+            // 6. 鍙戣揣 + 鍙戣揣瀹℃壒 + 鍑哄簱瀹℃壒
+            LocalDate shipDate = qualityDate.plusDays(ThreadLocalRandom.current().nextInt(0, 4));
+            processSalesShipping(salesLedger, shipDate);
+
+            log.info("閿�鍞彴璐{}]瀹屾暣娴佺▼澶勭悊瀹屾瘯", salesLedger.getSalesContractNo());
+        } catch (Exception e) {
+            log.warn("閿�鍞畬鏁存祦绋嬪鐞嗗け璐{}]: {}", salesLedger.getSalesContractNo(), e.getMessage());
+        }
+    }
+
+    /**
+     * 鏌ヨ瑙掕壊鎴栭儴闂ㄥ惈鎸囧畾鍏抽敭瀛楃殑鐢ㄦ埛锛岄殢鏈鸿繑鍥炰竴涓�
+     */
+    private SysUser randomUserByKeyword(String keyword) {
+        try {
+            List<Long> userIds = new ArrayList<>(sysUserMapper.getUserByRole(keyword));
+
+            List<SysDept> depts = sysDeptMapper.selectList(
+                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<SysDept>()
+                            .like(SysDept::getDeptName, keyword)
+                            .eq(SysDept::getDelFlag, "0")
+                            .eq(SysDept::getStatus, "0"));
+            if (!depts.isEmpty()) {
+                List<Long> deptIds = depts.stream().map(SysDept::getDeptId).collect(Collectors.toList());
+                List<Long> deptUserIds = sysUserDeptMapper.selectDistinctUserIdsByDeptIds(deptIds);
+                userIds.addAll(deptUserIds);
+            }
+
+            if (userIds.isEmpty()) {
+                return null;
+            }
+            List<Long> distinctIds = userIds.stream().distinct().collect(Collectors.toList());
+            Long randomId = distinctIds.get(ThreadLocalRandom.current().nextInt(distinctIds.size()));
+            return sysUserMapper.selectUserById(randomId);
+        } catch (Exception e) {
+            log.warn("鏌ヨ[{}]瑙掕壊/閮ㄩ棬鐢ㄦ埛澶辫触: {}", keyword, e.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * 鏌ヨ瑙掕壊鎴栭儴闂ㄥ惈"鐢熶骇"鐨勭敤鎴凤紝闅忔満杩斿洖涓�涓�
+     */
+    private SysUser randomProductionUser() {
+        return randomUserByKeyword("鐢熶骇");
+    }
+
+    /**
+     * 妫�鏌ヤ骇鍝佹槸鍚﹀叿澶囧畬鏁寸殑宸ヨ壓鏁版嵁锛堝伐鑹鸿矾绾裤�佸伐搴忋�丅OM锛�
+     * @return 缂哄皯宸ヨ壓鏁版嵁鐨勪骇鍝佽鏍糏D鍒楄〃锛堢┖鍒楄〃琛ㄧず鍏ㄩ儴灏辩华锛�
+     */
+    private List<Long> checkTechnologyDataReadiness(List<SalesLedgerProduct> products) {
+        List<Long> missingIds = new ArrayList<>();
+        for (SalesLedgerProduct slp : products) {
+            Long productModelId = slp.getProductModelId();
+            if (productModelId == null) continue;
+
+            // 1. 妫�鏌ュ伐鑹鸿矾绾�
+            List<com.ruoyi.technology.pojo.TechnologyRouting> routings =
+                    technologyRoutingMapper.selectList(
+                            new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.ruoyi.technology.pojo.TechnologyRouting>()
+                                    .eq(com.ruoyi.technology.pojo.TechnologyRouting::getProductModelId, productModelId));
+            if (routings.isEmpty()) {
+                log.warn("浜у搧瑙勬牸[{}]缂哄皯宸ヨ壓璺嚎", productModelId);
+                missingIds.add(productModelId);
+                continue;
+            }
+            Long routingId = routings.get(0).getId();
+
+            // 2. 妫�鏌ュ伐鑹鸿矾绾挎槸鍚︽湁鍏宠仈宸ュ簭
+            List<com.ruoyi.technology.pojo.TechnologyRoutingOperation> routingOps =
+                    technologyRoutingOperationMapper.selectList(
+                            new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.ruoyi.technology.pojo.TechnologyRoutingOperation>()
+                                    .eq(com.ruoyi.technology.pojo.TechnologyRoutingOperation::getTechnologyRoutingId, routingId));
+            if (routingOps.isEmpty()) {
+                log.warn("浜у搧瑙勬牸[{}]宸ヨ壓璺嚎[{}]缂哄皯宸ュ簭", productModelId, routingId);
+                missingIds.add(productModelId);
+                continue;
+            }
+
+            // 3. 妫�鏌OM锛堝彲閫変絾鏈夋洿濂斤級
+            com.ruoyi.technology.pojo.TechnologyRouting routing = routings.get(0);
+            if (routing.getBomId() != null) {
+                List<com.ruoyi.technology.pojo.TechnologyBomStructure> bomStructures =
+                        technologyBomStructureMapper.selectList(
+                                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.ruoyi.technology.pojo.TechnologyBomStructure>()
+                                        .eq(com.ruoyi.technology.pojo.TechnologyBomStructure::getBomId, routing.getBomId()));
+                if (bomStructures.isEmpty()) {
+                    log.warn("浜у搧瑙勬牸[{}]BOM[{}]缂哄皯浜у搧缁撴瀯", productModelId, routing.getBomId());
+                    missingIds.add(productModelId);
+                }
+            }
+        }
+        return missingIds;
+    }
+
+    /**
+     * 鐢熶骇璁″垝鍚堝苟涓嬪彂 鈫� 鐢熶骇璁㈠崟锛堟寜productModelId鍒嗙粍锛屽悓鍨嬪彿鍚堝苟涓嬪彂锛�
+     */
+    private void processProductionCombine(SalesLedger salesLedger, LocalDate planDate) {
+        try {
+            List<ProductionPlan> plans = productionPlanMapper.selectList(
+                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ProductionPlan>()
+                            .eq(ProductionPlan::getSalesLedgerId, salesLedger.getId())
+                            .and(w -> w.eq(ProductionPlan::getStatus, 0).or().isNull(ProductionPlan::getStatus)));
+            if (plans.isEmpty()) {
+                log.info("閿�鍞彴璐{}]鏃犲緟涓嬪彂鐢熶骇璁″垝", salesLedger.getSalesContractNo());
+                return;
+            }
+
+            // 鎸塸roductModelId鍒嗙粍锛屽悓鍨嬪彿鎵嶈兘鍚堝苟涓嬪彂锛沺roductModelId涓簄ull鐨勫崟鐙�愪釜涓嬪彂
+            Map<Long, List<ProductionPlan>> grouped = plans.stream()
+                    .filter(p -> p.getProductModelId() != null)
+                    .collect(Collectors.groupingBy(ProductionPlan::getProductModelId));
+
+            for (Map.Entry<Long, List<ProductionPlan>> entry : grouped.entrySet()) {
+                try {
+                    List<ProductionPlan> sameModelPlans = entry.getValue();
+                    BigDecimal totalQty = sameModelPlans.stream()
+                            .map(p -> Optional.ofNullable(p.getQtyRequired()).orElse(BigDecimal.ZERO))
+                            .reduce(BigDecimal.ZERO, BigDecimal::add);
+                    ProductionPlanDto combineDto = new ProductionPlanDto();
+                    combineDto.setIds(sameModelPlans.stream().map(ProductionPlan::getId).collect(Collectors.toList()));
+                    combineDto.setTotalAssignedQuantity(totalQty);
+                    combineDto.setPlanCompleteTime(planDate.plusDays(ThreadLocalRandom.current().nextInt(3, 7)));
+                    productionPlanService.combine(combineDto);
+
+                    // 淇鐢熶骇璁㈠崟鐨刾lanCompleteTime
+                    List<ProductionOrder> orders = productionOrderMapper.selectList(
+                            new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ProductionOrder>()
+                                    .like(ProductionOrder::getProductionPlanIds, String.valueOf(sameModelPlans.get(0).getId())));
+                    for (ProductionOrder order : orders) {
+                        order.setPlanCompleteTime(planDate.plusDays(ThreadLocalRandom.current().nextInt(3, 7)));
+                        order.setStartTime(planDate.atStartOfDay());
+                        productionOrderMapper.updateById(order);
+                    }
+                    log.info("閿�鍞彴璐{}]鐢熶骇璁″垝涓嬪彂鎴愬姛, productModelId={}, 璁″垝鏁�: {}",
+                            salesLedger.getSalesContractNo(), entry.getKey(), sameModelPlans.size());
+                } catch (Exception e) {
+                    log.warn("閿�鍞彴璐{}]鐢熶骇璁″垝涓嬪彂澶辫触, productModelId={}: {}",
+                            salesLedger.getSalesContractNo(), entry.getKey(), e.getMessage());
+                }
+            }
+        } catch (Exception e) {
+            log.warn("鐢熶骇璁″垝涓嬪彂澶辫触[{}]: {}", salesLedger.getSalesContractNo(), e.getMessage());
+        }
+    }
+
+    /**
+     * 棰嗘枡: 鏌ヨ鐢熶骇璁㈠崟鐨凚OM棰嗘枡娓呭崟锛屾鏌ュ簱瀛橈紝涓嶈冻鍒欏厛鑷姩鍏ュ簱瀹℃壒鍚庡啀棰嗘枡
+     */
+    private void processMaterialPick(SalesLedger salesLedger, LocalDate pickDate) {
+        try {
+            List<ProductionOrder> orders = findOrdersForSalesLedger(salesLedger);
+            if (orders.isEmpty()) {
+                log.info("閿�鍞彴璐{}]鏃犵敓浜ц鍗曪紝璺宠繃棰嗘枡", salesLedger.getSalesContractNo());
+                return;
+            }
+
+            for (ProductionOrder order : orders) {
+                try {
+                    // 鏌ヨ璁㈠崟BOM棰嗘枡娓呭崟
+                    List<com.ruoyi.production.bean.vo.ProductionOrderPickVo> pickList = productionOrderService.pick(order.getId());
+                    if (pickList == null || pickList.isEmpty()) {
+                        log.info("鐢熶骇璁㈠崟[{}]鏃犻鏂欐竻鍗�", order.getId());
+                        continue;
+                    }
+
+                    // 妫�鏌ュ簱瀛樹笉瓒崇殑鐗╂枡锛屽厛鑷姩鍏ュ簱
+                    ensureMaterialStock(pickList, pickDate);
+
+                    // 閲嶆柊鑾峰彇棰嗘枡娓呭崟锛堝叆搴撳悗鎵瑰彿鍜屽簱瀛橀噺宸叉洿鏂帮級
+                    pickList = productionOrderService.pick(order.getId());
+                    if (pickList == null || pickList.isEmpty()) {
+                        log.info("鐢熶骇璁㈠崟[{}]閲嶆柊鑾峰彇棰嗘枡娓呭崟涓虹┖", order.getId());
+                        continue;
+                    }
+
+                    // 鎵ц棰嗘枡
+                    List<ProductionOrderPickDto> pickDtoList = new ArrayList<>();
+                    for (com.ruoyi.production.bean.vo.ProductionOrderPickVo pickVo : pickList) {
+                        ProductionOrderPickDto pickDto = new ProductionOrderPickDto();
+                        pickDto.setProductionOrderId(order.getId());
+                        pickDto.setProductModelId(pickVo.getProductModelId());
+                        pickDto.setPickQuantity(pickVo.getDemandedQuantity());
+                        pickDto.setPickType((byte) 1);
+                        pickDto.setOperationName(pickVo.getOperationName());
+                        pickDto.setTechnologyOperationId(pickVo.getTechnologyOperationId());
+                        pickDto.setDemandedQuantity(pickVo.getDemandedQuantity());
+                        pickDto.setBom(pickVo.getBom());
+                        // 璁剧疆鎵瑰彿锛堢敤鏇存柊鍚庣殑鎵瑰彿鍒楄〃锛�
+                        if (pickVo.getBatchNoList() != null && !pickVo.getBatchNoList().isEmpty()) {
+                            pickDto.setBatchNoList(pickVo.getBatchNoList());
+                            pickDto.setBatchNo(pickVo.getBatchNoList().get(0));
+                        }
+                        pickDtoList.add(pickDto);
+                    }
+
+                    if (!pickDtoList.isEmpty()) {
+                        ProductionOrderPickDto batchDto = new ProductionOrderPickDto();
+                        batchDto.setPickList(pickDtoList);
+                        productionOrderPickService.savePick(batchDto);
+                        log.info("鐢熶骇璁㈠崟[{}]棰嗘枡鎴愬姛, 棰嗘枡椤规暟: {}", order.getId(), pickDtoList.size());
+                    }
+                } catch (Exception e) {
+                    log.warn("鐢熶骇璁㈠崟[{}]棰嗘枡澶辫触: {}", order.getId(), e.getMessage());
+                }
+            }
+        } catch (Exception e) {
+            log.warn("棰嗘枡娴佺▼澶辫触[{}]: {}", salesLedger.getSalesContractNo(), e.getMessage());
+        }
+    }
+
+    /**
+     * 纭繚鐗╂枡搴撳瓨鍏呰冻锛屼笉瓒冲垯鍏堣嚜鍔ㄥ叆搴撳鎵�
+     */
+    private void ensureMaterialStock(List<com.ruoyi.production.bean.vo.ProductionOrderPickVo> pickList, LocalDate pickDate) {
+        LocalDateTime pickDateTime = pickDate.atTime(9, 0, 0).plusMinutes(ThreadLocalRandom.current().nextInt(0, 480));
+        String pickDateStr = pickDate.format(DateTimeFormatter.BASIC_ISO_DATE);
+
+        for (com.ruoyi.production.bean.vo.ProductionOrderPickVo pickVo : pickList) {
+            BigDecimal demanded = pickVo.getDemandedQuantity() != null ? pickVo.getDemandedQuantity() : BigDecimal.ZERO;
+            BigDecimal stockQty = pickVo.getStockQuantity() != null ? pickVo.getStockQuantity() : BigDecimal.ZERO;
+            BigDecimal shortage = demanded.subtract(stockQty);
+
+            if (shortage.compareTo(BigDecimal.ZERO) <= 0) {
+                continue; // 搴撳瓨鍏呰冻
+            }
+
+            // 搴撳瓨涓嶈冻锛岃嚜鍔ㄥ叆搴撹ˉ鍏�
+            try {
+                StockInventoryDto dto = new StockInventoryDto();
+                dto.setProductModelId(pickVo.getProductModelId());
+                dto.setQualitity(shortage);
+                dto.setRecordType(StockInQualifiedRecordTypeEnum.CUSTOMIZATION_STOCK_IN.getCode());
+                dto.setRecordId(0L);
+                stockInventoryService.addStockInRecordOnly(dto);
+
+                // 鏌ユ壘鍒氬垱寤虹殑鍏ュ簱璁板綍
+                List<com.ruoyi.stock.pojo.StockInRecord> records = stockInRecordService.list(
+                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.ruoyi.stock.pojo.StockInRecord>()
+                                .eq(com.ruoyi.stock.pojo.StockInRecord::getProductModelId, pickVo.getProductModelId())
+                                .eq(com.ruoyi.stock.pojo.StockInRecord::getApprovalStatus, 0)
+                                .orderByDesc(com.ruoyi.stock.pojo.StockInRecord::getId)
+                                .last("limit 1"));
+                if (!records.isEmpty()) {
+                    com.ruoyi.stock.pojo.StockInRecord record = records.get(0);
+                    record.setCreateTime(pickDateTime);
+                    record.setBatchNo(fixBatchNoDate(record.getBatchNo(), pickDateStr));
+                    record.setInboundBatches(fixBatchNoDate(record.getInboundBatches(), pickDateStr));
+                    stockInRecordMapper.updateById(record);
+                    // 瀹℃壒閫氳繃
+                    stockInRecordService.batchApprove(List.of(record.getId()), ReviewStatusEnum.APPROVED.getCode());
+                    log.info("鐗╂枡[{}]鑷姩鍏ュ簱瀹℃壒瀹屾垚, 鍏ュ簱鏁伴噺: {}", pickVo.getProductModelId(), shortage);
+                }
+            } catch (Exception e) {
+                log.warn("鐗╂枡[{}]鑷姩鍏ュ簱澶辫触: {}", pickVo.getProductModelId(), e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * 鐢熶骇鎶ュ伐: 閬嶅巻宸ュ崟閫愪釜鎶ュ伐锛屼粠鐢熶骇瑙掕壊鐢ㄦ埛涓殢鏈洪�夊彇鎶ュ伐浜�
+     */
+    private void processProductionReport(SalesLedger salesLedger, LocalDate reportDate) {
+        try {
+            List<ProductionOrder> orders = findOrdersForSalesLedger(salesLedger);
+            if (orders.isEmpty()) {
+                log.info("閿�鍞彴璐{}]鏃犵敓浜ц鍗�", salesLedger.getSalesContractNo());
+                return;
+            }
+
+            for (ProductionOrder order : orders) {
+                List<ProductionOperationTask> tasks = productionOperationTaskMapper.selectList(
+                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ProductionOperationTask>()
+                                .eq(ProductionOperationTask::getProductionOrderId, order.getId())
+                                .orderByAsc(ProductionOperationTask::getId));
+                for (ProductionOperationTask task : tasks) {
+                    if (task.getStatus() != null && task.getStatus() >= 3) continue;
+
+                    // 姣忔鎶ュ伐闅忔満閫変竴涓敓浜х敤鎴�
+                    SysUser productionUser = randomProductionUser();
+                    Long userId = productionUser != null ? productionUser.getUserId() : 1L;
+                    String userName = productionUser != null ? productionUser.getNickName() : "绯荤粺";
+
+                    // 鎶ュ伐
+                    ProductionProductMainDto reportDto = new ProductionProductMainDto();
+                    reportDto.setProductionOperationTaskId(task.getId());
+                    reportDto.setQuantity(task.getPlanQuantity());
+                    reportDto.setScrapQty(BigDecimal.ZERO);
+                    reportDto.setUserId(userId);
+                    reportDto.setUserName(userName);
+                    productionProductMainService.addProductMain(reportDto);
+
+                    // 淇鎶ュ伐鏃堕棿锛堥噸鏂颁粠DB璇诲彇锛岄伩鍏嶈鐩朼ddProductMain鏇存柊鐨刢ompleteQuantity锛�
+                    fixProductionReportTimes(task.getId(), reportDate);
+                }
+                // 淇鐢熶骇璁㈠崟鏃堕棿锛堥噸鏂颁粠DB璇诲彇锛岄伩鍏嶈鐩朼ddProductMain鏇存柊鐨刢ompleteQuantity锛�
+                fixProductionOrderTimes(order.getId(), reportDate);
+            }
+            log.info("閿�鍞彴璐{}]鐢熶骇鎶ュ伐瀹屾垚, 璁㈠崟鏁�: {}", salesLedger.getSalesContractNo(), orders.size());
+        } catch (Exception e) {
+            log.warn("鐢熶骇鎶ュ伐澶辫触[{}]: {}", salesLedger.getSalesContractNo(), e.getMessage());
+        }
+    }
+
+    /**
+     * 鏌ユ壘閿�鍞彴璐﹀叧鑱旂殑鐢熶骇璁㈠崟
+     */
+    private List<ProductionOrder> findOrdersForSalesLedger(SalesLedger salesLedger) {
+        List<ProductionOrder> orders = new ArrayList<>();
+        List<ProductionPlan> plans = productionPlanMapper.selectList(
+                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ProductionPlan>()
+                        .eq(ProductionPlan::getSalesLedgerId, salesLedger.getId()));
+        for (ProductionPlan plan : plans) {
+            List<ProductionOrder> po = productionOrderMapper.selectList(
+                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ProductionOrder>()
+                            .like(ProductionOrder::getProductionPlanIds, String.valueOf(plan.getId())));
+            orders.addAll(po);
+        }
+        // 鍘婚噸
+        return orders.stream()
+                .collect(Collectors.toMap(ProductionOrder::getId, o -> o, (a, b) -> a))
+                .values().stream().collect(Collectors.toList());
+    }
+
+    /**
+     * 淇鐢熶骇鎶ュ伐鐩稿叧鏃堕棿锛堥噸鏂颁粠DB璇诲彇task锛岄伩鍏嶈鐩朼ddProductMain宸叉洿鏂扮殑completeQuantity锛�
+     */
+    private void fixProductionReportTimes(Long taskId, LocalDate reportDate) {
+        try {
+            ProductionOperationTask freshTask = productionOperationTaskMapper.selectById(taskId);
+            if (freshTask != null) {
+                freshTask.setActualStartTime(reportDate);
+                freshTask.setActualEndTime(reportDate);
+                freshTask.setStatus(4);
+                productionOperationTaskMapper.updateById(freshTask);
+            }
+        } catch (Exception e) {
+            log.warn("淇鐢熶骇鎶ュ伐鏃堕棿澶辫触: {}", e.getMessage());
+        }
+    }
+
+    /**
+     * 淇鐢熶骇璁㈠崟鏃堕棿锛堥噸鏂颁粠DB璇诲彇order锛岄伩鍏嶈鐩朼ddProductMain宸叉洿鏂扮殑completeQuantity锛�
+     */
+    private void fixProductionOrderTimes(Long orderId, LocalDate reportDate) {
+        try {
+            ProductionOrder freshOrder = productionOrderMapper.selectById(orderId);
+            if (freshOrder != null) {
+                freshOrder.setStartTime(reportDate.minusDays(1).atStartOfDay());
+                freshOrder.setEndTime(reportDate.plusDays(1).atStartOfDay());
+                freshOrder.setStatus(3);
+                productionOrderMapper.updateById(freshOrder);
+            }
+        } catch (Exception e) {
+            log.warn("淇鐢熶骇璁㈠崟鏃堕棿澶辫触: {}", e.getMessage());
+        }
+    }
+
+    /**
+     * 閿�鍞川妫�鎻愪氦 + 鍏ュ簱瀹℃壒
+     */
+    private void processSalesQualityAndStockIn(SalesLedger salesLedger, LocalDate qualityDate) {
+        try {
+            LocalDateTime qualityDateTime = qualityDate.atTime(9, 0, 0)
+                    .plusMinutes(ThreadLocalRandom.current().nextInt(0, 480));
+
+            // 鏌ユ墍鏈夋湭鎻愪氦鐨勮川妫�鍗曪紙inspectType=1杩囩▼妫�楠�, 2=鍑哄巶妫�楠岋紝鐢辩敓浜ф姤宸ョ敓鎴愶級
+            List<QualityInspect> allUnsubmitted = qualityInspectService.list(
+                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<QualityInspect>()
+                            .eq(QualityInspect::getInspectState, 0)
+                            .in(QualityInspect::getInspectType, java.util.Arrays.asList(1, 2)));
+            for (QualityInspect qi : allUnsubmitted) {
+                qualityInspectService.autoSubmit(qi.getId());
+                qi.setCreateTime(qualityDateTime);
+                qualityInspectMapper.updateById(qi);
+            }
+            log.info("閿�鍞彴璐{}]璐ㄦ鎻愪氦瀹屾垚, 璐ㄦ鍗曟暟: {}", salesLedger.getSalesContractNo(), allUnsubmitted.size());
+
+            // 鍏ュ簱瀹℃壒锛氬鎵规墍鏈夊緟瀹℃壒鐨勫叆搴撹褰�
+            LocalDate stockDate = qualityDate.plusDays(ThreadLocalRandom.current().nextInt(0, 3));
+            LocalDateTime stockDateTime = stockDate.atTime(9, 0, 0)
+                    .plusMinutes(ThreadLocalRandom.current().nextInt(0, 480));
+            String stockDateStr = stockDate.format(DateTimeFormatter.BASIC_ISO_DATE);
+            List<com.ruoyi.stock.pojo.StockInRecord> stockRecords = stockInRecordService.list(
+                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.ruoyi.stock.pojo.StockInRecord>()
+                            .eq(com.ruoyi.stock.pojo.StockInRecord::getApprovalStatus, 0));
+            List<Long> recordIds = stockRecords.stream()
+                    .map(com.ruoyi.stock.pojo.StockInRecord::getId)
+                    .collect(Collectors.toList());
+            if (!recordIds.isEmpty()) {
+                for (com.ruoyi.stock.pojo.StockInRecord sr : stockRecords) {
+                    sr.setCreateTime(stockDateTime);
+                    sr.setBatchNo(fixBatchNoDate(sr.getBatchNo(), stockDateStr));
+                    sr.setInboundBatches(fixBatchNoDate(sr.getInboundBatches(), stockDateStr));
+                    stockInRecordMapper.updateById(sr);
+                }
+                stockInRecordService.batchApprove(recordIds, ReviewStatusEnum.APPROVED.getCode());
+                for (com.ruoyi.stock.pojo.StockInRecord sr : stockRecords) {
+                    StockInventory si = stockInventoryMapper.selectOne(
+                            new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<StockInventory>()
+                                    .eq(StockInventory::getProductModelId, sr.getProductModelId())
+                                    .eq(StockInventory::getBatchNo, sr.getBatchNo()));
+                    if (si != null) {
+                        si.setBatchNo(fixBatchNoDate(si.getBatchNo(), stockDateStr));
+                        stockInventoryMapper.updateById(si);
+                    }
+                }
+                log.info("閿�鍞彴璐{}]鍏ュ簱瀹℃壒瀹屾垚, 鍏ュ簱璁板綍鏁�: {}", salesLedger.getSalesContractNo(), recordIds.size());
+            }
+        } catch (Exception e) {
+            log.warn("閿�鍞川妫�鍏ュ簱澶辫触[{}]: {}", salesLedger.getSalesContractNo(), e.getMessage());
+        }
+    }
+
+    /**
+     * 鍙戣揣 + 鍙戣揣瀹℃壒閫氳繃 + 鍑哄簱瀹℃壒
+     */
+    private void processSalesShipping(SalesLedger salesLedger, LocalDate shipDate) {
+        try {
+            LocalDateTime shipDateTime = shipDate.atTime(9, 0, 0)
+                    .plusMinutes(ThreadLocalRandom.current().nextInt(0, 480));
+            String shipDateStr = shipDate.format(DateTimeFormatter.BASIC_ISO_DATE);
+
+            // 鏌ユ壘鏈夊簱瀛樼殑浜у搧瑙勬牸
+            List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(
+                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<SalesLedgerProduct>()
+                            .eq(SalesLedgerProduct::getSalesLedgerId, salesLedger.getId()));
+
+            List<ShippingProductDetail> details = new ArrayList<>();
+            for (SalesLedgerProduct slp : products) {
+                StockInventory si = stockInventoryMapper.selectOne(
+                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<StockInventory>()
+                                .eq(StockInventory::getProductModelId, slp.getProductModelId())
+                                .gt(StockInventory::getQualitity, BigDecimal.ZERO)
+                                .orderByDesc(StockInventory::getId)
+                                .last("limit 1"));
+                if (si != null) {
+                    ShippingProductDetail detail = new ShippingProductDetail();
+                    detail.setStockInventoryId(si.getId());
+                    detail.setProductModelId(slp.getProductModelId());
+                    detail.setBatchNo(si.getBatchNo());
+                    detail.setQuantity(slp.getQuantity());
+                    details.add(detail);
+                }
+            }
+            if (details.isEmpty()) {
+                log.info("閿�鍞彴璐{}]鏃犲彲鐢ㄥ簱瀛橈紝璺宠繃鍙戣揣", salesLedger.getSalesContractNo());
+                return;
+            }
+
+            // 鍒涘缓鍙戣揣鍗�
+            ShippingInfoDto shipDto = new ShippingInfoDto();
+            shipDto.setSalesLedgerId(salesLedger.getId());
+            shipDto.setSalesLedgerProductId(products.get(0).getId());
+            shipDto.setCreateTime(shipDateTime);
+            shipDto.setBatchNoDetailList(details);
+            shippingInfoService.addReq(shipDto);
+
+            // 鎵惧埌鍙戣揣鍗曞拰瀹℃壒瀹炰緥
+            ShippingInfo shippingInfo = shippingInfoMapper.selectOne(
+                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ShippingInfo>()
+                            .eq(ShippingInfo::getShippingNo, shipDto.getShippingNo())
+                            .last("limit 1"));
+            if (shippingInfo != null) {
+                shippingInfo.setCreateTime(shipDateTime);
+                shippingInfo.setShippingDate(java.sql.Date.valueOf(shipDate));
+                // 鏍规嵁瀹㈡埛鍦板潃鐢熸垚鍙戣揣杞︾墝鍙�
+                shippingInfo.setShippingCarNumber(generateCarNumber(salesLedger.getCustomerName()));
+                shippingInfoMapper.updateById(shippingInfo);
+
+                // 鍙戣揣瀹℃壒鑷姩閫氳繃
+                ApprovalInstance shipApproval = approvalInstanceMapper.selectOne(
+                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ApprovalInstance>()
+                                .eq(ApprovalInstance::getBusinessId, shippingInfo.getId())
+                                .eq(ApprovalInstance::getBusinessType, 7L)
+                                .eq(ApprovalInstance::getDeleted, 0)
+                                .orderByDesc(ApprovalInstance::getId)
+                                .last("limit 1"));
+                if (shipApproval != null) {
+                    LocalDate shipApproveDate = shipDate.plusDays(ThreadLocalRandom.current().nextInt(0, 3));
+                    LocalDateTime shipApproveDateTime = shipApproveDate.atTime(9, 0, 0)
+                            .plusMinutes(ThreadLocalRandom.current().nextInt(0, 480));
+                    approvalInstanceService.autoApprove(shipApproval.getId());
+                    fixApprovalTimes(shipApproval.getId(), shipApproveDateTime);
+
+                    shippingInfo.setStatus("宸插彂璐�");
+                    shippingInfo.setShippingDate(java.sql.Date.valueOf(shipApproveDate));
+                    shippingInfoMapper.updateById(shippingInfo);
+                }
+
+                // 鍑哄簱瀹℃壒
+                LocalDate outDate = shipDate.plusDays(ThreadLocalRandom.current().nextInt(0, 3));
+                LocalDateTime outDateTime = outDate.atTime(9, 0, 0)
+                        .plusMinutes(ThreadLocalRandom.current().nextInt(0, 480));
+                String outDateStr = outDate.format(DateTimeFormatter.BASIC_ISO_DATE);
+                List<StockOutRecord> outRecords = stockOutRecordMapper.selectList(
+                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<StockOutRecord>()
+                                .eq(StockOutRecord::getRecordId, shippingInfo.getId())
+                                .eq(StockOutRecord::getRecordType,
+                                        String.valueOf(StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode())));
+                List<Long> outIds = new ArrayList<>();
+                for (StockOutRecord sr : outRecords) {
+                    if (sr.getApprovalStatus() == null || sr.getApprovalStatus() == 0 || sr.getApprovalStatus() == 3) {
+                        sr.setCreateTime(outDateTime);
+                        sr.setOutboundBatches(fixBatchNoDate(sr.getOutboundBatches(), outDateStr));
+                        sr.setBatchNo(fixBatchNoDate(sr.getBatchNo(), outDateStr));
+                        stockOutRecordMapper.updateById(sr);
+                        outIds.add(sr.getId());
+                    }
+                }
+                if (!outIds.isEmpty()) {
+                    // 鍑哄簱瀹℃壒閫氳繃锛堣蛋姝e紡瀹℃壒娴佺▼锛屽唴閮ㄤ細鎵e噺搴撳瓨锛�
+                    stockOutRecordService.batchApprove(outIds, ReviewStatusEnum.APPROVED.getCode());
+                    log.info("閿�鍞彴璐{}]鍑哄簱瀹℃壒瀹屾垚, 鍑哄簱璁板綍鏁�: {}",
+                            salesLedger.getSalesContractNo(), outIds.size());
+                }
+            }
+            log.info("閿�鍞彴璐{}]鍙戣揣娴佺▼瀹屾垚", salesLedger.getSalesContractNo());
+        } catch (Exception e) {
+            log.warn("閿�鍞彂璐ф祦绋嬪け璐{}]: {}", salesLedger.getSalesContractNo(), e.getMessage());
+        }
+    }
+
+    private ModuleSummary createPurchaseLedgers(List<JSONObject> items, Map<String, Long> supplierNameToId,
+                                                 String additionalInfo, String dateStart, String dateEnd) {
+        // 鏄惁闇�瑕佽川妫�锛屼粠琛ュ厖淇℃伅鍒ゆ柇锛岄粯璁や笉闇�瑕�
+        boolean needQualityInspect = additionalInfo != null
+                && (additionalInfo.contains("璐ㄦ") || additionalInfo.contains("闇�瑕佹楠�"));
+        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.setPurchaseContractNumber(item.getString("purchaseContractNumber"));
+                dto.setProjectName(item.getString("projectName"));
+                dto.setContractAmount(item.getBigDecimal("contractAmount"));
+                dto.setPaymentMethod(item.getString("paymentMethod"));
+
+                String entryDateStr = item.getString("entryDate");
+                LocalDate entryDate = null;
+                if (item.containsKey("entryDate") && entryDateStr != null && entryDateStr.matches("\\d{4}-\\d{2}-\\d{2}")) {
+                    entryDate = LocalDate.parse(entryDateStr);
+                    dto.setEntryDate(java.sql.Date.valueOf(entryDateStr));
+                } else {
+                    dto.setEntryDate(java.sql.Date.valueOf(dateStart));
+                }
+                if (item.containsKey("executionDate")) {
+                    String execDateStr = item.getString("executionDate");
+                    if (execDateStr != null && execDateStr.matches("\\d{4}-\\d{2}-\\d{2}")) {
+                        dto.setExecutionDate(java.sql.Date.valueOf(execDateStr));
+                    } else {
+                        dto.setExecutionDate(java.sql.Date.valueOf(dateStart));
+                    }
+                }
+                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);
+                        // 鏄惁璐ㄦ锛氫粠琛ュ厖淇℃伅鍒ゆ柇锛岄粯璁や笉闇�瑕�
+                        slp.setIsChecked(needQualityInspect);
+                        if (pd.containsKey("taxExclusiveTotalPrice")) {
+                            slp.setTaxExclusiveTotalPrice(pd.getBigDecimal("taxExclusiveTotalPrice"));
+                        } else if (pd.getBigDecimal("taxInclusiveTotalPrice") != null && pd.getBigDecimal("taxRate") != null) {
+                            slp.setTaxExclusiveTotalPrice(
+                                pd.getBigDecimal("taxInclusiveTotalPrice").divide(
+                                    BigDecimal.ONE.add(pd.getBigDecimal("taxRate").divide(new BigDecimal("100"), 4, RoundingMode.HALF_UP)),
+                                    2, RoundingMode.HALF_UP));
+                        } else {
+                            slp.setTaxExclusiveTotalPrice(BigDecimal.ZERO);
+                        }
+                        products.add(slp);
+                    }
+                    dto.setProductData(products);
+                }
+                purchaseLedgerService.addOrEditPurchase(dto);
+                // 閫氳繃鍚堝悓鍙锋壘鍒板垰鍒涘缓鐨勯噰璐彴璐�
+                PurchaseLedger savedLedger = purchaseLedgerService.getOne(
+                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<PurchaseLedger>()
+                                .eq(PurchaseLedger::getPurchaseContractNumber, dto.getPurchaseContractNumber())
+                                .last("limit 1"));
+                if (savedLedger != null) {
+                    // 璧板畬鏁存祦绋嬶細瀹℃牳閫氳繃 鈫� 璐ㄦ(鍙��) 鈫� 鍏ュ簱 + 鍏ュ簱瀹℃牳閫氳繃
+                    processPurchaseFullFlow(savedLedger, needQualityInspect, entryDate, dateEnd);
+                }
+                success++;
+            } catch (Exception e) {
+                log.warn("鍒涘缓閲囪喘鍙拌处澶辫触: {}", e.getMessage(), e);
+                fail++;
+            }
+        }
+        return summary("purchase", "閲囪喘鍙拌处", items.size(), success, fail);
+    }
+
+    /**
+     * 閲囪喘瀹屾暣娴佺▼: 瀹℃牳閫氳繃 鈫� 璐ㄦ(鍙��) 鈫� 鍏ュ簱瀹℃牳閫氳繃
+     * 鍚勭幆鑺傛椂闂翠互閲囪喘褰曞叆鏃ユ湡涓哄熀鍑嗭紝鍋跺皵鎺ㄨ繜1-3澶�
+     */
+    private void processPurchaseFullFlow(PurchaseLedger purchaseLedger, boolean needQualityInspect,
+                                          LocalDate entryDate, String dateEnd) {
+        try {
+            // 鍩哄噯鏃ユ湡锛氶噰璐綍鍏ユ棩鏈燂紝涓虹┖鍒欑敤褰撳ぉ
+            LocalDate baseDate = entryDate != null ? entryDate : LocalDate.now();
+            // 瀹℃壒鏃堕棿锛氬熀浜庡綍鍏ユ棩鏈燂紝闅忔満鎺�0-3澶�
+            LocalDate approveDate = baseDate.plusDays(ThreadLocalRandom.current().nextInt(0, 4));
+            LocalDateTime approveDateTime = approveDate.atTime(9, 0, 0)
+                    .plusMinutes(ThreadLocalRandom.current().nextInt(0, 480));
+
+            // 1. 瀹℃壒鑷姩閫氳繃
+            ApprovalInstance approvalInstance = approvalInstanceMapper.selectOne(
+                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ApprovalInstance>()
+                            .eq(ApprovalInstance::getBusinessId, purchaseLedger.getId())
+                            .eq(ApprovalInstance::getBusinessType, 5L)
+                            .eq(ApprovalInstance::getDeleted, 0)
+                            .orderByDesc(ApprovalInstance::getId)
+                            .last("limit 1"));
+            if (approvalInstance != null) {
+                approvalInstanceService.autoApprove(approvalInstance.getId());
+                // 淇瀹℃壒鐩稿叧鏃堕棿涓洪噰璐綍鍏ユ棩鏈熻寖鍥�
+                fixApprovalTimes(approvalInstance.getId(), approveDateTime);
+                log.info("閲囪喘鍙拌处[{}]瀹℃壒閫氳繃, 瀹℃壒鏃ユ湡: {}", purchaseLedger.getPurchaseContractNumber(), approveDate);
+            }
+
+            // 2. 璐ㄦ娴佺▼锛堝鏋滈渶瑕佽川妫�锛�
+            if (needQualityInspect) {
+                // 璐ㄦ鏃堕棿锛氬鎵逛箣鍚庡啀鎺�0-3澶�
+                LocalDate inspectDate = approveDate.plusDays(ThreadLocalRandom.current().nextInt(0, 4));
+                processQualityInspect(purchaseLedger, inspectDate);
+            }
+
+            // 3. 鍏ュ簱瀹℃壒閫氳繃
+            // 鍏ュ簱鏃堕棿锛氳川妫�鏃堕棿锛堟湁璐ㄦ锛夋垨瀹℃壒鏃堕棿涔嬪悗鍐嶆帹0-3澶�
+            LocalDate stockBaseDate = needQualityInspect
+                    ? approveDate.plusDays(ThreadLocalRandom.current().nextInt(1, 4))
+                    : approveDate.plusDays(ThreadLocalRandom.current().nextInt(0, 4));
+            processStockInApprove(purchaseLedger, stockBaseDate);
+
+        } catch (Exception e) {
+            log.warn("閲囪喘瀹屾暣娴佺▼澶勭悊澶辫触[{}]: {}", purchaseLedger.getPurchaseContractNumber(), e.getMessage());
+        }
+    }
+
+    /**
+     * 淇瀹℃壒瀹炰緥鍙婂叧鑱旇妭鐐广�佷换鍔°�佽褰曠殑鏃堕棿
+     */
+    private void fixApprovalTimes(Long instanceId, LocalDateTime dateTime) {
+        try {
+            // 鏇存柊瀹℃壒瀹炰緥鐨刦inishTime鍜宑reateTime
+            ApprovalInstance instance = approvalInstanceMapper.selectById(instanceId);
+            if (instance != null) {
+                instance.setFinishTime(dateTime);
+                instance.setCreateTime(dateTime.minusHours(1));
+                approvalInstanceMapper.updateById(instance);
+            }
+
+            // 鏇存柊瀹℃壒瀹炰緥鑺傜偣鐨刦inishTime
+            List<ApprovalInstanceNode> nodes = approvalInstanceNodeMapper.selectList(
+                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ApprovalInstanceNode>()
+                            .eq(ApprovalInstanceNode::getInstanceId, instanceId));
+            for (ApprovalInstanceNode node : nodes) {
+                node.setFinishTime(dateTime);
+                node.setCreateTime(dateTime.minusHours(1));
+                approvalInstanceNodeMapper.updateById(node);
+            }
+
+            // 鏇存柊瀹℃壒浠诲姟鐨刢reateTime
+            List<ApprovalTask> tasks = approvalTaskMapper.selectList(
+                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ApprovalTask>()
+                            .eq(ApprovalTask::getInstanceId, instanceId));
+            for (ApprovalTask task : tasks) {
+                task.setCreateTime(dateTime.minusMinutes(30));
+                approvalTaskMapper.updateById(task);
+            }
+
+            // 鏇存柊瀹℃壒璁板綍鐨刢reateTime
+            List<ApprovalRecord> records = approvalRecordMapper.selectList(
+                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ApprovalRecord>()
+                            .eq(ApprovalRecord::getInstanceId, instanceId));
+            for (ApprovalRecord record : records) {
+                record.setCreateTime(dateTime.minusMinutes(10));
+                approvalRecordMapper.updateById(record);
+            }
+        } catch (Exception e) {
+            log.warn("淇瀹℃壒鏃堕棿澶辫触: {}", e.getMessage());
+        }
+    }
+
+    /**
+     * 璐ㄦ: 鎵惧埌閲囪喘鍏宠仈鐨勮川妫�鍗曪紝鑷姩鎻愪氦涓哄悎鏍�
+     */
+    private void processQualityInspect(PurchaseLedger purchaseLedger, LocalDate inspectDate) {
+        try {
+            LocalDateTime inspectDateTime = inspectDate.atTime(9, 0, 0)
+                    .plusMinutes(ThreadLocalRandom.current().nextInt(0, 480));
+            List<QualityInspect> inspectList = qualityInspectService.list(
+                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<QualityInspect>()
+                            .eq(QualityInspect::getPurchaseLedgerId, purchaseLedger.getId()));
+            for (QualityInspect qi : inspectList) {
+                if (qi.getInspectState() == null || qi.getInspectState() == 0) {
+                    qualityInspectService.autoSubmit(qi.getId());
+                    // 淇璐ㄦ鏃堕棿
+                    qi.setCreateTime(inspectDateTime);
+                    qualityInspectMapper.updateById(qi);
+                    log.info("閲囪喘鍙拌处[{}]璐ㄦ鍗昜{}]鑷姩鎻愪氦鍚堟牸, 璐ㄦ鏃ユ湡: {}",
+                            purchaseLedger.getPurchaseContractNumber(), qi.getId(), inspectDate);
+                }
+            }
+        } catch (Exception e) {
+            log.warn("璐ㄦ娴佺▼澶勭悊澶辫触[{}]: {}", purchaseLedger.getPurchaseContractNumber(), e.getMessage());
+        }
+    }
+
+    /**
+     * 鍏ュ簱瀹℃牳: 鎵惧埌鍏ュ簱璁板綍骞跺鎵归�氳繃锛屽苟淇鏃堕棿涓庢壒鍙锋棩鏈�
+     */
+    private void processStockInApprove(PurchaseLedger purchaseLedger, LocalDate stockDate) {
+        try {
+            LocalDateTime stockDateTime = stockDate.atTime(9, 0, 0)
+                    .plusMinutes(ThreadLocalRandom.current().nextInt(0, 480));
+            String stockDateStr = stockDate.format(java.time.format.DateTimeFormatter.BASIC_ISO_DATE);
+
+            List<com.ruoyi.stock.pojo.StockInRecord> stockRecords = stockInRecordService.list(
+                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.ruoyi.stock.pojo.StockInRecord>()
+                            .eq(com.ruoyi.stock.pojo.StockInRecord::getRecordId, purchaseLedger.getId())
+                            .eq(com.ruoyi.stock.pojo.StockInRecord::getRecordType,
+                                    String.valueOf(com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum.PURCHASE_STOCK_IN.getCode())));
+            if (stockRecords.isEmpty()) {
+                stockRecords = stockInRecordService.list(
+                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.ruoyi.stock.pojo.StockInRecord>()
+                                .eq(com.ruoyi.stock.pojo.StockInRecord::getRecordId, purchaseLedger.getId())
+                                .eq(com.ruoyi.stock.pojo.StockInRecord::getRecordType,
+                                        String.valueOf(com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum.CUSTOMIZATION_UNSTOCK_OUT.getCode())));
+            }
+            for (QualityInspect qi : qualityInspectService.list(
+                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<QualityInspect>()
+                            .eq(QualityInspect::getPurchaseLedgerId, purchaseLedger.getId()))) {
+                List<com.ruoyi.stock.pojo.StockInRecord> qiRecords = stockInRecordService.list(
+                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.ruoyi.stock.pojo.StockInRecord>()
+                                .eq(com.ruoyi.stock.pojo.StockInRecord::getRecordId, qi.getId()));
+                stockRecords.addAll(qiRecords);
+            }
+            stockRecords = stockRecords.stream()
+                    .collect(Collectors.toMap(com.ruoyi.stock.pojo.StockInRecord::getId, r -> r, (a, b) -> a))
+                    .values().stream().collect(Collectors.toList());
+
+            if (!stockRecords.isEmpty()) {
+                List<Long> recordIds = stockRecords.stream()
+                        .filter(r -> r.getApprovalStatus() == null || r.getApprovalStatus() == 0)
+                        .map(com.ruoyi.stock.pojo.StockInRecord::getId)
+                        .collect(Collectors.toList());
+                if (!recordIds.isEmpty()) {
+                    // 鍏堜慨姝e叆搴撹褰曠殑createTime鍜屾壒鍙锋棩鏈燂紙batchApprove鍐呴儴浼氱敤batchNo鍒涘缓StockInventory锛�
+                    for (Long recordId : recordIds) {
+                        com.ruoyi.stock.pojo.StockInRecord sr = stockInRecordMapper.selectById(recordId);
+                        if (sr != null) {
+                            sr.setCreateTime(stockDateTime);
+                            sr.setBatchNo(fixBatchNoDate(sr.getBatchNo(), stockDateStr));
+                            String s = OrderUtils.countTodayByCreateTime(stockInRecordMapper, "RK", "inbound_batches", stockDateTime);
+                            sr.setInboundBatches(s);
+                            stockInRecordMapper.updateById(sr);
+                        }
+                    }
+                    stockInRecordService.batchApprove(recordIds, ReviewStatusEnum.APPROVED.getCode());
+                    log.info("閲囪喘鍙拌处[{}]鍏ュ簱瀹℃壒閫氳繃, 鍏ュ簱鏃ユ湡: {}, 鍏ュ簱璁板綍鏁�: {}",
+                            purchaseLedger.getPurchaseContractNumber(), stockDate, recordIds.size());
+                }
+            }
+        } catch (Exception e) {
+            log.warn("鍏ュ簱瀹℃壒澶辫触[{}]: {}", purchaseLedger.getPurchaseContractNumber(), e.getMessage());
+        }
+    }
+
+    /**
+     * 鏇挎崲鎵瑰彿涓殑鏃ユ湡閮ㄥ垎锛坹yyyMMdd 鈫� 鎸囧畾鏃ユ湡锛�
+     */
+    /**
+     * 鏍规嵁瀹㈡埛鍚嶇О鏌ュ湴鍧�锛屾帹鏂渷浠界畝绉扮敓鎴愯溅鐗屽彿
+     * 鏍煎紡: 鐪佷唤绠�绉� + 瀛楁瘝 + 5浣嶉殢鏈烘暟瀛楀瓧姣�, 濡� 鑻廇12345
+     */
+    private String generateCarNumber(String customerName) {
+        // 鐪佷唤绠�绉板埌鍩庡競瀛楁瘝鐨勫父瑙佹槧灏�
+        Map<String, String[]> provinceCityMap = new HashMap<>();
+        provinceCityMap.put("浜�", new String[]{"A", "B", "C", "E", "F", "G"});
+        provinceCityMap.put("娌�", new String[]{"A", "B", "D", "E", "F"});
+        provinceCityMap.put("绮�", new String[]{"A", "B", "E", "F", "G", "H", "J", "K"});
+        provinceCityMap.put("鑻�", new String[]{"A", "B", "E", "F", "G", "H", "J", "K", "L", "M"});
+        provinceCityMap.put("娴�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L"});
+        provinceCityMap.put("椴�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "Y"});
+        provinceCityMap.put("璞�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "U"});
+        provinceCityMap.put("宸�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"});
+        provinceCityMap.put("娓�", new String[]{"A", "B", "C", "D"});
+        provinceCityMap.put("閯�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S"});
+        provinceCityMap.put("婀�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "S"});
+        provinceCityMap.put("闂�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K"});
+        provinceCityMap.put("璧�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M"});
+        provinceCityMap.put("鐨�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R", "S"});
+        provinceCityMap.put("鍐�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "R", "T"});
+        provinceCityMap.put("杈�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P"});
+        provinceCityMap.put("鍚�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K"});
+        provinceCityMap.put("榛�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R"});
+        provinceCityMap.put("鏅�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M"});
+        provinceCityMap.put("闄�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "V"});
+        provinceCityMap.put("妗�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R"});
+        provinceCityMap.put("浜�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S"});
+        provinceCityMap.put("璐�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J"});
+        provinceCityMap.put("鐢�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P"});
+        provinceCityMap.put("鐞�", new String[]{"A", "B", "C", "D", "E", "F"});
+        provinceCityMap.put("瀹�", new String[]{"A", "B", "C", "D", "E"});
+        provinceCityMap.put("闈�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H"});
+        provinceCityMap.put("钘�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J"});
+        provinceCityMap.put("钂�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M"});
+        provinceCityMap.put("鏂�", new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R"});
+        provinceCityMap.put("娲�", new String[]{"A", "B", "C", "E", "F", "G", "H", "J", "K", "L", "M", "N", "Q", "R"});
+
+        // 鍦板潃鍏抽敭璇嶅埌鐪佷唤绠�绉扮殑鏄犲皠
+        Map<String, String> addressToProvince = new HashMap<>();
+        addressToProvince.put("鍖椾含", "浜�"); addressToProvince.put("涓婃捣", "娌�");
+        addressToProvince.put("骞垮窞", "绮�"); addressToProvince.put("娣卞湷", "绮�");
+        addressToProvince.put("涓滆帪", "绮�"); addressToProvince.put("浣涘北", "绮�");
+        addressToProvince.put("鍗椾含", "鑻�"); addressToProvince.put("鑻忓窞", "鑻�");
+        addressToProvince.put("鏃犻敗", "鑻�"); addressToProvince.put("鍗楅��", "鑻�");
+        addressToProvince.put("甯稿窞", "鑻�"); addressToProvince.put("寰愬窞", "鑻�");
+        addressToProvince.put("鏉窞", "娴�"); addressToProvince.put("瀹佹尝", "娴�");
+        addressToProvince.put("娓╁窞", "娴�"); addressToProvince.put("鍢夊叴", "娴�");
+        addressToProvince.put("娴庡崡", "椴�"); addressToProvince.put("闈掑矝", "椴�");
+        addressToProvince.put("閮戝窞", "璞�"); addressToProvince.put("鎴愰兘", "宸�");
+        addressToProvince.put("閲嶅簡", "娓�"); addressToProvince.put("姝︽眽", "閯�");
+        addressToProvince.put("闀挎矙", "婀�"); addressToProvince.put("绂忓窞", "闂�");
+        addressToProvince.put("鍘﹂棬", "闂�"); addressToProvince.put("鍗楁槍", "璧�");
+        addressToProvince.put("鍚堣偉", "鐨�"); addressToProvince.put("鐭冲搴�", "鍐�");
+        addressToProvince.put("娌堥槼", "杈�"); addressToProvince.put("澶ц繛", "杈�");
+        addressToProvince.put("闀挎槬", "鍚�"); addressToProvince.put("鍝堝皵婊�", "榛�");
+        addressToProvince.put("澶師", "鏅�"); addressToProvince.put("瑗垮畨", "闄�");
+        addressToProvince.put("鍗楀畞", "妗�"); addressToProvince.put("鏄嗘槑", "浜�");
+        addressToProvince.put("璐甸槼", "璐�"); addressToProvince.put("鍏板窞", "鐢�");
+        addressToProvince.put("娴峰彛", "鐞�"); addressToProvince.put("閾跺窛", "瀹�");
+        addressToProvince.put("瑗垮畞", "闈�"); addressToProvince.put("鎷夎惃", "钘�");
+        addressToProvince.put("鍛煎拰娴╃壒", "钂�"); addressToProvince.put("涔岄瞾鏈ㄩ綈", "鏂�");
+        addressToProvince.put("澶╂触", "娲�");
+        // 鐪佸悕鏄犲皠
+        addressToProvince.put("姹熻嫃", "鑻�"); addressToProvince.put("娴欐睙", "娴�");
+        addressToProvince.put("灞变笢", "椴�"); addressToProvince.put("娌冲崡", "璞�");
+        addressToProvince.put("鍥涘窛", "宸�"); addressToProvince.put("婀栧寳", "閯�");
+        addressToProvince.put("婀栧崡", "婀�"); addressToProvince.put("绂忓缓", "闂�");
+        addressToProvince.put("姹熻タ", "璧�"); addressToProvince.put("瀹夊窘", "鐨�");
+        addressToProvince.put("娌冲寳", "鍐�"); addressToProvince.put("杈藉畞", "杈�");
+        addressToProvince.put("鍚夋灄", "鍚�"); addressToProvince.put("榛戦緳姹�", "榛�");
+        addressToProvince.put("灞辫タ", "鏅�"); addressToProvince.put("闄曡タ", "闄�");
+        addressToProvince.put("骞夸笢", "绮�"); addressToProvince.put("骞胯タ", "妗�");
+        addressToProvince.put("浜戝崡", "浜�"); addressToProvince.put("璐靛窞", "璐�");
+        addressToProvince.put("鐢樿們", "鐢�"); addressToProvince.put("娴峰崡", "鐞�");
+        addressToProvince.put("瀹佸", "瀹�"); addressToProvince.put("闈掓捣", "闈�");
+        addressToProvince.put("瑗胯棌", "钘�"); addressToProvince.put("鍐呰挋鍙�", "钂�");
+        addressToProvince.put("鏂扮枂", "鏂�");
+
+        String province = "鑻�"; // 榛樿姹熻嫃
+        // 灏濊瘯浠庡鎴峰湴鍧�鎺ㄦ柇鐪佷唤
+        if (customerName != null) {
+            try {
+                Customer customer = customerService.getOne(
+                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Customer>()
+                                .eq(Customer::getCustomerName, customerName)
+                                .last("limit 1"));
+                if (customer != null && customer.getCompanyAddress() != null) {
+                    String addr = customer.getCompanyAddress();
+                    for (Map.Entry<String, String> e : addressToProvince.entrySet()) {
+                        if (addr.contains(e.getKey())) {
+                            province = e.getValue();
+                            break;
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                log.debug("鏌ュ鎴峰湴鍧�澶辫触: {}", e.getMessage());
+            }
+        }
+
+        // 鐢熸垚杞︾墝鍙�: 鐪佷唤绠�绉� + 鍩庡競瀛楁瘝 + 5浣嶉殢鏈哄瓧绗�(鏁板瓧+澶у啓瀛楁瘝)
+        String[] cities = provinceCityMap.getOrDefault(province, new String[]{"A", "B", "C"});
+        String city = cities[ThreadLocalRandom.current().nextInt(cities.length)];
+        String chars = "ABCDEFGHJKLMNPQRSTUVWXYZ0123456789";
+        StringBuilder suffix = new StringBuilder();
+        for (int i = 0; i < 5; i++) {
+            suffix.append(chars.charAt(ThreadLocalRandom.current().nextInt(chars.length())));
+        }
+        return province + city + suffix;
+    }
+
+    private String fixBatchNoDate(String batchNo, String newDate) {
+        if (batchNo == null || batchNo.length() < 8) {
+            return batchNo;
+        }
+        // 鎵瑰彿鏍煎紡: yyyyMMdd-浜у搧缂栫爜-NNN
+        String prefix = batchNo.substring(0, 8);
+        if (prefix.matches("\\d{8}")) {
+            return newDate + batchNo.substring(8);
+        }
+        return batchNo;
+    }
+
+    private ModuleSummary createProductionPlans(List<JSONObject> items) {
+        int success = 0, fail = 0;
+        List<ProductionPlan> createdPlans = new ArrayList<>();
+        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")) {
+                    String dateStr = item.getString("requiredDate");
+                    if (dateStr != null && dateStr.matches("\\d{4}-\\d{2}-\\d{2}")) {
+                        plan.setRequiredDate(LocalDate.parse(dateStr));
+                    }
+                }
+                if (item.containsKey("promisedDeliveryDate")) {
+                    String dateStr = item.getString("promisedDeliveryDate");
+                    if (dateStr != null && dateStr.matches("\\d{4}-\\d{2}-\\d{2}")) {
+                        plan.setPromisedDeliveryDate(LocalDate.parse(dateStr));
+                    }
+                }
+                productionPlanService.save(plan);
+                createdPlans.add(plan);
+                success++;
+            } catch (Exception e) {
+                log.warn("鍒涘缓鐢熶骇璁″垝澶辫触: {}", e.getMessage());
+                fail++;
+            }
+        }
+
+        // 鎸塸roductModelId鍒嗙粍锛岃嚜鍔ㄥ悎骞朵笅鍙�
+        Map<Long, List<ProductionPlan>> grouped = createdPlans.stream()
+                .filter(p -> p.getProductModelId() != null)
+                .collect(Collectors.groupingBy(ProductionPlan::getProductModelId));
+        for (Map.Entry<Long, List<ProductionPlan>> entry : grouped.entrySet()) {
+            try {
+                List<Long> planIds = entry.getValue().stream().map(ProductionPlan::getId).collect(Collectors.toList());
+                BigDecimal totalQty = entry.getValue().stream()
+                        .map(ProductionPlan::getQtyRequired)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+                ProductionPlanDto combineDto = new ProductionPlanDto();
+                combineDto.setIds(planIds);
+                combineDto.setTotalAssignedQuantity(totalQty);
+                combineDto.setPlanCompleteTime(LocalDate.now().plusDays(ThreadLocalRandom.current().nextInt(3, 10)));
+                productionPlanService.combine(combineDto);
+                log.info("鐢熶骇璁″垝鑷姩涓嬪彂鎴愬姛, productModelId={}, 璁″垝鏁�: {}, 涓嬪彂鏁伴噺: {}",
+                        entry.getKey(), planIds.size(), totalQty);
+            } catch (Exception e) {
+                log.warn("鐢熶骇璁″垝鑷姩涓嬪彂澶辫触, productModelId={}: {}", entry.getKey(), e.getMessage());
+            }
+        }
+
+        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")) {
+                    String dateStr = item.getString("planCompleteTime");
+                    if (dateStr != null && dateStr.matches("\\d{4}-\\d{2}-\\d{2}")) {
+                        order.setPlanCompleteTime(LocalDate.parse(dateStr));
+                    }
+                }
+                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;
+    }
+}
diff --git a/src/main/java/com/ruoyi/procurementrecord/bean/dto/ReturnManagementDto.java b/src/main/java/com/ruoyi/procurementrecord/bean/dto/ReturnManagementDto.java
index 539f3c7..98eb5da 100644
--- a/src/main/java/com/ruoyi/procurementrecord/bean/dto/ReturnManagementDto.java
+++ b/src/main/java/com/ruoyi/procurementrecord/bean/dto/ReturnManagementDto.java
@@ -27,6 +27,18 @@
     @Schema(description = "鍏宠仈鍑哄簱鍗曞彿")
     private String shippingNo;
 
+    @Schema(description = "鍙戣揣绫诲瀷")
+    private Integer shippingType;
+
+    @Schema(description = "鍙戣揣杞︾墝鍙�")
+    private String truckPlateNo;
+
+    @Schema(description = "蹇�掑叕鍙�")
+    private String expressCompany;
+
+    @Schema(description = "蹇�掑崟鍙�")
+    private String expressNo;
+
     @Schema(description = "椤圭洰鍚嶇О")
     private String projectName;
 
@@ -36,4 +48,7 @@
     @Schema(description = "閿�鍞骇鍝佸璞℃暟缁�")
     private List<ReturnSaleProductDto> returnSaleProducts;
 
+    @Schema(description = "閿�鍞��璐у叆搴撳鎵圭姸鎬�")
+    private Integer stockInApprovalStatus;
+
 }
diff --git a/src/main/java/com/ruoyi/procurementrecord/bean/dto/ReturnSaleProductDto.java b/src/main/java/com/ruoyi/procurementrecord/bean/dto/ReturnSaleProductDto.java
index 6cfae1b..b24ad14 100644
--- a/src/main/java/com/ruoyi/procurementrecord/bean/dto/ReturnSaleProductDto.java
+++ b/src/main/java/com/ruoyi/procurementrecord/bean/dto/ReturnSaleProductDto.java
@@ -35,4 +35,7 @@
 
     @Schema(description = "鍙戣揣鍑哄簱鏁伴噺")
     private BigDecimal stockOutNum;
+
+    @Schema(description = "寰呭鐞嗛��璐ф暟閲�")
+    private BigDecimal pendingReturnNum;
 }
diff --git a/src/main/java/com/ruoyi/procurementrecord/bean/vo/ShippingProductVo.java b/src/main/java/com/ruoyi/procurementrecord/bean/vo/ShippingProductVo.java
index 9f87aef..760d83f 100644
--- a/src/main/java/com/ruoyi/procurementrecord/bean/vo/ShippingProductVo.java
+++ b/src/main/java/com/ruoyi/procurementrecord/bean/vo/ShippingProductVo.java
@@ -40,4 +40,7 @@
 
     @Schema(description = "鍚◣鍗曚环")
     private BigDecimal taxInclusiveUnitPrice;
+
+    @Schema(description = "寰呭鐞嗛��璐ф暟閲�")
+    private BigDecimal pendingReturnNum;
 }
diff --git a/src/main/java/com/ruoyi/procurementrecord/pojo/ReturnManagement.java b/src/main/java/com/ruoyi/procurementrecord/pojo/ReturnManagement.java
index 046fb5c..5f04de8 100644
--- a/src/main/java/com/ruoyi/procurementrecord/pojo/ReturnManagement.java
+++ b/src/main/java/com/ruoyi/procurementrecord/pojo/ReturnManagement.java
@@ -34,6 +34,18 @@
     @Schema(description = "鍏宠仈鍑哄簱鍗曞彿Id")
     private Long shippingId;
 
+    @Schema(description = "鍙戣揣绫诲瀷 1璐ц溅 2蹇��")
+    private Integer shippingType;
+
+    @Schema(description = "鍙戣揣杞︾墝鍙�")
+    private String truckPlateNo;
+
+    @Schema(description = "蹇�掑叕鍙�")
+    private String expressCompany;
+
+    @Schema(description = "蹇�掑崟鍙�")
+    private String expressNo;
+
     @Schema(description = "椤圭洰id")
     private Long projectId;
 
diff --git a/src/main/java/com/ruoyi/procurementrecord/service/impl/ReturnManagementServiceImpl.java b/src/main/java/com/ruoyi/procurementrecord/service/impl/ReturnManagementServiceImpl.java
index 28bbb43..6420622 100644
--- a/src/main/java/com/ruoyi/procurementrecord/service/impl/ReturnManagementServiceImpl.java
+++ b/src/main/java/com/ruoyi/procurementrecord/service/impl/ReturnManagementServiceImpl.java
@@ -20,7 +20,6 @@
 import com.ruoyi.procurementrecord.service.ReturnManagementService;
 import com.ruoyi.procurementrecord.service.ReturnSaleProductService;
 import com.ruoyi.procurementrecord.utils.StockUtils;
-import com.ruoyi.sales.mapper.SalesLedgerMapper;
 import com.ruoyi.sales.pojo.ShippingInfo;
 import com.ruoyi.sales.service.ShippingInfoService;
 import lombok.RequiredArgsConstructor;
@@ -32,6 +31,7 @@
 
 import java.math.BigDecimal;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * @author :yys
@@ -45,7 +45,6 @@
     private final ReturnManagementMapper returnManagementMapper;
     private final ReturnSaleProductService returnSaleProductService;
     private final ShippingInfoService shippingInfoService;
-    private final SalesLedgerMapper salesLedgerMapper;
     private final SalesRefundAmountOrderService salesRefundAmountOrderService;
     private final StockUtils stockUtils;
 
@@ -100,31 +99,36 @@
     public boolean handle(Long returnManagementId) {
         ReturnManagement byId = this.getById(returnManagementId);
         List<ReturnSaleProductDto> list = returnSaleProductService.listReturnSaleProduct(returnManagementId);
-        byId.setStatus(1);
-        byId.setSettler(SecurityUtils.getLoginUser().getNickName());
-        updateById(byId);
-        SalesRefundAmountOrderDto salesRefundAmountOrder = new SalesRefundAmountOrderDto();
-        salesRefundAmountOrder.setReturnManagementId(returnManagementId);
-        salesRefundAmountOrder.setStatus(0);
-        salesRefundAmountOrder.setCreateTime(byId.getCreateTime());
-        salesRefundAmountOrder.setCreateUserId(SecurityUtils.getUserId());
-        BigDecimal bigDecimal = new BigDecimal(0);
+
+        // 1. 璁$畻姝g‘鐨勯��娆炬�婚锛堥噾棰�=鍗曚环脳鏁伴噺锛�
+        BigDecimal totalRefund = BigDecimal.ZERO;
         for (ReturnSaleProductDto returnSaleProduct : list) {
-            bigDecimal = bigDecimal.add(returnSaleProduct.getPrice());
-            salesRefundAmountOrder.setRefundedAmount(new BigDecimal(0));
+            BigDecimal itemAmount = returnSaleProduct.getAmount() != null
+                    ? returnSaleProduct.getAmount()
+                    : BigDecimal.ZERO;
+            totalRefund = totalRefund.add(itemAmount);
             // 鏄惁鏈夎川閲忛棶棰�
             if (returnSaleProduct.getIsQuality() == 1) {
-                // 鏈夎川閲忛棶棰橈紝鍏ヤ笉鍚堟牸搴�(甯︽壒娆�)
-                stockUtils.addUnStockWithBatchNo(returnSaleProduct.getProductModelId(),returnSaleProduct.getNum(), StockInQualifiedRecordTypeEnum.RETURN_UNSTOCK_IN.getCode(),returnSaleProduct.getId(),returnSaleProduct.getBatchNo());
-            }else{
-                // 鏃犺川閲忛棶棰橈紝鍏ュ悎鏍煎簱(甯︽壒娆�)
-                stockUtils.addStockWithBatchNo(returnSaleProduct.getProductModelId(),returnSaleProduct.getNum(), StockInQualifiedRecordTypeEnum.RETURN_HE_IN.getCode(),returnSaleProduct.getId(),returnSaleProduct.getBatchNo());
+                stockUtils.addUnStockWithBatchNo(returnSaleProduct.getProductModelId(), returnSaleProduct.getNum(), StockInQualifiedRecordTypeEnum.RETURN_UNSTOCK_IN.getCode(), returnSaleProduct.getId(), returnSaleProduct.getBatchNo());
+            } else {
+                stockUtils.addStockWithBatchNo(returnSaleProduct.getProductModelId(), returnSaleProduct.getNum(), StockInQualifiedRecordTypeEnum.RETURN_HE_IN.getCode(), returnSaleProduct.getId(), returnSaleProduct.getBatchNo());
             }
         }
-        salesRefundAmountOrder.setRefundAmount(bigDecimal);
-        salesRefundAmountOrder.setNotRefundedAmount(salesRefundAmountOrder.getRefundedAmount());
-        // 鍒嗘壒閫�娆�
-//        salesRefundAmountOrderService.addSalesRefundAmountOrderDto(salesRefundAmountOrder);
+
+        // 2. 鏇存柊閫�璐у崟鐘舵�佸拰閫�娆炬�婚
+        byId.setStatus(1);
+        byId.setSettler(SecurityUtils.getLoginUser().getNickName());
+        byId.setRefundAmount(totalRefund);
+        updateById(byId);
+        //鏇存柊閫�璐т骇鍝佸垪琛ㄧ殑鐘舵��
+        List<ReturnSaleProduct> updateList = list.stream().map(m -> {
+            ReturnSaleProduct returnSaleProduct = new ReturnSaleProduct();
+            returnSaleProduct.setId(m.getId());
+            returnSaleProduct.setStatus(1);
+            return returnSaleProduct;
+        }).collect(Collectors.toList());
+        returnSaleProductService.updateBatchById(updateList);
+
         return true;
     }
 
diff --git a/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java b/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
index 9b8735f..6c56359 100644
--- a/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
+++ b/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
@@ -20,6 +20,7 @@
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.Collections;
+import java.util.List;
 
 @Component
 @RequiredArgsConstructor
@@ -183,15 +184,25 @@
 
     //鍒犻櫎鍑哄簱璁板綍
     public void deleteStockOutRecord(Long recordId, String recordType) {
-        StockOutRecord one = stockOutRecordService.getOne(new QueryWrapper<StockOutRecord>()
+        List<StockOutRecord> records = stockOutRecordService.list(new QueryWrapper<StockOutRecord>()
                 .lambda().eq(StockOutRecord::getRecordId, recordId)
-                .eq(StockOutRecord::getRecordType, recordType), false);
-        if (ObjectUtils.isNotEmpty(one)) {
-            if (ReviewStatusEnum.APPROVED.getCode().equals(one.getApprovalStatus())) {
-                stockOutRecordService.batchDelete(Collections.singletonList(one.getId()));
-            } else {
-                stockOutRecordService.removeById(one.getId());
-            }
+                .eq(StockOutRecord::getRecordType, recordType));
+        if (ObjectUtils.isEmpty(records)) {
+            return;
+        }
+        List<Long> approvedIds = records.stream()
+                .filter(one -> ReviewStatusEnum.APPROVED.getCode().equals(one.getApprovalStatus()))
+                .map(StockOutRecord::getId)
+                .toList();
+        List<Long> pendingIds = records.stream()
+                .filter(one -> !ReviewStatusEnum.APPROVED.getCode().equals(one.getApprovalStatus()))
+                .map(StockOutRecord::getId)
+                .toList();
+        if (!approvedIds.isEmpty()) {
+            stockOutRecordService.batchDelete(approvedIds);
+        }
+        if (!pendingIds.isEmpty()) {
+            stockOutRecordService.removeByIds(pendingIds);
         }
 
     }
diff --git a/src/main/java/com/ruoyi/production/bean/dto/ProductionPlanImportDto.java b/src/main/java/com/ruoyi/production/bean/dto/ProductionPlanImportDto.java
index 5dd5160..62b50da 100644
--- a/src/main/java/com/ruoyi/production/bean/dto/ProductionPlanImportDto.java
+++ b/src/main/java/com/ruoyi/production/bean/dto/ProductionPlanImportDto.java
@@ -36,10 +36,6 @@
     @Excel(name = "闇�姹傛暟閲�")
     private BigDecimal qtyRequired;
 
-    @Schema(description = "鏉ユ簮 閿�鍞�/鍐呴儴")
-    @Excel(name = "鏉ユ簮 閿�鍞�/鍐呴儴")
-    private String source;
-
     @Schema(description = "鎵胯鏃ユ湡")
     @Excel(name = "鎵胯鏃ユ湡")
     private LocalDate promisedDeliveryDate;
diff --git a/src/main/java/com/ruoyi/production/enums/ProductOrderStatusEnum.java b/src/main/java/com/ruoyi/production/enums/ProductOrderStatusEnum.java
index 5ad55c3..631b2b0 100644
--- a/src/main/java/com/ruoyi/production/enums/ProductOrderStatusEnum.java
+++ b/src/main/java/com/ruoyi/production/enums/ProductOrderStatusEnum.java
@@ -17,7 +17,8 @@
     WAIT(1, "寰呭紑濮�"),
     RUNNING(2, "杩涜涓�"),
     FINISHED(3, "宸插畬鎴�"),
-    CANCEL(4, "宸插彇娑�");
+    //CANCEL(4, "宸插彇娑�"),
+    END(5, "宸茬粨鏉�");
 
     private final Integer code;
     private final String desc;
@@ -43,10 +44,10 @@
     }
 
     /**
-     * 鍒ゆ柇鏄惁鍏佽鍒犻櫎锛�4锛�
+     * 鍒ゆ柇鏄惁鍏佽鍒犻櫎锛�1锛�
      */
     public static boolean canDelete(Integer code) {
-        return WAIT.getCode().equals(code) || CANCEL.getCode().equals(code);
+        return WAIT.getCode().equals(code);
     }
 
     /**
@@ -57,9 +58,9 @@
     }
 
     /**
-     * 鍒ゆ柇鏄惁宸插紑濮嬬敓浜э紙2銆�3锛�
+     * 鍒ゆ柇鏄惁宸插紑濮嬬敓浜э紙2銆�3銆�5锛�
      */
     public static boolean isStarted(Integer code) {
-        return RUNNING.getCode().equals(code) || FINISHED.getCode().equals(code);
+        return RUNNING.getCode().equals(code) || FINISHED.getCode().equals(code) || END.getCode().equals(code);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java
index 0513bdc..8278148 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java
@@ -31,6 +31,7 @@
 import com.ruoyi.technology.pojo.TechnologyOperationParam;
 import com.ruoyi.technology.pojo.TechnologyParam;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -49,6 +50,7 @@
  * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
  * @since 2026-04-21 03:55:52
  */
+@Slf4j
 @Service
 @RequiredArgsConstructor()
 public class ProductionBomStructureServiceImpl extends ServiceImpl<ProductionBomStructureMapper, ProductionBomStructure> implements ProductionBomStructureService {
@@ -137,6 +139,9 @@
             entity.setProductionOrderBomId(orderBomId);
             if (item.getId() == null) {
                 entity.setParentId(null);
+                // 鏂板鑺傜偣鐨勯渶姹傞噺鐢卞悗绔寜BOM鏍戝舰缁撴瀯閲嶆柊璁$畻锛屼笉娓呯┖鍙兘瀵艰嚧鍓嶇浼犵殑鍊兼孩鍑�
+                entity.setDemandedQuantity(null);
+                entity.setId(null);
                 insertList.add(entity);
                 tempEntityMap.put(item.getTempId(), entity);
             } else {
@@ -146,6 +151,11 @@
 
         // 鎵归噺鏂板锛屾嬁鍒版暟鎹簱鐢熸垚鐨勭湡瀹濱D
         if (!insertList.isEmpty()) {
+            for (ProductionBomStructure entity : insertList) {
+                log.info("鍑嗗鏂板BOM缁撴瀯鑺傜偣: productModelId={}, technologyOperationId={}, unitQuantity={}, demandedQuantity={}, unit={}",
+                        entity.getProductModelId(), entity.getTechnologyOperationId(),
+                        entity.getUnitQuantity(), entity.getDemandedQuantity(), entity.getUnit());
+            }
             this.saveBatch(insertList);
         }
 
@@ -216,24 +226,76 @@
         if (structureList == null || structureList.isEmpty()) {
             return;
         }
-        List<ProductionBomStructure> updateList = new ArrayList<>();
-        BigDecimal lastProcessDemandedQuantity = orderQuantity;
+        log.info("寮�濮嬫寜BOM鏍戝舰缁撴瀯璁$畻闇�姹傞噺锛岃鍗曟暟閲�={}, BOM鑺傜偣鎬绘暟={}", orderQuantity, structureList.size());
+        // 鏋勫缓 id 鈫� structure 鏄犲皠鍜� parentId 鈫� children 鏄犲皠
+        Map<Long, ProductionBomStructure> structureById = new HashMap<>();
+        Map<Long, List<ProductionBomStructure>> childrenMap = new LinkedHashMap<>();
         for (ProductionBomStructure structure : structureList) {
             if (structure == null || structure.getId() == null) {
                 continue;
             }
+            structureById.put(structure.getId(), structure);
+            Long parentId = structure.getParentId();
+            childrenMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(structure);
+        }
 
-            BigDecimal demandedQuantity = lastProcessDemandedQuantity.multiply(defaultDecimal(structure.getUnitQuantity()));
-//            if (compareDecimal(structure.getDemandedQuantity(), demandedQuantity) == 0) {
-//                continue;
-//            }
+        List<ProductionBomStructure> updateList = new ArrayList<>();
+        // 浠庢牴鑺傜偣寮�濮嬶紝鎸夋爲褰㈠眰绾ч�愬眰璁$畻闇�姹傞噺
+        // 鏍硅妭鐐� parentId 涓� null 鎴� 0
+        Deque<Long> queue = new ArrayDeque<>();
+        List<ProductionBomStructure> rootNodes = childrenMap.get(null);
+        if (rootNodes != null) {
+            for (ProductionBomStructure root : rootNodes) {
+                queue.add(root.getId());
+            }
+        }
+        // parentId=0 鐨勪篃瑙嗕负鏍硅妭鐐�
+        List<ProductionBomStructure> zeroParentNodes = childrenMap.get(0L);
+        if (zeroParentNodes != null) {
+            for (ProductionBomStructure root : zeroParentNodes) {
+                if (!queue.contains(root.getId())) {
+                    queue.add(root.getId());
+                }
+            }
+        }
+
+        while (!queue.isEmpty()) {
+            Long nodeId = queue.poll();
+            ProductionBomStructure node = structureById.get(nodeId);
+            if (node == null) {
+                continue;
+            }
+            // 璁$畻褰撳墠鑺傜偣鐨勯渶姹傛暟閲� = 鐖惰妭鐐归渶姹傞噺 脳 鑷韩 unitQuantity
+            // 鏍硅妭鐐癸細闇�姹傞噺 = 璁㈠崟鏁伴噺 脳 unitQuantity
+            BigDecimal parentDemandedQuantity = orderQuantity;
+            Long parentId = node.getParentId();
+            if (parentId != null && parentId != 0L) {
+                ProductionBomStructure parent = structureById.get(parentId);
+                if (parent != null && parent.getDemandedQuantity() != null) {
+                    parentDemandedQuantity = parent.getDemandedQuantity();
+                }
+            }
+            BigDecimal demandedQuantity = parentDemandedQuantity.multiply(defaultDecimal(node.getUnitQuantity()));
+
+            log.info("BOM闇�姹傞噺璁$畻: nodeId={}, parentId={}, parentDemandedQuantity={}, unitQuantity={}, demandedQuantity={}",
+                    node.getId(), node.getParentId(), parentDemandedQuantity,
+                    defaultDecimal(node.getUnitQuantity()), demandedQuantity);
+
             ProductionBomStructure update = new ProductionBomStructure();
-            update.setId(structure.getId());
+            update.setId(node.getId());
             update.setDemandedQuantity(demandedQuantity);
             updateList.add(update);
-            structure.setDemandedQuantity(demandedQuantity);
-            lastProcessDemandedQuantity = demandedQuantity;
+            node.setDemandedQuantity(demandedQuantity);
+
+            // 灏嗗瓙鑺傜偣鍔犲叆闃熷垪
+            List<ProductionBomStructure> children = childrenMap.get(nodeId);
+            if (children != null) {
+                for (ProductionBomStructure child : children) {
+                    queue.add(child.getId());
+                }
+            }
         }
+
         if (!updateList.isEmpty()) {
             this.updateBatchById(updateList);
         }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationParamServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationParamServiceImpl.java
index d66ebc7..a792b35 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationParamServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationParamServiceImpl.java
@@ -161,11 +161,21 @@
         // 妫�鏌ユ暟鎹槸鍚﹂噸澶嶏紝閬垮厤閲嶅淇濆瓨
         boolean duplicate = productionOrderRoutingOperationParamMapper.selectCount(
                 Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery()
+                        .eq(ProductionOrderRoutingOperationParam::getProductionOrderId, item.getProductionOrderId())
                         .isNull(ProductionOrderRoutingOperationParam::getProductionProductMainId)
                         .eq(ProductionOrderRoutingOperationParam::getProductionOrderRoutingOperationId, item.getProductionOrderRoutingOperationId())
                         .eq(item.getTechnologyRoutingOperationParamId() != null,
                                 ProductionOrderRoutingOperationParam::getTechnologyRoutingOperationParamId, item.getTechnologyRoutingOperationParamId())
-                        .eq(item.getTechnologyRoutingOperationParamId() == null && item.getParamCode() != null,
+                        .eq(item.getTechnologyRoutingOperationParamId() == null && item.getTechnologyOperationParamId() != null,
+                                ProductionOrderRoutingOperationParam::getTechnologyOperationParamId, item.getTechnologyOperationParamId())
+                        .eq(item.getTechnologyRoutingOperationParamId() == null
+                                        && item.getTechnologyOperationParamId() == null
+                                        && item.getParamId() != null,
+                                ProductionOrderRoutingOperationParam::getParamId, item.getParamId())
+                        .eq(item.getTechnologyRoutingOperationParamId() == null
+                                        && item.getTechnologyOperationParamId() == null
+                                        && item.getParamId() == null
+                                        && item.getParamCode() != null,
                                 ProductionOrderRoutingOperationParam::getParamCode, item.getParamCode())
                         .ne(item.getId() != null, ProductionOrderRoutingOperationParam::getId, item.getId())
         ) > 0;
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
index 5c103b8..95c7344 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
@@ -439,9 +439,54 @@
         productionOrderBomMapper.insert(orderBom);
 
         Map<Long, Long> idMap = new HashMap<>();
-        BigDecimal lastProcessDemandedQuantity = orderQuantity;
+        // 鏋勫缓 sourceId 鈫� sourceNode 鏄犲皠 鍜� parentId 鈫� children 鏄犲皠
+        Map<Long, TechnologyBomStructure> sourceById = new HashMap<>();
+        Map<Long, List<TechnologyBomStructure>> childrenMap = new LinkedHashMap<>();
         for (TechnologyBomStructure source : structureList) {
-            // 瀛愯妭鐐� parentId 闇�瑕佹槧灏勬垚鏂板揩鐓ц妭鐐� id锛屾墠鑳戒繚鐣欏師濮� BOM 灞傜骇銆�
+            if (source == null || source.getId() == null) {
+                continue;
+            }
+            sourceById.put(source.getId(), source);
+            Long parentId = source.getParentId();
+            childrenMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(source);
+        }
+
+        // BFS 浠庢牴鑺傜偣寮�濮嬶紝鐖惰妭鐐瑰厛浜庡瓙鑺傜偣澶勭悊
+        Deque<TechnologyBomStructure> queue = new ArrayDeque<>();
+        List<TechnologyBomStructure> rootNodes = childrenMap.get(null);
+        if (rootNodes != null) {
+            queue.addAll(rootNodes);
+        }
+        // parentId=0 鐨勪篃瑙嗕负鏍硅妭鐐�
+        List<TechnologyBomStructure> zeroParentNodes = childrenMap.get(0L);
+        if (zeroParentNodes != null) {
+            for (TechnologyBomStructure node : zeroParentNodes) {
+                if (!queue.contains(node)) {
+                    queue.add(node);
+                }
+            }
+        }
+
+        while (!queue.isEmpty()) {
+            TechnologyBomStructure source = queue.poll();
+            if (source == null || source.getId() == null) {
+                continue;
+            }
+            // 璁$畻闇�姹傞噺 = 鐖惰妭鐐归渶姹傞噺 脳 鑷韩 unitQuantity
+            BigDecimal parentDemandedQuantity = orderQuantity;
+            Long sourceParentId = source.getParentId();
+            if (sourceParentId != null && sourceParentId != 0L) {
+                Long parentTargetId = idMap.get(sourceParentId);
+                if (parentTargetId != null) {
+                    // 鐖惰妭鐐瑰凡缁忔彃鍏ワ紝鐢ㄧ埗鑺傜偣鐨� targetId 浠庡凡鎻掑叆鍒楄〃鎵�
+                    // 杩欓噷鎴戜滑鐩存帴鐢ㄥ瓨涓嬫潵鐨勭埗鑺傜偣闇�姹傞噺
+                    TechnologyBomStructure parentSource = sourceById.get(sourceParentId);
+                    if (parentSource != null && parentSource.getDemandedQuantity() != null) {
+                        parentDemandedQuantity = parentSource.getDemandedQuantity();
+                    }
+                }
+            }
+
             ProductionBomStructure target = new ProductionBomStructure();
             target.setProductionOrderId(productionOrder.getId());
             target.setProductionOrderBomId(orderBom.getId());
@@ -449,11 +494,20 @@
             target.setProductModelId(source.getProductModelId());
             target.setTechnologyOperationId(source.getOperationId());
             target.setUnitQuantity(source.getUnitQuantity());
-            target.setDemandedQuantity(lastProcessDemandedQuantity.multiply(source.getUnitQuantity()));
+            target.setDemandedQuantity(parentDemandedQuantity.multiply(defaultDecimal(source.getUnitQuantity())));
             target.setUnit(source.getUnit());
             productionBomStructureMapper.insert(target);
             idMap.put(source.getId(), target.getId());
-            lastProcessDemandedQuantity = target.getDemandedQuantity();
+            // 灏嗗綋鍓嶈妭鐐圭殑 demandedQuantity 鍥炲啓鍒� source 瀵硅薄涓婏紝渚涘瓙鑺傜偣璁$畻浣跨敤
+            source.setDemandedQuantity(target.getDemandedQuantity());
+
+            // 灏嗗瓙鑺傜偣鍔犲叆闃熷垪
+            List<TechnologyBomStructure> children = childrenMap.get(source.getId());
+            if (children != null) {
+                for (TechnologyBomStructure child : children) {
+                    queue.add(child);
+                }
+            }
         }
         return orderBom;
     }
@@ -1134,7 +1188,7 @@
     @Override
     public int updateOrder(ProductionOrderDto productionOrderDto) {
         // 鏇存柊鐢熶骇璁㈠崟涓绘暟鎹�
-        productionOrderDto.setStatus(5);
+        productionOrderDto.setStatus(ProductOrderStatusEnum.END.getCode());
         return baseMapper.updateById(productionOrderDto);
     }
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionPlanServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionPlanServiceImpl.java
index b00266b..53b1ee9 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionPlanServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionPlanServiceImpl.java
@@ -311,7 +311,7 @@
             BeanUtils.copyProperties(dto, entity);
             entity.setProductModelId(resolveProductModelId(dto, i + 2, allModels, productNameById));
             entity.setStatus(PLAN_STATUS_WAIT);
-            entity.setSource(StringUtils.isNotEmpty(dto.getSource()) ? StringUtils.trim(dto.getSource()) : "鍐呴儴");
+            entity.setSource("鍐呴儴");
             entity.setQuantityIssued(BigDecimal.ZERO);
             entity.setCreateTime(now);
             entity.setUpdateTime(now);
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
index c52892a..4a8366a 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -378,8 +378,10 @@
             if (ObjectUtils.isNull(productionOrder.getStartTime())) {
                 productionOrder.setStartTime(LocalDateTime.now());
             }
-            // 璁㈠崟鐘舵�佺敱鏈�鍚庝竴閬撳伐搴忕殑鍚堟牸浜у嚭鎺ㄥ姩锛岄伩鍏嶄腑闂村伐搴忔彁鍓嶅畬宸ャ��
-            productionOrder.setStatus(ProductOrderStatusEnum.RUNNING.getCode());
+            // 浠呭緟寮�濮嬬姸鎬佹墠鎺ㄨ繘鍒拌繘琛屼腑锛岄伩鍏嶉潪鏈亾宸ュ簭鎶ュ伐鏃惰鐩栧凡瀹屾垚鐘舵�併��
+            if (ProductOrderStatusEnum.WAIT.getCode().equals(productionOrder.getStatus())) {
+                productionOrder.setStatus(ProductOrderStatusEnum.RUNNING.getCode());
+            }
             if (isLastOperation) {
                 productionOrder.setCompleteQuantity(defaultDecimal(productionOrder.getCompleteQuantity()).add(productQty));
                 if (productionOrder.getQuantity() != null
diff --git a/src/main/java/com/ruoyi/project/system/domain/SysUser.java b/src/main/java/com/ruoyi/project/system/domain/SysUser.java
index 515210e..39050e5 100644
--- a/src/main/java/com/ruoyi/project/system/domain/SysUser.java
+++ b/src/main/java/com/ruoyi/project/system/domain/SysUser.java
@@ -1,8 +1,8 @@
 package com.ruoyi.project.system.domain;
 
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.ruoyi.common.xss.Xss;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.ruoyi.common.xss.Xss;
 import com.ruoyi.framework.aspectj.lang.annotation.Excel;
 import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
 import com.ruoyi.framework.aspectj.lang.annotation.Excel.Type;
@@ -60,13 +60,13 @@
     @Excel(name = "璐﹀彿鐘舵��", readConverterExp = "0=姝e父,1=鍋滅敤")
     private String status;
 
-    /** 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛� */
-    private String delFlag;
-
-    /** 鏄惁寮�閫欰I鍔熻兘锛�0鍚� 1鏄級 */
-    @JsonIgnore
-    private Integer aiEnabled;
-
+    /** 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛� */
+    private String delFlag;
+
+    /** 鏄惁寮�閫欰I鍔熻兘锛�0鍚� 1鏄級 */
+    @JsonIgnore
+    private Integer aiEnabled;
+
     /** 鏈�鍚庣櫥褰旾P */
     @Excel(name = "鏈�鍚庣櫥褰旾P", type = Type.EXPORT)
     private String loginIp;
@@ -128,6 +128,12 @@
      */
     @TableField(exist = false)
     private String deptNames;
+
+    /**
+     * 瑙掕壊鍚嶇О
+     */
+    @TableField(exist = false)
+    private String roleNames;
 
     public Long getCurrentDeptId() {
         return currentDeptId;
@@ -255,25 +261,25 @@
         this.status = status;
     }
 
-    public String getDelFlag()
-    {
-        return delFlag;
-    }
+    public String getDelFlag()
+    {
+        return delFlag;
+    }
 
-    public void setDelFlag(String delFlag)
-    {
-        this.delFlag = delFlag;
-    }
-
-    public Integer getAiEnabled()
-    {
-        return aiEnabled;
-    }
-
-    public void setAiEnabled(Integer aiEnabled)
-    {
-        this.aiEnabled = aiEnabled;
-    }
+    public void setDelFlag(String delFlag)
+    {
+        this.delFlag = delFlag;
+    }
+
+    public Integer getAiEnabled()
+    {
+        return aiEnabled;
+    }
+
+    public void setAiEnabled(Integer aiEnabled)
+    {
+        this.aiEnabled = aiEnabled;
+    }
 
     public String getLoginIp()
     {
@@ -369,6 +375,14 @@
         this.deptNames = deptNames;
     }
 
+    public String getRoleNames() {
+        return roleNames;
+    }
+
+    public void setRoleNames(String roleNames) {
+        this.roleNames = roleNames;
+    }
+
     public Long getDeptId() {
         return deptId;
     }
@@ -388,10 +402,10 @@
             .append("sex", getSex())
             .append("avatar", getAvatar())
             .append("password", getPassword())
-            .append("status", getStatus())
-            .append("delFlag", getDelFlag())
-            .append("aiEnabled", getAiEnabled())
-            .append("loginIp", getLoginIp())
+            .append("status", getStatus())
+            .append("delFlag", getDelFlag())
+            .append("aiEnabled", getAiEnabled())
+            .append("loginIp", getLoginIp())
             .append("loginDate", getLoginDate())
             .append("createBy", getCreateBy())
             .append("createTime", getCreateTime())
diff --git a/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java b/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java
index 5507b3f..ccabf71 100644
--- a/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java
+++ b/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java
@@ -155,5 +155,10 @@
 
     List<Long> getUserByRole(@Param("role") String role);
 
+    /**
+     * 鏌ヨ鎵�鏈夋椿璺冪敤鎴凤紙鍚儴闂ㄥ悕绉板拰瑙掕壊鍚嶇О锛�
+     */
+    List<SysUser> selectUserListWithDetail();
+
     List<Long> getUserByPerms(@Param("perms") List<String> perms);
 }
diff --git a/src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java b/src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java
index 58216c1..3b20e8f 100644
--- a/src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java
+++ b/src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java
@@ -118,6 +118,16 @@
     }
 
     /**
+     * 鏌ヨ閲囪喘閫�璐у彲閫夐噰璐彴璐�
+     */
+    @GetMapping("/returnableList")
+    public TableDataInfo returnableList(PurchaseLedger purchaseLedger) {
+        startPage();
+        List<PurchaseLedger> list = purchaseLedgerService.selectReturnablePurchaseLedgerList(purchaseLedger);
+        return getDataTable(list);
+    }
+
+    /**
      * 瀵煎嚭閲囪喘鍙拌处鍒楄〃
      */
     @Log(title = "閲囪喘鍙拌处", businessType = BusinessType.EXPORT)
diff --git a/src/main/java/com/ruoyi/purchase/controller/PurchaseReturnOrdersController.java b/src/main/java/com/ruoyi/purchase/controller/PurchaseReturnOrdersController.java
index 6e73ee1..579d62d 100644
--- a/src/main/java/com/ruoyi/purchase/controller/PurchaseReturnOrdersController.java
+++ b/src/main/java/com/ruoyi/purchase/controller/PurchaseReturnOrdersController.java
@@ -13,6 +13,8 @@
 import com.ruoyi.purchase.dto.PurchaseReturnOrderDto;
 import com.ruoyi.purchase.mapper.PurchaseReturnOrdersMapper;
 import com.ruoyi.purchase.pojo.PurchaseReturnOrders;
+import com.ruoyi.stock.mapper.StockOutRecordMapper;
+import com.ruoyi.stock.pojo.StockOutRecord;
 
 import java.time.LocalDateTime;
 import com.ruoyi.purchase.service.PurchaseReturnOrdersService;
@@ -40,6 +42,7 @@
     private PurchaseReturnOrdersService purchaseReturnOrdersService;
     private PurchaseReturnOrdersMapper purchaseReturnOrdersMapper;
     private AccountStatementDetailsService accountStatementDetailsService;
+    private StockOutRecordMapper stockOutRecordMapper;
 
 
     @GetMapping("/listPage")
@@ -72,6 +75,13 @@
         if (CollectionUtils.isNotEmpty(accountStatementDetails)){
             throw new ServiceException("璇ラ噰璐��璐у崟宸茬粡鐢熸垚瀵硅处鍗曪紝鏃犳硶鍒犻櫎");
         }
+        List<StockOutRecord> approvedStockOutRecords = stockOutRecordMapper.selectList(Wrappers.<StockOutRecord>lambdaQuery()
+                .eq(StockOutRecord::getRecordType, "9")
+                .eq(StockOutRecord::getApprovalStatus, 1)
+                .inSql(StockOutRecord::getRecordId, "select id from purchase_return_order_products where purchase_return_order_id = " + id));
+        if (CollectionUtils.isNotEmpty(approvedStockOutRecords)) {
+            throw new ServiceException("璇ラ噰璐��璐у崟瀵瑰簲鍑哄簱宸插鏍搁�氳繃锛屾棤娉曞垹闄�");
+        }
         purchaseReturnOrdersService.deleteById(id);
         return AjaxResult.success();
     }
diff --git a/src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java b/src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java
index cbca6f7..ee089a5 100644
--- a/src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java
+++ b/src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java
@@ -33,6 +33,11 @@
     private Long id;
 
     /**
+     * 瀹℃壒瀹炰緥ID
+     */
+    private Long approvalInstanceId;
+
+    /**
      * 閲囪喘鍚堝悓鍙�
      */
     @Excel(name = "閲囪喘鍚堝悓鍙�")
@@ -88,7 +93,7 @@
     /**
      * 褰曞叆鏃ユ湡
      */
-    @JsonFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     @Excel(name = "褰曞叆鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd")
     private Date entryDate;
 
@@ -175,6 +180,12 @@
     @Excel(name = "鍚堝悓閲戦")
     private BigDecimal contractAmount = BigDecimal.ZERO;
 
+    /**
+     * 瀹為檯鍚堝悓閲戦锛堟墸鍑忛��璐у悗锛�
+     */
+    @Schema(description = "瀹為檯鍚堝悓閲戦")
+    private BigDecimal netContractAmount = BigDecimal.ZERO;
+
 
     @Schema(description = "鏂囦欢绫诲瀷  鍙� 4")
     @TableField(exist = false)
diff --git a/src/main/java/com/ruoyi/purchase/dto/PurchaseReturnOrderHasAllInfoDto.java b/src/main/java/com/ruoyi/purchase/dto/PurchaseReturnOrderHasAllInfoDto.java
index 68ef597..67c98dd 100644
--- a/src/main/java/com/ruoyi/purchase/dto/PurchaseReturnOrderHasAllInfoDto.java
+++ b/src/main/java/com/ruoyi/purchase/dto/PurchaseReturnOrderHasAllInfoDto.java
@@ -15,6 +15,13 @@
     // 閲囪喘鍚堝悓鍙�
     private String purchaseContractNumber;
 
+    private String shippingTypeText;
+
+    /**
+     * 瀵瑰簲鍑哄簱鏄惁宸插鏍搁�氳繃
+     */
+    private Boolean stockOutApproved;
+
     //閫�鏂欎汉濮撳悕
     private String returnUserName;
 
diff --git a/src/main/java/com/ruoyi/purchase/mapper/PurchaseLedgerMapper.java b/src/main/java/com/ruoyi/purchase/mapper/PurchaseLedgerMapper.java
index 8d5ab54..feba849 100644
--- a/src/main/java/com/ruoyi/purchase/mapper/PurchaseLedgerMapper.java
+++ b/src/main/java/com/ruoyi/purchase/mapper/PurchaseLedgerMapper.java
@@ -23,6 +23,8 @@
 
     IPage<PurchaseLedgerDto> selectPurchaseLedgerListPage(IPage ipage, @Param("c") PurchaseLedgerDto purchaseLedger);
 
+    List<PurchaseLedger> selectReturnablePurchaseLedgerList(@Param("c") PurchaseLedger purchaseLedger);
+
     List<IncomeExpenseAnalysisDto> selectPurchaseStats(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("dateFormat") String dateFormat);
 
     BigDecimal selectTotalPurchaseAmount(@Param("startDate") String startDate, @Param("endDate") String endDate);
diff --git a/src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java b/src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java
index e7ec1eb..ec96643 100644
--- a/src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java
+++ b/src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java
@@ -69,7 +69,7 @@
     /**
      * 褰曞叆鏃ユ湡
      */
-    @JsonFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     @Excel(name = "褰曞叆鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd")
     private Date entryDate;
 
@@ -119,6 +119,12 @@
      * 鍚堝悓閲戦锛堜骇鍝佸惈绋庢�讳环锛�
      */
     private BigDecimal contractAmount;
+
+    /**
+     * 瀹為檯鍚堝悓閲戦锛堟墸鍑忛��璐у悗锛�
+     */
+    @Schema(description = "瀹為檯鍚堝悓閲戦")
+    private BigDecimal netContractAmount;
 //
 //    /**
 //     * 涓氬姟鍛�
diff --git a/src/main/java/com/ruoyi/purchase/pojo/PurchaseReturnOrders.java b/src/main/java/com/ruoyi/purchase/pojo/PurchaseReturnOrders.java
index 936b5b5..abe0b8a 100644
--- a/src/main/java/com/ruoyi/purchase/pojo/PurchaseReturnOrders.java
+++ b/src/main/java/com/ruoyi/purchase/pojo/PurchaseReturnOrders.java
@@ -44,6 +44,18 @@
     @Schema(description = "渚涘簲鍟唅d")
     private Long supplierId;
 
+    @Schema(description = "鍙戣揣绫诲瀷 1璐ц溅 2蹇��")
+    private Integer shippingType;
+
+    @Schema(description = "鍙戣揣杞︾墝鍙�")
+    private String truckPlateNo;
+
+    @Schema(description = "蹇�掑叕鍙�")
+    private String expressCompany;
+
+    @Schema(description = "蹇�掑崟鍙�")
+    private String expressNo;
+
     @Schema(description = "椤圭洰id")
     private Long projectId;
 
diff --git a/src/main/java/com/ruoyi/purchase/service/IPurchaseLedgerService.java b/src/main/java/com/ruoyi/purchase/service/IPurchaseLedgerService.java
index 4b91b89..78e86a1 100644
--- a/src/main/java/com/ruoyi/purchase/service/IPurchaseLedgerService.java
+++ b/src/main/java/com/ruoyi/purchase/service/IPurchaseLedgerService.java
@@ -23,6 +23,8 @@
 
     List<PurchaseLedger> selectPurchaseLedgerList(PurchaseLedger purchaseLedger);
 
+    List<PurchaseLedger> selectReturnablePurchaseLedgerList(PurchaseLedger purchaseLedger);
+
     int addOrEditPurchase(PurchaseLedgerDto purchaseLedgerDto) throws Exception;
 
     R batchInsertPurchaseSteps(List<Long> ids);
diff --git a/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
index 7a70435..7c25815 100644
--- a/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -6,6 +6,7 @@
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.alibaba.fastjson2.JSON;
 import com.ruoyi.approve.bean.dto.ApprovalInstanceDto;
 import com.ruoyi.approve.mapper.ApprovalTemplateMapper;
 import com.ruoyi.approve.pojo.ApprovalInstance;
@@ -22,10 +23,11 @@
 import com.ruoyi.basic.pojo.ProductModel;
 import com.ruoyi.basic.pojo.SupplierManage;
 import com.ruoyi.basic.utils.FileUtil;
-import com.ruoyi.common.exception.base.BaseException;
 import com.ruoyi.common.enums.ApprovalStatusEnum;
 import com.ruoyi.common.enums.ReviewStatusEnum;
 import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
+import com.ruoyi.common.enums.TypeEnums;
+import com.ruoyi.common.exception.base.BaseException;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
@@ -129,7 +131,15 @@
         if (purchaseLedger.getApprovalStatus() != null) {
             queryWrapper.eq(PurchaseLedger::getApprovalStatus, purchaseLedger.getApprovalStatus());
         }
+        // 鍙煡璇㈠叆搴撳凡瀹℃壒閫氳繃鐨勯噰璐彴璐�
+        queryWrapper.inSql(PurchaseLedger::getId,
+                "SELECT DISTINCT record_id FROM stock_in_record WHERE approval_status = 1");
         return purchaseLedgerMapper.selectList(queryWrapper);
+    }
+
+    @Override
+    public List<PurchaseLedger> selectReturnablePurchaseLedgerList(PurchaseLedger purchaseLedger) {
+        return purchaseLedgerMapper.selectReturnablePurchaseLedgerList(purchaseLedger);
     }
 
     @Override
@@ -162,21 +172,13 @@
         purchaseLedger.setRecorderId(purchaseLedgerDto.getRecorderId());
 
         purchaseLedger.setApprovalStatus(1);
+        // 瀹為檯鍚堝悓閲戦濮嬬粓绛変簬鍚堝悓閲戦
+        purchaseLedger.setNetContractAmount(purchaseLedger.getContractAmount());
         // 3. 鏂板鎴栨洿鏂颁富琛�
-        if (purchaseLedger.getId() == null) {
-            purchaseLedgerMapper.insert(purchaseLedger);
-        } else {
-            // 鍒犻櫎閲囪喘瀹℃牳锛岄噸鏂版彁浜�
-            ApproveProcess one = approveProcessService.getOne(new LambdaQueryWrapper<ApproveProcess>()
-                    .eq(ApproveProcess::getApproveType, 5)
-                    .eq(ApproveProcess::getApproveReason, purchaseLedger.getPurchaseContractNumber())
-                    .eq(ApproveProcess::getApproveDelete, 0)
-                    .last("limit 1"));
-            if (one != null) {
-                approveProcessService.delByIds(Collections.singletonList(one.getId()));
-            }
-            purchaseLedgerMapper.updateById(purchaseLedger);
+        if (purchaseLedger.getId() == null && !StringUtils.hasText(purchaseLedger.getPurchaseContractNumber())) {
+            purchaseLedger.setPurchaseContractNumber(generatePurchaseContractNo(purchaseLedger.getEntryDate()));
         }
+        this.saveOrUpdate(purchaseLedger);
 
         // 4. 澶勭悊瀛愯〃鏁版嵁
         List<SalesLedgerProduct> productList = purchaseLedgerDto.getProductData();
@@ -184,7 +186,17 @@
             handleSalesLedgerProducts(purchaseLedger.getId(), productList, purchaseLedgerDto.getType());
         }
         // 6.閲囪喘瀹℃牳鏂板锛涘鎵圭鐞嗘湭閰嶇疆閲囪喘瀹℃壒浜烘椂锛屽鎵规湇鍔′細鑷姩缃负瀹℃壒閫氳繃銆�
-        addApproveByPurchase(loginUser, purchaseLedger);
+        //鏌ヨ褰撳墠閲囪喘鍚堝悓鍙锋槸鍚﹀凡娣诲姞瀹℃壒锛屽鏋滄湁涓斾笉鏄┏鍥炵姸鎬侊紝鍒欎笉閲嶅娣诲姞
+        ApprovalInstance oldApprovalInstance = approvalInstanceService.getOne(Wrappers.<ApprovalInstance>lambdaQuery()
+                .eq(ApprovalInstance::getDeleted, 0)
+                .eq(ApprovalInstance::getBusinessType, TypeEnums.PURCHASE_APPROVAL.getCode())
+                .eq(ApprovalInstance::getBusinessId, purchaseLedger.getId())
+                .ne(ApprovalInstance::getStatus,"REJECTED")
+                .last("limit 1")
+        );
+        if(Objects.isNull(oldApprovalInstance)){
+            addApproveByPurchase(loginUser, purchaseLedger, productList);
+        }
         // 5. 杩佺Щ涓存椂鏂囦欢鍒版寮忕洰褰�
         fileUtil.saveStorageAttachment(ApplicationTypeEnum.FILE, RecordTypeEnum.PURCHASE_LEDGER, purchaseLedger.getId(), purchaseLedgerDto.getStorageBlobDTOS());
         return 1;
@@ -751,13 +763,30 @@
         for (Long id : ids) {
             PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(id);
             if(purchaseLedger != null){
-                ApproveProcess one = approveProcessService.getOne(new LambdaQueryWrapper<ApproveProcess>()
+                List<ApprovalInstance> approvalInstances = approvalInstanceService.list(new LambdaQueryWrapper<ApprovalInstance>()
+                        .eq(ApprovalInstance::getBusinessId, purchaseLedger.getId())
+                        .eq(ApprovalInstance::getBusinessType, 5L)
+                        .eq(ApprovalInstance::getDeleted, 0));
+                if (CollectionUtils.isNotEmpty(approvalInstances)) {
+                    approvalInstanceService.delete(
+                            approvalInstances.stream()
+                                    .map(ApprovalInstance::getId)
+                                    .filter(Objects::nonNull)
+                                    .collect(Collectors.toList())
+                    );
+                }
+
+                List<ApproveProcess> approveProcesses = approveProcessService.list(new LambdaQueryWrapper<ApproveProcess>()
                         .eq(ApproveProcess::getApproveType, 5)
                         .eq(ApproveProcess::getApproveDelete, 0)
-                        .eq(ApproveProcess::getApproveReason, purchaseLedger.getPurchaseContractNumber())
-                        .last("limit 1"));
-                if (one != null) {
-                    approveProcessService.delByIds(Collections.singletonList(one.getId()));
+                        .eq(ApproveProcess::getApproveReason, purchaseLedger.getPurchaseContractNumber()));
+                if (CollectionUtils.isNotEmpty(approveProcesses)) {
+                    approveProcessService.delByIds(
+                            approveProcesses.stream()
+                                    .map(ApproveProcess::getId)
+                                    .filter(Objects::nonNull)
+                                    .collect(Collectors.toList())
+                    );
                 }
             }
         }
@@ -938,6 +967,7 @@
                 salesLedger.setContractAmount(salesLedgerProductImportDtos.stream()
                         .map(PurchaseLedgerProductImportDto::getTaxInclusiveTotalPrice)
                         .reduce(BigDecimal.ZERO,BigDecimal::add));
+                salesLedger.setNetContractAmount(salesLedger.getContractAmount());
                 // 閫氳繃閿�鍞崟鍙风粦瀹氶攢鍞�
                 SalesLedger salesLedger1 = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>()
                         .eq(SalesLedger::getSalesContractNo, salesLedger.getSalesContractNo())
@@ -987,7 +1017,12 @@
                     salesLedgerProductMapper.insert(salesLedgerProduct);
                 }
                 // 閲囪喘瀹℃牳
-                addApproveByPurchase(loginUser,salesLedger);
+                List<SalesLedgerProduct> snapshotProducts = salesLedgerProductMapper.selectList(
+                        new LambdaQueryWrapper<SalesLedgerProduct>()
+                                .eq(SalesLedgerProduct::getSalesLedgerId, salesLedger.getId())
+                                .eq(SalesLedgerProduct::getType, 2)
+                );
+                addApproveByPurchase(loginUser, salesLedger, snapshotProducts);
             }
 
             return AjaxResult.success("瀵煎叆鎴愬姛");
@@ -999,21 +1034,91 @@
 
     @Override
     public PurchaseLedgerDto getPurchaseByCode(PurchaseLedgerDto purchaseLedgerDto) {
-        // 1. 鏌ヨ涓昏〃
-        PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectOne(new LambdaQueryWrapper<PurchaseLedger>()
-                .eq(PurchaseLedger::getPurchaseContractNumber, purchaseLedgerDto.getPurchaseContractNumber())
-                .last("LIMIT 1"));
-        if (purchaseLedger == null) {
-            throw new BaseException("閲囪喘鍙拌处涓嶅瓨鍦�");
+        PurchaseLedger purchaseLedger = null;
+        ApprovalInstance approvalSnapshotInstance = null;
+
+        // 1. 浼樺厛鎸夊綋鍓嶅鎵瑰疄渚嬫煡璇㈠揩鐓�
+        if (purchaseLedgerDto.getApprovalInstanceId() != null) {
+            approvalSnapshotInstance = approvalInstanceService.getById(purchaseLedgerDto.getApprovalInstanceId());
+            if (approvalSnapshotInstance != null && approvalSnapshotInstance.getBusinessId() != null) {
+                purchaseLedger = purchaseLedgerMapper.selectById(approvalSnapshotInstance.getBusinessId());
+            }
         }
 
-        // 2. 鏌ヨ瀛愯〃
+        // 2. 娌′紶瀹℃壒瀹炰緥ID鏃讹紝閫�鍥炲埌鎸夐噰璐悎鍚屽彿鏌ヨ
+        if (purchaseLedger == null) {
+            purchaseLedger = purchaseLedgerMapper.selectOne(new LambdaQueryWrapper<PurchaseLedger>()
+                    .eq(PurchaseLedger::getPurchaseContractNumber, purchaseLedgerDto.getPurchaseContractNumber())
+                    .last("LIMIT 1"));
+            if (purchaseLedger == null) {
+                throw new BaseException("閲囪喘鍙拌处涓嶅瓨鍦�");
+            }
+        }
+
+        // 3. 鏌ヨ褰撳墠閲囪喘鍗曞搴旂殑瀹℃壒蹇収
+        if (approvalSnapshotInstance == null) {
+            approvalSnapshotInstance = approvalInstanceService.getOne(new LambdaQueryWrapper<ApprovalInstance>()
+                    .eq(ApprovalInstance::getBusinessId, purchaseLedger.getId())
+                    .eq(ApprovalInstance::getBusinessType, 5L)
+                    .eq(ApprovalInstance::getDeleted, 0)
+                    .orderByDesc(ApprovalInstance::getId)
+                    .last("LIMIT 1"));
+        }
+
+        if (approvalSnapshotInstance != null && StringUtils.hasText(approvalSnapshotInstance.getFormConfig())) {
+            try {
+                PurchaseLedgerDto snapshot = JSON.parseObject(approvalSnapshotInstance.getFormConfig(), PurchaseLedgerDto.class);
+                if (snapshot != null) {
+                    snapshot.setId(purchaseLedger.getId());
+                    if (snapshot.getPurchaseContractNumber() == null) {
+                        snapshot.setPurchaseContractNumber(purchaseLedger.getPurchaseContractNumber());
+                    }
+                    if (snapshot.getSupplierId() == null) {
+                        snapshot.setSupplierId(purchaseLedger.getSupplierId());
+                    }
+                    if (snapshot.getSupplierName() == null) {
+                        snapshot.setSupplierName(purchaseLedger.getSupplierName());
+                    }
+                    if (snapshot.getSalesContractNo() == null) {
+                        snapshot.setSalesContractNo(purchaseLedger.getSalesContractNo());
+                    }
+                    if (snapshot.getSalesContractNoId() == null) {
+                        snapshot.setSalesContractNoId(purchaseLedger.getSalesLedgerId());
+                    }
+                    if (snapshot.getProjectName() == null) {
+                        snapshot.setProjectName(purchaseLedger.getProjectName());
+                    }
+                    if (snapshot.getEntryDate() == null) {
+                        snapshot.setEntryDate(purchaseLedger.getEntryDate());
+                    }
+                    if (snapshot.getExecutionDate() == null) {
+                        snapshot.setExecutionDate(purchaseLedger.getExecutionDate());
+                    }
+                    if (snapshot.getRemarks() == null) {
+                        snapshot.setRemarks(purchaseLedger.getRemarks());
+                    }
+                    if (snapshot.getRecorderId() == null) {
+                        snapshot.setRecorderId(purchaseLedger.getRecorderId());
+                    }
+                    if (snapshot.getRecorderName() == null) {
+                        snapshot.setRecorderName(purchaseLedger.getRecorderName());
+                    }
+                    snapshot.setProductData(snapshot.getProductData() == null ? Collections.emptyList() : snapshot.getProductData());
+                    snapshot.setHasChildren(CollectionUtils.isNotEmpty(snapshot.getProductData()));
+                    return snapshot;
+                }
+            } catch (Exception e) {
+                log.warn("瑙f瀽閲囪喘瀹℃壒蹇収澶辫触: {}", e.getMessage());
+            }
+        }
+
+        // 4. 鏌ヨ瀛愯〃
         LambdaQueryWrapper<SalesLedgerProduct> productWrapper = new LambdaQueryWrapper<>();
         productWrapper.eq(SalesLedgerProduct::getSalesLedgerId, purchaseLedger.getId())
                 .eq(SalesLedgerProduct::getType, 2);
         List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(productWrapper);
 
-        // 4. 杞崲 DTO
+        // 5. 杞崲 DTO
         PurchaseLedgerDto resultDto = new PurchaseLedgerDto();
         BeanUtils.copyProperties(purchaseLedger, resultDto);
         if (!products.isEmpty()) {
@@ -1023,13 +1128,14 @@
         return resultDto;
     }
 
-    public void addApproveByPurchase(LoginUser loginUser,PurchaseLedger purchaseLedger) throws Exception {
+    public void addApproveByPurchase(LoginUser loginUser, PurchaseLedger purchaseLedger, List<SalesLedgerProduct> productList) {
         if (loginUser == null) {
             return;
         }
         ApprovalTemplate approvalTemplate = approvalTemplateMapper.selectOne(
                 new LambdaQueryWrapper<ApprovalTemplate>()
                         .eq(ApprovalTemplate::getBusinessType, 5L)
+                        .eq(ApprovalTemplate::getDeleted, 0)
                         .orderByDesc(ApprovalTemplate::getId)
                         .last("LIMIT 1")
         );
@@ -1047,6 +1153,10 @@
         approvalInstance.setTitle(purchaseLedger.getPurchaseContractNumber()+"瀹℃壒");
         approvalInstance.setApplicantName(loginUser.getNickName());
         approvalInstance.setApplyTime(LocalDateTime.now());
+        PurchaseLedgerDto snapshot = new PurchaseLedgerDto();
+        BeanUtils.copyProperties(purchaseLedger, snapshot);
+        snapshot.setProductData(productList == null ? Collections.emptyList() : new ArrayList<>(productList));
+        approvalInstance.setFormConfig(JSON.toJSONString(snapshot));
         approvalInstanceService.add(approvalInstance);
 
     }
@@ -1072,4 +1182,82 @@
         }
         return sb.toString();
     }
+
+    private static final String PURCHASE_LOCK_PREFIX = "purchase_contract_no:";
+    private static final long PURCHASE_LOCK_WAIT_TIMEOUT = 10;
+    private static final long PURCHASE_LOCK_EXPIRE_TIME = 30;
+
+    private String generatePurchaseContractNo(Date entryDate) {
+        LocalDate currentDate = entryDate != null ? DateUtils.toLocalDate(entryDate) : LocalDate.now();
+        String datePart = currentDate.format(DateTimeFormatter.BASIC_ISO_DATE);
+        String lockKey = PURCHASE_LOCK_PREFIX + datePart;
+        String lockValue = Thread.currentThread().getId() + "-" + System.nanoTime();
+
+        try {
+            long startWaitTime = System.currentTimeMillis();
+            while (System.currentTimeMillis() - startWaitTime < PURCHASE_LOCK_WAIT_TIMEOUT * 1000) {
+                Boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, PURCHASE_LOCK_EXPIRE_TIME, TimeUnit.SECONDS);
+                if (Boolean.TRUE.equals(locked)) {
+                    break;
+                }
+                try {
+                    Thread.sleep(100);
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                    throw new RuntimeException("鑾峰彇閿佹椂琚腑鏂�", e);
+                }
+            }
+
+            if (Boolean.FALSE.equals(redisTemplate.hasKey(lockKey))) {
+                throw new RuntimeException("鑾峰彇閲囪喘鍚堝悓缂栧彿鐢熸垚閿佸け璐ワ細瓒呮椂");
+            }
+
+            String prefix = "CG-" + datePart + "-";
+            List<PurchaseLedger> existingList = purchaseLedgerMapper.selectList(
+                    new LambdaQueryWrapper<PurchaseLedger>()
+                            .likeRight(PurchaseLedger::getPurchaseContractNumber, prefix)
+                            .select(PurchaseLedger::getPurchaseContractNumber));
+            List<Integer> existingSequences = existingList.stream()
+                    .map(PurchaseLedger::getPurchaseContractNumber)
+                    .filter(Objects::nonNull)
+                    .map(no -> {
+                        int lastDash = no.lastIndexOf('-');
+                        if (lastDash >= 0) {
+                            try {
+                                return Integer.parseInt(no.substring(lastDash + 1));
+                            } catch (NumberFormatException e) {
+                                return 0;
+                            }
+                        }
+                        return 0;
+                    })
+                    .collect(Collectors.toList());
+            int nextSequence = findFirstMissingSequence(existingSequences);
+
+            return prefix + String.format("%03d", nextSequence);
+        } finally {
+            String luaScript = "if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) else return 0 end";
+            redisTemplate.execute(
+                    new org.springframework.data.redis.core.script.DefaultRedisScript<>(luaScript, Long.class),
+                    Collections.singletonList(lockKey),
+                    lockValue
+            );
+        }
+    }
+
+    private int findFirstMissingSequence(List<Integer> sequences) {
+        if (sequences.isEmpty()) {
+            return 1;
+        }
+        sequences.sort(Integer::compareTo);
+        int next = 1;
+        for (int seq : sequences) {
+            if (seq == next) {
+                next++;
+            } else if (seq > next) {
+                break;
+            }
+        }
+        return next;
+    }
 }
diff --git a/src/main/java/com/ruoyi/purchase/service/impl/PurchaseReturnOrdersServiceImpl.java b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseReturnOrdersServiceImpl.java
index 318c36d..dd8fa0f 100644
--- a/src/main/java/com/ruoyi/purchase/service/impl/PurchaseReturnOrdersServiceImpl.java
+++ b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseReturnOrdersServiceImpl.java
@@ -14,6 +14,7 @@
 import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
 import com.ruoyi.purchase.mapper.PurchaseReturnOrderProductsMapper;
 import com.ruoyi.purchase.mapper.PurchaseReturnOrdersMapper;
+import com.ruoyi.purchase.pojo.PurchaseLedger;
 import com.ruoyi.purchase.pojo.PurchaseReturnOrderProducts;
 import com.ruoyi.purchase.pojo.PurchaseReturnOrders;
 import com.ruoyi.purchase.service.PurchaseReturnOrdersService;
@@ -28,6 +29,7 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -76,6 +78,18 @@
         }else {
             throw new RuntimeException("璇烽�夋嫨閫�璐у晢鍝�");
         }
+
+        // 鏇存柊閲囪喘鍙拌处鐨勫疄闄呭悎鍚岄噾棰�
+        if (purchaseReturnOrderDto.getPurchaseLedgerId() != null && purchaseReturnOrderDto.getTotalAmount() != null) {
+            PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(purchaseReturnOrderDto.getPurchaseLedgerId());
+            if (purchaseLedger != null) {
+                BigDecimal baseAmount = purchaseLedger.getNetContractAmount() != null
+                        ? purchaseLedger.getNetContractAmount()
+                        : purchaseLedger.getContractAmount();
+                purchaseLedger.setNetContractAmount(baseAmount.subtract(purchaseReturnOrderDto.getTotalAmount()));
+                purchaseLedgerMapper.updateById(purchaseLedger);
+            }
+        }
         return true;
     }
 
diff --git a/src/main/java/com/ruoyi/purchase/vo/PurchaseReturnOrderProductsDetailVo.java b/src/main/java/com/ruoyi/purchase/vo/PurchaseReturnOrderProductsDetailVo.java
index dcd58b5..e50d5d0 100644
--- a/src/main/java/com/ruoyi/purchase/vo/PurchaseReturnOrderProductsDetailVo.java
+++ b/src/main/java/com/ruoyi/purchase/vo/PurchaseReturnOrderProductsDetailVo.java
@@ -47,6 +47,9 @@
     @Schema(description = "宸查��璐ф暟閲�")
     private BigDecimal totalReturnNum;
 
+    @Schema(description = "閿�鍞彂璐ф暟閲�")
+    private BigDecimal saleOutQuantity;
+
     @Schema(description = "鍚◣鍗曚环")
     private BigDecimal taxInclusiveUnitPrice;
 
diff --git a/src/main/java/com/ruoyi/purchase/vo/PurchaseStockInProductVo.java b/src/main/java/com/ruoyi/purchase/vo/PurchaseStockInProductVo.java
index 3f8e0ec..ff7754e 100644
--- a/src/main/java/com/ruoyi/purchase/vo/PurchaseStockInProductVo.java
+++ b/src/main/java/com/ruoyi/purchase/vo/PurchaseStockInProductVo.java
@@ -42,6 +42,9 @@
     @Schema(description = "閫�璐ф�绘暟")
     private BigDecimal totalReturnNum;
 
+    @Schema(description = "閿�鍞彂璐ф暟閲�")
+    private BigDecimal saleOutQuantity;
+
     @Schema(description = "鍚◣鍗曚环")
     private BigDecimal taxInclusiveUnitPrice;
 
diff --git a/src/main/java/com/ruoyi/purchase/vo/SupplierTransactionsDetailsVo.java b/src/main/java/com/ruoyi/purchase/vo/SupplierTransactionsDetailsVo.java
index 3533e6e..5cf592d 100644
--- a/src/main/java/com/ruoyi/purchase/vo/SupplierTransactionsDetailsVo.java
+++ b/src/main/java/com/ruoyi/purchase/vo/SupplierTransactionsDetailsVo.java
@@ -30,4 +30,7 @@
     @Schema(description = "搴斾粯閲戦")
     private BigDecimal payableAmount;
 
+    @Schema(description = "閫�璐ч噾棰�")
+    private BigDecimal returnAmount;
+
 }
diff --git a/src/main/java/com/ruoyi/purchase/vo/SupplierTransactionsVo.java b/src/main/java/com/ruoyi/purchase/vo/SupplierTransactionsVo.java
index 35cefc0..2434017 100644
--- a/src/main/java/com/ruoyi/purchase/vo/SupplierTransactionsVo.java
+++ b/src/main/java/com/ruoyi/purchase/vo/SupplierTransactionsVo.java
@@ -24,7 +24,10 @@
     private BigDecimal paymentAmount;
 
     @Schema(description = "搴斾粯閲戦")
-    //璇ヤ緵搴斿晢閲囪喘搴斾粯绱閲戦=璐㈠姟(鍏ュ簱-閫�璐�)
+    //璇ヤ緵搴斿晢閲囪喘搴斾粯绱閲戦=鍒濆閲戦-浠樻-閫�娆�
     private BigDecimal payableAmount;
 
+    @Schema(description = "閫�璐ч噾棰�")
+    private BigDecimal returnAmount;
+
 }
diff --git a/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java b/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
index bc3f60a..611bde8 100644
--- a/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
+++ b/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
@@ -38,7 +38,7 @@
     /**
      * 妫�娴嬫棩鏈�
      */
-    @JsonFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     @Excel(name = "妫�娴嬫棩鏈�", width = 30, dateFormat = "yyyy-MM-dd")
     private Date checkTime;
 
diff --git a/src/main/java/com/ruoyi/quality/pojo/QualityUnqualified.java b/src/main/java/com/ruoyi/quality/pojo/QualityUnqualified.java
index 249299a..e20f4be 100644
--- a/src/main/java/com/ruoyi/quality/pojo/QualityUnqualified.java
+++ b/src/main/java/com/ruoyi/quality/pojo/QualityUnqualified.java
@@ -47,7 +47,7 @@
     /**
      * 妫�娴嬫棩鏈�
      */
-    @JsonFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     @Excel(name = "妫�娴嬫棩鏈�", width = 30, dateFormat = "yyyy-MM-dd")
     private Date checkTime;
 
@@ -107,7 +107,7 @@
     /**
      * 澶勭悊鏃ユ湡
      */
-    @JsonFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     @Excel(name = "澶勭悊鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd")
     private Date dealTime;
 
diff --git a/src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java b/src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java
index 6d45432..f04417e 100644
--- a/src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java
+++ b/src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java
@@ -7,20 +7,13 @@
 import com.ruoyi.framework.web.controller.BaseController;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.framework.web.domain.R;
-import com.ruoyi.procurementrecord.service.ProcurementRecordService;
-import com.ruoyi.procurementrecord.utils.StockUtils;
-import com.ruoyi.purchase.dto.SimpleReturnOrderGroupDto;
-import com.ruoyi.purchase.mapper.PurchaseReturnOrderProductsMapper;
 import com.ruoyi.sales.pojo.SalesLedgerProduct;
 import com.ruoyi.sales.service.ISalesLedgerProductService;
 import jakarta.servlet.http.HttpServletResponse;
 import lombok.RequiredArgsConstructor;
 import org.springframework.web.bind.annotation.*;
 
-import java.math.BigDecimal;
 import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
 
 /**
  * 浜у搧淇℃伅Controller
@@ -34,9 +27,6 @@
 public class SalesLedgerProductController extends BaseController
 {
     private final ISalesLedgerProductService salesLedgerProductService;
-    private final ProcurementRecordService procurementRecordService;
-    private final StockUtils stockUtils;
-    private final PurchaseReturnOrderProductsMapper purchaseReturnOrderProductsMapper;
 
 
     /**
@@ -45,26 +35,32 @@
     @GetMapping("/list")
     public AjaxResult list(SalesLedgerProduct salesLedgerProduct) {
         List<SalesLedgerProduct> list = salesLedgerProductService.selectSalesLedgerProductList(salesLedgerProduct);
-        if (CollUtil.isEmpty(list)) {
-            return AjaxResult.success(list);
-        }
-        List<Long> productIds = list.stream().map(SalesLedgerProduct::getProductModelId).collect(Collectors.toList());
-        List<SimpleReturnOrderGroupDto> groupListByProductIds = purchaseReturnOrderProductsMapper.getReturnOrderGroupListByProductIds(productIds);
-        Map<Long, BigDecimal> returnOrderGroupDtoMap = groupListByProductIds.stream().collect(Collectors.toMap(SimpleReturnOrderGroupDto::getProductModelId, item -> item.getSumReturnQuantity()));
-
-        list.forEach(item -> {
-            if (item.getApproveStatus() != 2) {
-                if (item.getHasSufficientStock() == 0) {
-                    item.setApproveStatus(0);
-                } else {
-                    item.setApproveStatus(1);
+        if (CollUtil.isNotEmpty(list)) {
+            list.forEach(item -> {
+                if (item.getApproveStatus() != 2) {
+                    if (item.getHasSufficientStock() == 0) {
+                        item.setApproveStatus(0);
+                    } else {
+                        item.setApproveStatus(1);
+                    }
                 }
-            }
-            // 缁熻閫�璐ф暟閲�
-            BigDecimal returnQuality = returnOrderGroupDtoMap.getOrDefault(item.getProductModelId(), BigDecimal.ZERO);
-            item.setReturnQuality(returnQuality);
-            item.setAvailableQuality(item.getQuantity().subtract(returnQuality));
-        });
+                java.math.BigDecimal returnQuantity = item.getReturnQuantity() == null
+                        ? java.math.BigDecimal.ZERO
+                        : item.getReturnQuantity();
+                item.setReturnQuantity(returnQuantity);
+                java.math.BigDecimal availableQuality = item.getQuantity() == null
+                        ? java.math.BigDecimal.ZERO
+                        : item.getQuantity();
+                if (item.getType() != null && item.getType() == 2) {
+                    availableQuality = item.getApprovedStockInNum() == null
+                            ? java.math.BigDecimal.ZERO
+                            : item.getApprovedStockInNum();
+                    availableQuality = availableQuality
+                            .subtract(item.getShippedQuantity() == null ? java.math.BigDecimal.ZERO : item.getShippedQuantity());
+                }
+                item.setAvailableQuality(availableQuality.subtract(returnQuantity));
+            });
+        }
         return AjaxResult.success(list);
     }
 
diff --git a/src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java b/src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java
index c119e94..a4fc57c 100644
--- a/src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java
+++ b/src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java
@@ -19,7 +19,7 @@
     private String salesContractNo;
     private String customerContractNo;
     private String projectName;
-    @JsonFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     private Date entryDate;
 
     private String entryDateStart;
diff --git a/src/main/java/com/ruoyi/sales/pojo/SalesLedger.java b/src/main/java/com/ruoyi/sales/pojo/SalesLedger.java
index 00736ba..c8a0443 100644
--- a/src/main/java/com/ruoyi/sales/pojo/SalesLedger.java
+++ b/src/main/java/com/ruoyi/sales/pojo/SalesLedger.java
@@ -50,7 +50,7 @@
     /**
      * 褰曞叆鏃ユ湡
      */
-    @JsonFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     @Excel(name = "褰曞叆鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd")
     @DateTimeFormat(pattern = "yyyy-MM-dd")
     private Date entryDate;
@@ -109,6 +109,9 @@
     @Schema(description = "浠樻鏂瑰紡")
     private String paymentMethod;
 
+    @Schema(description = "瀹為檯鍚堝悓閲戦")
+    private BigDecimal netContractAmount;
+
     @TableField(exist = false)
     @Schema(description = "鐢熶骇鐘舵��")
     private String productionStatus = "鏈紑濮�";
diff --git a/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java b/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
index f4a42d6..9bcbd07 100644
--- a/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
+++ b/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -164,11 +164,7 @@
     @TableField(exist = false)
     private Integer hasSufficientStock;
 
-    // 閫�璐ф暟閲�
-    @TableField(exist = false)
-    private BigDecimal returnQuality;
-
-    // 鍙敤鏁伴噺  quantity - returnQuality
+    // 鍙敤鏁伴噺  quantity - returnQuantity
     @TableField(exist = false)
     private BigDecimal availableQuality;
     @Schema(description = "鍒涘缓鐢ㄦ埛")
@@ -185,4 +181,20 @@
     @TableField(exist = false)
     @Schema(description = "寰呭彂璐ф暟閲�")
     private BigDecimal noQuantity;
+
+    @TableField(exist = false)
+    @Schema(description = "閫�璐ф暟閲�")
+    private BigDecimal returnQuantity;
+
+    @TableField(exist = false)
+    @Schema(description = "閿�鍞彂璐ф暟閲�")
+    private BigDecimal shippedQuantity;
+
+    @TableField(exist = false)
+    @Schema(description = "宸插鏍稿叆搴撴暟閲�")
+    private BigDecimal approvedStockInNum;
+
+    @TableField(exist = false)
+    @Schema(description = "瀹℃壒涓暟閲�")
+    private BigDecimal pendingApprovalQuantity;
 }
diff --git a/src/main/java/com/ruoyi/sales/pojo/ShippingInfo.java b/src/main/java/com/ruoyi/sales/pojo/ShippingInfo.java
index f244453..ed9a268 100644
--- a/src/main/java/com/ruoyi/sales/pojo/ShippingInfo.java
+++ b/src/main/java/com/ruoyi/sales/pojo/ShippingInfo.java
@@ -68,6 +68,7 @@
     private String shippingCarNumber;
 
     @Schema(description = "鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
     private LocalDateTime createTime;
 
     @Schema(description = "淇敼鏃堕棿")
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
index 9f6e004..171f5ae 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -25,6 +25,7 @@
 import com.ruoyi.technology.mapper.TechnologyBomStructureMapper;
 import com.ruoyi.technology.mapper.TechnologyRoutingMapper;
 import com.ruoyi.technology.pojo.TechnologyRouting;
+import org.apache.commons.lang3.BooleanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -33,9 +34,7 @@
 import java.lang.reflect.Field;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.util.Arrays;
 import java.util.List;
@@ -98,16 +97,29 @@
         List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectSalesLedgerProductList(salesLedgerProduct);
         if(!CollectionUtils.isEmpty(salesLedgerProducts)){
             salesLedgerProducts.forEach(item -> {
-                // 鍙戣揣淇℃伅
-                ShippingInfo shippingInfo = shippingInfoMapper.selectOne(new LambdaQueryWrapper<ShippingInfo>()
+                // 鍙戣揣淇℃伅锛堝彇鏈�鏂颁竴鏉★紝鍙煡璇㈠鏍搁�氳繃鎴栧凡鍙戣揣鐨勮褰曪級
+                ShippingInfo latestShippingInfo = shippingInfoMapper.selectOne(new LambdaQueryWrapper<ShippingInfo>()
                         .eq(ShippingInfo::getSalesLedgerProductId, item.getId())
+                        .in(ShippingInfo::getStatus, "瀹℃牳閫氳繃", "宸插彂璐�")
                         .orderByDesc(ShippingInfo::getCreateTime)
                         .last("limit 1"));
-                if(shippingInfo != null){
-                    item.setShippingDate(shippingInfo.getShippingDate());
-                    item.setShippingCarNumber(shippingInfo.getShippingCarNumber());
-                    item.setExpressCompany(shippingInfo.getExpressCompany());
-                    item.setExpressNumber(shippingInfo.getExpressNumber());
+                if(latestShippingInfo != null){
+                    item.setShippingDate(latestShippingInfo.getShippingDate());
+                    item.setExpressCompany(latestShippingInfo.getExpressCompany());
+                    item.setExpressNumber(latestShippingInfo.getExpressNumber());
+                }
+                // 杞︾墝鍙凤細鍙栨墍鏈夊鏍搁�氳繃鎴栧凡鍙戣揣璁板綍鐨勮溅鐗屽彿锛岄�楀彿鎷兼帴
+                List<ShippingInfo> allShippingInfos = shippingInfoMapper.selectList(new LambdaQueryWrapper<ShippingInfo>()
+                        .eq(ShippingInfo::getSalesLedgerProductId, item.getId())
+                        .in(ShippingInfo::getStatus, "瀹℃牳閫氳繃", "宸插彂璐�")
+                        .orderByAsc(ShippingInfo::getCreateTime));
+                if(!CollectionUtils.isEmpty(allShippingInfos)){
+                    String carNumbers = allShippingInfos.stream()
+                            .map(ShippingInfo::getShippingCarNumber)
+                            .filter(carNo -> carNo != null && !carNo.trim().isEmpty())
+                            .distinct()
+                            .collect(Collectors.joining(","));
+                    item.setShippingCarNumber(carNumbers);
                 }
             });
         }
@@ -216,16 +228,15 @@
      */
     public void addProductionData(SalesLedgerProduct salesLedgerProduct) {
         //鍏堝垽鏂浜у搧鏄惁闇�瑕佺敓浜�
-        if (!salesLedgerProduct.getIsProduction()) {
+        if (!BooleanUtils.isTrue(salesLedgerProduct.getIsProduction())) {
             return;
         }
         SalesLedger salesLedger = salesLedgerMapper.selectById(salesLedgerProduct.getSalesLedgerId());
         ProductionPlan productionPlan = new ProductionPlan();
         productionPlan.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId());
         productionPlan.setSalesLedgerProductId(salesLedgerProduct.getId());
-        productionPlan.setMpsNo(generateNextPlanNo(salesLedger.getEntryDate().toInstant()
-                .atZone(ZoneId.systemDefault())
-                .toLocalDate().format(DateTimeFormatter.ofPattern("yyyyMMdd"))));
+        productionPlan.setMpsNo(generateNextPlanNo(com.ruoyi.common.utils.DateUtils.toLocalDate(salesLedger.getEntryDate())
+                .format(DateTimeFormatter.ofPattern("yyyyMMdd"))));
         productionPlan.setProductModelId(salesLedgerProduct.getProductModelId());
         productionPlan.setQtyRequired(salesLedgerProduct.getQuantity());
         productionPlan.setSource("閿�鍞�");
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
index 7b71ef3..00e913f 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -38,8 +38,6 @@
 import com.ruoyi.project.system.domain.SysUser;
 import com.ruoyi.project.system.mapper.SysDeptMapper;
 import com.ruoyi.project.system.mapper.SysUserMapper;
-import com.ruoyi.purchase.dto.SimpleReturnOrderGroupDto;
-import com.ruoyi.purchase.mapper.PurchaseReturnOrderProductsMapper;
 import com.ruoyi.quality.mapper.QualityInspectMapper;
 import com.ruoyi.sales.dto.*;
 import com.ruoyi.sales.mapper.CommonFileMapper;
@@ -121,9 +119,6 @@
     @Autowired
     private ProductionProductMainService productionProductMainService;
     @Autowired
-    private PurchaseReturnOrderProductsMapper purchaseReturnOrderProductsMapper;
-    ;
-    @Autowired
     private SysUserMapper sysUserMapper;
 
     @Override
@@ -148,17 +143,11 @@
         productWrapper.eq(SalesLedgerProduct::getType, type.getCode());
         List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(productWrapper);
         if (type.equals(SaleEnum.PURCHASE)) {
-            // 鏌ヨ閫�璐т俊鎭�
-            List<Long> productIds = salesLedgerProducts.stream().map(SalesLedgerProduct::getProductModelId).collect(Collectors.toList());
-            List<SimpleReturnOrderGroupDto> groupListByProductIds = new ArrayList<>();
-            if(CollectionUtils.isNotEmpty(productIds)){
-                groupListByProductIds = purchaseReturnOrderProductsMapper.getReturnOrderGroupListByProductIds(productIds);
-            }
-            Map<Long, BigDecimal> returnOrderGroupDtoMap = groupListByProductIds.stream().collect(Collectors.toMap(SimpleReturnOrderGroupDto::getProductModelId, SimpleReturnOrderGroupDto::getSumReturnQuantity));
             salesLedgerProducts.forEach(item -> {
-                BigDecimal returnQuality = returnOrderGroupDtoMap.getOrDefault(item.getProductModelId(), BigDecimal.ZERO);
-                item.setReturnQuality(returnQuality);
-                item.setAvailableQuality(item.getQuantity().subtract(returnQuality));
+                BigDecimal returnQuantity = item.getReturnQuantity() == null ? BigDecimal.ZERO : item.getReturnQuantity();
+                item.setReturnQuantity(returnQuantity);
+                BigDecimal quantity = item.getQuantity() == null ? BigDecimal.ZERO : item.getQuantity();
+                item.setAvailableQuality(quantity.subtract(returnQuantity));
             });
         }
         return salesLedgerProducts;
@@ -396,6 +385,7 @@
                 salesLedger.setContractAmount(salesLedgerProductImportDtos.stream()
                         .map(SalesLedgerProductImportDto::getTaxInclusiveTotalPrice)
                         .reduce(BigDecimal.ZERO, BigDecimal::add));
+                salesLedger.setNetContractAmount(salesLedger.getContractAmount());
                 salesLedgerMapper.insert(salesLedger);
 
 
@@ -571,6 +561,10 @@
         SalesLedger salesLedger = convertToEntity(salesLedgerDto);
         salesLedger.setCustomerName(customer.getCustomerName());
         salesLedger.setTenantId(customer.getTenantId());
+        // 褰曞叆浜猴細濡傛灉鏈紶鍒欎娇鐢ㄥ綋鍓嶇櫥褰曠敤鎴�
+        if (StringUtils.isEmpty(salesLedger.getEntryPerson())) {
+            salesLedger.setEntryPerson(String.valueOf(SecurityUtils.getUserId()));
+        }
         // 3. 鏂板鎴栨洿鏂颁富琛�
         if (salesLedger.getId() == null) {
             String contractNo = salesLedger.getSalesContractNo();
@@ -597,7 +591,18 @@
             );
         }
 
-        // 5. 淇濆瓨閿�鍞彴璐﹂檮浠�
+        // 5. 鍏滃簳锛氱‘淇濆疄闄呭悎鍚岄噾棰濇湁鍒濆鍊肩瓑浜庡悎鍚岄噾棰�
+        if (salesLedger.getNetContractAmount() == null) {
+            SalesLedger dbLedger = salesLedgerMapper.selectById(salesLedger.getId());
+            if (dbLedger != null && dbLedger.getNetContractAmount() == null && dbLedger.getContractAmount() != null) {
+                SalesLedger updateEntity = new SalesLedger();
+                updateEntity.setId(salesLedger.getId());
+                updateEntity.setNetContractAmount(dbLedger.getContractAmount());
+                salesLedgerMapper.updateById(updateEntity);
+            }
+        }
+
+        // 6. 淇濆瓨閿�鍞彴璐﹂檮浠�
         fileUtil.saveStorageAttachment(ApplicationTypeEnum.FILE, RecordTypeEnum.SALES_LEDGER, salesLedger.getId(), salesLedgerDto.getStorageBlobDTOs());
 
         return 1;
@@ -735,6 +740,15 @@
             amountField.setAccessible(true);
             amountField.set(entity, totalAmount);
 
+            // 瀹為檯鍚堝悓閲戦鍒濆鍊肩瓑浜庡悎鍚岄噾棰�
+            try {
+                Field netAmountField = mainEntityClass.getDeclaredField("netContractAmount");
+                netAmountField.setAccessible(true);
+                netAmountField.set(entity, totalAmount);
+            } catch (NoSuchFieldException ignored) {
+                // 瀛愮被鍙兘娌℃湁璇ュ瓧娈碉紝蹇界暐
+            }
+
             mainMapper.updateById(entity);
         } catch (Exception e) {
             throw new RuntimeException("鍔ㄦ�佹洿鏂颁富琛ㄩ噾棰濆け璐�", e);
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java
index 5e31cfa..37d7261 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java
@@ -104,9 +104,19 @@
         }).collect(Collectors.toList());
         salesQuotationProductService.saveBatch(products);
         // 鎶ヤ环瀹℃壒
+        ApprovalTemplate approvalTemplate = approvalTemplateMapper.selectOne(
+                new LambdaQueryWrapper<ApprovalTemplate>()
+                        .eq(ApprovalTemplate::getBusinessType, 6L)
+                        .eq(ApprovalTemplate::getDeleted, 0)
+                        .orderByDesc(ApprovalTemplate::getId)
+                        .last("LIMIT 1")
+        );
+        if (approvalTemplate == null) {
+            throw new RuntimeException("璇峰厛閰嶇疆鎶ヤ环瀹℃壒妯℃澘");
+        }
         ApprovalInstanceDto approvalInstance = new ApprovalInstanceDto();
-        approvalInstance.setTemplateId(approvalTemplateMapper.selectOne(new LambdaQueryWrapper<ApprovalTemplate>().eq(ApprovalTemplate::getBusinessType,6L).orderByDesc(ApprovalTemplate::getId).last("LIMIT 1")).getId());
-        approvalInstance.setTemplateName(approvalTemplateMapper.selectOne(new LambdaQueryWrapper<ApprovalTemplate>().eq(ApprovalTemplate::getBusinessType,6L).orderByDesc(ApprovalTemplate::getId).last("LIMIT 1")).getTemplateName());
+        approvalInstance.setTemplateId(approvalTemplate.getId());
+        approvalInstance.setTemplateName(approvalTemplate.getTemplateName());
         approvalInstance.setBusinessId(salesQuotation.getId());
         approvalInstance.setBusinessType(6L);
         approvalInstance.setCurrentLevel(1);
@@ -150,9 +160,19 @@
         // 鍏堢粨鏉熶箣鍓嶆湭缁撴潫鐨勬姤浠峰鎵�
         approvalInstanceService.lambdaUpdate().set(ApprovalInstance::getStatus,"REJECTED").eq(ApprovalInstance::getBusinessId,salesQuotation.getId()).eq(ApprovalInstance::getBusinessType,6L).update();
 
+        ApprovalTemplate approvalTemplate = approvalTemplateMapper.selectOne(
+                new LambdaQueryWrapper<ApprovalTemplate>()
+                        .eq(ApprovalTemplate::getBusinessType, 6L)
+                        .eq(ApprovalTemplate::getDeleted, 0)
+                        .orderByDesc(ApprovalTemplate::getId)
+                        .last("LIMIT 1")
+        );
+        if (approvalTemplate == null) {
+            throw new RuntimeException("璇峰厛閰嶇疆鎶ヤ环瀹℃壒妯℃澘");
+        }
         ApprovalInstanceDto approvalInstance = new ApprovalInstanceDto();
-        approvalInstance.setTemplateId(approvalTemplateMapper.selectOne(new LambdaQueryWrapper<ApprovalTemplate>().eq(ApprovalTemplate::getBusinessType,6L).orderByDesc(ApprovalTemplate::getId).last("LIMIT 1")).getId());
-        approvalInstance.setTemplateName(approvalTemplateMapper.selectOne(new LambdaQueryWrapper<ApprovalTemplate>().eq(ApprovalTemplate::getBusinessType,6L).orderByDesc(ApprovalTemplate::getId).last("LIMIT 1")).getTemplateName());
+        approvalInstance.setTemplateId(approvalTemplate.getId());
+        approvalInstance.setTemplateName(approvalTemplate.getTemplateName());
         approvalInstance.setBusinessId(salesQuotation.getId());
         approvalInstance.setBusinessType(6L);
         approvalInstance.setCurrentLevel(1);
@@ -174,13 +194,31 @@
         if(salesQuotation==null) return false;
         salesQuotationMapper.deleteById(id);
         salesQuotationProductMapper.delete(new LambdaQueryWrapper<SalesQuotationProduct>().eq(SalesQuotationProduct::getSalesQuotationId, id));
-        // 鍒犻櫎鎶ヤ环瀹℃壒
-        ApproveProcess one = approveProcessService.getOne(new LambdaQueryWrapper<ApproveProcess>()
+        // 鍒犻櫎璇ユ姤浠峰搴旂殑鍏ㄩ儴瀹℃壒瀹炰緥锛堝彲鑳藉瓨鍦ㄥ娆℃彁浜�/閲嶅锛�
+        List<ApprovalInstance> approvalInstances = approvalInstanceService.list(new LambdaQueryWrapper<ApprovalInstance>()
+                .eq(ApprovalInstance::getBusinessId, id)
+                .eq(ApprovalInstance::getBusinessType, 6L)
+                .eq(ApprovalInstance::getDeleted, 0));
+        if(!approvalInstances.isEmpty()){
+            approvalInstanceService.delete(
+                    approvalInstances.stream()
+                            .map(ApprovalInstance::getId)
+                            .filter(Objects::nonNull)
+                            .collect(Collectors.toList())
+            );
+        }
+        // 鍒犻櫎璇ユ姤浠峰搴旂殑鍏ㄩ儴瀹℃壒娴佺▼锛堝悓涓�鎶ヤ环鍙兘鍙嶅鍙戣捣锛�
+        List<ApproveProcess> approveProcesses = approveProcessService.list(new LambdaQueryWrapper<ApproveProcess>()
                 .eq(ApproveProcess::getApproveType, 6)
                 .eq(ApproveProcess::getApproveDelete, IsDeleteEnum.NOT_DELETED)
                 .eq(ApproveProcess::getApproveReason, salesQuotation.getQuotationNo()));
-        if(one != null){
-            approveProcessService.delByIds(Collections.singletonList(one.getId()));
+        if(!approveProcesses.isEmpty()){
+            approveProcessService.delByIds(
+                    approveProcesses.stream()
+                            .map(ApproveProcess::getId)
+                            .filter(Objects::nonNull)
+                            .collect(Collectors.toList())
+            );
         }
         return true;
     }
diff --git a/src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
index 4e6ff58..be34bc0 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
@@ -172,24 +172,48 @@
     @Override
     public boolean addReq(ShippingInfoDto req) {
 
-                LoginUser loginUser = SecurityUtils.getLoginUser();
+        // 鏍¢獙璇ヤ骇鍝佹槸鍚﹀凡鏈夊緟瀹℃牳/瀹℃牳涓殑鍙戣揣璁板綍锛岄槻姝㈤噸澶嶆彁浜�
+        Long salesLedgerProductId = req.getSalesLedgerProductId();
+        if (salesLedgerProductId != null) {
+            long pendingCount = this.count(new LambdaQueryWrapper<ShippingInfo>()
+                    .eq(ShippingInfo::getSalesLedgerProductId, salesLedgerProductId)
+                    .in(ShippingInfo::getStatus, "寰呭鏍�", "瀹℃牳涓�"));
+            if (pendingCount > 0) {
+                throw new RuntimeException("璇ヤ骇鍝佸凡鏈夊緟瀹℃牳鐨勫彂璐ц褰曪紝璇峰嬁閲嶅鎻愪氦");
+            }
+        }
+
+        LoginUser loginUser = SecurityUtils.getLoginUser();
         String sh = OrderUtils.countTodayByCreateTime(shippingInfoMapper, "SH","shipping_no",req.getCreateTime());
         // 鍏堜繚瀛樺彂璐у崟锛屽啀鍙戣捣瀹℃壒锛涙棤瀹℃牳浜鸿嚜鍔ㄩ�氳繃鏃堕渶瑕佹寜鍙戣揣缂栧彿鍥炲啓鍙戣揣鐘舵�併��
         req.setShippingNo(sh);
         req.setStatus("寰呭鏍�");
         boolean save = this.add(req);
         // 鍙戣揣瀹℃壒
+        ApprovalTemplate approvalTemplate = approvalTemplateMapper.selectOne(
+                new LambdaQueryWrapper<ApprovalTemplate>()
+                        .eq(ApprovalTemplate::getBusinessType, 7L)
+                        .eq(ApprovalTemplate::getDeleted, 0)
+                        .orderByDesc(ApprovalTemplate::getId)
+                        .last("LIMIT 1")
+        );
+        if (approvalTemplate == null) {
+            throw new RuntimeException("璇峰厛閰嶇疆鍙戣揣瀹℃壒妯℃澘");
+        }
         ApprovalInstanceDto approvalInstance = new ApprovalInstanceDto();
-        approvalInstance.setTemplateId(approvalTemplateMapper.selectOne(new LambdaQueryWrapper<ApprovalTemplate>().eq(ApprovalTemplate::getBusinessType,7L).orderByDesc(ApprovalTemplate::getId).last("LIMIT 1")).getId());
-        approvalInstance.setTemplateName(approvalTemplateMapper.selectOne(new LambdaQueryWrapper<ApprovalTemplate>().eq(ApprovalTemplate::getBusinessType,7L).orderByDesc(ApprovalTemplate::getId).last("LIMIT 1")).getTemplateName());
+        approvalInstance.setTemplateId(approvalTemplate.getId());
+        approvalInstance.setTemplateName(approvalTemplate.getTemplateName());
         approvalInstance.setBusinessId(req.getId());
         approvalInstance.setBusinessType(7L);
         approvalInstance.setCurrentLevel(1);
-        approvalInstance.setTitle(sh+"瀹℃壒");
+        approvalInstance.setTitle(sh);
         approvalInstance.setApplicantId(loginUser.getUserId());
         approvalInstance.setApplicantName(loginUser.getNickName());
         approvalInstance.setApplyTime(LocalDateTime.now());
         approvalInstanceService.add(approvalInstance);
+        // 鍒涘缓瀹℃壒瀹炰緥鍚庯紝鏇存柊鍙戣揣鐘舵�佷负"瀹℃牳涓�"锛屼娇鍓嶇姝g‘鏄剧ず瀹℃壒鐘舵��
+        req.setStatus("瀹℃牳涓�");
+        this.updateById(req);
         return true;
     }
 }
diff --git a/src/main/java/com/ruoyi/sales/vo/CustomerTransactionsDetailsVo.java b/src/main/java/com/ruoyi/sales/vo/CustomerTransactionsDetailsVo.java
index 992860e..cc205b1 100644
--- a/src/main/java/com/ruoyi/sales/vo/CustomerTransactionsDetailsVo.java
+++ b/src/main/java/com/ruoyi/sales/vo/CustomerTransactionsDetailsVo.java
@@ -30,4 +30,7 @@
     @Schema(description = "搴旀敹閲戦")
     private BigDecimal receiptableAmount;
 
+    @Schema(description = "閫�璐ч噾棰�")
+    private BigDecimal returnAmount;
+
 }
diff --git a/src/main/java/com/ruoyi/sales/vo/CustomerTransactionsVo.java b/src/main/java/com/ruoyi/sales/vo/CustomerTransactionsVo.java
index 7b8fc1a..a6c7d7f 100644
--- a/src/main/java/com/ruoyi/sales/vo/CustomerTransactionsVo.java
+++ b/src/main/java/com/ruoyi/sales/vo/CustomerTransactionsVo.java
@@ -24,7 +24,10 @@
     private BigDecimal receiptPaymentAmount;
 
     @Schema(description = "搴旀敹閲戦")
-    //璇ュ鎴烽攢鍞簲鏀剁疮璁¢噾棰�=璐㈠姟(鍑哄簱-閫�璐�)
+    //璇ュ鎴烽攢鍞簲鏀剁疮璁¢噾棰�=鍒濆閲戦-鍥炴-閫�娆�
     private BigDecimal receiptableAmount;
 
+    @Schema(description = "閫�璐ч噾棰�")
+    private BigDecimal returnAmount;
+
 }
diff --git a/src/main/java/com/ruoyi/staff/controller/PersonalAttendanceLocationConfigController.java b/src/main/java/com/ruoyi/staff/controller/PersonalAttendanceLocationConfigController.java
index 2872a89..fc9cf4c 100644
--- a/src/main/java/com/ruoyi/staff/controller/PersonalAttendanceLocationConfigController.java
+++ b/src/main/java/com/ruoyi/staff/controller/PersonalAttendanceLocationConfigController.java
@@ -1,6 +1,8 @@
 package com.ruoyi.staff.controller;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.OrderItem;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.staff.pojo.PersonalAttendanceLocationConfig;
@@ -31,8 +33,10 @@
     @Operation(summary = "鏂板/淇敼浜哄憳鎵撳崱瑙勫垯閰嶇疆")
     @PostMapping("/add")
     public R add(@RequestBody PersonalAttendanceLocationConfig personalAttendanceLocationConfig){
-
-
+        if (personalAttendanceLocationConfig.getId() != null
+                && !personalAttendanceLocationConfigService.canEdit(personalAttendanceLocationConfig.getId())) {
+            return R.fail("璇ョ彮娆¢厤缃凡琚帓鐝苟浜х敓鎵撳崱璁板綍锛屼笉鑳界紪杈�");
+        }
         // 鐝闇�瑕佷笉鑳藉閲嶅
         if (personalAttendanceLocationConfig.getId() == null && personalAttendanceLocationConfigService.lambdaQuery().eq(PersonalAttendanceLocationConfig::getShift, personalAttendanceLocationConfig.getShift()).one() != null) {
             return R.fail("鐝涓嶈兘閲嶅");
@@ -42,15 +46,35 @@
 
     @Operation(summary = "鍒嗛〉鏌ヨ浜哄憳鎵撳崱瑙勫垯閰嶇疆")
     @GetMapping("/listPage")
-    public R listPage(Page page){
+    public R listPage(Page page, PersonalAttendanceLocationConfig query){
         page.addOrder(OrderItem.desc("id"));
-        return R.ok(personalAttendanceLocationConfigService.page(page));
+        LambdaQueryWrapper<PersonalAttendanceLocationConfig> wrapper = new LambdaQueryWrapper<PersonalAttendanceLocationConfig>()
+                .ne(PersonalAttendanceLocationConfig::getId, 999);
+        if (query.getSysDeptId() != null) {
+            wrapper.eq(PersonalAttendanceLocationConfig::getSysDeptId, query.getSysDeptId());
+        }
+        if (query.getShift() != null && !query.getShift().isEmpty()) {
+            wrapper.eq(PersonalAttendanceLocationConfig::getShift, query.getShift());
+        }
+        IPage<PersonalAttendanceLocationConfig> result = personalAttendanceLocationConfigService.page(page, wrapper);
+        result.getRecords().forEach(item -> {
+            boolean locked = personalAttendanceLocationConfigService.hasAttendanceUsage(item.getId());
+            item.setUsageLocked(locked);
+            item.setCanEdit(!locked);
+            item.setCanDelete(!locked);
+        });
+        return R.ok(result);
     }
 
 
     @Operation(summary = "鍒犻櫎浜哄憳鎵撳崱瑙勫垯閰嶇疆")
     @DeleteMapping("/del")
     public R del(@RequestBody List<Integer> ids) {
+        for (Integer id : ids) {
+            if (!personalAttendanceLocationConfigService.canDelete(id)) {
+                return R.fail("瀛樺湪宸叉帓鐝笖宸叉湁鎵撳崱璁板綍鐨勭彮娆¢厤缃紝涓嶈兘鍒犻櫎");
+            }
+        }
         return R.ok(personalAttendanceLocationConfigService.removeBatchByIds(ids));
     }
 
diff --git a/src/main/java/com/ruoyi/staff/controller/PersonalShiftController.java b/src/main/java/com/ruoyi/staff/controller/PersonalShiftController.java
index 2f1496b..a86dcb4 100644
--- a/src/main/java/com/ruoyi/staff/controller/PersonalShiftController.java
+++ b/src/main/java/com/ruoyi/staff/controller/PersonalShiftController.java
@@ -60,7 +60,7 @@
     }
 
     @Operation(summary = "鐝鐘舵�佷慨鏀�")
-    @PostMapping("update")
+    @PostMapping("/update")
     public R performanceShiftUpdate(@RequestBody PersonalShift personalShift) {
         personalShiftService.performanceShiftUpdate(personalShift);
         return R.ok();
diff --git a/src/main/java/com/ruoyi/staff/controller/StaffSalaryMainController.java b/src/main/java/com/ruoyi/staff/controller/StaffSalaryMainController.java
index 569ca1c..d30bf3a 100644
--- a/src/main/java/com/ruoyi/staff/controller/StaffSalaryMainController.java
+++ b/src/main/java/com/ruoyi/staff/controller/StaffSalaryMainController.java
@@ -5,10 +5,12 @@
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.staff.dto.CalculateSalaryDto;
+import com.ruoyi.staff.dto.StaffSalaryCalculateDto;
 import com.ruoyi.staff.pojo.StaffSalaryMain;
 import com.ruoyi.staff.service.StaffSalaryMainService;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import io.swagger.v3.oas.annotations.Operation;
+import jakarta.servlet.http.HttpServletResponse;
 import lombok.AllArgsConstructor;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
@@ -43,6 +45,12 @@
         return staffSalaryMainService.calculateSalary(calculateSalaryDto);
     }
 
+    @Operation(summary = "鎸夊憳宸ラ噸绠楀伐璧勬槑缁�")
+    @PostMapping("/calculateByEmployeeId")
+    public AjaxResult calculateByEmployeeId(@RequestBody StaffSalaryCalculateDto staffSalaryCalculateDto) {
+        return staffSalaryMainService.calculateSalaryByEmployee(staffSalaryCalculateDto);
+    }
+
     @PostMapping("/add")
     @Operation(summary = "鏂板缓宸ヨ祫琛�")
     @Log(title = "鏂板缓宸ヨ祫琛�", businessType = BusinessType.INSERT)
@@ -67,6 +75,16 @@
         return staffSalaryMainService.delete(ids);
     }
 
+    @PostMapping("/export")
+    @Operation(summary = "瀵煎嚭鍛樺伐钖祫鏄庣粏")
+    public void export(HttpServletResponse response, String salaryMonth) {
+        staffSalaryMainService.exportSalaryDetail(response, salaryMonth);
+    }
 
+    @GetMapping("/availableDepts")
+    @Operation(summary = "鑾峰彇鍙�夐儴闂紙鎺掗櫎宸插彂鏀惧伐璧勮〃鐨勯儴闂級")
+    public AjaxResult getAvailableDepts(String salaryMonth) {
+        return staffSalaryMainService.getAvailableDepts(salaryMonth);
+    }
 
 }
diff --git a/src/main/java/com/ruoyi/staff/dto/StaffLeaveDto.java b/src/main/java/com/ruoyi/staff/dto/StaffLeaveDto.java
index 3685410..0556e57 100644
--- a/src/main/java/com/ruoyi/staff/dto/StaffLeaveDto.java
+++ b/src/main/java/com/ruoyi/staff/dto/StaffLeaveDto.java
@@ -36,7 +36,6 @@
     /**
      * 瀹跺涵浣忓潃
      */
-    @Excel(name = "瀹跺涵浣忓潃", sort = 6)
     private String adress;
 
     /**
diff --git a/src/main/java/com/ruoyi/staff/dto/StaffSalaryCalculateDto.java b/src/main/java/com/ruoyi/staff/dto/StaffSalaryCalculateDto.java
new file mode 100644
index 0000000..ef0a50e
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/dto/StaffSalaryCalculateDto.java
@@ -0,0 +1,16 @@
+package com.ruoyi.staff.dto;
+
+import com.ruoyi.staff.pojo.StaffSalaryDetail;
+import lombok.Data;
+
+/**
+ * 鍗曚釜鍛樺伐宸ヨ祫閲嶇畻鍙傛暟
+ */
+@Data
+public class StaffSalaryCalculateDto extends StaffSalaryDetail {
+
+    /**
+     * 宸ヨ祫鏈堜唤锛屾牸寮� yyyy-MM
+     */
+    private String salaryMonth;
+}
diff --git a/src/main/java/com/ruoyi/staff/excel/StaffSalaryExportData.java b/src/main/java/com/ruoyi/staff/excel/StaffSalaryExportData.java
new file mode 100644
index 0000000..c1f2725
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/excel/StaffSalaryExportData.java
@@ -0,0 +1,64 @@
+package com.ruoyi.staff.excel;
+
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 鍛樺伐钖祫瀵煎嚭鏁版嵁
+ */
+@Data
+public class StaffSalaryExportData {
+
+    @Excel(name = "宸ヨ祫鏈堜唤")
+    private String salaryMonth;
+
+    @Excel(name = "宸ヨ祫涓婚")
+    private String salaryTitle;
+
+    @Excel(name = "鍛樺伐濮撳悕")
+    private String staffName;
+
+    @Excel(name = "閮ㄩ棬鍚嶇О")
+    private String deptName;
+
+    @Excel(name = "鍩烘湰宸ヨ祫")
+    private BigDecimal basicSalary;
+
+    @Excel(name = "璁′欢宸ヨ祫")
+    private BigDecimal pieceSalary;
+
+    @Excel(name = "璁℃椂宸ヨ祫")
+    private BigDecimal hourlySalary;
+
+    @Excel(name = "鍏朵粬鏀跺叆")
+    private BigDecimal otherIncome;
+
+    @Excel(name = "绀句繚涓汉")
+    private BigDecimal socialPersonal;
+
+    @Excel(name = "鍏Н閲戜釜浜�")
+    private BigDecimal fundPersonal;
+
+    @Excel(name = "鍏朵粬鏀嚭")
+    private BigDecimal otherDeduct;
+
+    @Excel(name = "绀句繚琛ョ即")
+    private BigDecimal socialSupplementAmount;
+
+    @Excel(name = "宸ヨ祫涓◣")
+    private BigDecimal salaryTax;
+
+    @Excel(name = "搴斿彂宸ヨ祫")
+    private BigDecimal grossSalary;
+
+    @Excel(name = "搴旀墸宸ヨ祫")
+    private BigDecimal deductSalary;
+
+    @Excel(name = "瀹炲彂宸ヨ祫")
+    private BigDecimal netSalary;
+
+    @Excel(name = "澶囨敞")
+    private String remark;
+}
diff --git a/src/main/java/com/ruoyi/staff/init/DataInitializer.java b/src/main/java/com/ruoyi/staff/init/DataInitializer.java
new file mode 100644
index 0000000..1432d2e
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/init/DataInitializer.java
@@ -0,0 +1,33 @@
+package com.ruoyi.staff.init;
+
+import com.ruoyi.staff.mapper.PersonalAttendanceLocationConfigMapper;
+import com.ruoyi.staff.pojo.PersonalAttendanceLocationConfig;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class DataInitializer implements ApplicationRunner {
+
+    private final PersonalAttendanceLocationConfigMapper configMapper;
+
+    @Override
+    public void run(ApplicationArguments args) {
+        initLeaveConfig();
+    }
+
+    private void initLeaveConfig() {
+        PersonalAttendanceLocationConfig config = configMapper.selectById(999);
+        if (config == null) {
+            config = new PersonalAttendanceLocationConfig();
+            config.setId(999);
+            config.setShift("璇峰亣");
+            configMapper.insert(config);
+            log.info("宸插垵濮嬪寲璇峰亣鐝閰嶇疆(id=999)");
+        }
+    }
+}
diff --git a/src/main/java/com/ruoyi/staff/mapper/PersonalShiftMapper.java b/src/main/java/com/ruoyi/staff/mapper/PersonalShiftMapper.java
index 8ae881f..ea48d09 100644
--- a/src/main/java/com/ruoyi/staff/mapper/PersonalShiftMapper.java
+++ b/src/main/java/com/ruoyi/staff/mapper/PersonalShiftMapper.java
@@ -31,4 +31,6 @@
     List<Map<String, Object>> performanceShiftYearList(@Param("time") String time, @Param("userName") String userName, @Param("sysDeptId") Integer sysDeptId);
 
     List<PerformanceShiftMapDto> performanceShiftList(@Param("time") String time, @Param("userName") String userName, @Param("sysDeptId") Integer sysDeptId);
+
+    boolean existsAttendanceUsedByConfig(@Param("configId") Integer configId);
 }
diff --git a/src/main/java/com/ruoyi/staff/mapper/SchemeApplicableStaffMapper.java b/src/main/java/com/ruoyi/staff/mapper/SchemeApplicableStaffMapper.java
index f58b76a..41cd653 100644
--- a/src/main/java/com/ruoyi/staff/mapper/SchemeApplicableStaffMapper.java
+++ b/src/main/java/com/ruoyi/staff/mapper/SchemeApplicableStaffMapper.java
@@ -26,6 +26,13 @@
     List<SchemeApplicableStaff> selectSchemeByStaffId(@Param("staffId") Long staffId);
 
     /**
+     * 鏍规嵁閮ㄩ棬ID鏌ヨ鏈�鏂扮ぞ淇濇柟妗�
+     * @param deptId 閮ㄩ棬ID
+     * @return 鏈�鏂扮ぞ淇濇柟妗�
+     */
+    SchemeApplicableStaff selectLatestSchemeByDeptId(@Param("deptId") Long deptId);
+
+    /**
      * 鏍规嵁绀句繚鏂规ID鏌ヨ瀵瑰簲鐨勬槑缁嗗垪琛�
      * @param schemeId 绀句繚鏂规ID
      * @return 鏂规鏄庣粏鍒楄〃
diff --git a/src/main/java/com/ruoyi/staff/mapper/StaffSalaryMainMapper.java b/src/main/java/com/ruoyi/staff/mapper/StaffSalaryMainMapper.java
index eca5dbe..7e29494 100644
--- a/src/main/java/com/ruoyi/staff/mapper/StaffSalaryMainMapper.java
+++ b/src/main/java/com/ruoyi/staff/mapper/StaffSalaryMainMapper.java
@@ -4,6 +4,8 @@
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.util.List;
+
 /**
  * <p>
  * 鍛樺伐宸ヨ祫涓昏〃 Mapper 鎺ュ彛
@@ -15,4 +17,6 @@
 @Mapper
 public interface StaffSalaryMainMapper extends BaseMapper<StaffSalaryMain> {
 
+    List<String> selectIssuedDeptIds(String salaryMonth);
+
 }
diff --git a/src/main/java/com/ruoyi/staff/pojo/PersonalAttendanceLocationConfig.java b/src/main/java/com/ruoyi/staff/pojo/PersonalAttendanceLocationConfig.java
index 13e0ca5..13e93c8 100644
--- a/src/main/java/com/ruoyi/staff/pojo/PersonalAttendanceLocationConfig.java
+++ b/src/main/java/com/ruoyi/staff/pojo/PersonalAttendanceLocationConfig.java
@@ -61,6 +61,28 @@
 
     @Schema(description = "鐝")
     private String shift;
+
+    /**
+     * 鏄惁宸茶鎺掔彮涓斿凡鏈夋墦鍗¤褰曚娇鐢�
+     */
+    @Schema(description = "鏄惁宸茶鎺掔彮涓斿凡鏈夋墦鍗¤褰曚娇鐢�")
+    @TableField(exist = false)
+    private Boolean usageLocked;
+
+    /**
+     * 鏄惁鍙紪杈�
+     */
+    @Schema(description = "鏄惁鍙紪杈�")
+    @TableField(exist = false)
+    private Boolean canEdit;
+
+    /**
+     * 鏄惁鍙垹闄�
+     */
+    @Schema(description = "鏄惁鍙垹闄�")
+    @TableField(exist = false)
+    private Boolean canDelete;
+
     @Schema(description = "鍒涘缓鐢ㄦ埛")
     @TableField(fill = FieldFill.INSERT)
     private Integer createUser;
diff --git a/src/main/java/com/ruoyi/staff/pojo/StaffOnJob.java b/src/main/java/com/ruoyi/staff/pojo/StaffOnJob.java
index bff864a..ccf8a57 100644
--- a/src/main/java/com/ruoyi/staff/pojo/StaffOnJob.java
+++ b/src/main/java/com/ruoyi/staff/pojo/StaffOnJob.java
@@ -77,7 +77,6 @@
     /**
      * 瀹跺涵浣忓潃
      */
-    @Excel(name = "瀹跺涵浣忓潃", sort = 6)
     private String adress;
 
     /**
diff --git a/src/main/java/com/ruoyi/staff/pojo/StaffSalaryDetail.java b/src/main/java/com/ruoyi/staff/pojo/StaffSalaryDetail.java
index 6cbe396..e616c2b 100644
--- a/src/main/java/com/ruoyi/staff/pojo/StaffSalaryDetail.java
+++ b/src/main/java/com/ruoyi/staff/pojo/StaffSalaryDetail.java
@@ -68,6 +68,9 @@
     @Schema(description = "鍏朵粬鏀嚭")
     private BigDecimal otherDeduct;
 
+    @Schema(description = "绀句繚琛ョ即")
+    private BigDecimal socialSupplementAmount;
+
     @Schema(description = "宸ヨ祫涓◣")
     private BigDecimal salaryTax;
 
diff --git a/src/main/java/com/ruoyi/staff/service/PersonalAttendanceLocationConfigService.java b/src/main/java/com/ruoyi/staff/service/PersonalAttendanceLocationConfigService.java
index 14afa19..f5c1205 100644
--- a/src/main/java/com/ruoyi/staff/service/PersonalAttendanceLocationConfigService.java
+++ b/src/main/java/com/ruoyi/staff/service/PersonalAttendanceLocationConfigService.java
@@ -13,4 +13,19 @@
  */
 public interface PersonalAttendanceLocationConfigService extends IService<PersonalAttendanceLocationConfig> {
 
+    /**
+     * 鍒ゆ柇鐝閰嶇疆鏄惁宸茶鎺掔彮涓斿凡鏈夋墦鍗¤褰曚娇鐢ㄣ��
+     */
+    boolean hasAttendanceUsage(Integer configId);
+
+    /**
+     * 鍒ゆ柇鐝閰嶇疆鏄惁鍏佽缂栬緫銆�
+     */
+    boolean canEdit(Integer configId);
+
+    /**
+     * 鍒ゆ柇鐝閰嶇疆鏄惁鍏佽鍒犻櫎銆�
+     */
+    boolean canDelete(Integer configId);
+
 }
diff --git a/src/main/java/com/ruoyi/staff/service/StaffSalaryMainService.java b/src/main/java/com/ruoyi/staff/service/StaffSalaryMainService.java
index 1794e43..0317a3b 100644
--- a/src/main/java/com/ruoyi/staff/service/StaffSalaryMainService.java
+++ b/src/main/java/com/ruoyi/staff/service/StaffSalaryMainService.java
@@ -3,7 +3,9 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.staff.dto.CalculateSalaryDto;
+import com.ruoyi.staff.dto.StaffSalaryCalculateDto;
 import com.ruoyi.staff.pojo.StaffSalaryMain;
+import jakarta.servlet.http.HttpServletResponse;
 import com.baomidou.mybatisplus.extension.service.IService;
 
 import java.util.List;
@@ -27,4 +29,10 @@
     AjaxResult delete(List<Long> ids);
 
     AjaxResult calculateSalary(CalculateSalaryDto calculateSalaryDto);
+
+    AjaxResult calculateSalaryByEmployee(StaffSalaryCalculateDto staffSalaryCalculateDto);
+
+    void exportSalaryDetail(HttpServletResponse response, String salaryMonth);
+
+    AjaxResult getAvailableDepts(String salaryMonth);
 }
diff --git a/src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceLocationConfigServiceImpl.java b/src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceLocationConfigServiceImpl.java
index b1dffca..7548db8 100644
--- a/src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceLocationConfigServiceImpl.java
+++ b/src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceLocationConfigServiceImpl.java
@@ -1,15 +1,12 @@
 package com.ruoyi.staff.service.impl;
 
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.ruoyi.common.exception.base.BaseException;
-import com.ruoyi.staff.pojo.PersonalAttendanceLocationConfig;
-import com.ruoyi.staff.mapper.PersonalAttendanceLocationConfigMapper;
-import com.ruoyi.staff.service.PersonalAttendanceLocationConfigService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import org.springframework.beans.factory.annotation.Autowired;
+import com.ruoyi.staff.mapper.PersonalAttendanceLocationConfigMapper;
+import com.ruoyi.staff.mapper.PersonalShiftMapper;
+import com.ruoyi.staff.pojo.PersonalAttendanceLocationConfig;
+import com.ruoyi.staff.service.PersonalAttendanceLocationConfigService;
+import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
-
-import java.util.List;
 
 /**
  * <p>
@@ -20,6 +17,26 @@
  * @since 2026-02-11 09:41:34
  */
 @Service
+@RequiredArgsConstructor
 public class PersonalAttendanceLocationConfigServiceImpl extends ServiceImpl<PersonalAttendanceLocationConfigMapper, PersonalAttendanceLocationConfig> implements PersonalAttendanceLocationConfigService {
 
+    private final PersonalShiftMapper personalShiftMapper;
+
+    @Override
+    public boolean hasAttendanceUsage(Integer configId) {
+        if (configId == null) {
+            return false;
+        }
+        return personalShiftMapper.existsAttendanceUsedByConfig(configId);
+    }
+
+    @Override
+    public boolean canEdit(Integer configId) {
+        return !hasAttendanceUsage(configId);
+    }
+
+    @Override
+    public boolean canDelete(Integer configId) {
+        return !hasAttendanceUsage(configId);
+    }
 }
diff --git a/src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceRecordsServiceImpl.java b/src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceRecordsServiceImpl.java
index 48c6745..14d522c 100644
--- a/src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceRecordsServiceImpl.java
+++ b/src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceRecordsServiceImpl.java
@@ -72,7 +72,8 @@
         List<PersonalShift> personalShifts = personalShiftMapper.selectList(Wrappers.<PersonalShift>lambdaQuery()
                 .eq(PersonalShift::getStaffOnJobId, staffOnJob.getId())
                 .eq(PersonalShift::getWorkTime, currentDate.atStartOfDay())
-                .isNotNull(PersonalShift::getPersonalAttendanceLocationConfigId));
+                .isNotNull(PersonalShift::getPersonalAttendanceLocationConfigId)
+                .ne(PersonalShift::getPersonalAttendanceLocationConfigId, 999));
         if (CollectionUtil.isEmpty(personalShifts)){
             throw new BaseException("褰撳墠鐢ㄦ埛褰撳ぉ娌℃湁鎺掔彮鏁版嵁");
         }
@@ -230,12 +231,15 @@
         List<PersonalShift> personalShifts = personalShiftMapper.selectList(Wrappers.<PersonalShift>lambdaQuery()
                 .eq(PersonalShift::getStaffOnJobId, staffOnJob.getId())
                 .eq(PersonalShift::getWorkTime, currentDate.atStartOfDay())
-                .isNotNull(PersonalShift::getPersonalAttendanceLocationConfigId));
+                .isNotNull(PersonalShift::getPersonalAttendanceLocationConfigId)
+                .ne(PersonalShift::getPersonalAttendanceLocationConfigId, 999));
         if (CollectionUtil.isNotEmpty(personalShifts)){
             PersonalAttendanceLocationConfig personalAttendanceLocationConfig = personalAttendanceLocationConfigMapper.selectById(personalShifts.get(0).getPersonalAttendanceLocationConfigId());
-            resultDto.setStartAt(personalAttendanceLocationConfig.getStartAt());
-            resultDto.setEndAt(personalAttendanceLocationConfig.getEndAt());
-            resultDto.setShift(personalAttendanceLocationConfig.getShift());
+            if (personalAttendanceLocationConfig != null) {
+                resultDto.setStartAt(personalAttendanceLocationConfig.getStartAt());
+                resultDto.setEndAt(personalAttendanceLocationConfig.getEndAt());
+                resultDto.setShift(personalAttendanceLocationConfig.getShift());
+            }
         }
         return resultDto;
     }
diff --git a/src/main/java/com/ruoyi/staff/service/impl/SchemeApplicableStaffServiceImpl.java b/src/main/java/com/ruoyi/staff/service/impl/SchemeApplicableStaffServiceImpl.java
index 793f94f..60607ba 100644
--- a/src/main/java/com/ruoyi/staff/service/impl/SchemeApplicableStaffServiceImpl.java
+++ b/src/main/java/com/ruoyi/staff/service/impl/SchemeApplicableStaffServiceImpl.java
@@ -25,6 +25,7 @@
 import org.springframework.util.CollectionUtils;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
@@ -153,100 +154,85 @@
      * @param id
      */
     public void calculateByEmployeeId(Integer id,Map<String, Object> map,String date) {
-        // 1. 鍏ュ弬鏍¢獙
-        if (id == null) {
-            return; // 鎴栬繑鍥炵┖鍒楄〃锛屾牴鎹笟鍔¢渶姹傝皟鏁�
+        if (id == null || map == null) {
+            return;
         }
         Long staffId = id.longValue();
-        // 绀句繚閲戦
-        BigDecimal socialPersonal = new BigDecimal("0.00");
-        // 鍏Н閲戦噾棰�
-        BigDecimal fundPersonal = new BigDecimal("0.00");
-        // 鍩烘湰宸ヨ祫
-        BigDecimal basicSalary = new BigDecimal("0.00");
-        map.put("fundPersonal", fundPersonal); // 鍏Н閲�
-        map.put("socialPersonal", socialPersonal); // 绀句繚閲戦
-        map.put("basicSalary", basicSalary); // 鍩烘湰宸ヨ祫
-        // 涓◣閲戦
-        BigDecimal salaryTax = new BigDecimal("0.00");
-        map.put("salaryTax", salaryTax);
-        // 璁′欢宸ヨ祫
-        BigDecimal pieceSalary = new BigDecimal("0.00");
-        map.put("pieceSalary", pieceSalary);
-        // 璁℃椂宸ヨ祫
-        BigDecimal hourlySalary = new BigDecimal("0.00");
-        map.put("hourlySalary", hourlySalary);
-        // 鍏朵粬鏀跺叆
-        BigDecimal otherIncome = new BigDecimal("0.00");
-        map.put("otherIncome", otherIncome);
-        // 鍏朵粬鏀嚭
-        BigDecimal otherDeduct = new BigDecimal("0.00");
-        map.put("otherDeduct", otherDeduct);
-        // 搴斿彂宸ヨ祫
-        BigDecimal grossSalary = new BigDecimal("0.00");
-        map.put("grossSalary", grossSalary);
-        // 搴旀墸宸ヨ祫
-        BigDecimal deductSalary = new BigDecimal("0.00");
-        map.put("deductSalary", deductSalary);
-        // 瀹炲彂宸ヨ祫
-        BigDecimal netSalary = new BigDecimal("0.00");
-        map.put("netSalary", netSalary);
-        // 璋冪敤鍩烘湰宸ヨ祫
         StaffOnJob staffOnJobDto = staffOnJobMapper.selectById(staffId);
         if(staffOnJobDto == null){
             return;
         }
-        basicSalary = staffOnJobDto.getBasicSalary();
-        map.put("basicSalary", basicSalary);
-        // 搴斿彂宸ヨ祫
-        map.put("grossSalary", basicSalary);
-        // 涓◣閲戦锛堟棤绀句繚鐗堬級
-        BigDecimal bigDecimal = TaxCalculator.calculateMonthlyTax(basicSalary, socialPersonal, fundPersonal);
-        map.put("salaryTax", bigDecimal);
-        // 璁℃椂宸ヨ祫 璁′欢宸ヨ祫
+        BigDecimal basicSalary = hasValue(map, "basicSalary")
+                ? normalizeMoney(getBigDecimal(map, "basicSalary"))
+                : normalizeMoney(staffOnJobDto.getBasicSalary());
+        BigDecimal otherIncome = normalizeMoney(getBigDecimal(map, "otherIncome"));
+        BigDecimal otherDeduct = normalizeMoney(getBigDecimal(map, "otherDeduct"));
+        BigDecimal socialSupplementAmount = hasValue(map, "socialSupplementAmount")
+                ? normalizeMoney(getBigDecimal(map, "socialSupplementAmount"))
+                : calculateLatestDeptSocialSupplementAmount(staffOnJobDto);
+        BigDecimal pieceSalary = normalizeMoney(getBigDecimal(map, "pieceSalary"));
+        BigDecimal hourlySalary = normalizeMoney(getBigDecimal(map, "hourlySalary"));
+        BigDecimal socialPersonal = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
+        BigDecimal fundPersonal = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
+
         UserProductionAccountingDto userProductionAccountingDto = new UserProductionAccountingDto();
         userProductionAccountingDto.setUserId(getUidByStaffId(staffId));
         userProductionAccountingDto.setDate(date);
         UserAccountDto byUserId = salesLedgerProductionAccountingService.getByUserId(userProductionAccountingDto);
         if(byUserId != null){
-            map.put("pieceSalary", byUserId.getAccountBalance());
-            map.put("hourlySalary", byUserId.getAccount());
-            // 搴斿彂 瀹炲彂澧炲姞
-            grossSalary = grossSalary.add(byUserId.getAccountBalance()).add(byUserId.getAccount());
-            map.put("grossSalary", grossSalary);
-            netSalary = netSalary.add(byUserId.getAccountBalance()).add(byUserId.getAccount());
-            map.put("netSalary", netSalary);
+            pieceSalary = normalizeMoney(byUserId.getAccountBalance());
+            hourlySalary = normalizeMoney(byUserId.getAccount());
         }
-        // 2. 鏌ヨ璇ヤ汉鍛樺搴旂殑绀句繚鏂规
+
+        // 鏌ヨ璇ヤ汉鍛樺搴旂殑绀句繚鏂规
         List<SchemeApplicableStaff> schemeList = schemeApplicableStaffMapper.selectSchemeByStaffId(staffId);
-        if (CollectionUtils.isEmpty(schemeList)) {
-            return; // 鏃犲尮閰嶆柟妗堬紝杩斿洖绌哄垪琛�
-        }
-        // 3. 涓烘瘡涓柟妗堝叧鑱旀槑缁嗗垪琛�
-        for (SchemeApplicableStaff scheme : schemeList) {
-            List<SchemeInsuranceDetail> detailList = schemeApplicableStaffMapper.selectDetailBySchemeId(scheme.getId());
-            // 鏍规嵁鏄庣粏鍒楄〃璁$畻绀句繚缂磋垂閲戦
-            if(CollectionUtils.isEmpty(detailList)){
-                continue;
-            }
-            for (SchemeInsuranceDetail detail : detailList) {
-                if("鍏Н閲�".equals(detail.getInsuranceType())){
-                    fundPersonal = fundPersonal.add(calculateByEmployeeIdType(detail.getInsuranceType(),fundPersonal, staffOnJobDto, detail));
-                }else{
-                    socialPersonal = socialPersonal.add(calculateByEmployeeIdType(detail.getInsuranceType(),socialPersonal, staffOnJobDto, detail));
+        if (!CollectionUtils.isEmpty(schemeList)) {
+            for (SchemeApplicableStaff scheme : schemeList) {
+                List<SchemeInsuranceDetail> detailList = schemeApplicableStaffMapper.selectDetailBySchemeId(scheme.getId());
+                if(CollectionUtils.isEmpty(detailList)){
+                    continue;
+                }
+                for (SchemeInsuranceDetail detail : detailList) {
+                    if("鍏Н閲�".equals(detail.getInsuranceType())){
+                        fundPersonal = calculateByEmployeeIdType(detail.getInsuranceType(), fundPersonal, basicSalary, staffOnJobDto, detail);
+                    }else{
+                        socialPersonal = calculateByEmployeeIdType(detail.getInsuranceType(), socialPersonal, basicSalary, staffOnJobDto, detail);
+                    }
                 }
             }
         }
+
+        BigDecimal grossSalary = basicSalary.add(pieceSalary).add(hourlySalary).add(otherIncome);
+        BigDecimal salaryTax = TaxCalculator.calculateMonthlyTax(
+                grossSalary,
+                socialPersonal.add(socialSupplementAmount),
+                fundPersonal
+        );
+        BigDecimal deductSalary = salaryTax
+                .add(fundPersonal)
+                .add(socialPersonal)
+                .add(socialSupplementAmount)
+                .add(otherDeduct);
+        BigDecimal netSalary = grossSalary.subtract(deductSalary);
+
+        if (!hasText(map, "staffName")) {
+            map.put("staffName", staffOnJobDto.getStaffName());
+        }
+        if (!hasText(map, "nation")) {
+            map.put("nation", staffOnJobDto.getNation());
+        }
+        map.put("basicSalary", basicSalary);
+        map.put("pieceSalary", pieceSalary);
+        map.put("hourlySalary", hourlySalary);
+        map.put("otherIncome", otherIncome);
         map.put("socialPersonal", socialPersonal);
         map.put("fundPersonal", fundPersonal);
-        // 涓◣閲戦锛堢ぞ淇濈増锛�
-        bigDecimal = TaxCalculator.calculateMonthlyTax(basicSalary, socialPersonal, fundPersonal);
-        map.put("salaryTax", bigDecimal);
-        // 搴旀墸宸ヨ祫
-        map.put("deductSalary", bigDecimal.add(fundPersonal).add(socialPersonal));
-        // 瀹炲彂宸ヨ祫
-        map.put("netSalary", basicSalary.subtract(bigDecimal).subtract(fundPersonal).subtract(socialPersonal));
-
+        map.put("otherDeduct", otherDeduct);
+        map.put("socialSupplementAmount", socialSupplementAmount);
+        map.put("grossSalary", grossSalary);
+        map.put("salaryTax", salaryTax);
+        map.put("deductSalary", deductSalary);
+        map.put("netSalary", netSalary);
     }
 
     /**
@@ -277,17 +263,81 @@
      * @param detail
      * @return
      */
-    public BigDecimal calculateByEmployeeIdType(String type,BigDecimal bigDecimal, StaffOnJob staffOnJobDto,SchemeInsuranceDetail detail) {
+    public BigDecimal calculateByEmployeeIdType(String type,BigDecimal bigDecimal, BigDecimal basicSalary, StaffOnJob staffOnJobDto,SchemeInsuranceDetail detail) {
         // 鍒ゆ柇鏄惁璋冪敤鍩烘湰宸ヨ祫
         if (detail.getUseBasicSalary() == 1) {
             BigDecimal divide = detail.getPaymentBase().multiply(detail.getPersonalRatio()).divide(new BigDecimal("100"), 2);
             bigDecimal = bigDecimal.add(divide);
         }else{
-            // 璋冪敤鍩烘湰宸ヨ祫
-            BigDecimal multiply = staffOnJobDto.getBasicSalary().multiply(detail.getPersonalRatio().divide(new BigDecimal("100"), 2));
+            // 璋冪敤褰撳墠宸ヨ祫琛ㄤ腑鐨勫熀鏈伐璧�
+            BigDecimal multiply = basicSalary.multiply(detail.getPersonalRatio().divide(new BigDecimal("100"), 2));
             bigDecimal = bigDecimal.add(multiply);
         }
         bigDecimal = bigDecimal.add(detail.getPersonalFixed());
         return bigDecimal;
     }
+
+    private BigDecimal calculateLatestDeptSocialSupplementAmount(StaffOnJob staffOnJobDto) {
+        if (staffOnJobDto == null || staffOnJobDto.getSysDeptId() == null) {
+            return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
+        }
+        SchemeApplicableStaff latestScheme = schemeApplicableStaffMapper.selectLatestSchemeByDeptId(staffOnJobDto.getSysDeptId());
+        if (latestScheme == null) {
+            return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
+        }
+        List<SchemeInsuranceDetail> detailList = schemeApplicableStaffMapper.selectDetailBySchemeId(latestScheme.getId());
+        if (CollectionUtils.isEmpty(detailList)) {
+            return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
+        }
+        BigDecimal socialSupplementAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
+        for (SchemeInsuranceDetail detail : detailList) {
+            if (!"鍏Н閲�".equals(detail.getInsuranceType())) {
+                socialSupplementAmount = calculateByEmployeeIdType(
+                        detail.getInsuranceType(),
+                        socialSupplementAmount,
+                        normalizeMoney(staffOnJobDto.getBasicSalary()),
+                        staffOnJobDto,
+                        detail
+                );
+            }
+        }
+        return socialSupplementAmount.setScale(2, RoundingMode.HALF_UP);
+    }
+
+    private boolean hasValue(Map<String, Object> map, String key) {
+        return map != null && map.get(key) != null;
+    }
+
+    private boolean hasText(Map<String, Object> map, String key) {
+        if (map == null) {
+            return false;
+        }
+        Object value = map.get(key);
+        return value != null && !String.valueOf(value).trim().isEmpty();
+    }
+
+    private BigDecimal getBigDecimal(Map<String, Object> map, String key) {
+        if (map == null) {
+            return null;
+        }
+        Object value = map.get(key);
+        if (value == null) {
+            return null;
+        }
+        if (value instanceof BigDecimal) {
+            return (BigDecimal) value;
+        }
+        if (value instanceof Number) {
+            return new BigDecimal(String.valueOf(value));
+        }
+        String text = String.valueOf(value).trim();
+        if (text.isEmpty()) {
+            return null;
+        }
+        return new BigDecimal(text);
+    }
+
+    private BigDecimal normalizeMoney(BigDecimal value) {
+        return value == null ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP) : value.setScale(2, RoundingMode.HALF_UP);
+    }
 }
diff --git a/src/main/java/com/ruoyi/staff/service/impl/StaffSalaryMainServiceImpl.java b/src/main/java/com/ruoyi/staff/service/impl/StaffSalaryMainServiceImpl.java
index dcbd9c7..41f8af3 100644
--- a/src/main/java/com/ruoyi/staff/service/impl/StaffSalaryMainServiceImpl.java
+++ b/src/main/java/com/ruoyi/staff/service/impl/StaffSalaryMainServiceImpl.java
@@ -4,9 +4,15 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.project.system.domain.SysDept;
+import com.ruoyi.project.system.mapper.SysDeptMapper;
 import com.ruoyi.project.system.mapper.SysUserDeptMapper;
+import com.ruoyi.staff.excel.StaffSalaryExportData;
+import jakarta.servlet.http.HttpServletResponse;
 import com.ruoyi.staff.dto.CalculateSalaryDto;
+import com.ruoyi.staff.dto.StaffSalaryCalculateDto;
 import com.ruoyi.staff.mapper.StaffLeaveMapper;
 import com.ruoyi.staff.mapper.StaffSalaryDetailMapper;
 import com.ruoyi.staff.mapper.StaffSalaryMainMapper;
@@ -20,8 +26,12 @@
 import org.springframework.util.CollectionUtils;
 
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * <p>
@@ -41,6 +51,7 @@
     private final SchemeApplicableStaffServiceImpl schemeApplicableStaffService;
     private final SysUserDeptMapper sysUserDeptMapper;
     private final StaffLeaveMapper staffLeaveMapper;
+    private final SysDeptMapper sysDeptMapper;
 
     @Override
     public AjaxResult listPage(Page page, StaffSalaryMain staffSalaryMain) {
@@ -67,6 +78,26 @@
 
     @Override
     public AjaxResult add(StaffSalaryMain staffSalaryMain) {
+        if (staffSalaryMain == null || StringUtils.isEmpty(staffSalaryMain.getSalaryMonth())) {
+            return AjaxResult.error("鍙傛暟閿欒");
+        }
+
+        Integer status = staffSalaryMain.getStatus();
+        if (status != null && status == 5) {
+            String salaryMonth = staffSalaryMain.getSalaryMonth();
+            String deptIds = staffSalaryMain.getDeptIds();
+
+            List<StaffSalaryMain> issuedList = staffSalaryMainMapper.selectList(new LambdaQueryWrapper<StaffSalaryMain>()
+                    .eq(StaffSalaryMain::getSalaryMonth, salaryMonth)
+                    .eq(StaffSalaryMain::getStatus, 5));
+
+            for (StaffSalaryMain issued : issuedList) {
+                if (hasOverlappingDept(deptIds, issued.getDeptIds())) {
+                    return AjaxResult.error("鍚屼竴鏈堜唤鍚屼竴閮ㄩ棬宸ヨ祫涓嶅彲浠ュ彂鏀惧娆�");
+                }
+            }
+        }
+
         staffSalaryMainMapper.insert(staffSalaryMain);
         staffSalaryMain.getStaffSalaryDetailList().forEach(detail -> {
             detail.setMainId(staffSalaryMain.getId());
@@ -84,6 +115,30 @@
         if(staffSalaryMain1 == null){
             return AjaxResult.error("鍙傛暟閿欒");
         }
+
+        Integer newStatus = staffSalaryMain.getStatus();
+        if (newStatus != null && newStatus == 5) {
+            String salaryMonth = staffSalaryMain.getSalaryMonth();
+            if (StringUtils.isEmpty(salaryMonth)) {
+                salaryMonth = staffSalaryMain1.getSalaryMonth();
+            }
+            String deptIds = staffSalaryMain.getDeptIds();
+            if (StringUtils.isEmpty(deptIds)) {
+                deptIds = staffSalaryMain1.getDeptIds();
+            }
+
+            List<StaffSalaryMain> issuedList = staffSalaryMainMapper.selectList(new LambdaQueryWrapper<StaffSalaryMain>()
+                    .eq(StaffSalaryMain::getSalaryMonth, salaryMonth)
+                    .eq(StaffSalaryMain::getStatus, 5)
+                    .ne(StaffSalaryMain::getId, staffSalaryMain.getId()));
+
+            for (StaffSalaryMain issued : issuedList) {
+                if (hasOverlappingDept(deptIds, issued.getDeptIds())) {
+                    return AjaxResult.error("鍚屼竴鏈堜唤鍚屼竴閮ㄩ棬宸ヨ祫涓嶅彲浠ュ彂鏀惧娆�");
+                }
+            }
+        }
+
         // 寰呭鏍镐笉鍙紪杈�
 //        if(staffSalaryMain1.getStatus() > 3){
 //            return AjaxResult.error("寰呭鏍镐笉鍙紪杈�");
@@ -135,6 +190,84 @@
         return AjaxResult.success(mapList);
     }
 
+    @Override
+    public AjaxResult calculateSalaryByEmployee(StaffSalaryCalculateDto staffSalaryCalculateDto) {
+        if (staffSalaryCalculateDto == null
+                || staffSalaryCalculateDto.getStaffOnJobId() == null
+                || StringUtils.isEmpty(staffSalaryCalculateDto.getSalaryMonth())) {
+            return AjaxResult.error("鍙傛暟閿欒");
+        }
+        Map<String, Object> map = new HashMap<>();
+        map.put("id", staffSalaryCalculateDto.getStaffOnJobId());
+        map.put("staffOnJobId", staffSalaryCalculateDto.getStaffOnJobId());
+        map.put("salaryMonth", staffSalaryCalculateDto.getSalaryMonth());
+        map.put("staffName", staffSalaryCalculateDto.getStaffName());
+        map.put("postName", staffSalaryCalculateDto.getPostName());
+        map.put("deptName", staffSalaryCalculateDto.getDeptName());
+        if (staffSalaryCalculateDto.getBasicSalary() != null) {
+            map.put("basicSalary", staffSalaryCalculateDto.getBasicSalary());
+        }
+        map.put("pieceSalary", staffSalaryCalculateDto.getPieceSalary());
+        map.put("hourlySalary", staffSalaryCalculateDto.getHourlySalary());
+        map.put("otherIncome", staffSalaryCalculateDto.getOtherIncome());
+        map.put("socialPersonal", staffSalaryCalculateDto.getSocialPersonal());
+        map.put("fundPersonal", staffSalaryCalculateDto.getFundPersonal());
+        map.put("otherDeduct", staffSalaryCalculateDto.getOtherDeduct());
+        map.put("socialSupplementAmount", staffSalaryCalculateDto.getSocialSupplementAmount());
+        map.put("salaryTax", staffSalaryCalculateDto.getSalaryTax());
+        map.put("grossSalary", staffSalaryCalculateDto.getGrossSalary());
+        map.put("deductSalary", staffSalaryCalculateDto.getDeductSalary());
+        map.put("netSalary", staffSalaryCalculateDto.getNetSalary());
+        map.put("remark", staffSalaryCalculateDto.getRemark());
+        schemeApplicableStaffService.calculateByEmployeeId(
+                staffSalaryCalculateDto.getStaffOnJobId().intValue(),
+                map,
+                staffSalaryCalculateDto.getSalaryMonth()
+        );
+        return AjaxResult.success(map);
+    }
+
+    @Override
+    public void exportSalaryDetail(HttpServletResponse response, String salaryMonth) {
+        LambdaQueryWrapper<StaffSalaryMain> mainWrapper = new LambdaQueryWrapper<>();
+        if (StringUtils.isNotEmpty(salaryMonth)) {
+            mainWrapper.eq(StaffSalaryMain::getSalaryMonth, salaryMonth);
+        }
+        List<StaffSalaryMain> mainList = staffSalaryMainMapper.selectList(mainWrapper);
+
+        List<StaffSalaryExportData> exportDataList = new ArrayList<>();
+        for (StaffSalaryMain main : mainList) {
+            List<StaffSalaryDetail> detailList = staffSalaryDetailMapper.selectList(
+                    new LambdaQueryWrapper<StaffSalaryDetail>().eq(StaffSalaryDetail::getMainId, main.getId())
+            );
+
+            for (StaffSalaryDetail detail : detailList) {
+                StaffSalaryExportData exportData = new StaffSalaryExportData();
+                exportData.setSalaryMonth(main.getSalaryMonth());
+                exportData.setSalaryTitle(main.getSalaryTitle());
+                exportData.setStaffName(detail.getStaffName());
+                exportData.setDeptName(detail.getDeptName());
+                exportData.setBasicSalary(detail.getBasicSalary());
+                exportData.setPieceSalary(detail.getPieceSalary());
+                exportData.setHourlySalary(detail.getHourlySalary());
+                exportData.setOtherIncome(detail.getOtherIncome());
+                exportData.setSocialPersonal(detail.getSocialPersonal());
+                exportData.setFundPersonal(detail.getFundPersonal());
+                exportData.setOtherDeduct(detail.getOtherDeduct());
+                exportData.setSocialSupplementAmount(detail.getSocialSupplementAmount());
+                exportData.setSalaryTax(detail.getSalaryTax());
+                exportData.setGrossSalary(detail.getGrossSalary());
+                exportData.setDeductSalary(detail.getDeductSalary());
+                exportData.setNetSalary(detail.getNetSalary());
+                exportData.setRemark(detail.getRemark());
+                exportDataList.add(exportData);
+            }
+        }
+
+        ExcelUtil<StaffSalaryExportData> util = new ExcelUtil<>(StaffSalaryExportData.class);
+        util.exportExcel(response, exportDataList, "鍛樺伐钖祫鏄庣粏");
+    }
+
     public List<Map<String, Object>> setSchemeApplicableStaffUserInfo(List<Long> ids) {
         if(CollectionUtils.isEmpty(ids)){
             return new ArrayList<>();
@@ -143,4 +276,52 @@
         return sysUserDeptMapper.setSchemeApplicableStaffUserInfo(ids);
     }
 
+    @Override
+    public AjaxResult getAvailableDepts(String salaryMonth) {
+        if (StringUtils.isEmpty(salaryMonth)) {
+            return AjaxResult.error("宸ヨ祫鏈堜唤涓嶈兘涓虹┖");
+        }
+
+        List<String> issuedDeptIdStrings = staffSalaryMainMapper.selectIssuedDeptIds(salaryMonth);
+
+        Set<Long> issuedDeptIds = new HashSet<>();
+        for (String deptIds : issuedDeptIdStrings) {
+            if (StringUtils.isNotEmpty(deptIds)) {
+                String[] ids = deptIds.split(",");
+                for (String id : ids) {
+                    issuedDeptIds.add(Long.parseLong(id.trim()));
+                }
+            }
+        }
+
+        List<SysDept> allDepts = sysDeptMapper.selectList(new LambdaQueryWrapper<SysDept>()
+                .eq(SysDept::getStatus, "0")
+                .eq(SysDept::getDelFlag, "0"));
+
+        List<SysDept> availableDepts = new ArrayList<>();
+        for (SysDept dept : allDepts) {
+            if (!issuedDeptIds.contains(dept.getDeptId())) {
+                availableDepts.add(dept);
+            }
+        }
+
+        return AjaxResult.success(availableDepts);
+    }
+
+    private boolean hasOverlappingDept(String deptIds1, String deptIds2) {
+        if (StringUtils.isEmpty(deptIds1) || StringUtils.isEmpty(deptIds2)) {
+            return false;
+        }
+
+        Set<String> deptSet1 = new HashSet<>(Arrays.asList(deptIds1.split(",")));
+        String[] deptArray2 = deptIds2.split(",");
+
+        for (String deptId : deptArray2) {
+            if (deptSet1.contains(deptId.trim())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
 }
diff --git a/src/main/java/com/ruoyi/stock/controller/StockOutRecordController.java b/src/main/java/com/ruoyi/stock/controller/StockOutRecordController.java
index 7351890..660cf31 100644
--- a/src/main/java/com/ruoyi/stock/controller/StockOutRecordController.java
+++ b/src/main/java/com/ruoyi/stock/controller/StockOutRecordController.java
@@ -87,4 +87,15 @@
         return AjaxResult.success();
     }
 
+    @PostMapping("/reAudit")
+    @Log(title = "鍑哄簱绠$悊-鍙嶅鍑哄簱", businessType = BusinessType.UPDATE)
+    @Operation(summary = "鎵归噺鍙嶅鍑哄簱璁板綍")
+    public AjaxResult reAudit(@RequestBody StockOutRecordDto approveDto) {
+        if(CollectionUtils.isEmpty(approveDto.getIds())){
+            return AjaxResult.error("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
+        }
+        stockOutRecordService.batchReAudit(approveDto.getIds());
+        return AjaxResult.success();
+    }
+
 }
diff --git a/src/main/java/com/ruoyi/stock/service/StockOutRecordService.java b/src/main/java/com/ruoyi/stock/service/StockOutRecordService.java
index bbad1f6..ca498b3 100644
--- a/src/main/java/com/ruoyi/stock/service/StockOutRecordService.java
+++ b/src/main/java/com/ruoyi/stock/service/StockOutRecordService.java
@@ -31,4 +31,6 @@
     void exportStockOutRecord(HttpServletResponse response, StockOutRecordDto stockOutRecordDto);
 
     int batchApprove(List<Long> ids, Integer approvalStatus);
+
+    int batchReAudit(List<Long> ids);
 }
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
index 61aac8b..00161b5 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
@@ -21,6 +21,14 @@
 import com.ruoyi.stock.execl.StockInRecordExportData;
 import com.ruoyi.production.mapper.ProductionOrderPickMapper;
 import com.ruoyi.production.pojo.ProductionOrderPick;
+import com.ruoyi.procurementrecord.mapper.ReturnManagementMapper;
+import com.ruoyi.procurementrecord.mapper.ReturnSaleProductMapper;
+import com.ruoyi.procurementrecord.pojo.ReturnManagement;
+import com.ruoyi.procurementrecord.pojo.ReturnSaleProduct;
+import com.ruoyi.sales.mapper.SalesLedgerMapper;
+import com.ruoyi.sales.mapper.ShippingInfoMapper;
+import com.ruoyi.sales.pojo.SalesLedger;
+import com.ruoyi.sales.pojo.ShippingInfo;
 import com.ruoyi.stock.mapper.StockInRecordMapper;
 import com.ruoyi.stock.mapper.StockInventoryMapper;
 import com.ruoyi.stock.mapper.StockUninventoryMapper;
@@ -45,6 +53,10 @@
     private StockInventoryMapper stockInventoryMapper;
     private StockUninventoryMapper stockUninventoryMapper;
     private ProductionOrderPickMapper productionOrderPickMapper;
+    private ReturnSaleProductMapper returnSaleProductMapper;
+    private ReturnManagementMapper returnManagementMapper;
+    private ShippingInfoMapper shippingInfoMapper;
+    private SalesLedgerMapper salesLedgerMapper;
 
     @Override
     public IPage<StockInRecordDto> listPage(Page page, StockInRecordDto stockInRecordDto) {
@@ -55,8 +67,13 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public int add(StockInRecordDto stockInRecordDto) {
-        String no = OrderUtils.countTodayByCreateTime(stockInRecordMapper, "RK","inbound_batches", stockInRecordDto.getCreateTime() != null ? stockInRecordDto.getCreateTime() : LocalDateTime.now());
+        LocalDateTime createTime = stockInRecordDto.getCreateTime();
+        if (createTime == null) {
+            createTime = LocalDateTime.now();
+        }
+        String no = OrderUtils.countTodayByCreateTime(stockInRecordMapper, "RK","inbound_batches", createTime);
         stockInRecordDto.setInboundBatches(no);
+        stockInRecordDto.setCreateTime(createTime);
         StockInRecord stockInRecord = new StockInRecord();
         BeanUtils.copyProperties(stockInRecordDto, stockInRecord);
         return stockInRecordMapper.insert(stockInRecord);
@@ -241,14 +258,18 @@
                     stockInventoryDto.setQualitity(stockInRecord.getStockInNum());
                     stockInventoryDto.setRemark(stockInRecord.getRemark());
                     if (stockInventory == null) {
-                        stockInventoryMapper.insert(new StockInventory() {{
-                            setProductModelId(stockInRecord.getProductModelId());
-                            setQualitity(stockInRecord.getStockInNum());
-                            setBatchNo(stockInRecord.getBatchNo());
-                            setRemark(stockInRecord.getRemark());
-                            setWarnNum(stockInRecord.getWarnNum());
-                            setVersion(1);
-                        }});
+                        try {
+                            stockInventoryMapper.insert(new StockInventory() {{
+                                setProductModelId(stockInRecord.getProductModelId());
+                                setQualitity(stockInRecord.getStockInNum());
+                                setBatchNo(stockInRecord.getBatchNo());
+                                setRemark(stockInRecord.getRemark());
+                                setWarnNum(stockInRecord.getWarnNum());
+                                setVersion(1);
+                            }});
+                        } catch (org.springframework.dao.DuplicateKeyException e) {
+                            stockInventoryMapper.updateAddStockInventory(stockInventoryDto);
+                        }
                     } else {
                         stockInventoryMapper.updateAddStockInventory(stockInventoryDto);
                     }
@@ -261,17 +282,23 @@
                     stockUninventoryDto.setQualitity(stockInRecord.getStockInNum());
                     stockUninventoryDto.setRemark(stockInRecord.getRemark());
                     if (stockUninventory == null) {
-                        stockUninventoryMapper.insert(new StockUninventory() {{
-                            setProductModelId(stockInRecord.getProductModelId());
-                            setQualitity(stockInRecord.getStockInNum());
-                            setBatchNo(stockInRecord.getBatchNo());
-                            setRemark(stockInRecord.getRemark());
-                            setVersion(1);
-                        }});
+                        try {
+                            stockUninventoryMapper.insert(new StockUninventory() {{
+                                setProductModelId(stockInRecord.getProductModelId());
+                                setQualitity(stockInRecord.getStockInNum());
+                                setBatchNo(stockInRecord.getBatchNo());
+                                setRemark(stockInRecord.getRemark());
+                                setVersion(1);
+                            }});
+                        } catch (org.springframework.dao.DuplicateKeyException e) {
+                            stockUninventoryMapper.updateAddStockUnInventory(stockUninventoryDto);
+                        }
                     } else {
                         stockUninventoryMapper.updateAddStockUnInventory(stockUninventoryDto);
                     }
                 }
+                // 閿�鍞��璐у叆搴�:鎵e噺閿�鍞彴璐﹀疄闄呭悎鍚岄噾棰�(閫�璐х敓鏁�)
+                handleSalesReturnRefund(stockInRecord);
             }
         }
         return ids.size();
@@ -322,4 +349,47 @@
 
         return ids.size();
     }
+
+    /**
+     * 閿�鍞��璐у叆搴撳鎵归�氳繃鏃�,鎵e噺瀵瑰簲閿�鍞彴璐︾殑瀹為檯鍚堝悓閲戦銆�
+     * 鍏宠仈閾�:stock_in_record.record_id = return_sale_product.id
+     *        鈫� return_management.shipping_id = shipping_info.id
+     *        鈫� shipping_info.sales_ledger_id = sales_ledger.id
+     * 鍙鐞� record_type 涓� 14(鍚堟牸)鎴� 15(涓嶅悎鏍�)鐨勯攢鍞��璐у叆搴撱��
+     */
+    private void handleSalesReturnRefund(StockInRecord stockInRecord) {
+        String recordType = stockInRecord.getRecordType();
+        if (!StockInQualifiedRecordTypeEnum.RETURN_HE_IN.getCode().equals(recordType)
+                && !StockInQualifiedRecordTypeEnum.RETURN_UNSTOCK_IN.getCode().equals(recordType)) {
+            return;
+        }
+        if (stockInRecord.getRecordId() == null) {
+            return;
+        }
+        ReturnSaleProduct rsp = returnSaleProductMapper.selectById(stockInRecord.getRecordId());
+        if (rsp == null || rsp.getReturnManagementId() == null) {
+            return;
+        }
+        ReturnManagement rm = returnManagementMapper.selectById(rsp.getReturnManagementId());
+        if (rm == null || rm.getShippingId() == null) {
+            return;
+        }
+        ShippingInfo shippingInfo = shippingInfoMapper.selectById(rm.getShippingId());
+        if (shippingInfo == null || shippingInfo.getSalesLedgerId() == null) {
+            return;
+        }
+        SalesLedger salesLedger = salesLedgerMapper.selectById(shippingInfo.getSalesLedgerId());
+        if (salesLedger == null || salesLedger.getContractAmount() == null) {
+            return;
+        }
+        BigDecimal refund = rsp.getAmount() != null ? rsp.getAmount() : BigDecimal.ZERO;
+        if (refund.compareTo(BigDecimal.ZERO) == 0) {
+            return;
+        }
+        BigDecimal baseAmount = salesLedger.getNetContractAmount() != null
+                ? salesLedger.getNetContractAmount()
+                : salesLedger.getContractAmount();
+        salesLedger.setNetContractAmount(baseAmount.subtract(refund));
+        salesLedgerMapper.updateById(salesLedger);
+    }
 }
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
index c82ac34..07d70a5 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -105,7 +105,11 @@
             newStockInventory.setBatchNo(stockInventoryDto.getBatchNo());
             newStockInventory.setLockedQuantity(stockInventoryDto.getLockedQuantity());
             newStockInventory.setWarnNum(stockInventoryDto.getWarnNum());
-            stockInventoryMapper.insert(newStockInventory);
+            try {
+                stockInventoryMapper.insert(newStockInventory);
+            } catch (org.springframework.dao.DuplicateKeyException e) {
+                stockInventoryMapper.updateAddStockInventory(stockInventoryDto);
+            }
         } else {
             stockInventoryMapper.updateAddStockInventory(stockInventoryDto);
         }
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
index 26f0c2d..7138641 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
@@ -60,8 +60,13 @@
 
     @Override
     public int add(StockOutRecordDto stockOutRecordDto) {
-        String no = OrderUtils.countTodayByCreateTime(stockOutRecordMapper, "CK","outbound_batches", stockOutRecordDto.getCreateTime() != null ? stockOutRecordDto.getCreateTime() : LocalDateTime.now());
+        LocalDateTime createTime = stockOutRecordDto.getCreateTime();
+        if (createTime == null) {
+            createTime = LocalDateTime.now();
+        }
+        String no = OrderUtils.countTodayByCreateTime(stockOutRecordMapper, "CK","outbound_batches", createTime);
         stockOutRecordDto.setOutboundBatches(no);
+        stockOutRecordDto.setCreateTime(createTime);
         if (StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode().equals(stockOutRecordDto.getRecordType())){
             stockOutRecordDto.setApprovalStatus(3);
         }
@@ -210,6 +215,26 @@
         return ids.size();
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int batchReAudit(List<Long> ids) {
+        if (CollectionUtils.isEmpty(ids)) {
+            throw new BaseException("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
+        }
+        for (Long id : ids) {
+            StockOutRecord stockOutRecord = stockOutRecordMapper.selectById(id);
+            if (stockOutRecord == null) {
+                throw new BaseException("鍑哄簱璁板綍涓嶅瓨鍦�,鏃犳硶閲嶆柊瀹℃牳!!!");
+            }
+            if (!ReviewStatusEnum.REJECTED.getCode().equals(stockOutRecord.getApprovalStatus())) {
+                throw new BaseException("鍙湁椹冲洖鐘舵�佺殑璁板綍鎵嶈兘閲嶆柊瀹℃牳,鍑哄簱鎵规:" + stockOutRecord.getOutboundBatches());
+            }
+            stockOutRecord.setApprovalStatus(ReviewStatusEnum.PENDING_REVIEW.getCode());
+            stockOutRecordMapper.updateById(stockOutRecord);
+        }
+        return ids.size();
+    }
+
     private StockInventory getStockInventory(Long productModelId, String batchNo) {
         LambdaQueryWrapper<StockInventory> eq = new LambdaQueryWrapper<>();
         eq.eq(StockInventory::getProductModelId, productModelId);
diff --git a/src/main/java/com/ruoyi/technology/controller/TechnologyOperationController.java b/src/main/java/com/ruoyi/technology/controller/TechnologyOperationController.java
index ecf4f38..4279311 100644
--- a/src/main/java/com/ruoyi/technology/controller/TechnologyOperationController.java
+++ b/src/main/java/com/ruoyi/technology/controller/TechnologyOperationController.java
@@ -41,7 +41,7 @@
     @Log(title = "宸ュ簭鏇存柊", businessType = BusinessType.UPDATE)
     @Operation(summary = "淇敼宸ュ簭")
     public R update(@RequestBody com.ruoyi.technology.pojo.TechnologyOperation technologyOperation) {
-        return R.ok(technologyOperationService.updateById(technologyOperation));
+        return technologyOperationService.update(technologyOperation);
     }
 
     @DeleteMapping("/batchDelete")
diff --git a/src/main/java/com/ruoyi/technology/service/TechnologyOperationService.java b/src/main/java/com/ruoyi/technology/service/TechnologyOperationService.java
index 42ba667..ec301d6 100644
--- a/src/main/java/com/ruoyi/technology/service/TechnologyOperationService.java
+++ b/src/main/java/com/ruoyi/technology/service/TechnologyOperationService.java
@@ -16,6 +16,8 @@
 
     R add(TechnologyOperationDto technologyOperationDto);
 
+    R update(TechnologyOperation technologyOperation);
+
     String batchDelete(List<Long> ids);
 
     List<TechnologyOperationVo> listVo();
diff --git a/src/main/java/com/ruoyi/technology/service/impl/TechnologyOperationServiceImpl.java b/src/main/java/com/ruoyi/technology/service/impl/TechnologyOperationServiceImpl.java
index da9ed8b..a407cd6 100644
--- a/src/main/java/com/ruoyi/technology/service/impl/TechnologyOperationServiceImpl.java
+++ b/src/main/java/com/ruoyi/technology/service/impl/TechnologyOperationServiceImpl.java
@@ -57,6 +57,27 @@
         return R.ok();
     }
 
+    @Override
+    public R update(TechnologyOperation technologyOperation) {
+        if (technologyOperation.getId() == null) {
+            return R.fail("宸ュ簭ID涓嶈兘涓虹┖");
+        }
+        boolean updated = technologyOperationMapper.update(
+                null,
+                Wrappers.<TechnologyOperation>lambdaUpdate()
+                        .eq(TechnologyOperation::getId, technologyOperation.getId())
+                        .set(TechnologyOperation::getName, technologyOperation.getName())
+                        .set(TechnologyOperation::getNo, technologyOperation.getNo())
+                        .set(TechnologyOperation::getRemark, technologyOperation.getRemark())
+                        .set(TechnologyOperation::getSalaryQuota, technologyOperation.getSalaryQuota())
+                        .set(TechnologyOperation::getIsQuality, technologyOperation.getIsQuality())
+                        .set(TechnologyOperation::getIsProduction, technologyOperation.getIsProduction())
+                        .set(TechnologyOperation::getType, technologyOperation.getType())
+                        .set(TechnologyOperation::getDeviceLedgerId, technologyOperation.getDeviceLedgerId())
+        ) > 0;
+        return updated ? R.ok() : R.fail("淇敼澶辫触");
+    }
+
     /**
      * 鍒犻櫎宸ュ簭鍓嶆牎楠屾槸鍚﹀凡琚獴OM缁撴瀯鎴栧伐鑹鸿矾绾垮紩鐢ㄣ��
      */
diff --git a/src/main/resources/application-btw.yml b/src/main/resources/application-btw.yml
new file mode 100644
index 0000000..c532961
--- /dev/null
+++ b/src/main/resources/application-btw.yml
@@ -0,0 +1,268 @@
+# 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9003
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:3306/product-inventory-management-btw?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: xd@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_btw
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+#      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 6379
+      # 鏁版嵁搴撶储寮�
+      database: 0
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://1.15.17.182:9101 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/application-hjgc.yml b/src/main/resources/application-hjgc.yml
new file mode 100644
index 0000000..c49aa33
--- /dev/null
+++ b/src/main/resources/application-hjgc.yml
@@ -0,0 +1,268 @@
+# 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9003
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:11101/product-inventory-management-hjgc?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: xd@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_hjgc
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+#      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 11102
+      # 鏁版嵁搴撶储寮�
+      database: 0
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /data/javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /data/javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /data/javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://36.213.180.217:9013 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/application-hthb.yml b/src/main/resources/application-hthb.yml
new file mode 100644
index 0000000..543b8dd
--- /dev/null
+++ b/src/main/resources/application-hthb.yml
@@ -0,0 +1,268 @@
+# 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9003
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:3306/product-inventory-management-hthb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: xd@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_hthb
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+#      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 6379
+      # 鏁版嵁搴撶储寮�
+      database: 0
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://1.15.17.182:9089 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/application-jfhy.yml b/src/main/resources/application-jfhy.yml
new file mode 100644
index 0000000..ffee8bc
--- /dev/null
+++ b/src/main/resources/application-jfhy.yml
@@ -0,0 +1,268 @@
+# 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9003
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:3306/product-inventory-management-jfhy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: xd@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_jfhy
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+#      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 6379
+      # 鏁版嵁搴撶储寮�
+      database: 0
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://1.15.17.182:9099 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/application-khyy.yml b/src/main/resources/application-khyy.yml
new file mode 100644
index 0000000..acb4712
--- /dev/null
+++ b/src/main/resources/application-khyy.yml
@@ -0,0 +1,268 @@
+# 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9003
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:3306/product-inventory-management-khyy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: xd@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_khyy
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+#      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 6379
+      # 鏁版嵁搴撶储寮�
+      database: 0
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://1.15.17.182:9093 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/application-lsy.yml b/src/main/resources/application-lsy.yml
new file mode 100644
index 0000000..821119e
--- /dev/null
+++ b/src/main/resources/application-lsy.yml
@@ -0,0 +1,268 @@
+# 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9003
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:3306/product-inventory-management-lsy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: xd@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_lsy
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+#      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 6379
+      # 鏁版嵁搴撶储寮�
+      database: 0
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://1.15.17.182:9083 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/application-lt.yml b/src/main/resources/application-lt.yml
new file mode 100644
index 0000000..ef3fcb6
--- /dev/null
+++ b/src/main/resources/application-lt.yml
@@ -0,0 +1,268 @@
+# 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /data/javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9003
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:11101/product-inventory-management-lt?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: xd@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_lt
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+#      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 11102
+      # 鏁版嵁搴撶储寮�
+      database: 0
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /data/javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /data/javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /data/javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://36.213.180.217:9200 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/application-myhb-pro.yml b/src/main/resources/application-myhb-pro.yml
new file mode 100644
index 0000000..a94aa06
--- /dev/null
+++ b/src/main/resources/application-myhb-pro.yml
@@ -0,0 +1,268 @@
+# 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9110
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:3306/product-inventory-management-myhb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: xd@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_qlmc
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+      #      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 6379
+      # 鏁版嵁搴撶储寮�
+      database: 0
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://1.15.17.182:9095 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/application-nhxcl.yml b/src/main/resources/application-nhxcl.yml
new file mode 100644
index 0000000..5734844
--- /dev/null
+++ b/src/main/resources/application-nhxcl.yml
@@ -0,0 +1,268 @@
+# 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9003
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:3306/product-inventory-management-nhxcl?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: nhxcl@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_nhxcl
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+      #      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 6379
+      # 鏁版嵁搴撶储寮�
+      database: 0
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://127.0.0.1:9001 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/application-old-pro.yml b/src/main/resources/application-old-pro.yml
new file mode 100644
index 0000000..c61ef80
--- /dev/null
+++ b/src/main/resources/application-old-pro.yml
@@ -0,0 +1,268 @@
+# 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9003
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:9002/product-inventory-management-old-pro?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: old@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_old
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+#      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 6379
+      # 鏁版嵁搴撶储寮�
+      database: 0
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://223.221.37.139:9000 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/application-qfsw.yml b/src/main/resources/application-qfsw.yml
new file mode 100644
index 0000000..4ae73ec
--- /dev/null
+++ b/src/main/resources/application-qfsw.yml
@@ -0,0 +1,268 @@
+# 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9003
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:3306/product-inventory-management-qfsw?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: xd@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_qfsw
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+#      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 6379
+      # 鏁版嵁搴撶储寮�
+      database: 0
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://1.15.17.182:9079 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/application-qlmc-pro.yml b/src/main/resources/application-qlmc-pro.yml
new file mode 100644
index 0000000..1370c5d
--- /dev/null
+++ b/src/main/resources/application-qlmc-pro.yml
@@ -0,0 +1,268 @@
+# 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9096
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:3306/product-inventory-management-qlmc-pro?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: xd@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_qlmc
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+      #      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 6379
+      # 鏁版嵁搴撶储寮�
+      database: 0
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://1.15.17.182:9095 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/application-qyhy.yml b/src/main/resources/application-qyhy.yml
new file mode 100644
index 0000000..069abdc
--- /dev/null
+++ b/src/main/resources/application-qyhy.yml
@@ -0,0 +1,268 @@
+# 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9003
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:11101/product-inventory-management-qyhy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: xd@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_qyhy
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+#      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 11102
+      # 鏁版嵁搴撶储寮�
+      database: 0
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /data/javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /data/javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /data/javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://36.213.180.217:9011 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/application-rbhb-pro.yml b/src/main/resources/application-rbhb-pro.yml
new file mode 100644
index 0000000..744aee9
--- /dev/null
+++ b/src/main/resources/application-rbhb-pro.yml
@@ -0,0 +1,268 @@
+# 鍏嬫媺鐜涗緷铻嶉偊鐜繚绉戞妧鏈夐檺鍏徃 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9003
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:11101/product-inventory-management-rbhb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: xd@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_xjgm
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+#      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 11102
+      # 鏁版嵁搴撶储寮�
+      database: 14
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /data/javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /data/javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /data/javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://36.213.180.217:9018 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/application-xjgm-pro.yml b/src/main/resources/application-xjgm-pro.yml
new file mode 100644
index 0000000..74289b2
--- /dev/null
+++ b/src/main/resources/application-xjgm-pro.yml
@@ -0,0 +1,268 @@
+# 鍏嬫媺鐜涗緷甯傛柊鑱氬伐璐告湁闄愯矗浠诲叕鍙� 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9003
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:11101/product-inventory-management-xjgm?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: xd@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_rbhb
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+#      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 11102
+      # 鏁版嵁搴撶储寮�
+      database: 15
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /data/javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /data/javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /data/javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://36.213.180.217:9016 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/application-xlgs.yml b/src/main/resources/application-xlgs.yml
new file mode 100644
index 0000000..0cdbd39
--- /dev/null
+++ b/src/main/resources/application-xlgs.yml
@@ -0,0 +1,268 @@
+# 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9003
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:3306/product-inventory-management-xlgs?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: xd@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_xlgs
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+#      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 6379
+      # 鏁版嵁搴撶储寮�
+      database: 0
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://1.15.17.182:9091 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/application-yss.yml b/src/main/resources/application-yss.yml
new file mode 100644
index 0000000..76f7ead
--- /dev/null
+++ b/src/main/resources/application-yss.yml
@@ -0,0 +1,268 @@
+# 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9003
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:3306/product-inventory-management-yss?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: xd@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_yss
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+#      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 6379
+      # 鏁版嵁搴撶储寮�
+      database: 0
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://1.15.17.182:9085 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/application-zdjc.yml b/src/main/resources/application-zdjc.yml
new file mode 100644
index 0000000..ca0d5ee
--- /dev/null
+++ b/src/main/resources/application-zdjc.yml
@@ -0,0 +1,268 @@
+# 椤圭洰鐩稿叧閰嶇疆
+ruoyi:
+  # 鍚嶇О
+  name: RuoYi
+  # 鐗堟湰
+  version: 3.8.9
+  # 鐗堟潈骞翠唤
+  copyrightYear: 2025
+  # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+  profile: /javaWork/product-inventory-management/file
+
+  # 鑾峰彇ip鍦板潃寮�鍏�
+  addressEnabled: false
+  # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+  captchaType: math
+  # 鍗忓悓瀹℃壒缂栧彿鍓嶇紑(閰嶇疆鏂囦欢鍚庣紑鍛藉悕)
+  approvalNumberPrefix: NEW
+
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+  # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+  port: 9003
+  servlet:
+    # 搴旂敤鐨勮闂矾寰�
+    context-path: /
+  tomcat:
+    # tomcat鐨刄RI缂栫爜
+    uri-encoding: UTF-8
+    # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+    accept-count: 1000
+    threads:
+      # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+      max: 800
+      # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+      min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.ruoyi: warn
+    org.springframework: warn
+
+minio:
+  endpoint: http://114.132.189.42/
+  port: 7019
+  secure: false
+  accessKey: admin
+  secretKey: 12345678
+  preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+  default-bucket: jxc
+# 鐢ㄦ埛閰嶇疆
+user:
+  password:
+    # 瀵嗙爜鏈�澶ч敊璇鏁�
+    maxRetryCount: 5
+    # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+    lockTime: 10
+
+# Spring閰嶇疆
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 涓诲簱鏁版嵁婧�
+      master:
+        url: jdbc:mysql://172.17.0.1:3306/product-inventory-management-zdjc?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: xd@123456..
+      # 浠庡簱鏁版嵁婧�
+      slave:
+        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+        enabled: false
+        url:
+        username:
+        password:
+      # 鍒濆杩炴帴鏁�
+      initialSize: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      minIdle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      maxActive: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      maxWait: 60000
+      # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+      connectTimeout: 30000
+      # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+      socketTimeout: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      timeBetweenEvictionRunsMillis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      minEvictableIdleTimeMillis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      maxEvictableIdleTimeMillis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+        allow:
+        url-pattern: /druid/*
+        # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 鎱QL璁板綍
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+  # 璧勬簮淇℃伅
+  messages:
+    # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+    basename: i18n/messages
+  # 鏂囦欢涓婁紶
+  servlet:
+    multipart:
+      # 鍗曚釜鏂囦欢澶у皬
+      max-file-size: 1GB
+      # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+      max-request-size: 2GB
+  # 鏈嶅姟妯″潡
+  devtools:
+    restart:
+      # 鐑儴缃插紑鍏�
+      enabled: false
+  # redis 閰嶇疆
+  data:
+    mongodb:
+      uri: mongodb://114.132.189.42:9028/chat_memory_db_zdjc
+    # redis 閰嶇疆
+    redis:
+      # 鍦板潃
+#      host: 127.0.0.1
+      host: 172.17.0.1
+      # 绔彛锛岄粯璁や负6379
+      port: 6379
+      # 鏁版嵁搴撶储寮�
+      database: 0
+      # 瀵嗙爜
+      #    password: root2022!
+      password:
+
+      # 杩炴帴瓒呮椂鏃堕棿
+      timeout: 10s
+      lettuce:
+        pool:
+          # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+          min-idle: 0
+          # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+          max-idle: 8
+          # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+          max-active: 8
+          # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+          max-wait: -1ms
+
+  # Quartz瀹氭椂浠诲姟閰嶇疆锛堟柊澧為儴鍒嗭級
+  quartz:
+    job-store-type: jdbc  # 浣跨敤鏁版嵁搴撳瓨鍌�
+    jdbc:
+      initialize-schema: never  # 棣栨杩愯鏃惰嚜鍔ㄥ垱寤鸿〃缁撴瀯锛屾垚鍔熷悗鏀逛负never
+      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL琛ㄧ粨鏋勮剼鏈�
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: RuoYiScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL閫傞厤
+            tablePrefix: qrtz_  # 琛ㄥ悕鍓嶇紑锛屼笌鑴氭湰涓�鑷�
+            isClustered: false  # 鍗曡妭鐐规ā寮忥紙闆嗙兢闇�鏀逛负true锛�
+            clusterCheckinInterval: 10000
+            txIsolationLevelSerializable: true
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10  # 绾跨▼姹犲ぇ灏�
+            threadPriority: 5
+            makeThreadsDaemons: true
+          updateCheck: false  # 鍏抽棴鐗堟湰妫�鏌�
+# token閰嶇疆
+token:
+  # 浠ょ墝鑷畾涔夋爣璇�
+  header: Authorization
+  # 浠ょ墝瀵嗛挜
+  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
+  # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+  expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  # 鎼滅储鎸囧畾鍖呭埆鍚�   鏍规嵁鑷繁鐨勯」鐩潵
+  typeAliasesPackage: com.ruoyi.**.pojo
+  # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+  configLocation: classpath:mybatis/mybatis-config.xml
+  global-config:
+    enable-sql-runner: true
+    db-config:
+      id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+  # 鏄惁寮�鍚痵wagger
+  enabled: true
+  # 璇锋眰鍓嶇紑
+  pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+  # 杩囨护寮�鍏�
+  enabled: true
+  # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+  excludes: /system/notice
+  # 鍖归厤閾炬帴
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+  # 浣滆��
+  author: ruoyi
+  # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+  packageName: com.ruoyi.project.system
+  # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+  autoRemovePre: false
+  # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+  tablePrefix: sys_
+  # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+  allowOverwrite: false
+
+# 鏂囦欢涓婁紶閰嶇疆
+file:
+  temp-dir: /javaWork/product-inventory-management/file/temp/uploads   # 涓存椂鐩綍
+  upload-dir: /javaWork/product-inventory-management/file/prod/uploads # 姝e紡鐩綍
+  path: /javaWork/product-inventory-management/file # 涓婁紶鐩綍
+  urlPrefix: /prod-api/common # 閾炬帴鍓嶇紑
+  domain: http://1.15.17.182:9081 # 鍩熷悕鍓嶇紑
+  expired: 120 # 杩囨湡鏃堕棿(鍗曚綅:鍒嗛挓)
+  useLimit: 10 # 浣跨敤娆℃暟
+  compress: true # 鏄惁鍘嬬缉
+  needCompressSize: 10MB # 鍘嬬缉闃堝��
+  compressQuality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
diff --git a/src/main/resources/mapper/account/purchase/AccountPaymentApplicationMapper.xml b/src/main/resources/mapper/account/purchase/AccountPaymentApplicationMapper.xml
index 267de0b..f4d6284 100644
--- a/src/main/resources/mapper/account/purchase/AccountPaymentApplicationMapper.xml
+++ b/src/main/resources/mapper/account/purchase/AccountPaymentApplicationMapper.xml
@@ -88,12 +88,14 @@
     </select>
 
     <select id="existsByStockInRecordId" resultType="java.lang.Boolean">
-         SELECT COUNT(*) > 0
+        SELECT COUNT(*) > 0
         FROM account_payment_application
-        WHERE  status != 2
-        <foreach collection="stockInRecordIds" item="id" open="(" separator=" OR " close=")">
-            FIND_IN_SET(#{id}, stock_in_record_ids)
-        </foreach>
+        WHERE status != 2
+        AND (
+            <foreach collection="stockInRecordIds" item="id" separator=" OR ">
+                FIND_IN_SET(#{id}, stock_in_record_ids) > 0
+            </foreach>
+        )
     </select>
 
 </mapper>
diff --git a/src/main/resources/mapper/account/sales/AccountInvoiceApplicationMapper.xml b/src/main/resources/mapper/account/sales/AccountInvoiceApplicationMapper.xml
index 7884e75..4121614 100644
--- a/src/main/resources/mapper/account/sales/AccountInvoiceApplicationMapper.xml
+++ b/src/main/resources/mapper/account/sales/AccountInvoiceApplicationMapper.xml
@@ -65,10 +65,33 @@
     <select id="existsByStockOutRecordId" resultType="java.lang.Boolean">
         SELECT COUNT(*) > 0
         FROM account_invoice_application
-        WHERE status!=2
-        <foreach collection="stockOutRecordIds" item="id" open="(" separator=" OR " close=")">
-            FIND_IN_SET(#{id}, stock_out_record_ids)
-        </foreach>
+        WHERE status != 2
+        AND (
+            <foreach collection="stockOutRecordIds" item="id" separator=" OR ">
+                FIND_IN_SET(#{id}, stock_out_record_ids) > 0
+            </foreach>
+        )
+    </select>
+    <select id="selectAccountInvoiceApplicationList"
+            resultType="com.ruoyi.account.bean.vo.sales.AccountInvoiceApplicationVo">
+        select
+            *
+        from (
+            select aia.*,
+            asi.id AS sales_invoice_id,
+            asi.status AS sales_invoice_status,
+            c.customer_name,
+            GROUP_CONCAT(sour.outbound_batches SEPARATOR ',') AS outboundBatches
+            from account_invoice_application aia
+            left join customer c on aia.customer_id = c.id
+            left join stock_out_record sour on FIND_IN_SET(sour.id, aia.stock_out_record_ids) > 0
+            left join account_sales_invoice asi on aia.id = asi.account_invoice_application_id
+            GROUP BY aia.id
+        )A
+        WHERE A.customer_id = #{customerId}
+        AND (COALESCE(A.sales_invoice_id,'') = '' OR A.sales_invoice_status = 1)
+        AND A.status = 1
+        order by A.id desc
     </select>
 
 </mapper>
diff --git a/src/main/resources/mapper/account/sales/AccountSalesCollectionMapper.xml b/src/main/resources/mapper/account/sales/AccountSalesCollectionMapper.xml
index 4898072..6a35890 100644
--- a/src/main/resources/mapper/account/sales/AccountSalesCollectionMapper.xml
+++ b/src/main/resources/mapper/account/sales/AccountSalesCollectionMapper.xml
@@ -58,36 +58,51 @@
     <select id="getOutboundBatchesByCustomer"
             resultType="com.ruoyi.account.bean.vo.sales.SalesOutboundVo">
         SELECT
-        sor.id,
-        sor.outbound_batches,
-        sl.customer_name,
-        sor.create_time as shippingDate,
-        p.product_name,
-        pm.model as specification_model,
-        slp.tax_rate,
-        sor.stock_out_num * slp.tax_inclusive_unit_price as outboundAmount,
-        s.shipping_no,
-        sl.sales_contract_no
-        FROM stock_out_record sor
-        left join shipping_info s on sor.record_id = s.id
-        LEFT JOIN sales_ledger sl ON s.sales_ledger_id = sl.id
-        LEFT JOIN sales_ledger_product slp ON s.sales_ledger_product_id = slp.id and slp.type = 1
-        left join product_model pm on slp.product_model_id = pm.id
-        left join product p on pm.product_id = p.id
-        WHERE sor.record_type='13' and sor.approval_status=1
-        and sl.customer_id=#{customerId}
-
-        and sor.id NOT IN (
-        SELECT DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(a.stock_out_record_ids, ',', n.n), ',', -1)
-        FROM account_sales_collection a
-        CROSS JOIN (
-            SELECT 1 n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL
-            SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6
-        ) n
-        WHERE n.n &lt;= CHAR_LENGTH(a.stock_out_record_ids) - CHAR_LENGTH(REPLACE(a.stock_out_record_ids, ',', '')) + 1
-        )
-
-        order by sor.id DESC
+            id,
+            outbound_batches,
+            customer_name,
+            shipping_date,
+            product_name,
+            specification_model,
+            tax_rate,
+            outbound_amount,
+            shipping_no,
+            sales_contract_no,
+            amount_received
+        FROM
+            (
+                SELECT
+                    sor.id,
+                    sor.outbound_batches,
+                    sl.customer_name,
+                    sor.create_time AS shipping_date,
+                    p.product_name,
+                    pm.model AS specification_model,
+                    slp.tax_rate,
+                    sor.stock_out_num * slp.tax_inclusive_unit_price AS outbound_amount,
+                    s.shipping_no,
+                    sl.sales_contract_no,
+                    COALESCE ( SUM( acsc.collection_amount ), 0 ) AS amount_received
+                FROM
+                    stock_out_record sor
+                        LEFT JOIN shipping_info s ON sor.record_id = s.id
+                        LEFT JOIN sales_ledger sl ON s.sales_ledger_id = sl.id
+                        LEFT JOIN sales_ledger_product slp ON s.sales_ledger_product_id = slp.id
+                        AND slp.type = 1
+                        LEFT JOIN product_model pm ON slp.product_model_id = pm.id
+                        LEFT JOIN product p ON pm.product_id = p.id
+                        LEFT JOIN account_sales_collection acsc ON acsc.stock_out_record_ids = sor.id
+                WHERE
+                    sor.record_type = '13'
+                  AND sor.approval_status = 1
+                  AND sl.customer_id = #{customerId}
+                GROUP BY
+                    sor.outbound_batches
+                ORDER BY
+                    sor.id
+            ) tempA
+        WHERE
+            amount_received &lt; outbound_amount
     </select>
     <select id="selectIncomeStats" resultType="com.ruoyi.home.dto.IncomeExpenseAnalysisDto">
          SELECT DATE_FORMAT(collection_date, #{dateFormat}) AS dateStr,
diff --git a/src/main/resources/mapper/approve/ApprovalInstanceMapper.xml b/src/main/resources/mapper/approve/ApprovalInstanceMapper.xml
index f632e74..f3720c2 100644
--- a/src/main/resources/mapper/approve/ApprovalInstanceMapper.xml
+++ b/src/main/resources/mapper/approve/ApprovalInstanceMapper.xml
@@ -29,6 +29,9 @@
         left join sys_user su on ai.create_user = su.user_id
         <where>
             deleted = 0
+            <if test="ew.id != null">
+                and ai.id = #{ew.id}
+            </if>
             <if test="ew.instanceNo != null">
                 and ai.instance_no like concat('%',#{ew.instanceNo},'%')
             </if>
diff --git a/src/main/resources/mapper/basic/CustomerMapper.xml b/src/main/resources/mapper/basic/CustomerMapper.xml
index 2957c7e..ffaff4e 100644
--- a/src/main/resources/mapper/basic/CustomerMapper.xml
+++ b/src/main/resources/mapper/basic/CustomerMapper.xml
@@ -22,7 +22,14 @@
         from customer_user cu
         where cu.customer_id = c.id
         and cu.user_id != c.usage_user
-        ) as user_ids_str
+        ) as user_ids_str,
+        CASE
+            WHEN EXISTS (SELECT 1 FROM sales_ledger sl WHERE sl.customer_id = c.id)
+              OR EXISTS (SELECT 1 FROM sales_quotation sq WHERE sq.customer_id = c.id)
+              OR EXISTS (SELECT 1 FROM return_management rm WHERE rm.customer_id = c.id)
+            THEN 1
+            ELSE 0
+        END AS sales_reference_flag
         from customer c
         left join sys_user u on c.usage_user = u.user_id
         <where>
@@ -71,7 +78,14 @@
         from customer_user cu
         where cu.customer_id = c.id
         and cu.user_id != c.usage_user
-        ) as user_ids_str
+        ) as user_ids_str,
+        CASE
+            WHEN EXISTS (SELECT 1 FROM sales_ledger sl WHERE sl.customer_id = c.id)
+              OR EXISTS (SELECT 1 FROM sales_quotation sq WHERE sq.customer_id = c.id)
+              OR EXISTS (SELECT 1 FROM return_management rm WHERE rm.customer_id = c.id)
+            THEN 1
+            ELSE 0
+        END AS sales_reference_flag
         from customer c
         left join sys_user u on c.usage_user = u.user_id
         <where>
@@ -112,24 +126,12 @@
     <select id="customewTransactions" resultType="com.ruoyi.sales.vo.CustomerTransactionsVo">
         select T1.customer_id,
                c.customer_name,
-               T1.contractAmounts,
+               T1.contractAmounts AS contractAmounts,
                IFNULL(T2.receiptPaymentAmount, 0) AS receiptPaymentAmount,
-               IFNULL(T3.outboundAmount, 0) - IFNULL(T4.returnAmount, 0) AS receiptableAmount
+               T1.contractAmounts - IFNULL(T2.receiptPaymentAmount, 0) - IFNULL(T4.returnAmount, 0) AS receiptableAmount,
+               IFNULL(T4.returnAmount, 0) AS returnAmount
         from (select customer_id, sum(contract_amount) as contractAmounts from sales_ledger group by customer_id) T1
         left join (select customer_id, sum(collection_amount) as receiptPaymentAmount from account_sales_collection group by customer_id) T2 on T1.customer_id = T2.customer_id
-        left join (
-            SELECT
-                sl.customer_id,
-                sum(sor.stock_out_num * slp.tax_inclusive_unit_price) as outboundAmount
-            FROM stock_out_record sor
-            LEFT join shipping_info s on sor.record_id = s.id
-            LEFT JOIN sales_ledger sl ON s.sales_ledger_id = sl.id
-            LEFT JOIN sales_ledger_product slp ON s.sales_ledger_product_id = slp.id
-            WHERE sor.record_type='13'
-                and sor.approval_status=1
-                and slp.type = 1
-            group by sl.customer_id
-        ) T3 on T3.customer_id=T1.customer_id
         left join (
             select
                 sl.customer_id,
@@ -153,9 +155,10 @@
         select sl.id salesLedgerId,
                sl.sales_contract_no,
                sl.execution_date,
-               sl.contract_amount,
+               sl.contract_amount AS contract_amount,
                IFNULL(T1.receiptPaymentAmount, 0) AS receiptPaymentAmount,
-               IFNULL(T2.outboundAmount, 0) - IFNULL(T3.returnAmount, 0) AS receiptableAmount
+               sl.contract_amount - IFNULL(T1.receiptPaymentAmount, 0) - IFNULL(T3.returnAmount, 0) AS receiptableAmount,
+               IFNULL(T3.returnAmount, 0) AS returnAmount
         from sales_ledger sl
         left join (
             select
@@ -169,19 +172,6 @@
               and sor.approval_status=1
             group by  sl.id
         )T1 on T1.id = sl.id
-        left join (
-            SELECT
-                sl.id,
-                sum(sor.stock_out_num * slp.tax_inclusive_unit_price) as outboundAmount
-            FROM stock_out_record sor
-                     left join shipping_info s on sor.record_id = s.id
-                     LEFT JOIN sales_ledger sl ON s.sales_ledger_id = sl.id
-                     LEFT JOIN sales_ledger_product slp ON s.sales_ledger_product_id = slp.id
-            WHERE sor.record_type='13'
-              and sor.approval_status=1
-              and slp.type = 1
-            group by  sl.id
-        )T2 on T2.id = sl.id
         left join (
             select sl.id,
                    sum(rm.refund_amount) as returnAmount
diff --git a/src/main/resources/mapper/basic/SupplierManageMapper.xml b/src/main/resources/mapper/basic/SupplierManageMapper.xml
index 299274c..63bdf7e 100644
--- a/src/main/resources/mapper/basic/SupplierManageMapper.xml
+++ b/src/main/resources/mapper/basic/SupplierManageMapper.xml
@@ -74,26 +74,10 @@
                sm.supplier_name,
                T1.contractAmounts,
                IFNULL(T2.paymentAmount, 0) AS paymentAmount,
-               IFNULL(T3.InboundAmount, 0) - IFNULL(T4.returnAmount, 0) AS payableAmount
+               T1.contractAmounts - IFNULL(T2.paymentAmount, 0) - IFNULL(T4.returnAmount, 0) AS payableAmount,
+               IFNULL(T4.returnAmount, 0) AS returnAmount
         from (select supplier_id, sum(contract_amount) as contractAmounts from purchase_ledger group by supplier_id) T1
         left join (select supplier_id, sum(payment_amount) as paymentAmount from account_purchase_payment group by supplier_id) T2 on T1.supplier_id = T2.supplier_id
-        left join (
-            SELECT
-                pl.supplier_id,
-                sum(sir.stock_in_num * slp.tax_inclusive_unit_price) AS InboundAmount
-            FROM stock_in_record sir
-                     -- 10 绫诲瀷鎵嶅叧鑱旇川妫�琛�
-                     LEFT JOIN quality_inspect qi ON sir.record_type = 10 AND sir.record_id = qi.id
-                -- 鍔ㄦ�佸叧鑱旈噰璐紙鑷姩閫傞厤 7 鍜� 10锛�
-                     LEFT JOIN purchase_ledger pl
-                               ON pl.id = IF(sir.record_type = 7, sir.record_id, qi.purchase_ledger_id)
-                -- 浜у搧鍏宠仈涓嶅姩
-                     LEFT JOIN sales_ledger_product slp ON pl.id = slp.sales_ledger_id
-            -- 鏉′欢
-            WHERE sir.approval_status = 1 AND slp.type = 2
-              AND sir.record_type IN ('7','10')
-            group by pl.supplier_id
-        ) T3 on T3.supplier_id=T1.supplier_id
         left join (
             select
                 supplier_id,
@@ -114,9 +98,10 @@
        select pl.id  purchaseLedgerId,
               pl.purchase_contract_number,
               pl.execution_date,
-              pl.contract_amount,
+              pl.contract_amount AS contract_amount,
               IFNULL(T1.paymentAmount, 0) AS paymentAmount,
-              IFNULL(T2.InboundAmount, 0) - IFNULL(T3.returnAmount, 0) AS payableAmount
+              pl.contract_amount - IFNULL(T1.paymentAmount, 0) - IFNULL(T3.returnAmount, 0) AS payableAmount,
+              IFNULL(T3.returnAmount, 0) AS returnAmount
        from purchase_ledger pl
        left join (
            select
@@ -134,23 +119,6 @@
              AND sir.record_type IN ('7','10')
            group by pl.id
        )T1 on T1.id = pl.id
-       left join (
-           SELECT
-               pl.id,
-               sum(sir.stock_in_num * slp.tax_inclusive_unit_price) AS InboundAmount
-           FROM stock_in_record sir
-                    -- 10 绫诲瀷鎵嶅叧鑱旇川妫�琛�
-                    LEFT JOIN quality_inspect qi ON sir.record_type = 10 AND sir.record_id = qi.id
-               -- 鍔ㄦ�佸叧鑱旈噰璐紙鑷姩閫傞厤 7 鍜� 10锛�
-                    LEFT JOIN purchase_ledger pl
-                              ON pl.id = IF(sir.record_type = 7, sir.record_id, qi.purchase_ledger_id)
-               -- 浜у搧鍏宠仈涓嶅姩
-                    LEFT JOIN sales_ledger_product slp ON pl.id = slp.sales_ledger_id
-           -- 鏉′欢
-           WHERE sir.approval_status = 1 AND slp.type = 2
-             AND sir.record_type IN ('7','10')
-           group by pl.id
-       )T2 on T2.id = pl.id
        left join (
            select pl.id,
                   sum(pro.total_amount) as returnAmount
diff --git a/src/main/resources/mapper/procurementrecord/ReturnManagementMapper.xml b/src/main/resources/mapper/procurementrecord/ReturnManagementMapper.xml
index e15e4aa..6231005 100644
--- a/src/main/resources/mapper/procurementrecord/ReturnManagementMapper.xml
+++ b/src/main/resources/mapper/procurementrecord/ReturnManagementMapper.xml
@@ -6,13 +6,30 @@
         select rm.*,
                c.customer_name,
                si.shipping_no,
+               rm.shipping_type,
+               rm.truck_plate_no,
+               rm.express_company,
+               rm.express_no,
                sl.project_name,
                sl.sales_contract_no,
-               sl.salesman
+               sl.salesman,
+                CASE
+                    WHEN tempA.total_approval = 0 OR tempA.total_approval IS NULL THEN 0
+                    WHEN tempA.approval_sum = tempA.total_approval THEN 1
+                    ELSE 2
+                END AS stock_in_approval_status
         from return_management rm
                  left join shipping_info si on rm.shipping_id = si.id
                  left join customer c on rm.customer_id = c.id
                  left join sales_ledger sl on si.sales_ledger_id = sl.id
+                LEFT JOIN (
+                SELECT
+                rsp.return_management_id,
+                COUNT(sir.id) AS total_approval,
+                SUM(CASE WHEN sir.approval_status = 1 THEN 1 ELSE 0 END) AS approval_sum
+                FROM return_sale_product rsp LEFT JOIN stock_in_record sir ON rsp.id = sir.record_id
+                GROUP BY rsp.return_management_id
+                ) tempA ON tempA.return_management_id = rm.id
         <where>
             <if test="req.returnNo != null and req.returnNo != ''">
                 and rm.return_no like concat('%',#{req.returnNo},'%')
@@ -45,6 +62,10 @@
      select rm.*,
                c.customer_name,
                si.shipping_no,
+               rm.shipping_type,
+               rm.truck_plate_no,
+               rm.express_company,
+               rm.express_no,
                sl.project_name,
                sl.sales_contract_no,
                sl.salesman
@@ -59,6 +80,10 @@
                 rm.return_no,
                 c.customer_name,
                 si.shipping_no,
+                rm.shipping_type,
+                rm.truck_plate_no,
+                rm.express_company,
+                rm.express_no,
                 rm.make_time,
                 rm.refund_amount,
                 rm.return_reason,
diff --git a/src/main/resources/mapper/procurementrecord/ReturnSaleProductMapper.xml b/src/main/resources/mapper/procurementrecord/ReturnSaleProductMapper.xml
index 6b15d56..d104b21 100644
--- a/src/main/resources/mapper/procurementrecord/ReturnSaleProductMapper.xml
+++ b/src/main/resources/mapper/procurementrecord/ReturnSaleProductMapper.xml
@@ -19,8 +19,9 @@
             sor.outbound_batches,
             sor.stock_out_num,
             sor.batch_no,
-               GREATEST(sor.stock_out_num - COALESCE(rs1.total_return_num1, 0), 0) AS un_quantity,
-               COALESCE(rs.total_return_num, 0)                             AS total_return_num
+            GREATEST( sor.stock_out_num - COALESCE ( rs.total_return_num, 0 ), 0 ) AS un_quantity,
+            COALESCE ( rs.pending_return_num, 0 ) AS pending_return_num ,
+            COALESCE ( rs.return_num, 0 ) AS total_return_num
         FROM return_sale_product rsp
                  LEFT JOIN return_management rm ON rm.id = rsp.return_management_id
                  LEFT JOIN shipping_info si ON si.id = rm.shipping_id
@@ -30,15 +31,11 @@
                 left join product_model pm on slp.product_model_id = pm.id
                   LEFT JOIN product p on pm.product_id = p.id
                  LEFT JOIN (SELECT stock_out_record_id,
-                                   SUM(num) AS total_return_num
+                                   SUM(num) AS total_return_num,
+                                   SUM( CASE WHEN return_management_id =#{returnManagementId} AND STATUS = 0 THEN num ELSE 0 END ) AS pending_return_num ,
+                                   SUM( CASE WHEN STATUS = 1 THEN num ELSE 0 END ) AS return_num
                             FROM return_sale_product
-                            WHERE 1 = 1 and return_management_id = #{returnManagementId}
                             GROUP BY stock_out_record_id) rs ON rs.stock_out_record_id = sor.id
-                 LEFT JOIN (SELECT stock_out_record_id,
-                                   SUM(num) AS total_return_num1
-                            FROM return_sale_product
-                            WHERE 1 = 1
-                            GROUP BY stock_out_record_id) rs1 ON rs1.stock_out_record_id = sor.id
         where rm.id =#{returnManagementId}
     </select>
     <select id="listReturnSaleProduct" resultType="com.ruoyi.procurementrecord.bean.dto.ReturnSaleProductDto">
diff --git a/src/main/resources/mapper/production/ProductionOrderMapper.xml b/src/main/resources/mapper/production/ProductionOrderMapper.xml
index 8e64413..67cc55b 100644
--- a/src/main/resources/mapper/production/ProductionOrderMapper.xml
+++ b/src/main/resources/mapper/production/ProductionOrderMapper.xml
@@ -233,7 +233,9 @@
             </if>
         </where>
         order by po.id desc
-        limit #{offset}, #{size}
+        <if test="size != null and size &gt;= 0">
+            limit #{offset}, #{size}
+        </if>
     </select>
 
     <select id="countHomeOrderProgress" resultType="java.lang.Long">
diff --git a/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml b/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
index a0a0a2d..8b94eb7 100644
--- a/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
+++ b/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
@@ -6,7 +6,8 @@
 
     <update id="updateContractAmountById">
         UPDATE purchase_ledger
-        SET contract_amount = #{totalTaxInclusiveAmount}
+        SET contract_amount = #{totalTaxInclusiveAmount},
+            net_contract_amount = #{totalTaxInclusiveAmount}
         WHERE id = #{id}
     </update>
     <select id="selectPurchaseStats" resultType="com.ruoyi.home.dto.IncomeExpenseAnalysisDto">
@@ -27,6 +28,7 @@
                 pl.supplier_name,
                 pl.project_name,
                 pl.contract_amount,
+                pl.net_contract_amount,
                 pl.entry_date,
                 pl.execution_date,
                 pl.recorder_id,
@@ -137,6 +139,46 @@
         ORDER BY result.entry_date DESC
     </select>
 
+    <select id="selectReturnablePurchaseLedgerList" resultType="com.ruoyi.purchase.pojo.PurchaseLedger">
+        SELECT DISTINCT pl.*
+        FROM purchase_ledger pl
+        WHERE 1 = 1
+        <if test="c.purchaseContractNumber != null and c.purchaseContractNumber != ''">
+            AND pl.purchase_contract_number LIKE CONCAT('%', #{c.purchaseContractNumber}, '%')
+        </if>
+        <if test="c.supplierId != null">
+            AND pl.supplier_id = #{c.supplierId}
+        </if>
+        <if test="c.approvalStatus != null">
+            AND pl.approval_status = #{c.approvalStatus}
+        </if>
+        AND EXISTS (
+            SELECT 1
+            FROM stock_in_record sir
+            LEFT JOIN quality_inspect qi
+                ON sir.record_type = '10'
+               AND sir.record_id = qi.id
+            LEFT JOIN sales_ledger_product slp
+                ON slp.sales_ledger_id = pl.id
+               AND slp.product_model_id = sir.product_model_id
+               AND slp.type = 2
+            LEFT JOIN (
+                SELECT stock_in_record_id, SUM(return_quantity) AS total_return_num
+                FROM purchase_return_order_products
+                GROUP BY stock_in_record_id
+            ) rs ON rs.stock_in_record_id = sir.id
+            WHERE sir.approval_status = 1
+              AND sir.record_type IN ('7','10')
+              AND (
+                  (sir.record_type = '7' AND sir.record_id = pl.id)
+                  OR (sir.record_type = '10' AND qi.purchase_ledger_id = pl.id)
+              )
+              AND slp.id IS NOT NULL
+              AND GREATEST(sir.stock_in_num - COALESCE(rs.total_return_num, 0), 0) > 0
+        )
+        ORDER BY pl.entry_date DESC
+    </select>
+
     <select id="selectTotalPurchaseAmount" resultType="java.math.BigDecimal">
         SELECT IFNULL(SUM(contract_amount), 0)
         FROM purchase_ledger
diff --git a/src/main/resources/mapper/purchase/PurchaseReturnOrdersMapper.xml b/src/main/resources/mapper/purchase/PurchaseReturnOrdersMapper.xml
index 2f782ff..8ca4903 100644
--- a/src/main/resources/mapper/purchase/PurchaseReturnOrdersMapper.xml
+++ b/src/main/resources/mapper/purchase/PurchaseReturnOrdersMapper.xml
@@ -8,6 +8,10 @@
         <result column="no" property="no" />
         <result column="return_type" property="returnType" />
         <result column="supplier_id" property="supplierId" />
+        <result column="shipping_type" property="shippingType" />
+        <result column="truck_plate_no" property="truckPlateNo" />
+        <result column="express_company" property="expressCompany" />
+        <result column="express_no" property="expressNo" />
         <result column="project_id" property="projectId" />
         <result column="project_phase" property="projectPhase" />
         <result column="prepared_at" property="preparedAt" />
@@ -22,7 +26,18 @@
         SELECT
             pro.*,
             sm.supplier_name as supplier_name,
-            pl.purchase_contract_number as purchase_contract_number
+            pl.purchase_contract_number as purchase_contract_number,
+            CASE
+                WHEN EXISTS (
+                    SELECT 1
+                    FROM purchase_return_order_products prop
+                    INNER JOIN stock_out_record sor ON sor.record_id = prop.id
+                        AND sor.record_type = '9'
+                        AND sor.approval_status = 1
+                    WHERE prop.purchase_return_order_id = pro.id
+                ) THEN 1
+                ELSE 0
+            END AS stock_out_approved
         FROM purchase_return_orders pro
                  LEFT JOIN supplier_manage sm ON pro.supplier_id = sm.id
                  LEFT JOIN purchase_ledger pl ON pl.id = pro.purchase_ledger_id
@@ -59,6 +74,10 @@
                 pro.no returnNo,
                 t.inboundBatches,
                 sm.supplier_name,
+                pro.shipping_type,
+                pro.truck_plate_no,
+                pro.express_company,
+                pro.express_no,
                 pro.prepared_at,
                 pro.total_amount,
                 CASE pro.return_type WHEN 0 THEN '閫�璐ч��娆�' WHEN 1 THEN '鎷掓敹' END AS returnType,
@@ -100,13 +119,22 @@
             sir.stock_in_num,
             sir.batch_no,
             slp.tax_inclusive_unit_price,
-            GREATEST(sir.stock_in_num - COALESCE(rs.total_return_num, 0), 0) AS un_quantity,
-            COALESCE(rs.total_return_num, 0) AS total_return_num
+            GREATEST(
+                sir.stock_in_num
+                - COALESCE(rs.total_return_num, 0)
+                - COALESCE(so.total_sale_out_num, 0),
+                0
+            ) AS un_quantity,
+            COALESCE(rs.total_return_num, 0) AS total_return_num,
+            COALESCE(so.total_sale_out_num, 0) AS saleOutQuantity
             FROM stock_in_record sir
             LEFT JOIN quality_inspect qi ON sir.record_type = 10 AND sir.record_id = qi.id
             LEFT JOIN purchase_ledger pl
             ON pl.id = IF(sir.record_type = 7, sir.record_id, qi.purchase_ledger_id)
-            LEFT JOIN sales_ledger_product slp ON pl.id = slp.sales_ledger_id
+            LEFT JOIN sales_ledger_product slp
+                ON pl.id = slp.sales_ledger_id
+               AND slp.product_model_id = sir.product_model_id
+               AND slp.type = 2
             LEFT JOIN (
                 SELECT
                     stock_in_record_id,
@@ -116,7 +144,24 @@
                 WHERE 1=1
                 GROUP BY stock_in_record_id
             ) rs ON rs.stock_in_record_id = sir.id
-        WHERE sir.approval_status = 1 AND slp.type = 2
+            LEFT JOIN (
+                SELECT
+                    inv.batch_no,
+                    inv.product_model_id,
+                    SUM(spd.quantity) AS total_sale_out_num
+                FROM shipping_product_detail spd
+                INNER JOIN shipping_info si
+                    ON si.id = spd.shipping_info_id
+                INNER JOIN stock_out_record sor
+                    ON sor.record_id = si.id
+                   AND sor.record_type = '13'
+                   AND sor.approval_status IN (0, 1, 3)
+                INNER JOIN stock_inventory inv
+                    ON inv.id = spd.stock_inventory_id
+                GROUP BY inv.batch_no, inv.product_model_id
+            ) so ON so.product_model_id = sir.product_model_id
+               AND (so.batch_no = sir.batch_no OR (so.batch_no IS NULL AND sir.batch_no IS NULL))
+        WHERE sir.approval_status = 1
         AND sir.record_type IN ('7','10')
          and pl.id = #{purchaseLedgerId}
     </select>
@@ -135,8 +180,14 @@
            slp.tax_inclusive_unit_price,
            prop.return_quantity,
            prop.purchase_return_order_id,
-           GREATEST(sir.stock_in_num - COALESCE(rs1.total_return_num1, 0), 0) AS un_quantity,
-           COALESCE(rs.total_return_num, 0)                             AS total_return_num
+           GREATEST(
+               sir.stock_in_num
+               - COALESCE(rs.total_return_num, 0)
+               - COALESCE(so.total_sale_out_num, 0),
+               0
+           ) AS un_quantity,
+           COALESCE(rs.total_return_num, 0)                             AS total_return_num,
+           COALESCE(so.total_sale_out_num, 0)                           AS saleOutQuantity
     from purchase_return_order_products prop
     left join purchase_return_orders pro on prop.purchase_return_order_id = pro.id
     LEFT JOIN stock_in_record sir ON prop.stock_in_record_id = sir.id and sir.record_type in ('7','10')
@@ -144,13 +195,25 @@
     LEFT JOIN (SELECT stock_in_record_id,
                       SUM(return_quantity) AS total_return_num
                FROM purchase_return_order_products
-               WHERE 1 = 1 and purchase_return_order_id = #{id}
+               WHERE 1 = 1
                GROUP BY stock_in_record_id) rs ON rs.stock_in_record_id = sir.id
-    LEFT JOIN (SELECT stock_in_record_id,
-                      SUM(return_quantity) AS total_return_num1
-               FROM purchase_return_order_products
-               WHERE 1 = 1 and purchase_return_order_id = #{id}
-               GROUP BY stock_in_record_id) rs1 ON rs1.stock_in_record_id = sir.id
+    LEFT JOIN (
+        SELECT
+            inv.batch_no,
+            inv.product_model_id,
+            SUM(spd.quantity) AS total_sale_out_num
+        FROM shipping_product_detail spd
+        INNER JOIN shipping_info si
+            ON si.id = spd.shipping_info_id
+        INNER JOIN stock_out_record sor
+            ON sor.record_id = si.id
+           AND sor.record_type = '13'
+           AND sor.approval_status IN (0, 1, 3)
+        INNER JOIN stock_inventory inv
+            ON inv.id = spd.stock_inventory_id
+        GROUP BY inv.batch_no, inv.product_model_id
+    ) so ON so.product_model_id = sir.product_model_id
+       AND (so.batch_no = sir.batch_no OR (so.batch_no IS NULL AND sir.batch_no IS NULL))
     where pro.id = #{id}
     </select>
 </mapper>
diff --git a/src/main/resources/mapper/sales/SalesLedgerMapper.xml b/src/main/resources/mapper/sales/SalesLedgerMapper.xml
index a5650f9..2d6b7f8 100644
--- a/src/main/resources/mapper/sales/SalesLedgerMapper.xml
+++ b/src/main/resources/mapper/sales/SalesLedgerMapper.xml
@@ -56,6 +56,7 @@
         T1.attachment_materials,
         T1.tenant_id,
         T1.contract_amount,
+        T1.net_contract_amount,
         T1.contract_amount AS noInvoiceAmountTotal,
         T1.execution_date,
         T2.nick_name AS entry_person_name,
diff --git a/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
index 49569de..9e6839f 100644
--- a/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
+++ b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -33,9 +33,14 @@
         WHEN (IFNULL(t2.qualitity, 0) - IFNULL(t2.locked_quantity, 0)) >0 THEN 1
         ELSE 0
         END as has_sufficient_stock,
-        (IFNULL(T1.quantity, 0) - IFNULL(t3.shipped_quantity, 0)) as no_quantity,
+        (IFNULL(T1.quantity, 0) - IFNULL(t3.shipped_quantity, 0) - IFNULL(t5.pending_approval_quantity, 0)) as no_quantity,
+        IFNULL(t3.shipped_quantity, 0) as shipped_quantity,
+        IFNULL(t6.return_quantity, 0) as return_quantity,
+        IFNULL(t4.approved_stock_in_num, 0) as approved_stock_in_num,
+        IFNULL(t5.pending_approval_quantity, 0) as pending_approval_quantity,
         CASE
-         WHEN IFNULL(t3.shipped_quantity, 0) = 0 THEN '寰呭彂璐�'
+         WHEN IFNULL(t3.shipped_quantity, 0) = 0 AND IFNULL(t5.pending_approval_quantity, 0) = 0 THEN '寰呭彂璐�'
+         WHEN IFNULL(t3.shipped_quantity, 0) = 0 AND IFNULL(t5.pending_approval_quantity, 0) > 0 THEN '瀹℃壒涓�'
          WHEN (IFNULL(T1.quantity, 0) - IFNULL(t3.shipped_quantity, 0)) > 0 THEN '閮ㄥ垎鍙戣揣'
         ELSE '宸插彂璐�'
         END as shippingStatus,
@@ -53,11 +58,60 @@
         GROUP BY product_model_id
         ) t2 ON T1.product_model_id = t2.product_model_id
         LEFT JOIN (
-        SELECT sales_ledger_product_id, IFNULL(SUM(spd.quantity), 0) as shipped_quantity
+        SELECT
+            slp.id AS sales_ledger_product_id,
+            IFNULL(SUM(so.total_sale_out_num), 0) AS shipped_quantity
+        FROM sales_ledger_product slp
+        LEFT JOIN (
+            SELECT
+                pl.id AS purchase_ledger_id,
+                sir.product_model_id,
+                SUM(spd.quantity) AS total_sale_out_num
+            FROM shipping_product_detail spd
+            INNER JOIN shipping_info si
+                ON si.id = spd.shipping_info_id
+            INNER JOIN stock_out_record sor
+                ON sor.record_id = si.id
+               AND TRIM(sor.record_type) = '13'
+               AND sor.approval_status IN (0, 1, 3)
+            INNER JOIN stock_inventory inv
+                ON inv.id = spd.stock_inventory_id
+            INNER JOIN stock_in_record sir
+                ON sir.product_model_id = inv.product_model_id
+               AND (
+                    (sir.batch_no IS NOT NULL AND sir.batch_no = inv.batch_no)
+                    OR (sir.batch_no IS NULL AND inv.batch_no IS NULL)
+               )
+               AND sir.approval_status = 1
+               AND sir.record_type IN ('7', '10')
+            LEFT JOIN quality_inspect qi
+                ON sir.record_type = '10'
+               AND sir.record_id = qi.id
+            LEFT JOIN purchase_ledger pl
+                ON pl.id = IF(sir.record_type = '7', sir.record_id, qi.purchase_ledger_id)
+            WHERE si.status IN ('瀹℃牳閫氳繃', '宸插彂璐�')
+              AND pl.id IS NOT NULL
+            GROUP BY pl.id, sir.product_model_id
+        ) so ON so.purchase_ledger_id = slp.sales_ledger_id
+            AND so.product_model_id = slp.product_model_id
+        WHERE slp.type = 2
+        GROUP BY slp.id
+
+        UNION ALL
+
+        -- 閿�鍞彴璐�(type=1): shipping_info 鐩存帴鎸� sales_ledger_product_id,鍙粺璁″嚭搴撳鏍搁�氳繃(approval_status=1)鐨勫彂璐ч噺,涓� t5 鐨� pending 閫昏緫浜掕ˉ
+        SELECT
+            si.sales_ledger_product_id AS sales_ledger_product_id,
+            IFNULL(SUM(spd.quantity), 0) AS shipped_quantity
         FROM shipping_info si
-        LEFT JOIN shipping_product_detail spd ON si.id = spd.shipping_info_id
-        where si.status != '瀹℃牳鎷掔粷'
-        GROUP BY sales_ledger_product_id
+        INNER JOIN shipping_product_detail spd ON si.id = spd.shipping_info_id
+        INNER JOIN stock_out_record sor
+            ON sor.record_id = si.id
+           AND TRIM(sor.record_type) = '13'
+           AND sor.approval_status = 1
+        WHERE si.status IN ('瀹℃牳閫氳繃', '宸插彂璐�')
+          AND si.sales_ledger_product_id IS NOT NULL
+        GROUP BY si.sales_ledger_product_id
         ) t3 ON t3.sales_ledger_product_id = T1.id
         LEFT JOIN (
         SELECT rel.sales_ledger_product_id,
@@ -92,6 +146,42 @@
         ) rel
         GROUP BY rel.sales_ledger_product_id
         ) t4 ON t4.sales_ledger_product_id = T1.id
+        LEFT JOIN (
+        SELECT si.sales_ledger_product_id, IFNULL(SUM(spd.quantity), 0) as pending_approval_quantity
+        FROM shipping_info si
+        LEFT JOIN shipping_product_detail spd ON si.id = spd.shipping_info_id
+        WHERE si.status IN ('寰呭鏍�', '瀹℃牳涓�')
+           OR (si.status = '瀹℃牳閫氳繃' AND NOT EXISTS (
+                SELECT 1 FROM stock_out_record sor
+                WHERE sor.record_id = si.id
+                  AND TRIM(sor.record_type) = '13'
+                  AND sor.approval_status = 1
+           ))
+        GROUP BY si.sales_ledger_product_id
+        ) t5 ON t5.sales_ledger_product_id = T1.id
+        LEFT JOIN (
+            SELECT
+                prop.sales_ledger_product_id,
+                IFNULL(SUM(prop.return_quantity), 0) AS return_quantity
+            FROM purchase_return_order_products prop
+            LEFT JOIN purchase_return_orders pro
+                ON pro.id = prop.purchase_return_order_id
+            GROUP BY prop.sales_ledger_product_id
+
+            UNION ALL
+
+            SELECT
+                si.sales_ledger_product_id,
+                IFNULL(SUM(rsp.num), 0) AS return_quantity
+            FROM return_sale_product rsp
+            INNER JOIN return_management rm ON rm.id = rsp.return_management_id
+            INNER JOIN shipping_info si ON si.id = rm.shipping_id
+            INNER JOIN stock_in_record sir ON sir.record_id = rsp.id
+                AND TRIM(sir.record_type) IN ('14','15')
+                AND sir.approval_status = 1
+            WHERE si.sales_ledger_product_id IS NOT NULL
+            GROUP BY si.sales_ledger_product_id
+        ) t6 ON t6.sales_ledger_product_id = T1.id
         left join product_model pm ON T1.product_model_id = pm.id
         left join product p ON pm.product_id = p.id
         <where>
diff --git a/src/main/resources/mapper/sales/ShippingInfoMapper.xml b/src/main/resources/mapper/sales/ShippingInfoMapper.xml
index 762c2d4..8775933 100644
--- a/src/main/resources/mapper/sales/ShippingInfoMapper.xml
+++ b/src/main/resources/mapper/sales/ShippingInfoMapper.xml
@@ -78,7 +78,8 @@
             sor.batch_no,
             slp.tax_inclusive_unit_price,
             GREATEST(sor.stock_out_num - COALESCE(rs.total_return_num, 0), 0) AS un_quantity,
-            COALESCE(rs.total_return_num, 0) AS total_return_num
+            COALESCE(rs.return_num, 0) AS total_return_num,
+            COALESCE(rs.pending_return_num, 0) AS pending_return_num
         FROM shipping_info si
         LEFT JOIN shipping_product_detail spd ON spd.shipping_info_id = si.id
         LEFT JOIN stock_out_record sor ON sor.record_id = si.id and sor.record_type = '13'
@@ -86,7 +87,9 @@
         LEFT JOIN (
         SELECT
         stock_out_record_id,
-        SUM(num) AS total_return_num
+        SUM(num) AS total_return_num,
+        SUM( CASE WHEN rsp.STATUS = 0 THEN rsp.num ELSE 0 END ) AS pending_return_num ,
+        SUM( CASE WHEN rsp.STATUS = 1 THEN rsp.num ELSE 0 END ) AS return_num
         FROM return_sale_product rsp
         left join return_management rm on rm.id = rsp.return_management_id
         left join shipping_info si on si.id = rm.shipping_id
@@ -101,8 +104,9 @@
         order by sor.id
     </select>
     <select id="getShippingInfoByCustomerName" resultType="com.ruoyi.sales.pojo.ShippingInfo">
-        select * from shipping_info si
+        select distinct si.* from shipping_info si
         left join sales_ledger sl on si.sales_ledger_id = sl.id
-        where  sl.customer_name = #{customerName}
+        inner join stock_out_record sor on sor.record_id = si.id and sor.record_type = '13' and sor.approval_status = 1
+        where sl.customer_name = #{customerName} and si.status = '瀹℃牳閫氳繃'
     </select>
 </mapper>
diff --git a/src/main/resources/mapper/staff/PersonalAttendanceRecordsMapper.xml b/src/main/resources/mapper/staff/PersonalAttendanceRecordsMapper.xml
index 9ae20d6..4a15bbf 100644
--- a/src/main/resources/mapper/staff/PersonalAttendanceRecordsMapper.xml
+++ b/src/main/resources/mapper/staff/PersonalAttendanceRecordsMapper.xml
@@ -42,7 +42,7 @@
         order by personal_attendance_records.id desc
     </select>
 
-    <!-- 鏌ヨ鎸囧畾鏃ユ湡娌℃湁鑰冨嫟璁板綍鐨勫湪鑱屽憳宸ワ紙鍦ㄦ寚瀹氭椂闂翠箣鍓嶅叆鑱岀殑锛� -->
+    <!-- 鏌ヨ鎸囧畾鏃ユ湡鏈夋帓鐝紙闈炶鍋囷級浣嗘病鏈夎�冨嫟璁板綍鐨勫湪鑱屽憳宸ワ紝娌℃帓鐝涓轰紤鎭笉鏍囪缂哄嫟 -->
     <select id="selectStaffWithoutAttendanceRecordBeforeTime" resultType="com.ruoyi.staff.pojo.StaffOnJob">
         SELECT soj.*
         FROM staff_on_job soj
@@ -50,8 +50,11 @@
         AND soj.create_time &lt; #{entryDeadline}
         AND EXISTS (
         SELECT 1
-        FROM personal_attendance_location_config palc
-        WHERE palc.sys_dept_id = soj.sys_dept_id
+        FROM personal_shift ps
+        WHERE ps.staff_on_job_id = soj.id
+        AND DATE(ps.work_time) = #{date}
+        AND ps.personal_attendance_location_config_id IS NOT NULL
+        AND ps.personal_attendance_location_config_id != 999
         )
         AND NOT EXISTS (
         SELECT 1
diff --git a/src/main/resources/mapper/staff/PersonalShiftMapper.xml b/src/main/resources/mapper/staff/PersonalShiftMapper.xml
index 7d80392..b912e24 100644
--- a/src/main/resources/mapper/staff/PersonalShiftMapper.xml
+++ b/src/main/resources/mapper/staff/PersonalShiftMapper.xml
@@ -18,13 +18,16 @@
         u.id user_id
         FROM personal_shift s
         LEFT JOIN staff_on_job u ON u.id = s.staff_on_job_id
+        LEFT JOIN staff_leave sl ON sl.staff_on_job_id = u.id
         LEFT JOIN personal_attendance_location_config palc ON palc.id = s.personal_attendance_location_config_id
         <where>
+            u.id IS NOT NULL
             <if test="sysDeptId != null and sysDeptId != ''">
                 and u.sys_dept_id = #{sysDeptId}
             </if>
             <if test="time != null and time != ''">
                 and DATE_FORMAT(s.work_time, '%Y-%m') = DATE_FORMAT(#{time}, '%Y-%m')
+                AND (u.staff_state = 1 OR (u.staff_state = 0 AND sl.leave_date IS NOT NULL AND sl.leave_date >= DATE_FORMAT(#{time}, '%Y-%m-01')))
             </if>
             <if test="userName != null and userName != ''">
                 and u.staff_name like concat('%', #{userName}, '%')
@@ -43,10 +46,12 @@
         GROUP_CONCAT(DATE_FORMAT(s.work_time, '%c'), '锛�', IFNULL(palc.shift, '') order by s.work_time SEPARATOR ';') month_str
         FROM personal_shift s
         LEFT JOIN staff_on_job u ON u.id = s.staff_on_job_id
-         LEFT JOIN personal_attendance_location_config palc ON palc.id = s.personal_attendance_location_config_id
+        LEFT JOIN staff_leave sl ON sl.staff_on_job_id = u.id
+        LEFT JOIN personal_attendance_location_config palc ON palc.id = s.personal_attendance_location_config_id
          <where>
             <if test="time != null and time != ''">
                 and DATE_FORMAT(s.work_time, '%Y') = DATE_FORMAT(#{time}, '%Y' )
+                AND (u.staff_state = 1 OR (u.staff_state = 0 AND sl.leave_date IS NOT NULL AND sl.leave_date >= DATE_FORMAT(#{time}, '%Y-01-01')))
             </if>
             <if test="userName != null and userName != ''">
                 and u.staff_name like concat('%', #{userName}, '%')
@@ -66,10 +71,12 @@
         GROUP_CONCAT(DATE_FORMAT(s.work_time, '%c'), '锛�', IFNULL(palc.shift, '') order by s.work_time SEPARATOR ';') month_str
         FROM personal_shift s
         LEFT JOIN staff_on_job u ON u.id = s.staff_on_job_id
+        LEFT JOIN staff_leave sl ON sl.staff_on_job_id = u.id
         LEFT JOIN personal_attendance_location_config palc ON palc.id = s.personal_attendance_location_config_id
        <where>
         <if test="time != null and time != ''">
             and DATE_FORMAT(s.work_time, '%Y') = DATE_FORMAT(#{time}, '%Y' )
+            AND (u.staff_state = 1 OR (u.staff_state = 0 AND sl.leave_date IS NOT NULL AND sl.leave_date >= DATE_FORMAT(#{time}, '%Y-01-01')))
         </if>
         <if test="userName != null and userName != ''">
             and u.staff_name like concat('%', #{userName}, '%')
@@ -87,10 +94,12 @@
         GROUP_CONCAT(s.work_time, '锛�', IFNULL(palc.shift, ''), '锛�', s.id order by s.work_time SEPARATOR ';') AS shift_time, u.id user_id
         FROM personal_shift s
         LEFT JOIN staff_on_job u ON u.id = s.staff_on_job_id
+        LEFT JOIN staff_leave sl ON sl.staff_on_job_id = u.id
         LEFT JOIN personal_attendance_location_config palc ON palc.id = s.personal_attendance_location_config_id
         <where>
             <if test="time != null and time != ''">
                 and DATE_FORMAT(s.work_time, '%Y-%m') = DATE_FORMAT(#{time}, '%Y-%m' )
+                AND (u.staff_state = 1 OR (u.staff_state = 0 AND sl.leave_date IS NOT NULL AND sl.leave_date >= DATE_FORMAT(#{time}, '%Y-%m-01')))
             </if>
             <if test="userName != null and userName != ''">
                 and u.staff_name like concat('%', #{userName}, '%')
@@ -103,4 +112,15 @@
         order by s.create_time
     </select>
 
+    <select id="existsAttendanceUsedByConfig" resultType="boolean">
+        SELECT EXISTS (
+            SELECT 1
+            FROM personal_shift ps
+            INNER JOIN personal_attendance_records par
+                ON par.staff_on_job_id = ps.staff_on_job_id
+               AND par.date = DATE(ps.work_time)
+            WHERE ps.personal_attendance_location_config_id = #{configId}
+        )
+    </select>
+
 </mapper>
diff --git a/src/main/resources/mapper/staff/SchemeApplicableStaffMapper.xml b/src/main/resources/mapper/staff/SchemeApplicableStaffMapper.xml
index 1652dd6..78a2a98 100644
--- a/src/main/resources/mapper/staff/SchemeApplicableStaffMapper.xml
+++ b/src/main/resources/mapper/staff/SchemeApplicableStaffMapper.xml
@@ -25,6 +25,20 @@
         create_time DESC
     </select>
 
+    <!-- 鏍规嵁閮ㄩ棬ID鏌ヨ鏈�鏂扮ぞ淇濇柟妗� -->
+    <select id="selectLatestSchemeByDeptId" resultType="com.ruoyi.staff.pojo.SchemeApplicableStaff">
+        SELECT
+        <include refid="schemeColumns"/>
+        FROM
+        scheme_applicable_staff
+        WHERE
+        1 = 1
+        AND FIND_IN_SET(#{deptId}, dept_ids)
+        ORDER BY
+        create_time DESC
+        LIMIT 1
+    </select>
+
     <!-- 鏌ヨ鏂规瀵瑰簲鐨勬槑缁� -->
     <select id="selectDetailBySchemeId" resultType="com.ruoyi.staff.pojo.SchemeInsuranceDetail">
         SELECT
diff --git a/src/main/resources/mapper/staff/StaffSalaryMainMapper.xml b/src/main/resources/mapper/staff/StaffSalaryMainMapper.xml
index c3f0c62..bec4e6d 100644
--- a/src/main/resources/mapper/staff/StaffSalaryMainMapper.xml
+++ b/src/main/resources/mapper/staff/StaffSalaryMainMapper.xml
@@ -16,4 +16,11 @@
         <result column="update_user" property="updateUser" />
     </resultMap>
 
+    <select id="selectIssuedDeptIds" resultType="java.lang.String">
+        SELECT DISTINCT dept_ids
+        FROM staff_salary_main
+        WHERE salary_month = #{salaryMonth}
+          AND status = 5
+    </select>
+
 </mapper>
diff --git a/src/main/resources/mapper/stock/StockInRecordMapper.xml b/src/main/resources/mapper/stock/StockInRecordMapper.xml
index a3bf3f9..3e10e2b 100644
--- a/src/main/resources/mapper/stock/StockInRecordMapper.xml
+++ b/src/main/resources/mapper/stock/StockInRecordMapper.xml
@@ -21,9 +21,9 @@
         pm.unit,
         u.nick_name as createBy,
         CASE
-            WHEN #{params.topParentProductId} = 278 AND TRIM(sir.record_type) = '7' THEN
+            WHEN TRIM(sir.record_type) = '7' THEN
                 COALESCE(pl_by_product.purchase_contract_number, pl_direct.purchase_contract_number)
-            WHEN #{params.topParentProductId} = 278 AND TRIM(sir.record_type) = '10' THEN
+            WHEN TRIM(sir.record_type) = '10' THEN
                 pl_by_quality.purchase_contract_number
             WHEN #{params.topParentProductId} = 276 THEN
                 CASE
diff --git a/src/main/resources/mapper/stock/StockInventoryMapper.xml b/src/main/resources/mapper/stock/StockInventoryMapper.xml
index ed780a7..ac9c49b 100644
--- a/src/main/resources/mapper/stock/StockInventoryMapper.xml
+++ b/src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -352,7 +352,11 @@
         su.nick_name as create_by
         from
         stock_in_record sir
-        left join stock_inventory si on sir.product_model_id = si.product_model_id
+        left join (
+            select product_model_id, sum(qualitity) as qualitity
+            from stock_inventory
+            group by product_model_id
+        ) si on sir.product_model_id = si.product_model_id
         left join product_model pm on sir.product_model_id = pm.id
         left join product p on pm.product_id = p.id
         left join sys_user su on sir.create_user = su.user_id
diff --git a/src/main/resources/mapper/system/SysDeptMapper.xml b/src/main/resources/mapper/system/SysDeptMapper.xml
index c71cd19..de46729 100644
--- a/src/main/resources/mapper/system/SysDeptMapper.xml
+++ b/src/main/resources/mapper/system/SysDeptMapper.xml
@@ -26,7 +26,6 @@
 	<sql id="selectDeptVo">
         select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.create_by, d.create_time
         from sys_dept d
-        order by d.create_time desc
     </sql>
 
 	<select id="selectDeptList" parameterType="com.ruoyi.project.system.domain.SysDept" resultMap="SysDeptResult">
@@ -92,7 +91,7 @@
 
 	<select id="checkDeptNameUnique" resultMap="SysDeptResult">
 	    <include refid="selectDeptVo"/>
-		where dept_name=#{deptName} and parent_id = #{parentId} and del_flag = '0' limit 1
+		where dept_name=#{deptName} and parent_id = #{parentId} and del_flag = '0' order by d.create_time desc limit 1
 	</select>
 
     <insert id="insertDept" parameterType="com.ruoyi.project.system.domain.SysDept">
diff --git a/src/main/resources/mapper/system/SysUserMapper.xml b/src/main/resources/mapper/system/SysUserMapper.xml
index ea68745..b12ee0f 100644
--- a/src/main/resources/mapper/system/SysUserMapper.xml
+++ b/src/main/resources/mapper/system/SysUserMapper.xml
@@ -25,6 +25,7 @@
         <result property="remark"       column="remark"       />
 		<result property="deptNames"       column="dept_names"       />
 		<result property="tenantId"       column="tenant_id"       />
+		<result property="roleNames"       column="role_names"       />
         <association property="dept"    javaType="com.ruoyi.project.system.domain.SysDept"         resultMap="deptResult" />
         <collection  property="roles"   javaType="java.util.List"  resultMap="RoleResult" />
     </resultMap>
@@ -290,6 +291,29 @@
 		  and su.del_flag = '0'
 		ORDER BY su.create_time DESC
 	</select>
+
+	<select id="selectUserListWithDetail" resultMap="SysUserResult">
+		select u.user_id, u.nick_name, u.user_name, u.status, u.del_flag,
+		       dept_agg.dept_names,
+		       role_agg.role_names
+		from sys_user u
+		left join (
+		    SELECT ud.user_id, GROUP_CONCAT(d.dept_name SEPARATOR ', ') AS dept_names
+		    FROM sys_user_dept ud
+		    LEFT JOIN sys_dept d ON ud.dept_id = d.dept_id
+		    WHERE d.del_flag = '0' AND d.status = '0'
+		    GROUP BY ud.user_id
+		) dept_agg on dept_agg.user_id = u.user_id
+		left join (
+		    SELECT ur.user_id, GROUP_CONCAT(r.role_name SEPARATOR ', ') AS role_names
+		    FROM sys_user_role ur
+		    LEFT JOIN sys_role r ON ur.role_id = r.role_id
+		    WHERE r.del_flag = '0' AND r.status = '0'
+		    GROUP BY ur.user_id
+		) role_agg on role_agg.user_id = u.user_id
+		where u.del_flag = '0' AND u.status = '0'
+	</select>
+
 	<select id="getUserByPerms" resultType="java.lang.Long">
 		select distinct t5.user_id
 		from sys_role_menu t1

--
Gitblit v1.9.3