package com.yeejoin.amos.boot.module.common.biz.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.servlet.http.HttpServletRequest;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.entity.DataDictionary;
import com.yeejoin.amos.boot.biz.common.service.IDataDictionaryService;
import com.yeejoin.amos.boot.module.common.api.mapper.DynamicFormInstanceMapper;
import com.yeejoin.amos.boot.module.common.biz.enums.DataDictionaryTypeEnum;
import com.yeejoin.amos.boot.module.common.biz.enums.DynamicGroupCodeEnum;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.Bean;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Sequence;
import com.yeejoin.amos.boot.biz.common.entity.BaseEntity;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.module.common.api.dto.DutyCarDto;
import com.yeejoin.amos.boot.module.common.api.dto.DutyFireFightingDto;
import com.yeejoin.amos.boot.module.common.api.dto.DutyFirstAidDto;
import com.yeejoin.amos.boot.module.common.api.dto.DutyPersonDto;
import com.yeejoin.amos.boot.module.common.api.dto.DutyPersonShiftDto;
import com.yeejoin.amos.boot.module.common.api.dto.DutyShiftDto;
import com.yeejoin.amos.boot.module.common.api.entity.DutyPersonShift;
import com.yeejoin.amos.boot.module.common.api.entity.DutyShift;
import com.yeejoin.amos.boot.module.common.api.entity.DynamicFormColumn;
import com.yeejoin.amos.boot.module.common.api.entity.DynamicFormInstance;
import com.yeejoin.amos.boot.module.common.api.entity.OrgUsr;
import com.yeejoin.amos.boot.module.common.api.enums.DutyViewTypeEnum;
import com.yeejoin.amos.boot.module.common.api.mapper.DutyPersonShiftMapper;
import com.yeejoin.amos.boot.module.common.api.service.IDutyCommonService;

