Просмотр исходного кода

Merge branch 'wrdp' into 'develop'

Wrdp

See merge request o2oa/o2oa!2589
胡起 5 лет назад
Родитель
Сommit
9f09e15161
19 измененных файлов с 825 добавлено и 114 удалено
  1. 3 2
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/date/DateOperation.java
  2. 118 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceDetailFactory.java
  3. 12 1
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceSelfHolidayFactory.java
  4. 329 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attachment/ActionExportDetailWithFilter.java
  5. 2 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attachment/BaseAction.java
  6. 16 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attachment/ExceptionAttendanceDetailProcess.java
  7. 30 6
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attachment/FileImportExportAction.java
  8. 60 3
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/selfholiday/ActionListNextWithFilter.java
  9. 6 6
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailAnalyseSignProxy2.java
  10. 119 62
      o2server/x_processplatform_assemble_designer/src/main/java/com/x/processplatform/assemble/designer/ProjectionExecuteQueue.java
  11. 10 11
      o2web/source/o2_core/o2.js
  12. 25 7
      o2web/source/o2_core/o2/xAction/services/x_attendance_assemble_control.js
  13. 6 3
      o2web/source/o2_core/o2/xAction/services/x_attendance_assemble_control.json
  14. 27 3
      o2web/source/x_component_Attendance/PeopleDetail.js
  15. 9 3
      o2web/source/x_component_Attendance/SelfHoliday.js
  16. 26 3
      o2web/source/x_component_Attendance/TopUnitDetail.js
  17. 26 3
      o2web/source/x_component_Attendance/UnitDetail.js
  18. 1 1
      o2web/source/x_component_Template/MSelector.js
  19. BIN
      o2web/source/x_component_process_FormDesigner/Module/Actionbar/default/tools/xform_blue_simple/downloadAll.png

+ 3 - 2
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/date/DateOperation.java

@@ -711,8 +711,9 @@ public class DateOperation {
 	 */
 	 */
 	public static Date getLastDayOfMonth(Date date) {  
 	public static Date getLastDayOfMonth(Date date) {  
         Calendar calendar = convert(date);  
         Calendar calendar = convert(date);  
-        calendar.set(Calendar.DATE, calendar.getMaximum(Calendar.DATE));  
-        return calendar.getTime();  
+        //calendar.set(Calendar.DATE, calendar.getMaximum(Calendar.DATE));
+		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
+		return calendar.getTime();
     }  
     }  
 	/** 
 	/** 
      * 将日期转换为日历 
      * 将日期转换为日历 

+ 118 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceDetailFactory.java

@@ -965,8 +965,126 @@ public class AttendanceDetailFactory extends AbstractFactory {
 		for (int i = 0; i < vs.size(); i++) {
 		for (int i = 0; i < vs.size(); i++) {
 			query.setParameter(i + 1, vs.get(i));
 			query.setParameter(i + 1, vs.get(i));
 		}
 		}
+		System.out.println("query=" +query.toString());
 		return query.setMaxResults(count).getResultList();
 		return query.setMaxResults(count).getResultList();
 	}
 	}
+
+	/**
+	 * 根据条件查询考勤信息ids(排除不参加考勤的人员)
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	//根据人员和打卡日期查找打卡记录
+	public List<AttendanceDetail> listIdsWithFilterUn( WrapInFilter wrapIn ,List<String> unUnitNameList,List<String> personNameList )  throws Exception {
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		String order = wrapIn.getOrder();//排序方式
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+
+		if( order == null || order.isEmpty() ){
+			order = "DESC";
+		}
+
+		Integer index = 1;
+		sql_stringBuffer.append( "SELECT o FROM "+AttendanceDetail.class.getCanonicalName()+" o where 1=1" );
+
+		if ((null != wrapIn.getQ_empName()) && (!wrapIn.getQ_empName().isEmpty())) {
+			sql_stringBuffer.append(" and o.empName = ?" + (index));
+			vs.add( wrapIn.getQ_empName() );
+			index++;
+		}
+		if (null != wrapIn.getUnitNames() && wrapIn.getUnitNames().size()>0) {
+			sql_stringBuffer.append(" and o.unitName in ( ?" + (index) + ")");
+			vs.add( wrapIn.getUnitNames() );
+			index++;
+		}
+		if (null != wrapIn.getTopUnitNames() && wrapIn.getTopUnitNames().size() > 0 ) {
+			sql_stringBuffer.append(" and o.topUnitName in ( ?" + (index) + ")");
+			vs.add( wrapIn.getTopUnitNames() );
+			index++;
+		}
+		if ((null != wrapIn.getCycleYear() ) && (!wrapIn.getCycleYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.cycleYear = ?" + (index));
+			vs.add( wrapIn.getCycleYear() );
+			index++;
+		}
+		if ((null != wrapIn.getCycleMonth()) && (!wrapIn.getCycleMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.cycleMonth = ?" + (index));
+			vs.add( wrapIn.getCycleMonth() );
+			index++;
+		}
+		if ((null != wrapIn.getQ_year() ) && (!wrapIn.getQ_year().isEmpty())) {
+			sql_stringBuffer.append(" and o.yearString = ?" + (index));
+			vs.add( wrapIn.getQ_year() );
+			index++;
+		}
+		if ((null != wrapIn.getQ_month()) && (!wrapIn.getQ_month().isEmpty())) {
+			sql_stringBuffer.append(" and o.monthString = ?" + (index));
+			vs.add( wrapIn.getQ_month() );
+			index++;
+		}
+		if ((null != wrapIn.getQ_date()) && (!wrapIn.getQ_date().isEmpty())) {
+			sql_stringBuffer.append(" and o.recordDateString = ?" + (index));
+			vs.add( wrapIn.getQ_date() );
+			index++;
+		}
+
+		if ( wrapIn.getRecordStatus() != 999 ) {
+			sql_stringBuffer.append(" and o.recordStatus = ?" + (index));
+			vs.add( wrapIn.getRecordStatus() );
+			index++;
+		}
+
+		if (wrapIn.getIsAbsent() != null ) {
+			sql_stringBuffer.append(" and o.isAbsent = ?" + (index));
+			vs.add( wrapIn.getIsAbsent() );
+			index++;
+		}
+
+		if (wrapIn.getIsLate() != null ) {
+			sql_stringBuffer.append(" and o.isLate = ?" + (index));
+			vs.add( wrapIn.getIsLate() );
+			index++;
+		}
+
+		if (wrapIn.getIsLackOfTime() != null ) {
+			sql_stringBuffer.append(" and o.isLackOfTime = ?" + (index));
+			vs.add( wrapIn.getIsLackOfTime() );
+			index++;
+		}
+
+		if (wrapIn.getIsLeaveEarlier() != null ) {
+			sql_stringBuffer.append(" and o.isLeaveEarlier = ?" + (index));
+			vs.add( wrapIn.getIsLeaveEarlier() );
+			index++;
+		}
+
+		if (ListTools.isNotEmpty(unUnitNameList)) {
+			sql_stringBuffer.append(" and o.unitName not in ( ?" + (index) + ")");
+			vs.add( unUnitNameList );
+			index++;
+		}
+		if (ListTools.isNotEmpty(personNameList)) {
+			sql_stringBuffer.append(" and o.empName not in ( ?" + (index) + ")");
+			vs.add( personNameList );
+			index++;
+		}
+
+		if( StringUtils.isNotEmpty( wrapIn.getKey() )){
+			sql_stringBuffer.append(" order by o."+wrapIn.getKey()+" " + order );
+		}else{
+			sql_stringBuffer.append(" order by o.sequence " + order );
+		}
+		Query query = em.createQuery( sql_stringBuffer.toString(), AttendanceDetail.class );
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}
+		System.out.println("query=" +query.toString());
+		return query.getResultList();
+		/*cq.select( root.get(AttendanceDetail_.id ));
+		return em.createQuery(cq.where(p)).getResultList();*/
+	}
 	
 	
 	/**
 	/**
 	 * 查询上一页的文档信息数据
 	 * 查询上一页的文档信息数据

+ 12 - 1
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceSelfHolidayFactory.java

@@ -2,6 +2,7 @@ package com.x.attendance.assemble.control.factory;
 
 
 import com.x.attendance.assemble.control.AbstractFactory;
 import com.x.attendance.assemble.control.AbstractFactory;
 import com.x.attendance.assemble.control.Business;
 import com.x.attendance.assemble.control.Business;
+import com.x.attendance.assemble.control.jaxrs.selfholiday.ActionListNextWithFilter;
 import com.x.attendance.assemble.control.jaxrs.selfholiday.WrapInFilter;
 import com.x.attendance.assemble.control.jaxrs.selfholiday.WrapInFilter;
 import com.x.attendance.entity.AttendanceSelfHoliday;
 import com.x.attendance.entity.AttendanceSelfHoliday;
 import com.x.attendance.entity.AttendanceSelfHoliday_;
 import com.x.attendance.entity.AttendanceSelfHoliday_;
@@ -122,7 +123,7 @@ public class AttendanceSelfHolidayFactory extends AbstractFactory {
 	 * @throws Exception
 	 * @throws Exception
 	 */
 	 */
 	@SuppressWarnings("unchecked")
 	@SuppressWarnings("unchecked")
