package co.sh.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.util.CollectionUtils;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* 测试-预订接口
*
* @author chenzb
* @since 10/23/21
*/
public class Test2 {
public static void main(String[] args) {
File file = new File("/Users/jabez/python/会议室预定信息.txt");
String fileType = file.getName().substring(file.getName().lastIndexOf("."));
List<String> excelTypes = Arrays.asList(".xls", "docx", ".csv");
String workStartTime = null;
String workEndTime = null;
List<BookingData> keyList = new ArrayList<>();
if (fileType.equals(".txt")) {
BufferedReader reader = null;
StringBuffer sb = new StringBuffer();
try {
reader = new BufferedReader(new FileReader(file));
String line;
while ((line = reader.readLine()) != null) {
// 针对每行数据处理
// TODO 处理规制
// 处理第一条上班时间
String[] split = line.split("\s+");
if (split.length == 2) {
// TODO 校验匹配时间的正则表达式校验一下24小时制时间 如果
String pattern = "^(([1-9]{1})|([0-1][0-9])|([1-2][0-3])):([0-5][0-9])$";
if (Pattern.matches(pattern, split[0]) && Pattern.matches(pattern, split[1])) {
// 直接去前两位转Integer 比大小
if (Integer.valueOf(split[0].substring(0, 2)) > Integer.valueOf(split[1].substring(0, 2))) {
workEndTime = split[0];
workStartTime = split[1];
} else {
workEndTime = split[1];
workStartTime = split[0];
}
}
}
if (split.length == 3) {
if (line.contains("EMP")) {
// 直接转对象吧
// TODO 时间我就不用正则获取了直接截取了
BookingData dto = new BookingData();
String dateStr = line.substring(0, line.indexOf(" EMP"));
String emp = line.substring(line.indexOf("EMP"), line.length());
dto.setCommitTime(toDate(dateStr, "yyyy-MM-dd HH:mm:ss"));
dto.setEmployeeId(emp);
keyList.add(dto);
} else {
//获取最新的KeyList最后追加进去的数据
BookingData dto = keyList.get(keyList.size() - 1);
String startTime = line.substring(0, line.length() - 2);
String hours = line.substring(line.length() - 1, line.length());
dto.setStartTime(toDate(startTime, "yyyy-MM-dd HH:mm"));
dto.setStartYmd(line.substring(0, 10));
dto.setStartHms(line.substring(11, 16));
dto.setHours(Integer.valueOf(hours));
}
}
sb.append(line + "
");
}
reader.close();
// TODO 上面封装DataMap数据是原数据必须按早文本格式 若格式错误 最总结果错误获取运行时取时间校验都会错
// 数据校验与入库
//●会议不得在办公时间以外进行(周一到周五 早上九点到晚上 6 点)。
//●会议不能重叠。
//●预订提交系统一次只允许一个提交,所以提交时间保证是唯一的。
//●预订必须按照提交的时间顺序进行处理。
//●在提供的输入中不保证预订提交的顺序
//09:00 18:00
//2011-03-17 10:17:06 EMP001
//2011-03-21 09:00 2
//2011-03-16 12:34:56 EMP002
//2011-03-21 09:00 2
//2011-03-16 09:28:23 EMP003
//2011-03-22 14:00 2
//2011-03-17 11:23:45 EMP004
//2011-03-22 16:00 1
//2011-03-15 17:29:12 EMP005
//2011-03-21 16:00 3
// 提交时间保持唯一
List<Date> checkList = keyList.stream().map(item -> item.getCommitTime()).distinct().collect(Collectors.toList());
// TODO 是要指出来哪条数据吗 还有存在相同数据抛出异常提示重传
if (checkList.size() != keyList.size()) {
System.out.println("!!有两个预约的请求提交时间相同~~");
}
// 还预订必须按照提交的时间顺序进行处理 ..
keyList.stream().sorted(Comparator.comparing(BookingData::getCommitTime)).collect(Collectors.toList());
// poList 表示所有从数据中取出的所有的预定信息
List<BookingData> poList = new ArrayList<>();
// 更具会议开时间的日期分组
for (BookingData item : keyList) {
// 返回是否为工作日
if (getIsWorkingDay(getStringDate(item.getStartTime(), "yyyyMMdd"))) {
// 校验是否在时间工作时间范围
if (isEffectiveDate(toDate(workStartTime), toDate(workEndTime), toDate(getStringDate(item.getStartTime(), "HH:mm")))) {
// 获取统一日期的的数据 在对比 在拿当开始时间的与已预定的好的会议比较 收否可以安排会议
Map<String, List<BookingData>> listMap = poList.stream().collect(Collectors.groupingBy(BookingData::getStartYmd));
// 预定日期当天的所有记录
if (listMap.containsKey(getStringDate(item.getStartTime(), "yyyy-MM-dd"))) {
// 预约当天所有的会议
List<BookingData> bookingDataList = listMap.get(getStringDate(item.getStartTime(), "yyyy-MM-dd"));
if (CollectionUtils.isEmpty(bookingDataList)) {
// 没有数据直接插入
poList.add(item);
} else {
Boolean boo=false;
// 判断两个时间段是否有交集 用当前的 会议开始时间+时长
for (BookingData a : bookingDataList){
if(isOverlap(a.getStartTime(),addDateMinut(a.getStartTime(),a.getHours()),item.getStartTime(),addDateMinut(a.getStartTime(),a.getHours()))){
boo = true;
}else {
boo = false;
}
}
// 不在当日的区间内可插入数据库预约成功
if (boo){
poList.add(item);
}
}
}
} else {
System.out.println("会议:" + item.getEmployeeId() + "会议的开时间不在工作时间呢");
}
} else {
System.out.println("会议:" + item.getEmployeeId() + "预定日期不在工作日内");
}
}
Gson gson=new Gson();
System.out.println(gson.toJson(poList));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
// 不用.txt 直接定义一个模版Excel表格不行吗。。
if (excelTypes.contains(fileType)) {
InputStream inputStream;
try {
inputStream = new FileInputStream(file);
} catch (IOException e) {
throw new RuntimeException("error");
}
// excel表格
// TODO 定义接收 dataModel
}
}
// date 加 hours
public static Date addDateMinut(Date date, int hour){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
if (date == null){
return null;
}
System.out.println("front:" + format.format(date)); //显示输入的日期
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.HOUR, hour);// 24小时制
date = cal.getTime();
System.out.println("after:" + format.format(date)); //显示更新后的日期
return date;
}
/**
* 判断当前时间是否在[startTime, endTime]区间,注意时间格式要一致
*
* @param nowTime 当前时间
* @param startTime 开始时间
* @param endTime 结束时间
* @return
*/
public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
if (nowTime.getTime() == startTime.getTime()
|| nowTime.getTime() == endTime.getTime()) {
return true;
}
Calendar date = Calendar.getInstance();
date.setTime(nowTime);
Calendar begin = Calendar.getInstance();
begin.setTime(startTime);
Calendar end = Calendar.getInstance();
end.setTime(endTime);
if (date.after(begin) && date.before(end)) {
return true;
} else {
return false;
}
}
private static boolean isOverlap(Date startdate1, Date enddate1,Date startdate2, Date enddate2) {
Date leftStartDate = startdate1;
Date leftEndDate = enddate1;
Date rightStartDate = startdate2;
Date rightEndDate = enddate2;
return
((leftStartDate.getTime() >= rightStartDate.getTime())
&& leftStartDate.getTime() < rightEndDate.getTime())
||
((leftStartDate.getTime() > rightStartDate.getTime())
&& leftStartDate.getTime() <= rightEndDate.getTime())
||
((rightStartDate.getTime() >= leftStartDate.getTime())
&& rightStartDate.getTime() < leftEndDate.getTime())
||
((rightStartDate.getTime() > leftStartDate.getTime())
&& rightStartDate.getTime() <= leftEndDate.getTime());
}
/**
* 传入格式 为 yyyyMMdd 日期 返回 是否是工作日
*/
public static Boolean getIsWorkingDay(String date) {
BufferedReader reader = null;
String result = null;
StringBuffer sbf = new StringBuffer();
int d = 0;//工作日对应结果为 0, 休息日对应结果为 1, 节假日对应的结果为 2
try {
URL u = new URL("http://api.goseek.cn/Tools/holiday?date=" + date);
HttpURLConnection connection = (HttpURLConnection) u.openConnection();
connection.setRequestMethod("GET");
connection.connect();
InputStream is = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String strRead = null;
while ((strRead = reader.readLine()) != null) {
sbf.append(strRead);
sbf.append("
");
}
reader.close();
result = sbf.toString();
JSONObject ob = JSON.parseObject(result);
if (ob != null) {
d = Integer.parseInt(ob.getString("data"));
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("------------------调用获取工作日接口失败------------------");
return true;
}
return d == 0 ? true : false;
}
// Date 转指定模版的String date
private static String getStringDate(Date startTime, String pattern) {
DateFormat dateFormat = new SimpleDateFormat(pattern);
return dateFormat.format(startTime);
}
//String 转模版Date
public static Date toDate(String dateTime, String format) {
if (ObjectUtils.isEmpty(dateTime)) {
return null;
}
SimpleDateFormat formatter = new SimpleDateFormat(format);
ParsePosition pos = new ParsePosition(0);
Date date = formatter.parse(dateTime, pos);
return date;
}
//String 转 时分 Date
public static Date toDate(String dateTime) {
if (ObjectUtils.isEmpty(dateTime)) {
return null;
}
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm");
ParsePosition pos = new ParsePosition(0);
Date date = formatter.parse(dateTime, pos);
return date;
}
//booking dataModel
public static class BookingData {
// TODO 又没有数据库 ID 创建/更新时间 isDeleted 暂时不写了
// 预约提交时间
private Date commitTime;
// 会议号
private String employeeId;
// 会议开时间
private Date startTime;
// 会议开始日期
private String startYmd;
// 会议开始时间
private String startHms;
// 会议时长 hours
private Integer hours;
public Date getCommitTime() {
return commitTime;
}
public void setCommitTime(Date commitTime) {
this.commitTime = commitTime;
}
public String getEmployeeId() {
return employeeId;
}
public void setEmployeeId(String employeeId) {
this.employeeId = employeeId;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Integer getHours() {
return hours;
}
public void setHours(Integer hours) {
this.hours = hours;
}
public String getStartYmd() {
return startYmd;
}
public void setStartYmd(String startYmd) {
this.startYmd = startYmd;
}
public String getStartHms() {
return startHms;
}
public void setStartHms(String startHms) {
this.startHms = startHms;
}
public BookingData() {
}
public BookingData(Date commitTime, String employeeId, Date startTime, String startYmd, String startHms, Integer hours) {
this.commitTime = commitTime;
this.employeeId = employeeId;
this.startTime = startTime;
this.startYmd = startYmd;
this.startHms = startHms;
this.hours = hours;
}
}
}