diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/controller/KcDetectionDetailedController.java b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/controller/KcDetectionDetailedController.java new file mode 100644 index 00000000..533fe6eb --- /dev/null +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/controller/KcDetectionDetailedController.java @@ -0,0 +1,178 @@ +package org.jeecg.modules.kc.detection.controller; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.kc.detection.entity.KcDetectionDetailed; +import org.jeecg.modules.kc.detection.service.IKcDetectionDetailedService; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; + +import org.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.jeecg.common.system.base.controller.JeecgController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.servlet.ModelAndView; +import com.alibaba.fastjson.JSON; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.apache.shiro.authz.annotation.RequiresPermissions; + + /** + * @Description: 教室人数检测-详细表 + * @Author: jeecg-boot + * @Date: 2024-05-07 + * @Version: V1.0 + */ +@Api(tags="教室人数检测-详细表") +@RestController +@RequestMapping("/detection/kcDetectionDetailed") +@Slf4j +public class KcDetectionDetailedController extends JeecgController { + @Autowired + private IKcDetectionDetailedService kcDetectionDetailedService; + + /** + * 分页列表查询 + * + * @param kcDetectionDetailed + * @param pageNo + * @param pageSize + * @param req + * @return + */ + //@AutoLog(value = "教室人数检测-详细表-分页列表查询") + @ApiOperation(value="教室人数检测-详细表-分页列表查询", notes="教室人数检测-详细表-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(KcDetectionDetailed kcDetectionDetailed, + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + HttpServletRequest req) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(kcDetectionDetailed, req.getParameterMap()); + Page page = new Page(pageNo, pageSize); + IPage pageList = kcDetectionDetailedService.page(page, queryWrapper); + return Result.OK(pageList); + } + +// /** +// * 添加 +// * +// * @param kcDetectionDetailed +// * @return +// */ +// @AutoLog(value = "教室人数检测-详细表-添加") +// @ApiOperation(value="教室人数检测-详细表-添加", notes="教室人数检测-详细表-添加") +// @RequiresPermissions("detection:kc_detection_detailed:add") +// @PostMapping(value = "/add") +// public Result add(@RequestBody KcDetectionDetailed kcDetectionDetailed) { +// kcDetectionDetailedService.save(kcDetectionDetailed); +// return Result.OK("添加成功!"); +// } +// +// /** +// * 编辑 +// * +// * @param kcDetectionDetailed +// * @return +// */ +// @AutoLog(value = "教室人数检测-详细表-编辑") +// @ApiOperation(value="教室人数检测-详细表-编辑", notes="教室人数检测-详细表-编辑") +// @RequiresPermissions("detection:kc_detection_detailed:edit") +// @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) +// public Result edit(@RequestBody KcDetectionDetailed kcDetectionDetailed) { +// kcDetectionDetailedService.updateById(kcDetectionDetailed); +// return Result.OK("编辑成功!"); +// } +// +// /** +// * 通过id删除 +// * +// * @param id +// * @return +// */ +// @AutoLog(value = "教室人数检测-详细表-通过id删除") +// @ApiOperation(value="教室人数检测-详细表-通过id删除", notes="教室人数检测-详细表-通过id删除") +// @RequiresPermissions("detection:kc_detection_detailed:delete") +// @DeleteMapping(value = "/delete") +// public Result delete(@RequestParam(name="id",required=true) String id) { +// kcDetectionDetailedService.removeById(id); +// return Result.OK("删除成功!"); +// } +// +// /** +// * 批量删除 +// * +// * @param ids +// * @return +// */ +// @AutoLog(value = "教室人数检测-详细表-批量删除") +// @ApiOperation(value="教室人数检测-详细表-批量删除", notes="教室人数检测-详细表-批量删除") +// @RequiresPermissions("detection:kc_detection_detailed:deleteBatch") +// @DeleteMapping(value = "/deleteBatch") +// public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { +// this.kcDetectionDetailedService.removeByIds(Arrays.asList(ids.split(","))); +// return Result.OK("批量删除成功!"); +// } +// +// /** +// * 通过id查询 +// * +// * @param id +// * @return +// */ +// //@AutoLog(value = "教室人数检测-详细表-通过id查询") +// @ApiOperation(value="教室人数检测-详细表-通过id查询", notes="教室人数检测-详细表-通过id查询") +// @GetMapping(value = "/queryById") +// public Result queryById(@RequestParam(name="id",required=true) String id) { +// KcDetectionDetailed kcDetectionDetailed = kcDetectionDetailedService.getById(id); +// if(kcDetectionDetailed==null) { +// return Result.error("未找到对应数据"); +// } +// return Result.OK(kcDetectionDetailed); +// } +// +// /** +// * 导出excel +// * +// * @param request +// * @param kcDetectionDetailed +// */ +// @RequiresPermissions("detection:kc_detection_detailed:exportXls") +// @RequestMapping(value = "/exportXls") +// public ModelAndView exportXls(HttpServletRequest request, KcDetectionDetailed kcDetectionDetailed) { +// return super.exportXls(request, kcDetectionDetailed, KcDetectionDetailed.class, "教室人数检测-详细表"); +// } +// +// /** +// * 通过excel导入数据 +// * +// * @param request +// * @param response +// * @return +// */ +// @RequiresPermissions("detection:kc_detection_detailed:importExcel") +// @RequestMapping(value = "/importExcel", method = RequestMethod.POST) +// public Result importExcel(HttpServletRequest request, HttpServletResponse response) { +// return super.importExcel(request, response, KcDetectionDetailed.class); +// } + +} diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/controller/KcDetectionMainController.java b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/controller/KcDetectionMainController.java new file mode 100644 index 00000000..94945fd0 --- /dev/null +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/controller/KcDetectionMainController.java @@ -0,0 +1,213 @@ +package org.jeecg.modules.kc.detection.controller; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.beust.jcommander.internal.Sets; +import com.google.common.collect.Maps; +import org.apache.commons.compress.utils.Lists; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.kc.detection.entity.KcDetectionDetailed; +import org.jeecg.modules.kc.detection.entity.KcDetectionMain; +import org.jeecg.modules.kc.detection.service.IKcDetectionDetailedService; +import org.jeecg.modules.kc.detection.service.IKcDetectionMainService; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; + +import org.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.jeecg.common.system.base.controller.JeecgController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.servlet.ModelAndView; +import com.alibaba.fastjson.JSON; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.apache.shiro.authz.annotation.RequiresPermissions; + + /** + * @Description: 教室人数检测-主表 + * @Author: jeecg-boot + * @Date: 2024-05-07 + * @Version: V1.0 + */ +@Api(tags="教室人数检测-主表") +@RestController +@RequestMapping("/detection/kcDetectionMain") +@Slf4j +public class KcDetectionMainController extends JeecgController { + @Autowired + private IKcDetectionMainService kcDetectionMainService; + + @Autowired + private IKcDetectionDetailedService kcDetectionDetailedService; + + /** + * 分页列表查询 + * + * @param kcDetectionMain + * @param pageNo + * @param pageSize + * @param req + * @return + */ + //@AutoLog(value = "教室人数检测-主表-分页列表查询") + @ApiOperation(value="教室人数检测-主表-分页列表查询", notes="教室人数检测-主表-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(KcDetectionMain kcDetectionMain, + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + HttpServletRequest req) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(kcDetectionMain, req.getParameterMap()); + Page page = new Page<>(pageNo, pageSize); + IPage pageList = kcDetectionMainService.page(page, queryWrapper); + //补充查询子列表 + if(kcDetectionMain.getIsSelectKcDetailed() != null && kcDetectionMain.getIsSelectKcDetailed()){ + Set pidSet = Sets.newHashSet(); + Map detectionMainMap = Maps.newHashMap(); + pageList.getRecords().forEach(x -> { + pidSet.add(x.getId()); + detectionMainMap.put(x.getId(),x); + x.setDetectionDetailedList(Lists.newArrayList()); + } ); + if(!pidSet.isEmpty()){ + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().in(KcDetectionDetailed::getPid,pidSet); + qw.orderByAsc("detection_num", "create_time"); + List detailedList = kcDetectionDetailedService.list(qw); + detailedList.forEach(x -> { + if(detectionMainMap.containsKey(x.getPid())){ + KcDetectionMain pData = detectionMainMap.get(x.getPid()); + pData.getDetectionDetailedList().add(x); + } + }); + + } + + } + + return Result.OK(pageList); + } + +// /** +// * 添加 +// * +// * @param kcDetectionMain +// * @return +// */ +// @AutoLog(value = "教室人数检测-主表-添加") +// @ApiOperation(value="教室人数检测-主表-添加", notes="教室人数检测-主表-添加") +// @RequiresPermissions("detection:kc_detection_main:add") +// @PostMapping(value = "/add") +// public Result add(@RequestBody KcDetectionMain kcDetectionMain) { +// kcDetectionMainService.save(kcDetectionMain); +// return Result.OK("添加成功!"); +// } +// +// /** +// * 编辑 +// * +// * @param kcDetectionMain +// * @return +// */ +// @AutoLog(value = "教室人数检测-主表-编辑") +// @ApiOperation(value="教室人数检测-主表-编辑", notes="教室人数检测-主表-编辑") +// @RequiresPermissions("detection:kc_detection_main:edit") +// @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) +// public Result edit(@RequestBody KcDetectionMain kcDetectionMain) { +// kcDetectionMainService.updateById(kcDetectionMain); +// return Result.OK("编辑成功!"); +// } +// +// /** +// * 通过id删除 +// * +// * @param id +// * @return +// */ +// @AutoLog(value = "教室人数检测-主表-通过id删除") +// @ApiOperation(value="教室人数检测-主表-通过id删除", notes="教室人数检测-主表-通过id删除") +// @RequiresPermissions("detection:kc_detection_main:delete") +// @DeleteMapping(value = "/delete") +// public Result delete(@RequestParam(name="id",required=true) String id) { +// kcDetectionMainService.removeById(id); +// return Result.OK("删除成功!"); +// } +// +// /** +// * 批量删除 +// * +// * @param ids +// * @return +// */ +// @AutoLog(value = "教室人数检测-主表-批量删除") +// @ApiOperation(value="教室人数检测-主表-批量删除", notes="教室人数检测-主表-批量删除") +// @RequiresPermissions("detection:kc_detection_main:deleteBatch") +// @DeleteMapping(value = "/deleteBatch") +// public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { +// this.kcDetectionMainService.removeByIds(Arrays.asList(ids.split(","))); +// return Result.OK("批量删除成功!"); +// } +// +// /** +// * 通过id查询 +// * +// * @param id +// * @return +// */ +// //@AutoLog(value = "教室人数检测-主表-通过id查询") +// @ApiOperation(value="教室人数检测-主表-通过id查询", notes="教室人数检测-主表-通过id查询") +// @GetMapping(value = "/queryById") +// public Result queryById(@RequestParam(name="id",required=true) String id) { +// KcDetectionMain kcDetectionMain = kcDetectionMainService.getById(id); +// if(kcDetectionMain==null) { +// return Result.error("未找到对应数据"); +// } +// return Result.OK(kcDetectionMain); +// } +// +// /** +// * 导出excel +// * +// * @param request +// * @param kcDetectionMain +// */ +// @RequiresPermissions("detection:kc_detection_main:exportXls") +// @RequestMapping(value = "/exportXls") +// public ModelAndView exportXls(HttpServletRequest request, KcDetectionMain kcDetectionMain) { +// return super.exportXls(request, kcDetectionMain, KcDetectionMain.class, "教室人数检测-主表"); +// } +// +// /** +// * 通过excel导入数据 +// * +// * @param request +// * @param response +// * @return +// */ +// @RequiresPermissions("detection:kc_detection_main:importExcel") +// @RequestMapping(value = "/importExcel", method = RequestMethod.POST) +// public Result importExcel(HttpServletRequest request, HttpServletResponse response) { +// return super.importExcel(request, response, KcDetectionMain.class); +// } + +} diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/entity/KcDetectionDetailed.java b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/entity/KcDetectionDetailed.java new file mode 100644 index 00000000..1aeb2434 --- /dev/null +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/entity/KcDetectionDetailed.java @@ -0,0 +1,93 @@ +package org.jeecg.modules.kc.detection.entity; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.util.Date; +import java.math.BigDecimal; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecg.common.aspect.annotation.Dict; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * @Description: 教室人数检测-详细表 + * @Author: jeecg-boot + * @Date: 2024-05-07 + * @Version: V1.0 + */ +@Data +@TableName("kc_detection_detailed") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@ApiModel(value="kc_detection_detailed对象", description="教室人数检测-详细表") +public class KcDetectionDetailed implements Serializable { + private static final long serialVersionUID = 1L; + + /**id*/ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "id") + private java.lang.String id; + /**创建时间*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + @ApiModelProperty(value = "创建时间") + private java.util.Date createTime; + /**更新时间*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + @ApiModelProperty(value = "更新时间") + private java.util.Date updateTime; + /**教室人数检测-主表ID[kc_detection_main.id]*/ + @Excel(name = "教室人数检测-主表ID[kc_detection_main.id]", width = 15) + @ApiModelProperty(value = "教室人数检测-主表ID[kc_detection_main.id]") + private java.lang.String pid; + /**任务编号(课堂)*/ + @Excel(name = "任务编号(课堂)", width = 15) + @ApiModelProperty(value = "任务编号(课堂)") + private java.lang.String rwbh; + /**课程编号*/ + @Excel(name = "课程编号", width = 15) + @ApiModelProperty(value = "课程编号") + private java.lang.String kcbh; + /**课程名称*/ + @Excel(name = "课程名称", width = 15) + @ApiModelProperty(value = "课程名称") + private java.lang.String kcmc; + /**教室编号*/ + @Excel(name = "教室编号", width = 15) + @ApiModelProperty(value = "教室编号") + private java.lang.String jsbh; + /**学年学期内部用*/ + @Excel(name = "学年学期内部用", width = 15) + @ApiModelProperty(value = "学年学期内部用") + private java.lang.String xnxq; + /**检测url*/ + @Excel(name = "检测url", width = 15) + @ApiModelProperty(value = "检测url") + private java.lang.String detectionUrl; + /**截取图片结果URL*/ + @Excel(name = "截取图片结果URL", width = 15) + @ApiModelProperty(value = "截取图片结果URL") + private java.lang.String detectionOutImgUrl; + /**截取图片计算人数返回结果*/ + @Excel(name = "截取图片计算人数返回结果", width = 15) + @ApiModelProperty(value = "截取图片计算人数返回结果") + private java.lang.String detectionOutImgRes; + /**检测次数(当前是第几次)*/ + @Excel(name = "检测次数(当前是第几次)", width = 15) + @ApiModelProperty(value = "检测次数(当前是第几次)") + private java.lang.Integer detectionNum; + /**当次检测人数*/ + @Excel(name = "当次检测人数", width = 15) + @ApiModelProperty(value = "当次检测人数") + private java.lang.Integer num; +} diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/entity/KcDetectionMain.java b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/entity/KcDetectionMain.java new file mode 100644 index 00000000..fac61703 --- /dev/null +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/entity/KcDetectionMain.java @@ -0,0 +1,99 @@ +package org.jeecg.modules.kc.detection.entity; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.util.Date; +import java.math.BigDecimal; +import java.util.List; + +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; +import com.sun.org.apache.xpath.internal.operations.Bool; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.jeecg.modules.kc.ktgl.entity.KcKetangbiao; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecg.common.aspect.annotation.Dict; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * @Description: 教室人数检测-主表 + * @Author: jeecg-boot + * @Date: 2024-05-07 + * @Version: V1.0 + */ +@Data +@TableName(value = "kc_detection_main", autoResultMap = true) +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@ApiModel(value="kc_detection_main对象", description="教室人数检测-主表") +public class KcDetectionMain implements Serializable { + private static final long serialVersionUID = 1L; + + /**id*/ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "id") + private String id; + /**创建时间*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + @ApiModelProperty(value = "创建时间") + private Date createTime; + /**更新时间*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + @ApiModelProperty(value = "更新时间") + private Date updateTime; + /**任务编号(课堂)*/ + @Excel(name = "任务编号(课堂)", width = 15) + @ApiModelProperty(value = "任务编号(课堂)") + private String rwbh; + /**课程编号*/ + @Excel(name = "课程编号", width = 15) + @ApiModelProperty(value = "课程编号") + private String kcbh; + /**课程名称*/ + @Excel(name = "课程名称", width = 15) + @ApiModelProperty(value = "课程名称") + private String kcmc; + /**教室编号*/ + @Excel(name = "教室编号", width = 15) + @ApiModelProperty(value = "教室编号") + private String jsbh; + /**学年学期内部用*/ + @Excel(name = "学年学期内部用", width = 15) + @ApiModelProperty(value = "学年学期内部用") + private String xnxq; + /**检测url*/ + @Excel(name = "检测url", width = 15) + @ApiModelProperty(value = "检测url") + private String detectionUrl; + /**检测次数*/ + @Excel(name = "检测次数", width = 15) + @ApiModelProperty(value = "检测次数") + private Integer detectionNum; + /**人数(累加)*/ + @Excel(name = "人数(累加)", width = 15) + @ApiModelProperty(value = "人数(累加)") + private Integer allNum; + /**平均数*/ + @Excel(name = "平均数", width = 15) + @ApiModelProperty(value = "平均数") + private Integer averageNum; + /**课堂信息*/ + @TableField(updateStrategy = FieldStrategy.IGNORED, typeHandler = FastjsonTypeHandler.class) + @ApiModelProperty(value = "课堂信息") + private KcKetangbiao ketangbiaoInfo; + + /***/ + @TableField(exist = false) + private List detectionDetailedList; + + /***/ + @TableField(exist = false) + private Boolean isSelectKcDetailed; +} diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/job/DetectionJob.java b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/job/DetectionJob.java new file mode 100644 index 00000000..23bdf8df --- /dev/null +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/job/DetectionJob.java @@ -0,0 +1,26 @@ +package org.jeecg.modules.kc.detection.job; + +import org.jeecg.modules.kc.detection.service.IKcDetectionDetailedService; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; + +import javax.annotation.Resource; + +/** + * @ClassName DetectionJob + * @Description 定时抓取 + * @Author bai + * @Date 2024/5/7 16:48 + * @Version 1.0 + **/ +public class DetectionJob implements Job { + + @Resource + private IKcDetectionDetailedService detectionDetailedService; + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + detectionDetailedService.videoScreenshotAll(); + } +} diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/mapper/KcDetectionDetailedMapper.java b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/mapper/KcDetectionDetailedMapper.java new file mode 100644 index 00000000..94f07de2 --- /dev/null +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/mapper/KcDetectionDetailedMapper.java @@ -0,0 +1,17 @@ +package org.jeecg.modules.kc.detection.mapper; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; +import org.jeecg.modules.kc.detection.entity.KcDetectionDetailed; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @Description: 教室人数检测-详细表 + * @Author: jeecg-boot + * @Date: 2024-05-07 + * @Version: V1.0 + */ +public interface KcDetectionDetailedMapper extends BaseMapper { + +} diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/mapper/KcDetectionMainMapper.java b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/mapper/KcDetectionMainMapper.java new file mode 100644 index 00000000..f2dd3eae --- /dev/null +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/mapper/KcDetectionMainMapper.java @@ -0,0 +1,17 @@ +package org.jeecg.modules.kc.detection.mapper; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; +import org.jeecg.modules.kc.detection.entity.KcDetectionMain; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @Description: 教室人数检测-主表 + * @Author: jeecg-boot + * @Date: 2024-05-07 + * @Version: V1.0 + */ +public interface KcDetectionMainMapper extends BaseMapper { + +} diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/mapper/xml/KcDetectionDetailedMapper.xml b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/mapper/xml/KcDetectionDetailedMapper.xml new file mode 100644 index 00000000..cf4afd3d --- /dev/null +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/mapper/xml/KcDetectionDetailedMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/mapper/xml/KcDetectionMainMapper.xml b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/mapper/xml/KcDetectionMainMapper.xml new file mode 100644 index 00000000..cf4011f3 --- /dev/null +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/mapper/xml/KcDetectionMainMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/service/IKcDetectionDetailedService.java b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/service/IKcDetectionDetailedService.java new file mode 100644 index 00000000..5ed2c689 --- /dev/null +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/service/IKcDetectionDetailedService.java @@ -0,0 +1,18 @@ +package org.jeecg.modules.kc.detection.service; + +import org.jeecg.modules.kc.detection.entity.KcDetectionDetailed; +import com.baomidou.mybatisplus.extension.service.IService; +import org.jeecg.modules.tools.AuthService; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @Description: 教室人数检测-详细表 + * @Author: jeecg-boot + * @Date: 2024-05-07 + * @Version: V1.0 + */ +public interface IKcDetectionDetailedService extends IService { + + void videoScreenshotAll(); + +} diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/service/IKcDetectionMainService.java b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/service/IKcDetectionMainService.java new file mode 100644 index 00000000..7225d82e --- /dev/null +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/service/IKcDetectionMainService.java @@ -0,0 +1,14 @@ +package org.jeecg.modules.kc.detection.service; + +import org.jeecg.modules.kc.detection.entity.KcDetectionMain; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * @Description: 教室人数检测-主表 + * @Author: jeecg-boot + * @Date: 2024-05-07 + * @Version: V1.0 + */ +public interface IKcDetectionMainService extends IService { + +} diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/service/impl/KcDetectionDetailedServiceImpl.java b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/service/impl/KcDetectionDetailedServiceImpl.java new file mode 100644 index 00000000..f0c99e2e --- /dev/null +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/service/impl/KcDetectionDetailedServiceImpl.java @@ -0,0 +1,227 @@ +package org.jeecg.modules.kc.detection.service.impl; +import java.util.*; + +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.io.FileUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.beust.jcommander.internal.Sets; +import com.google.common.collect.Maps; +import io.swagger.annotations.ApiModelProperty; +import org.apache.commons.lang3.StringUtils; +import org.jeecg.modules.kc.detection.entity.KcDetectionDetailed; +import org.jeecg.modules.kc.detection.entity.KcDetectionMain; +import org.jeecg.modules.kc.detection.mapper.KcDetectionDetailedMapper; +import org.jeecg.modules.kc.detection.service.IKcDetectionDetailedService; +import org.jeecg.modules.kc.detection.service.IKcDetectionMainService; +import org.jeecg.modules.kc.jiaoshi.controller.KcZhihuijiaoshiController; +import org.jeecg.modules.kc.jiaoshi.entity.KcZhihuijiaoshi; +import org.jeecg.modules.kc.jiaoshi.service.IKcZhihuijiaoshiService; +import org.jeecg.modules.kc.kcJieci.entity.KcJieci; +import org.jeecg.modules.kc.kcJieci.service.IKcJieciService; +import org.jeecg.modules.kc.ktgl.controller.KcKetangbiaoController; +import org.jeecg.modules.kc.ktgl.entity.KcKetangbiao; +import org.jeecg.modules.kc.ktgl.service.IKcKetangbiaoService; +import org.jeecg.modules.tools.AuthService; +import org.jeecg.modules.tools.CommonUtil; +import org.jeecg.modules.tools.DateUtils; +import org.jeecg.modules.tools.URLEncoder; +import org.jeecg.modules.tools.ffmpeg.FFmpegTools; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.util.FileCopyUtils; + +import javax.annotation.Resource; +import java.io.File; +import java.util.stream.Collectors; + +/** + * @Description: 教室人数检测-详细表 + * @Author: jeecg-boot + * @Date: 2024-05-07 + * @Version: V1.0 + */ +@Service +public class KcDetectionDetailedServiceImpl extends ServiceImpl implements IKcDetectionDetailedService { + + @Resource + private IKcDetectionMainService kcDetectionMainService; + + @Resource + private IKcZhihuijiaoshiService zhihuijiaoshiService; + + @Resource + private AuthService authService; + + @Resource + private FFmpegTools _FFmpegTools; + + @Resource + private IKcKetangbiaoService kcKetangbiaoService; + + @Resource + private IKcJieciService jieciService; + + + @Value(value = "${jeecg.path.upload}") + private String uploadpath; + + @Override + public void videoScreenshotAll() { + DateTime starTime = DateTime.now(); + String nowStr = starTime.toString("yyyy-MM-dd"); + + //新版,查询当前是否有课 +// KcZhihuijiaoshi jiaoshi = new KcZhihuijiaoshi(); +// jiaoshi.setXm("学生全景"); +// jiaoshi.setChangshang("奥威亚"); +// QueryWrapper queryWrapper = new QueryWrapper<>(); +// queryWrapper.eq("xm","学生全景"); +// queryWrapper.eq("changshang","奥威亚"); + + String hh = ""; + KcJieci kcJieci = new KcJieci(); + List kcJieciList = jieciService.getIndexJcList(kcJieci); + if(kcJieciList != null && !kcJieciList.isEmpty()){ + KcJieci kcJieciParam = kcJieciList.get(0); + String[] jcArray = StringUtils.split(kcJieciParam.getJieci(),"、"); + + hh = kcJieciParam.getJieci() + "," + String.join(",", jcArray); + } + + KcKetangbiao kcKetangbiao = new KcKetangbiao(); + kcKetangbiao.setSfyzhjs("1"); + kcKetangbiao.setHh(hh); + kcKetangbiao.setSkrq(nowStr); +// kcKetangbiao.setUserid(""); + kcKetangbiao.setSkxs(1); + kcKetangbiao.setSbType("1"); + kcKetangbiao.setSftkb("1"); + kcKetangbiao.setYwskxs(""); + + if(StringUtils.equals(",", hh)){ + log.error("未查到节次,原因未知!"); + return; + } + + Page page = new Page<>(1, -1); + IPage pageList = kcKetangbiaoService.getKclblist(page, kcKetangbiao); + + if(pageList != null){ + List list = pageList.getRecords(); + Set jsbhSet = Sets.newHashSet(); + Map KcKetangbiaoMap = Maps.newHashMap(); + list.forEach(x -> { + KcKetangbiaoMap.put(x.getJsbh(), x); + jsbhSet.add(x.getJsbh()); + }); + //取智慧教室信息 + //id: item.jsbh, ktId: item.id + QueryWrapper zhjsQW = new QueryWrapper<>(); + zhjsQW.lambda().eq(KcZhihuijiaoshi::getXm,"学生全景"); + zhjsQW.lambda().eq(KcZhihuijiaoshi::getChangshang,"奥威亚"); + zhjsQW.lambda().in(KcZhihuijiaoshi::getJsbh, jsbhSet); + + List zhihuijiaoshiList = zhihuijiaoshiService.list(zhjsQW); + + zhihuijiaoshiList.forEach(x -> { + KcKetangbiao ketangbiao = KcKetangbiaoMap.get(x.getJsbh()); + + String fileName; + File uploadpathFile = new File(uploadpath); + String uploadpathFilePath = uploadpathFile.getPath(); + File file = new File(uploadpathFilePath + File.separator + "videoScreenshot" + File.separator + DateUtils.getTradeNo() + File.separator); + String orgName = x.getPullUrl();// 获取文件名 + orgName = CommonUtil.getFileName(orgName); + if(orgName.lastIndexOf(".")!=-1){ + //qn更改-- 修复特殊字符上传后无法下载的问题,修复多个.名称错乱的问题 + orgName = URLEncoder.DEFAULT.encode(orgName); + //原名是m3u8,不是图片,改成jpeg +// fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + DateUtils.getTradeNo() + orgName.substring(orgName.lastIndexOf(".")); + fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + DateUtils.getTradeNo() + ".jpeg"; + }else{ +// fileName = x.getRw"_" + orgName+ "_" + DateUtils.getTradeNo(); + fileName = orgName+ "_" + DateUtils.getTradeNo(); + } + //qn更改-- 修复特殊字符上传后无法下载的问题,修复多个.名称错乱的问题END +// String savePath = file.getPath() + File.separator + fileName; +// File savefile = new File(savePath); +// FileCopyUtils.copy(mf.getBytes(), savefile); + + //截图 + String outImagePath = file.getPath() + File.separator + fileName; + FileUtil.touch(outImagePath); + String miniOutImagePath = StringUtils.replace(outImagePath, uploadpathFilePath, ""); + miniOutImagePath = StringUtils.replace(miniOutImagePath,"\\","/"); + boolean isSuccess = _FFmpegTools.videoScreenshot(x.getPullUrl(), outImagePath); + //查找主表, + QueryWrapper detectionMainQw = new QueryWrapper<>(); + + detectionMainQw.apply("create_time >= '" + nowStr + " 00:00:00' and create_time <= '" + nowStr + " 23:59:59'"); + detectionMainQw.lambda().eq(KcDetectionMain::getRwbh, ketangbiao.getRwbh()); + detectionMainQw.last("limit 1"); + KcDetectionMain detectionMain = kcDetectionMainService.getOne(detectionMainQw); + if(detectionMain == null) { + detectionMain = new KcDetectionMain(); + detectionMain.setRwbh(ketangbiao.getRwbh()); + detectionMain.setKcbh(ketangbiao.getKcbh()); + detectionMain.setKcmc(ketangbiao.getKcmc()); + detectionMain.setJsbh(x.getJsbh()); + detectionMain.setXnxq(ketangbiao.getXnxq()); + detectionMain.setDetectionUrl(x.getPullUrl()); + detectionMain.setDetectionNum(0); + detectionMain.setAllNum(0); + detectionMain.setAverageNum(0); + } + Integer detectionNum = detectionMain.getDetectionNum(); + detectionNum++; + detectionMain.setDetectionNum(detectionNum); + detectionMain.setKetangbiaoInfo(ketangbiao); + + KcDetectionDetailed detectionDetailed = new KcDetectionDetailed(); + detectionDetailed.setRwbh(ketangbiao.getRwbh()); + detectionDetailed.setKcbh(ketangbiao.getKcbh()); + detectionDetailed.setKcmc(ketangbiao.getKcmc()); + detectionDetailed.setJsbh(x.getJsbh()); + detectionDetailed.setXnxq(ketangbiao.getXnxq()); + detectionDetailed.setDetectionUrl(x.getPullUrl()); + detectionDetailed.setDetectionOutImgUrl(miniOutImagePath); + detectionDetailed.setDetectionOutImgRes("{\"res\":\"无法截取图片!\"}"); + detectionDetailed.setDetectionNum(detectionNum);//截图序列号 + detectionDetailed.setNum(0); + + //取数量 + if(isSuccess){ + String rJson = authService.body_num(outImagePath); + detectionDetailed.setDetectionOutImgRes(rJson); + //解析获取数 + JSONObject object= JSON.parseObject(rJson); + detectionDetailed.setNum(object.getInteger("person_num")); + } + + Integer allNum = detectionMain.getAllNum(); + allNum += detectionDetailed.getNum(); + detectionMain.setAllNum(allNum); + detectionMain.setAverageNum(allNum/detectionNum); + //保存主表 + if(StringUtils.isBlank(detectionMain.getId())){ + kcDetectionMainService.save(detectionMain); + } else { + kcDetectionMainService.updateById(detectionMain); + } + detectionDetailed.setPid(detectionMain.getId()); + //保存子表 + save(detectionDetailed); + + }); + } + } +} diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/service/impl/KcDetectionMainServiceImpl.java b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/service/impl/KcDetectionMainServiceImpl.java new file mode 100644 index 00000000..9e953723 --- /dev/null +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/detection/service/impl/KcDetectionMainServiceImpl.java @@ -0,0 +1,19 @@ +package org.jeecg.modules.kc.detection.service.impl; + +import org.jeecg.modules.kc.detection.entity.KcDetectionMain; +import org.jeecg.modules.kc.detection.mapper.KcDetectionMainMapper; +import org.jeecg.modules.kc.detection.service.IKcDetectionMainService; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +/** + * @Description: 教室人数检测-主表 + * @Author: jeecg-boot + * @Date: 2024-05-07 + * @Version: V1.0 + */ +@Service +public class KcDetectionMainServiceImpl extends ServiceImpl implements IKcDetectionMainService { + +} diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/ktgl/service/impl/KcKetangbiaoServiceImpl.java b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/ktgl/service/impl/KcKetangbiaoServiceImpl.java index 17e34184..4a5b7b3d 100644 --- a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/ktgl/service/impl/KcKetangbiaoServiceImpl.java +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/ktgl/service/impl/KcKetangbiaoServiceImpl.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.apache.shiro.SecurityUtils; +import org.apache.shiro.UnavailableSecurityManagerException; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.modules.kc.kcTingkeBmd.entity.KcTingkeBmd; import org.jeecg.modules.kc.kcTingkeBmd.mapper.KcTingkeBmdKcxxMapper; @@ -36,16 +37,24 @@ public class KcKetangbiaoServiceImpl extends ServiceImpl getKclblist(Page page, KcKetangbiao kcKetangbiao) { - LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser user = null; + try { + user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + } catch (UnavailableSecurityManagerException e) { + log.error("无法获取用户"); + } + //获取当前用户是否有白名单权限 QueryWrapper kcTingkeBmdQueryWrapper = new QueryWrapper<>(); - kcTingkeBmdQueryWrapper.eq("jgh",user.getUsername()); + if(user != null){ + kcTingkeBmdQueryWrapper.eq("jgh",user.getUsername()); + } List list = kcTingkeBmdMapper.selectList(kcTingkeBmdQueryWrapper); String bmdId = ""; for(int i = 0; i < list.size(); i++){ bmdId = list.get(i).getId()+","; } - if(bmdId.indexOf(",")>-1){ + if(bmdId.contains(",")){ bmdId = bmdId.substring(0,bmdId.length()-1); } kcKetangbiao.setBmdId(bmdId); diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/tools/DateUtils.java b/jeecg-module-main/src/main/java/org/jeecg/modules/tools/DateUtils.java new file mode 100644 index 00000000..d06a7568 --- /dev/null +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/tools/DateUtils.java @@ -0,0 +1,94 @@ +package org.jeecg.modules.tools; + +//import org.apache.commons.lang.StringUtils; +//import org.joda.time.format.DateTimeFormat; +//import org.joda.time.format.DateTimeFormatter; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +/** + * @ClassName DateUtils + * @Description 日期工具类 + * @Author raymond + * @Date 2024/4/7 10:24 + * @Version 1.0 + **/ +public class DateUtils { + + /** 时间格式(yyyy-MM-dd) */ + public final static String DATE_PATTERN = "yyyy-MM-dd"; + public final static String DATE_PATTERN_CHINESE = "yyyy年MM月dd日"; + public final static String DATE_PATTERN_String = "yyyy-MM-dd"+" 00:00:00"; + public final static String DATE_PATTERN_END_TIME = "yyyy-MM-dd"+" 23:59:59"; + /** 时间格式(yyyy-MM-dd HH) */ + public final static String DATE_PATTERN_HOURS = "yyyy-MM-dd HH"; + /** 时间格式(yyyy-MM-dd HH:mm) */ + public final static String DATE_PATTERN_MINUTE = "yyyy-MM-dd HH:mm"; + /** 时间格式(yyyy-MM-dd HH:mm:ss) */ + public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; + + public final static String DATE_PAY_TIME = "yyyyMMddHHmmss"; + + /** + * 日期格式化 日期格式为:yyyy-MM-dd + * @param date 日期 + * @return 返回yyyy-MM-dd格式日期 + */ + public static String format(Date date) { + return format(date, DATE_PATTERN); + } + + /** + * 日期格式化 日期格式为:yyyy-MM-dd + * @param date 日期 + * @param pattern 格式,如:DateUtils.DATE_TIME_PATTERN + * @return 返回yyyy-MM-dd格式日期 + */ + public static String format(Date date, String pattern) { + if(date != null){ + SimpleDateFormat df = new SimpleDateFormat(pattern); + return df.format(date); + } + return null; + } + +// public static Date stringToDate(String strDate, String pattern) { +// if (StringUtils.isBlank(strDate)){ +// return null; +// } +// +// DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern); +// return fmt.parseLocalDateTime(strDate).toDate(); +// } + + public static Date executeDate(String payTime){ + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); + try { + return sdf.parse(payTime); + } catch (ParseException e) { + return null; + } + } + + public static String getTradeNo(){ + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm"); + String str = sdf.format(new Date()); + str += DateUtils.getCaptcha().substring(0,6); + return str.toLowerCase(Locale.ROOT); + } + + public static String getCaptcha(){ + String str = ""; + for (int i = 0; i < 7; i++) { + int num = (int) (Math.random() * 8); + str = str +num; + } + return str; + } + + public static void main(String[] args) { + } +} diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/tools/ffmpeg/FFmpegTools.java b/jeecg-module-main/src/main/java/org/jeecg/modules/tools/ffmpeg/FFmpegTools.java new file mode 100644 index 00000000..27429393 --- /dev/null +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/tools/ffmpeg/FFmpegTools.java @@ -0,0 +1,120 @@ +package org.jeecg.modules.tools.ffmpeg; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.RuntimeUtil; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @ClassName FFmpegTools + * @Description FFmpeg相关工具 + * @Author bai + * @Date 2024/5/6 19:53 + * @Version 1.0 + **/ +@Component +@Slf4j +public class FFmpegTools { + + /** + * 执行命令的核心文件 + */ + @Value("${ffmpeg.executableFile}") + public String executableFile; + + /** + * 日志等级,【 quiet | panic | fatal | error | warning | info | verbose | debug | trace】默认值为 info + */ + @Value("${ffmpeg.videoScreenshot.loglevel}") + public String loglevel; + + /** + * 视频过滤器 + */ + @Value("${ffmpeg.videoScreenshot.vf}") + public String vf; + + /** + * 图片压缩比例 + */ + @Value("${ffmpeg.videoScreenshot.compressionRatio}") + public String compressionRatio; + + + /** + * 是否覆盖输出文件【 y:覆盖 | n:不覆盖 】 + */ + @Value("${ffmpeg.videoScreenshot.isOverwrite}") + public String isOverwrite; + + + + /** + * + * @return [true: 压缩成功 | false: 压缩失败或是未压缩] + */ + public boolean videoScreenshot(String inputPath,String outPath){ + // -q:v 2 压缩比例,数越大,图越小 + // -vsync vfr 同步类型,,不知含义 + // -frames 1 截一帧 + // -vf 视频过滤器,select 选择器, scale缩放比例,-1:-1为原比例 + // ffmpeg -i https://kczx.nenu.edu.cn:9553/live_hls/wzl0236s_xsqj.m3u8 -q:v 2 -vf "select=not(mod(n\,15)),scale=-1:-1" -vsync vfr -frames:v 1 snapshot2.jpg + + List command = Lists.newArrayList(); + command.add(executableFile); + command.add("-i"); + command.add(inputPath);//输入的文件地址 + command.add("-vf"); + command.add(vf);//视频过滤器参数 + command.add("-vsync"); + command.add("vfr");//同步类型 + command.add("-frames:v"); + command.add("1");//截取一帧 + command.add("-q:v"); + command.add(compressionRatio);//压缩比 + command.add(outPath);//出的文件地址 + if(StringUtils.isNotBlank(loglevel)){ + command.add("-loglevel");//如果写了日志级别,则添加参数,不写默认是info + command.add(loglevel); + } + if(StringUtils.isNotBlank(isOverwrite)){ + command.add("-" + isOverwrite);//是否覆盖【 y | n 】 + } + + String[] cmdArr = command.toArray(new String[]{}); + log.debug("命令行参数为:{}",command); + log.debug("命令行参数为:{}",command.stream().collect(Collectors.joining(" "))); + log.info("\n--FFmpegTools--\n开始截取一帧图片!\n输入文件地址:{}",inputPath); + Process process = RuntimeUtil.exec(cmdArr); + String res = RuntimeUtil.getResult(process); + log.debug("脚本输出信息:\n{}",res); + //没法判断返回值,信息贼多,且没有个成功标识 + if(FileUtil.exist(outPath)){ + log.info("\n--FFmpegTools--\n截取一帧图片成功!\n输出文件地址:{}",outPath); + return true; + }else{ + log.error("\n--FFmpegTools--\n截取一帧图片失败!\n输出文件不存在,输出文件地址:{}",outPath); + } + return false; + } + + public static void main(String[] args) { + FFmpegTools _FFmpegTools = new FFmpegTools(); + _FFmpegTools.executableFile = "D:\\ProgramGreeFile\\ffmpeg\\bin\\ffmpeg.exe"; + _FFmpegTools.loglevel = "info"; + _FFmpegTools.vf = "\"select=not(mod(n\\,15)),scale=-1:-1\""; +// _FFmpegTools.vf = " -vsync vfr -frames:v 1"; + _FFmpegTools.compressionRatio = "2"; + _FFmpegTools.isOverwrite = "y"; + + boolean res = _FFmpegTools.videoScreenshot("https://kczx.nenu.edu.cn:9553/live_hls/wzl0236s_xsqj.m3u8","F:\\temp\\000\\11\\jietu22.jpeg"); + log.debug("最终结果:{}",res); + } + +} diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/tools/image/ZipImage.java b/jeecg-module-main/src/main/java/org/jeecg/modules/tools/image/ZipImage.java index f2f28551..5ea50b6d 100644 --- a/jeecg-module-main/src/main/java/org/jeecg/modules/tools/image/ZipImage.java +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/tools/image/ZipImage.java @@ -17,18 +17,18 @@ import java.util.List; @Slf4j public class ZipImage { + /** + * 执行命令的核心文件 + */ + @Value("${ffmpeg.executableFile}") + public String executableFile; + /** * 是否开启压缩【true:开启压缩 | false:关闭压缩 】 */ @Value("${ffmpeg.compress.enable}") public boolean enable; - /** - * 执行命令的核心文件 - */ - @Value("${ffmpeg.compress.executableFile}") - public String executableFile; - /** * 压缩比,正整数,数越大压缩比越高 */ diff --git a/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml b/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml index b06bb8b4..447a046c 100644 --- a/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml +++ b/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml @@ -302,14 +302,14 @@ libreOffice: ffmpeg: # 根路径 path: D:\ProgramGreeFile\ffmpeg\bin + # 执行命令的核心文件 + executableFile: ${ffmpeg.path}\ffmpeg.exe # 压缩相关 compress: # 是否开启压缩【true:开启压缩 | false:关闭压缩 】 enable: false # 日志等级,【 quiet | panic | fatal | error | warning | info | verbose | debug | trace】默认值为info loglevel: error - # 执行命令的核心文件 - executableFile: ${ffmpeg.path}\ffmpeg.exe # 压缩比,正整数,数越大压缩比越高 compressionRatio: 50 # 是否覆盖输出文件【 y:覆盖 | n:不覆盖 】 @@ -318,6 +318,16 @@ ffmpeg: isDeleteSourceFile: true # 压缩文件扩展名范围 extensionFilter: png,jpg,jpeg + # 视频截图相关 + videoScreenshot: + # 日志等级,【 quiet | panic | fatal | error | warning | info | verbose | debug | trace】默认值为info + loglevel: error + # 是否覆盖输出文件【 y:覆盖 | n:不覆盖 】 + isOverwrite: y + # 压缩 数越大,图越小 + compressionRatio: 2 + # 视频过滤器参数,,此处用意为截1张原尺寸当前时间的最新帧 + vf: '"select=not(mod(n\,15)),scale=-1:-1"' # 维普检测接口 weipu: userId: 765996 diff --git a/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml b/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml index 181ac82d..07ed4c50 100644 --- a/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml +++ b/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml @@ -310,14 +310,14 @@ libreOffice: ffmpeg: # 根路径 path: D:\ProgramGreeFile\ffmpeg\bin + # 执行命令的核心文件 + executableFile: ${ffmpeg.path}\ffmpeg.exe # 压缩相关 compress: # 是否开启压缩【true:开启压缩 | false:关闭压缩 】 enable: false # 日志等级,【 quiet | panic | fatal | error | warning | info | verbose | debug | trace】默认值为info loglevel: error - # 执行命令的核心文件 - executableFile: ${ffmpeg.path}\ffmpeg.exe # 压缩比,正整数,数越大压缩比越高 compressionRatio: 50 # 是否覆盖输出文件【 y:覆盖 | n:不覆盖 】 @@ -326,6 +326,16 @@ ffmpeg: isDeleteSourceFile: true # 压缩文件扩展名范围 extensionFilter: png,jpg,jpeg + # 视频截图相关 + videoScreenshot: + # 日志等级,【 quiet | panic | fatal | error | warning | info | verbose | debug | trace】默认值为info + loglevel: error + # 是否覆盖输出文件【 y:覆盖 | n:不覆盖 】 + isOverwrite: y + # 压缩 数越大,图越小 + compressionRatio: 2 + # 视频过滤器参数,,此处用意为截1张原尺寸当前时间的最新帧 + vf: '"select=not(mod(n\,15)),scale=-1:-1"' # 维普检测接口 weipu: userId: 765996