-	public List<AttendanceSelfHoliday> listIdsNextWithFilter( String id, Integer count, Object sequence, WrapInFilter wrapIn ) throws Exception {
+	public List<AttendanceSelfHoliday> listIdsNextWithFilter( String id, Integer count, Object sequence, ActionListNextWithFilter.WrapIn wrapIn ) throws Exception {
 		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
 		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
 		EntityManager em = this.entityManagerContainer().get( AttendanceSelfHoliday.class );
 		EntityManager em = this.entityManagerContainer().get( AttendanceSelfHoliday.class );
 		String order = wrapIn.getOrder();//排序方式
 		String order = wrapIn.getOrder();//排序方式
@@ -156,6 +157,15 @@ public class AttendanceSelfHolidayFactory extends AbstractFactory {
 			vs.add( wrapIn.getTopUnitNames() );
 			vs.add( wrapIn.getTopUnitNames() );
 			index++;
 			index++;
 		}
 		}
+		if (null != wrapIn.getStartdate() && null != wrapIn.getEnddate()) {
+			sql_stringBuffer.append(" and o.startTime >  ?" + (index) );
+			vs.add( wrapIn.getStartdate());
+			index++;
+
+			sql_stringBuffer.append(" and o.endTime < ?" + (index));
+			vs.add( wrapIn.getEnddate());
+			index++;
+		}
 		
 		
 		if( StringUtils.isNotEmpty( wrapIn.getKey() )){
 		if( StringUtils.isNotEmpty( wrapIn.getKey() )){
 			sql_stringBuffer.append(" order by o."+wrapIn.getKey()+" " + order );
 			sql_stringBuffer.append(" order by o."+wrapIn.getKey()+" " + order );
@@ -164,6 +174,7 @@ public class AttendanceSelfHolidayFactory extends AbstractFactory {
 		}
 		}
 		
 		
 		Query query = em.createQuery( sql_stringBuffer.toString(), AttendanceSelfHoliday.class );
 		Query query = em.createQuery( sql_stringBuffer.toString(), AttendanceSelfHoliday.class );
+		System.out.println("query=" +query.toString());
 		//为查询设置所有的参数值
 		//为查询设置所有的参数值
 		for (int i = 0; i < vs.size(); i++) {
 		for (int i = 0; i < vs.size(); i++) {
 			query.setParameter(i + 1, vs.get(i));
 			query.setParameter(i + 1, vs.get(i));

+ 329 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attachment/ActionExportDetailWithFilter.java

@@ -0,0 +1,329 @@
+package com.x.attendance.assemble.control.jaxrs.attachment;
+
+import com.google.gson.JsonElement;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.assemble.control.ExceptionWrapInConvert;
+import com.x.attendance.assemble.control.jaxrs.attendancedetail.WrapInFilter;
+import com.x.attendance.assemble.control.service.AttendanceEmployeeConfigServiceAdv;
+import com.x.attendance.assemble.control.service.UserManagerService;
+import com.x.attendance.entity.*;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.jaxrs.WoFile;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.DateTools;
+import com.x.base.core.project.tools.ListTools;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 导出统计明细
+ */
+public class ActionExportDetailWithFilter extends BaseAction {
+	
+	private static  Logger logger = LoggerFactory.getLogger(ActionExportDetailWithFilter.class);
+	private UserManagerService userManagerService = new UserManagerService();
+	protected AttendanceEmployeeConfigServiceAdv attendanceEmployeeConfigServiceAdv = new AttendanceEmployeeConfigServiceAdv();
+	
+	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson,
+										String q_topUnitName,
+										String q_unitName,
+										String q_empName,
+										String cycleYear,
+										String cycleMonth,
+										String q_date,
+										String isAbsent,
+										String isLackOfTime,
+										String isLate,
+										Boolean stream) throws Exception {
+		ActionResult<Wo> result = new ActionResult<>();
+		EffectivePerson currentPerson = this.effectivePerson(request);
+		List<String> ids = null;
+		List<AttendanceDetail> detailList = null;
+		Workbook wb = null;
+		Wo wo = null;
+		String fileName = null;
+		String sheetName = null;
+		Boolean check = true;
+		WrapInFilter wrapIn = new WrapInFilter();
+
+		long total = 0;
+		List<String> topUnitNames = new ArrayList<String>();
+		List<String> unitNames = new ArrayList<String>();
+		List<String> topUnitNames_tmp = null;
+		List<String> unitNames_tmp = null;
+		AttendanceScheduleSetting scheduleSetting_top = null;
+		AttendanceScheduleSetting scheduleSetting = null;
+
+
+		List<String> unUnitNameList = new ArrayList<String>();
+		List<String> personNameList = new ArrayList<String>();
+
+		try {
+			if(StringUtils.isNotEmpty(q_topUnitName) && !StringUtils.equals(q_topUnitName,"0")){
+				wrapIn.setQ_topUnitName(q_topUnitName);
+			}
+			if(StringUtils.isNotEmpty(q_unitName)&& !StringUtils.equals(q_unitName,"0")){
+				wrapIn.setQ_unitName(q_unitName);
+			}
+			if(StringUtils.isNotEmpty(q_empName)&& !StringUtils.equals(q_empName,"0")){
+				wrapIn.setQ_empName(q_empName);
+				wrapIn.setKey("recordDateString");
+			}
+			if(StringUtils.isNotEmpty(cycleYear)&& !StringUtils.equals(cycleYear,"0")){
+				wrapIn.setCycleYear(cycleYear);
+			}
+			if(StringUtils.isNotEmpty(cycleMonth)&& !StringUtils.equals(cycleMonth,"0")){
+				wrapIn.setCycleMonth(cycleMonth);
+			}
+			if(StringUtils.isNotEmpty(q_date)&& !StringUtils.equals(q_date,"0")){
+				wrapIn.setQ_date(q_date);
+			}
+			if(!StringUtils.equals(isAbsent,"0")){
+				wrapIn.setIsAbsent(BooleanUtils.toBoolean(isAbsent));
+			}
+			if(!StringUtils.equals(isLackOfTime,"0")){
+				wrapIn.setIsLackOfTime(BooleanUtils.toBoolean(isLackOfTime));
+			}
+			if(!StringUtils.equals(isLate,"0")){
+				wrapIn.setIsLate(BooleanUtils.toBoolean(isLate));
+			}
+		} catch (Exception e) {
+			check = false;
+			logger.error(e, currentPerson, request, null);
+		}
+		if(check){
+				// 处理一下顶层组织,查询下级顶层组织
+				if ( StringUtils.isNotEmpty( wrapIn.getQ_topUnitName() )) {
+					topUnitNames.add(wrapIn.getQ_topUnitName());
+					scheduleSetting_top = attendanceScheduleSettingServiceAdv.getAttendanceScheduleSettingWithUnit(wrapIn.getQ_topUnitName(), effectivePerson.getDebugger() );
+					try {
+						topUnitNames_tmp = userManagerService.listSubUnitNameWithParent(wrapIn.getQ_topUnitName());
+					} catch (Exception e) {
+						Exception exception = new ExceptionAttendanceDetailProcess(e,
+								"根据顶层组织顶层组织列示所有下级组织名称发生异常!TopUnit:" + wrapIn.getQ_topUnitName());
+						result.error(exception);
+						logger.error(e, currentPerson, request, null);
+					}
+					if (topUnitNames_tmp != null && topUnitNames_tmp.size() > 0) {
+						for (String topUnitName : topUnitNames_tmp) {
+							topUnitNames.add(topUnitName);
+						}
+					}
+					wrapIn.setTopUnitNames(topUnitNames);
+				}
+
+				// 处理一下组织,查询下级组织
+				if ( StringUtils.isNotEmpty( wrapIn.getQ_unitName() )) {
+					unitNames.add(wrapIn.getQ_unitName());
+					scheduleSetting = attendanceScheduleSettingServiceAdv.getAttendanceScheduleSettingWithUnit(wrapIn.getQ_unitName(), effectivePerson.getDebugger() );
+					try {
+						unitNames_tmp = userManagerService.listSubUnitNameWithParent(wrapIn.getQ_unitName());
+					} catch (Exception e) {
+						Exception exception = new ExceptionAttendanceDetailProcess(e,
+								"根据组织名称列示所有下级组织名称发生异常!Unit:" + wrapIn.getQ_unitName());
+						result.error(exception);
+						logger.error(e, currentPerson, request, null);
+					}
+					if (unitNames_tmp != null && unitNames_tmp.size() > 0) {
+						for (String unitName : unitNames_tmp) {
+							unitNames.add(unitName);
+						}
+					}
+					wrapIn.setUnitNames(unitNames);
+				}
+
+		}
+		if (check ) {
+			unUnitNameList = getUnUnitNameList();
+			personNameList = getUnPersonNameList();
+			try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+				// 从数据库中查询符合条件的一页数据对象
+				Business business = new Business(emc);
+				/*ids = business.getAttendanceDetailFactory().listIdsWithFilterUn(wrapIn,unUnitNameList,personNameList);
+				detailList = business.getAttendanceDetailFactory().list(ids);*/
+				detailList = business.getAttendanceDetailFactory().listIdsWithFilterUn(wrapIn,unUnitNameList,personNameList);
+				logger.info("detailList======"+detailList.size() );
+			}catch (Exception e) {
+				logger.info("系统在查询符合条件的打卡记录时发生异常。" );
+				e.printStackTrace();
+			}
+
+		}
+		// 将结果组织成EXCEL		
+		if( check ) {
+			fileName = "统计打卡记录明细_"+ DateTools.formatDate(new Date())+".xls";
+			sheetName = "Sheet1";
+			wb = composeDetail( fileName, sheetName, detailList );
+		}
+		
+		if( check ) {
+			ByteArrayOutputStream bos = new ByteArrayOutputStream();
+			try {
+			    wb.write(bos);
+			    wo = new Wo(bos.toByteArray(), 
+						this.contentType(stream, fileName), 
+						this.contentDisposition(stream, fileName));
+			} finally {
+			    bos.close();
+			}
+		}		
+		result.setData(wo);
+		return result;
+	}
+
+	private Workbook composeDetail(String fileName, String sheetName, List<AttendanceDetail> detailList) {
+		AttendanceDetail attendanceDetail = null;
+		AttendanceAppealInfo attendanceAppealInfo = null;
+		
+		Workbook wb = new HSSFWorkbook();
+		Row row = null;
+		if (ListTools.isNotEmpty(detailList) ) {
+			// 创建新的表格
+			Sheet sheet = wb.createSheet(sheetName);
+			
+			// 先创建表头
+			row = sheet.createRow(0);
+			row.createCell(0).setCellValue("顶层组织名称");
+			row.createCell(1).setCellValue("组织名称");
+			row.createCell(2).setCellValue("姓名");
+			row.createCell(3).setCellValue("日期");
+			row.createCell(4).setCellValue("说明");
+			row.createCell(5).setCellValue("上午上班打卡时间");
+			row.createCell(6).setCellValue("上午下班打卡时间");
+			row.createCell(7).setCellValue("下午上班打卡时间");
+			row.createCell(8).setCellValue("下午下班打开时间");
+			row.createCell(9).setCellValue("考勤状态");
+			row.createCell(10).setCellValue("申诉状态");
+
+			for (int i = 0; i < detailList.size(); i++) {
+				attendanceDetail = detailList.get(i);
+				row = sheet.createRow(i + 1);
+				String topUnitName = attendanceDetail.getTopUnitName();
+				String unitName = attendanceDetail.getUnitName();
+				String empName = attendanceDetail.getEmpName();
+				if(StringUtils.isNotEmpty(topUnitName) && StringUtils.contains(topUnitName,"@")){
+					topUnitName = topUnitName.split("@")[0];
+				}
+				if(StringUtils.isNotEmpty(unitName) && StringUtils.contains(unitName,"@")){
+					unitName = unitName.split("@")[0];
+				}
+				if(StringUtils.isNotEmpty(empName) && StringUtils.contains(empName,"@")){
+					empName = empName.split("@")[0];
+				}
+				row.createCell(0).setCellValue(topUnitName);
+				row.createCell(1).setCellValue(unitName);
+				row.createCell(2).setCellValue(empName);
+				row.createCell(3).setCellValue(attendanceDetail.getRecordDateString());
+				row.createCell(4).setCellValue(attendanceDetail.getDescription());
+				row.createCell(5).setCellValue(attendanceDetail.getOnDutyTime());
+				row.createCell(6).setCellValue(attendanceDetail.getMorningOffDutyTime());
+				row.createCell(7).setCellValue(attendanceDetail.getAfternoonOnDutyTime());
+				row.createCell(8).setCellValue(attendanceDetail.getOffDutyTime());
+
+				if(attendanceDetail.getIsGetSelfHolidays()){
+					row.createCell(9).setCellValue("请假或外出报备");
+				}else if (attendanceDetail.getIsAbsent()) {
+					row.createCell(9).setCellValue("缺勤");
+				} else if (attendanceDetail.getIsLackOfTime()) {
+					row.createCell(9).setCellValue("工时不足");
+				} else if (attendanceDetail.getIsAbnormalDuty()) {
+					row.createCell(9).setCellValue("异常打卡");
+				}else if(attendanceDetail.getIsLeaveEarlier()){
+					row.createCell(9).setCellValue("早退");
+				} else if (attendanceDetail.getIsLate()) {
+					row.createCell(9).setCellValue("迟到");
+				} else {
+					row.createCell(9).setCellValue("正常");
+				}
+
+				switch(attendanceDetail.getAppealStatus()){
+					case 1 :
+						row.createCell(10).setCellValue("申诉中");
+						break;
+					case -1 :
+						row.createCell(10).setCellValue("申诉未通过");
+						break;
+					case 9 :
+						row.createCell(10).setCellValue("申诉通过");
+						break;
+					default :
+						row.createCell(10).setCellValue("未申诉");
+				}
+			}
+		}
+		return wb;
+	}
+
+	/**
+	 * 获取不需要考勤的组织
+	 * @return
+	 * @throws Exception
+	 */
+	protected  List<String> getUnUnitNameList() throws Exception {
+		List<String> unUnitNameList = new ArrayList<String>();
+
+		List<AttendanceEmployeeConfig> attendanceEmployeeConfigs = attendanceEmployeeConfigServiceAdv.listByConfigType("NOTREQUIRED");
+
+		if(ListTools.isNotEmpty(attendanceEmployeeConfigs)){
+			for (AttendanceEmployeeConfig attendanceEmployeeConfig : attendanceEmployeeConfigs) {
+				String unitName = attendanceEmployeeConfig.getUnitName();
+				String employeeName = attendanceEmployeeConfig.getEmployeeName();
+
+				if(StringUtils.isEmpty(employeeName) && StringUtils.isNotEmpty(unitName)){
+					unUnitNameList.add(unitName);
+					List<String> tempUnitNameList = userManagerService.listSubUnitNameWithParent(unitName);
+					if(ListTools.isNotEmpty(tempUnitNameList)){
+						for(String tempUnit:tempUnitNameList){
+							if(!ListTools.contains(unUnitNameList, tempUnit)){
+								unUnitNameList.add(tempUnit);
+							}
+						}
+					}
+				}
+			}
+		}
+		return unUnitNameList;
+	}
+
+	/**
+	 * 获取不需要考勤的人员
+	 * @return
+	 * @throws Exception
+	 */
+	protected  List<String> getUnPersonNameList() throws Exception {
+		List<String> personNameList = new ArrayList<String>();
+		List<AttendanceEmployeeConfig> attendanceEmployeeConfigs = attendanceEmployeeConfigServiceAdv.listByConfigType("NOTREQUIRED");
+
+		if(ListTools.isNotEmpty(attendanceEmployeeConfigs)){
+			for (AttendanceEmployeeConfig attendanceEmployeeConfig : attendanceEmployeeConfigs) {
+				String employeeName = attendanceEmployeeConfig.getEmployeeName();
+
+				if(StringUtils.isNotEmpty(employeeName) && !ListTools.contains(personNameList, employeeName)){
+					personNameList.add(employeeName);
+				}
+			}
+		}
+		return personNameList;
+	}
+
+	public static class Wo extends WoFile {
+		public Wo(byte[] bytes, String contentType, String contentDisposition) {
+			super(bytes, contentType, contentDisposition);
+		}
+	}
+
+}

+ 2 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attachment/BaseAction.java

@@ -2,10 +2,12 @@ package com.x.attendance.assemble.control.jaxrs.attachment;
 
 
 import com.x.attendance.assemble.common.date.DateOperation;
 import com.x.attendance.assemble.common.date.DateOperation;
 import com.x.attendance.assemble.control.service.AttendanceImportFileInfoServiceAdv;
 import com.x.attendance.assemble.control.service.AttendanceImportFileInfoServiceAdv;
+import com.x.attendance.assemble.control.service.AttendanceScheduleSettingServiceAdv;
 import com.x.base.core.project.jaxrs.StandardJaxrsAction;
 import com.x.base.core.project.jaxrs.StandardJaxrsAction;
 
 
 public class BaseAction extends StandardJaxrsAction {
 public class BaseAction extends StandardJaxrsAction {
 	protected AttendanceImportFileInfoServiceAdv importFileInfoServiceAdv = new AttendanceImportFileInfoServiceAdv();
 	protected AttendanceImportFileInfoServiceAdv importFileInfoServiceAdv = new AttendanceImportFileInfoServiceAdv();
+	protected AttendanceScheduleSettingServiceAdv attendanceScheduleSettingServiceAdv = new AttendanceScheduleSettingServiceAdv();
 	protected DateOperation dateOperation = new DateOperation();
 	protected DateOperation dateOperation = new DateOperation();
 }
 }
 
 

+ 16 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attachment/ExceptionAttendanceDetailProcess.java

@@ -0,0 +1,16 @@
+package com.x.attendance.assemble.control.jaxrs.attachment;
+
+import com.x.base.core.project.exception.PromptException;
+
+class ExceptionAttendanceDetailProcess extends PromptException {
+
+	private static final long serialVersionUID = 1859164370743532895L;
+
+	public ExceptionAttendanceDetailProcess(Throwable e, String message ) {
+		super("用户在进行考勤打卡数据信息处理时发生异常!message:" + message, e );
+	}
+	
+	public ExceptionAttendanceDetailProcess(String message ) {
+		super("用户在进行考勤打卡数据信息处理时发生异常!message:" + message );
+	}
+}

+ 30 - 6
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attachment/FileImportExportAction.java

@@ -1,17 +1,13 @@
 package com.x.attendance.assemble.control.jaxrs.attachment;
 package com.x.attendance.assemble.control.jaxrs.attachment;
 
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
+import javax.ws.rs.*;
 import javax.ws.rs.container.AsyncResponse;
 import javax.ws.rs.container.AsyncResponse;
 import javax.ws.rs.container.Suspended;
 import javax.ws.rs.container.Suspended;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MediaType;
 
 
+import com.google.gson.JsonElement;
 import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
 import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
 import org.glassfish.jersey.media.multipart.FormDataParam;
 import org.glassfish.jersey.media.multipart.FormDataParam;
 
 
@@ -27,6 +23,8 @@ import com.x.base.core.project.jaxrs.StandardJaxrsAction;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.logger.LoggerFactory;
 
 
+import java.util.List;
+
 @Path("file")
 @Path("file")
 @JaxrsDescribe("附件操作")
 @JaxrsDescribe("附件操作")
 public class FileImportExportAction extends StandardJaxrsAction {
 public class FileImportExportAction extends StandardJaxrsAction {
@@ -111,4 +109,30 @@ public class FileImportExportAction extends StandardJaxrsAction {
 		}
 		}
 		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
 		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
 	}
 	}
+
+	@JaxrsMethodDescribe(value = "导出符合过滤条件的打卡记录明细", action = ActionExportDetailWithFilter.class)
+	@GET
+	@Path("export/filter/{q_topUnitName}/{q_unitName}/{q_empName}/{cycleYear}/{cycleMonth}/{q_date}/{isAbsent}/{isLackOfTime}/{isLate}/stream/{stream}")
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void detailsExportStream(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+									@JaxrsParameterDescribe("公司,为空时输入0") @PathParam("q_topUnitName") String q_topUnitName,
+									@JaxrsParameterDescribe("部门,为空时输入0") @PathParam("q_unitName") String q_unitName,
+									@JaxrsParameterDescribe("员工,为空时输入0") @PathParam("q_empName") String q_empName,
+									@JaxrsParameterDescribe("统计周期年份,为空时输入0") @PathParam("cycleYear") String cycleYear,
+									@JaxrsParameterDescribe("统计周期月份,为空时输入0") @PathParam("cycleMonth") String cycleMonth,
+									@JaxrsParameterDescribe("统计具体日期,为空时输入0") @PathParam("q_date") String q_date,
+									@JaxrsParameterDescribe("是否缺勤,为空时输入0") @PathParam("isAbsent") String isAbsent,
+									@JaxrsParameterDescribe("是否工时不足,为空时输入0") @PathParam("isLackOfTime") String isLackOfTime,
+									@JaxrsParameterDescribe("是否迟到,为空时输入0") @PathParam("isLate") String isLate,
+								   @JaxrsParameterDescribe("用.APPLICATION_OCTET_STREAM头输出") @PathParam("stream") Boolean stream) {
+		ActionResult<ActionExportDetailWithFilter.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionExportDetailWithFilter().execute(request, effectivePerson, q_topUnitName, q_unitName,q_empName,cycleYear,cycleMonth,q_date,isAbsent,isLackOfTime,isLate, stream);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
 }
 }

