Commit d1b68e88 authored by kiritoausna's avatar kiritoausna

2025.6.3 提交

parent 5678dc1b
...@@ -55,4 +55,6 @@ public interface CacheKey { ...@@ -55,4 +55,6 @@ public interface CacheKey {
* 数据字典 * 数据字典
*/ */
String DICT_NAME = "dict::name:"; String DICT_NAME = "dict::name:";
String CHULIANG_TOKEN="chuliang:token";
} }
...@@ -18,7 +18,10 @@ package me.zhengjie.utils; ...@@ -18,7 +18,10 @@ package me.zhengjie.utils;
import java.time.*; import java.time.*;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List;
/** /**
* @author: liaojinlong * @author: liaojinlong
...@@ -157,4 +160,20 @@ public class DateUtil { ...@@ -157,4 +160,20 @@ public class DateUtil {
public static LocalDateTime parseLocalDateTimeFormatyMdHms(String localDateTime) { public static LocalDateTime parseLocalDateTimeFormatyMdHms(String localDateTime) {
return LocalDateTime.from(DFY_MD_HMS.parse(localDateTime)); return LocalDateTime.from(DFY_MD_HMS.parse(localDateTime));
} }
/**
* 计算起止日期所有日期(年月日),并返回字符串格式的日期列表
*
* @param startDate 开始日期
* @param endDate 结束日期
* @return 包含所有日期的字符串列表
*/
public static List<String> getAllDatesBetweenAsString(LocalDate startDate, LocalDate endDate) {
List<String> dateStrings = new ArrayList<>();
long numOfDaysBetween = ChronoUnit.DAYS.between(startDate, endDate);
for (long i = 0; i <= numOfDaysBetween; i++) {
LocalDate currentDate = startDate.plusDays(i);
dateStrings.add(currentDate.toString()); // 将日期转换为字符串格式
}
return dateStrings;
}
} }
...@@ -32,6 +32,7 @@ import javax.servlet.ServletOutputStream; ...@@ -32,6 +32,7 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.*; import java.io.*;
import java.net.URLEncoder;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
...@@ -415,6 +416,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { ...@@ -415,6 +416,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
File file = new File(path); File file = new File(path);
// 取得文件名。 // 取得文件名。
String filename = file.getName(); String filename = file.getName();
filename = URLEncoder.encode(filename,"UTF-8");
// 取得文件的后缀名。 // 取得文件的后缀名。
String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase(); String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();
...@@ -426,11 +428,13 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { ...@@ -426,11 +428,13 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
// 清空response // 清空response
response.reset(); response.reset();
// 设置response的Header // 设置response的Header
//response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes())); response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
response.addHeader("Content-Length", "" + file.length()); response.addHeader("Content-Length", "" + file.length());
OutputStream toClient = new BufferedOutputStream(response.getOutputStream()); OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream"); response.setContentType("application/octet-stream;charset=utf-8");
toClient.write(buffer); toClient.write(buffer);
toClient.flush(); toClient.flush();
toClient.close(); toClient.close();
......
...@@ -29,6 +29,12 @@ ...@@ -29,6 +29,12 @@
<artifactId>eladmin-tools</artifactId> <artifactId>eladmin-tools</artifactId>
<version>2.6</version> <version>2.6</version>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.4</version>
</dependency>
</dependencies> </dependencies>
</project> </project>
\ No newline at end of file
package me.zhengjie.rbscreen.controller;
import me.zhengjie.rbscreen.service.PerHistoryService;
import me.zhengjie.rbscreen.util.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("api/per/screen")
@RestController
public class PerScreenController {
@Autowired
private PerHistoryService perHistoryService;
// 查询所有人员实时位置
@GetMapping("real")
public ResponseEntity getAllReal() {
return ResponseEntity.ok(AjaxResult.success(perHistoryService.getAllReal()));
}
}
package me.zhengjie.rbscreen.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import me.zhengjie.ruibo.domain.PerInfo;
@Data
public class PerInfoRealDto {
private Integer id;
private String perName;
private String phone;
private String perImei;
private String perSex;
private String perTel;
private String perNumber;
private String perDept;
private String perOffice;
private String lat;
private String lng;
private String hight;
}
package me.zhengjie.rbscreen.mapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.HashMap;
import java.util.List;
@Mapper
public interface PerHistoryMapper {
List<HashMap<String, Object>> getAllReal(String time);
}
package me.zhengjie.rbscreen.service;
public interface PerHistoryService {
Object getAllReal();
}
package me.zhengjie.rbscreen.service.impl;
import me.zhengjie.rbscreen.mapper.PerHistoryMapper;
import me.zhengjie.rbscreen.service.PerHistoryService;
import me.zhengjie.ruibo.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
@Service
public class PerHistoryServiceImpl implements PerHistoryService {
@Autowired
private PerHistoryMapper perHistoryMapper;
@Override
public Object getAllReal() {
String nowMonthInt = StringUtils.getNowMonthInt();
List<HashMap<String, Object>> allReal = perHistoryMapper.getAllReal(nowMonthInt);
return allReal;
}
}
package me.zhengjie.ruibo.controller; package me.zhengjie.ruibo.controller;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import me.zhengjie.annotation.AnonymousAccess; import me.zhengjie.annotation.AnonymousAccess;
import me.zhengjie.rbscreen.domain.vo.DataQueryCriteria;
import me.zhengjie.rbscreen.util.AjaxResult; import me.zhengjie.rbscreen.util.AjaxResult;
import me.zhengjie.ruibo.domain.DiBang;
import me.zhengjie.ruibo.domain.DiBangMysql; import me.zhengjie.ruibo.domain.DiBangMysql;
import me.zhengjie.ruibo.service.DiBangMysqlService; import me.zhengjie.ruibo.service.DiBangMysqlService;
import me.zhengjie.ruibo.service.DiBangService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.List; import java.util.List;
...@@ -20,6 +22,8 @@ import java.util.List; ...@@ -20,6 +22,8 @@ import java.util.List;
public class DiBangController { public class DiBangController {
@Autowired @Autowired
private DiBangMysqlService diBangMysqlService; private DiBangMysqlService diBangMysqlService;
// 初始化单位字符串
public static final String UNIT_STRING = "t";
@RequestMapping("list") @RequestMapping("list")
@AnonymousAccess @AnonymousAccess
...@@ -30,11 +34,29 @@ public class DiBangController { ...@@ -30,11 +34,29 @@ public class DiBangController {
/** /**
* 分页查询 * 分页查询
*
* @return * @return
*/ */
@GetMapping("page") @GetMapping("page")
public ResponseEntity getDiBangPage() { public ResponseEntity getDiBangPage(DataQueryCriteria dataQueryCriteria, @RequestParam(defaultValue = "0") Long page, @RequestParam(defaultValue = "10") Long size) {
return ResponseEntity.ok(AjaxResult.success(diBangMysqlService.page(null))); Page diBangMysqlPage = new Page<DiBangMysql>(page, size);
Page diBangPage = diBangMysqlService.getDiBangPage(dataQueryCriteria, diBangMysqlPage);
//统计day
int day = diBangMysqlService.cycleStatistics("day");
//统计 周
int week = diBangMysqlService.cycleStatistics("week");
// 统计 月
int month = diBangMysqlService.cycleStatistics("month");
// 统计 年
int year = diBangMysqlService.cycleStatistics("year");
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("当天称重量: ").append(day).append(UNIT_STRING).append("; ")
.append("本周称重量: ").append(week).append(UNIT_STRING).append("; ")
.append("本月称重量: ").append(month).append(UNIT_STRING).append("; ")
.append("本年称重量: ").append(year).append(UNIT_STRING);
AjaxResult success = AjaxResult.success(diBangPage);
success.put("cycleStatistics", stringBuffer.toString());
return ResponseEntity.ok(success);
} }
@GetMapping("real") @GetMapping("real")
...@@ -42,8 +64,10 @@ public class DiBangController { ...@@ -42,8 +64,10 @@ public class DiBangController {
DiBangMysql diBang = diBangMysqlService.getRealDiBang(); DiBangMysql diBang = diBangMysqlService.getRealDiBang();
return ResponseEntity.ok(AjaxResult.success(diBang)); return ResponseEntity.ok(AjaxResult.success(diBang));
} }
@GetMapping("cycleStatistics") @GetMapping("cycleStatistics")
public ResponseEntity cycleStatistics(String dateRange) { public ResponseEntity cycleStatistics(String dateRange) {
return ResponseEntity.ok(AjaxResult.success(diBangMysqlService.cycleStatistics(dateRange))); return ResponseEntity.ok(AjaxResult.success(diBangMysqlService.cycleStatistics(dateRange)));
} }
} }
package me.zhengjie.ruibo.controller;
import me.zhengjie.rbscreen.domain.vo.BadRequestException;
import me.zhengjie.rbscreen.util.AjaxResult;
import me.zhengjie.ruibo.domain.PerInfo;
import me.zhengjie.ruibo.service.PerInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/perInfo")
public class PerInfoController {
@Autowired
private PerInfoService perInfoService;
// 查询所有人员信息
@GetMapping
public List<PerInfo> getAllPerInfo() {
return perInfoService.list();
}
// 分页查询
@GetMapping("page")
public ResponseEntity<Object> pageAll(Long page, Long size, PerInfo perInfo) {
Map result = perInfoService.pageAll(page, size, perInfo);
return ResponseEntity.ok(AjaxResult.success(result));
}
// 根据 ID 查询人员信息
@GetMapping("/{id}")
public PerInfo getPerInfoById(@PathVariable Integer id) {
return perInfoService.getById(id);
}
// 添加人员信息
@PostMapping
public ResponseEntity<Object> addPerInfo(@RequestBody PerInfo perInfo) {
try {
perInfoService.save(perInfo);
} catch (Exception e) {
if (e instanceof SQLIntegrityConstraintViolationException) {
boolean duplicate = e.getMessage().contains("Duplicate");
if (duplicate) {
throw new BadRequestException(" 存在重复手机号或者定位卡ID!");
}
}
}
return ResponseEntity.ok(AjaxResult.success());
}
// 导出人员基本信息模版文件
@GetMapping("exportTemplate")
public void exportTemplate(HttpServletResponse response) {
perInfoService.exportTemplate(response);
}
// 导入人员基本信息
@PostMapping("import")
public ResponseEntity<Object> importPerInfo(MultipartFile file) throws IOException {
perInfoService.importPerInfo(file);
return ResponseEntity.ok(AjaxResult.success("导入成功"));
}
// 更新人员信息
@PutMapping
public ResponseEntity<Object> updatePerInfo(@RequestBody PerInfo perInfo) {
try {
perInfoService.updateById(perInfo);
} catch (Exception e) {
if (e instanceof SQLIntegrityConstraintViolationException) {
boolean duplicate = e.getMessage().contains("Duplicate");
if (duplicate) {
throw new BadRequestException(" 存在重复手机号或者定位卡ID!");
}
}
}
return ResponseEntity.ok(AjaxResult.success());
}
// 根据 ID 删除人员信息
@DeleteMapping("/{ids}")
public ResponseEntity<Object> deletePerInfo(@PathVariable Long[] ids) {
for (Long id : ids) {
perInfoService.removeById(id);
}
return ResponseEntity.ok(AjaxResult.success());
}
}
\ No newline at end of file
package me.zhengjie.ruibo.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("per_info")
public class PerInfo {
@TableId(type = IdType.AUTO)
private Integer id;
@TableField(value = "per_name")
private String perName;
private String phone;
@TableField(value = "per_imei")
private String perImei;
@TableField(value = "per_sex")
private Integer perSex;
@TableField(value = "per_tel")
private String perTel;
@TableField(value = "per_number")
private String perNumber;
@TableField(value = "per_dept")
private String perDept;
@TableField(value = "per_office")
private String perOffice;
@TableField(value = "safe_educate")
private String safeEducate;
private String temporary;
}
\ No newline at end of file
package me.zhengjie.ruibo.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import me.zhengjie.ruibo.excel.converter.SexConverter;
@Data
public class PerInfoExcelDto {
@ExcelProperty(value = "姓名", index = 0)
private String perName;
@ExcelProperty(value = "性别", index = 1, converter = SexConverter.class)
private Integer perSex;
@ExcelProperty(value = "工号", index = 2)
private String perNumber;
@ExcelProperty(value = "部门", index = 3)
private String perDept;
@ExcelProperty(value = "职务", index = 4)
private String perOffice;
@ExcelProperty(value = "人员手机号", index = 5)
private String perTel;
@ExcelProperty(value = "定位卡ID", index = 6)
private String phone;
@ExcelProperty(value = "定位卡IMEI", index = 7)
private String perImei;
@ExcelProperty(value = "三级安全教育是否通过", index = 8)
private String safeEducate;
@ExcelProperty(value = "是否为临时卡", index = 9)
private String temporary;
}
package me.zhengjie.ruibo.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.rbscreen.domain.vo.BadRequestException;
import me.zhengjie.ruibo.service.mapper.PerInfoMapper;
import org.springframework.util.ObjectUtils;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
// 有个很重要的点 PerInfoExcelDtoListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
@Slf4j
public class PerInfoExcelDtoListener implements ReadListener<PerInfoExcelDto> {
/**
* 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
*/
private static final int BATCH_COUNT = 100;
private static List<String> phoneList = null;
private static boolean phoneFlag = true;
private static List<String> perTelList = null;
private static boolean perTelFlag = true;
/**
* 缓存的数据
*/
private List<PerInfoExcelDto> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
private PerInfoMapper perInfoMapper;
/**
* 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
*
* @param perInfoMapper
*/
public PerInfoExcelDtoListener(PerInfoMapper perInfoMapper) {
this.phoneFlag = true;
this.phoneList = null;
this.perTelFlag = true;
this.perTelList = null;
this.perInfoMapper = perInfoMapper;
}
/**
* 这个每一条数据解析都会来调用
*
* @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}
* @param context
*/
@Override
public void invoke(PerInfoExcelDto data, AnalysisContext context) {
// log.info("解析到一条数据:{}", JSON.toJSONString(data));
boolean lineNullValue = this.isLineNullValue(data);
if (lineNullValue) {
return;
}
cachedDataList.add(data);
// 新增一条之前先要去比对 数据库是否存在相同的手机号
if (phoneFlag && ObjectUtils.isEmpty(phoneList)) {
List<String> strings = perInfoMapper.selectPhoneAll();
if (ObjectUtils.isEmpty(strings)) {
phoneFlag = false;
} else {
phoneList = strings;
}
}
if (!ObjectUtils.isEmpty(phoneList)) {
if (phoneList.contains(data.getPhone())) {
Field phone = null;
try {
phone = data.getClass().getDeclaredField("phone");
} catch (NoSuchFieldException e) {
}
ExcelProperty excelProperty = phone.getAnnotation(ExcelProperty.class);
int index = excelProperty.index();
throw new BadRequestException("第" + context.readRowHolder().getRowIndex() + "行" +
",第" + (index + 1) + "列 存在和数据库重复的定位卡ID!");
}
}
if (perTelFlag && ObjectUtils.isEmpty(perTelList)) {
List<String> strings = perInfoMapper.selectPerTelAll();
if (ObjectUtils.isEmpty(strings)) {
perTelFlag = false;
} else {
perTelList = strings;
}
}
if (!ObjectUtils.isEmpty(perTelList)) {
if (perTelList.contains(data.getPerTel())) {
Field phone = null;
try {
phone = data.getClass().getDeclaredField("perTel");
} catch (NoSuchFieldException e) {
}
ExcelProperty excelProperty = phone.getAnnotation(ExcelProperty.class);
int index = excelProperty.index();
throw new BadRequestException("第" + context.readRowHolder().getRowIndex() + "行" +
",第" + (index + 1) + "列 存在和数据库重复的手机号码!");
}
}
}
/**
* 异常方法 (类型转换异常也会执行此方法) (读取一行抛出异常也会执行此方法)
*
* @param exception
* @param context
* @throws Exception
*/
@Override
public void onException(Exception exception, AnalysisContext context) {
// 如果是某一个单元格的转换异常 能获取到具体行号
// 如果要获取头的信息 配合invokeHeadMap使用
if (exception instanceof ExcelDataConvertException) {
ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
log.error("第{}行,第{}列解析异常,数据为:{}", excelDataConvertException.getRowIndex(),
excelDataConvertException.getColumnIndex(), excelDataConvertException.getCellData());
throw new RuntimeException("第" + excelDataConvertException.getRowIndex() + "行" +
",第" + (excelDataConvertException.getColumnIndex() + 1) + "列读取错误");
} else if (exception instanceof BadRequestException) {
throw new BadRequestException(exception.getMessage());
}
}
/**
* 所有数据解析完成了 都会来调用
*
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 这里也要保存数据,确保最后遗留的数据也存储到数据库
saveData();
log.info("所有数据解析完成!");
}
/**
* 加上存储数据库
*/
private void saveData() {
log.info("{}条数据,开始存储数据库!", cachedDataList.size());
perInfoMapper.insertBatchExcel(cachedDataList);
log.info("存储数据库成功!");
}
/**
* 判断整行单元格数据是否均为空
*/
private boolean isLineNullValue(PerInfoExcelDto data) {
try {
List<Field> fields = Arrays.stream(data.getClass().getDeclaredFields())
.filter(f -> f.isAnnotationPresent(ExcelProperty.class))
.collect(Collectors.toList());
List<Boolean> lineNullList = new ArrayList<>(fields.size());
for (Field field : fields) {
field.setAccessible(true);
Object value = field.get(data);
if (ObjectUtils.isEmpty(value)) {
lineNullList.add(Boolean.TRUE);
} else {
lineNullList.add(Boolean.FALSE);
}
}
return lineNullList.stream().allMatch(Boolean.TRUE::equals);
} catch (Exception e) {
log.error("读取数据行[{}]解析失败: {}", data, e.getMessage());
}
return true;
}
}
\ No newline at end of file
package me.zhengjie.ruibo.excel.converter;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import me.zhengjie.rbscreen.domain.vo.BadRequestException;
/**
* 性别由数据库的0/1 转换成
*/
public class SexConverter implements Converter<Integer> {
@Override
public Class<?> supportJavaTypeKey() {
return Integer.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
@Override
public Integer convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
String stringValue = cellData.getStringValue();
switch (stringValue) {
case "男":
return 1;
case "女":
return 0;
default:
throw new BadRequestException("存在未知性别");
}
}
@Override
public WriteCellData<?> convertToExcelData(Integer value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
switch (value) {
case 1:
return new WriteCellData<>("男");
case 0:
return new WriteCellData<>("女");
default:
throw new BadRequestException("存在未知性别");
}
}
}
package me.zhengjie.ruibo.service; package me.zhengjie.ruibo.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import me.zhengjie.rbscreen.domain.vo.DataQueryCriteria;
import me.zhengjie.ruibo.domain.DiBangMysql; import me.zhengjie.ruibo.domain.DiBangMysql;
import java.util.HashMap; import java.util.HashMap;
...@@ -9,7 +11,10 @@ import java.util.List; ...@@ -9,7 +11,10 @@ import java.util.List;
public interface DiBangMysqlService extends IService<DiBangMysql> { public interface DiBangMysqlService extends IService<DiBangMysql> {
DiBangMysql getRealDiBang(); DiBangMysql getRealDiBang();
void insertBatch(List<DiBangMysql> diBangMysqlList); void insertBatch(List<DiBangMysql> diBangMysqlList);
List<HashMap> cycleStatistics(String dateRange); int cycleStatistics(String dateRange);
Page getDiBangPage(DataQueryCriteria dataQueryCriteria, Page<DiBangMysql> page);
} }
package me.zhengjie.ruibo.service;
import com.baomidou.mybatisplus.extension.service.IService;
import me.zhengjie.ruibo.domain.PerInfo;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
public interface PerInfoService extends IService<PerInfo> {
Map pageAll(Long page, Long size, PerInfo perInfo);
void importPerInfo(MultipartFile multipartFile) throws IOException;
void exportTemplate(HttpServletResponse response);
}
\ No newline at end of file
package me.zhengjie.ruibo.service.impl; package me.zhengjie.ruibo.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.rbscreen.domain.vo.DataQueryCriteria;
import me.zhengjie.ruibo.domain.DiBangMysql; import me.zhengjie.ruibo.domain.DiBangMysql;
import me.zhengjie.ruibo.service.DiBangMysqlService; import me.zhengjie.ruibo.service.DiBangMysqlService;
import me.zhengjie.ruibo.service.mapper.DiBangMysqlMapper; import me.zhengjie.ruibo.service.mapper.DiBangMysqlMapper;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
...@@ -16,6 +24,10 @@ import java.util.List; ...@@ -16,6 +24,10 @@ import java.util.List;
public class DiBangMysqlServiceImpl extends ServiceImpl<DiBangMysqlMapper, DiBangMysql> implements DiBangMysqlService { public class DiBangMysqlServiceImpl extends ServiceImpl<DiBangMysqlMapper, DiBangMysql> implements DiBangMysqlService {
private final DiBangMysqlMapper diBangMysqlMapper; private final DiBangMysqlMapper diBangMysqlMapper;
// 初始化定义 起始时间拼接字符串
private static final String START_DATE_STRING = " 00:00:00";
// 初始化定义结束时间拼接字符串
private static final String END_DATE_STRING = " 23:59:59";
@Override @Override
public DiBangMysql getRealDiBang() { public DiBangMysql getRealDiBang() {
DiBangMysql realDiBangMysql = diBangMysqlMapper.getRealDiBang(); DiBangMysql realDiBangMysql = diBangMysqlMapper.getRealDiBang();
...@@ -28,7 +40,66 @@ public class DiBangMysqlServiceImpl extends ServiceImpl<DiBangMysqlMapper, DiBan ...@@ -28,7 +40,66 @@ public class DiBangMysqlServiceImpl extends ServiceImpl<DiBangMysqlMapper, DiBan
} }
@Override @Override
public List<HashMap> cycleStatistics(String dateRange) { public int cycleStatistics(String dateRange) {
return diBangMysqlMapper.cycleStatistics(dateRange); // 创建startDate ,endDate
String startDate = "";
String endDate = "";
// 获取当天时间
LocalDate now = LocalDate.now();
// 查询数据
switch (dateRange){
case "day":
// 计算当天的0时到24时
String string = now.toString();
startDate = string + START_DATE_STRING;
endDate = string + END_DATE_STRING;
break;
case "week":
// 计算本周时间
startDate = now.with(DayOfWeek.MONDAY).toString() +START_DATE_STRING;
endDate = now.with(DayOfWeek.SUNDAY).toString() +END_DATE_STRING;
break;
case "month":
// 计算本月的起止时间
startDate = now.withDayOfMonth(1).toString() +START_DATE_STRING;
endDate = now.withDayOfMonth(now.lengthOfMonth()).toString() +END_DATE_STRING;
break;
case "year":
//计算本年的起止时间
startDate = now.withDayOfYear(1).toString() +START_DATE_STRING;
endDate = now.withDayOfYear(now.lengthOfYear()).toString() +END_DATE_STRING;
break;
default:
// 默认
throw new BadRequestException("未指定查询周期");
}
return diBangMysqlMapper.cycleStatistics(startDate,endDate);
} }
@Override
public Page getDiBangPage(DataQueryCriteria dataQueryCriteria, Page<DiBangMysql> page) {
QueryWrapper<DiBangMysql> diBangMysqlQueryWrapper = new QueryWrapper<>();
// 分页查询
List<String> range = dataQueryCriteria.getRange();
if (!CollectionUtils.isEmpty(range)) {
if (range.size() >= 2) {
diBangMysqlQueryWrapper.between("weight_time", range.get(0)+START_DATE_STRING, range.get(1)+END_DATE_STRING);
}
}
diBangMysqlQueryWrapper.orderByDesc("weight_time");
page = diBangMysqlMapper.selectPage(page, diBangMysqlQueryWrapper);
return page;
}
public static void main(String[] args) {
LocalDate now = LocalDate.now();
String string = now.with(DayOfWeek.MONDAY).toString() + " 00:00:00";
String end = now.with(DayOfWeek.SUNDAY).toString() + " 00:00:00";
System.out.println("string = " + string+"******"+end);
String string1 = "[\"2024-01-01\",\"2025-01-09\"]";
List<List> lists = JSONObject.parseArray(string1, List.class);
System.out.println("lists = " + lists);
}
} }
package me.zhengjie.ruibo.service.impl;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import me.zhengjie.ruibo.domain.PerInfo;
import me.zhengjie.ruibo.excel.PerInfoExcelDto;
import me.zhengjie.ruibo.excel.PerInfoExcelDtoListener;
import me.zhengjie.ruibo.service.PerInfoService;
import me.zhengjie.ruibo.service.mapper.PerInfoMapper;
import me.zhengjie.ruibo.utils.StringUtils;
import me.zhengjie.utils.FileUtil;
import me.zhengjie.utils.PageUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Map;
@Service
public class PerInfoServiceImpl extends ServiceImpl<PerInfoMapper, PerInfo> implements PerInfoService {
@Autowired
private PerInfoMapper perInfoMapper;
@Override
public Map pageAll(Long page, Long size, PerInfo perInfo) {
Page<PerInfo> perInfoPage = new Page<PerInfo>(page, size);
QueryWrapper<PerInfo> perInfoQueryWrapper = new QueryWrapper<>();
// 构建查询条件
//
Field[] fields = perInfo.getClass().getFields();
for (Field field : fields) {
try {
// 设置可访问私有字段
field.setAccessible(true);
// 获取字段的值
Object value = field.get(perInfo);
// 判断字段值是否不为空
if (value != null) {
String name = field.getName();
//
String camelToSnake = StringUtils.camelToSnake(name);
perInfoQueryWrapper.eq(camelToSnake, value);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
perInfoQueryWrapper.orderByDesc("id");
Page<PerInfo> resultPage = perInfoMapper.selectPage(perInfoPage, perInfoQueryWrapper);
Map resultMap = PageUtil.toPage(resultPage);
return resultMap;
}
@Override
public void importPerInfo(MultipartFile multipartFile) throws IOException {
InputStream inputStream = multipartFile.getInputStream();
EasyExcel.read(inputStream, PerInfoExcelDto.class, new PerInfoExcelDtoListener(perInfoMapper)).sheet().doRead();
}
@Override
public void exportTemplate(HttpServletResponse response) {
FileUtil.download(System.getProperty("user.dir") + "/import/人员基础信息导入模版.xlsx", response);
}
}
\ No newline at end of file
...@@ -2,16 +2,14 @@ package me.zhengjie.ruibo.service.mapper; ...@@ -2,16 +2,14 @@ package me.zhengjie.ruibo.service.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import me.zhengjie.ruibo.domain.DiBang;
import me.zhengjie.ruibo.domain.DiBangMysql; import me.zhengjie.ruibo.domain.DiBangMysql;
import java.util.HashMap;
import java.util.List; import java.util.List;
public interface DiBangMysqlMapper extends BaseMapper<DiBangMysql> { public interface DiBangMysqlMapper extends BaseMapper<DiBangMysql> {
DiBangMysql getRealDiBang(); DiBangMysql getRealDiBang();
List<HashMap> cycleStatistics(String dateRange); int cycleStatistics(String startDate, String endDate);
void insertBatch(List<DiBangMysql> diBangMysqlList); void insertBatch(List<DiBangMysql> diBangMysqlList);
} }
package me.zhengjie.ruibo.service.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import me.zhengjie.rbscreen.domain.vo.PerorcarVo;
import me.zhengjie.ruibo.domain.PerInfo;
import me.zhengjie.ruibo.excel.PerInfoExcelDto;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.HashMap;
import java.util.List;
@Mapper
public interface PerInfoMapper extends BaseMapper<PerInfo> {
void insertBatchExcel(List<PerInfoExcelDto> perInfoExcelList);
// 查询所有的 phone
List<String> selectPhoneAll();
List<String> selectPerTelAll();
PerorcarVo queryOnlineState(@Param("time")String time);
List<HashMap<String,Object>> queryOnlineStatAWeek(@Param("time")String time);
}
\ No newline at end of file
...@@ -6,8 +6,9 @@ ...@@ -6,8 +6,9 @@
<select id="getRealDiBang" resultType="me.zhengjie.ruibo.domain.DiBangMysql"> <select id="getRealDiBang" resultType="me.zhengjie.ruibo.domain.DiBangMysql">
select * from tbl_back_record order by Weight_time desc limit 1 select * from tbl_back_record order by Weight_time desc limit 1
</select> </select>
<select id="cycleStatistics" resultType="hashmap"> <select id="cycleStatistics" resultType="integer">
select ifnull(sum(weight) ,0)as weight from tbl_back_record
where weight_time between #{startDate} and #{endDate}
</select> </select>
<insert id="insertBatch"> <insert id="insertBatch">
insert into tbl_back_record (weight,weight_time) values insert into tbl_back_record (weight,weight_time) values
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="me.zhengjie.rbscreen.mapper.PerHistoryMapper">
<select id="getAllReal" resultType="me.zhengjie.rbscreen.dto.PerInfoRealDto">
select pi.per_name as perName,
pi.phone,
pi.per_imei as perImei,
case when pi.per_sex = '1' then '男' when pi.per_sex = '2' then '女' else '未知' end as perSex,
pi.per_tel as perTel,
pi.per_number as perNumber,
pi.per_dept as perDept,
pi.per_office as perOffice,
ph.lat,
ph.lng,
ph.hight
from per_info pi
join (select a.*
from per_history_${time} a
join (select max(create_time) as maxTime, phone
from per_history_${time} where create_time >= DATE_SUB(NOW(), INTERVAL 5 MINUTE )
group by phone) phmx on phmx.maxTime = a.create_time and phmx.phone=a.phone) ph
on pi.phone = ph.phone
group by pi.phone
</select>
</mapper>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="me.zhengjie.ruibo.service.mapper.PerInfoMapper">
<insert id="insertBatchExcel">
insert into per_info (per_name, phone, per_imei, per_sex, per_tel, per_number, per_dept, per_office,safe_educate,temporary)
values
<foreach collection="perInfoExcelList" separator="," index="index" item="perInfoExcel">
(#{perInfoExcel.perName},
#{perInfoExcel.phone}, #{perInfoExcel.perImei},
#{perInfoExcel.perSex}, #{perInfoExcel.perTel},
#{perInfoExcel.perNumber}, #{perInfoExcel.perDept},
#{perInfoExcel.perOffice}, #{perInfoExcel.safeEducate}, #{perInfoExcel.temporary})
</foreach>
</insert>
<select id="selectPhoneAll" resultType="string">
select phone
from per_info
</select>
<select id="selectPerTelAll" resultType="string">
select per_tel
from per_info
</select>
<select id="queryOnlineState" resultType="me.zhengjie.rbscreen.domain.vo.PerorcarVo">
select '人员定位' as name,
count(1) as count,
(select count(DISTINCT a.phone)
from per_info a
join per_history_${time} b on a.phone = b.phone and a.temporary = 1
where b.create_time >= DATE_SUB(NOW(), INTERVAL 5 MINUTE)) as online
from per_info
</select>
<select id="queryOnlineStatAWeek" resultType="java.util.HashMap">
SELECT
sub.phone,
dt AS time,
COUNT( DISTINCT c.phone ) AS count
FROM
(-- 子查询:计算每个手机号在每天的首次和末次访问时间,筛选出活动时间>=2小时的记录
SELECT
phone,
DATE ( create_time ) AS dt,
MIN( create_time ) AS first_time,
MAX( create_time ) AS last_time
FROM
per_history_${time}
WHERE
create_time > DATE_SUB( NOW(), INTERVAL 7 DAY )
GROUP BY
phone,
DATE ( create_time )
HAVING
TIMESTAMPDIFF(
HOUR,
MIN( create_time ),
MAX( create_time )) >= 2
) AS sub
JOIN per_info c ON c.phone = sub.phone
AND c.TEMPORARY = 1
GROUP BY
dt
</select>
</mapper>
\ No newline at end of file
...@@ -124,7 +124,6 @@ ...@@ -124,7 +124,6 @@
<artifactId>json</artifactId> <artifactId>json</artifactId>
<version>20090211</version> <version>20090211</version>
</dependency> </dependency>
</dependencies> </dependencies>
<!-- 打包 --> <!-- 打包 -->
......
...@@ -124,6 +124,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { ...@@ -124,6 +124,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
.antMatchers("/file/**").permitAll() .antMatchers("/file/**").permitAll()
// 阿里巴巴 druid // 阿里巴巴 druid
.antMatchers("/druid/**").permitAll() .antMatchers("/druid/**").permitAll()
.antMatchers("/magic/web/**").permitAll()
// 放行OPTIONS请求 // 放行OPTIONS请求
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll() .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
// 自定义匿名访问所有url放行:允许匿名和带Token访问,细腻化到每个 Request 类型 // 自定义匿名访问所有url放行:允许匿名和带Token访问,细腻化到每个 Request 类型
......
#配置数据源 #配置数据源
spring: spring:
datasource: datasource:
initialization-mode: never
dynamic: dynamic:
primary: master primary: master
datasource: datasource:
...@@ -14,9 +15,9 @@ spring: ...@@ -14,9 +15,9 @@ spring:
#配置 sqlServer #配置 sqlServer
type: com.alibaba.druid.pool.DruidDataSource type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
url: jdbc:sqlserver://${DB_HOST:192.168.2.37}:1451;databaseName=demo01;encrypt=false url: jdbc:sqlserver://${DB_HOST:192.168.2.38}:1450;databaseName=demo01;encrypt=false
username: root username: root
password: jinghe2022 password: jinghe20221
druid: druid:
......
...@@ -4,6 +4,7 @@ spring: ...@@ -4,6 +4,7 @@ spring:
dynamic: dynamic:
primary: master primary: master
datasource: datasource:
initialization-mode: never
master: master:
#driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy #driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
#url: jdbc:log4jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:10101}/${DB_NAME:ruibo}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false #url: jdbc:log4jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:10101}/${DB_NAME:ruibo}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
......
server: server:
port: 9005 port: 9015
spring: spring:
freemarker: freemarker:
...@@ -33,7 +33,20 @@ spring: ...@@ -33,7 +33,20 @@ spring:
password: ${REDIS_PWD:R#9Xz&2Lp$Wq8v!u} password: ${REDIS_PWD:R#9Xz&2Lp$Wq8v!u}
#连接超时时间 #连接超时时间
timeout: 5000 timeout: 5000
magic-api:
#在线编辑代码的入口地址
web: /magic/web
#保存在线编辑的代码的位置
resource:
location: J:/RuShanRuiBo/magic-api
response-code:
exception: 500
success: 200
security:
# 用户名
username: admin
# 密码
password: Gemho2025.
task: task:
pool: pool:
# 核心线程池大小 # 核心线程池大小
...@@ -79,4 +92,7 @@ netty: ...@@ -79,4 +92,7 @@ netty:
filepath: d:/file/ filepath: d:/file/
backPath: d:/file/ backPath: d:/file/
environment: environment:
path: H:\zy\mysql-5.7.43-winx64\bin\ path: H:\zy\mysql-5.7.43-winx64\bin\
\ No newline at end of file chuliang:
ip: 192.168.3.249
port: 9995
\ No newline at end of file
...@@ -251,6 +251,11 @@ ...@@ -251,6 +251,11 @@
<artifactId>ip2region</artifactId> <artifactId>ip2region</artifactId>
<version>1.7.2</version> <version>1.7.2</version>
</dependency> </dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment