yanghb
2025-01-07 1ea7e38d7d2152012db3f49934e84d164a07d613
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
package com.zzg.system.service.system.impl;
 
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzg.common.exception.GlobalException;
import com.zzg.common.utils.DateUtil;
import com.zzg.system.domain.InternalDate;
import com.zzg.system.mapper.system.InternalDateMapper;
import com.zzg.system.service.system.IInternalDateService;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
 
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
 
/**
 * 描述:节假日管理接口
 *
 * @author wangjiang
 * @create 2018-09-18 17:19
 */
 
@Service
public class InternalDateServiceImpl extends ServiceImpl<InternalDateMapper, InternalDate> implements IInternalDateService {
 
    @Override
    @Transactional
    public String initInternalDate(String startDate, String endDate) {
//        internalDateRepository.deleteAll();
        this.remove(new LambdaQueryWrapper<InternalDate>()
                .ge(InternalDate::getDate, DateUtil.formatDate(startDate, DateUtil.DATE_FORMAT))
                .le(InternalDate::getDate, DateUtil.formatDate(endDate, DateUtil.DATE_FORMAT)));
        // 获取两个节点之间的全部日期
        List<String> list = DateUtil.getPerDaysByStartAndEndDate(startDate, endDate, DateUtil.DATE_FORMAT);
        // 调用静态方法获取对应星期并返回实体集
        List<InternalDate> internalDateList = list.parallelStream().map(InternalDateServiceImpl::dateToWeek)
                .collect(Collectors.toList());
        // 遍历保存实体
        // internalDateList.forEach(single -> internalDateRepository.save(single));
//        internalDateRepository.saveAll(internalDateList);
        this.saveBatch(internalDateList);
        return "初始化成功";
    }
 
    /**
     * 根据给定日期判断星期几,并构建实体
     *
     * @param datetime
     * @return
     */
    public static InternalDate dateToWeek(String datetime) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance(); // 获得一个日历
        java.util.Date date = null;
        try {
            date = format.parse(datetime);
            cal.setTime(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。
        if (w < 0) {
            w = 0;
        }
        // 构建InternalDateDO
        int type;
        switch (weekDays[w]) {
            case "星期日":
                type = 2;
                break;
            case "星期六":
                type = 2;
                break;
            default:
                type = 1;
                break;
        }
        return new InternalDate(new Date(date.getTime()), type);
    }
 
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> importInternalDate(HttpServletRequest request, HttpServletResponse response,
                                                  MultipartFile file) throws EncryptedDocumentException, IOException {
        if (!file.isEmpty()) {
            String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            if (suffix.equalsIgnoreCase(".xls") || suffix.equalsIgnoreCase(".xlsx")) {
                Workbook workbook = WorkbookFactory.create(file.getInputStream());
                for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
                    Sheet sheet = workbook.getSheetAt(sheetNum);
                    if (sheet == null) {
                        continue;
                    }
                    for (int rowNum = 1; rowNum <= sheet.getLastRowNum(); rowNum++) {
                        Row row = sheet.getRow(rowNum);
                        if (row != null) {
                            Long time = null;
                            Integer typeValue = null;
                            try {
                                time = row.getCell(0).getDateCellValue().getTime();
                                typeValue = (int) row.getCell(1).getNumericCellValue();
                            } catch (NullPointerException | IllegalStateException e) {
                                throw new GlobalException("上传的Excel文件未能识别");
                            }
                            InternalDate internalDate = new InternalDate(new Date(time), typeValue);
//                            internalDateRepository.save(internalDate);
                            this.save(internalDate);
                        }
                    }
                }
                HashMap<String, Object> resultMap = new HashMap<>(1);
                resultMap.put("msg", "success");
                return resultMap;
            } else {
                throw new GlobalException("上传的不是Excel文件");
            }
        } else {
            throw new GlobalException("请选择文件");
        }
    }
 
    @Override
    public void downloadTemplate(HttpServletResponse response) throws IOException {
        try (InputStream is = Optional
                .ofNullable(getClass().getClassLoader().getResourceAsStream("holidaytemplate/holiday_template.xlsx"))
                .orElseThrow(() -> new NullPointerException("没有找到对应模板!"));
             // 通过响应获取输出流
             OutputStream os = response.getOutputStream();) {
            String docName = URLEncoder.encode("节假日模板", "UTF-8");
            // 设置响应类型为excel格式,附件形式,避免浏览器自动打开(例如:图片)
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-disposition", "attachment;filename=" + docName + ".xlsx");
            byte[] buff = new byte[2048];
            int len;
            while ((len = is.read(buff, 0, buff.length)) != -1) {
                os.write(buff, 0, len);
            }
        }
    }
 
