|
@@ -1,21 +1,36 @@
|
|
|
package com.management.platform.service.impl;
|
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
|
|
-import com.management.platform.entity.DeviceCost;
|
|
|
-import com.management.platform.entity.User;
|
|
|
+import com.management.platform.entity.*;
|
|
|
+import com.management.platform.entity.vo.SysRichFunction;
|
|
|
import com.management.platform.mapper.DeviceCostMapper;
|
|
|
+import com.management.platform.mapper.DeviceLogMapper;
|
|
|
+import com.management.platform.mapper.DeviceMapper;
|
|
|
import com.management.platform.mapper.UserMapper;
|
|
|
import com.management.platform.service.DeviceCostService;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.management.platform.util.ExcelUtil;
|
|
|
import com.management.platform.util.HttpRespMsg;
|
|
|
+import com.management.platform.util.MessageUtils;
|
|
|
+import org.apache.commons.io.FileUtils;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.apache.poi.EncryptedDocumentException;
|
|
|
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
|
|
+import org.apache.poi.ss.usermodel.*;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
-import java.util.Arrays;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
+import java.io.*;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.math.RoundingMode;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
@@ -29,12 +44,21 @@ import java.util.stream.Collectors;
|
|
|
@Service
|
|
|
public class DeviceCostServiceImpl extends ServiceImpl<DeviceCostMapper, DeviceCost> implements DeviceCostService {
|
|
|
|
|
|
+ @Resource
|
|
|
+ private DeviceMapper deviceMapper;
|
|
|
+
|
|
|
@Resource
|
|
|
private DeviceCostMapper deviceCostMapper;
|
|
|
|
|
|
+ @Resource
|
|
|
+ private DeviceLogMapper deviceLogMapper;
|
|
|
+
|
|
|
@Resource
|
|
|
private UserMapper userMapper;
|
|
|
|
|
|
+ @Value(value = "${upload.path}")
|
|
|
+ private String path;
|
|
|
+
|
|
|
@Override
|
|
|
public HttpRespMsg getDeviceCostPage(HttpServletRequest request, DeviceCost deviceCost) {
|
|
|
HttpRespMsg httpRespMsg = new HttpRespMsg();
|
|
@@ -76,4 +100,235 @@ public class DeviceCostServiceImpl extends ServiceImpl<DeviceCostMapper, DeviceC
|
|
|
}
|
|
|
return httpRespMsg;
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public HttpRespMsg importDeviceCost(HttpServletRequest request, MultipartFile multipartFile,String ymonthStr) {
|
|
|
+ HttpRespMsg msg = new HttpRespMsg();
|
|
|
+ String token = request.getHeader("TOKEN");
|
|
|
+ User user = userMapper.selectById(token);
|
|
|
+
|
|
|
+ if (StringUtils.isEmpty(ymonthStr)){
|
|
|
+ msg.setError("请传递月份");
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
+
|
|
|
+ Integer companyId = user.getCompanyId();
|
|
|
+ //然后处理文件
|
|
|
+ String fileName = multipartFile.getOriginalFilename();
|
|
|
+ File file = new File(fileName == null ? "file" : fileName);
|
|
|
+ InputStream inputStream = null;
|
|
|
+ OutputStream outputStream = null;
|
|
|
+ try {
|
|
|
+ inputStream = multipartFile.getInputStream();
|
|
|
+ outputStream = new FileOutputStream(file);
|
|
|
+ byte[] buffer = new byte[4096];
|
|
|
+ int temp = 0;
|
|
|
+ while ((temp = inputStream.read(buffer, 0, 4096)) != -1) {
|
|
|
+ outputStream.write(buffer, 0, temp);
|
|
|
+ }
|
|
|
+ inputStream.close();
|
|
|
+ outputStream.close();
|
|
|
+ //然后解析表格
|
|
|
+ Workbook workbook = WorkbookFactory.create(new FileInputStream(file));
|
|
|
+ Sheet sheet = workbook.getSheetAt(0);
|
|
|
+ int rowNum = sheet.getLastRowNum();
|
|
|
+ if (rowNum == 0) {
|
|
|
+ msg.setError("请填写设备成本信息");
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
+ List<Device> deviceList = deviceMapper.selectList(new QueryWrapper<Device>().eq("company_id", companyId));
|
|
|
+ ArrayList<DeviceCost> deviceCostArrayList = new ArrayList<>();
|
|
|
+ int dataIndex = 1;
|
|
|
+ for (int rowIndex = 1; rowIndex <= rowNum; rowIndex++) {
|
|
|
+ Row row = sheet.getRow(rowIndex);
|
|
|
+ if (row == null) {
|
|
|
+ dataIndex++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (ExcelUtil.isRowEmpty(row)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ boolean NoExists = false;
|
|
|
+ for (int i = 0; i < 3; i++) {
|
|
|
+ if (row.getCell(i) != null) {
|
|
|
+ row.getCell(i).setCellType(CellType.STRING);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (row.getCell(0) == null) {
|
|
|
+ msg.setError("第"+dataIndex+"行缺少设备编号");
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
+ if (row.getCell(1) == null) {
|
|
|
+ msg.setError("第"+dataIndex+"行缺少设备名称");
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
+ if (row.getCell(2) == null) {
|
|
|
+ msg.setError("第"+dataIndex+"行缺少当月成本");
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
+ String deviceCode = row.getCell(0)==null?null:row.getCell(0).getStringCellValue();
|
|
|
+ String deviceName = row.getCell(1)==null?null:row.getCell(1).getStringCellValue();
|
|
|
+ String monthCost = row.getCell(2)==null?null:row.getCell(2).getStringCellValue();
|
|
|
+ if (StringUtils.isNotEmpty(deviceCode)&&StringUtils.isNotEmpty(deviceName)&&StringUtils.isNotEmpty(monthCost)){
|
|
|
+ for (Device device : deviceList) {
|
|
|
+ if (deviceCode.equals(device.getDeviceCode())){
|
|
|
+ NoExists=true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (NoExists){
|
|
|
+ Optional<Device> optional = deviceList.stream().filter(d -> d.getDeviceCode().equals(deviceCode)).findFirst();
|
|
|
+ if (optional.isPresent()){
|
|
|
+ Device device = optional.get();
|
|
|
+ if (!deviceName.equals(device.getDeviceName())){
|
|
|
+ msg.setError("第"+dataIndex+"行设备名称不匹配");
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
+ if (BigDecimal.valueOf(Long.parseLong(monthCost)).compareTo(BigDecimal.ZERO)<0){
|
|
|
+ msg.setError("第"+dataIndex+"行当月成本为负数");
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
+ DeviceCost deviceCost = new DeviceCost();
|
|
|
+ deviceCost.setDeviceId(device.getId());
|
|
|
+ deviceCost.setMonthCost(BigDecimal.valueOf(Double.parseDouble(monthCost)));
|
|
|
+ deviceCost.setYmonth(ymonthStr);
|
|
|
+
|
|
|
+ if (!deviceCostArrayList.isEmpty()){
|
|
|
+ long count = deviceCostArrayList.stream().filter(c -> c.getDeviceId().equals(deviceCost.getDeviceId())).count();
|
|
|
+ if (count>0){
|
|
|
+ msg.setError("存在与第"+dataIndex+"行重复的设备成本数据");
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ deviceCostArrayList.add(deviceCost);
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ msg.setError("第"+dataIndex+"行填写的设备编号跟所在公司不匹配");
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ dataIndex++;
|
|
|
+ }
|
|
|
+ List<DeviceCost> selectedList = deviceCostMapper.selectList(new QueryWrapper<DeviceCost>().eq("ymonth", ymonthStr));
|
|
|
+ if(!deviceCostArrayList.isEmpty()){
|
|
|
+ int i = 0;
|
|
|
+ for (DeviceCost deviceCost : deviceCostArrayList) {
|
|
|
+ if (!selectedList.isEmpty()){
|
|
|
+ long count = selectedList.stream().filter(s -> s.getDeviceId().equals(deviceCost.getDeviceId()) && s.getYmonth().equals(deviceCost.getYmonth())).count();
|
|
|
+ if (count>0){
|
|
|
+ deviceCostMapper.update(null,new UpdateWrapper<DeviceCost>()
|
|
|
+ .eq("ymonth",ymonthStr)
|
|
|
+ .eq("device_id",deviceCost.getDeviceId()).set("month_cost",deviceCost.getMonthCost()));
|
|
|
+ i++;
|
|
|
+ }else {
|
|
|
+ deviceCostMapper.insert(deviceCost);
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ deviceCostMapper.insert(deviceCost);
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ String[] strings = ymonthStr.split("-");
|
|
|
+ int year = Integer.parseInt(strings[0]);
|
|
|
+ int month = Integer.parseInt(strings[1]);
|
|
|
+ // 获取该月份的第一天
|
|
|
+ String startDate = String.format("%04d-%02d-01", year, month);
|
|
|
+ // 获取该月的最后一天
|
|
|
+ LocalDate lastDate = LocalDate.of(year, month, 1).plusDays(LocalDate.of(year, month, 1).lengthOfMonth() - 1);
|
|
|
+ String endDate = String.format("%04d-%02d-%02d", year, month, lastDate.getDayOfMonth());
|
|
|
+
|
|
|
+ List<DeviceLog> deviceLogs = deviceLogMapper.selectList(new QueryWrapper<DeviceLog>()
|
|
|
+ .between("create_date", startDate, endDate)
|
|
|
+ .isNotNull("end_time"));
|
|
|
+ for (DeviceCost deviceCost : deviceCostArrayList) {
|
|
|
+ BigDecimal monthCost = deviceCost.getMonthCost();
|
|
|
+ Integer deviceId = deviceCost.getDeviceId();
|
|
|
+ double sumTime = deviceLogs.stream().filter(dl -> dl.getDeviceId().equals(deviceId)).mapToDouble(DeviceLog::getUseTime).sum();
|
|
|
+ if (sumTime>0){
|
|
|
+ BigDecimal result = monthCost.divide(BigDecimal.valueOf(sumTime), 2, RoundingMode.HALF_UP);
|
|
|
+ List<DeviceLog> deviceLogList = deviceLogs.stream().filter(dl -> dl.getDeviceId().equals(deviceId)).collect(Collectors.toList());
|
|
|
+ for (DeviceLog deviceLog : deviceLogList) {
|
|
|
+ Double useTime = deviceLog.getUseTime();
|
|
|
+ BigDecimal multiply = BigDecimal.valueOf(useTime).multiply(result);
|
|
|
+ deviceLog.setUsageCost(multiply);
|
|
|
+ }
|
|
|
+ List<DeviceLog> sortList = deviceLogList.stream()
|
|
|
+ .sorted(Comparator.comparing(DeviceLog::getId).reversed())
|
|
|
+ .collect(Collectors.toList());// 根据 id 降序排序
|
|
|
+ if (sortList.size()>1){
|
|
|
+ DeviceLog deviceLog0 = sortList.get(0);
|
|
|
+ List<DeviceLog> deviceLogs2 = sortList.subList(1, sortList.size());
|
|
|
+ BigDecimal reduce = deviceLogs2.stream().map(DeviceLog::getUsageCost).reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+ BigDecimal subtract = monthCost.subtract(reduce);
|
|
|
+ deviceLog0.setUsageCost(subtract);
|
|
|
+ deviceLogs2.add(0, deviceLog0);
|
|
|
+
|
|
|
+ for (DeviceLog deviceLog : deviceLogs2) {
|
|
|
+ deviceLogMapper.update(null,new UpdateWrapper<DeviceLog>().eq("id", deviceLog.getId()).set("usage_cost", deviceLog.getUsageCost()));
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ DeviceLog deviceLog = sortList.get(0);
|
|
|
+ deviceLog.setUsageCost(monthCost);
|
|
|
+ deviceLogMapper.update(null,new UpdateWrapper<DeviceLog>().eq("id", deviceLog.getId()).set("usage_cost", deviceLog.getUsageCost()));
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ msg.data = i;
|
|
|
+ String originName = fileName;
|
|
|
+ //定义一个独立的文件夹
|
|
|
+ String importFolder = "deviceCost_import";
|
|
|
+ File dir = new File(path, importFolder);
|
|
|
+ if (!dir.exists()) {
|
|
|
+ dir.mkdir();
|
|
|
+ }
|
|
|
+
|
|
|
+ System.out.println("fileName=="+originName);
|
|
|
+ String[] names = originName.split("\\.");
|
|
|
+ String destFileName = names[0] + "_"+System.currentTimeMillis()+"."+names[1];
|
|
|
+ File destFile = new File(dir, destFileName);
|
|
|
+ FileUtils.copyFile(file, destFile);
|
|
|
+ }
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ //msg.setError("文件处理出错");
|
|
|
+ msg.setError(MessageUtils.message("file.error"));
|
|
|
+ return msg;
|
|
|
+ } catch (NullPointerException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ //msg.setError("数据格式有误或存在空数据 导入失败");
|
|
|
+ msg.setError(MessageUtils.message("file.dataFormatError"));
|
|
|
+ return msg;
|
|
|
+ }catch (InvalidFormatException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ //msg.setError("文件格式错误,如果安装了加密软件需要先解密再上传");
|
|
|
+ msg.setError(MessageUtils.message("file.FormatErrorAndDecrypt"));
|
|
|
+ return msg;
|
|
|
+ }catch (EncryptedDocumentException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ //msg.setError("文件加密状态,需要先解除加密状态再上传");
|
|
|
+ msg.setError(MessageUtils.message("file.encryption"));
|
|
|
+ return msg;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ //msg.setError("发生其他错误:"+e.getMessage());
|
|
|
+ msg.setError(MessageUtils.message("other.errorByParameter",e.getMessage()));
|
|
|
+ return msg;
|
|
|
+ } finally {
|
|
|
+ //关闭流
|
|
|
+ try {
|
|
|
+ if (outputStream != null && inputStream != null) {
|
|
|
+ outputStream.close();
|
|
|
+ inputStream.close();
|
|
|
+ }
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ file.delete();
|
|
|
+ }
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
}
|