Merge branch 'dev_New_pro' into dev_pro_山西_晋和园
# Conflicts:
# src/main/resources/application-jhy.yml
# src/main/resources/application.yml
| | |
| | | !.mvn/wrapper/maven-wrapper.jar
|
| | |
|
| | | ######################################################################
|
| | | # IDE
|
| | | # Claude Code
|
| | | .claude/
|
| | |
|
| | |
|
| | | ### STS ###
|
| | | .apt_generated
|
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # çäº§å·¥åºæ°å¢è®¡å人ååè®¡åæ§è¡äººååæ®µ |
| | | 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'; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ç¥è¯åºåéæ£ç´¢åè½æ°æ®åºåæ´ |
| | | -- æ§è¡åè¯·ç¡®ä¿ 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 'å
³èç¥è¯åºID', |
| | | 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='ç¥è¯åºæä»¶åéè®°å½è¡¨'; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # ç¥è¯åºRAGåéæ£ç´¢åè½å®ç°ææ¡£ |
| | | |
| | | ## ä¸ãåè½æ¦è¿° |
| | | |
| | | åºäº RAGï¼Retrieval-Augmented Generationï¼ææ¯å®ç°ç¥è¯åºé®çåè½ï¼æ¯æï¼ |
| | | - ç¥è¯åºç®¡çï¼CRUDï¼ |
| | | - æä»¶ä¸ä¼ ä¸åéåå¤ç |
| | | - åºäºåéæ£ç´¢çæºè½é®ç |
| | | - å¤ç§æä»¶æ ¼å¼æ¯æï¼txtãmdãdocxãxlsxãxlsãpdfï¼ |
| | | |
| | | ## äºãææ¯æ¶æ |
| | | |
| | | ### 2.1 ææ¯æ |
| | | | ç»ä»¶ | ææ¯ | |
| | | |------|------| |
| | | | åéæ°æ®åº | Pinecone | |
| | | | Embedding模å | é¿éäº DashScope text-embedding-v3 | |
| | | | LLM | é¿éäºéä¹åé® qwen-max | |
| | | | æ¡æ¶ | langchain4j | |
| | | | ORM | MyBatis-Plus | |
| | | |
| | | ### 2.2 æ¶æå¾ |
| | | |
| | | ``` |
| | | âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ |
| | | â å端åºç¨ â |
| | | âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ |
| | | â |
| | | â¼ |
| | | âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ |
| | | â Controller Layer â |
| | | â âââââââââââââââââââââââ âââââââââââââââââââââââââââââââ â |
| | | â â KnowledgeBaseCtrl â â KnowledgeChatController â â |
| | | â â (ç¥è¯åºç®¡ç) â â (ç¥è¯åºé®ç) â â |
| | | â âââââââââââââââââââââââ âââââââââââââââââââââââââââââââ â |
| | | âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ |
| | | â |
| | | â¼ |
| | | âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ |
| | | â Service Layer â |
| | | â âââââââââââââââââââââââ âââââââââââââââââââââââââââââââ â |
| | | â âKnowledgeBaseService â â KnowledgeRagService â â |
| | | â â (ç¥è¯åºCRUD) â â (åéå/æ£ç´¢) â â |
| | | â âââââââââââââââââââââââ âââââââââââââââââââââââââââââââ â |
| | | âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ |
| | | â |
| | | â¼ |
| | | âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ |
| | | â AI Layer â |
| | | â âââââââââââââââââââââââ âââââââââââââââââââââââââââââââ â |
| | | â â KnowledgeChatAgent â â EmbeddingStore (Pinecone) â â |
| | | â â (é®çAgent) â â (åéåå¨) â â |
| | | â âââââââââââââââââââââââ âââââââââââââââââââââââââââââââ â |
| | | âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ |
| | | ``` |
| | | |
| | | --- |
| | | |
| | | ## ä¸ãå端å®ç° |
| | | |
| | | ### 3.1 æ°æ®åºè®¾è®¡ |
| | | |
| | | #### 3.1.1 ç¥è¯åºè¡¨ï¼knowledge_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 'è§£å³æç', |
| | | problem TEXT COMMENT 'é®é¢æè¿°', |
| | | solution TEXT COMMENT 'è§£å³æ¹æ¡', |
| | | 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 ç¥è¯åºåéè®°å½è¡¨ï¼knowledge_base_vectorï¼ |
| | | |
| | | ```sql |
| | | CREATE TABLE knowledge_base_vector ( |
| | | id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主é®ID', |
| | | knowledge_base_id BIGINT NOT NULL COMMENT 'å
³èç¥è¯åºID', |
| | | 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 é
ç½®æä»¶ï¼application.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 æ ¸å¿ä»£ç å®ç° |
| | | |
| | | #### 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 ç¥è¯åºé®çAgent |
| | | |
| | | **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()); |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | --- |
| | | |
| | | ## åãAPIæ¥å£ææ¡£ |
| | | |
| | | ### 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": "å¦ä½å¤çåºåçç¹å·®å¼ï¼" |
| | | } |
| | | ``` |
| | | |
| | | **ååº**ï¼SSEæµå¼ï¼ |
| | | ``` |
| | | æ ¹æ®ç¥è¯åºå
容ï¼åºåçç¹å·®å¼çå¤çæµç¨å¦ä¸ï¼ |
| | | |
| | | 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ï¼æµå¼æ¥å£ï¼ |
| | | 3. å端å¤çï¼ |
| | | âââ æå»ºå½å空é´ï¼kb-{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å°è£
|
| | | ``` |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # æ°æ®æ¨¡æ - åºç¡æ°æ®æ£æµ |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - æ°æ®æ¨¡ææä½é¡µé¢ï¼æ°å¢ï¼ |
| | | |
| | | ## API |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | POST | /mock/dataCheck | æ£æµæå®æ¨¡åçåºç¡æ°æ®æ¯å¦å°±ç»ª | |
| | | |
| | | **请æ±åæ°ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | modules | List\<String\> | æ¯ | è¦æ£æµç模åå表ï¼å¯éå¼ï¼salesï¼éå®ï¼ãpurchaseï¼éè´ï¼ãqualityï¼è´¨éï¼ãproductionï¼çäº§ï¼ | |
| | | |
| | | 请æ±ä½ç¤ºä¾ï¼ |
| | | ```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管çãä¸ä¸ºBOMæ·»å 产åç»æèç¹ | |
| | | | å·¥èºè·¯çº¿ | 1 | 缺å°å·¥èºè·¯çº¿ï¼è¯·å
å¨ãå·¥èºè®¾è®¡-å·¥èºè·¯çº¿ãä¸å建工èºè·¯çº¿ | |
| | | | å·¥èºè·¯çº¿å·¥åº | 1 | 缺å°å·¥èºè·¯çº¿å·¥åºï¼è¯·å
å¨ãå·¥èºè®¾è®¡-å·¥èºè·¯çº¿ãä¸ä¸ºå·¥èºè·¯çº¿æ·»å å·¥åº | |
| | | | 产å-å·¥èºè·¯çº¿å
³è | â¥1 | é¨å产åè§æ ¼æªå
³èå·¥èºè·¯çº¿ï¼è¯·å
å¨ãå·¥èºè®¾è®¡-å·¥èºè·¯çº¿ãä¸ä¸ºäº§åè§æ ¼å建工èºè·¯çº¿ | |
| | | | å·¥èºè·¯çº¿-å·¥åºå
³è | â¥1 | é¨åå·¥èºè·¯çº¿æªæ·»å å·¥åºï¼è¯·å
å¨ãå·¥èºè®¾è®¡-å·¥èºè·¯çº¿ãä¸ä¸ºå·¥èºè·¯çº¿æ·»å å·¥åº | |
| | | | BOM-产åç»æå
³è | â¥1 | é¨åBOMæªæ·»å 产åç»æï¼è¯·å
å¨ãå·¥èºè®¾è®¡-BOM管çãä¸ä¸ºBOMæ·»å 产åç»æèç¹ | |
| | | |
| | | ### è´¨éæ¨¡å (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 |
| | | } |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - äº§åæ°æ®ï¼å
Œ
±åºç¡ï¼å¨å¤ä¸ªæ¨¡åé´å
±äº«ï¼æ£æµç»æä¸åªåºç°ä¸æ¬¡ï¼ä¸ä¼éå¤å±ç¤º |
| | | - æ£æµä»
ååªè¯»æ¥è¯¢ï¼ä¸åå
¥ä»»ä½æ°æ® |
| | | - 模ååæ°ä¸ºç©ºæ°ç»æ¶è¿åç©ºæ£æµå表 |
| | | - å»ºè®®å¨æ°æ®æ¨¡æå¼å§åå
è°ç¨æ¤æ¥å£ç¡®è®¤åºç¡æ°æ®å°±ç»ª |
| | | - ç产模åé¤äºæ£æµæ°æ®éï¼è¿ä¼æ£æµå
³èæ§ï¼äº§å-å·¥èºè·¯çº¿ãå·¥èºè·¯çº¿-å·¥åºãBOM-产åç»æï¼ï¼ç¡®ä¿å·¥èºè®¾è®¡æ°æ®å®æ´ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # æ°æ®æ¨¡æ - AI æ°æ®çæ |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - æ°æ®æ¨¡ææä½é¡µé¢ï¼æ°å¢/ä¿®æ¹ï¼ |
| | | |
| | | ## API |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | POST | /mock/generate | AI çææ¨¡ææ°æ®ï¼å«åç½®åºç¡æ°æ®æ£æµï¼ | |
| | | |
| | | **请æ±åæ°ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | modules | List\<String\> | æ¯ | è¦çææ°æ®ç模åï¼salesï¼éå®ï¼ãpurchaseï¼éè´ï¼ãqualityï¼è´¨éï¼ãproductionï¼ç产ï¼ãstockï¼åºåï¼ | |
| | | | industries | List\<String\> | æ¯ | è¡ä¸ï¼å¦ï¼["æºæ¢°å¶é ", "é£åå å·¥", "çµåè£
é
"] | |
| | | | countMin | int | å¦ | æ¯ä¸ªå®ä½çææ¡æ°æå°å¼ï¼é»è®¤ 3 | |
| | | | countMax | int | å¦ | æ¯ä¸ªå®ä½çææ¡æ°æå¤§å¼ï¼é»è®¤ 10 | |
| | | | dateStart | String | å¦ | æ¶é´èå´å¼å§ï¼yyyy-MM-ddï¼ | |
| | | | dateEnd | String | å¦ | æ¶é´èå´ç»æï¼yyyy-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 çåæ®µ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # çäº§å·¥åºæ°å¢è®¡å人ååè®¡åæ§è¡äººå |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - å·¥èºè·¯çº¿å·¥åºç®¡ç页é¢ï¼technology_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: [], // åå·¥å表ï¼é仿¥å£è·å |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ### 3. è¡¨æ ¼åæ°å¢ |
| | | |
| | | å表ä¸å¯ç´æ¥ä½¿ç¨å端è¿åçå§åå±ç¤ºï¼ |
| | | |
| | | ```html |
| | | <el-table-column label="计å人å" prop="planPersonName" /> |
| | | <el-table-column label="è®¡åæ§è¡äººå" prop="executorName" /> |
| | | ``` |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - `planPerson` å `executor` åå¨çæ¯åå·¥IDï¼Longç±»åï¼ï¼æäº¤è¡¨åæ¶ä¼ ID |
| | | - ååºä¸ `planPersonName` å `executorName` ç±å端éè¿ `staff_on_job` 表èªå¨å
³èæ¥è¯¢ï¼å端æ éé¢å¤è½¬æ¢ |
| | | - å工䏿åè¡¨æ°æ®éä»åå·¥æ¥å£è·åï¼åèç°æ `employeeOptions` æ°æ®æºï¼ |
| | | - æ°æ®åºè¿ç§»SQLï¼`doc/20260615_add_plan_person_and_executor_to_routing_operation.sql` |
| | | - ç产订åå·¥åºï¼`production_order_routing_operation`ï¼åæ¥æ¯æè¿ä¸¤ä¸ªå段 |
| | |
| | | @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") |
| | |
| | | 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; |
| | |
| | | @Schema(description = "éå®è®¢åå·") |
| | | @Excel(name = "éå®è®¢åå·") |
| | | private String salesContractNo; |
| | | |
| | | @Schema(description = "å·²æ¶æ¬¾éé¢") |
| | | @ExcelIgnore |
| | | private BigDecimal amountReceived; |
| | | } |
| | |
| | | @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") |
| | |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | 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 = "è´¢å¡ç®¡ç--æ ¹æ®å®¢æ·æ¥è¯¢åºåºåå·(å¼ç¥¨ç³è¯·)") |
| | |
| | | |
| | | //å¤æè¯¥åºåºè®°å½æ¯å¦æå¼ç¥¨ç³è¯· |
| | | boolean existsByStockOutRecordId(@Param("stockOutRecordIds") List<Long> stockOutRecordIds); |
| | | |
| | | List<AccountInvoiceApplicationVo> selectAccountInvoiceApplicationList(@Param("customerId") Integer customerId); |
| | | } |
| | |
| | | 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); |
| | | } |
| | |
| | | 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); |
| | | } |
| | | |
| | |
| | | void exportAccountInvoiceApplication(HttpServletResponse response, AccountInvoiceApplicationDto accountInvoiceApplicationDto); |
| | | |
| | | boolean deleteAccountInvoiceApplication(List<Long> ids); |
| | | |
| | | List<AccountInvoiceApplicationVo> getAccountInvoiceApplicationList(Integer customerId); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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; |
| | | |
| | | /** |
| | | * ç¥è¯åºé®çAgent |
| | | * åºäº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); |
| | | } |
| | |
| | | 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(); |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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; |
| | | |
| | | /** |
| | | * ç¥è¯åºé®çController |
| | | */ |
| | | @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("ç¥è¯åºIDä¸è½ä¸ºç©º"); |
| | | } |
| | | 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); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.ai.dto; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * ç¥è¯åºé®çè¯·æ± |
| | | */ |
| | | @Data |
| | | @Schema(description = "ç¥è¯åºé®ç请æ±") |
| | | public class KnowledgeChatRequest { |
| | | |
| | | @Schema(description = "ç¥è¯åºID", required = true) |
| | | private Long knowledgeBaseId; |
| | | |
| | | @Schema(description = "ä¼è¯IDï¼ç¨äºä¿æä¸ä¸æ", required = true) |
| | | private String memoryId; |
| | | |
| | | @Schema(description = "ç¨æ·æé®å
容", required = true) |
| | | private String question; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.ai.service; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ç¥è¯åºRAGæå¡ |
| | | * è´è´£æä»¶åéåå¤çåæ£ç´¢ |
| | | */ |
| | | 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); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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; |
| | | |
| | | /** |
| | | * ç¥è¯åºRAGæå¡å®ç° |
| | | */ |
| | | @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 è§£ç 失败æ¶åºç°) |
| | | 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; |
| | | } |
| | | } |
| | |
| | | |
| | | 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 |
| | |
| | | @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("è¯·ä¼ å
¥è¦å é¤çID"); |
| | | public AjaxResult delete(@RequestBody List<Long> ids) { |
| | | if (CollectionUtils.isEmpty(ids)) return AjaxResult.error("è¯·ä¼ å
¥è¦å é¤çID"); |
| | | return AjaxResult.success(knowledgeBaseService.removeByIds(ids)); |
| | | } |
| | | |
| | |
| | | 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("ç¥è¯åºIDä¸è½ä¸ºç©º"); |
| | | } |
| | | 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(); |
| | | } |
| | | |
| | | /** |
| | | * ç¥è¯åºæä»¶DTO |
| | | */ |
| | | @lombok.Data |
| | | public static class KnowledgeBaseFileDTO { |
| | | private Long knowledgeBaseId; |
| | | private List<Long> storageBlobIds; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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; |
| | | |
| | | /** |
| | | * ç¥è¯åºæä»¶åéç¶æVO |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @Schema(description = "ç¥è¯åºæä»¶åéç¶æVO") |
| | | public class KnowledgeBaseVectorVO extends KnowledgeBaseVector { |
| | | |
| | | @Schema(description = "æä»¶é¢è§URL") |
| | | private String previewUrl; |
| | | |
| | | @Schema(description = "æä»¶ä¸è½½URL") |
| | | private String downloadUrl; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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); |
| | | } |
| | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long deptId; |
| | | |
| | | /** |
| | | * æä»¶æ°é |
| | | */ |
| | | private Integer fileCount; |
| | | |
| | | /** |
| | | * æ»åçæ°é |
| | | */ |
| | | private Integer totalChunkCount; |
| | | |
| | | /** |
| | | * ç¥è¯åºæè¿° |
| | | */ |
| | | private String description; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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 = "å
³èç¥è¯åºID") |
| | | 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; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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); |
| | | } |
| | |
| | | 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()); |
| | | } |
| | |
| | | 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("审æ¹å·²é©³å"); |
| | | } |
| | | |
| | |
| | | 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") |
| | | ); |
| | |
| | | |
| | | 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) { |
| | |
| | | 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; |
| | |
| | | private final ApprovalTemplateMapper approvalTemplateMapper; |
| | | private final ApprovalTemplateNodeService approvalTemplateNodeService; |
| | | private final ApprovalTemplateNodeApproverMapper approvalTemplateNodeApproverMapper; |
| | | private final ApprovalInstanceMapper approvalInstanceMapper; |
| | | private final FileUtil fileUtil; |
| | | |
| | | @Override |
| | |
| | | |
| | | @Override |
| | | public Boolean updateApprovalTemplateDto(ApprovalTemplateDto approvalTemplateDto) { |
| | | // æ£æ¥æ¨¡æ¿æ¯å¦è¢«å®¡æ¹å®ä¾å¼ç¨ |
| | | if (isTemplateReferenced(approvalTemplateDto.getId())) { |
| | | throw new RuntimeException("è¯¥å®¡æ¹æ¨¡æ¿å·²è¢«å®¡æ¹æµç¨å¼ç¨ï¼æ æ³ç¼è¾"); |
| | | } |
| | | approvalTemplateMapper.updateById(approvalTemplateDto); |
| | | approvalTemplateNodeService.remove( |
| | | new LambdaQueryWrapper<ApprovalTemplateNode>() |
| | |
| | | public Boolean delete(List<Long> ids) { |
| | | if (ids == null || ids.isEmpty()) { |
| | | return false; |
| | | } |
| | | // æ£æ¥æ¨¡æ¿æ¯å¦è¢«å®¡æ¹å®ä¾å¼ç¨ |
| | | for (Long id : ids) { |
| | | if (isTemplateReferenced(id)) { |
| | | throw new RuntimeException("å®¡æ¹æ¨¡æ¿ï¼ID: " + id + "ï¼å·²è¢«å®¡æ¹æµç¨å¼ç¨ï¼æ æ³å é¤"); |
| | | } |
| | | } |
| | | ApprovalTemplate updateEntity = new ApprovalTemplate(); |
| | | updateEntity.setDeleted(1); |
| | |
| | | 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; |
| | | } |
| | | } |
| | |
| | | @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)); |
| | |
| | | } |
| | | 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; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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); |
| | | } |
| | | } |
| | |
| | | FILE("file"), |
| | | AFTER_FILE("after_file"), |
| | | BEFORE_FILE("before_file"), |
| | | APK("apk"); |
| | | APK("apk"), |
| | | RAG_FILE("rag_file"); |
| | | |
| | | |
| | | private final String type; |
| | |
| | | public int updateCustomer(Customer customer) { |
| | | LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | Long tenantId = loginUser.getTenantId(); |
| | | validateCustomerEditPermission(customer.getId()); |
| | | customer.setTenantId(tenantId); |
| | | return customerMapper.updateById(customer); |
| | | } |
| | |
| | | |
| | | @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()); |
| | | } |
| | | |
| | | // åé
å
¬æµ·å®¢æ·ç»ç§æµ· |
| | |
| | | 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); |
| | |
| | | return this.updateById(customer); |
| | | } |
| | | |
| | | private void validateCustomerEditPermission(Long customerId) { |
| | | Customer customer = customerMapper.selectById(customerId); |
| | | if (customer == null) { |
| | | throw new RuntimeException("å®¢æ·æ¡£æ¡ä¸åå¨"); |
| | | } |
| | | 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); |
| | |
| | | * å
±äº«ç¨æ·IDå符串ï¼SQLæ¥è¯¢è¿åï¼ç¨äºè½¬æ¢ä¸ºListï¼ |
| | | */ |
| | | private String userIdsStr; |
| | | |
| | | /** |
| | | * æ¯å¦è¢«é宿¨¡åå¼ç¨ï¼0-å¦ï¼1-æ¯ |
| | | */ |
| | | private Integer salesReferenceFlag; |
| | | } |
| | |
| | | |
| | | 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); |
| | | } |
| | | } |
| | |
| | | .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); |
| | |
| | | @JsonFormat(pattern = "yyyy-MM-dd") |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd") |
| | | private Date meetingDate; |
| | | |
| | | private String date; |
| | | } |
| | |
| | | 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", "éå®-åè´§åºåº"), |
| | |
| | | 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
|
| | |
| | | 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()
|
| | |
| | |
|
| | | public static LocalDate toLocalDate(Date date){
|
| | | if(date == null) return LocalDate.now();
|
| | | // 2. æå®åºå®æ¶åºè½¬æ¢ï¼å¦ä¸å
«åºUTC+8ãUTCé¶æ¶åºï¼
|
| | | 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();
|
| | | }
|
| | |
|
| | | /**
|
| | | * è·åå½åæ¥æ, é»è®¤æ ¼å¼ä¸ºyyyy-MM-dd
|
| | | * |
| | | *
|
| | | * @return String
|
| | | */
|
| | | public static String getDate()
|
| | |
| | | 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") |
| | |
| | | } |
| | | 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(); |
| | | |
| | |
| | | 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) { |
| | |
| | | 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; |
| | | } |
| | | } |
| | | } |
| | |
| | | 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); |
| | | } |
| | |
| | | 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; |
| | | } |
| | |
| | | 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"; |
| | |
| | | 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"; |
| | | } |
| | |
| | | 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 "æªç¥"; |
| | | } |
| | |
| | | .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; |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | private final QualityInspectMapper qualityStatisticsMapper; |
| | | |
| | | private final ApproveProcessMapper approveProcessMapper; |
| | | |
| | | private final ApprovalTaskMapper approvalTaskMapper; |
| | | |
| | | private final ApprovalInstanceMapper approvalInstanceMapper; |
| | | |
| | | private final SysDeptMapper sysDeptMapper; |
| | | |
| | |
| | | @Override |
| | | public List<ApproveProcess> todos() throws ParseException { |
| | | LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | List<ApproveProcess> approveProcesses = new ArrayList<>(); |
| | | |
| | | // æ¥è¯¢æ§å®¡æ¹è¡¨ï¼approve_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())); |
| | | // æ¥è¯¢æ°å®¡æ¹è¡¨ï¼approval_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; |
| | | } |
| | |
| | | |
| | | @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); |
| | | } |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.mock.dto; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * åºç¡æ°æ®æ£æµè¯·æ± |
| | | */ |
| | | @Data |
| | | public class DataCheckRequest { |
| | | |
| | | /** éè¦æ£æµç模å: sales / purchase / quality */ |
| | | private List<String> modules; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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 """ |
| | | ä½ æ¯ä¸ä¸ªä¼ä¸ERPç³»ç»çæ°æ®æ¨¡æä¸å®¶ã |
| | | |
| | | æ ¸å¿è§åï¼å¿
é¡»ä¸¥æ ¼éµå®ï¼ï¼ |
| | | 1. è¾åºå¿
é¡»æ¯çº¯JSONæ°ç»ï¼ä¸è¦ç¨markdown代ç åå
裹ï¼ä¸è¦æä»»ä½å
¶ä»æå |
| | | 2. æ¯ä¸ªJSON对象å¿
é¡»å
å« "entity" åæ®µï¼å¼ä¸ºå®ä½ç±»åå |
| | | 3. æ°æ®å
容è¦ç¬¦åæå®è¡ä¸çç¹å¾ |
| | | 4. éé¢ãæ°éçæ°å¼å段è¦åç |
| | | 5. å䏿¨¡åå
çå®ä½ä¹é´è¦æå¼ç¨å
³ç³» |
| | | 6. ä¸è¦ä½¿ç¨emojiæç¹æ®unicodeå符 |
| | | 7. æéè¦ï¼æ¥æåªä»"æå®æ¶é´èå´"ä¸åï¼ç»å¯¹ä¸è¦ç¨å
¶ä»å¹´ä»½ï¼ |
| | | 8. 人ååæ®µï¼å¦entryPersonãsalesmançï¼å¿
é¡»ä»"ç³»ç»ç¨æ·å表"ä¸éåï¼æ ¹æ®è§è²åé¨é¨å¹é
å¯¹åºæ¨¡åï¼ä¸è¦ç¼é 人åï¼ |
| | | """; |
| | | } |
| | | |
| | | 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ãsalesman)éè§è²æé¨é¨å«\"éå®\"çç¨æ·\n"); |
| | | sb.append("- éè´æ¨¡åç人åéè§è²æé¨é¨å«\"éè´\"çç¨æ·\n"); |
| | | sb.append("- ç产模åç人åéè§è²æé¨é¨å«\"ç产\"çç¨æ·\n"); |
| | | sb.append("- è´¨éæ¨¡åç人åéè§è²æé¨é¨å«\"è´¨é\"æ\"è´¨æ£\"çç¨æ·\n"); |
| | | sb.append("- ä»åºæ¨¡åç人åéè§è²æé¨é¨å«\"ä»åº\"æ\"åºå\"çç¨æ·\n\n"); |
| | | |
| | | if (!existingCustomerNames.isEmpty()) { |
| | | sb.append("=== å·²æå®¢æ·ï¼åªè½å¼ç¨ï¼ä¸è¦çææ°customerå®ä½ï¼===\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è¯·ç´æ¥è¾åºJSONæ°ç»:"); |
| | | 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注æï¼ä¸è¦çæcustomerå®ä½ï¼åªçæsalesLedgerï¼ |
| | | productDataä¸çproductModelIdå¿
é¡»éãæåç±»ãè§æ ¼IDï¼ |
| | | entryPersonåsalesmanå¿
é¡»ä»ç³»ç»ç¨æ·å表ä¸è§è²æé¨é¨å«"éå®"çç¨æ·ä¸éåï¼ |
| | | { |
| | | "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ä¸YYYYMMDDæ¿æ¢ä¸ºentryDateçæ¥æã%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注æï¼ä¸è¦çæsupplierå®ä½ï¼åªçæpurchaseLedgerï¼ |
| | | productDataä¸çproductModelIdå¿
é¡»éãåææç±»ãè§æ ¼IDï¼ |
| | | 人ååæ®µå¿
é¡»ä»ç³»ç»ç¨æ·å表ä¸è§è²æé¨é¨å«"éè´"çç¨æ·ä¸éåï¼ |
| | | { |
| | | "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ä¸YYYYMMDDæ¿æ¢ä¸ºentryDateçæ¥æã%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": "éç¨äºXXè¡ä¸çè´¨éæ£éªæ å" |
| | | } |
| | | inspectType: 0=åæææ£éª, 1=è¿ç¨æ£éª, 2=åºåæ£éªãä¸ç§ç±»åé½è¦è¦çã |
| | | standardNoä¸YYYYMMDDæ¿æ¢ä¸º %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ä¸YYYYMMDDæ¿æ¢ä¸º %sã%d-%dæ¡ã |
| | | """.formatted(dateStart.replace("-", ""), min, max); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.mock.service; |
| | | |
| | | import com.ruoyi.mock.dto.DataCheckRequest; |
| | | import com.ruoyi.mock.vo.DataCheckResult; |
| | | |
| | | /** |
| | | * åºç¡æ°æ®æ£æµæå¡ |
| | | */ |
| | | public interface DataCheckService { |
| | | |
| | | /** |
| | | * æ£æµæå®æ¨¡åçåºç¡æ°æ®æ¯å¦å°±ç»ª |
| | | */ |
| | | DataCheckResult check(DataCheckRequest request); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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管çãä¸ä¸ºBOMæ·»å 产åç»æèç¹")); |
| | | } |
| | | |
| | | // 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. å
³èæ§æ£æµï¼æBOM使 产åç»æç |
| | | 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管çãä¸ä¸ºBOMæ·»å 产åç»æèç¹")); |
| | | } |
| | | } |
| | | |
| | | 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; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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("æ æ³è§£æ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è§£æå¤±è´¥ï¼å°è¯æåæ°ç»ç段: {}", 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("æ¥æèå´è§£æå¤±è´¥: {} ~ {}", 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: åºç¡æ°æ® ---- |
| | | |
| | | /** |
| | | * 仿°æ®åºå 载已æå®¢æ·åç§°âIDæ å° |
| | | */ |
| | | 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() { |
| | | // å è½½ææProductèç¹ |
| | | List<Product> allProducts = productMapper.selectList(null); |
| | | Map<Long, Product> productMap = allProducts.stream() |
| | | .collect(Collectors.toMap(Product::getId, p -> p, (a, b) -> a)); |
| | | |
| | | // 对æ¯ä¸ªProductï¼æ²¿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); |
| | | } |
| | | } |
| | | |
| | | // 对æ¯ä¸ªProductModelï¼éè¿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")); |
| | | |
| | | // å½å
¥äººï¼ä¼å
ç¨AIè¿åçï¼å¦åä»"éå®"è§è²/é¨é¨éæºé |
| | | String entryPerson = item.getString("entryPerson"); |
| | | if (entryPerson == null || entryPerson.isBlank()) { |
| | | SysUser salesUser = randomUserByKeyword("éå®"); |
| | | entryPerson = salesUser != null ? salesUser.getNickName() : "ç³»ç»"; |
| | | } |
| | | dto.setEntryPerson(entryPerson); |
| | | |
| | | // ä¸å¡åï¼ä¼å
ç¨AIè¿åçï¼å¦åä»"éå®"è§è²/é¨é¨éæºé |
| | | String salesman = dto.getSalesman(); |
| | | if (salesman == null || salesman.isBlank()) { |
| | | SysUser salesUser = randomUserByKeyword("éå®"); |
| | | salesman = salesUser != null ? salesUser.getNickName() : "ç³»ç»"; |
| | | dto.setSalesman(salesman); |
| | | } |
| | | // customerId为nullä¼å¯¼è´"客æ·ä¸åå¨"å¼å¸¸ï¼è·³è¿ |
| | | 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å
é¨ä¼èªå¨çæååå·å¹¶insertï¼ä½dto䏿²¡æåå |
| | | // ç´æ¥ç¨dtoçentryDateåcustomerIdæ¥ææ°å建çè®°å½ |
| | | 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; |
| | | } |
| | | |
| | | // æ£æ¥äº§åæ¯å¦å
·å¤å®æ´çå·¥èºæ°æ®ï¼å·¥èºè·¯çº¿ãå·¥åºãBOMï¼ |
| | | 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("ç产"); |
| | | } |
| | | |
| | | /** |
| | | * æ£æ¥äº§åæ¯å¦å
·å¤å®æ´çå·¥èºæ°æ®ï¼å·¥èºè·¯çº¿ãå·¥åºãBOMï¼ |
| | | * @return 缺å°å·¥èºæ°æ®ç产åè§æ ¼IDå表ï¼ç©ºå表表示å
¨é¨å°±ç»ªï¼ |
| | | */ |
| | | 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. æ£æ¥BOMï¼å¯é使æ´å¥½ï¼ |
| | | 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; |
| | | } |
| | | |
| | | // æproductModelIdåç»ï¼ååå·æè½åå¹¶ä¸åï¼productModelId为nullçåç¬é个ä¸å |
| | | 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); |
| | | |
| | | // ä¿®æ£ç产订åçplanCompleteTime |
| | | 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()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 颿: æ¥è¯¢ç产订åçBOM颿æ¸
åï¼æ£æ¥åºåï¼ä¸è¶³åå
èªå¨å
¥åºå®¡æ¹åå颿 |
| | | */ |
| | | 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读åï¼é¿å
è¦çaddProductMainæ´æ°çcompleteQuantityï¼ |
| | | fixProductionReportTimes(task.getId(), reportDate); |
| | | } |
| | | // ä¿®æ£çäº§è®¢åæ¶é´ï¼éæ°ä»DB读åï¼é¿å
è¦çaddProductMainæ´æ°çcompleteQuantityï¼ |
| | | 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ï¼é¿å
è¦çaddProductMainå·²æ´æ°ç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ï¼é¿å
è¦çaddProductMainå·²æ´æ°ç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()) { |
| | | // åºåºå®¡æ¹éè¿ï¼èµ°æ£å¼å®¡æ¹æµç¨ï¼å
é¨ä¼æ£ååºåï¼ |
| | | 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 { |
| | | // æ´æ°å®¡æ¹å®ä¾çfinishTimeåcreateTime |
| | | ApprovalInstance instance = approvalInstanceMapper.selectById(instanceId); |
| | | if (instance != null) { |
| | | instance.setFinishTime(dateTime); |
| | | instance.setCreateTime(dateTime.minusHours(1)); |
| | | approvalInstanceMapper.updateById(instance); |
| | | } |
| | | |
| | | // æ´æ°å®¡æ¹å®ä¾èç¹çfinishTime |
| | | 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); |
| | | } |
| | | |
| | | // æ´æ°å®¡æ¹ä»»å¡çcreateTime |
| | | 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); |
| | | } |
| | | |
| | | // æ´æ°å®¡æ¹è®°å½çcreateTime |
| | | 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()) { |
| | | // å
ä¿®æ£å
¥åºè®°å½ç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()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ¿æ¢æ¹å·ä¸çæ¥æé¨åï¼yyyyMMdd â æå®æ¥æï¼ |
| | | */ |
| | | /** |
| | | * æ ¹æ®å®¢æ·åç§°æ¥å°åï¼æ¨æç份ç®ç§°çæè½¦çå· |
| | | * æ ¼å¼: ç份ç®ç§° + 忝 + 5ä½éæºæ°å忝, å¦ èA12345 |
| | | */ |
| | | 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++; |
| | | } |
| | | } |
| | | |
| | | // æproductModelIdåç»ï¼èªå¨åå¹¶ä¸å |
| | | 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; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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 { |
| | | /** 模åï¼sales / purchase / quality / common */ |
| | | private String module; |
| | | /** æ£æµé¡¹åç§° */ |
| | | private String itemName; |
| | | /** æéæä½æ°é */ |
| | | private int minRequired; |
| | | /** å½åå®é
æ°é */ |
| | | private int currentCount; |
| | | /** æ¯å¦éè¿ */ |
| | | private boolean passed; |
| | | /** æç¤ºä¿¡æ¯ */ |
| | | private String message; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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; |
| | | } |
| | | } |
| | |
| | | @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; |
| | | |
| | |
| | | @Schema(description = "éå®äº§å对象æ°ç»") |
| | | private List<ReturnSaleProductDto> returnSaleProducts; |
| | | |
| | | @Schema(description = "éå®éè´§å
¥åºå®¡æ¹ç¶æ") |
| | | private Integer stockInApprovalStatus; |
| | | |
| | | } |
| | |
| | | |
| | | @Schema(description = "åè´§åºåºæ°é") |
| | | private BigDecimal stockOutNum; |
| | | |
| | | @Schema(description = "å¾
å¤çéè´§æ°é") |
| | | private BigDecimal pendingReturnNum; |
| | | } |
| | |
| | | |
| | | @Schema(description = "å«ç¨åä»·") |
| | | private BigDecimal taxInclusiveUnitPrice; |
| | | |
| | | @Schema(description = "å¾
å¤çéè´§æ°é") |
| | | private BigDecimal pendingReturnNum; |
| | | } |
| | |
| | | @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; |
| | | |
| | |
| | | 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; |
| | |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * @author :yys |
| | |
| | | private final ReturnManagementMapper returnManagementMapper; |
| | | private final ReturnSaleProductService returnSaleProductService; |
| | | private final ShippingInfoService shippingInfoService; |
| | | private final SalesLedgerMapper salesLedgerMapper; |
| | | private final SalesRefundAmountOrderService salesRefundAmountOrderService; |
| | | private final StockUtils stockUtils; |
| | | |
| | |
| | | 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. è®¡ç®æ£ç¡®ç鿬¾æ»é¢ï¼éé¢=åä»·Ãæ°éï¼ |
| | | 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; |
| | | } |
| | | |
| | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | |
| | | @Component |
| | | @RequiredArgsConstructor |
| | |
| | | |
| | | //å é¤åºåºè®°å½ |
| | | 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); |
| | | } |
| | | |
| | | } |
| | |
| | | @Excel(name = "éæ±æ°é") |
| | | private BigDecimal qtyRequired; |
| | | |
| | | @Schema(description = "æ¥æº éå®/å
é¨") |
| | | @Excel(name = "æ¥æº éå®/å
é¨") |
| | | private String source; |
| | | |
| | | @Schema(description = "æ¿è¯ºæ¥æ") |
| | | @Excel(name = "æ¿è¯ºæ¥æ") |
| | | private LocalDate promisedDeliveryDate; |
| | |
| | | WAIT(1, "å¾
å¼å§"), |
| | | RUNNING(2, "è¿è¡ä¸"), |
| | | FINISHED(3, "已宿"), |
| | | CANCEL(4, "已忶"); |
| | | //CANCEL(4, "已忶"), |
| | | END(5, "å·²ç»æ"); |
| | | |
| | | private final Integer code; |
| | | private final String desc; |
| | |
| | | } |
| | | |
| | | /** |
| | | * 夿æ¯å¦å
许å é¤ï¼4ï¼ |
| | | * 夿æ¯å¦å
许å é¤ï¼1ï¼ |
| | | */ |
| | | public static boolean canDelete(Integer code) { |
| | | return WAIT.getCode().equals(code) || CANCEL.getCode().equals(code); |
| | | return WAIT.getCode().equals(code); |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | /** |
| | | * 夿æ¯å¦å·²å¼å§ç产ï¼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); |
| | | } |
| | | } |
| | |
| | | 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; |
| | |
| | | * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå
¬å¸ |
| | | * @since 2026-04-21 03:55:52 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | @RequiredArgsConstructor() |
| | | public class ProductionBomStructureServiceImpl extends ServiceImpl<ProductionBomStructureMapper, ProductionBomStructure> implements ProductionBomStructureService { |
| | |
| | | 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 { |
| | |
| | | |
| | | // æ¹éæ°å¢ï¼æ¿å°æ°æ®åºçæççå®ID |
| | | 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); |
| | | } |
| | | |
| | |
| | | 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); |
| | | } |
| | |
| | | // æ£æ¥æ°æ®æ¯å¦éå¤ï¼é¿å
éå¤ä¿å |
| | | 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; |
| | |
| | | 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()); |
| | |
| | | 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; |
| | | } |
| | |
| | | @Override |
| | | public int updateOrder(ProductionOrderDto productionOrderDto) { |
| | | // æ´æ°ç产订åä¸»æ°æ® |
| | | productionOrderDto.setStatus(5); |
| | | productionOrderDto.setStatus(ProductOrderStatusEnum.END.getCode()); |
| | | return baseMapper.updateById(productionOrderDto); |
| | | } |
| | | } |
| | |
| | | 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); |
| | |
| | | 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 |
| | |
| | | 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;
|
| | |
| | | @Excel(name = "è´¦å·ç¶æ", readConverterExp = "0=æ£å¸¸,1=åç¨")
|
| | | private String status;
|
| | |
|
| | | /** å 餿 å¿ï¼0代表åå¨ 2代表å é¤ï¼ */ |
| | | private String delFlag; |
| | | |
| | | /** æ¯å¦å¼éAIåè½ï¼0å¦ 1æ¯ï¼ */ |
| | | @JsonIgnore |
| | | private Integer aiEnabled; |
| | | |
| | | /** å 餿 å¿ï¼0代表åå¨ 2代表å é¤ï¼ */
|
| | | private String delFlag;
|
| | |
|
| | | /** æ¯å¦å¼éAIåè½ï¼0å¦ 1æ¯ï¼ */
|
| | | @JsonIgnore
|
| | | private Integer aiEnabled;
|
| | |
|
| | | /** æåç»å½IP */
|
| | | @Excel(name = "æåç»å½IP", type = Type.EXPORT)
|
| | | private String loginIp;
|
| | |
| | | */
|
| | | @TableField(exist = false)
|
| | | private String deptNames;
|
| | |
|
| | | /**
|
| | | * è§è²åç§°
|
| | | */
|
| | | @TableField(exist = false)
|
| | | private String roleNames;
|
| | |
|
| | | public Long getCurrentDeptId() {
|
| | | return currentDeptId;
|
| | |
| | | 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()
|
| | | {
|
| | |
| | | this.deptNames = deptNames;
|
| | | }
|
| | |
|
| | | public String getRoleNames() {
|
| | | return roleNames;
|
| | | }
|
| | |
|
| | | public void setRoleNames(String roleNames) {
|
| | | this.roleNames = roleNames;
|
| | | }
|
| | |
|
| | | public Long getDeptId() {
|
| | | return deptId;
|
| | | }
|
| | |
| | | .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())
|
| | |
| | |
|
| | | List<Long> getUserByRole(@Param("role") String role);
|
| | |
|
| | | /**
|
| | | * æ¥è¯¢æææ´»è·ç¨æ·ï¼å«é¨é¨åç§°åè§è²åç§°ï¼
|
| | | */
|
| | | List<SysUser> selectUserListWithDetail();
|
| | |
|
| | | List<Long> getUserByPerms(@Param("perms") List<String> perms);
|
| | | }
|
| | |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢éè´éè´§å¯ééè´å°è´¦ |
| | | */ |
| | | @GetMapping("/returnableList") |
| | | public TableDataInfo returnableList(PurchaseLedger purchaseLedger) { |
| | | startPage(); |
| | | List<PurchaseLedger> list = purchaseLedgerService.selectReturnablePurchaseLedgerList(purchaseLedger); |
| | | return getDataTable(list); |
| | | } |
| | | |
| | | /** |
| | | * 导åºéè´å°è´¦å表 |
| | | */ |
| | | @Log(title = "éè´å°è´¦", businessType = BusinessType.EXPORT) |
| | |
| | | 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; |
| | |
| | | private PurchaseReturnOrdersService purchaseReturnOrdersService; |
| | | private PurchaseReturnOrdersMapper purchaseReturnOrdersMapper; |
| | | private AccountStatementDetailsService accountStatementDetailsService; |
| | | private StockOutRecordMapper stockOutRecordMapper; |
| | | |
| | | |
| | | @GetMapping("/listPage") |
| | |
| | | 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(); |
| | | } |
| | |
| | | private Long id; |
| | | |
| | | /** |
| | | * 审æ¹å®ä¾ID |
| | | */ |
| | | private Long approvalInstanceId; |
| | | |
| | | /** |
| | | * éè´ååå· |
| | | */ |
| | | @Excel(name = "éè´ååå·") |
| | |
| | | /** |
| | | * å½å
¥æ¥æ |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd") |
| | | @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") |
| | | @Excel(name = "å½å
¥æ¥æ", width = 30, dateFormat = "yyyy-MM-dd") |
| | | private Date entryDate; |
| | | |
| | |
| | | @Excel(name = "ååéé¢") |
| | | private BigDecimal contractAmount = BigDecimal.ZERO; |
| | | |
| | | /** |
| | | * å®é
ååéé¢ï¼æ£åéè´§åï¼ |
| | | */ |
| | | @Schema(description = "å®é
ååéé¢") |
| | | private BigDecimal netContractAmount = BigDecimal.ZERO; |
| | | |
| | | |
| | | @Schema(description = "æä»¶ç±»å å 4") |
| | | @TableField(exist = false) |
| | |
| | | // éè´ååå· |
| | | private String purchaseContractNumber; |
| | | |
| | | private String shippingTypeText; |
| | | |
| | | /** |
| | | * 对åºåºåºæ¯å¦å·²å®¡æ ¸éè¿ |
| | | */ |
| | | private Boolean stockOutApproved; |
| | | |
| | | //éæäººå§å |
| | | private String returnUserName; |
| | | |
| | |
| | | |
| | | 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); |
| | |
| | | /** |
| | | * å½å
¥æ¥æ |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd") |
| | | @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") |
| | | @Excel(name = "å½å
¥æ¥æ", width = 30, dateFormat = "yyyy-MM-dd") |
| | | private Date entryDate; |
| | | |
| | |
| | | * ååéé¢ï¼äº§åå«ç¨æ»ä»·ï¼ |
| | | */ |
| | | private BigDecimal contractAmount; |
| | | |
| | | /** |
| | | * å®é
ååéé¢ï¼æ£åéè´§åï¼ |
| | | */ |
| | | @Schema(description = "å®é
ååéé¢") |
| | | private BigDecimal netContractAmount; |
| | | // |
| | | // /** |
| | | // * ä¸å¡å |
| | |
| | | @Schema(description = "ä¾åºåid") |
| | | 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; |
| | | |
| | |
| | | |
| | | List<PurchaseLedger> selectPurchaseLedgerList(PurchaseLedger purchaseLedger); |
| | | |
| | | List<PurchaseLedger> selectReturnablePurchaseLedgerList(PurchaseLedger purchaseLedger); |
| | | |
| | | int addOrEditPurchase(PurchaseLedgerDto purchaseLedgerDto) throws Exception; |
| | | |
| | | R batchInsertPurchaseSteps(List<Long> ids); |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | 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 |
| | |
| | | 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(); |
| | |
| | | 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; |
| | |
| | | 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()) |
| | | ); |
| | | } |
| | | } |
| | | } |
| | |
| | | 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()) |
| | |
| | | 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("导å
¥æå"); |
| | |
| | | |
| | | @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("è§£æéè´å®¡æ¹å¿«ç
§å¤±è´¥: {}", 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()) { |
| | |
| | | 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") |
| | | ); |
| | |
| | | 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); |
| | | |
| | | } |
| | |
| | | } |
| | | 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; |
| | | } |
| | | } |
| | |
| | | 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; |
| | |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | }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; |
| | | } |
| | | |
| | |
| | | @Schema(description = "å·²éè´§æ°é") |
| | | private BigDecimal totalReturnNum; |
| | | |
| | | @Schema(description = "éå®åè´§æ°é") |
| | | private BigDecimal saleOutQuantity; |
| | | |
| | | @Schema(description = "å«ç¨åä»·") |
| | | private BigDecimal taxInclusiveUnitPrice; |
| | | |
| | |
| | | @Schema(description = "éè´§æ»æ°") |
| | | private BigDecimal totalReturnNum; |
| | | |
| | | @Schema(description = "éå®åè´§æ°é") |
| | | private BigDecimal saleOutQuantity; |
| | | |
| | | @Schema(description = "å«ç¨åä»·") |
| | | private BigDecimal taxInclusiveUnitPrice; |
| | | |
| | |
| | | @Schema(description = "åºä»éé¢") |
| | | private BigDecimal payableAmount; |
| | | |
| | | @Schema(description = "éè´§éé¢") |
| | | private BigDecimal returnAmount; |
| | | |
| | | } |
| | |
| | | private BigDecimal paymentAmount; |
| | | |
| | | @Schema(description = "åºä»éé¢") |
| | | //该ä¾åºåéè´åºä»ç´¯è®¡éé¢=è´¢å¡(å
¥åº-éè´§) |
| | | //该ä¾åºåéè´åºä»ç´¯è®¡éé¢=åå§éé¢-仿¬¾-鿬¾ |
| | | private BigDecimal payableAmount; |
| | | |
| | | @Schema(description = "éè´§éé¢") |
| | | private BigDecimal returnAmount; |
| | | |
| | | } |
| | |
| | | /** |
| | | * æ£æµæ¥æ |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd") |
| | | @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") |
| | | @Excel(name = "æ£æµæ¥æ", width = 30, dateFormat = "yyyy-MM-dd") |
| | | private Date checkTime; |
| | | |
| | |
| | | /** |
| | | * æ£æµæ¥æ |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd") |
| | | @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") |
| | | @Excel(name = "æ£æµæ¥æ", width = 30, dateFormat = "yyyy-MM-dd") |
| | | private Date checkTime; |
| | | |
| | |
| | | /** |
| | | * å¤çæ¥æ |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd") |
| | | @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") |
| | | @Excel(name = "å¤çæ¥æ", width = 30, dateFormat = "yyyy-MM-dd") |
| | | private Date dealTime; |
| | | |
| | |
| | | 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 |
| | |
| | | public class SalesLedgerProductController extends BaseController |
| | | { |
| | | private final ISalesLedgerProductService salesLedgerProductService; |
| | | private final ProcurementRecordService procurementRecordService; |
| | | private final StockUtils stockUtils; |
| | | private final PurchaseReturnOrderProductsMapper purchaseReturnOrderProductsMapper; |
| | | |
| | | |
| | | /** |
| | |
| | | @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); |
| | | } |
| | | |
| | |
| | | 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; |
| | |
| | | /** |
| | | * å½å
¥æ¥æ |
| | | */ |
| | | @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; |
| | |
| | | @Schema(description = "仿¬¾æ¹å¼") |
| | | private String paymentMethod; |
| | | |
| | | @Schema(description = "å®é
ååéé¢") |
| | | private BigDecimal netContractAmount; |
| | | |
| | | @TableField(exist = false) |
| | | @Schema(description = "çäº§ç¶æ") |
| | | private String productionStatus = "æªå¼å§"; |
| | |
| | | @TableField(exist = false) |
| | | private Integer hasSufficientStock; |
| | | |
| | | // éè´§æ°é |
| | | @TableField(exist = false) |
| | | private BigDecimal returnQuality; |
| | | |
| | | // å¯ç¨æ°é quantity - returnQuality |
| | | // å¯ç¨æ°é quantity - returnQuantity |
| | | @TableField(exist = false) |
| | | private BigDecimal availableQuality; |
| | | @Schema(description = "åå»ºç¨æ·") |
| | |
| | | @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; |
| | | } |
| | |
| | | private String shippingCarNumber; |
| | | |
| | | @Schema(description = "å建æ¶é´") |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private LocalDateTime createTime; |
| | | |
| | | @Schema(description = "ä¿®æ¹æ¶é´") |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | 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); |
| | | } |
| | | }); |
| | | } |
| | |
| | | */ |
| | | 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("éå®"); |
| | |
| | | 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; |
| | |
| | | @Autowired |
| | | private ProductionProductMainService productionProductMainService; |
| | | @Autowired |
| | | private PurchaseReturnOrderProductsMapper purchaseReturnOrderProductsMapper; |
| | | ; |
| | | @Autowired |
| | | private SysUserMapper sysUserMapper; |
| | | |
| | | @Override |
| | |
| | | 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; |
| | |
| | | salesLedger.setContractAmount(salesLedgerProductImportDtos.stream() |
| | | .map(SalesLedgerProductImportDto::getTaxInclusiveTotalPrice) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add)); |
| | | salesLedger.setNetContractAmount(salesLedger.getContractAmount()); |
| | | salesLedgerMapper.insert(salesLedger); |
| | | |
| | | |
| | |
| | | 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(); |
| | |
| | | ); |
| | | } |
| | | |
| | | // 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; |
| | |
| | | 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); |
| | |
| | | }).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); |
| | |
| | | // å
ç»æä¹åæªç»æçæ¥ä»·å®¡æ¹ |
| | | 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); |
| | |
| | | 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; |
| | | } |
| | |
| | | @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); |
| | | // å建审æ¹å®ä¾åï¼æ´æ°åè´§ç¶æä¸º"å®¡æ ¸ä¸"ï¼ä½¿å端æ£ç¡®æ¾ç¤ºå®¡æ¹ç¶æ |
| | | req.setStatus("å®¡æ ¸ä¸"); |
| | | this.updateById(req); |
| | | return true; |
| | | } |
| | | } |
| | |
| | | @Schema(description = "åºæ¶éé¢") |
| | | private BigDecimal receiptableAmount; |
| | | |
| | | @Schema(description = "éè´§éé¢") |
| | | private BigDecimal returnAmount; |
| | | |
| | | } |
| | |
| | | private BigDecimal receiptPaymentAmount; |
| | | |
| | | @Schema(description = "åºæ¶éé¢") |
| | | //该客æ·éå®åºæ¶ç´¯è®¡éé¢=è´¢å¡(åºåº-éè´§) |
| | | //该客æ·éå®åºæ¶ç´¯è®¡éé¢=åå§éé¢-忬¾-鿬¾ |
| | | private BigDecimal receiptableAmount; |
| | | |
| | | @Schema(description = "éè´§éé¢") |
| | | private BigDecimal returnAmount; |
| | | |
| | | } |
| | |
| | | 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; |
| | |
| | | @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("çæ¬¡ä¸è½éå¤"); |
| | |
| | | |
| | | @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)); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | @Operation(summary = "çæ¬¡ç¶æä¿®æ¹") |
| | | @PostMapping("update") |
| | | @PostMapping("/update") |
| | | public R performanceShiftUpdate(@RequestBody PersonalShift personalShift) { |
| | | personalShiftService.performanceShiftUpdate(personalShift); |
| | | return R.ok(); |
| | |
| | | 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.*; |
| | |
| | | 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) |
| | |
| | | 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); |
| | | } |
| | | |
| | | } |
| | |
| | | /** |
| | | * å®¶åºä½å |
| | | */ |
| | | @Excel(name = "å®¶åºä½å", sort = 6) |
| | | private String adress; |
| | | |
| | | /** |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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)"); |
| | | } |
| | | } |
| | | } |
| | |
| | | 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); |
| | | } |
| | |
| | | List<SchemeApplicableStaff> selectSchemeByStaffId(@Param("staffId") Long staffId); |
| | | |
| | | /** |
| | | * æ ¹æ®é¨é¨IDæ¥è¯¢ææ°ç¤¾ä¿æ¹æ¡ |
| | | * @param deptId é¨é¨ID |
| | | * @return ææ°ç¤¾ä¿æ¹æ¡ |
| | | */ |
| | | SchemeApplicableStaff selectLatestSchemeByDeptId(@Param("deptId") Long deptId); |
| | | |
| | | /** |
| | | * æ ¹æ®ç¤¾ä¿æ¹æ¡IDæ¥è¯¢å¯¹åºçæç»å表 |
| | | * @param schemeId ç¤¾ä¿æ¹æ¡ID |
| | | * @return æ¹æ¡æç»å表 |
| | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | | * å工工èµä¸»è¡¨ Mapper æ¥å£ |
| | |
| | | @Mapper |
| | | public interface StaffSalaryMainMapper extends BaseMapper<StaffSalaryMain> { |
| | | |
| | | List<String> selectIssuedDeptIds(String salaryMonth); |
| | | |
| | | } |
| | |
| | | |
| | | @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; |
| | |
| | | /** |
| | | * å®¶åºä½å |
| | | */ |
| | | @Excel(name = "å®¶åºä½å", sort = 6) |
| | | private String adress; |
| | | |
| | | /** |
| | |
| | | @Schema(description = "å
¶ä»æ¯åº") |
| | | private BigDecimal otherDeduct; |
| | | |
| | | @Schema(description = "社ä¿è¡¥ç¼´") |
| | | private BigDecimal socialSupplementAmount; |
| | | |
| | | @Schema(description = "å·¥èµä¸ªç¨") |
| | | private BigDecimal salaryTax; |
| | | |
| | |
| | | */ |
| | | public interface PersonalAttendanceLocationConfigService extends IService<PersonalAttendanceLocationConfig> { |
| | | |
| | | /** |
| | | * å¤æçæ¬¡é
ç½®æ¯å¦å·²è¢«æçä¸å·²ææå¡è®°å½ä½¿ç¨ã |
| | | */ |
| | | boolean hasAttendanceUsage(Integer configId); |
| | | |
| | | /** |
| | | * å¤æçæ¬¡é
ç½®æ¯å¦å
许ç¼è¾ã |
| | | */ |
| | | boolean canEdit(Integer configId); |
| | | |
| | | /** |
| | | * å¤æçæ¬¡é
ç½®æ¯å¦å
许å é¤ã |
| | | */ |
| | | boolean canDelete(Integer configId); |
| | | |
| | | } |
| | |
| | | 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; |
| | |
| | | AjaxResult delete(List<Long> ids); |
| | | |
| | | AjaxResult calculateSalary(CalculateSalaryDto calculateSalaryDto); |
| | | |
| | | AjaxResult calculateSalaryByEmployee(StaffSalaryCalculateDto staffSalaryCalculateDto); |
| | | |
| | | void exportSalaryDetail(HttpServletResponse response, String salaryMonth); |
| | | |
| | | AjaxResult getAvailableDepts(String salaryMonth); |
| | | } |
| | |
| | | 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> |
| | |
| | | * @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); |
| | | } |
| | | } |
| | |
| | | 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("å½åç¨æ·å½å¤©æ²¡ææçæ°æ®"); |
| | | } |
| | |
| | | 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; |
| | | } |
| | |
| | | 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; |
| | |
| | | * @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); |
| | | } |
| | | |
| | | /** |
| | |
| | | * @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); |
| | | } |
| | | } |
| | |
| | | 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; |
| | |
| | | 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> |
| | |
| | | private final SchemeApplicableStaffServiceImpl schemeApplicableStaffService; |
| | | private final SysUserDeptMapper sysUserDeptMapper; |
| | | private final StaffLeaveMapper staffLeaveMapper; |
| | | private final SysDeptMapper sysDeptMapper; |
| | | |
| | | @Override |
| | | public AjaxResult listPage(Page page, StaffSalaryMain staffSalaryMain) { |
| | |
| | | |
| | | @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()); |
| | |
| | | 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("å¾
å®¡æ ¸ä¸å¯ç¼è¾"); |
| | |
| | | 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<>(); |
| | |
| | | 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; |
| | | } |
| | | |
| | | } |
| | |
| | | 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(); |
| | | } |
| | | |
| | | } |
| | |
| | | void exportStockOutRecord(HttpServletResponse response, StockOutRecordDto stockOutRecordDto); |
| | | |
| | | int batchApprove(List<Long> ids, Integer approvalStatus); |
| | | |
| | | int batchReAudit(List<Long> ids); |
| | | } |
| | |
| | | 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; |
| | |
| | | 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) { |
| | |
| | | @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); |
| | |
| | | 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); |
| | | } |
| | |
| | | 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); |
| | | } |
| | | } |
| | | // éå®éè´§å
¥åº:æ£åéå®å°è´¦å®é
ååéé¢(éè´§çæ) |
| | | handleSalesReturnRefund(stockInRecord); |
| | | } |
| | | } |
| | | return ids.size(); |
| | |
| | | |
| | | return ids.size(); |
| | | } |
| | | |
| | | /** |
| | | * éå®éè´§å
¥åºå®¡æ¹éè¿æ¶,æ£å对åºéå®å°è´¦çå®é
ååéé¢ã |
| | | * å
³èé¾: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); |
| | | } |
| | | } |
| | |
| | | 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); |
| | | } |
| | |
| | | |
| | | @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); |
| | | } |
| | |
| | | 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); |
| | |
| | | @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") |
| | |
| | | |
| | | R add(TechnologyOperationDto technologyOperationDto); |
| | | |
| | | R update(TechnologyOperation technologyOperation); |
| | | |
| | | String batchDelete(List<Long> ids); |
| | | |
| | | List<TechnologyOperationVo> listVo(); |
| | |
| | | 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("ä¿®æ¹å¤±è´¥"); |
| | | } |
| | | |
| | | /** |
| | | * å é¤å·¥åºåæ ¡éªæ¯å¦å·²è¢«BOMç»ææå·¥èºè·¯çº¿å¼ç¨ã |
| | | */ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # å
æçä¾èé¦ç¯ä¿ç§ææéå
¬å¸ 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # å
æçä¾å¸æ°è工贸æé责任å
¬å¸ 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /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çURIç¼ç |
| | | 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 |
| | | # æ
¢SQLè®°å½ |
| | | 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: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | 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 # æ£å¼ç®å½ |
| | | 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) |
| | |
| | | </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> |
| | |
| | | <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> |
| | |
| | | <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 <= 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 < outbound_amount |
| | | </select> |
| | | <select id="selectIncomeStats" resultType="com.ruoyi.home.dto.IncomeExpenseAnalysisDto"> |
| | | SELECT DATE_FORMAT(collection_date, #{dateFormat}) AS dateStr, |
| | |
| | | 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> |
| | |
| | | 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> |
| | |
| | | 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> |
| | |
| | | <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, |
| | |
| | | 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 |
| | |
| | | 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 |
| | |
| | | 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, |
| | |
| | | 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 |
| | |
| | | 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 |
| | |
| | | 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},'%') |
| | |
| | | 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 |
| | |
| | | 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, |
| | |
| | | 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 |
| | |
| | | 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"> |
| | |
| | | </if> |
| | | </where> |
| | | order by po.id desc |
| | | limit #{offset}, #{size} |
| | | <if test="size != null and size >= 0"> |
| | | limit #{offset}, #{size} |
| | | </if> |
| | | </select> |
| | | |
| | | <select id="countHomeOrderProgress" resultType="java.lang.Long"> |
| | |
| | | |
| | | <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"> |
| | |
| | | pl.supplier_name, |
| | | pl.project_name, |
| | | pl.contract_amount, |
| | | pl.net_contract_amount, |
| | | pl.entry_date, |
| | | pl.execution_date, |
| | | pl.recorder_id, |
| | |
| | | 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 |
| | |
| | | <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" /> |
| | |
| | | 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 |
| | |
| | | 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, |
| | |
| | | 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, |
| | |
| | | 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> |
| | |
| | | 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') |
| | |
| | | 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> |
| | |
| | | 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, |
| | |
| | | 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, |
| | |
| | | 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, |
| | |
| | | ) 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> |
| | |
| | | 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' |
| | |
| | | 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 |
| | |
| | | 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> |
| | |
| | | order by personal_attendance_records.id desc |
| | | </select> |
| | | |
| | | <!-- æ¥è¯¢æå®æ¥ææ²¡æèå¤è®°å½çå¨èåå·¥ï¼å¨æå®æ¶é´ä¹åå
¥èçï¼ --> |
| | | <!-- æ¥è¯¢æå®æ¥æææçï¼é请åï¼ä½æ²¡æèå¤è®°å½çå¨èåå·¥ï¼æ²¡æçè§ä¸ºä¼æ¯ä¸æ è®°ç¼ºå¤ --> |
| | | <select id="selectStaffWithoutAttendanceRecordBeforeTime" resultType="com.ruoyi.staff.pojo.StaffOnJob"> |
| | | SELECT soj.* |
| | | FROM staff_on_job soj |
| | |
| | | AND soj.create_time < #{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 |
| | |
| | | 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}, '%') |
| | |
| | | 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}, '%') |
| | |
| | | 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}, '%') |
| | |
| | | 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}, '%') |
| | |
| | | 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> |
| | |
| | | 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 |
| | |
| | | <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> |
| | |
| | | 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 |
| | |
| | | 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 |
| | |
| | | <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"> |
| | |
| | | |
| | | <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"> |
| | |
| | | <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> |
| | |
| | | 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 |