From 7cd413d0f1e3235223848d47e428aad97f9f13fc Mon Sep 17 00:00:00 2001
From: yangys <y_ys79@sina.com>
Date: 星期一, 30 十二月 2024 11:23:02 +0800
Subject: [PATCH] 去掉数据点中的计算规则和计算参数-暂时

---
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/convert/PartWorkingProcessConvert.java       |   24 
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/controller/PartWorkHourController.java       |   76 +
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/service/PartWorkingHourService.java          |  148 +++
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/service/JFreeChartUtil.java                  |  290 ++++++
 smart-man-boot/src/main/resources/sql/mysql/workinghours.sql                                                       |   58 +
 smart-man-boot/src/test/java/com/qianwen/smartman/common/utils/DurationUtilTest.java                               |   33 
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/service/PartWorkingProcessService.java       |   84 +
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/vo/PartWorkingHourVO.java                    |  168 +++
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/vo/PartWorkingProcessVO.java                 |   65 +
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/mapper/PartWorkingProcessMapper.java         |   18 
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/entity/PartWorkingProcess.java               |   73 +
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/excel/PartWorkingProcessExcel.java           |   62 +
 smart-man-boot/src/test/java/com/qianwen/smartman/modules/workinghour/service/PartWorkingHourServiceTest.java      |  510 +++++++++++
 smart-man-boot/src/main/java/com/qianwen/smartman/common/utils/DurationUtil.java                                   |   47 +
 smart-man-boot/src/main/java/com/qianwen/smartman/common/vo/CommonIdsVO.java                                       |   23 
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/service/PartWorkingHourExportService.java    |  378 ++++++++
 smart-man-boot/src/main/java/com/qianwen/smartman/common/config/SwaggerConfiguration.java                          |    5 
 smart-man-boot/src/main/resources/dp/dpend.json                                                                    |    2 
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/smis/controller/WorkstationController.java               |    1 
 smart-man-boot/src/main/resources/dp/dpend-带计算规则.json                                                              |    1 
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/entity/PartWorkingHour.java                  |  170 +++
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/convert/PartWorkingHourConvert.java          |   24 
 smart-man-boot/src/main/resources/com/qianwen/smartman/modules/workinghour/mapper/PartWorkingHourMapper.xml        |   74 +
 smart-man-boot/pom.xml                                                                                             |    7 
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/vo/PartWorkingHourQueryVO.java               |   50 +
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/excel/PartWorkingHourExcel.java              |  159 +++
 smart-man-boot/src/main/resources/sql/iotdb/iot_struct.sql                                                         |   17 
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/controller/PartWorkingProcessController.java |   42 
 smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/mapper/PartWorkingHourMapper.java            |   36 
 29 files changed, 2,643 insertions(+), 2 deletions(-)

diff --git a/smart-man-boot/pom.xml b/smart-man-boot/pom.xml
index 08028d1..5b64850 100644
--- a/smart-man-boot/pom.xml
+++ b/smart-man-boot/pom.xml
@@ -504,6 +504,13 @@
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
         </dependency>
+        
+        
+        <dependency>
+		    <groupId>org.jfree</groupId>
+		    <artifactId>jfreechart</artifactId>
+		    <version>1.5.5</version>
+		</dependency>
     </dependencies>
 	
   <build>
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/common/config/SwaggerConfiguration.java b/smart-man-boot/src/main/java/com/qianwen/smartman/common/config/SwaggerConfiguration.java
index 6490374..fa91a74 100644
--- a/smart-man-boot/src/main/java/com/qianwen/smartman/common/config/SwaggerConfiguration.java
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/common/config/SwaggerConfiguration.java
@@ -137,6 +137,11 @@
         return docket("andon", Collections.singletonList("com.qianwen.smartman.modules.andon"));
     }
 