    @Override
    public List<InternalDate> getInternalDatesByMonth(String yearAndMonth) {
        int year = Integer.parseInt(yearAndMonth.split("-")[0]);
        int month = Integer.parseInt(yearAndMonth.split("-")[1]);
        // 当月第一天
        String firstDayOfMonth = DateUtil.getFirstDayOfMonth(year, month);
        // 当月最后一天
        String lastDayOfMonth = DateUtil.getLastDayOfMonth(year, month);
        return this.list(new LambdaQueryWrapper<InternalDate>()
                .ge(InternalDate::getDate, DateUtil.formatDate(firstDayOfMonth, DateUtil.DATE_FORMAT))
                .le(InternalDate::getDate, DateUtil.formatDate(lastDayOfMonth, DateUtil.DATE_FORMAT))
                .orderByAsc(InternalDate::getDate));
//        java.util.Date firstDay = DateUtil.transStrToDate(firstDayOfMonth);
//        java.util.Date lastDay = DateUtil.transStrToDate(lastDayOfMonth);
//        return internalDateRepository.findAllByDateBetween(new Date(firstDay.getTime()), new Date(lastDay.getTime()),
//                new Sort(Direction.ASC, "date"));
    }
 
    @Override
    public InternalDate getInternalAfterInterval(java.util.Date utilDate, int interval) {
        Date sqlDate = new Date(utilDate.getTime());
        // 找出未来所有工作日
//        List<InternalDate> list = internalDateRepository.findByTypeAndDateAfterOrderByDateAsc(1, sqlDate);
        List<InternalDate> list = this.list(new LambdaQueryWrapper<InternalDate>()
                .gt(InternalDate::getDate, sqlDate)
                .eq(InternalDate::getType, InternalDate.TYPE_WORK)
                .orderByDesc(InternalDate::getDate));
        int index = interval - 1;
        if (list.size() <= index) {
            throw new GlobalException("节假日异常,请重新初始化节假日!");
        }
        // 取出指定天数后的工作日
        return list.get(index);
    }
 
    @Override
    public InternalDate getInternalBeforeInterval(String utilDate, int interval) {
        // 找出之前所有工作日
        List<InternalDate> list = this.list(new LambdaQueryWrapper<InternalDate>()
                .lt(InternalDate::getDate, DateUtil.formatDate(utilDate, DateUtil.DATE_FORMAT))
                .eq(InternalDate::getType, InternalDate.TYPE_WORK)
                .orderByAsc(InternalDate::getDate));
//        List<InternalDate> list = internalDateRepository.findByTypeAndDateBeforeOrderByDateAsc(1, sqlDate);
        int index = list.size() - interval - 1;
        if (index < 0) {
            throw new GlobalException("节假日异常,请重新初始化节假日!");
        }
        // 取出指定天数前的工作日
        return list.get(index);
    }
 
    @Override
    public boolean dateLimit(String startTime, String endTime, int days) {
        return dateLimit(startTime, endTime, days, true);
    }
 
    @Override
    public boolean dateLimit(String startTime, String endTime, int days, boolean isWork) {
        //找出时间范围内的工作日
        List<InternalDate> list = Optional.ofNullable(this.list(new LambdaQueryWrapper<InternalDate>()
                .gt(InternalDate::getDate, DateUtil.formatDate(startTime, DateUtil.DATE_FORMAT))
                .le(InternalDate::getDate, DateUtil.formatDate(endTime, DateUtil.DATE_FORMAT))
                .eq(isWork, InternalDate::getType, InternalDate.TYPE_WORK))).orElse(new ArrayList<>());
        if (list.size() < days) {
            return false;
        }
        return true;
    }
 
    /**
     * 初始化,如果系统未初始化日期则执行
     */
    @PostConstruct
    private void init() {
//        long count = internalDateRepository.count();
        long count = this.count();
        if (count == 0) {
            initInternalDate("2020-01-01", "2030-12-31");
        }
    }
 
}