/**
 * @author DELL
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DutyCommonServiceImpl implements IDutyCommonService {

	@Autowired
	DynamicFormColumnServiceImpl dynamicFormColumnService;

	@Autowired
	DynamicFormInstanceServiceImpl dynamicFormInstanceService;

	@Autowired
	DutyPersonShiftServiceImpl dutyPersonShiftService;

	@Autowired
	Sequence sequence;

	@Autowired
	HttpServletRequest request;

	@Autowired
	DutyShiftServiceImpl dutyShiftService;

	@Autowired
	OrgUsrServiceImpl orgUsrService;
	
	@Autowired
	DutyPersonShiftMapper dutyPersonShiftMapper;

	@Autowired
	IDataDictionaryService dataDictionaryService;

	@Autowired
	DynamicFormInstanceMapper dynamicFormInstanceMapper;

	/**
	 * 每天单个班次执勤人数全部小于等于3人
	 */
	final int LIMIT_PERSON_NUMBER = 3;

	/**
	 * 班次小于等于2
	 */
	final int LIMIT_SHIFT_NUMBER = 2;

	@Override
	public IPage<Map<String, Object>> pageList(int current, int size, String beginDate, String endDate)
			throws ParseException {
		// 1.已column为准 进行返回
		String groupCode = this.getGroupCode();
		// 不存在值班数据则不查找 修改sql 方法去除 by kongfm 2021-09-14
		IPage<Map<String, Object>> iPage = dynamicFormInstanceService.pageListNew(current, size, groupCode, beginDate, endDate);
		for (Map<String, Object> m : iPage.getRecords()) {
			this.fillDutyShiftData(beginDate, endDate, m);
		}
		// 不存在值班数据则不查找 修改sql 方法去除 by kongfm 2021-09-14

		return iPage;
	}

	//120系统迁移接口 sql固定查询急救科下值班人员
	@Override
	public List<Map<String, Object>> listOnDutyPersonByAid() {
		String groupCode = this.getGroupCode();
		// 获取当前班次列表
		DateTime now = new DateTime();
		List<Long> shiftIdList = getOnDuty(now);
		String shiftIds = StringUtils.join(shiftIdList.toArray(), ",");
		String dutyDay = now.toString("yyyy-MM-dd");
		// 获取当前值班人员
		List<DynamicFormColumn> columns = dynamicFormColumnService
				.list(new LambdaQueryWrapper<DynamicFormColumn>().eq(DynamicFormColumn::getGroupCode, groupCode));
		Map<String, Object> fieldCodes = Bean.listToMap(columns, "fieldCode", "queryStrategy", DynamicFormColumn.class);
		List<Map<String, Object>> maps = dynamicFormInstanceService.getBaseMapper().listOnDutyPersonByAid(dutyDay, shiftIds,
				fieldCodes, groupCode);
		// 获取人员照片和电话
		List<Long> ids = new ArrayList<>();
		maps.forEach(item -> ids.add(Long.valueOf(String.valueOf(item.get("userId")))));
		try {
			List<Map<String, Object>> orgUsrList = orgUsrService.selectForShowByListId(ids);
			maps.forEach(item -> {
				String userId = String.valueOf(item.get("userId"));
				//此处是用来给119日常值班首页值班岗位排序用
				String sort = "";
				switch (    item.get("postType").toString() ){
					case "826" :
						sort = "4";
						break;
					case "824" :
						sort = "3";
						break;
					case "825" :
						sort = "2";
						break;
					case "827" :
						sort = "1";
						break;
				}
				item.put("postSort",sort);
				for (Map<String, Object> usr : orgUsrList) {
					if (userId.equals(String.valueOf(usr.get("sequenceNbr")))) {
						item.put("personImg", usr.get("personImg"));
						item.put("telephone", usr.get("telephone"));
						item.put("companyId", usr.get("companyId"));
						item.put("bizOrgType", usr.get("bizOrgType"));
						item.put("parentId", usr.get("parentId"));
						break;
					}
				}
			});
			maps= maps.stream().sorted((map1,map2)->{
				if (map1.get("companyId").toString().equals(map2.get("companyId").toString())){
					if (map1.get("deptId").toString().equals(map2.get("deptId").toString())){
						return map2.get("postSort").toString().compareTo(map1.get("postSort").toString());
					}else {
						return map1.get("deptId").toString().compareTo(map2.get("deptId").toString());
					}
				}else {
					return map2.get("companyId").toString().compareTo(map1.get("companyId").toString());
				}
			}).collect(Collectors.toList());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return maps;
	}


	@Override
	public IPage<Map<String, Object>> pageListDetail(int current, int size, String beginDate, String endDate, String bizOrgCode)
			throws ParseException {
//		// 1.已column为准 进行返回
//		String groupCode = this.getGroupCode();
//		// 不存在值班数据则不查找 修改sql 方法去除 by kongfm 2021-09-14
//		IPage<Map<String, Object>> iPage = dynamicFormInstanceService.pageListNew(current, size, groupCode, beginDate, endDate);
//		List<Map<String, Object>> records = iPage.getRecords();
//		HashSet<String> userIdSet = new HashSet<>();
//		if (!CollectionUtils.isEmpty(records)) {
//			records.forEach(x -> {
//				userIdSet.add(x.get("userId").toString());
//			});
//		}
//		//	获取人员详细信息
//		List<Map<String, Object>> personInfoList = dynamicFormInstanceService.personInfoList(DynamicGroupCodeEnum.JCS_PERSON.getCode(), userIdSet);
//		if (!CollectionUtils.isEmpty(personInfoList)) {
//			Map<String, List<Map<String, Object>>> listMap = personInfoList.stream().collect(Collectors.groupingBy((Map m) -> String.valueOf(m.get("userId"))));
//			records.forEach(x -> {
//				String userId = x.get("userId").toString();
//				List<Map<String, Object>> list = listMap.get(userId);
//				if (!CollectionUtils.isEmpty(list)) {
//					list.forEach(x::putAll);
//				}
//			});
//			iPage.setRecords(records);
//		}
//		return iPage;
		return dynamicFormInstanceMapper.getPersonInfoByPage(new Page(current, size), bizOrgCode);
	}


	public List<Map<String, Object>> dutyCardCount()
			throws ParseException {
		return dynamicFormInstanceMapper.dutyCardCount();
	}

	public List<Map<String, Object>> dutyCardList()
			throws ParseException {
		return dynamicFormInstanceMapper.dutyCardList();
	}

	private void fillDutyShiftData(String beginDate, String endDate, Map<String, Object> m) throws ParseException {
		// 获取值班的实例id
		String instanceId = m.get("instanceId").toString();
		// 根据appkey 获取未删除的值班班次
		List<DutyShift> dutyShifts = dutyShiftService.list(new LambdaQueryWrapper<DutyShift>()
				.eq(BaseEntity::getIsDelete, false).eq(DutyShift::getAppKey, RequestContext.getAppKey()));
		// 根据id 保存成key -value
		Map<Long, DutyShift> keyNameMap = dutyShifts.stream()
				.collect(Collectors.toMap(BaseEntity::getSequenceNbr, Function.identity()));
		// 根据时间 查询值班关系表

		// BUG 2806 获取月份第一天和最后一天  2021-09-09 by kongfm
		SimpleDateFormat shortformat = new SimpleDateFormat("yyyy-MM-dd");
		if(beginDate != null ) {
			Calendar c = Calendar.getInstance();
			if(DateUtils.longStr2Date(beginDate) != null) {
				c.setTime(DateUtils.longStr2Date(beginDate));
			} else {
				c.setTime(shortformat.parse(beginDate));
			}
			c.set(Calendar.DAY_OF_MONTH, 1);
			c.set(Calendar.HOUR_OF_DAY,0);
			c.set(Calendar.MINUTE,0);
			c.set(Calendar.SECOND,0);
			beginDate = DateUtils.date2LongStr(c.getTime());
		}
		if(endDate != null ) {
			Calendar c = Calendar.getInstance();
			if(DateUtils.longStr2Date(endDate) != null) {
				c.setTime(DateUtils.longStr2Date(endDate));
			} else {
				c.setTime(shortformat.parse(endDate));
			}
			c.add(Calendar.MONTH, 1);
			c.set(Calendar.DAY_OF_MONTH, 1);
			c.add(Calendar.DATE, -1);
			c.set(Calendar.HOUR_OF_DAY,23);
			c.set(Calendar.MINUTE,59);
			c.set(Calendar.SECOND,59);
			endDate = DateUtils.date2LongStr(c.getTime());
		}
		List<DutyPersonShiftDto> personShiftList = dutyPersonShiftService
				.list(new LambdaQueryWrapper<DutyPersonShift>().eq(DutyPersonShift::getInstanceId, instanceId)
						.ge(beginDate != null, DutyPersonShift::getDutyDate, beginDate)
						.le(endDate != null, DutyPersonShift::getDutyDate, endDate))
				.stream().map(e -> {
					// 值班关系查询到以后 重新封装
					DutyPersonShiftDto dto = new DutyPersonShiftDto();
					Bean.copyExistPropertis(e, dto);
					// 没值班信息，默认休
					DutyShift dutyShift = keyNameMap.get(e.getShiftId());
					dto.setShiftName(dutyShift != null ? dutyShift.getName() : "休班");
					dto.setColor(dutyShift != null ? dutyShift.getColor() : "");
					return dto;
				}).collect(Collectors.toList());
		m.put("dutyShift", personShiftList);
	}

	/*bug2468 值班排班，日历视图单班次执勤人数满足≤3且班次≤2时，值班显示方式错误    陈召   开始*/
	//获取时间段内的每一天
	public static List<String> getBetweenDate(String start, String end) {
		List<String> list = new ArrayList<>();
		LocalDate startDate = LocalDate.parse(start);
		LocalDate endDate = LocalDate.parse(end);
		long distance = ChronoUnit.DAYS.between(startDate, endDate);
		if (distance < 1 && StringUtils.isNotBlank(start)) {
			list.add(start);
			return list;
		}
		Stream.iterate(startDate, d -> d.plusDays(1)).limit(distance + 1).forEach(f -> list.add(f.toString()));
		return list;
	}

	@Override
	public List<Map<String, Object>> statisticsDay(String beginDate, String endDate) throws ParseException {

		Date dateBegin = DateUtils.dateParse(beginDate, DateUtils.DATE_PATTERN);
		String timeStart = DateUtils.dateTimeToDateString(dateBegin);
		Date dateEnd = DateUtils.dateParse(endDate, DateUtils.DATE_PATTERN);
		String timeEnd = DateUtils.dateTimeToDateString(dateEnd);
		List<String> betweenDate = getBetweenDate(timeStart, timeEnd);

		//拿到每一天的视图展示
		String beginTime = null;
		String endTime = null;
		List<Map<String, Object>> viewTypeResult = new ArrayList<>();
		for (String time : betweenDate) {
			beginTime = time + " 00:00:00";
			endTime = time + " 23:59:59";
			Map<String, Object> viewTypeMap = new HashMap<>();
			viewTypeMap.put("date",time);
			viewTypeMap.put("viewType", this.inferView(beginTime, endTime, RequestContext.getAppKey()));
			viewTypeResult.add(viewTypeMap);
		}

		List<Map<String, Object>> rangeDate = dutyPersonShiftService.getBaseMapper().genRangeDate(beginDate, endDate);

		List<Map<String, Object>> resultMap = new ArrayList<>();
		for (Map<String, Object> stringObjectMap : viewTypeResult) {
			for (Map<String, Object> objectMap : rangeDate) {
				if (stringObjectMap.get("date").equals(objectMap.get("date"))){
					Map<String, Object> result = new LinkedHashMap<>();
					DutyViewTypeEnum viewType = (DutyViewTypeEnum) stringObjectMap.get("viewType");
					result.put("key", objectMap.get("date"));
					result.put("viewType", viewType.getCode());
					result.put("data", this.buildViewData(viewType, objectMap.get("date").toString(), RequestContext.getAppKey()));
					resultMap.add(result);
				}
			}
		}
		return resultMap;
		/*bug2468 值班排班，日历视图单班次执勤人数满足≤3且班次≤2时，值班显示方式错误 陈召 结束*/
	}
	
	public List<Map<String, Object>> newStatisticsDay(String beginDate, String endDate, String fieldCode) throws ParseException {

		Date dateBegin = DateUtils.dateParse(beginDate, DateUtils.DATE_PATTERN);
		String timeStart = DateUtils.dateTimeToDateString(dateBegin);
		Date dateEnd = DateUtils.dateParse(endDate, DateUtils.DATE_PATTERN);
		String timeEnd = DateUtils.dateTimeToDateString(dateEnd);
		List<String> betweenDate = getBetweenDate(timeStart, timeEnd);

		//拿到每一天的视图展示
		String beginTime = null;
		String endTime = null;
		List<Map<String, Object>> viewTypeResult = new ArrayList<>();
		for (String time : betweenDate) {
			beginTime = time + " 00:00:00";
			endTime = time + " 23:59:59";
			Map<String, Object> viewTypeMap = new HashMap<>();
			viewTypeMap.put("date",time);
			viewTypeResult.add(viewTypeMap);
		}
		List<Map<String, Object>> rangeDate = dutyPersonShiftService.getBaseMapper().genRangeDate(beginDate, endDate);
		List<Map<String, Object>> resultMap = new ArrayList<>();
		for (Map<String, Object> stringObjectMap : viewTypeResult) {
			for (Map<String, Object> objectMap : rangeDate) {
				if (stringObjectMap.get("date").equals(objectMap.get("date"))){
					Map<String, Object> result = new LinkedHashMap<>();
					result.put("key", objectMap.get("date"));
					String dateString =	 objectMap.get("date").toString();
					if(this.getGroupCode().equals("dutyPerson")) {
						result.put("data", getPersonPostTypeNameAndCount(dateString, fieldCode));
					}else if(this.getGroupCode().equals("dutyCar")) {
						result.put("data", getCarPostTypeNameAndCount(dateString));
					}else if(this.getGroupCode().equals("dutyFireFighting")) {
						result.put("data", getFireFightingPostTypeNameAndCount(dateString));
					}else if(this.getGroupCode().equals("dutyFirstAid")) {
						result.put("data", getFirstAidPostTypeNameAndCount(dateString));
					}
					resultMap.add(result);
				}
			}
		}
		return resultMap;
	}
	
	/**
	 * 排班值班人员的统计类型为：
	 * 岗位： 岗位人员数量
	 *
	 * @param dutyDate
	 * @param dutyType
	 * @return
	 */
	public Object getPersonPostTypeNameAndCount(String dutyDate, String fieldCode) {
		if (StringUtils.isNotBlank(fieldCode)) {
			return dutyPersonShiftService.getBaseMapper().newStationViewDataByFieldCode(dutyDate, this.getGroupCode(), fieldCode);
		}
		return dutyPersonShiftService.getBaseMapper().newStationViewData(dutyDate, this.getGroupCode());
	}
	/**
	 * 车辆值班人员左侧的统计： 只有几辆车
	 * @param dutyDate
	 * @return
	 */
	public Object getCarPostTypeNameAndCount(String dutyDate) {
		Map<String, Object> map = new HashMap<String, Object>();
		int station =0;
		int person=0;
		List<Map<String, Object>> equipmentList = dutyPersonShiftMapper.getEquipmentForSpecifyDate(dutyDate,
				this.getGroupCode(), "carId", "carName", "teamName","result.carId");
		if(equipmentList==null || equipmentList.size()<1 || equipmentList.get(0)==null) {
			station =0;
		}else {
			station=equipmentList.size();
		}
		map.put("station", station);
		List<Map<String, Object>>  list = dutyPersonShiftService.getBaseMapper().newStationViewData(dutyDate, this.getGroupCode());
		for (Map<String, Object> map2 : list) {
			person = person +Integer.parseInt(map2.get("total").toString());
		}
		map.put("person", person);
		return map;
	}
	
	
	public Object getFireFightingPostTypeNameAndCount(String dutyDate) {
		Map<String, Object> map = new HashMap<String, Object>();
		int station =0;
		int person=0;
		List<Map<String, Object>> equipmentList = dutyPersonShiftMapper.getEquipmentForSpecifyDate(dutyDate,
				this.getGroupCode(), "fireFightingId", "fireFighting", "teamName","result.fireFightingId");
		if(equipmentList==null || equipmentList.size()<1 || equipmentList.get(0)==null) {
			station =0;
		}else {
			station=equipmentList.size();
		}
		map.put("station", station);
		List<Map<String, Object>>  list = dutyPersonShiftService.getBaseMapper().newStationViewData(dutyDate, this.getGroupCode());
		for (Map<String, Object> map2 : list) {
			person = person +Integer.parseInt(map2.get("total").toString());
		}
		map.put("person", person);
		return map;
	}
	
	public Object getFirstAidPostTypeNameAndCount(String dutyDate) {
		Map<String, Object> map = new HashMap<String, Object>();
		int station =0;
		int person=0;
		List<Map<String, Object>> equipmentList = dutyPersonShiftMapper.getEquipmentForSpecifyDate(dutyDate,
				this.getGroupCode(), "firstAidId", "firstAid", "teamName", "result.firstAidId");
		if(equipmentList==null || equipmentList.size()<1 || equipmentList.get(0)==null) {
			station =0;
		}else {
			station=equipmentList.size();
		}
		map.put("station", station);
		List<Map<String, Object>>  list = dutyPersonShiftService.getBaseMapper().newStationViewData(dutyDate, this.getGroupCode());
		for (Map<String, Object> map2 : list) {
			person = person +Integer.parseInt(map2.get("total").toString());
		}
		map.put("person", person);
		return map;
	}
	
	
	private Object buildViewData(DutyViewTypeEnum viewTypeEnum, String dutyDate, String appKey) {
		List<Map<String, Object>> result = new ArrayList<>();
		switch (viewTypeEnum) {
		case BANK:
			result = dutyPersonShiftService.getBaseMapper().bankViewData(dutyDate, appKey, this.getGroupCode());
			break;
		case STATION:
			result = dutyPersonShiftService.getBaseMapper().stationViewData(dutyDate, appKey, this.getGroupCode());
			break;
		default:
			break;
		}
		return result;
	}

	private DutyViewTypeEnum inferView(String beginDate, String endDate, String appKey) {
		Map<String, Long> result = dutyPersonShiftService.getBaseMapper().calMaxPersonAndShiftNum(beginDate, endDate,
				appKey, this.getGroupCode());
		// 计算班次最大执勤人数，时间区间内
		Long maxDutyPersonNumDay = result.get("maxDutyPersonNumDay");
		// 计算天的最大班次数量，时间区间内
		Long maxShiftNumDay = result.get("maxShiftNumDay");
		if (maxDutyPersonNumDay <= LIMIT_PERSON_NUMBER && maxShiftNumDay <= LIMIT_SHIFT_NUMBER) {
			return DutyViewTypeEnum.BANK;
		} else {
			return DutyViewTypeEnum.STATION;
		}
	}

	@Override
	public List<Map<String, Object>> list(Long teamId, String beginDate, String endDate) throws ParseException {
		// 1.已column为准 进行返回
		String groupCode = this.getGroupCode();
		// 动态表单查询所有值班信息
		List<Map<String, Object>> list = dynamicFormInstanceService.listAll(groupCode);
		
		// 2.组织值班数据
		for (Map<String, Object> map : list) {
			this.fillDutyShiftData(beginDate, endDate, map);
		}
		// BUG 2807 更新人员车辆排版值班的保存逻辑 如果没有填写数据则保存空数据 。 同步修改 查询 导出相关逻辑 by kongfm 2021-09-14
		list = list.stream().filter(m ->
			m.get("dutyShift") != null && ((List<DutyPersonShiftDto>) m.get("dutyShift")).size() > 0
		).collect(Collectors.toList());

		/*bug2472 添加根据部门id筛选数据的方法  陈浩 2021-08-21 开始	*/
		if(teamId!=null && teamId.intValue()!=0) {
			List<OrgUsr> orgUsrList = orgUsrService.getPersonListByParentId(teamId);
			List<Map<String, Object>>  resultList= new ArrayList<Map<String, Object>>();
			list.stream().forEach(i->{
				orgUsrList.forEach(m->{
					if(i.get("userId").toString().equals(m.getSequenceNbr().longValue()+"")) {
						resultList.add(i);
					}
				});
			});
			return resultList;
		}
		/*bug2472 添加根据部门id筛选数据的方法  陈浩 2021-08-21 结束	*/
		return list;
	}

	@Override
	public String getGroupCode() {
		return null;
	}

	@Override
	public List downloadList(String beginDate, String endDate) throws ParseException {
		List<Map<String, Object>> maps = this.list(null,beginDate, endDate);
		// BUG 2807 如果不存在值班数据则不显示
		maps = maps.stream().filter(m ->
				m.get("dutyShift") != null && ((List<DutyPersonShiftDto>) m.get("dutyShift")).size() > 0
		).collect(Collectors.toList());

		JSONArray jsonArray = new JSONArray();
		jsonArray.addAll(maps);
		List<?> list = new ArrayList<>();
		String groupCode = this.getGroupCode();
		String fileName;
		if ("dutyCar".equals(groupCode)) {
			list = jsonArray.toJavaList(DutyCarDto.class);
		} else if("dutyPerson".equals(groupCode)){
			list = jsonArray.toJavaList(DutyPersonDto.class);
		}else if("dutyFireFighting".equals(groupCode)){
			list = jsonArray.toJavaList(DutyFireFightingDto.class);
		}else if("dutyFirstAid".equals(groupCode)){
			list = jsonArray.toJavaList(DutyFirstAidDto.class);
		}
		return list;
	}

	@Override
	public void saveImportData(List<Map<String, Object>> dataList) {
		List<DynamicFormInstance> formInstanceList = new ArrayList<>();
		Set<DutyPersonShift> dutyPersonShifts = new HashSet<>();
		dataList.forEach(d -> {
			// TODO： 业务唯一索引，用户id
			String userId = d.get("userId").toString();
			List<DynamicFormInstance> instances = dynamicFormInstanceService
					.list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getFieldCode, "userId")
							.eq(DynamicFormInstance::getFieldValue, userId)
							.eq(DynamicFormInstance::getGroupCode, this.getGroupCode()));
			Long instanceId = null;
			List<DynamicFormColumn> columns = dynamicFormColumnService.list(new LambdaQueryWrapper<DynamicFormColumn>()
					.eq(DynamicFormColumn::getGroupCode, this.getGroupCode()));
			Map<String, Object> dataMap = buildDataMap(d, userId);
			// 1.组装动态表单数据
			if (!instances.isEmpty()) {
				// 0.定位instanceId，准备进行更新操作
				instanceId = instances.get(0).getInstanceId();
				// 1.查询已有数据
				List<DynamicFormInstance> instancesInDb = dynamicFormInstanceService
						.list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getInstanceId,
								instanceId));
				// 2.list 转 map
				Map<Object, DynamicFormInstance> instanceMap = Bean.listToMap(instancesInDb, "fieldCode",
						DynamicFormInstance.class);
				// 3.待更新数据组装，待批量入库
				this.updateFormValue(formInstanceList, dataMap, instanceId, columns, instanceMap);
			} else {
				// 0.新数据，生成id
				instanceId = sequence.nextId();
				Long finalInstanceId1 = instanceId;
				// 1.组装数据
				List<DynamicFormInstance> newInstances = columns.stream().map(column -> {
					DynamicFormInstance instance = new DynamicFormInstance();
					buildFormInstanceData(finalInstanceId1, dataMap, column, instance);
					return instance;
				}).collect(Collectors.toList());
				// 2.待更新数据组装，待批量入库
				formInstanceList.addAll(newInstances);
			}
			// 2.组装值班数据
			List<DutyPersonShiftDto> shiftDtos = (List<DutyPersonShiftDto>) dataMap.get("dutyShift");
			Long finalInstanceId = instanceId;
			// 按照业务唯一索引查询主键
			List<DutyPersonShift> dutyPersonShiftsDb = dutyPersonShiftService
					.list(new LambdaQueryWrapper<DutyPersonShift>().eq(DutyPersonShift::getInstanceId, instanceId));
			Map<Date, Long> dutyPersonShiftMap = dutyPersonShiftsDb.stream()
					.collect(Collectors.toMap(DutyPersonShift::getDutyDate, DutyPersonShift::getSequenceNbr));
			// todo: 只更新当天及值班之后数据

			// 修复导入当天值班数据bug
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
			String format = simpleDateFormat.format(new Date());
			Date date = null;
			try {
				date = simpleDateFormat.parse(format);
			} catch (ParseException e) {
				e.printStackTrace();
			}
			Date finalDate = date;
			Set<DutyPersonShift> needToDb = shiftDtos.stream()
					.filter(s -> DateUtils.dateCompare(s.getDutyDate(), finalDate) >= 0).map(shiftDto -> {
						DutyPersonShift dutyPersonShift = new DutyPersonShift();
						Bean.copyExistPropertis(shiftDto, dutyPersonShift);
						dutyPersonShift.setInstanceId(finalInstanceId);
						dutyPersonShift.setAppKey(RequestContext.getAppKey());
						dutyPersonShift.setSequenceNbr(dutyPersonShiftMap.get(dutyPersonShift.getDutyDate()));
						return dutyPersonShift;
					}).collect(Collectors.toSet());
			dutyPersonShifts.addAll(needToDb);
		});
		if (!formInstanceList.isEmpty()) {
			dynamicFormInstanceService.saveOrUpdateBatch(formInstanceList);
		}
		if (!dutyPersonShifts.isEmpty()) {
			dutyPersonShiftService.saveOrUpdateBatch(dutyPersonShifts);
		}
	}

	public void updateFormValue(List<DynamicFormInstance> formInstanceList, Map<String, Object> d, Long instanceId,
			List<DynamicFormColumn> columns, Map<Object, DynamicFormInstance> instanceMap) {
		for (DynamicFormColumn column : columns) {
			DynamicFormInstance formInstance = instanceMap.get(column.getFieldCode());
			if (!ObjectUtils.isEmpty(formInstance)) {
				// 有的更新
				formInstance.setFieldValue(
						d.get(column.getFieldCode()) != null ? d.get(column.getFieldCode()).toString() : "");
			} else {
				// 没有的新增
				formInstance = new DynamicFormInstance();
				buildFormInstanceData(instanceId, d, column, formInstance);
			}
			formInstanceList.add(formInstance);
		}
	}

	private Map<String, Object> buildDataMap(Map<String, Object> d, String userId) {
		// 表单存在人员类型，获取用户ID，查询人员类型赋值
		if (!ObjectUtils.isEmpty(userId)) {
			List<DynamicFormInstance> instances = dynamicFormInstanceService
					.list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getFieldCode, "peopleType")
							.eq(DynamicFormInstance::getInstanceId, userId)
							.eq(DynamicFormInstance::getGroupCode, DynamicGroupCodeEnum.JCS_PERSON.getCode()));
			if (!CollectionUtils.isEmpty(instances)) {
				String fieldValue = instances.get(0).getFieldValue();
				List<DataDictionary> dictionaryList = dataDictionaryService.getByType(DataDictionaryTypeEnum.PERSON_TYPE.getCode());
				if (StringUtils.isNotBlank(fieldValue) && !CollectionUtils.isEmpty(dictionaryList)) {
					Map<String, List<DataDictionary>> map = dictionaryList.stream().collect(Collectors.groupingBy(DataDictionary::getCode));
					List<DataDictionary> list = map.get(fieldValue);
					if (!CollectionUtils.isEmpty(list)) {
						d.put("personType", list.get(0).getName());
					}
				}
			}
		}
		return d;
	}

	private void buildFormInstanceData(Long instanceId, Map<String, Object> map, DynamicFormColumn column,
			DynamicFormInstance formInstance) {
		fillFormInstanceData(instanceId, map, column, formInstance, sequence.nextId());
	}

	static void fillFormInstanceData(Long instanceId, Map<String, Object> map, DynamicFormColumn column,
			DynamicFormInstance formInstance, long l) {
		Bean.copyExistPropertis(column, formInstance);
		formInstance.setAppKey(RequestContext.getAppKey());
		formInstance.setInstanceId(instanceId);
		formInstance.setSequenceNbr(l);
		formInstance.setFormColumnId(column.getSequenceNbr());
		formInstance
				.setFieldValue(map.get(column.getFieldCode()) != null ? map.get(column.getFieldCode()).toString() : "");
	}

	@Override
	public Boolean deleteDutyData(Long instanceId, String startTime, String endTime) {
        // BUG 2807 删除逻辑缺陷，现在前端后端传入 删除月份 2021-09-10 by kongfm
		//dynamicFormInstanceService.remove(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getInstanceId, instanceId));
		dutyPersonShiftService
				.remove(new LambdaQueryWrapper<DutyPersonShift>().ge(DutyPersonShift::getDutyDate,startTime).le(DutyPersonShift::getDutyDate,endTime).eq(DutyPersonShift::getInstanceId, instanceId));
		return true;
	}

	@Override
	public List<Map<String, Object>> dayDutyPersonList(String dutyDay, Long shiftId, String postType) {
		String groupCode = this.getGroupCode();
		Map<String, String> params = new HashMap<>();
		params.put("postType", postType);
		List<DynamicFormColumn> columns = dynamicFormColumnService
				.list(new LambdaQueryWrapper<DynamicFormColumn>().eq(DynamicFormColumn::getGroupCode, groupCode));
		Map<String, Object> fieldCodes = Bean.listToMap(columns, "fieldCode", "queryStrategy", DynamicFormColumn.class);
		return dynamicFormInstanceService.getBaseMapper().listOneDayDutyPerson(dutyDay, shiftId, fieldCodes,
				RequestContext.getAppKey(), groupCode, params);
	}

	@Override
	public List<Map<String, Object>> listOnDutyPerson() {
		String groupCode = this.getGroupCode();
		// 获取当前班次列表
		DateTime now = new DateTime();
		List<Long> shiftIdList = getOnDuty(now);
		String shiftIds = StringUtils.join(shiftIdList.toArray(), ",");
		String dutyDay = now.toString("yyyy-MM-dd");
		// 获取当前值班人员
		List<DynamicFormColumn> columns = dynamicFormColumnService
				.list(new LambdaQueryWrapper<DynamicFormColumn>().eq(DynamicFormColumn::getGroupCode, groupCode));
		Map<String, Object> fieldCodes = Bean.listToMap(columns, "fieldCode", "queryStrategy", DynamicFormColumn.class);
		List<Map<String, Object>> maps = dynamicFormInstanceService.getBaseMapper().listOnDutyPerson(dutyDay, shiftIds,
				fieldCodes, groupCode);
		// 获取人员照片和电话
		List<Long> ids = new ArrayList<>();
		maps.forEach(item -> ids.add(Long.valueOf(String.valueOf(item.get("userId")))));
		try {
			List<Map<String, Object>> orgUsrList = orgUsrService.selectForShowByListId(ids);
			maps.forEach(item -> {
				String userId = String.valueOf(item.get("userId"));
				for (Map<String, Object> usr : orgUsrList) {
					if (userId.equals(String.valueOf(usr.get("sequenceNbr")))) {
						item.put("personImg", usr.get("personImg"));
						item.put("telephone", usr.get("telephone"));
						break;
					}
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
		return maps;
	}

	private List<Long> getOnDuty(DateTime now) {
		List<DutyShiftDto> dutyShiftDtos = dutyShiftService.queryForDutyShiftList(false);
		List<Long> shiftIds = new ArrayList<>();
		int hour = now.getHourOfDay();
		int minute = now.getMinuteOfHour();
		dutyShiftDtos.forEach(item -> {
			String[] start = item.getStartTime().split(": ");
			String[] startTime = start[1].split(":");
			Integer startHour = Integer.valueOf(startTime[0]);
			Integer startMinute = Integer.valueOf(startTime[1]);
			String[] end = item.getEndTime().split(": ");
			String[] endTime = end[1].split(":");
			Integer endHour = Integer.valueOf(endTime[0]);
			Integer endMinute = Integer.valueOf(endTime[1]);
			if ("当日".equals(start[0])) {
				if (hour > startHour || hour == startHour && minute > startMinute) {
					if ("次日".equals(end[0])
							|| "当日".equals(end[0]) && (hour < endHour || hour == endHour && minute < endMinute)) {
						shiftIds.add(item.getSequenceNbr());
					}
				}
			}
		});
		return shiftIds;
	}

	@Override
	public List<Long> getDutyShiftIdList() {
		return getOnDuty(new DateTime());
	}
	/***
	 * 将操作动态表单的方法单独提出来
	 * @author 陈浩 
	 * @serialData 2021-09-28
	 * @param userId
	 * @param map
	 * @param groupCode
	 * @return
	 */
	    public Long excuteDynamicFormInstance( String userId,Map<String, Object> map, String groupCode) {
	    	 List<DynamicFormInstance> instances = dynamicFormInstanceService
	                 .list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getFieldCode, "userId")
	                         .eq(DynamicFormInstance::getFieldValue, userId)
	                         .eq(DynamicFormInstance::getGroupCode, this.getGroupCode()));
	         Long instanceId = null;
	         if (!instances.isEmpty()) {
	             // 0.定位instanceId，准备进行更新操作
	             instanceId = instances.get(0).getInstanceId(); // 已经有了走更新方法
	             //1.查询已有数据
	             List<DynamicFormInstance> hasInstances = dynamicFormInstanceService.list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getInstanceId, instanceId));
	             //2.list 转 map
	             Map<Object, DynamicFormInstance> instanceMap = Bean.listToMap(hasInstances, "fieldCode", DynamicFormInstance.class);
	             //3.查询列数据，已列为主
	             List<DynamicFormColumn> columns = dynamicFormColumnService.list(new LambdaQueryWrapper<DynamicFormColumn>().eq(DynamicFormColumn::getGroupCode, groupCode));
	             //4.已列为主 填充动态表单数据
	             List<DynamicFormInstance> entrys = new ArrayList<>();
	             for (DynamicFormColumn column : columns) {
	                 DynamicFormInstance formInstance = instanceMap.get(column.getFieldCode());
	                 if (!ObjectUtils.isEmpty(formInstance)) {
	                     //有的更新
	                     formInstance.setFieldValue(map.get(column.getFieldCode()) != null ? map.get(column.getFieldCode()).toString() : "");
	                 } else {
	                     //没有的新增
	                     formInstance = new DynamicFormInstance();
	                     buildFormInstanceData(instanceId, map, column, formInstance);
	                 }
	                 entrys.add(formInstance);
	             }
	             if(!entrys.isEmpty()){
	                 dynamicFormInstanceService.saveOrUpdateBatch(entrys);
	             }

	         } else {
	             instanceId =  dynamicFormInstanceService.commonSave(groupCode,map);
	         }
			return instanceId;
	    }
	    
	    public void updateDynamicFormInstance(String groupCode,Long instanceId, Map<String, Object> map) {
	   	 //1.查询已有数据
	       List<DynamicFormInstance> instances = dynamicFormInstanceService.list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getInstanceId, instanceId));
	       //2.list 转 map
	       Map<Object, DynamicFormInstance> instanceMap = Bean.listToMap(instances, "fieldCode", DynamicFormInstance.class);
	       //3.查询列数据，已列为主
	       List<DynamicFormColumn> columns = dynamicFormColumnService.list(new LambdaQueryWrapper<DynamicFormColumn>().eq(DynamicFormColumn::getGroupCode, groupCode));
	       //页面数据转Map
	       //4.已列为主 填充动态表单数据
	       List<DynamicFormInstance> entrys = new ArrayList<>();
	       updateFormValue(entrys, map, instanceId, columns, instanceMap);
	       if (!entrys.isEmpty()) {
	           dynamicFormInstanceService.saveOrUpdateBatch(entrys);
	       }
	   } 
	    
	    public void saveDutyPersonShiftDetail( Long instanceId ,List<DutyPersonShiftDto> dutyShift ,String startTime) {
	    	 if(dutyShift != null && dutyShift.size() == 0) {
	             Calendar startDate = Calendar.getInstance();
	             startDate.setTime(DateUtils.longStr2Date(startTime));
	             int dates = startDate.getActualMaximum(Calendar.DAY_OF_MONTH);
	             startDate.set(Calendar.DAY_OF_MONTH, 1);
	             List<DutyPersonShift> dutyShiftList = new ArrayList<>(dates);
	             for (int i = 0 ; i < dates ; i ++) {
	                 DutyPersonShift temp = new DutyPersonShift();
	                 temp.setAppKey(RequestContext.getAppKey());
	                 temp.setDutyDate(startDate.getTime());
	                 temp.setIsDelete(false);
	                 temp.setInstanceId(instanceId);
	                 dutyShiftList.add(temp);
	                 startDate.add(Calendar.DAY_OF_YEAR,1);
	             }
	             dutyPersonShiftService.saveOrUpdateBatch(dutyShiftList);
	         }
	    }
	    public void insertPersonShift(Long instanceId, List<DutyPersonShiftDto> dutyShiftList) {
	        Set<DutyPersonShift> personShiftList = dutyShiftList.stream().map(dto -> {
	            // BUG 2807 修改时发现BUG 车辆保存有问题 by kongfm 2021-09-14
	            // 根据instanceId 和 日期查找 如果有则更新
	            DutyPersonShift dutyPersonShift = dutyPersonShiftService.getOne(new LambdaQueryWrapper<DutyPersonShift>().eq(DutyPersonShift::getInstanceId,instanceId).eq(DutyPersonShift::getDutyDate,dto.getDutyDate()));
	            if(dutyPersonShift == null) {
	                dutyPersonShift = new DutyPersonShift();
	            }
	            dto.setInstanceId(instanceId);
	            Bean.copyExistPropertis(dto, dutyPersonShift);
	            dutyPersonShift.setAppKey(RequestContext.getAppKey());
	            return dutyPersonShift;
	        }).collect(Collectors.toSet());
	        if (!personShiftList.isEmpty()) {
	            dutyPersonShiftService.saveOrUpdateBatch(personShiftList);
	        }
	    }

		@Override
		public Object getSchedulingDutyForSpecifyDate(String dutyDay, Long shiftId, String postType, String fieldCode) {
			// TODO Auto-generated method stub
			return null;
		}
}