+    @Bean
+    public Docket workinghourDocket() {
+        return docket("workinghour", Collections.singletonList("com.qianwen.smartman.modules.workinghour"));
+    }
+    
     private Docket docket(String groupName, List<String> basePackages) {
         TypeResolver resolver = new TypeResolver();
         AlternateTypeRule listLongToString = AlternateTypeRules.newRule(resolver.resolve(List.class, new Type[]{Long.class}), resolver.resolve(List.class, new Type[]{String.class}));
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/common/utils/DurationUtil.java b/smart-man-boot/src/main/java/com/qianwen/smartman/common/utils/DurationUtil.java
new file mode 100644
index 0000000..c0486eb
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/common/utils/DurationUtil.java
@@ -0,0 +1,47 @@
+package com.qianwen.smartman.common.utils;
+
+import java.time.Duration;
+
+public class DurationUtil {
+	/**
+     * 灏嗘椂闂村樊杞崲涓轰腑鏂囷紝濡�1澶�2灏忔椂3鍒�15绉�
+     * @param duration
+     * @return 涓枃鏃堕棿宸�
+     */
+    public static String toChineseDuration(Duration duration) {
+    	String dayStr = "";
+		if(duration.toDays() > 0) {
+			dayStr = duration.toDays()+"澶�";
+		}
+		
+		long temp;
+		
+		String secStr = "";
+		if(duration.getSeconds() > 0) {
+			temp = duration.getSeconds()%60;
+			if(temp > 0) {
+				secStr = temp+"绉�";
+			}
+		}
+		
+		String minStr = "";
+		if(duration.toMinutes() > 0) {
+			temp = duration.toMinutes()%60;
+			if(temp > 0) {
+				minStr += temp+"鍒�";
+			}
+		}
+		
+		String hourStr = "";
+		if(duration.toHours() > 0) {
+			temp = duration.toHours()%24;
+			if(temp > 0) {
+				hourStr = temp+"灏忔椂";
+			}
+		}
+		
+		
+		
+		return dayStr + hourStr+minStr+secStr;
+    }
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/common/vo/CommonIdsVO.java b/smart-man-boot/src/main/java/com/qianwen/smartman/common/vo/CommonIdsVO.java
new file mode 100644
index 0000000..a71efa9
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/common/vo/CommonIdsVO.java
@@ -0,0 +1,23 @@
+package com.qianwen.smartman.common.vo;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.validation.constraints.NotEmpty;
+
+public class CommonIdsVO  implements Serializable {
+    /**
+	 * 
+	 */
+	private static final long serialVersionUID = 1791423608430772402L;
+	@NotEmpty(message = "ids涓嶈兘涓虹┖")
+    private List<Long> ids;
+	public List<Long> getIds() {
+		return ids;
+	}
+	public void setIds(List<Long> ids) {
+		this.ids = ids;
+	}
+	
+	
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/smis/controller/WorkstationController.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/smis/controller/WorkstationController.java
index 99def29..b0d6fe1 100644
--- a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/smis/controller/WorkstationController.java
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/smis/controller/WorkstationController.java
@@ -35,7 +35,6 @@
 import com.qianwen.smartman.modules.smis.dto.WorkstationRealTimeStatusDTO;
 import com.qianwen.smartman.modules.smis.excel.WorkstationImport;
 import com.qianwen.smartman.modules.smis.service.IWorkstationService;
-import com.qianwen.smartman.modules.smis.vo.DmpVariablesVO;
 import com.qianwen.smartman.modules.smis.vo.FmsWorkstationGroupVO;
 import com.qianwen.smartman.modules.smis.vo.FmsWorkstationQueryVO;
 import com.qianwen.smartman.modules.smis.vo.WorkMachineEasyVO;
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/controller/PartWorkHourController.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/controller/PartWorkHourController.java
new file mode 100644
index 0000000..55c57f3
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/controller/PartWorkHourController.java
@@ -0,0 +1,76 @@
+package com.qianwen.smartman.modules.workinghour.controller;
+
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.qianwen.core.boot.ctrl.BladeController;
+import com.qianwen.core.mp.support.Condition;
+import com.qianwen.core.mp.support.Query;
+import com.qianwen.core.oss.model.BladeFile;
+import com.qianwen.core.scanner.modular.stereotype.ApiResource;
+import com.qianwen.core.tenant.annotation.NonDS;
+import com.qianwen.core.tool.api.R;
+import com.qianwen.smartman.common.vo.CommonIdsVO;
+import com.qianwen.smartman.modules.workinghour.service.PartWorkingHourExportService;
+import com.qianwen.smartman.modules.workinghour.service.PartWorkingHourService;
+import com.qianwen.smartman.modules.workinghour.vo.PartWorkingHourQueryVO;
+import com.qianwen.smartman.modules.workinghour.vo.PartWorkingHourVO;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@Api(value = "宸ユ椂鍒嗘瀽", tags = {"宸ユ椂鍒嗘瀽"})
+@RestController
+@ApiResource({"workinghour"})
+@NonDS
+@Validated
+public class PartWorkHourController extends BladeController {
+	private Logger log = LoggerFactory.getLogger(this.getClass());
+	@Autowired
+    private PartWorkingHourService partWorkingHourService;
+	@Autowired
+    private PartWorkingHourExportService partWorkingHourExportService;
+
+    @PostMapping({"/page"})
+    @ApiOperation("鏌ヨ闆朵欢鍒楄〃鍒嗛〉")
+    public R<IPage<PartWorkingHourVO>> page(@RequestBody PartWorkingHourQueryVO queryVO,Query query) {
+    	//@RequestParam(value = "partNo", required = false) String partNo, @RequestParam(value="workstationName", required = false) String workstationName, @RequestParam("startDate") LocalDate startDate, @RequestParam("endDate") LocalDate endDate
+        return R.data(partWorkingHourService.listPage(Condition.getPage(query), queryVO.getPartNo(), queryVO.getWorkstationName(), queryVO.getStartDate(),queryVO.getEndDate()));
+    }
+    
+    
+    
+    @PostMapping({"/listByIds"})
+    @ApiOperation("鏌ヨ闆朵欢鍒楄〃-鎸塱ds")
+    public R<List<PartWorkingHourVO>> listByIds(@RequestBody CommonIdsVO idsVO) {
+        return R.data(partWorkingHourService.listVOByIds(idsVO.getIds()));
+    }
+
+    
+    @GetMapping({"/exportold"})
+    @ApiOperation("宸ユ椂鏁版嵁瀵煎嚭old")
+    public R<BladeFile> exportOld(long id) {
+        return R.data(partWorkingHourService.export(id));
+    }
+    
+    @GetMapping({"/export"})
+    @ApiOperation("宸ユ椂鏁版嵁瀵煎嚭")
+    public R<BladeFile> export(long id) {
+        try {
+			return R.data(partWorkingHourExportService.export(id));
+		} catch (Exception e) {
+			log.error("瀵煎嚭鍏紡鏁版嵁閿欒",e);
+			
+			return R.fail(e.getMessage());
+		}
+    }
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/controller/PartWorkingProcessController.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/controller/PartWorkingProcessController.java
new file mode 100644
index 0000000..eeae1f7
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/controller/PartWorkingProcessController.java
@@ -0,0 +1,42 @@
+package com.qianwen.smartman.modules.workinghour.controller;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.qianwen.core.boot.ctrl.BladeController;
+import com.qianwen.core.oss.model.BladeFile;
+import com.qianwen.core.scanner.modular.stereotype.ApiResource;
+import com.qianwen.core.tenant.annotation.NonDS;
+import com.qianwen.core.tool.api.R;
+import com.qianwen.smartman.modules.workinghour.service.PartWorkingProcessService;
+import com.qianwen.smartman.modules.workinghour.vo.PartWorkingProcessVO;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@Api(value = "宸ユ椂鍒嗘瀽", tags = {"宸ユ椂鍒嗘瀽"})
+@RestController
+@ApiResource({"workinghour"})
+@NonDS
+@Validated
+public class PartWorkingProcessController extends BladeController {
+	@Autowired
+    private PartWorkingProcessService partWorkingProcessService;
+    
+    
+    @GetMapping({"/working-process"})
+    @ApiOperation("鍔犲伐杩囩▼鏁版嵁")
+    public R<List<PartWorkingProcessVO>> list(long id) {
+        return R.data(partWorkingProcessService.listByWorkinghourId(id));
+    }
+
+    @GetMapping({"/working-process-export"})
+    @ApiOperation("鍔犲伐杩囩▼鏁版嵁瀵煎嚭")
+    public R<BladeFile> export(long id) {
+        return R.data(partWorkingProcessService.export(id));
+    }
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/convert/PartWorkingHourConvert.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/convert/PartWorkingHourConvert.java
new file mode 100644
index 0000000..455f002
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/convert/PartWorkingHourConvert.java
@@ -0,0 +1,24 @@
+package com.qianwen.smartman.modules.workinghour.convert;
+
+import java.util.List;
+
+import org.mapstruct.Builder;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+import com.qianwen.smartman.modules.mdc.utils.ConvertUtils;
+import com.qianwen.smartman.modules.workinghour.entity.PartWorkingHour;
+import com.qianwen.smartman.modules.workinghour.vo.PartWorkingHourVO;
+
+@Mapper(builder = @Builder(disableBuilder = true), imports = {ConvertUtils.class})
+public interface PartWorkingHourConvert {
+    public static final PartWorkingHourConvert INSTANCE = (PartWorkingHourConvert) Mappers.getMapper(PartWorkingHourConvert.class);
+
+    //@Mappings({@Mapping(target = "alarmTime", expression = "java(ConvertUtils.format(alarm.getTime()))"), @Mapping(target = "alarmCode", source = "code"), @Mapping(target = "alarmMsg", source = "message"), @Mapping(target = "count", expression = "java(ConvertUtils.defaultValue())")})
+    @Mappings({})
+    PartWorkingHourVO convert(PartWorkingHour pwh);
+
+    @Mappings({})
+    List<PartWorkingHourVO> convert(List<PartWorkingHour> alarms);
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/convert/PartWorkingProcessConvert.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/convert/PartWorkingProcessConvert.java
new file mode 100644
index 0000000..2faf4f2
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/convert/PartWorkingProcessConvert.java
@@ -0,0 +1,24 @@
+package com.qianwen.smartman.modules.workinghour.convert;
+
+import java.util.List;
+
+import org.mapstruct.Builder;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+import com.qianwen.smartman.modules.mdc.utils.ConvertUtils;
+import com.qianwen.smartman.modules.workinghour.entity.PartWorkingProcess;
+import com.qianwen.smartman.modules.workinghour.vo.PartWorkingProcessVO;
+
+@Mapper(builder = @Builder(disableBuilder = true), imports = {ConvertUtils.class})
+public interface PartWorkingProcessConvert {
+    public static final PartWorkingProcessConvert INSTANCE = (PartWorkingProcessConvert) Mappers.getMapper(PartWorkingProcessConvert.class);
+
+    //@Mappings({@Mapping(target = "alarmTime", expression = "java(ConvertUtils.format(alarm.getTime()))"), @Mapping(target = "alarmCode", source = "code"), @Mapping(target = "alarmMsg", source = "message"), @Mapping(target = "count", expression = "java(ConvertUtils.defaultValue())")})
+    @Mappings({})
+    PartWorkingProcessVO convert(PartWorkingProcess pwh);
+
+    @Mappings({})
+    List<PartWorkingProcessVO> convert(List<PartWorkingProcess> housrs);
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/entity/PartWorkingHour.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/entity/PartWorkingHour.java
new file mode 100644
index 0000000..6a0a94e
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/entity/PartWorkingHour.java
@@ -0,0 +1,170 @@
+package com.qianwen.smartman.modules.workinghour.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+import com.qianwen.core.tenant.mp.TenantEntity;
+
+/**
+ * 闆朵欢宸ユ椂
+ */
+@TableName("part_workinghour")
+public class PartWorkingHour extends TenantEntity {
+	/**
+	 * 闆朵欢缂栧彿
+	 */
+	private String partNo;
+	/**
+	 * 宸ュ簭鍙�
+	 */
+	private String processNo;
+	/**
+	 * 鐗堟
+	 */
+	private String version;
+	/**
+	 * 宸ヤ綅id
+	 * */
+	private long workstationId;
+	/**
+	 * 寮�濮嬫椂闂�*/
+	private LocalDateTime startTime;
+	/**
+	 * 缁撴潫鏃堕棿
+	 */
+	private LocalDateTime endTime;
+	/**
+	 * 鍗犳満鏃堕棿(绉�)
+	 */
+	private Long occupancySecs;
+	/**
+	 * 瑁呭す璋冭瘯鏃堕棿(绉�)
+	 */
+	private Long clampingSecs;
+	/**
+	 * 棣栦欢鍒囧墛鏃堕棿(绉�)
+	 */
+	private Long firstWorkingSecs;
+	/**
+	 * 鏈欢鎷嗗嵏鏃堕棿(绉�)
+	 */
+	private Long lastRemoveSecs;
+	/**
+	 * 棣栦欢璁¢噺鏃堕棿(绉�)
+	 */
+	private Long firstMeasureSecs;
+	
+	/**
+	 * 鍔犲伐鏃堕棿(绉�)
+	 */
+	private Long processingSecs;
+	/**
+	 * 鍑嗗鏃堕棿(绉�)
+	 */
+	private Long prepareSecs;
+	/**
+	 * 鍗曚欢宸ユ椂(绉�)
+	 */
+	private Long singleProcessSecs;
+	/**
+	 * 闆朵欢鐢熶骇鏁伴噺
+	 */
+	private Long amount;
+	public String getPartNo() {
+		return partNo;
+	}
+	public void setPartNo(String partNo) {
+		this.partNo = partNo;
+	}
+	public String getProcessNo() {
+		return processNo;
+	}
+	public void setProcessNo(String processNo) {
+		this.processNo = processNo;
+	}
+	public String getVersion() {
+		return version;
+	}
+	public void setVersion(String version) {
+		this.version = version;
+	}
+	public long getWorkstationId() {
+		return workstationId;
+	}
+	public void setWorkstationId(long workstationId) {
+		this.workstationId = workstationId;
+	}
+	public LocalDateTime getStartTime() {
+		return startTime;
+	}
+	public void setStartTime(LocalDateTime startTime) {
+		this.startTime = startTime;
+	}
+	public LocalDateTime getEndTime() {
+		return endTime;
+	}
+	public void setEndTime(LocalDateTime endTime) {
+		this.endTime = endTime;
+	}
+	public Long getOccupancySecs() {
+		return occupancySecs;
+	}
+	public void setOccupancySecs(Long occupancySecs) {
+		this.occupancySecs = occupancySecs;
+	}
+	public Long getClampingSecs() {
+		return clampingSecs;
+	}
+	public void setClampingSecs(Long clampingSecs) {
+		this.clampingSecs = clampingSecs;
+	}
+	public Long getFirstWorkingSecs() {
+		return firstWorkingSecs;
+	}
+	public void setFirstWorkingSecs(Long firstWorkingSecs) {
+		this.firstWorkingSecs = firstWorkingSecs;
+	}
+	public Long getLastRemoveSecs() {
+		return lastRemoveSecs;
+	}
+	public void setLastRemoveSecs(Long lastRemoveSecs) {
+		this.lastRemoveSecs = lastRemoveSecs;
+	}
+	public Long getFirstMeasureSecs() {
+		return firstMeasureSecs;
+	}
+	public void setFirstMeasureSecs(Long firstMeasureSecs) {
+		this.firstMeasureSecs = firstMeasureSecs;
+	}
+	
+	public Long getProcessingSecs() {
+		return processingSecs;
+	}
+	public void setProcessingSecs(Long processingSecs) {
+		this.processingSecs = processingSecs;
+	}
+	public Long getPrepareSecs() {
+		return prepareSecs;
+	}
+	public void setPrepareSecs(Long prepareSecs) {
+		this.prepareSecs = prepareSecs;
+	}
+	public Long getSingleProcessSecs() {
+		return singleProcessSecs;
+	}
+	public void setSingleProcessSecs(Long singleProcessSecs) {
+		this.singleProcessSecs = singleProcessSecs;
+	}
+	public Long getAmount() {
+		return amount;
+	}
+	public void setAmount(Long amount) {
+		this.amount = amount;
+	}
+	
+	
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/entity/PartWorkingProcess.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/entity/PartWorkingProcess.java
new file mode 100644
index 0000000..aa76ca3
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/entity/PartWorkingProcess.java
@@ -0,0 +1,73 @@
+package com.qianwen.smartman.modules.workinghour.entity;
+
+import java.time.LocalDateTime;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+
+/**
+ * 闆朵欢鍔犲伐杩囩▼鏁版嵁
+ */
+@TableName("part_working_process")
+public class PartWorkingProcess{
+	long id;
+	/**
+	 * 闆朵欢缂栧彿
+	 */
+	private String progName;
+	
+	/**
+	 * 宸ヤ綅id
+	 * */
+	private long workinghourId;
+	/**
+	 * 寮�濮嬫椂闂�*/
+	private LocalDateTime startTime;
+	/**
+	 * 缁撴潫鏃堕棿
+	 */
+	private LocalDateTime endTime;
+	
+	/**
+	 * 璁惧鐘舵��
+	 */
+	private Integer deviceStatus;
+	
+	public long getId() {
+		return id;
+	}
+	public void setId(long id) {
+		this.id = id;
+	}
+	public String getProgName() {
+		return progName;
+	}
+	public void setProgName(String progName) {
+		this.progName = progName;
+	}
+	public long getWorkinghourId() {
+		return workinghourId;
+	}
+	public void setWorkinghourId(long workinghourId) {
+		this.workinghourId = workinghourId;
+	}
+	public LocalDateTime getStartTime() {
+		return startTime;
+	}
+	public void setStartTime(LocalDateTime startTime) {
+		this.startTime = startTime;
+	}
+	public LocalDateTime getEndTime() {
+		return endTime;
+	}
+	public void setEndTime(LocalDateTime endTime) {
+		this.endTime = endTime;
+	}
+	public Integer getDeviceStatus() {
+		return deviceStatus;
+	}
+	public void setDeviceStatus(Integer deviceStatus) {
+		this.deviceStatus = deviceStatus;
+	}
+	
+	
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/excel/PartWorkingHourExcel.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/excel/PartWorkingHourExcel.java
new file mode 100644
index 0000000..80c5cb9
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/excel/PartWorkingHourExcel.java
@@ -0,0 +1,159 @@
+package com.qianwen.smartman.modules.workinghour.excel;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+import com.qianwen.core.tenant.mp.TenantEntity;
+
+/**
+ * 闆朵欢宸ユ椂
+ */
+
+public class PartWorkingHourExcel{
+
+	@ExcelProperty({"闆朵欢缂栧彿"})
+	private String partNo;
+
+	@ExcelProperty({"宸ュ簭鍙�"})
+	private String processNo;
+	
+	@ExcelProperty({"鐗堟"})
+	private String version;
+	
+	@ExcelProperty({"宸ヤ綅"})
+	private String workstationName;
+
+	@ExcelProperty({"寮�濮嬫椂闂�"})
+	private String startTime;
+	
+	@ExcelProperty({"缁撴潫鏃堕棿"})
+	private String endTime;
+	
+	@ExcelProperty({"鍗犳満鏃堕棿"})
+	private String occupancySecs;
+	/**
+	 * 
+	 */
+	@ExcelProperty({"瑁呭す璋冭瘯鏃堕棿"})
+	private String clampingSecs;
+	
+	@ExcelProperty({"棣栦欢鍒囧墛鏃堕棿"})
+	private String firstWorkingSecs;
+	
+	@ExcelProperty({"鏈欢鎷嗗嵏鏃堕棿"})
+	private String lastRemoveSecs;
+	
+	@ExcelProperty({"棣栦欢璁¢噺鏃堕棿"})
+	private String firstMeasureSecs;
+	
+	
+	@ExcelProperty({"鍔犲伐鏃堕棿"})
+	private String processingSecs;
+	
+	@ExcelProperty({"鍑嗗鏃堕棿"})
+	private String prepareSecs;
+	
+	@ExcelProperty({"鍗曚欢宸ユ椂"})
+	private String singleProcessSecs;
+	
+	@ExcelProperty({"鏁伴噺"})
+	private Long amount;
+	public String getPartNo() {
+		return partNo;
+	}
+	public void setPartNo(String partNo) {
+		this.partNo = partNo;
+	}
+	public String getProcessNo() {
+		return processNo;
+	}
+	public void setProcessNo(String processNo) {
+		this.processNo = processNo;
+	}
+	public String getVersion() {
+		return version;
+	}
+	public void setVersion(String version) {
+		this.version = version;
+	}
+	
+	public String getWorkstationName() {
+		return workstationName;
+	}
+	public void setWorkstationName(String workstationName) {
+		this.workstationName = workstationName;
+	}
+	public String getStartTime() {
+		return startTime;
+	}
+	public void setStartTime(String startTime) {
+		this.startTime = startTime;
+	}
+	public String getEndTime() {
+		return endTime;
+	}
+	public void setEndTime(String endTime) {
+		this.endTime = endTime;
+	}
+	public Long getAmount() {
+		return amount;
+	}
+	public void setAmount(Long amount) {
+		this.amount = amount;
+	}
+	public String getOccupancySecs() {
+		return occupancySecs;
+	}
+	public void setOccupancySecs(String occupancySecs) {
+		this.occupancySecs = occupancySecs;
+	}
+	public String getClampingSecs() {
+		return clampingSecs;
+	}
+	public void setClampingSecs(String clampingSecs) {
+		this.clampingSecs = clampingSecs;
+	}
+	public String getFirstWorkingSecs() {
+		return firstWorkingSecs;
+	}
+	public void setFirstWorkingSecs(String firstWorkingSecs) {
+		this.firstWorkingSecs = firstWorkingSecs;
+	}
+	public String getLastRemoveSecs() {
+		return lastRemoveSecs;
+	}
+	public void setLastRemoveSecs(String lastRemoveSecs) {
+		this.lastRemoveSecs = lastRemoveSecs;
+	}
+	public String getFirstMeasureSecs() {
+		return firstMeasureSecs;
+	}
+	public void setFirstMeasureSecs(String firstMeasureSecs) {
+		this.firstMeasureSecs = firstMeasureSecs;
+	}
+	public String getProcessingSecs() {
+		return processingSecs;
+	}
+	public void setProcessingSecs(String processingSecs) {
+		this.processingSecs = processingSecs;
+	}
+	public String getPrepareSecs() {
+		return prepareSecs;
+	}
+	public void setPrepareSecs(String prepareSecs) {
+		this.prepareSecs = prepareSecs;
+	}
+	public String getSingleProcessSecs() {
+		return singleProcessSecs;
+	}
+	public void setSingleProcessSecs(String singleProcessSecs) {
+		this.singleProcessSecs = singleProcessSecs;
+	}
+	
+	
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/excel/PartWorkingProcessExcel.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/excel/PartWorkingProcessExcel.java
new file mode 100644
index 0000000..e7533e5
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/excel/PartWorkingProcessExcel.java
@@ -0,0 +1,62 @@
+package com.qianwen.smartman.modules.workinghour.excel;
+
+import java.io.Serializable;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import com.alibaba.excel.annotation.write.style.ContentRowHeight;
+import com.alibaba.excel.annotation.write.style.HeadRowHeight;
+
+@HeadRowHeight(20)
+@ColumnWidth(16)
+@ContentRowHeight(18)
+public class PartWorkingProcessExcel implements Serializable {
+	
+    /**
+	 * 
+	 */
+	private static final long serialVersionUID = -5329911071641310785L;
+
+    @ExcelProperty({"绋嬪簭鍚嶇О"})
+    private String progName;
+    @ExcelProperty({"寮�濮嬫椂闂�"})
+    private String startTime;
+    @ExcelProperty({"缁撴潫鏃堕棿"})
+    private String endTime;
+    @ExcelProperty({"鎸佺画鏃堕暱"})
+    private String duration;
+    @ExcelProperty({"鐘舵��"})
+    private String deviceStateName;
+	public String getProgName() {
+		return progName;
+	}
+	public void setProgName(String progName) {
+		this.progName = progName;
+	}
+	public String getStartTime() {
+		return startTime;
+	}
+	public void setStartTime(String startTime) {
+		this.startTime = startTime;
+	}
+	public String getEndTime() {
+		return endTime;
+	}
+	public void setEndTime(String endTime) {
+		this.endTime = endTime;
+	}
+	public String getDuration() {
+		return duration;
+	}
+	public void setDuration(String duration) {
+		this.duration = duration;
+	}
+	public String getDeviceStateName() {
+		return deviceStateName;
+	}
+	public void setDeviceStateName(String deviceStateName) {
+		this.deviceStateName = deviceStateName;
+	}
+    
+    
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/mapper/PartWorkingHourMapper.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/mapper/PartWorkingHourMapper.java
new file mode 100644
index 0000000..6187681
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/mapper/PartWorkingHourMapper.java
@@ -0,0 +1,36 @@
+package com.qianwen.smartman.modules.workinghour.mapper;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.qianwen.core.datascope.annotation.DataAuth;
+import com.qianwen.smartman.modules.smis.vo.WorkstationVO;
+import com.qianwen.smartman.modules.workinghour.entity.PartWorkingHour;
+import com.qianwen.smartman.modules.workinghour.vo.PartWorkingHourVO;
+
+public interface PartWorkingHourMapper extends BaseMapper<PartWorkingHour> {
+
+	/**
+	 * 鏌ヨ鍒嗛〉鍒楄〃
+	 * @param page
+	 * @param partNo
+	 * @param workstationName
+	 * @param startDate
+	 * @param endDate
+	 * @return
+	 */
+	@DataAuth(code = "workstation")
+    List<PartWorkingHourVO> listPage(IPage<PartWorkingHourVO> page, @Param("partNo")String partNo, @Param("workstationName")String workstationName, @Param("startDate")LocalDate startDate, @Param("endDate")LocalDate endDate);
+	
+	/**
+	 * 鏍规嵁id閫夋嫨璁板綍
+	 * @param ids
+	 * @return
+	 */
+	List<PartWorkingHourVO> listVOByIds(List<Long> ids);
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/mapper/PartWorkingProcessMapper.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/mapper/PartWorkingProcessMapper.java
new file mode 100644
index 0000000..388a7ac
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/mapper/PartWorkingProcessMapper.java
@@ -0,0 +1,18 @@
+package com.qianwen.smartman.modules.workinghour.mapper;
+
+import java.util.List;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qianwen.smartman.modules.workinghour.entity.PartWorkingProcess;
+import com.qianwen.smartman.modules.workinghour.vo.PartWorkingProcessVO;
+
+public interface PartWorkingProcessMapper extends BaseMapper<PartWorkingProcess> {
+
+	
+	/**
+	 * 鏍规嵁id閫夋嫨璁板綍
+	 * @param workinghourId 宸ユ椂琛╥d
+	 * @return
+	 */
+	List<PartWorkingProcessVO> listVOByWorkingHourId(Long workinghourId);
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/service/JFreeChartUtil.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/service/JFreeChartUtil.java
new file mode 100644
index 0000000..04d0128
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/service/JFreeChartUtil.java
@@ -0,0 +1,290 @@
+package com.qianwen.smartman.modules.workinghour.service;
+
+//import cn.hutool.core.util.StrUtil;
+import org.jfree.chart.*;
+import org.jfree.chart.axis.ValueAxis;
+import org.jfree.chart.labels.*;
+import org.jfree.chart.plot.*;
+import org.jfree.chart.renderer.category.*;
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
+import org.jfree.chart.ui.*;
+import org.jfree.data.category.DefaultCategoryDataset;
+import org.jfree.data.general.DefaultPieDataset;
+import org.springframework.core.io.ClassPathResource;
+ 
+import java.awt.*;
+import java.io.File;
+import java.io.IOException;
+import java.text.NumberFormat;
+import java.util.List;
+
+public class JFreeChartUtil {
+
+	public static String NO_DATA_MSG = "鏁版嵁鍔犺浇澶辫触";
+	 
+    /**
+     * 鐢熸垚涓婚
+     *
+     * @param fontName 瀛椾綋鍚嶇О锛堥粯璁や负瀹嬩綋锛�
+     * @return
+     */
+    public static StandardChartTheme createChartTheme(String fontName) throws Exception {
+        StandardChartTheme theme = new StandardChartTheme("unicode") {
+            public void apply(JFreeChart chart) {
+                chart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING,
+                        RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
+                super.apply(chart);
+            }
+        };
+        theme.setExtraLargeFont(getDefaultFont(Font.PLAIN, 20f));
+        theme.setLargeFont(getDefaultFont(Font.PLAIN, 14f));
+        theme.setRegularFont(getDefaultFont(Font.PLAIN, 12f));
+        theme.setSmallFont(getDefaultFont(Font.PLAIN, 10f));
+        return theme;
+    }
+ 
+    /**
+     * 鑾峰彇榛樿瀛椾綋
+     *
+     * @param style
+     * @param size  瀛椾綋澶у皬
+     * @return
+     * @throws Exception
+     */
+    public static Font getDefaultFont(int style, Float size) throws Exception {
+        //鑾峰彇瀹嬩綋鏂囦欢
+        //File defaultFontFile = new ClassPathResource("/font/simsun.ttc").getFile();
+        //Font defaultFont = Font.createFont(Font.TRUETYPE_FONT, defaultFontFile);
+    	Font defaultFont = new Font("瀹嬩綋",style,size.intValue());//yys鏀�
+        //defaultFont = defaultFont.deriveFont(style, size);
+        return defaultFont;
+    }
+ 
+    /**
+     * 鍒涘缓楗煎浘鏁版嵁闆嗗悎
+     *
+     * @param legendNameList 鍥句緥鍚嶇О鍒楄〃
+     * @param dataList       鏁版嵁鍒楄〃
+     * @return
+     */
+    public static DefaultPieDataset createDefaultPieDataset(List<String> legendNameList, List<Object> dataList) {
+        DefaultPieDataset dataset = new DefaultPieDataset();
+        //鍥句緥鍚嶇О鍒楄〃鎴栨暟鎹垪琛ㄤ负绌�
+        if (legendNameList == null || legendNameList.size() <= 0 || dataList == null || dataList.size() <= 0) {
+            return dataset;
+        }
+        for (int i = 0; i < legendNameList.size() && legendNameList.size() == dataList.size(); i++) {
+            String value = dataList.get(i).toString();
+            dataset.setValue(legendNameList.get(i), Double.valueOf(value));
+        }
+        return dataset;
+    }
+ 
+    /**
+     * 璁剧疆楗肩姸鍥炬覆鏌�
+     */
+    public static void setPieRender(Plot plot) {
+        plot.setNoDataMessage(NO_DATA_MSG);
+        plot.setInsets(new RectangleInsets(10, 10, 5, 10));
+        PiePlot piePlot = (PiePlot) plot;
+        piePlot.setInsets(new RectangleInsets(0, 0, 0, 0));
+        piePlot.setCircular(true);// 鍦嗗舰
+ 
+        // 绠�鍗曟爣绛�
+        piePlot.setLabelGap(0.01);
+        piePlot.setInteriorGap(0.05D);
+        // 鍥句緥褰㈢姸
+        piePlot.setLegendItemShape(new Rectangle(10, 10));
+        piePlot.setIgnoreNullValues(true);
+        // 鍘绘帀鏍囩鑳屾櫙鑹�
+        piePlot.setLabelBackgroundPaint(null);
+        //鍘绘帀鍥捐〃鑳屾櫙棰滆壊
+        piePlot.setBackgroundPaint(null);
+        // 鍘绘帀闃村奖
+        piePlot.setLabelShadowPaint(null);
+        // 鍘绘帀杈规
+        piePlot.setLabelOutlinePaint(null);
+        piePlot.setShadowPaint(null);
+        // 鏄剧ず鏍囩鏁版嵁
+        piePlot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}:{2}"));
+    }
+ 
+    /**
+     * 鍒涘缓绫诲埆鏁版嵁闆嗗悎(鏌卞舰鍥俱�佹姌绾垮浘)
+     *
+     * @param legendNameList 鍥句緥鍚嶇О鍒楄〃
+     * @param xAxisNameList  x杞村悕绉板垪琛�
+     * @param dataList       鏁版嵁鍒楄〃
+     * @return
+     */
+    public static DefaultCategoryDataset createDefaultCategoryDataset(List<String> legendNameList, List<String> xAxisNameList
+            , List<List<Object>> dataList) {//TODO 杩欓噷
+        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
+        //鍥句緥鍚嶇О鍒楄〃銆亁杞村悕绉板垪琛ㄦ垨鏁版嵁鍒楄〃涓虹┖
+        if (xAxisNameList == null || xAxisNameList.size() <= 0 || legendNameList == null || legendNameList.size() <= 0
+                || dataList == null || dataList.size() <= 0) {
+            return dataset;
+        }
+        for (int yAxisIndex = 0; yAxisIndex < legendNameList.size() && legendNameList.size() == dataList.size(); yAxisIndex++) {
+            String legendName = legendNameList.get(yAxisIndex);
+            List<Object> rowList = dataList.get(yAxisIndex);
+            //璇ョ粍鏁版嵁涓嶅瓨鍦ㄦ垨璇ョ粍鏁版嵁鎬绘暟涓嶇瓑浜巟杞存暟鎹暟閲�
+            if (rowList == null || rowList.size() != xAxisNameList.size()) {
+                continue;
+            }
+            for (int xAxisIndex = 0; xAxisIndex < rowList.size(); xAxisIndex++) {
+                String value = rowList.get(xAxisIndex).toString();
+                dataset.setValue(Double.parseDouble(value), legendName, xAxisNameList.get(xAxisIndex));
+            }
+        }
+        return dataset;
+    }
+ 
+    /**
+     * 璁剧疆鏌辩姸鍥炬覆鏌�
+     *
+     * @param plot
+     * @param isShowDataLabels 鏄剧ず鏁版嵁鍊兼爣璁�
+     */
+    public static void setBarRenderer(CategoryPlot plot, boolean isShowDataLabels) {
+        plot.setNoDataMessage(NO_DATA_MSG);
+        plot.setInsets(new RectangleInsets(10, 10, 5, 10));
+        BarRenderer renderer = (BarRenderer) plot.getRenderer();
+        // 璁剧疆鏌卞瓙鏈�澶у搴�
+        renderer.setMaximumBarWidth(0.175);
+        //璁剧疆鍥捐〃鑳屾櫙棰滆壊(閫忔槑)
+        plot.setBackgroundPaint(null);
+        //鏄剧ず鏁版嵁鍊兼爣璁�
+        if (isShowDataLabels) {
+            renderer.setDefaultItemLabelsVisible(true);
+        }
+        renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());
+        //娉ㄦ剰锛氭鍙ュ緢鍏抽敭锛岃嫢鏃犳鍙ワ紝閭f暟瀛楃殑鏄剧ず浼氳瑕嗙洊锛岀粰浜烘暟瀛楁病鏈夋樉绀哄嚭鏉ョ殑闂
+        renderer.setDefaultPositiveItemLabelPosition(new ItemLabelPosition(
+                ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER));
+ 
+        setXAixs(plot);
+        setYAixs(plot);
+    }
+ 
+    /**
+     * 璁剧疆鎶樼嚎鍥炬牱寮�
+     *
+     * @param plot
+     * @param isShowDataLabels 鏄惁鏄剧ず鏁版嵁鏍囩
+     * @param isShapesVisible  鏄惁鏄剧ず鏁版嵁鐐�
+     */
+    public static void setLineRender(CategoryPlot plot, boolean isShowDataLabels, boolean isShapesVisible) {
+        plot.setNoDataMessage(NO_DATA_MSG);
+        plot.setInsets(new RectangleInsets(10, 10, 0, 10), false);
+        LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer();
+        //璁剧疆鍥捐〃鑳屾櫙棰滆壊(閫忔槑)
+        plot.setBackgroundPaint(null);
+        renderer.setDefaultStroke(new BasicStroke(1.5F));
+        //鏄剧ず鏁版嵁鏍囩
+        if (isShowDataLabels) {
+            renderer.setDefaultItemLabelsVisible(true);
+            renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator(StandardCategoryItemLabelGenerator.DEFAULT_LABEL_FORMAT_STRING,
+                    NumberFormat.getInstance()));
+            // 浣嶇疆
+            renderer.setDefaultPositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE1, TextAnchor.BOTTOM_CENTER));
+        }
+        // 鏁版嵁鐐圭粯鍒跺舰鐘�
+        renderer.setDefaultShapesVisible(isShapesVisible);
+        setXAixs(plot);
+        setYAixs(plot);
+ 
+    }
+ 
+    /**
+     * 璁剧疆鏁g偣鍥炬牱寮�
+     *
+     * @param plot
+     */
+    public static void setScatterRender(XYPlot plot) {
+        plot.setNoDataMessage(NO_DATA_MSG);
+        plot.setInsets(new RectangleInsets(10, 10, 0, 10), false);
+        //璁剧疆鍥捐〃鑳屾櫙棰滆壊(閫忔槑)
+        plot.setBackgroundPaint(null);
+        setXAixs(plot);
+        setYAixs(plot);
+    }
+ 
+    /**
+     * 璁剧疆绫诲埆鍥捐〃(CategoryPlot) X鍧愭爣杞寸嚎鏉¢鑹插拰鏍峰紡
+     *
+     * @param plot
+     */
+    public static void setXAixs(CategoryPlot plot) {
+        Color lineColor = new Color(31, 121, 170);
+        // X鍧愭爣杞撮鑹�
+        plot.getDomainAxis().setAxisLinePaint(lineColor);
+        // X鍧愭爣杞存爣璁皘绔栫嚎棰滆壊
+        plot.getDomainAxis().setTickMarkPaint(lineColor);
+ 
+    }
+ 
+    /**
+     * 璁剧疆鍥捐〃(XYPlot) X鍧愭爣杞寸嚎鏉¢鑹插拰鏍峰紡
+     *
+     * @param plot
+     */
+    public static void setXAixs(XYPlot plot) {
+        Color lineColor = new Color(31, 121, 170);
+        // X鍧愭爣杞撮鑹�
+        plot.getDomainAxis().setAxisLinePaint(lineColor);
+        // X鍧愭爣杞存爣璁皘绔栫嚎棰滆壊
+        plot.getDomainAxis().setTickMarkPaint(lineColor);
+        // x杞寸綉鏍肩嚎鏉�
+        plot.setDomainGridlinePaint(new Color(192, 192, 192));
+    }
+ 
+    /**
+     * 璁剧疆绫诲埆鍥捐〃(CategoryPlot) Y鍧愭爣杞寸嚎鏉¢鑹插拰鏍峰紡 鍚屾椂闃叉鏁版嵁鏃犳硶鏄剧ず
+     *
+     * @param plot
+     */
+    public static void setYAixs(CategoryPlot plot) {
+        Color lineColor = new Color(192, 208, 224);
+        ValueAxis axis = plot.getRangeAxis();
+        // Y鍧愭爣杞撮鑹�
+        axis.setAxisLinePaint(lineColor);
+        // Y鍧愭爣杞存爣璁皘绔栫嚎棰滆壊
+        axis.setTickMarkPaint(lineColor);
+        // 闅愯棌Y鍒诲害
+        axis.setAxisLineVisible(false);
+        axis.setTickMarksVisible(false);
+        // Y杞寸綉鏍肩嚎鏉�
+        plot.setRangeGridlinePaint(new Color(192, 192, 192));
+        plot.setRangeGridlineStroke(new BasicStroke(1));
+        // 璁剧疆椤堕儴Y鍧愭爣杞撮棿璺�,闃叉鏁版嵁鏃犳硶鏄剧ず
+        plot.getRangeAxis().setUpperMargin(0.1);
+        // 璁剧疆搴曢儴Y鍧愭爣杞撮棿璺�
+        plot.getRangeAxis().setLowerMargin(0.1);
+ 
+    }
+ 
+    /**
+     * 璁剧疆鍥捐〃(XYPlot) Y鍧愭爣杞寸嚎鏉¢鑹插拰鏍峰紡 鍚屾椂闃叉鏁版嵁鏃犳硶鏄剧ず
+     *
+     * @param plot
+     */
+    public static void setYAixs(XYPlot plot) {
+        Color lineColor = new Color(192, 208, 224);
+        ValueAxis axis = plot.getRangeAxis();
+        // Y鍧愭爣杞撮鑹�
+        axis.setAxisLinePaint(lineColor);
+        // Y鍧愭爣杞存爣璁皘绔栫嚎棰滆壊
+        axis.setTickMarkPaint(lineColor);
+        // 闅愯棌Y鍒诲害
+        axis.setAxisLineVisible(false);
+        axis.setTickMarksVisible(false);
+        // Y杞寸綉鏍肩嚎鏉�
+        plot.setRangeGridlinePaint(new Color(192, 192, 192));
+        // 璁剧疆椤堕儴Y鍧愭爣杞撮棿璺�,闃叉鏁版嵁鏃犳硶鏄剧ず
+        plot.getRangeAxis().setUpperMargin(0.1);
+        // 璁剧疆搴曢儴Y鍧愭爣杞撮棿璺�
+        plot.getRangeAxis().setLowerMargin(0.1);
+    }
+ 
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/service/PartWorkingHourExportService.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/service/PartWorkingHourExportService.java
new file mode 100644
index 0000000..00ecc1e
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/service/PartWorkingHourExportService.java
@@ -0,0 +1,378 @@
+package com.qianwen.smartman.modules.workinghour.service;
+
+import java.awt.Color;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.text.NumberFormat;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType;
+import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
+import org.apache.poi.xssf.usermodel.XSSFDrawing;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.ChartUtils;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.StandardChartTheme;
+import org.jfree.chart.block.BlockBorder;
+import org.jfree.chart.labels.AbstractCategoryItemLabelGenerator;
+import org.jfree.chart.labels.CategoryItemLabelGenerator;
+import org.jfree.chart.labels.ItemLabelAnchor;
+import org.jfree.chart.labels.ItemLabelPosition;
+import org.jfree.chart.plot.CategoryPlot;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.renderer.category.StackedBarRenderer;
+import org.jfree.chart.ui.RectangleEdge;
+import org.jfree.chart.ui.RectangleInsets;
+import org.jfree.chart.ui.TextAnchor;
+import org.jfree.data.category.CategoryDataset;
+import org.jfree.data.category.DefaultCategoryDataset;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.qianwen.core.excel.util.ExcelUtil;
+import com.qianwen.core.mp.base.BaseServiceImpl;
+import com.qianwen.core.oss.model.BladeFile;
+import com.qianwen.core.tool.utils.DateUtil;
+import com.qianwen.smartman.common.enums.DefaultWcsEnum;
+import com.qianwen.smartman.common.utils.DurationUtil;
+import com.qianwen.smartman.modules.resource.builder.oss.OssBuilder;
+import com.qianwen.smartman.modules.smis.entity.Workstation;
+import com.qianwen.smartman.modules.smis.mapper.WorkstationMapper;
+import com.qianwen.smartman.modules.workinghour.entity.PartWorkingHour;
+import com.qianwen.smartman.modules.workinghour.entity.PartWorkingProcess;
+import com.qianwen.smartman.modules.workinghour.excel.PartWorkingHourExcel;
+import com.qianwen.smartman.modules.workinghour.mapper.PartWorkingHourMapper;
+import com.qianwen.smartman.modules.workinghour.mapper.PartWorkingProcessMapper;
+
+import cn.hutool.core.date.LocalDateTimeUtil;
+
+@Service
+public class PartWorkingHourExportService extends BaseServiceImpl<PartWorkingHourMapper, PartWorkingHour> {
+
+	@Autowired
+	private PartWorkingHourMapper partWorkingHourMapper;
+	@Autowired
+	private WorkstationMapper workstationMapper;
+	@Autowired
+    private PartWorkingProcessMapper partWorkingProcessMapper;
+	@Autowired
+	private OssBuilder ossBuilder;
+
+	/**
+	 * 瀵煎嚭涓�鏉℃暟鎹�
+	 * 
+	 * @param id
+	 * @return
+	 * @throws IOException
+	 */
+	@Transactional(readOnly = true)
+	public BladeFile export(long id) throws Exception {
+		// QueryWrapper<PartWorkingProcess> wrapper = new QueryWrapper<>();
+		// wrapper.lambda().eq(PartWorkingProcess::getWorkinghourId, id);
+
+		// xx宸ヤ欢鍦▁鏈哄簥
+		PartWorkingHour partWorkingHour = partWorkingHourMapper.selectById(id);
+		Workstation ws = workstationMapper.selectById(partWorkingHour.getWorkstationId());
+		String fileName = String.format("闆朵欢%s鐨勫伐鏃舵暟鎹�-%s.xlsx", partWorkingHour.getPartNo(), DateUtil.time());
+
+		PartWorkingHourExcel excelObj = new PartWorkingHourExcel();
+		excelObj.setPartNo(partWorkingHour.getPartNo());
+		excelObj.setAmount(partWorkingHour.getAmount());
+
+		LocalDateTime start = LocalDateTime.now();
+		LocalDateTime end;
+		Duration duration;
+		if (partWorkingHour.getClampingSecs() != null) {
+			end = start.plusSeconds(partWorkingHour.getClampingSecs());
+			duration = Duration.between(start, end);
+			excelObj.setClampingSecs(DurationUtil.toChineseDuration(duration));
+		}
+		final String format = "yyyy-MM-dd:hh:mm:ss";
+		if (partWorkingHour.getEndTime() != null) {
+			excelObj.setEndTime(LocalDateTimeUtil.format(partWorkingHour.getEndTime(), format));
+		}
+
+		if (partWorkingHour.getFirstMeasureSecs() != null) {
+			end = start.plusSeconds(partWorkingHour.getFirstMeasureSecs());
+			duration = Duration.between(start, end);
+			excelObj.setFirstMeasureSecs(DurationUtil.toChineseDuration(duration));
+		}
+
+		if (partWorkingHour.getFirstWorkingSecs() != null) {
+			end = start.plusSeconds(partWorkingHour.getFirstWorkingSecs());
+			duration = Duration.between(start, end);
+			excelObj.setFirstWorkingSecs(DurationUtil.toChineseDuration(duration));
+		}
+
+		if (partWorkingHour.getLastRemoveSecs() != null) {
+			end = start.plusSeconds(partWorkingHour.getLastRemoveSecs());
+			duration = Duration.between(start, end);
+			excelObj.setLastRemoveSecs(DurationUtil.toChineseDuration(duration));
+		}
+
+		if (partWorkingHour.getOccupancySecs() != null) {
+			end = start.plusSeconds(partWorkingHour.getOccupancySecs());
+			duration = Duration.between(start, end);
+			excelObj.setOccupancySecs(DurationUtil.toChineseDuration(duration));
+		}
+
+		excelObj.setPartNo(partWorkingHour.getPartNo());
+
+		if (partWorkingHour.getPrepareSecs() != null) {
+			end = start.plusSeconds(partWorkingHour.getPrepareSecs());
+			duration = Duration.between(start, end);
+			excelObj.setPrepareSecs(DurationUtil.toChineseDuration(duration));
+		}
+
+		if (partWorkingHour.getProcessingSecs() != null) {
+			end = start.plusSeconds(partWorkingHour.getProcessingSecs());
+			duration = Duration.between(start, end);
+			excelObj.setProcessingSecs(DurationUtil.toChineseDuration(duration));
+		}
+
+		excelObj.setProcessNo(partWorkingHour.getProcessNo());
+
+		if (partWorkingHour.getSingleProcessSecs() != null) {
+			end = start.plusSeconds(partWorkingHour.getSingleProcessSecs());
+			duration = Duration.between(start, end);
+			excelObj.setSingleProcessSecs(DurationUtil.toChineseDuration(duration));
+		}
+
+		excelObj.setStartTime(LocalDateTimeUtil.format(partWorkingHour.getStartTime(), format));
+
+		excelObj.setWorkstationName(ws.getName());
+
+		excelObj.setVersion(partWorkingHour.getVersion());
+
+		MultipartFile multipartFile = ExcelUtil.exportToMultipartFile(fileName, "闆朵欢宸ユ椂", Arrays.asList(excelObj),
+				PartWorkingHourExcel.class);
+
+		MultipartFile multipartFile2 = writeChart(id,multipartFile);
+
+		BladeFile bladeFile = this.ossBuilder.tempTemplate().putFile(multipartFile2.getOriginalFilename(),
+				multipartFile2);
+		return bladeFile;
+	}
+
+	/**
+	 * 鍒涘缓鍥捐〃
+	 * @param workinghourId
+	 * @param multipartFile
+	 * @return
+	 * @throws Exception
+	 */
+	MultipartFile writeChart(long workinghourId,MultipartFile multipartFile) throws Exception {
+		XSSFWorkbook workbook = new XSSFWorkbook(multipartFile.getInputStream());
+
+		byte[] chartBytes = barChart(workinghourId);
+		addPicture(workbook, chartBytes);
+
+		DiskFileItemFactory factory = new DiskFileItemFactory();
+		factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
+
+		FileItem fileItem = factory.createItem("excel", multipartFile.getContentType(), true,
+				multipartFile.getOriginalFilename());
+
+		workbook.write(fileItem.getOutputStream());
+		workbook.close();
+
+		return new CommonsMultipartFile(fileItem);
+
+	}
+
+	public static void addPicture(XSSFWorkbook wb, byte[] bytes) {
+		XSSFSheet sheet = wb.getSheetAt(0);
+		// 鐢诲浘鐨勯《绾х鐞嗗櫒锛屼竴涓猻heet鍙兘鑾峰彇涓�涓紙涓�瀹氳娉ㄦ剰杩欑偣锛�
+		// HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
+		XSSFDrawing patriarch = sheet.createDrawingPatriarch();
+		// 璁剧疆鍥剧墖浣嶇疆
+		// 鍏釜鍙傛暟, 鍓嶅洓涓〃绀哄浘鐗囩璧峰鍗曞厓鏍煎拰缁撴潫鍗曞厓鏍艰竟缂樼殑浣嶇疆锛�
+		// 鍚庡洓涓〃绀鸿捣濮嬪拰缁撴潫鍗曞厓鏍肩殑浣嶇疆, 濡備笅琛ㄧず浠庣2鍒楀埌绗�12鍒�, 浠庣1琛屽埌绗�15琛�,闇�瑕佹敞鎰廵xcel璧峰浣嶇疆鏄�0
+		// {0,0,0,0,2,1,12,15}琛ㄧず浠庣2鍒楀埌绗�12鍒楋紝浠庣1琛屽埌绗�15琛岋紝鍗曞厓鏍煎唴閮ㄧ殑杈硅窛閮芥槸0
+		// {0,0,0,0,1,4,20,5}琛ㄧず浠庣2鍒楀埌绗�12鍒楋紝浠庣1琛屽埌绗�15琛岋紝鍗曞厓鏍煎唴閮ㄧ殑杈硅窛閮芥槸0
+		// HSSFClientAnchor anchor = new HSSFClientAnchor(anchors[0], anchors[1],
+		// anchors[2], anchors[3], (short) anchors[4], anchors[5], (short) anchors[6],
+		// anchors[7]);
+
+		XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 0, 3, 30, 10); // 1鍒�-30鍒楋紱3琛�-10琛�
+		anchor.setAnchorType(AnchorType.DONT_MOVE_AND_RESIZE);
+		// 鎻掑叆鍥剧墖
+		int pictureIndex = wb.addPicture(bytes, XSSFWorkbook.PICTURE_TYPE_JPEG);
+		// XSSFWorkbook.PICTURE_TYPE_JPEG
+		patriarch.createPicture(anchor, pictureIndex);
+	}
+
+	public byte[] barChart(long workinghourId) throws Exception {
+		
+		// 璁剧疆鏌卞瓙鏄剧ず瀵瑰簲鐨勬暟鍊�
+
+		QueryWrapper<PartWorkingProcess> wrapper = new QueryWrapper<>();
+    	wrapper.lambda().eq(PartWorkingProcess::getWorkinghourId, workinghourId).orderByAsc(PartWorkingProcess::getStartTime);
+    	List<PartWorkingProcess> processList = partWorkingProcessMapper.selectList(wrapper);
+    	
+    	// 鏀寔鏍囩鏄剧ず鐨勬墍鏈夊垪鏁版嵁		
+    	List<List<Object>> dataList = new ArrayList<>();
+    	
+    	Duration duration;
+    	PartWorkingProcess process;
+    	for(int i=0;i<processList.size();i++) {
+    		//dataList.add(new ArrayList<>(Arrays.asList(133)));
+    		process = processList.get(i);
+    		duration = Duration.between(process.getStartTime(), process.getEndTime());
+    		dataList.add(Arrays.asList(duration.getSeconds()));
+    		
+    		//dataTable.add(new ArrayList<>(Arrays.asList(process.getProgName(), duration.getSeconds(), process.getDeviceStatus())));
+    	}
+    	
+    	JFreeChart chart = createStackedBarChart(workinghourId,"鍔犲伐璁板綍", dataList,processList,
+				JFreeChartUtil.createChartTheme("瀹嬩綋"), "绉�", "");
+    	StackedBarRenderer renderer = new StackedBarRenderer();
+		CategoryPlot plot = chart.getCategoryPlot();
+		plot.setOutlineVisible(true);
+		
+		
+		//dataTable.add(new ArrayList<>(Arrays.asList("YZL4-1100-01-50-A-2-2", 242, "杩愯")));
+
+		renderer.setDefaultItemLabelsVisible(true);
+		renderer.setDefaultItemLabelGenerator(new MyCategoryItemLabelGenerator(processList));
+		
+		renderer.setMaximumBarWidth(0.3);
+
+		// 鏌卞瓙棰滆壊,鏈夊嚑娈靛氨set鍑犱釜
+		Color color;
+		String colorStr;
+		DefaultWcsEnum wcsEnum;
+		for(int i=0;i<processList.size();i++) {
+			process = processList.get(i);
+			//if(dataTable.get(i))
+			//color = 
+			wcsEnum = DefaultWcsEnum.of(process.getDeviceStatus());
+			colorStr = StringUtils.removeStart(wcsEnum.getColor(), '#');
+			color  = new Color(Integer.parseInt(colorStr, 16));
+			renderer.setSeriesPaint(i, color);
+		}
+		//renderer.setSeriesPaint(0, Color.green);
+		//renderer.setSeriesPaint(1, Color.yellow);
+
+		ItemLabelPosition posi = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.HALF_ASCENT_CENTER);
+		//renderer.setDefaultNegativeItemLabelPosition(posi);
+		renderer.setDefaultPositiveItemLabelPosition(posi);
+
+		int offset = 10;
+		renderer.setItemLabelInsets(new RectangleInsets(0, offset, offset, offset));
+		plot.setRenderer(renderer);
+
+		java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
+
+		ChartUtils.writeChartAsJPEG(bos, 1.0f, chart, 4096, 400, null);
+
+		return bos.toByteArray();
+	}
+
+	/**
+	 * 鍒涘缓鍫嗗彔鏌辩姸鍥�
+	 * @param workinghourId
+	 * @param chartTitle
+	 * @param legendNameList
+	 * @param xAxisNameList
+	 * @param dataList
+	 * @param theme
+	 * @param yAxisTitle
+	 * @param xAxisTitle
+	 * @return
+	 * @throws Exception
+	 */
+	JFreeChart createStackedBarChart(long workinghourId,String chartTitle, List<List<Object>> dataList,List<PartWorkingProcess> processList,
+			 StandardChartTheme theme, String yAxisTitle, String xAxisTitle)
+			throws Exception {
+		
+		
+		// 璁剧疆涓婚锛岄槻姝腑鏂囦贡鐮�
+		theme = theme == null ? JFreeChartUtil.createChartTheme("") : theme;
+		ChartFactory.setChartTheme(theme);
+		
+		boolean showLegend =false;
+		//List<String> pnamelist = processList.stream().map(p -> p.getProgName()).collect(Collectors.toList());
+		
+		//DefaultCategoryDataset dataset = JFreeChartUtil.createDefaultCategoryDataset(pnamelist, Arrays.asList("xname"), dataList);
+		DefaultCategoryDataset dataset = createDataSet(processList);
+		JFreeChart chart = ChartFactory.createStackedBarChart(chartTitle, xAxisTitle, yAxisTitle,
+				dataset,
+				PlotOrientation.HORIZONTAL, showLegend, true, false);
+		// 璁剧疆鎶楅敮榻匡紝闃叉瀛椾綋鏄剧ず涓嶆竻妤�
+		chart.setTextAntiAlias(false);
+		// 瀵规煴瀛愯繘琛屾覆鏌�
+		JFreeChartUtil.setBarRenderer(chart.getCategoryPlot(), true);
+		
+		//showLegend=false鎯呭喌涓嬶紝涓嬪垪浠g爜浼氬紩璧種PE
+		// 璁剧疆鏍囨敞鏃犺竟妗�
+		//chart.getLegend().setFrame(new BlockBorder(Color.WHITE));
+		// 鏍囨敞浣嶄簬涓婁晶
+		//chart.getLegend().setPosition(RectangleEdge.TOP);
+
+		return chart;
+	}
+	
+	DefaultCategoryDataset createDataSet(List<PartWorkingProcess> processList){
+		DefaultCategoryDataset dataset = new DefaultCategoryDataset();
+		PartWorkingProcess p;
+		 for (int xAxisIndex = 0; xAxisIndex < processList.size(); xAxisIndex++) {
+			 p = processList.get(xAxisIndex);
+             //String value = rowList.get(xAxisIndex).toString();
+			 String value =p.getStartTime().toString();
+			 Duration duration = Duration.between(p.getStartTime(), p.getEndTime());
+			 value = duration.getSeconds()+"";
+             dataset.setValue(Double.parseDouble(value), xAxisIndex+"", "绋嬪簭鏃舵");
+         }
+		 
+		 return dataset;
+	}
+}
+
+//鑷畾涔夋爣绛剧敓鎴�
+class MyCategoryItemLabelGenerator extends AbstractCategoryItemLabelGenerator implements CategoryItemLabelGenerator {
+	// private final Integer category;
+	private List<PartWorkingProcess> dataTable;
+	
+	public MyCategoryItemLabelGenerator(List<PartWorkingProcess> dataTable) {
+		super("", NumberFormat.getInstance());
+		this.dataTable = dataTable;
+	}
+
+	@Override
+	public String generateLabel(CategoryDataset dataset, int row, int column) {
+		//Number val = dataset.getValue(row, column);
+
+		PartWorkingProcess dataRow = this.dataTable.get(row);
+		// dataset.
+		/*
+		ALARM(1, "鎶ヨ"),
+	    RUNNING(2, "杩愯"),
+	    STANDBY(3, "寰呮満"),
+	    OFFLINE(4, "绂荤嚎"),
+	    DEBUGGING(5, "璋冭瘯");
+	    */
+		
+		//DefaultWcsEnum wcsEnum = DefaultWcsEnum.of(dataRow.getDeviceStatus());
+		//return dataRow.getProgName() + ",:" + val + "," + wcsEnum.getName();
+		Duration duration = Duration.between(dataRow.getStartTime(), dataRow.getEndTime());
+		return dataRow.getProgName() + "," + DurationUtil.toChineseDuration(duration);
+	}
+
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/service/PartWorkingHourService.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/service/PartWorkingHourService.java
new file mode 100644
index 0000000..73ed987
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/service/PartWorkingHourService.java
@@ -0,0 +1,148 @@
+package com.qianwen.smartman.modules.workinghour.service;
+
+import java.time.Duration;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.qianwen.core.excel.util.ExcelUtil;
+import com.qianwen.core.mp.base.BaseServiceImpl;
+import com.qianwen.core.oss.model.BladeFile;
+import com.qianwen.core.tool.utils.DateUtil;
+import com.qianwen.smartman.common.enums.DefaultWcsEnum;
+import com.qianwen.smartman.common.utils.DurationUtil;
+import com.qianwen.smartman.modules.resource.builder.oss.OssBuilder;
+import com.qianwen.smartman.modules.smis.entity.Workstation;
+import com.qianwen.smartman.modules.smis.mapper.WorkstationMapper;
+import com.qianwen.smartman.modules.workinghour.entity.PartWorkingHour;
+import com.qianwen.smartman.modules.workinghour.entity.PartWorkingProcess;
+import com.qianwen.smartman.modules.workinghour.excel.PartWorkingHourExcel;
+import com.qianwen.smartman.modules.workinghour.excel.PartWorkingProcessExcel;
+import com.qianwen.smartman.modules.workinghour.mapper.PartWorkingHourMapper;
+import com.qianwen.smartman.modules.workinghour.vo.PartWorkingHourVO;
+
+import cn.hutool.core.date.LocalDateTimeUtil;
+
+@Service
+public class PartWorkingHourService extends BaseServiceImpl<PartWorkingHourMapper, PartWorkingHour>{
+
+    @Autowired
+    private PartWorkingHourMapper partWorkingHourMapper;
+    @Autowired
+    private WorkstationMapper workstationMapper;
+    @Autowired
+    private OssBuilder ossBuilder;
+
+    @Transactional(readOnly=true)
+    public IPage<PartWorkingHourVO> listPage(IPage<PartWorkingHourVO> workstationVOIPage, String partNo, String workstationName, LocalDate startDate, LocalDate endDate) {
+        
+        List<PartWorkingHourVO> workstationVOS = this.partWorkingHourMapper.listPage(workstationVOIPage, partNo, workstationName, startDate, endDate);
+        
+        return workstationVOIPage.setRecords(workstationVOS);
+    }
+
+
+    @Transactional(readOnly=true)
+	public List<PartWorkingHourVO> listVOByIds(List<Long> ids) {
+    	return partWorkingHourMapper.listVOByIds(ids);
+	}
+
+    /**
+     * 瀵煎嚭涓�鏉℃暟鎹�
+     * @param id
+     * @return
+     */
+    @Transactional(readOnly=true)
+   	public BladeFile export(long id) {
+    	//QueryWrapper<PartWorkingProcess> wrapper = new QueryWrapper<>();
+    	//wrapper.lambda().eq(PartWorkingProcess::getWorkinghourId, id);
+    	
+    	//xx宸ヤ欢鍦▁鏈哄簥
+    	PartWorkingHour partWorkingHour = partWorkingHourMapper.selectById(id);
+    	Workstation ws = workstationMapper.selectById(partWorkingHour.getWorkstationId());
+    	String fileName = String.format("闆朵欢%s鐨勫伐鏃舵暟鎹�-%s.xlsx", partWorkingHour.getPartNo(), DateUtil.time());
+    	
+    	PartWorkingHourExcel excelObj = new PartWorkingHourExcel();
+    	excelObj.setPartNo(partWorkingHour.getPartNo());
+    	excelObj.setAmount(partWorkingHour.getAmount());
+    	
+    	LocalDateTime start = LocalDateTime.now();
+    	LocalDateTime end;
+    	Duration duration;
+    	if(partWorkingHour.getClampingSecs() !=null) {
+	    	end = start.plusSeconds(partWorkingHour.getClampingSecs());
+	    	duration = Duration.between(start, end);
+	    	excelObj.setClampingSecs(DurationUtil.toChineseDuration(duration));
+    	}
+    	final String format =  "yyyy-MM-dd:hh:mm:ss";
+    	if(partWorkingHour.getEndTime() !=null) {
+    		excelObj.setEndTime(LocalDateTimeUtil.format(partWorkingHour.getEndTime(),format));
+    	}
+    	
+    	if(partWorkingHour.getFirstMeasureSecs() !=null) {
+	    	end = start.plusSeconds(partWorkingHour.getFirstMeasureSecs());
+	    	duration = Duration.between(start, end);
+	    	excelObj.setFirstMeasureSecs(DurationUtil.toChineseDuration(duration));
+    	}
+    	
+    	if(partWorkingHour.getFirstWorkingSecs() !=null) {
+	    	end = start.plusSeconds(partWorkingHour.getFirstWorkingSecs());
+	    	duration = Duration.between(start, end);
+	    	excelObj.setFirstWorkingSecs(DurationUtil.toChineseDuration(duration));
+    	}
+    	
+    	if(partWorkingHour.getLastRemoveSecs() !=null) {
+	    	end = start.plusSeconds(partWorkingHour.getLastRemoveSecs());
+	    	duration = Duration.between(start, end);
+	    	excelObj.setLastRemoveSecs(DurationUtil.toChineseDuration(duration));
+    	}
+    	
+    	if(partWorkingHour.getOccupancySecs() !=null) {
+	    	end = start.plusSeconds(partWorkingHour.getOccupancySecs());
+	    	duration = Duration.between(start, end);
+	    	excelObj.setOccupancySecs(DurationUtil.toChineseDuration(duration));
+    	}
+    	
+    	excelObj.setPartNo(partWorkingHour.getPartNo());
+    	
+    	if(partWorkingHour.getPrepareSecs() !=null) {
+	    	end = start.plusSeconds(partWorkingHour.getPrepareSecs());
+	    	duration = Duration.between(start, end);
+	    	excelObj.setPrepareSecs(DurationUtil.toChineseDuration(duration));
+    	}
+    	
+    	if(partWorkingHour.getProcessingSecs() !=null) {
+	    	end = start.plusSeconds(partWorkingHour.getProcessingSecs());
+	    	duration = Duration.between(start, end);
+	    	excelObj.setProcessingSecs(DurationUtil.toChineseDuration(duration));
+    	}
+    	
+    	excelObj.setProcessNo(partWorkingHour.getProcessNo());
+    	
+    	if(partWorkingHour.getSingleProcessSecs() !=null) {
+	    	end = start.plusSeconds(partWorkingHour.getSingleProcessSecs());
+	    	duration = Duration.between(start, end);
+	    	excelObj.setSingleProcessSecs(DurationUtil.toChineseDuration(duration));
+    	}
+    	
+    	excelObj.setStartTime(LocalDateTimeUtil.format(partWorkingHour.getStartTime(),format));
+    	
+    	
+    	excelObj.setWorkstationName(ws.getName());
+    	
+    	excelObj.setVersion(partWorkingHour.getVersion());
+    	
+        MultipartFile multipartFile = ExcelUtil.exportToMultipartFile(fileName, "闆朵欢宸ユ椂", Arrays.asList(excelObj), PartWorkingHourExcel.class);
+        BladeFile bladeFile = this.ossBuilder.tempTemplate().putFile(multipartFile.getOriginalFilename(), multipartFile);
+        return bladeFile;
+    }
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/service/PartWorkingProcessService.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/service/PartWorkingProcessService.java
new file mode 100644
index 0000000..5f5fd92
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/service/PartWorkingProcessService.java
@@ -0,0 +1,84 @@
+package com.qianwen.smartman.modules.workinghour.service;
+
+import java.time.Duration;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.commons.beanutils.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.qianwen.core.excel.util.ExcelUtil;
+import com.qianwen.core.oss.model.BladeFile;
+import com.qianwen.core.tool.utils.DateUtil;
+import com.qianwen.smartman.common.enums.DefaultWcsEnum;
+import com.qianwen.smartman.common.utils.DurationUtil;
+import com.qianwen.smartman.modules.resource.builder.oss.OssBuilder;
+import com.qianwen.smartman.modules.smis.entity.Workstation;
+import com.qianwen.smartman.modules.smis.excel.WorkstationExcel;
+import com.qianwen.smartman.modules.smis.mapper.WorkstationMapper;
+import com.qianwen.smartman.modules.workinghour.convert.PartWorkingProcessConvert;
+import com.qianwen.smartman.modules.workinghour.entity.PartWorkingHour;
+import com.qianwen.smartman.modules.workinghour.entity.PartWorkingProcess;
+import com.qianwen.smartman.modules.workinghour.excel.PartWorkingProcessExcel;
+import com.qianwen.smartman.modules.workinghour.mapper.PartWorkingHourMapper;
+import com.qianwen.smartman.modules.workinghour.mapper.PartWorkingProcessMapper;
+import com.qianwen.smartman.modules.workinghour.vo.PartWorkingProcessVO;
+
+@Service
+public class PartWorkingProcessService{
+
+    @Autowired
+    private PartWorkingProcessMapper partWorkingProcessMapper;
+    @Autowired
+    private WorkstationMapper workstationMapper;
+    @Autowired
+    private PartWorkingHourMapper partWorkingHourMapper;
+    @Autowired
+    private OssBuilder ossBuilder;
+
+
+    @Transactional(readOnly=true)
+	public List<PartWorkingProcessVO> listByWorkinghourId(Long workinghourId) {
+    	QueryWrapper<PartWorkingProcess> wrapper = new QueryWrapper<>();
+    	wrapper.lambda().eq(PartWorkingProcess::getWorkinghourId, workinghourId).orderByAsc(PartWorkingProcess::getStartTime);
+    	
+    	return PartWorkingProcessConvert.INSTANCE.convert(partWorkingProcessMapper.selectList(wrapper));
+	}
+
+    /**
+     * 鍔犲伐杩囩▼鏁版嵁瀵煎嚭
+     * @param id
+     * @return
+     */
+    @Transactional(readOnly=true)
+	public BladeFile export(long workinghourId) {
+    	QueryWrapper<PartWorkingProcess> wrapper = new QueryWrapper<>();
+    	wrapper.lambda().eq(PartWorkingProcess::getWorkinghourId, workinghourId).orderByAsc(PartWorkingProcess::getStartTime);
+    	List<PartWorkingProcess> data = partWorkingProcessMapper.selectList(wrapper);
+    	List<PartWorkingProcessExcel> exportList = data.stream().map(p -> {
+    		PartWorkingProcessExcel e = new PartWorkingProcessExcel();
+    		e.setProgName(p.getProgName());
+    		e.setStartTime(p.getStartTime().toString());
+    		e.setEndTime(p.getEndTime().toString());
+    		
+    		Duration duration = Duration.between(p.getStartTime(), p.getEndTime());
+    		e.setDuration(DurationUtil.toChineseDuration(duration));
+    		e.setDeviceStateName(DefaultWcsEnum.of(p.getDeviceStatus()).getName());
+    		return e;
+    	}).collect(Collectors.toList());
+    	//xx宸ヤ欢鍦▁鏈哄簥
+    	PartWorkingHour partWorkingHour = partWorkingHourMapper.selectById(workinghourId);
+    	Workstation ws = workstationMapper.selectById(partWorkingHour.getWorkstationId());
+    	String fileName = String.format("%s鐨勫姞宸ヨ褰�-%s.xlsx", ws.getName(), DateUtil.time());
+        MultipartFile multipartFile = ExcelUtil.exportToMultipartFile(fileName, "鍔犲伐璁板綍琛�", exportList, PartWorkingProcessExcel.class);
+        BladeFile bladeFile = this.ossBuilder.tempTemplate().putFile(multipartFile.getOriginalFilename(), multipartFile);
+        return bladeFile;
+	}
+    
+    
+
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/vo/PartWorkingHourQueryVO.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/vo/PartWorkingHourQueryVO.java
new file mode 100644
index 0000000..e2f16d6
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/vo/PartWorkingHourQueryVO.java
@@ -0,0 +1,50 @@
+package com.qianwen.smartman.modules.workinghour.vo;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * 闆朵欢宸ユ椂VO
+ */
+public class PartWorkingHourQueryVO {
+
+	@ApiModelProperty("闆朵欢缂栧彿")
+	private String partNo;
+	
+	@ApiModelProperty("宸ヤ綅鍚嶇О")
+	private String workstationName;
+
+	@ApiModelProperty("寮�濮嬫椂闂�")
+	private LocalDate startDate;
+	
+	@ApiModelProperty("缁撴潫鏃堕棿")
+	private LocalDate endDate;
+	public String getPartNo() {
+		return partNo;
+	}
+	public void setPartNo(String partNo) {
+		this.partNo = partNo;
+	}
+	public String getWorkstationName() {
+		return workstationName;
+	}
+	public void setWorkstationName(String workstationName) {
+		this.workstationName = workstationName;
+	}
+	public LocalDate getStartDate() {
+		return startDate;
+	}
+	public void setStartDate(LocalDate startDate) {
+		this.startDate = startDate;
+	}
+	public LocalDate getEndDate() {
+		return endDate;
+	}
+	public void setEndDate(LocalDate endDate) {
+		this.endDate = endDate;
+	}
+	
+	
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/vo/PartWorkingHourVO.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/vo/PartWorkingHourVO.java
new file mode 100644
index 0000000..627094b
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/vo/PartWorkingHourVO.java
@@ -0,0 +1,168 @@
+package com.qianwen.smartman.modules.workinghour.vo;
+
+import java.time.LocalDateTime;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * 闆朵欢宸ユ椂VO
+ */
+public class PartWorkingHourVO {
+	
+	long id;
+	/**
+	 * 闆朵欢缂栧彿
+	 */
+	@ApiModelProperty("闆朵欢缂栧彿")
+	private String partNo;
+	
+	@ApiModelProperty("宸ュ簭鍙�")
+	private String processNo;
+	
+	@ApiModelProperty("鐗堟")
+	private String version;
+	
+	@ApiModelProperty("宸ヤ綅id")
+	private long workstationId;
+	
+	@ApiModelProperty("宸ヤ綅鍚嶇О")
+	private String workstationName;
+	
+	@ApiModelProperty("寮�濮嬫椂闂�")
+	private LocalDateTime startTime;
+	
+	@ApiModelProperty("缁撴潫鏃堕棿")
+	private LocalDateTime endTime;
+	
+	@ApiModelProperty("鍗犳満鏃堕棿(绉�)")
+	private Long occupancySecs;
+	
+	@ApiModelProperty("瑁呭す璋冭瘯鏃堕棿(绉�)")
+	private Long clampingSecs;
+	
+	@ApiModelProperty("棣栦欢鍒囧墛鏃堕棿(绉�)")
+	private Long firstWorkingSecs;
+	
+	@ApiModelProperty("鏈欢鎷嗗嵏鏃堕棿(绉�)")
+	private Long lastRemoveSecs;
+	
+	@ApiModelProperty("棣栦欢璁¢噺鏃堕棿(绉�)")
+	private Long firstMeasureSecs;
+	
+	@ApiModelProperty("鍔犲伐鏃堕棿(绉�)")
+	private Long processingSecs;
+	
+	@ApiModelProperty("鍑嗗鏃堕棿(绉�)")
+	private Long prepareSecs;
+	
+	@ApiModelProperty(" 鍗曚欢宸ユ椂(绉�)")
+	private Long singleProcessSecs;
+	
+	@ApiModelProperty("鏁伴噺")
+	private Long amount;
+	
+	public long getId() {
+		return id;
+	}
+	public void setId(long id) {
+		this.id = id;
+	}
+	public String getPartNo() {
+		return partNo;
+	}
+	public void setPartNo(String partNo) {
+		this.partNo = partNo;
+	}
+	public String getProcessNo() {
+		return processNo;
+	}
+	public void setProcessNo(String processNo) {
+		this.processNo = processNo;
+	}
+	public String getVersion() {
+		return version;
+	}
+	public void setVersion(String version) {
+		this.version = version;
+	}
+	public long getWorkstationId() {
+		return workstationId;
+	}
+	public void setWorkstationId(long workstationId) {
+		this.workstationId = workstationId;
+	}
+	public LocalDateTime getStartTime() {
+		return startTime;
+	}
+	public void setStartTime(LocalDateTime startTime) {
+		this.startTime = startTime;
+	}
+	public LocalDateTime getEndTime() {
+		return endTime;
+	}
+	public void setEndTime(LocalDateTime endTime) {
+		this.endTime = endTime;
+	}
+	public Long getOccupancySecs() {
+		return occupancySecs;
+	}
+	public void setOccupancySecs(Long occupancySecs) {
+		this.occupancySecs = occupancySecs;
+	}
+	public Long getClampingSecs() {
+		return clampingSecs;
+	}
+	public void setClampingSecs(Long clampingSecs) {
+		this.clampingSecs = clampingSecs;
+	}
+	public Long getFirstWorkingSecs() {
+		return firstWorkingSecs;
+	}
+	public void setFirstWorkingSecs(Long firstWorkingSecs) {
+		this.firstWorkingSecs = firstWorkingSecs;
+	}
+	public Long getLastRemoveSecs() {
+		return lastRemoveSecs;
+	}
+	public void setLastRemoveSecs(Long lastRemoveSecs) {
+		this.lastRemoveSecs = lastRemoveSecs;
+	}
+	public Long getFirstMeasureSecs() {
+		return firstMeasureSecs;
+	}
+	public void setFirstMeasureSecs(Long firstMeasureSecs) {
+		this.firstMeasureSecs = firstMeasureSecs;
+	}
+	public Long getPrepareSecs() {
+		return prepareSecs;
+	}
+	public void setPrepareSecs(Long prepareSecs) {
+		this.prepareSecs = prepareSecs;
+	}
+	public Long getSingleProcessSecs() {
+		return singleProcessSecs;
+	}
+	public void setSingleProcessSecs(Long singleProcessSecs) {
+		this.singleProcessSecs = singleProcessSecs;
+	}
+	public Long getAmount() {
+		return amount;
+	}
+	public void setAmount(Long amount) {
+		this.amount = amount;
+	}
+	public String getWorkstationName() {
+		return workstationName;
+	}
+	public void setWorkstationName(String workstationName) {
+		this.workstationName = workstationName;
+	}
+	public Long getProcessingSecs() {
+		return processingSecs;
+	}
+	public void setProcessingSecs(Long processingSecs) {
+		this.processingSecs = processingSecs;
+	}
+	
+	
+}
diff --git a/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/vo/PartWorkingProcessVO.java b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/vo/PartWorkingProcessVO.java
new file mode 100644
index 0000000..1955945
--- /dev/null
+++ b/smart-man-boot/src/main/java/com/qianwen/smartman/modules/workinghour/vo/PartWorkingProcessVO.java
@@ -0,0 +1,65 @@
+package com.qianwen.smartman.modules.workinghour.vo;
+
+import java.time.LocalDateTime;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * 闆朵欢宸ユ椂VO
+ */
+public class PartWorkingProcessVO {
+	
+	long id;
+
+	@ApiModelProperty("绋嬪簭鍚嶇О")
+	private String progName;
+	
+	@ApiModelProperty("宸ユ椂琛╥d")
+	private long workinghourId;
+	
+	@ApiModelProperty("寮�濮嬫椂闂�")
+	private LocalDateTime startTime;
+	
+	@ApiModelProperty("缁撴潫鏃堕棿")
+	private LocalDateTime endTime;
+	@ApiModelProperty("璁惧鐘舵��")
+	private Integer deviceStatus;
+	
+	public long getId() {
+		return id;
+	}
+	public void setId(long id) {
+		this.id = id;
+	}
+	public String getProgName() {
+		return progName;
+	}
+	public void setProgName(String progName) {
+		this.progName = progName;
+	}
+	public long getWorkinghourId() {
+		return workinghourId;
+	}
+	public void setWorkinghourId(long workinghourId) {
+		this.workinghourId = workinghourId;
+	}
+	public LocalDateTime getStartTime() {
+		return startTime;
+	}
+	public void setStartTime(LocalDateTime startTime) {
+		this.startTime = startTime;
+	}
+	public LocalDateTime getEndTime() {
+		return endTime;
+	}
+	public void setEndTime(LocalDateTime endTime) {
+		this.endTime = endTime;
+	}
+	public Integer getDeviceStatus() {
+		return deviceStatus;
+	}
+	public void setDeviceStatus(Integer deviceStatus) {
+		this.deviceStatus = deviceStatus;
+	}
+	
+}
diff --git a/smart-man-boot/src/main/resources/com/qianwen/smartman/modules/workinghour/mapper/PartWorkingHourMapper.xml b/smart-man-boot/src/main/resources/com/qianwen/smartman/modules/workinghour/mapper/PartWorkingHourMapper.xml
new file mode 100644
index 0000000..c15eb64
--- /dev/null
+++ b/smart-man-boot/src/main/resources/com/qianwen/smartman/modules/workinghour/mapper/PartWorkingHourMapper.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qianwen.smartman.modules.workinghour.mapper.PartWorkingHourMapper">
+
+
+    <select id="listPage" resultType="com.qianwen.smartman.modules.workinghour.vo.PartWorkingHourVO">
+        SELECT
+        h.id,
+        h.part_no,
+        process_no,
+    version,
+    workstation_id,
+    ws.name as workstation_name,
+    start_time,
+    end_time,
+    occupancy_secs, 	
+	clamping_secs, 	
+	first_working_secs,
+	last_remove_secs,
+    first_measure_secs,
+     processing_secs,
+    prepare_secs,
+    single_process_secs,
+        h.amount
+        FROM part_workinghour h
+        LEFT JOIN blade_workstation ws on h.workstation_id=ws.id
+       
+        <where>
+            h.is_deleted = 0
+            <if test="partNo != null">
+                and h.part_no like concat('%',#{partNo,jdbcType=VARCHAR},'%')
+            </if>
+            <if test="startDate != null">
+                and h.start_time &gt;= #{startDate}
+            </if>
+            <if test="endDate != null">
+                and h.start_time &lt; date_add(#{endDate}, INTERVAL 1 day)
+            </if>
+        </where>
+        ORDER BY h.start_time DESC 
+    </select>
+   
+   <select id="listVOByIds" resultType="com.qianwen.smartman.modules.workinghour.vo.PartWorkingHourVO">
+        SELECT
+        h.id,
+        h.part_no,
+        process_no,
+    version,
+    workstation_id,
+    ws.name as workstation_name,
+    start_time,
+    end_time,
+    occupancy_secs, 	
+	clamping_secs, 	
+	first_working_secs,
+	last_remove_secs,
+    first_measure_secs,
+     processing_secs,
+    prepare_secs,
+    single_process_secs,
+        h.amount
+        FROM part_workinghour h
+        LEFT JOIN blade_workstation ws on h.workstation_id=ws.id
+       
+         where   h.id in 
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+        
+        ORDER BY h.start_time DESC 
+    </select>
+
+</mapper>
+
diff --git "a/smart-man-boot/src/main/resources/dp/dpend-\345\270\246\350\256\241\347\256\227\350\247\204\345\210\231.json" "b/smart-man-boot/src/main/resources/dp/dpend-\345\270\246\350\256\241\347\256\227\350\247\204\345\210\231.json"
new file mode 100644
index 0000000..1577a2b
--- /dev/null
+++ "b/smart-man-boot/src/main/resources/dp/dpend-\345\270\246\350\256\241\347\256\227\350\247\204\345\210\231.json"
@@ -0,0 +1 @@
+[{"prop":"dpUnit","label":"鍗曚綅"},{"prop":"ruleContent","label":"璁$畻瑙勫垯","describe":"璁$畻瑙勫垯鏉ユ簮浜嶽瑙勫垯绠$悊-璁$畻瑙勫垯]锛岄�氳繃lua鑴氭湰缂栧啓璁$畻瑙勫垯锛屽鏁版嵁鐐圭殑鍘熷鏁版嵁杩涜璁$畻锛岀敓鎴愭柊鐨勬暟鎹偣鍙婃暟鎹偣鍊笺��","sendCode":1,"isReqOptions":true,"type":"option","options":["s7status_trans"]},{"prop":"ruleArgs","label":"璁$畻鍙傛暟","describe":"鏍规嵁璁$畻瑙勫垯锛屽~鍐欒绠楀弬鏁帮紝澶氫釜璁$畻鍙傛暟鐢ㄨ嫳鏂団�滐紝鈥濋殧寮�锛涙敞鎰�:dpValue涓洪噰闆嗗埌鐨勫�间笉闇�瑕佸~鍐欍��","sendCode":1},{"prop":"access","isRequired":true,"sendCode":1,"label":"鏉冮檺","describe":"璇诲啓鏉冮檺\\n RO(鍙)锛氬彧鍏佽璇诲彇鐐逛綅鏁版嵁銆乗\nRW(璇�/鍐�)锛氭棦鑳借鍙栨暟鎹篃鑳藉啓鍏ユ暟鎹��","default":"RO","type":"option","options":["RO","RW"]},{"prop":"pollingInterval","isRequired":true,"label":"杞闂撮殧锛坢s锛�","describe":"杞闂撮殧锛坢s锛�","default":1000},{"prop":"keepOriginalValue","isRequired":true,"sendCode":1,"label":"淇濈暀鍘熷鍊�","describe":"淇濈暀鍘熷鍊�","default":true,"type":"boolean"},{"prop":"isSave","isRequired":true,"sendCode":1,"label":"鏄惁瀛樺偍","describe":"鏄惁瀛樺偍","default":true,"type":"boolean"}]
\ No newline at end of file
diff --git a/smart-man-boot/src/main/resources/dp/dpend.json b/smart-man-boot/src/main/resources/dp/dpend.json
index 1577a2b..bb122e8 100644
--- a/smart-man-boot/src/main/resources/dp/dpend.json
+++ b/smart-man-boot/src/main/resources/dp/dpend.json
@@ -1 +1 @@
-[{"prop":"dpUnit","label":"鍗曚綅"},{"prop":"ruleContent","label":"璁$畻瑙勫垯","describe":"璁$畻瑙勫垯鏉ユ簮浜嶽瑙勫垯绠$悊-璁$畻瑙勫垯]锛岄�氳繃lua鑴氭湰缂栧啓璁$畻瑙勫垯锛屽鏁版嵁鐐圭殑鍘熷鏁版嵁杩涜璁$畻锛岀敓鎴愭柊鐨勬暟鎹偣鍙婃暟鎹偣鍊笺��","sendCode":1,"isReqOptions":true,"type":"option","options":["s7status_trans"]},{"prop":"ruleArgs","label":"璁$畻鍙傛暟","describe":"鏍规嵁璁$畻瑙勫垯锛屽~鍐欒绠楀弬鏁帮紝澶氫釜璁$畻鍙傛暟鐢ㄨ嫳鏂団�滐紝鈥濋殧寮�锛涙敞鎰�:dpValue涓洪噰闆嗗埌鐨勫�间笉闇�瑕佸~鍐欍��","sendCode":1},{"prop":"access","isRequired":true,"sendCode":1,"label":"鏉冮檺","describe":"璇诲啓鏉冮檺\\n RO(鍙)锛氬彧鍏佽璇诲彇鐐逛綅鏁版嵁銆乗\nRW(璇�/鍐�)锛氭棦鑳借鍙栨暟鎹篃鑳藉啓鍏ユ暟鎹��","default":"RO","type":"option","options":["RO","RW"]},{"prop":"pollingInterval","isRequired":true,"label":"杞闂撮殧锛坢s锛�","describe":"杞闂撮殧锛坢s锛�","default":1000},{"prop":"keepOriginalValue","isRequired":true,"sendCode":1,"label":"淇濈暀鍘熷鍊�","describe":"淇濈暀鍘熷鍊�","default":true,"type":"boolean"},{"prop":"isSave","isRequired":true,"sendCode":1,"label":"鏄惁瀛樺偍","describe":"鏄惁瀛樺偍","default":true,"type":"boolean"}]
\ No newline at end of file
+[{"prop":"dpUnit","label":"鍗曚綅"},{"prop":"access","isRequired":true,"sendCode":1,"label":"鏉冮檺","describe":"璇诲啓鏉冮檺\\n RO(鍙)锛氬彧鍏佽璇诲彇鐐逛綅鏁版嵁銆乗\nRW(璇�/鍐�)锛氭棦鑳借鍙栨暟鎹篃鑳藉啓鍏ユ暟鎹��","default":"RO","type":"option","options":["RO","RW"]},{"prop":"pollingInterval","isRequired":true,"label":"杞闂撮殧锛坢s锛�","describe":"杞闂撮殧锛坢s锛�","default":1000},{"prop":"keepOriginalValue","isRequired":true,"sendCode":1,"label":"淇濈暀鍘熷鍊�","describe":"淇濈暀鍘熷鍊�","default":true,"type":"boolean"},{"prop":"isSave","isRequired":true,"sendCode":1,"label":"鏄惁瀛樺偍","describe":"鏄惁瀛樺偍","default":true,"type":"boolean"}]
\ No newline at end of file
diff --git a/smart-man-boot/src/main/resources/sql/iotdb/iot_struct.sql b/smart-man-boot/src/main/resources/sql/iotdb/iot_struct.sql
new file mode 100644
index 0000000..7eb01b1
--- /dev/null
+++ b/smart-man-boot/src/main/resources/sql/iotdb/iot_struct.sql
@@ -0,0 +1,17 @@
+CREATE DATABASE root.f2;
+
+create device template output aligned(workstation_id INT64,value_collect INT64 encoding=TS_2DIFF,calendar_code TEXT encoding=DICTIONARY,factory_year INT32 encoding=RLE,factory_month INT32 encoding=RLE,factory_date INT32 encoding=RLE,factory_week INT32 encoding=RLE,shift_index INT32,shift_time_type INT32,is_sync BOOLEAN encoding=RLE,employee_id INT64);
+
+create device template aggregate_output aligned(workstation_id INT64,output INT64 encoding=TS_2DIFF,cur_output INT64 encoding=TS_2DIFF,pre_output INT64 encoding=TS_2DIFF,pre_time INT64 encoding=TS_2DIFF,calendar_code TEXT encoding=DICTIONARY,factory_year INT32 encoding=RLE,factory_month INT32 encoding=RLE,factory_date INT32 encoding=RLE,factory_week INT32 encoding=RLE,shift_index INT32,shift_time_type INT32,employee_id INT64);
+
+create device template aggregate_state aligned(workstation_id INT64,end_time INT64,duration_collect INT64 encoding=TS_2DIFF,calendar_code TEXT encoding=DICTIONARY,factory_year INT32 encoding=RLE,factory_month INT32 encoding=RLE,factory_date INT32 encoding=RLE,factory_week INT32 encoding=RLE,shift_index INT32 encoding=TS_2DIFF,shift_time_type INT32 encoding=TS_2DIFF,wcs INT32 encoding=TS_2DIFF,rps INT32 encoding=TS_2DIFF,is_deleted BOOLEAN encoding=RLE,is_plan INT32,employee_id INT64);
+
+create device template aggregate_state_with_feedback aligned(workstation_id INT64,end_time INT64,duration_collect INT64 encoding=TS_2DIFF,calendar_code TEXT encoding=DICTIONARY,factory_year INT32 encoding=RLE,factory_month INT32 encoding=RLE,factory_date INT32 encoding=RLE,factory_week INT32 encoding=RLE,shift_index INT32 encoding=TS_2DIFF,shift_time_type INT32 encoding=TS_2DIFF,wcs INT32 encoding=TS_2DIFF,rps INT32 encoding=TS_2DIFF,is_deleted BOOLEAN encoding=RLE,is_plan INT32,feedback_id INT64);
+
+create device template state aligned(workstation_id INT64,value_collect INT32,calendar_code TEXT encoding=DICTIONARY,factory_year INT32 encoding=RLE,factory_month INT32 encoding=RLE,factory_date INT32 encoding=RLE,factory_week INT32 encoding=RLE,shift_index INT32 encoding=TS_2DIFF,shift_time_type INT32 encoding=TS_2DIFF,wcs INT32 encoding=TS_2DIFF,rps INT32 encoding=TS_2DIFF,is_fix_point BOOLEAN encoding=RLE,is_sync BOOLEAN encoding=RLE,is_plan INT32, feedback_point_type INT32,feedback_id INT64,is_deleted BOOLEAN encoding=RLE,employee_id INT64);
+
+create device template process_param aligned (workstation_id INT64,v TEXT,n TEXT);
+
+create device template alarm aligned(workstation_id INT64,calendar_code TEXT encoding=DICTIONARY,factory_year INT32 encoding=RLE,factory_month INT32 encoding=RLE,factory_date INT32 encoding=RLE,factory_week INT32 encoding=RLE,shift_index INT32,shift_time_type INT32,code TEXT,message TEXT,level TEXT);
+
+create device template prog_name aligned(workstation_id INT64,name TEXT,part_no TEXT,process_no TEXT,version TEXT,seg_total INT32,seg_no INT32);
diff --git a/smart-man-boot/src/main/resources/sql/mysql/workinghours.sql b/smart-man-boot/src/main/resources/sql/mysql/workinghours.sql
new file mode 100644
index 0000000..434f3a3
--- /dev/null
+++ b/smart-man-boot/src/main/resources/sql/mysql/workinghours.sql
@@ -0,0 +1,58 @@
+/*宸ユ椂鍒嗘瀽妯″潡*/
+
+DROP TABLE IF EXISTS `part_workinghour`;
+CREATE TABLE `part_workinghour`
+(
+    `id`           bigint(0)                                                     NOT NULL COMMENT '涓婚敭',
+    `status`       tinyint(0)                                                    NULL DEFAULT NULL COMMENT '鐘舵��',
+    `is_deleted`   int                                                      NULL DEFAULT NULL COMMENT '鍒犻櫎',
+    `create_user`  varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+    `create_dept`  bigint(0)                                                     NULL DEFAULT NULL COMMENT '鍒涘缓閮ㄩ棬',
+    `create_time`  datetime(0)                                                   NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+    `update_user`  bigint(0)                                                     NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+    `update_time`  datetime(0)                                                   NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+    `tenant_id`    varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci  NULL DEFAULT '0' COMMENT '绉熸埛',
+    `part_no`      varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '闆朵欢缂栧彿',
+    `process_no`   varchar(20)                                                   NULL DEFAULT NULL COMMENT '宸ュ簭鍙�',
+    `version` varchar(20)  NULL DEFAULT NULL COMMENT '鐗堟',
+    
+    `seg_total`   int                                                      NULL DEFAULT NULL COMMENT '宸ュ簭娈垫暟',
+    `workstation_id`    bigint                                               NULL DEFAULT 0 COMMENT '宸ヤ綅id',
+    `start_time`  datetime(3)                                                   NULL DEFAULT NULL COMMENT '寮�濮嬫椂闂�',
+    `end_time`  datetime(3)                                                   NULL DEFAULT NULL COMMENT '缁撴潫鏃堕棿',
+    `occupancy_secs`    bigint                                               NULL DEFAULT 0 COMMENT '鍗犳満鏃堕棿(绉�)', 	
+	`clamping_secs`    bigint                                               NULL DEFAULT 0 COMMENT '瑁呭す璋冭瘯鏃堕棿(绉�)', 	
+	`first_working_secs`    bigint                                               NULL DEFAULT 0 COMMENT '棣栦欢鍒囧墛鏃堕棿(绉�)',
+	`last_remove_secs`    bigint                                               NULL DEFAULT 0 COMMENT '鏈欢鎷嗗嵏鏃堕棿(绉�)',
+    `first_measure_secs`    bigint                                               NULL DEFAULT 0 COMMENT '棣栦欢璁¢噺鏃堕棿(绉�)',
+    `processing_secs`    bigint                                               NULL DEFAULT 0 COMMENT '鍔犲伐鏃堕棿(绉�)',
+    `prepare_secs`    bigint                                               NULL DEFAULT 0 COMMENT '鍑嗗鏃堕棿(绉�)',
+    `single_process_secs`    bigint                                               NULL DEFAULT 0 COMMENT '鍗曚欢宸ユ椂(绉�)',
+    `amount`    bigint                                               NULL DEFAULT 0 COMMENT '鏁伴噺(璇ユ壒娆″唴)',
+    PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB
+  CHARACTER SET = utf8mb4
+  COLLATE = utf8mb4_general_ci COMMENT = '闆朵欢宸ユ椂'
+  ROW_FORMAT = Dynamic;
+
+DROP TABLE IF EXISTS `part_working_process`;
+CREATE TABLE `part_working_process`
+(
+    `id`           bigint(0)                                                     NOT NULL COMMENT '涓婚敭',
+    `status`       tinyint(0)                                                    NULL DEFAULT NULL COMMENT '鐘舵��',
+    `is_deleted`   int                                                      NULL DEFAULT NULL COMMENT '鍒犻櫎',
+    `create_user`  varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '鍒涘缓浜�',
+    `create_dept`  bigint(0)                                                     NULL DEFAULT NULL COMMENT '鍒涘缓閮ㄩ棬',
+    `create_time`  datetime(0)                                                   NULL DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+    `update_user`  bigint(0)                                                     NULL DEFAULT NULL COMMENT '鏇存柊浜�',
+    `update_time`  datetime(0)                                                   NULL DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+    `prog_name`    varchar(120) NULL DEFAULT NULL COMMENT '绋嬪簭鍚嶇О',
+    `workinghour_id`    bigint                                               NOT NULL COMMENT '闆朵欢宸ユ椂琛╥d',
+    `start_time`  datetime(3)                                                   NULL DEFAULT NULL COMMENT '寮�濮嬫椂闂�',
+    `end_time`  datetime(3)                                                   NULL DEFAULT NULL COMMENT '缁撴潫鏃堕棿',
+    `device_status`  int                                                   NULL DEFAULT NULL COMMENT '璁惧鐘舵��',
+    PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB
+  CHARACTER SET = utf8mb4
+  COLLATE = utf8mb4_general_ci COMMENT = '闆朵欢鍔犲伐杩囩▼璁板綍'
+  ROW_FORMAT = Dynamic;
\ No newline at end of file
diff --git a/smart-man-boot/src/test/java/com/qianwen/smartman/common/utils/DurationUtilTest.java b/smart-man-boot/src/test/java/com/qianwen/smartman/common/utils/DurationUtilTest.java
new file mode 100644
index 0000000..7352286
--- /dev/null
+++ b/smart-man-boot/src/test/java/com/qianwen/smartman/common/utils/DurationUtilTest.java
@@ -0,0 +1,33 @@
+package com.qianwen.smartman.common.utils;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.time.Duration;
+
+import java.time.LocalDateTime;
+import org.junit.jupiter.api.Test;
+
+public class DurationUtilTest {
+
+	@Test
+	public void toChineseDuration() {
+		//new Duration()
+		LocalDateTime end = LocalDateTime.now();
+		LocalDateTime start = end.minusHours(25);//25灏忔椂
+		Duration duration = Duration.between(start, end);
+		
+		String str = DurationUtil.toChineseDuration(duration);
+		assertEquals("1澶�1灏忔椂",str);
+		
+		start = end.minusHours(3);
+		duration = Duration.between(start, end);
+		str = DurationUtil.toChineseDuration(duration);
+		assertEquals("3灏忔椂",str);
+		
+		
+		start = end.minusHours(1).minusMinutes(5).minusSeconds(22);
+		duration = Duration.between(start, end);
+		str = DurationUtil.toChineseDuration(duration);
+		assertEquals("1灏忔椂5鍒�22绉�",str);
+	}
+}
diff --git a/smart-man-boot/src/test/java/com/qianwen/smartman/modules/workinghour/service/PartWorkingHourServiceTest.java b/smart-man-boot/src/test/java/com/qianwen/smartman/modules/workinghour/service/PartWorkingHourServiceTest.java
new file mode 100644
index 0000000..25fb331
--- /dev/null
+++ b/smart-man-boot/src/test/java/com/qianwen/smartman/modules/workinghour/service/PartWorkingHourServiceTest.java
@@ -0,0 +1,510 @@
+package com.qianwen.smartman.modules.workinghour.service;
+
+import java.io.FileOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.poi.ss.usermodel.BorderStyle;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.Chart;
+import org.apache.poi.ss.usermodel.ClientAnchor;
+import org.apache.poi.ss.usermodel.Drawing;
+import org.apache.poi.ss.usermodel.FillPatternType;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xssf.streaming.SXSSFRow;
+import org.apache.poi.xssf.streaming.SXSSFSheet;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.apache.poi.xssf.usermodel.XSSFChart;
+import org.junit.jupiter.api.Test;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarChart;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarSer;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTBoolean;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTCatAx;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTDLbls;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTLegend;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumRef;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTScaling;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrRef;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STAxPos;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STBarDir;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STBarGrouping;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STDispBlanksAs;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STLegendPos;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STOrientation;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STTickLblPos;
+
+public class PartWorkingHourServiceTest {
+	static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+	 
+    private static String systemTime = System.currentTimeMillis()+"";//df.format(System.currentTimeMillis());;
+    private static SXSSFWorkbook wb = new SXSSFWorkbook();
+ 
+    private SXSSFSheet sheet = null;
+
+    @Test
+    public void testMain() {
+    	// 瀛楁鍚�
+        List<String> fldNameArr = new ArrayList();
+ 
+        // 鏍囬
+        List<String> titleArr = new ArrayList();
+ 
+        // 妯℃嫙鏁版嵁
+        List<Map> dataList = new ArrayList();
+ 
+        Map dataMap1 = new HashMap();
+ 
+        dataMap1.put("value1", "璐у竵鍩洪噾");
+ 
+        dataMap1.put("value2", Math.floor(Math.random() * 100) + "");
+ 
+        dataMap1.put("value3", Math.floor(Math.random() * 100) + "");
+ 
+        dataMap1.put("value4", Math.floor(Math.random() * 100) + "");
+ 
+        Map dataMap2 = new HashMap();
+ 
+        dataMap2.put("value1", "鎸囨暟鍩洪噾");
+ 
+        dataMap2.put("value2", Math.floor(Math.random() * 100) + "");
+ 
+        dataMap2.put("value3", Math.floor(Math.random() * 100) + "");
+ 
+        dataMap2.put("value4", Math.floor(Math.random() * 100) + "");
+ 
+        Map dataMap3 = new HashMap();
+ 
+        dataMap3.put("value1", "鍋忚偂鍩洪噾");
+ 
+        dataMap3.put("value2", Math.floor(Math.random() * 100) + "");
+ 
+        dataMap3.put("value3", Math.floor(Math.random() * 100) + "");
+ 
+        dataMap3.put("value4", Math.floor(Math.random() * 100) + "");
+ 
+        Map dataMap4 = new HashMap();
+ 
+        dataMap4.put("value1", "鍊哄埜鍩洪噾");
+ 
+        dataMap4.put("value2", Math.floor(Math.random() * 100) + "");
+ 
+        dataMap4.put("value3", Math.floor(Math.random() * 100) + "");
+ 
+        dataMap4.put("value4", Math.floor(Math.random() * 100) + "");
+ 
+ 
+ 
+        fldNameArr.add("value1");
+ 
+        fldNameArr.add("value2");
+ 
+        fldNameArr.add("value3");
+ 
+        fldNameArr.add("value4");
+ 
+        titleArr.add("绫诲瀷");
+ 
+        titleArr.add("涔板叆");
+ 
+        titleArr.add("鍗栧嚭");
+ 
+        titleArr.add("鍒嗙孩");
+ 
+        dataList.add(dataMap1);
+ 
+        dataList.add(dataMap2);
+ 
+        dataList.add(dataMap3);
+ 
+        dataList.add(dataMap4);
+ 
+ 
+ 
+        //PoiExcelUtil ecu = new PoiExcelUtil();
+ 
+        try {
+ 
+            // 鍒涘缓鏌辩姸鍥�
+            //ecu.createBarChart(titleArr, fldNameArr, dataList);
+        	createBarChart(titleArr, fldNameArr, dataList);
+            // 鍒涘缓楗肩姸鍥�
+           // ecu.createPieChart(titleArr, fldNameArr, dataList);
+ 
+            // 鍒涘缓鎶樼嚎鍥�
+            //ecu.createTimeXYChar(titleArr, fldNameArr, dataList);
+ //
+            // 鍒涘缓闈㈢Н鍥�
+            //ecu.createAreaChart(titleArr, fldNameArr, dataList);
+ 
+            String title="娴嬭瘯鏁版嵁";
+            //瀵煎嚭鍒版枃浠�
+            FileOutputStream out = new FileOutputStream(new File("D:/PoiExcel/"+systemTime+"_"+title+".xls"));
+ 
+            wb.write(out);
+ 
+            out.close();
+ 
+        } catch (IOException e) {
+ 
+            e.printStackTrace();
+ 
+        }
+
+    }
+	/**
+     * 鍒涘缓鏌辩姸鍥�(鍫嗙Н鍥撅紝澶氱粍)
+     *
+     * @throws IOException
+     */
+ 
+    public void createBarChart(List<String> titleArr, List<String> fldNameArr, List<Map> dataList) {
+ 
+        // 鍒涘缓涓�涓猻heet椤�
+        sheet = wb.createSheet("sheet0");
+        // drawSheet0Table(sheet,titleArr,fldNameArr,dataList);
+        // 鍫嗙Н=STBarGrouping.STACKED 澶氱粍=STBarGrouping.CLUSTERED
+        //boolean result = drawSheet0Map(sheet, STBarGrouping.CLUSTERED, fldNameArr, dataList, titleArr);
+        
+        boolean result = drawSheet0Map(sheet, STBarGrouping.STACKED, fldNameArr, dataList, titleArr);//yys鏀�
+        System.out.println("鐢熸垚鏌辩姸鍥�(鍫嗙Нor澶氱粍)-->" + result);
+ 
+    }
+    
+    /**
+     * 鐢熸垚鏌辩姸鍥�
+     *
+     * @param sheet      椤电
+     * @param group      鏌辩姸鍥剧被鍨�(鍫嗙Н,澶氱粍)
+     * @param fldNameArr 鍧愭爣鍚嶇О
+     * @param dataList   缁熻鏁版嵁
+     * @return
+     */
+ 
+    // private boolean drawSheet0Map(SXSSFSheet sheet, Enum group, List fldNameArr, List<Map> dataList, List titleArr) {
+    private boolean drawSheet0Map(SXSSFSheet sheet, STBarGrouping.Enum group, List<String> fldNameArr, List<Map> dataList, List<String> titleArr) {
+ 
+        boolean result = false;
+ 
+        // 鑾峰彇sheet鍚嶇О
+        String sheetName = sheet.getSheetName();
+ 
+        result = drawSheet0Table(sheet, titleArr, fldNameArr, dataList);
+ 
+        // 鍒涘缓涓�涓敾甯�
+        Drawing drawing = sheet.createDrawingPatriarch();
+ 
+        // 鐢讳竴涓浘鍖哄煙
+        // 鍓嶅洓涓粯璁�0锛屼粠绗�8琛屽埌绗�25琛�,浠庣0鍒楀埌绗�6鍒楃殑鍖哄煙
+ 
+        ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 8, 6, 25);
+ 
+        // 鍒涘缓涓�涓猚hart瀵硅薄
+        Chart chart = drawing.createChart(anchor);
+        
+        CTChart ctChart = ((XSSFChart) chart).getCTChart();
+        
+        CTPlotArea ctPlotArea = ctChart.getPlotArea();
+ 
+        // 鍒涘缓鏌辩姸鍥炬ā鍨�
+        CTBarChart ctBarChart = ctPlotArea.addNewBarChart();
+        
+        CTBoolean ctBoolean = ctBarChart.addNewVaryColors();
+ 
+        ctBarChart.getVaryColors().setVal(true);
+ 
+        // 璁剧疆鍥剧被鍨�
+        // STBarGrouping.Enum group = null;
+        ctBarChart.addNewGrouping().setVal(group);
+       
+        ctBoolean.setVal(true);
+ 
+        
+        //ctBarChart.addNewBarDir().setVal(STBarDir.COL);
+        ctBarChart.addNewBarDir().setVal(STBarDir.BAR);//yangysmod ,鏀规垚浜嗘í鍚�
+        // 鏄惁娣诲姞宸︿晶鍧愭爣杞�
+        ctChart.addNewDispBlanksAs().setVal(STDispBlanksAs.ZERO);
+ 
+        ctChart.addNewShowDLblsOverMax().setVal(true);
+ 
+        // 璁剧疆杩欎袱涓弬鏁版槸涓轰簡鍦⊿TACKED妯″紡涓嬬敓鎴愬爢绉ā寮忥紱(standard)鏍囧噯妯″紡鏃堕渶瑕佸皢杩欎袱琛屽幓鎺�
+        if ("stacked".equals(group.toString()) || "percentStacked".equals(group.toString())) {
+ 
+            ctBarChart.addNewGapWidth().setVal(150);
+ 
+            ctBarChart.addNewOverlap().setVal((byte) 100);
+ 
+        }
+ 
+        // 鍒涘缓搴忓垪,骞朵笖璁剧疆閫変腑鍖哄煙
+        //for (int i = 0; i < fldNameArr.size() - 1; i++) {
+ 
+            CTBarSer ctBarSer = ctBarChart.addNewSer();
+ 
+            CTSerTx ctSerTx = ctBarSer.addNewTx();
+ 
+            // 鍥句緥鍖�
+            CTStrRef ctStrRef = ctSerTx.addNewStrRef();
+ 
+            // 閫夊畾鍖哄煙绗�0琛�,绗�1,2,3鍒楁爣棰樹綔涓哄浘渚� //1 2 3
+            //String legendDataRange = new CellRangeAddress(0, 0, i + 1, i + 1).formatAsString(sheetName, true);
+ 
+            //ctStrRef.setF(legendDataRange);
+ 
+            ctBarSer.addNewIdx().setVal(3);//
+            //ctBarSer.
+            // 妯潗鏍囧尯
+            CTAxDataSource cttAxDataSource = ctBarSer.addNewCat();
+ 
+            ctStrRef = cttAxDataSource.addNewStrRef();
+ 
+            // 閫夌0鍒�,绗�1-6琛屼綔涓烘í鍧愭爣鍖哄煙
+            String axisDataRange = new CellRangeAddress(1, dataList.size(), 0, 0).formatAsString(sheetName, true);
+ 
+            ctStrRef.setF(axisDataRange);
+ 
+            // 鏁版嵁鍖哄煙
+            CTNumDataSource ctNumDataSource = ctBarSer.addNewVal();
+            
+            CTNumRef ctNumRef = ctNumDataSource.addNewNumRef();
+ 
+            // 閫夌1-6琛�,绗�1-3鍒椾綔涓烘暟鎹尯鍩� //1 2 3
+            //String numDataRange = new CellRangeAddress(1, dataList.size(), i + 1, i + 1).formatAsString(sheetName, true);
+            String numDataRange = new CellRangeAddress(1, dataList.size(), 1, 1).formatAsString(sheetName, true);//yangys mod
+            
+            System.out.println("鏁版嵁鍖哄煙"+numDataRange);
+ 
+            ctNumRef.setF(numDataRange);
+            
+ 
+            // 娣诲姞鏌辩姸杈规绾�
+            ctBarSer.addNewSpPr().addNewLn().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{0, 0, 0});
+ 
+            // 璁剧疆璐熻酱棰滆壊涓嶆槸鐧借壊
+            ctBarSer.addNewInvertIfNegative().setVal(false);
+ 
+            // 璁剧疆鏍囩鏍煎紡
+            ctBoolean.setVal(false);
+ 
+            CTDLbls newDLbls = ctBarSer.addNewDLbls();
+ 
+            newDLbls.setShowLegendKey(ctBoolean);
+ 
+            ctBoolean.setVal(true);
+            newDLbls.setShowVal(ctBoolean);
+ 
+            ctBoolean.setVal(false);
+ 
+            newDLbls.setShowCatName(ctBoolean);
+            newDLbls.setShowSerName(ctBoolean);
+            newDLbls.setShowPercent(ctBoolean);
+            newDLbls.setShowBubbleSize(ctBoolean);
+            newDLbls.setShowLeaderLines(ctBoolean);
+ 
+        //}
+ 
+        // 鍛婅瘔BarChart瀹冩湁鍧愭爣杞达紝骞剁粰瀹冧滑id
+        ctBarChart.addNewAxId().setVal(123456);
+ 
+        ctBarChart.addNewAxId().setVal(123457);
+ 
+        // 妯潗鏍�
+        CTCatAx ctCatAx = ctPlotArea.addNewCatAx();
+ 
+        ctCatAx.addNewAxId().setVal(123456); // id of the cat axis
+ 
+        CTScaling ctScaling = ctCatAx.addNewScaling();
+ 
+        ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
+ 
+        ctCatAx.addNewAxPos().setVal(STAxPos.B);
+ 
+        ctCatAx.addNewCrossAx().setVal(123457); // id of the val axis
+ 
+        ctCatAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);
+ 
+        // 绾靛潗鏍�
+        CTValAx ctValAx = ctPlotArea.addNewValAx();
+ 
+        ctValAx.addNewAxId().setVal(123457); // id of the val axis
+ 
+        ctScaling = ctValAx.addNewScaling();
+ 
+        ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
+ 
+        // 璁剧疆浣嶇疆
+        ctValAx.addNewAxPos().setVal(STAxPos.L);
+ 
+        ctValAx.addNewCrossAx().setVal(123456); // id of the cat axis
+ 
+        ctValAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);
+ 
+        // 鏄惁鍒犻櫎涓诲乏杈硅酱
+        ctValAx.addNewDelete().setVal(false);
+ 
+        // 鏄惁鍒犻櫎妯潗鏍�
+        ctCatAx.addNewDelete().setVal(false);
+ 
+        // legend鍥炬敞
+ 
+ 
+//        if (true) {
+        CTLegend ctLegend = ctChart.addNewLegend();
+ 
+        ctLegend.addNewLegendPos().setVal(STLegendPos.B);
+ 
+        ctLegend.addNewOverlay().setVal(false);
+//        }
+ 
+        return result;
+ 
+    }
+
+    
+    /**
+     * 鐢熸垚鏁版嵁琛�
+     *
+     * @param sheet      sheet椤靛璞�
+     * @param titleArr   琛ㄥご瀛楁
+     * @param fldNameArr 宸﹁竟鏍囬瀛楁
+     * @param dataList   鏁版嵁
+     * @return 鏄惁鐢熸垚鎴愬姛
+     */
+ 
+    private boolean drawSheet0Table(SXSSFSheet sheet, List<String> titleArr, List<String> fldNameArr, List<Map> dataList) {
+ 
+        // 娴嬭瘯鏃惰繑鍥炲��
+        boolean result = true;
+ 
+        // 鍒濆鍖栬〃鏍兼牱寮�
+        List styleList = tableStyle();
+ 
+        // 鏍规嵁鏁版嵁鍒涘缓excel绗竴琛屾爣棰樿
+        SXSSFRow row0 = sheet.createRow(0);
+ 
+        for (int i = 0; i < titleArr.size(); i++) {
+ 
+            // 璁剧疆鏍囬
+            row0.createCell(i).setCellValue(titleArr.get(i));
+ 
+            // 璁剧疆鏍囬琛屾牱寮�
+            row0.getCell(i).setCellStyle((CellStyle) styleList.get(0));
+ 
+        }
+ 
+        // 濉厖鏁版嵁
+        for (int i = 0; i < dataList.size(); i++) {
+ 
+            // 鑾峰彇姣忎竴椤圭殑鏁版嵁
+            Map data = (Map) dataList.get(i);
+ 
+            // 璁剧疆姣忎竴琛岀殑瀛楁鏍囬鍜屾暟鎹�
+            SXSSFRow rowi = sheet.createRow(i + 1);
+ 
+            for (int j = 0; j < data.size(); j++) {
+ 
+                // 鍒ゆ柇鏄惁鏄爣棰樺瓧娈靛垪
+                if (j == 0) {
+ 
+                    rowi.createCell(j).setCellValue((String) data.get("value" + (j + 1)));
+ 
+                    // 璁剧疆宸﹁竟瀛楁鏍峰紡
+                    sheet.getRow(i + 1).getCell(j).setCellStyle((CellStyle) styleList.get(0));
+ 
+                } else {
+ 
+                    rowi.createCell(j).setCellValue(Double.valueOf((String) data.get("value" + (j + 1))));
+ 
+                    // 璁剧疆鏁版嵁鏍峰紡
+                    sheet.getRow(i + 1).getCell(j).setCellStyle((CellStyle) styleList.get(2));
+ 
+                }
+ 
+            }
+ 
+        }
+ 
+        return result;
+ 
+    }
+
+    
+    /**
+     * 鐢熸垚琛ㄦ牸鏍峰紡
+     *
+     * @return
+     */
+ 
+    private static List tableStyle() {
+ 
+        List cellStyleList = new ArrayList();
+ 
+        // 鏍峰紡鍑嗗
+        // 鏍囬鏍峰紡
+        CellStyle style = wb.createCellStyle();
+ 
+        style.setFillForegroundColor(IndexedColors.ROYAL_BLUE.getIndex());
+ 
+        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+ 
+        style.setBorderBottom(BorderStyle.THIN); // 涓嬭竟妗�
+ 
+        style.setBorderLeft(BorderStyle.THIN);// 宸﹁竟妗�
+ 
+        style.setBorderTop(BorderStyle.THIN);// 涓婅竟妗�
+ 
+        style.setBorderRight(BorderStyle.THIN);// 鍙宠竟妗�
+ 
+        style.setAlignment(HorizontalAlignment.CENTER);
+ 
+        cellStyleList.add(style);
+ 
+        CellStyle style1 = wb.createCellStyle();
+ 
+        style1.setBorderBottom(BorderStyle.THIN); // 涓嬭竟妗�
+ 
+        style1.setBorderLeft(BorderStyle.THIN);// 宸﹁竟妗�
+ 
+        style1.setBorderTop(BorderStyle.THIN);// 涓婅竟妗�
+ 
+        style1.setBorderRight(BorderStyle.THIN);// 鍙宠竟妗�
+ 
+        style1.setAlignment(HorizontalAlignment.CENTER);
+ 
+        cellStyleList.add(style1);
+ 
+        CellStyle cellStyle = wb.createCellStyle();
+ 
+        cellStyle.setBorderTop(BorderStyle.THIN);// 涓婅竟妗�
+ 
+        cellStyle.setBorderBottom(BorderStyle.THIN); // 涓嬭竟妗�
+ 
+        cellStyle.setBorderLeft(BorderStyle.THIN);// 宸﹁竟妗�
+ 
+        cellStyle.setBorderRight(BorderStyle.THIN);// 鍙宠竟妗�
+ 
+        cellStyle.setAlignment(HorizontalAlignment.CENTER);// 姘村钩瀵归綈鏂瑰紡
+ 
+        // cellStyle.setVerticalAlignment(VerticalAlignment.TOP);//鍨傜洿瀵归綈鏂瑰紡
+        cellStyleList.add(cellStyle);
+ 
+        return cellStyleList;
+ 
+    }
+
+                        
+//https://blog.csdn.net/Lyq2017901206/article/details/126547542
+
+}

--
Gitblit v1.9.3