+ 60 - 3
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/selfholiday/ActionListNextWithFilter.java

@@ -1,10 +1,12 @@
 package com.x.attendance.assemble.control.jaxrs.selfholiday;
 package com.x.attendance.assemble.control.jaxrs.selfholiday;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 import java.util.List;
 
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
 
 
+import com.x.attendance.assemble.common.date.DateOperation;
 import org.apache.commons.beanutils.PropertyUtils;
 import org.apache.commons.beanutils.PropertyUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 
 
@@ -26,7 +28,7 @@ import com.x.base.core.project.logger.LoggerFactory;
 public class ActionListNextWithFilter extends BaseAction {
 public class ActionListNextWithFilter extends BaseAction {
 	
 	
 	private static  Logger logger = LoggerFactory.getLogger( ActionListNextWithFilter.class );
 	private static  Logger logger = LoggerFactory.getLogger( ActionListNextWithFilter.class );
-	
+	protected DateOperation dateOperation = new DateOperation();
 	protected ActionResult<List<Wo>> execute( HttpServletRequest request, EffectivePerson effectivePerson, String id, Integer count, JsonElement jsonElement ) throws Exception {
 	protected ActionResult<List<Wo>> execute( HttpServletRequest request, EffectivePerson effectivePerson, String id, Integer count, JsonElement jsonElement ) throws Exception {
 		ActionResult<List<Wo>> result = new ActionResult<>();
 		ActionResult<List<Wo>> result = new ActionResult<>();
 		List<Wo> wraps = new ArrayList<>();
 		List<Wo> wraps = new ArrayList<>();
@@ -36,11 +38,29 @@ public class ActionListNextWithFilter extends BaseAction {
 		List<String> topUnitNames = new ArrayList<String>();
 		List<String> topUnitNames = new ArrayList<String>();
 		List<String> unitNames = new ArrayList<String>();
 		List<String> unitNames = new ArrayList<String>();
 		List<String> unitNameList = null;
 		List<String> unitNameList = null;
-		WrapInFilter wrapIn = null;
+		WrapIn wrapIn = null;
 		Boolean check = true;
 		Boolean check = true;
+		Date startDate = null;
+		Date endDate = null;
 		
 		
 		try {
 		try {
-			wrapIn = this.convertToWrapIn( jsonElement, WrapInFilter.class );
+			wrapIn = this.convertToWrapIn( jsonElement, WrapIn.class );
+			startDate = dateOperation.getDateFromString( wrapIn.getStartdateString() + " 00:00:00");
+			endDate = dateOperation.getDateFromString( wrapIn.getEnddateString() + " 23:59:59");
+
+			if( endDate == null ){
+				endDate = dateOperation.getLastDateInMonth( new Date() );
+			}
+
+			if( startDate == null ){
+				startDate = dateOperation.getFirstDateInMonth( new Date() );
+			}
+
+			if( startDate.after( endDate ) ){
+				startDate = dateOperation.getFirstDateInMonth( new Date() );
+			}
+			wrapIn.setStartdate(startDate);
+			wrapIn.setEnddate(endDate);
 		} catch (Exception e ) {
 		} catch (Exception e ) {
 			check = false;
 			check = false;
 			Exception exception = new ExceptionWrapInConvert( e, jsonElement );
 			Exception exception = new ExceptionWrapInConvert( e, jsonElement );
@@ -116,7 +136,44 @@ public class ActionListNextWithFilter extends BaseAction {
 		result.setData(wraps);
 		result.setData(wraps);
 		return result;
 		return result;
 	}
 	}
+	public static class WrapIn extends WrapInFilter{
+		String startdateString;
+		String enddateString;
+		Date startdate = null;
+		Date enddate = null;
+
+		public String getStartdateString() {
+			return startdateString;
+		}
 
 
+		public void setStartdateString(String startdateString) {
+			this.startdateString = startdateString;
+		}
+
+		public String getEnddateString() {
+			return enddateString;
+		}
+
+		public void setEnddateString(String enddateString) {
+			this.enddateString = enddateString;
+		}
+
+		public Date getStartdate() {
+			return startdate;
+		}
+
+		public void setStartdate(Date startdate) {
+			this.startdate = startdate;
+		}
+
+		public Date getEnddate() {
+			return enddate;
+		}
+
+		public void setEnddate(Date enddate) {
+			this.enddate = enddate;
+		}
+	}
 	public static class Wo extends AttendanceSelfHoliday  {
 	public static class Wo extends AttendanceSelfHoliday  {
 		
 		
 		private static final long serialVersionUID = -5076990764713538973L;
 		private static final long serialVersionUID = -5076990764713538973L;

+ 6 - 6
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailAnalyseSignProxy2.java

@@ -169,8 +169,8 @@ class AttendanceDetailAnalyseSignProxy2 {
 				if( middleDutyTime == null){
 				if( middleDutyTime == null){
 					if ( isSelfHoliday_Afternoon || isSelfHoliday_Afternoon || isNotWorkDay ) {
 					if ( isSelfHoliday_Afternoon || isSelfHoliday_Afternoon || isNotWorkDay ) {
 						logger.debug(debugger, "请假不计考勤,不算出勤");
 						logger.debug(debugger, "请假不计考勤,不算出勤");
-						detail.setIsAbsent(false);
-						detail.setAbsence(0.0);
+						/*detail.setIsAbsent(false);
+						detail.setAbsence(0.0);*/
 					} else {
 					} else {
 						logger.debug(debugger, "没请假,中午缺卡");
 						logger.debug(debugger, "没请假,中午缺卡");
 						if( StringUtils.equals( "上午", detail.getAbnormalDutyDayTime()) ){
 						if( StringUtils.equals( "上午", detail.getAbnormalDutyDayTime()) ){
@@ -185,8 +185,8 @@ class AttendanceDetailAnalyseSignProxy2 {
 					if(middleDutyTime.before( morningEndTime )){
 					if(middleDutyTime.before( morningEndTime )){
 						if(isSelfHoliday_Morning || isSelfHoliday_Afternoon || isNotWorkDay){
 						if(isSelfHoliday_Morning || isSelfHoliday_Afternoon || isNotWorkDay){
 							logger.debug( debugger, "请假、休息天不计考勤,不算出勤,不算早退" );
 							logger.debug( debugger, "请假、休息天不计考勤,不算出勤,不算早退" );
-							detail.setLeaveEarlierTimeDuration( 0L );
-							detail.setIsLeaveEarlier( false );
+							/*detail.setLeaveEarlierTimeDuration( 0L );
+							detail.setIsLeaveEarlier( false );*/
 						}else{
 						}else{
 							minutes = dateOperation.getMinutes( middleDutyTime, morningEndTime );//计算早退时长
 							minutes = dateOperation.getMinutes( middleDutyTime, morningEndTime );//计算早退时长
 							detail.setLeaveEarlierTimeDuration(minutes); //早退时长
 							detail.setLeaveEarlierTimeDuration(minutes); //早退时长
@@ -197,8 +197,8 @@ class AttendanceDetailAnalyseSignProxy2 {
 					if(middleDutyTime.after( afternoonStartTime )){
 					if(middleDutyTime.after( afternoonStartTime )){
 						if( isSelfHoliday_Morning || isSelfHoliday_Afternoon || isNotWorkDay ){
 						if( isSelfHoliday_Morning || isSelfHoliday_Afternoon || isNotWorkDay ){
 							logger.debug( debugger, "请过假了不算迟到" );
 							logger.debug( debugger, "请过假了不算迟到" );
-							detail.setLateTimeDuration( 0L ); //请假了不算迟到
-							detail.setIsLate( false );//请假了不算迟到
+							/*detail.setLateTimeDuration( 0L ); //请假了不算迟到
+							detail.setIsLate( false );//请假了不算迟到*/
 						}else{
 						}else{
 							//迟到计算从上班时间开始计算,不是迟到起算时间
 							//迟到计算从上班时间开始计算,不是迟到起算时间
 							minutes = dateOperation.getMinutes( afternoonStartTime, middleDutyTime );
 							minutes = dateOperation.getMinutes( afternoonStartTime, middleDutyTime );

+ 119 - 62
o2server/x_processplatform_assemble_designer/src/main/java/com/x/processplatform/assemble/designer/ProjectionExecuteQueue.java

@@ -1,7 +1,11 @@
 package com.x.processplatform.assemble.designer;
 package com.x.processplatform.assemble.designer;
 
 
 import java.util.List;
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
 
 
+import com.x.base.core.project.tools.ListTools;
+import org.apache.commons.collections4.list.TreeList;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.BooleanUtils;
 
 
 import com.google.gson.JsonElement;
 import com.google.gson.JsonElement;
@@ -37,96 +41,150 @@ public class ProjectionExecuteQueue extends AbstractQueue<String> {
 
 
 	@Override
 	@Override
 	protected void execute(String id) throws Exception {
 	protected void execute(String id) throws Exception {
+		logger.print("开始执行流程数据映射process:{}", id);
+		Process process = null;
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
-			Business business = new Business(emc);
-			Process process = emc.find(id, Process.class);
+			process = emc.find(id, Process.class);
 			if (null == process) {
 			if (null == process) {
 				throw new ExceptionEntityNotExist(id, Process.class);
 				throw new ExceptionEntityNotExist(id, Process.class);
 			}
 			}
-			if (XGsonBuilder.isJsonArray(process.getProjection())) {
-				List<Projection> projections = XGsonBuilder.instance().fromJson(process.getProjection(),
-						new TypeToken<List<Projection>>() {
-						}.getType());
-				this.work(business, process, projections);
-				this.workCompleted(business, process, projections);
+		} catch (Exception e) {
+			logger.error(e);
+		}
+		try {
+			if(process!=null) {
+				if (XGsonBuilder.isJsonArray(process.getProjection())) {
+					List<Projection> projections = XGsonBuilder.instance().fromJson(process.getProjection(),
+							new TypeToken<List<Projection>>() {
+							}.getType());
+					logger.print("开始执行流转中工作数据映射process:{}", id);
+					this.work(process, projections);
+					logger.print("开始执行已完成工作数据映射process:{}", id);
+					this.workCompleted(process, projections);
+				}
 			}
 			}
 		} catch (Exception e) {
 		} catch (Exception e) {
 			logger.error(e);
 			logger.error(e);
 		}
 		}
+
+		logger.print("完成流程数据映射process:{}", id);
 	}
 	}
 
 
-	private void work(Business business, Process process, List<Projection> projections) throws Exception {
-		String sequence = "";
-		List<Work> os;
-		do {
-			os = business.entityManagerContainer().listEqualAndSequenceAfter(Work.class, Work.process_FIELDNAME,
-					process.getId(), 100, sequence);
-			if (!os.isEmpty()) {
-				sequence = workProjection(business, projections, sequence, os);
-			}
-		} while (!os.isEmpty());
+	private void work(Process process, final List<Projection> projections) throws Exception {
+		List<String> jobList;
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			Business business = new Business(emc);
+			jobList = business.work().listJobWithProcess(process.getId());
+		}
+		if(ListTools.isNotEmpty(jobList)){
+			logger.print("流转中工作需要执行数据映射个数:{}",jobList.size());
+			for (List<String> partJobs : ListTools.batch(jobList, 10)){
+				List<CompletableFuture<Void>> futures = new TreeList<>();
+				for (String job : partJobs){
+					CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
+						try {
+							this.workProjection(job, process.getId(), projections);
+						} catch (Exception e) {
+							logger.warn("流程{}的工作job={}数据映射异常:{}",process.getId(),job,e.getMessage());
+							logger.error(e);
+						}
+					});
+					futures.add(future);
+				}
+				for (CompletableFuture<Void> future : futures) {
+					try {
+						future.get(300, TimeUnit.SECONDS);
+					} catch (Exception e) {
+						logger.warn("允许流程数据映射任务异常:{}",e.getMessage());
+					}
+				}
+				futures.clear();
+			}
+		}
 	}
 	}
 
 
-	private String workProjection(Business business, List<Projection> projections, String sequence, List<Work> os)
-			throws Exception {
-		business.entityManagerContainer().beginTransaction(Work.class);
-		business.entityManagerContainer().beginTransaction(Task.class);
-		business.entityManagerContainer().beginTransaction(TaskCompleted.class);
-		business.entityManagerContainer().beginTransaction(Read.class);
-		business.entityManagerContainer().beginTransaction(ReadCompleted.class);
-		business.entityManagerContainer().beginTransaction(Review.class);
-		for (Work o : os) {
-			sequence = o.getSequence();
-			Data data = this.data(business, o);
-			ProjectionFactory.projectionWork(projections, data, o);
+	private void workProjection(String job, String process, List<Projection> projections) throws Exception{
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			Business business = new Business(emc);
+			Data data = this.data(business, job);
+			emc.beginTransaction(Work.class);
+			emc.beginTransaction(Task.class);
+			emc.beginTransaction(TaskCompleted.class);
+			emc.beginTransaction(Read.class);
+			emc.beginTransaction(ReadCompleted.class);
+			emc.beginTransaction(Review.class);
+			for (Work work : business.entityManagerContainer().listEqualAndEqual(Work.class, Work.job_FIELDNAME,
+					job, Work.process_FIELDNAME, process)) {
+				ProjectionFactory.projectionWork(projections, data, work);
+			}
 			for (Task task : business.entityManagerContainer().listEqualAndEqual(Task.class, Task.job_FIELDNAME,
 			for (Task task : business.entityManagerContainer().listEqualAndEqual(Task.class, Task.job_FIELDNAME,
-					o.getJob(), Task.process_FIELDNAME, o.getProcess())) {
+					job, Task.process_FIELDNAME, process)) {
 				ProjectionFactory.projectionTask(projections, data, task);
 				ProjectionFactory.projectionTask(projections, data, task);
 			}
 			}
 			for (TaskCompleted taskCompleted : business.entityManagerContainer().listEqualAndEqual(TaskCompleted.class,
 			for (TaskCompleted taskCompleted : business.entityManagerContainer().listEqualAndEqual(TaskCompleted.class,
-					TaskCompleted.job_FIELDNAME, o.getJob(), TaskCompleted.process_FIELDNAME, o.getProcess())) {
+					TaskCompleted.job_FIELDNAME, job, TaskCompleted.process_FIELDNAME, process)) {
 				ProjectionFactory.projectionTaskCompleted(projections, data, taskCompleted);
 				ProjectionFactory.projectionTaskCompleted(projections, data, taskCompleted);
 			}
 			}
 			for (Read read : business.entityManagerContainer().listEqualAndEqual(Read.class, Read.job_FIELDNAME,
 			for (Read read : business.entityManagerContainer().listEqualAndEqual(Read.class, Read.job_FIELDNAME,
-					o.getJob(), Read.process_FIELDNAME, o.getProcess())) {
+					job, Read.process_FIELDNAME, process)) {
 				ProjectionFactory.projectionRead(projections, data, read);
 				ProjectionFactory.projectionRead(projections, data, read);
 			}
 			}
 			for (ReadCompleted readCompleted : business.entityManagerContainer().listEqualAndEqual(ReadCompleted.class,
 			for (ReadCompleted readCompleted : business.entityManagerContainer().listEqualAndEqual(ReadCompleted.class,
-					ReadCompleted.job_FIELDNAME, o.getJob(), ReadCompleted.process_FIELDNAME, o.getProcess())) {
+					ReadCompleted.job_FIELDNAME, job, ReadCompleted.process_FIELDNAME, process)) {
 				ProjectionFactory.projectionReadCompleted(projections, data, readCompleted);
 				ProjectionFactory.projectionReadCompleted(projections, data, readCompleted);
 			}
 			}
 			for (Review review : business.entityManagerContainer().listEqualAndEqual(Review.class, Review.job_FIELDNAME,
 			for (Review review : business.entityManagerContainer().listEqualAndEqual(Review.class, Review.job_FIELDNAME,
-					o.getJob(), Review.process_FIELDNAME, o.getProcess())) {
+					job, Review.process_FIELDNAME, process)) {
 				ProjectionFactory.projectionReview(projections, data, review);
 				ProjectionFactory.projectionReview(projections, data, review);
 			}
 			}
+			emc.commit();
 		}
 		}
-		business.entityManagerContainer().commit();
-		return sequence;
 	}
 	}
 
 
-	private void workCompleted(Business business, Process process, List<Projection> projections) throws Exception {
-		String sequence = "";
-		List<WorkCompleted> os;
-		do {
-			os = business.entityManagerContainer().listEqualAndSequenceAfter(WorkCompleted.class,
-					WorkCompleted.process_FIELDNAME, process.getId(), 100, sequence);
-			if (!os.isEmpty()) {
-				sequence = workCompletedProjection(business, projections, sequence, os);
-			}
-		} while (!os.isEmpty());
+	private void workCompleted(Process process, final List<Projection> projections) throws Exception {
+		List<String> workComList;
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			Business business = new Business(emc);
+			workComList = business.workCompleted().listWithProcess(process.getId());
+		}
+		if(ListTools.isNotEmpty(workComList)){
+			logger.print("已完成工作需要执行数据映射个数:{}",workComList.size());
+			for (List<String> partWorkComList : ListTools.batch(workComList, 10)){
+				List<CompletableFuture<Void>> futures = new TreeList<>();
+				for (String workCompletedId : partWorkComList){
+					CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
+						try {
+							this.workCompletedProjection(workCompletedId, projections);
+						} catch (Exception e) {
+							logger.warn("流程{}的工作workCompletedId={}数据映射异常:{}",process.getId(),workCompletedId,e.getMessage());
+							logger.error(e);
+						}
+					});
+					futures.add(future);
+				}
+				for (CompletableFuture<Void> future : futures) {
+					try {
+						future.get(300, TimeUnit.SECONDS);
+					} catch (Exception e) {
+						logger.warn("允许流程数据映射任务异常:{}",e.getMessage());
+					}
+				}
+				futures.clear();
+			}
+		}
 	}
 	}
 
 
-	private String workCompletedProjection(Business business, List<Projection> projections, String sequence,
-			List<WorkCompleted> os) throws Exception {
-		business.entityManagerContainer().beginTransaction(WorkCompleted.class);
-		business.entityManagerContainer().beginTransaction(Task.class);
-		business.entityManagerContainer().beginTransaction(TaskCompleted.class);
-		business.entityManagerContainer().beginTransaction(Read.class);
-		business.entityManagerContainer().beginTransaction(ReadCompleted.class);
-		business.entityManagerContainer().beginTransaction(Review.class);
-		for (WorkCompleted o : os) {
-			sequence = o.getSequence();
+	private void workCompletedProjection(String workCompletedId, List<Projection> projections) throws Exception{
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			Business business = new Business(emc);
+			WorkCompleted o = emc.find(workCompletedId, WorkCompleted.class);
 			Data data = this.data(business, o);
 			Data data = this.data(business, o);
+			emc.beginTransaction(WorkCompleted.class);
+			emc.beginTransaction(Task.class);
+			emc.beginTransaction(TaskCompleted.class);
+			emc.beginTransaction(Read.class);
+			emc.beginTransaction(ReadCompleted.class);
+			emc.beginTransaction(Review.class);
 			ProjectionFactory.projectionWorkCompleted(projections, data, o);
 			ProjectionFactory.projectionWorkCompleted(projections, data, o);
 			for (Task task : business.entityManagerContainer().listEqualAndEqual(Task.class, Task.job_FIELDNAME,
 			for (Task task : business.entityManagerContainer().listEqualAndEqual(Task.class, Task.job_FIELDNAME,
 					o.getJob(), Task.process_FIELDNAME, o.getProcess())) {
 					o.getJob(), Task.process_FIELDNAME, o.getProcess())) {
@@ -148,14 +206,13 @@ public class ProjectionExecuteQueue extends AbstractQueue<String> {
 					o.getJob(), Review.process_FIELDNAME, o.getProcess())) {
 					o.getJob(), Review.process_FIELDNAME, o.getProcess())) {
 				ProjectionFactory.projectionReview(projections, data, review);
 				ProjectionFactory.projectionReview(projections, data, review);
 			}
 			}
+			emc.commit();
 		}
 		}
-		business.entityManagerContainer().commit();
-		return sequence;
 	}
 	}
 
 
-	private Data data(Business business, Work work) throws Exception {
+	private Data data(Business business, String job) throws Exception {
 		List<Item> items = business.entityManagerContainer().listEqualAndEqual(Item.class, DataItem.bundle_FIELDNAME,
 		List<Item> items = business.entityManagerContainer().listEqualAndEqual(Item.class, DataItem.bundle_FIELDNAME,
-				work.getJob(), DataItem.itemCategory_FIELDNAME, ItemCategory.pp);
+				job, DataItem.itemCategory_FIELDNAME, ItemCategory.pp);
 		if (items.isEmpty()) {
 		if (items.isEmpty()) {
 			return new Data();
 			return new Data();
 		} else {
 		} else {
@@ -187,4 +244,4 @@ public class ProjectionExecuteQueue extends AbstractQueue<String> {
 			}
 			}
 		}
 		}
 	}
 	}
-}
+}

+ 10 - 11
o2web/source/o2_core/o2.js

@@ -1315,10 +1315,18 @@ if (!window.Promise){
         r.send();
         r.send();
     };
     };
 
 
-    var _cacheUrls = [
+    var _cacheUrls = (Browser.name == "ie") ? [
+        /jaxrs\/form\/workorworkcompleted\/.+/ig,
+        /jaxrs\/form\/.+/ig,
+        /jaxrs\/script\/.+\/app\/.+\/imported/ig,
+        /jaxrs\/script\/portal\/.+\/name\/.+\/imported/ig,
+        /jaxrs\/script\/.+\/application\/.+\/imported/ig,
+        /jaxrs\/page\/.+\/portal\/.+/ig,
+        /jaxrs\/document\/.+/ig,
+        /jaxrs\/custom\/.+/ig
+    ]:[
         /jaxrs\/form\/workorworkcompleted\/.+/ig,
         /jaxrs\/form\/workorworkcompleted\/.+/ig,
         /jaxrs\/form\/.+/ig,
         /jaxrs\/form\/.+/ig,
-        //    /jaxrs\/script/ig,
         /jaxrs\/script\/.+\/app\/.+\/imported/ig,
         /jaxrs\/script\/.+\/app\/.+\/imported/ig,
         /jaxrs\/script\/portal\/.+\/name\/.+\/imported/ig,
         /jaxrs\/script\/portal\/.+\/name\/.+\/imported/ig,
         /jaxrs\/script\/.+\/application\/.+\/imported/ig,
         /jaxrs\/script\/.+\/application\/.+\/imported/ig,
@@ -1328,15 +1336,6 @@ if (!window.Promise){
         /jaxrs\/custom\/.+/ig,
         /jaxrs\/custom\/.+/ig,
         /jaxrs\/definition\/idea.+/ig,
         /jaxrs\/definition\/idea.+/ig,
         /jaxrs\/distribute\/assemble\/source\/.+/ig,
         /jaxrs\/distribute\/assemble\/source\/.+/ig,
-
-        ///jaxrs\/form\/workorworkcompleted\/.+/ig,
-        //    /jaxrs\/script/ig,
-        // /jaxrs\/script\/.+\/app\/.+\/imported/ig,
-        // /jaxrs\/script\/portal\/.+\/name\/.+\/imported/ig,
-        // /jaxrs\/script\/.+\/application\/.+\/imported/ig,
-        // /jaxrs\/page\/.+\/portal\/.+/ig
-        // /jaxrs\/authentication/ig
-        // /jaxrs\/statement\/.*\/execute\/page\/.*\/size\/.*/ig
     ];
     ];
     // _restful_bak = function(method, address, data, callback, async, withCredentials, cache){
     // _restful_bak = function(method, address, data, callback, async, withCredentials, cache){
     //     var loadAsync = (async !== false);
     //     var loadAsync = (async !== false);

+ 25 - 7
o2web/source/o2_core/o2/xAction/services/x_attendance_assemble_control.js

@@ -3,9 +3,9 @@ MWF.xAction.RestActions.Action["x_attendance_assemble_control"] = new Class({
     getUUID: function(success){
     getUUID: function(success){
         var id = "";
         var id = "";
         this.action.invoke({"name": "getId","async": false, "parameter": {"count": "1"}, "success": function(ids){
         this.action.invoke({"name": "getId","async": false, "parameter": {"count": "1"}, "success": function(ids){
-            id = ids.data[0];
-            if (success) success(id);
-        },	"failure": null});
+                id = ids.data[0];
+                if (success) success(id);
+            },	"failure": null});
         return id;
         return id;
     },
     },
     exportSelfHoliday: function(startdate, enddate, success, failure){
     exportSelfHoliday: function(startdate, enddate, success, failure){
@@ -13,7 +13,7 @@ MWF.xAction.RestActions.Action["x_attendance_assemble_control"] = new Class({
             var url = this.action.actions.exportSelfHoliday.uri;
             var url = this.action.actions.exportSelfHoliday.uri;
             url = url.replace("{startdate}", startdate);
             url = url.replace("{startdate}", startdate);
             url = url.replace("{enddate}", enddate);
             url = url.replace("{enddate}", enddate);
-            window.open(o2.filterUrl(this.action.address+url , "_blank"));
+            window.open(this.action.address+url , "_blank");
         }.bind(this));
         }.bind(this));
     },
     },
     uploadAttachment: function(success, failure, formData, file){
     uploadAttachment: function(success, failure, formData, file){
@@ -23,18 +23,36 @@ MWF.xAction.RestActions.Action["x_attendance_assemble_control"] = new Class({
         this.action.getActions(function(){
         this.action.getActions(function(){
             var url = this.action.actions.getAttachmentStream.uri;
             var url = this.action.actions.getAttachmentStream.uri;
             url = url.replace("{id}", encodeURIComponent(id));
             url = url.replace("{id}", encodeURIComponent(id));
-            window.open(o2.filterUrl(this.action.address+url));
+            window.open(this.action.address+url);
         }.bind(this));
         }.bind(this));
     },
     },
-    exportAbnormalAttachment: function(year, month, success, failure){
+    exportAbnormalAttachment: function(year, month, stream){
         this.action.getActions(function(){
         this.action.getActions(function(){
             var url = this.action.actions.exportAbnormalAttachment.uri;
             var url = this.action.actions.exportAbnormalAttachment.uri;
             url = url.replace("{year}", year);
             url = url.replace("{year}", year);
             url = url.replace("{month}", month);
             url = url.replace("{month}", month);
-            window.open(o2.filterUrl(this.action.address+url , "_blank"));
+            url = url.replace("{stream}", stream);
+            window.open(this.action.address+url , "_blank");
         }.bind(this));
         }.bind(this));
         //this.action.invoke({"name": "exportAbnormalAttachment", "parameter": {"year": year, "month": month },"success": success,"failure": failure});
         //this.action.invoke({"name": "exportAbnormalAttachment", "parameter": {"year": year, "month": month },"success": success,"failure": failure});
     },
     },
+    //统计导出
+    detailsExportStream: function(q_topUnitName, q_unitName,q_empName,cycleYear,cycleMonth,q_date,isAbsent,isLackOfTime,isLate, stream){
+        this.action.getActions(function(){
+            var url = this.action.actions.detailsExportStream.uri;
+            url = url.replace("{q_topUnitName}", q_topUnitName);
+            url = url.replace("{q_unitName}", q_unitName);
+            url = url.replace("{q_empName}", q_empName);
+            url = url.replace("{cycleYear}", cycleYear);
+            url = url.replace("{cycleMonth}", cycleMonth);
+            url = url.replace("{q_date}", q_date);
+            url = url.replace("{isAbsent}", isAbsent);
+            url = url.replace("{isLackOfTime}", isLackOfTime);
+            url = url.replace("{isLate}", isLate);
+            url = url.replace("{stream}", stream);
+            window.open(this.action.address+url , "_blank");
+        }.bind(this));
+    },
     listHolidayByYearAndName: function(year,name,success, failure, async){
     listHolidayByYearAndName: function(year,name,success, failure, async){
         this.action.invoke({"name": "listHolidayFilter","data": {"q_Year": year, "q_Name" : name },"async": async, "success": success,	"failure": failure});
         this.action.invoke({"name": "listHolidayFilter","data": {"q_Year": year, "q_Name" : name },"async": async, "success": success,	"failure": failure});
     },
     },

+ 6 - 3
o2web/source/o2_core/o2/xAction/services/x_attendance_assemble_control.json

@@ -44,13 +44,13 @@
   "listAttachmentInfo" : {"uri" : "/jaxrs/attendanceimportfileinfo/list/all"},
   "listAttachmentInfo" : {"uri" : "/jaxrs/attendanceimportfileinfo/list/all"},
   "deleteAttachment" : {"uri":"/jaxrs/attendanceimportfileinfo/{id}","method": "DELETE"},
   "deleteAttachment" : {"uri":"/jaxrs/attendanceimportfileinfo/{id}","method": "DELETE"},
   "getAttachmentInfo" : {"uri":"/jaxrs/attendanceimportfileinfo/{id}"},
   "getAttachmentInfo" : {"uri":"/jaxrs/attendanceimportfileinfo/{id}"},
-//  "importAttachment" : {"uri":"/jaxrs/fileimport/import/{file_id}"},
-//  "checkAttachment" : {"uri":"/jaxrs/fileimport/check/{file_id}"},
+  //  "importAttachment" : {"uri":"/jaxrs/fileimport/import/{file_id}"},
+  //  "checkAttachment" : {"uri":"/jaxrs/fileimport/check/{file_id}"},
   "getImportStatus" : {"uri":"/jaxrs/fileimport/getStatus/{file_id}"},
   "getImportStatus" : {"uri":"/jaxrs/fileimport/getStatus/{file_id}"},
   "getImportStatusAll" : {"uri":"/jaxrs/fileimport/getStatus/all"},
   "getImportStatusAll" : {"uri":"/jaxrs/fileimport/getStatus/all"},
   "getImportStatusDetail" : {"uri":"/jaxrs/fileimport/getStatus/{file_id}/detail"},
   "getImportStatusDetail" : {"uri":"/jaxrs/fileimport/getStatus/{file_id}/detail"},
 
 
-  "exportAbnormalAttachment" : {"uri":"/jaxrs/file/export/abnormaldetails/year/{year}/month/{month}/stream/true", "method": "GET"},
+  "exportAbnormalAttachment" : {"uri":"/jaxrs/file/export/abnormaldetails/year/{year}/month/{month}/stream/{stream}", "method": "GET"},
 
 
   "listDetail" : {"uri":"/jaxrs/attendancedetail/list/all"},
   "listDetail" : {"uri":"/jaxrs/attendancedetail/list/all"},
   "getDetail" : {"uri":"/jaxrs/attendancedetail/{id}"},
   "getDetail" : {"uri":"/jaxrs/attendancedetail/{id}"},
@@ -176,5 +176,8 @@ URL:x_attendance_assemble_control/jaxrs/attendancedetail/filter/list/{id}/prev
   "saveWorkplace" : {"uri":"/jaxrs/workplace", "method": "POST"},
   "saveWorkplace" : {"uri":"/jaxrs/workplace", "method": "POST"},
   "deleteWorkplace" : {"uri":"/jaxrs/workplace/{id}","method": "DELETE"},
   "deleteWorkplace" : {"uri":"/jaxrs/workplace/{id}","method": "DELETE"},
 
 
+  //统计导出
+  "detailsExportStream" : {"uri" : "/jaxrs/file/export/filter/{q_topUnitName}/{q_unitName}/{q_empName}/{cycleYear}/{cycleMonth}/{q_date}/{isAbsent}/{isLackOfTime}/{isLate}/stream/{stream}", "method": "GET"},
+
   "clazz": "x_attendance_assemble_control"
   "clazz": "x_attendance_assemble_control"
 }
 }

+ 27 - 3
o2web/source/x_component_Attendance/PeopleDetail.js

@@ -10,8 +10,8 @@ MWF.xApplication.Attendance.PeopleDetail = new Class({
     initialize: function(node, app, actions, options){
     initialize: function(node, app, actions, options){
         this.setOptions(options);
         this.setOptions(options);
         this.app = app;
         this.app = app;
-        this.path = "../x_component_Attendance/$PeopleDetail/";
-        this.cssPath = "../x_component_Attendance/$PeopleDetail/"+this.options.style+"/css.wcss";
+        this.path = "/x_component_Attendance/$PeopleDetail/";
+        this.cssPath = "/x_component_Attendance/$PeopleDetail/"+this.options.style+"/css.wcss";
         this._loadCss();
         this._loadCss();
 
 
         this.actions = actions;
         this.actions = actions;
@@ -126,6 +126,7 @@ MWF.xApplication.Attendance.PeopleDetail.Explorer = new Class({
             "    <td styles='filterTableTitle' lable='isLackOfTime'></td>"+
             "    <td styles='filterTableTitle' lable='isLackOfTime'></td>"+
             "    <td styles='filterTableValue' item='isLackOfTime'></td>" +
             "    <td styles='filterTableValue' item='isLackOfTime'></td>" +
             "    <td styles='filterTableValue' item='action'></td>" +
             "    <td styles='filterTableValue' item='action'></td>" +
+            "    <td styles='filterTableValue' item='export'></td>" +
             "</tr>" +
             "</tr>" +
             "</table>";
             "</table>";
         this.fileterNode.set("html",html);
         this.fileterNode.set("html",html);
@@ -185,7 +186,30 @@ MWF.xApplication.Attendance.PeopleDetail.Explorer = new Class({
                             }
                             }
                             this.loadView( result );
                             this.loadView( result );
                         }.bind(this)
                         }.bind(this)
-                    }}
+                    }},
+                    export : { "value" : "导出", type : "button", className : "filterButton", event : {
+                            click : function(){
+                                var result = this.form.getResult(true,",",true,true,false);
+                                if( !result )return;
+                                debugger;
+                                if( !result.q_topUnitName )result.q_topUnitName = "0";
+                                if( !result.q_unitName)result.q_unitName = "0";
+                                if( !result.q_empName)result.q_empName = "0";
+                                if( !result.cycleYear )result.cycleYear = "0";
+                                if( !result.cycleMonth )result.cycleMonth = "0";
+                                if( result.date && result.date !="" ){
+                                    result.q_date =  result.cycleYear + "-" + result.cycleMonth + "-" + result.date;
+                                }else{
+                                    result.q_date ="0";
+                                }
+                                //111
+                                if( !result.isAbsent )result.isAbsent = "0";
+                                if( !result.isLackOfTime  )result.isLackOfTime = "0";
+                                if( !result.isLate )result.isLate = "0";
+                                debugger;
+                                this.actions.detailsExportStream(result.q_topUnitName,result.q_unitName,result.q_empName,result.cycleYear,result.cycleMonth,result.q_date,result.isAbsent,result.isLackOfTime,result.isLate,true);
+                            }.bind(this)
+                        }}
                 }
                 }
             }, this.app, this.css);
             }, this.app, this.css);
             this.form.load();
             this.form.load();

+ 9 - 3
o2web/source/x_component_Attendance/SelfHoliday.js

@@ -8,8 +8,8 @@ MWF.xApplication.Attendance.SelfHoliday = new Class({
     initialize: function(node, app, actions, options){
     initialize: function(node, app, actions, options){
         this.setOptions(options);
         this.setOptions(options);
         this.app = app;
         this.app = app;
-        this.path = "../x_component_Attendance/$SelfHoliday/";
-        this.cssPath = "../x_component_Attendance/$SelfHoliday/"+this.options.style+"/css.wcss";
+        this.path = "/x_component_Attendance/$SelfHoliday/";
+        this.cssPath = "/x_component_Attendance/$SelfHoliday/"+this.options.style+"/css.wcss";
         this._loadCss();
         this._loadCss();
 
 
         this.actions = actions;
         this.actions = actions;
@@ -40,7 +40,7 @@ MWF.xApplication.Attendance.SelfHoliday = new Class({
     },
     },
     _loadFilterContent : function(){
     _loadFilterContent : function(){
         var _self = this;
         var _self = this;
-        var html = "<table bordr='0' cellpadding='5' cellspacing='0' styles='formTable' width='950'>"+
+        var html = "<table bordr='0' cellpadding='5' cellspacing='0' styles='formTable' width='1350'>"+
             "<tr>" +
             "<tr>" +
             "    <td styles='formTableTitle' lable='q_topUnitName'></td>"+
             "    <td styles='formTableTitle' lable='q_topUnitName'></td>"+
             "    <td styles='formTableValue' item='q_topUnitName'></td>"+
             "    <td styles='formTableValue' item='q_topUnitName'></td>"+
@@ -48,6 +48,10 @@ MWF.xApplication.Attendance.SelfHoliday = new Class({
             "    <td styles='formTableValue' item='q_unitName'></td>"+
             "    <td styles='formTableValue' item='q_unitName'></td>"+
             "    <td styles='formTableTitle' lable='q_empName'></td>"+
             "    <td styles='formTableTitle' lable='q_empName'></td>"+
             "    <td styles='formTableValue' item='q_empName'></td>"+
             "    <td styles='formTableValue' item='q_empName'></td>"+
+            "    <td styles='formTableTitle' lable='startdateString'></td>"+
+            "    <td styles='formTableValue' item='startdateString'></td>"+
+            "    <td styles='formTableTitle' lable='enddateString'></td>"+
+            "    <td styles='formTableValue' item='enddateString'></td>"+
             "    <td styles='formTableValue' item='action'></td>"+
             "    <td styles='formTableValue' item='action'></td>"+
             "</tr>" +
             "</tr>" +
             "</table>";
             "</table>";
@@ -61,6 +65,8 @@ MWF.xApplication.Attendance.SelfHoliday = new Class({
                     q_topUnitName : { "text" : "选择公司", "type" : "org", "orgType" : "unit", style : {"min-width" : "200px"} },
                     q_topUnitName : { "text" : "选择公司", "type" : "org", "orgType" : "unit", style : {"min-width" : "200px"} },
                     q_unitName : { "text" : "选择部门", "type" : "org", "orgType" : "unit", style : {"min-width" : "250px"} },
                     q_unitName : { "text" : "选择部门", "type" : "org", "orgType" : "unit", style : {"min-width" : "250px"} },
                     q_empName : {  "text" : "选择人员", "type" : "org", "orgType" : "person", style : {"min-width" : "100px"} },
                     q_empName : {  "text" : "选择人员", "type" : "org", "orgType" : "person", style : {"min-width" : "100px"} },
+                    startdateString : {  "text" : "开始日期", "tType" : "date",style : {"border" : "1px solid rgb(153, 153, 153)","background":'url("../x_component_Template/$MForm/default/icon/calendar.png") 98% center no-repeat',"border-radius":"3px","box-shadow":"rgb(204, 204, 204) 0px 0px 6px","height":"26px","width":"100px"} },
+                    enddateString : { "text" : "结束日期", "tType" : "date" ,style : {"border" : "1px solid rgb(153, 153, 153)","background":'url("../x_component_Template/$MForm/default/icon/calendar.png") 98% center no-repeat',"border-radius":"3px","box-shadow":"rgb(204, 204, 204) 0px 0px 6px","height":"26px","width":"100px"}},
                     action : {
                     action : {
                         "type" : "button",
                         "type" : "button",
                         "value" : "查询",
                         "value" : "查询",

+ 26 - 3
o2web/source/x_component_Attendance/TopUnitDetail.js

@@ -11,8 +11,8 @@ MWF.xApplication.Attendance.TopUnitDetail = new Class({
         this.setOptions(options);
         this.setOptions(options);
         this.app = app;
         this.app = app;
         this.lp = app.lp;
         this.lp = app.lp;
-        this.path = "../x_component_Attendance/$TopUnitDetail/";
-        this.cssPath = "../x_component_Attendance/$TopUnitDetail/"+this.options.style+"/css.wcss";
+        this.path = "/x_component_Attendance/$TopUnitDetail/";
+        this.cssPath = "/x_component_Attendance/$TopUnitDetail/"+this.options.style+"/css.wcss";
         this._loadCss();
         this._loadCss();
 
 
         this.actions = actions;
         this.actions = actions;
@@ -111,6 +111,7 @@ MWF.xApplication.Attendance.TopUnitDetail.Explorer = new Class({
             "    <td styles='filterTableTitle' lable='isLackOfTime'></td>"+
             "    <td styles='filterTableTitle' lable='isLackOfTime'></td>"+
             "    <td styles='filterTableValue' item='isLackOfTime'></td>" +
             "    <td styles='filterTableValue' item='isLackOfTime'></td>" +
             "    <td styles='filterTableValue' item='action'></td>" +
             "    <td styles='filterTableValue' item='action'></td>" +
+            "    <td styles='filterTableValue' item='export'></td>" +
             "</tr>" +
             "</tr>" +
             "</table>";
             "</table>";
         this.fileterNode.set("html",html);
         this.fileterNode.set("html",html);
@@ -170,7 +171,29 @@ MWF.xApplication.Attendance.TopUnitDetail.Explorer = new Class({
                             }
                             }
                             this.loadView( result );
                             this.loadView( result );
                         }.bind(this)
                         }.bind(this)
-                    }}
+                    }},
+                    export : { "value" : "导出", type : "button", className : "filterButton", event : {
+                            click : function(){
+                                var result = this.form.getResult(true,",",true,true,false);
+                                if( !result )return;
+                                debugger;
+                                if( !result.q_topUnitName )result.q_topUnitName = "0";
+                                if( !result.q_unitName)result.q_unitName = "0";
+                                if( !result.q_empName)result.q_empName = "0";
+                                if( !result.cycleYear )result.cycleYear = "0";
+                                if( !result.cycleMonth )result.cycleMonth = "0";
+                                if( result.date && result.date !="" ){
+                                    result.q_date =  result.cycleYear + "-" + result.cycleMonth + "-" + result.date;
+                                }else{
+                                    result.q_date ="0";
+                                }
+                                if( !result.isAbsent )result.isAbsent = "0";
+                                if( !result.isLackOfTime  )result.isLackOfTime = "0";
+                                if( !result.isLate )result.isLate = "0";
+                                debugger;
+                                this.actions.detailsExportStream(result.q_topUnitName,result.q_unitName,result.q_empName,result.cycleYear,result.cycleMonth,result.q_date,result.isAbsent,result.isLackOfTime,result.isLate,true);
+                            }.bind(this)
+                        }}
                 }
                 }
             }, this.app, this.css);
             }, this.app, this.css);
             this.form.load();
             this.form.load();

+ 26 - 3
o2web/source/x_component_Attendance/UnitDetail.js

@@ -10,8 +10,8 @@ MWF.xApplication.Attendance.UnitDetail = new Class({
     initialize: function(node, app, actions, options){
     initialize: function(node, app, actions, options){
         this.setOptions(options);
         this.setOptions(options);
         this.app = app;
         this.app = app;
-        this.path = "../x_component_Attendance/$UnitDetail/";
-        this.cssPath = "../x_component_Attendance/$UnitDetail/"+this.options.style+"/css.wcss";
+        this.path = "/x_component_Attendance/$UnitDetail/";
+        this.cssPath = "/x_component_Attendance/$UnitDetail/"+this.options.style+"/css.wcss";
         this._loadCss();
         this._loadCss();
 
 
         this.actions = actions;
         this.actions = actions;
@@ -109,6 +109,7 @@ MWF.xApplication.Attendance.UnitDetail.Explorer = new Class({
             "    <td styles='filterTableTitle' lable='isLackOfTime'></td>"+
             "    <td styles='filterTableTitle' lable='isLackOfTime'></td>"+
             "    <td styles='filterTableValue' item='isLackOfTime'></td>" +
             "    <td styles='filterTableValue' item='isLackOfTime'></td>" +
             "    <td styles='filterTableValue' item='action'></td>" +
             "    <td styles='filterTableValue' item='action'></td>" +
+            "    <td styles='filterTableValue' item='export'></td>" +
             "</tr>" +
             "</tr>" +
             "</table>";
             "</table>";
         this.fileterNode.set("html",html);
         this.fileterNode.set("html",html);
@@ -168,7 +169,29 @@ MWF.xApplication.Attendance.UnitDetail.Explorer = new Class({
                             }
                             }
                             this.loadView( result );
                             this.loadView( result );
                         }.bind(this)
                         }.bind(this)
-                    }}
+                    }},
+                    export : { "value" : "导出", type : "button", className : "filterButton", event : {
+                            click : function(){
+                                var result = this.form.getResult(true,",",true,true,false);
+                                if( !result )return;
+                                debugger;
+                                if( !result.q_topUnitName )result.q_topUnitName = "0";
+                                if( !result.q_unitName)result.q_unitName = "0";
+                                if( !result.q_empName)result.q_empName = "0";
+                                if( !result.cycleYear )result.cycleYear = "0";
+                                if( !result.cycleMonth )result.cycleMonth = "0";
+                                if( result.date && result.date !="" ){
+                                    result.q_date =  result.cycleYear + "-" + result.cycleMonth + "-" + result.date;
+                                }else{
+                                    result.q_date ="0";
+                                }
+                                if( !result.isAbsent )result.isAbsent = "0";
+                                if( !result.isLackOfTime  )result.isLackOfTime = "0";
+                                if( !result.isLate )result.isLate = "0";
+                                debugger;
+                                this.actions.detailsExportStream(result.q_topUnitName,result.q_unitName,result.q_empName,result.cycleYear,result.cycleMonth,result.q_date,result.isAbsent,result.isLackOfTime,result.isLate,true);
+                            }.bind(this)
+                        }}
                 }
                 }
             }, this.app, this.css);
             }, this.app, this.css);
             this.form.load();
             this.form.load();

+ 1 - 1
o2web/source/x_component_Template/MSelector.js

@@ -660,7 +660,7 @@ MSelector.Tootips = new Class({
                 var _self = this.obj;
                 var _self = this.obj;
                 var data = this.itemNode.retrieve( "data" );
                 var data = this.itemNode.retrieve( "data" );
                 _self.selector.setCurrentItem( this.itemNode );
                 _self.selector.setCurrentItem( this.itemNode );
-                _self.selector._selectItem( this.itemNode, data, ev );
+                // _self.selector._selectItem( this.itemNode, data, ev );
                 _self.selector.fireEvent("selectItem", [ this.itemNode, data, ev ] );
                 _self.selector.fireEvent("selectItem", [ this.itemNode, data, ev ] );
                 _self.hide();
                 _self.hide();
                 ev.stopPropagation();
                 ev.stopPropagation();

BIN
o2web/source/x_component_process_FormDesigner/Module/Actionbar/default/tools/xform_blue_simple/downloadAll.png