Merge remote-tracking branch 'origin/master'
commit
e438b1c5e6
2
ruoyi
2
ruoyi
|
|
@ -1 +1 @@
|
|||
Subproject commit abeed0c488d4f06787909249dd92f2e7fa5a25cd
|
||||
Subproject commit d456ff189647e16ffaaa170738d785eeee1253c0
|
||||
|
|
@ -10,7 +10,9 @@ import com.gunshi.core.result.R;
|
|||
import com.gunshi.project.xyt.entity.so.AttCctvBasePage;
|
||||
import com.gunshi.project.xyt.entity.vo.CctvControlVo;
|
||||
import com.gunshi.project.xyt.model.AttCctvBase;
|
||||
import com.gunshi.project.xyt.model.CctvBMenu;
|
||||
import com.gunshi.project.xyt.service.AttCctvBaseService;
|
||||
import com.gunshi.project.xyt.service.CctvBMenuService;
|
||||
import com.gunshi.project.xyt.util.OkHttpUtil;
|
||||
import com.gunshi.project.xyt.validate.markers.Insert;
|
||||
import com.gunshi.project.xyt.validate.markers.Update;
|
||||
|
|
@ -20,6 +22,8 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
|
@ -30,6 +34,7 @@ import java.util.Date;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 描述: 视频基本信息表
|
||||
|
|
@ -44,12 +49,24 @@ public class AttCctvBaseController {
|
|||
@Autowired
|
||||
private AttCctvBaseService service;
|
||||
|
||||
@Autowired
|
||||
private CctvBMenuService menuService;
|
||||
|
||||
@Operation(summary = "新增")
|
||||
@PostMapping("/insert")
|
||||
public R<AttCctvBase> insert(@Validated(Insert.class) @RequestBody AttCctvBase dto) {
|
||||
dto.setId(IdWorker.getId());
|
||||
dto.setCreateTime(new Date());
|
||||
if (StringUtils.isNotBlank(dto.getName()) && service.lambdaQuery().eq(AttCctvBase::getName,dto.getName())
|
||||
.count() > 0){
|
||||
throw new IllegalArgumentException("当前名称已存在");
|
||||
}
|
||||
if (Objects.nonNull(dto.getMenuId()) && menuService.lambdaQuery().eq(CctvBMenu::getId,dto.getMenuId())
|
||||
.count() == 0
|
||||
){
|
||||
throw new IllegalArgumentException("当前视频点目录不存在");
|
||||
}
|
||||
dto.setCreateTime(new Date());
|
||||
boolean result = service.save(dto);
|
||||
return R.ok(result ? dto : null);
|
||||
}
|
||||
|
|
@ -57,9 +74,22 @@ public class AttCctvBaseController {
|
|||
@Operation(summary = "修改")
|
||||
@PostMapping("/update")
|
||||
public R<AttCctvBase> update(@Validated(Update.class) @RequestBody AttCctvBase dto) {
|
||||
|
||||
if (Objects.isNull(service.getById(dto.getId()))){
|
||||
throw new RuntimeException("当前数据不存在");
|
||||
}
|
||||
if (StringUtils.isNotBlank(dto.getName()) && service.lambdaQuery().eq(AttCctvBase::getName,dto.getName())
|
||||
.ne(AttCctvBase::getId,dto.getId())
|
||||
.count() > 0){
|
||||
throw new IllegalArgumentException("当前名称已存在");
|
||||
}
|
||||
|
||||
if (Objects.nonNull(dto.getMenuId()) && menuService.lambdaQuery().eq(CctvBMenu::getId,dto.getMenuId())
|
||||
.count() == 0
|
||||
){
|
||||
throw new IllegalArgumentException("当前视频点目录不存在");
|
||||
}
|
||||
dto.setCreateTime(null);
|
||||
boolean result = service.updateById(dto);
|
||||
return R.ok(result ? dto : null);
|
||||
}
|
||||
|
|
@ -88,7 +118,7 @@ public class AttCctvBaseController {
|
|||
query.like(AttCctvBase::getIndexCode, page.getCode());
|
||||
}
|
||||
if (ObjectUtils.isNotNull(page.getMenuId())) {
|
||||
query.like(AttCctvBase::getMenuId, page.getMenuId());
|
||||
query.eq(AttCctvBase::getMenuId, page.getMenuId());
|
||||
}
|
||||
if (ObjectUtils.isNotNull(page.getName())) {
|
||||
query.like(AttCctvBase::getName, page.getName());
|
||||
|
|
@ -96,7 +126,24 @@ public class AttCctvBaseController {
|
|||
if (ObjectUtils.isNotNull(page.getType())) {
|
||||
query.eq(AttCctvBase::getType, Integer.valueOf(page.getType()));
|
||||
}
|
||||
return R.ok(service.page(page.getPageSo().toPage(), query));
|
||||
query.orderByDesc(AttCctvBase::getCreateTime);
|
||||
Page<AttCctvBase> basePage = service.page(page.getPageSo().toPage(), query);
|
||||
List<AttCctvBase> records = basePage.getRecords();
|
||||
if (CollectionUtils.isNotEmpty(records)){
|
||||
List<CctvBMenu> list = menuService.list();
|
||||
if (CollectionUtils.isNotEmpty(list)){
|
||||
Map<Long, List<String>> listMap = list.stream().
|
||||
collect(Collectors.groupingBy(CctvBMenu::getId, Collectors.mapping(CctvBMenu::getName, Collectors.toList())));
|
||||
|
||||
records.forEach(item -> {
|
||||
if (Objects.nonNull(item.getMenuId())){
|
||||
item.setMenuName(listMap.get(item.getMenuId()).getFirst());
|
||||
}
|
||||
});
|
||||
}
|
||||
basePage.setRecords(records);
|
||||
}
|
||||
return R.ok(basePage);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取预览地址")
|
||||
|
|
|
|||
|
|
@ -9,12 +9,15 @@ import com.gunshi.project.xyt.validate.markers.Update;
|
|||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 描述: 视频点目录
|
||||
* author: xusan
|
||||
|
|
@ -32,7 +35,23 @@ public class CctvBMenuController {
|
|||
@Operation(summary = "新增")
|
||||
@PostMapping("/insert")
|
||||
public R<CctvBMenu> insert(@Validated(Insert.class) @RequestBody CctvBMenu dto) {
|
||||
if (Objects.isNull(dto.getParentId())){
|
||||
dto.setParentId(0L);
|
||||
}
|
||||
if (StringUtils.isNotBlank(dto.getName()) && service.lambdaQuery().eq(CctvBMenu::getName,dto.getName())
|
||||
.count() > 0){
|
||||
throw new IllegalArgumentException("当前名称已存在");
|
||||
}
|
||||
dto.setId(IdWorker.getId());
|
||||
if (Objects.isNull(dto.getOrderIndex())){
|
||||
CctvBMenu one = service.lambdaQuery()
|
||||
.select(CctvBMenu::getOrderIndex)
|
||||
.orderByDesc(CctvBMenu::getOrderIndex)
|
||||
.one();
|
||||
if (Objects.nonNull(one)){
|
||||
dto.setOrderIndex(one.getOrderIndex() + 1);
|
||||
}
|
||||
}
|
||||
boolean result = service.save(dto);
|
||||
return R.ok(result ? dto : null);
|
||||
}
|
||||
|
|
@ -40,6 +59,11 @@ public class CctvBMenuController {
|
|||
@Operation(summary = "修改")
|
||||
@PostMapping("/update")
|
||||
public R<CctvBMenu> update(@Validated(Update.class) @RequestBody CctvBMenu dto) {
|
||||
if (StringUtils.isNotBlank(dto.getName()) && service.lambdaQuery().eq(CctvBMenu::getName,dto.getName())
|
||||
.ne(CctvBMenu::getId,dto.getId())
|
||||
.count() > 0){
|
||||
throw new IllegalArgumentException("当前名称已存在");
|
||||
}
|
||||
boolean result = service.updateById(dto);
|
||||
return R.ok(result ? dto : null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ public class GateValveCctvRelController {
|
|||
.count() > 0) {
|
||||
throw new IllegalArgumentException("当前编号已关联");
|
||||
}
|
||||
dto.setCreateTime(null);
|
||||
boolean result = service.updateById(dto);
|
||||
return R.ok(result ? dto : null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
package com.gunshi.project.xyt.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.gunshi.core.result.R;
|
||||
import com.gunshi.project.xyt.entity.so.CommonDataPageSo;
|
||||
import com.gunshi.project.xyt.model.ProjectEvents;
|
||||
import com.gunshi.project.xyt.service.ProjectEventsService;
|
||||
import com.gunshi.project.xyt.validate.markers.Insert;
|
||||
import com.gunshi.project.xyt.validate.markers.Update;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 描述: 工程大事记
|
||||
* author: wanyan
|
||||
* date: 2024-08-20 17:40:37
|
||||
*/
|
||||
@Tag(name = "工程大事记")
|
||||
@RestController
|
||||
@RequestMapping(value="/projectEvents")
|
||||
public class ProjectEventsController extends AbstractCommonFileController{
|
||||
|
||||
@Autowired
|
||||
private ProjectEventsService service;
|
||||
|
||||
|
||||
@Operation(summary = "新增")
|
||||
@PostMapping("/insert")
|
||||
public R<ProjectEvents> insert(@Validated(Insert.class) @RequestBody ProjectEvents dto) {
|
||||
return R.ok(service.saveData(dto));
|
||||
}
|
||||
|
||||
@Operation(summary = "修改")
|
||||
@PostMapping("/update")
|
||||
public R<ProjectEvents> update(@Validated(Update.class) @RequestBody ProjectEvents dto) {
|
||||
return R.ok(service.updateData(dto));
|
||||
}
|
||||
|
||||
@Operation(summary = "删除")
|
||||
@GetMapping("/del/{id}")
|
||||
public R<Boolean> del(@Schema(name = "id") @PathVariable("id") Serializable id) {
|
||||
return R.ok(service.delData(id));
|
||||
}
|
||||
|
||||
@Operation(summary = "列表")
|
||||
@PostMapping("/list")
|
||||
public R<List<ProjectEvents>> list(@RequestBody @Validated CommonDataPageSo so) {
|
||||
return R.ok(service.queryList(so));
|
||||
}
|
||||
|
||||
@Operation(summary = "分页")
|
||||
@PostMapping("/page")
|
||||
public R<Page<ProjectEvents>> page(@RequestBody @Validated CommonDataPageSo page) {
|
||||
return R.ok(service.pageQuery(page));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGroupId() {
|
||||
return "ProjectEvents";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
package com.gunshi.project.xyt.controller;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.gunshi.core.annotation.Get;
|
||||
import com.gunshi.core.annotation.Post;
|
||||
import com.gunshi.core.result.R;
|
||||
import com.gunshi.project.xyt.entity.dto.RotaDto;
|
||||
import com.gunshi.project.xyt.entity.vo.RotaVo;
|
||||
import com.gunshi.project.xyt.listener.RotaImportListener;
|
||||
import com.gunshi.project.xyt.model.RotaB;
|
||||
import com.gunshi.project.xyt.service.RotaService;
|
||||
import com.gunshi.project.xyt.util.ExcelUtil;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Created by wanyan on 2024/3/25
|
||||
*
|
||||
* @author wanyan
|
||||
* @version 1.0
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/rota")
|
||||
@Tag(name = "值班表")
|
||||
public class RotaController {
|
||||
|
||||
@Resource
|
||||
private RotaService rotaService;
|
||||
|
||||
|
||||
@Get(path = "/query", summary = "按年月查询")
|
||||
public R<Map<String,List<RotaB>>> query(@Schema(name = "yearMonth",description = "年月",example = "2024-03") @RequestParam(name = "yearMonth") String yearMonth) {
|
||||
return R.ok(rotaService.query(yearMonth));
|
||||
}
|
||||
|
||||
|
||||
@Post(path = "/edit/info", summary = "编辑值班信息")
|
||||
public R<String> editInfo(@RequestBody @Validated RotaDto rotaDto) {
|
||||
return R.ok(rotaService.editInfo(rotaDto));
|
||||
}
|
||||
|
||||
@Get(path = "/date/list", summary = "按年月日查询")
|
||||
public R<List<RotaB>> dateList(@Schema(name = "rotaDate",description = "年月日",example = "2024-08-19") @RequestParam(name = "rotaDate") String rotaDate) {
|
||||
return R.ok(rotaService.dateList(rotaDate));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取导入模板
|
||||
*/
|
||||
@Operation(summary = "获取导入模板")
|
||||
@PostMapping("/importTemplate")
|
||||
public void importTemplate(HttpServletResponse response) {
|
||||
ExcelUtil.exportExcel(new ArrayList<>(), "值班表", RotaVo.class, response, "值班表");
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入数据
|
||||
*
|
||||
* @param file 导入文件
|
||||
*
|
||||
*/
|
||||
@Operation(summary = "导入数据")
|
||||
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
public R importData(@RequestPart("file") MultipartFile file) throws Exception {
|
||||
//获取正确数据
|
||||
ArrayList<RotaVo> successArrayList = new ArrayList<>();
|
||||
//获取错误数据
|
||||
ArrayList<RotaVo> errorArrayList = new ArrayList<>();
|
||||
EasyExcel.read(file.getInputStream())
|
||||
.head(RotaVo.class)
|
||||
.registerReadListener(new RotaImportListener(
|
||||
// 监听器中doAfterAllAnalysed执行此方法;所有读取完成之后处理逻辑
|
||||
successArrayList::addAll, errorArrayList::addAll))
|
||||
// 设置sheet,默认读取第一个
|
||||
.sheet()
|
||||
// 设置标题(字段列表)所在行数
|
||||
.headRowNumber(2)
|
||||
.doRead();
|
||||
if(CollectionUtils.isNotEmpty(errorArrayList)){
|
||||
List<String> errMsg = errorArrayList.stream().map(RotaVo::getErrorMsg).collect(Collectors.toList());
|
||||
return R.error(400,String.join(";",errMsg));
|
||||
}
|
||||
if(CollectionUtils.isNotEmpty(successArrayList)){
|
||||
rotaService.saveImportData(successArrayList);
|
||||
return R.ok();
|
||||
}
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
package com.gunshi.project.xyt.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.gunshi.core.result.R;
|
||||
import com.gunshi.project.xyt.entity.so.RotaLogPageSo;
|
||||
import com.gunshi.project.xyt.model.RotaLog;
|
||||
import com.gunshi.project.xyt.service.RotaLogService;
|
||||
import com.gunshi.project.xyt.validate.markers.Insert;
|
||||
import com.gunshi.project.xyt.validate.markers.Update;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Created by wanyan on 2024/3/25
|
||||
*
|
||||
* @author wanyan
|
||||
* @version 1.0
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/rota/log")
|
||||
@Tag(name = "值班日志")
|
||||
public class RotaLogController {
|
||||
|
||||
@Resource
|
||||
private RotaLogService service;
|
||||
|
||||
@Operation(summary = "新增")
|
||||
@PostMapping("/insert")
|
||||
public R<RotaLog> insert(@Validated(Insert.class) @RequestBody RotaLog dto) {
|
||||
checkParam(dto);
|
||||
dto.setId(IdWorker.getId());
|
||||
boolean result = service.save(dto);
|
||||
return R.ok(result ? dto : null);
|
||||
}
|
||||
|
||||
@Operation(summary = "修改")
|
||||
@PostMapping("/update")
|
||||
public R<RotaLog> update(@Validated(Update.class) @RequestBody RotaLog dto) {
|
||||
checkParam(dto);
|
||||
boolean result = service.updateById(dto);
|
||||
return R.ok(result ? dto : null);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除")
|
||||
@GetMapping("/del/{id}")
|
||||
public R<Boolean> del(@Schema(name = "id") @PathVariable("id") Long id) {
|
||||
return R.ok(service.removeById(id));
|
||||
}
|
||||
|
||||
private void checkParam(RotaLog dto) {
|
||||
Long id = dto.getId();
|
||||
LambdaQueryWrapper<RotaLog> queryWrapper = Wrappers.lambdaQuery();
|
||||
queryWrapper.eq(RotaLog::getRotaDate,dto.getRotaDate());
|
||||
if(id != null){
|
||||
queryWrapper.ne(RotaLog::getId,id);
|
||||
}
|
||||
if(service.count(queryWrapper ) > 0){
|
||||
throw new IllegalArgumentException("该日期已存在值班日志");
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "分页")
|
||||
@PostMapping("/page")
|
||||
public R<Page<RotaLog>> page(@RequestBody RotaLogPageSo rotaLogPageSo) {
|
||||
return R.ok(service.queryPage(rotaLogPageSo));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -48,7 +48,7 @@ public class SysDictBController {
|
|||
throw new IllegalArgumentException("当前名称已存在");
|
||||
}
|
||||
}
|
||||
if (Objects.nonNull(dto.getPid())){
|
||||
if (Objects.nonNull(dto.getPid()) && !"0".equals(dto.getPid()) ){
|
||||
if (service.lambdaQuery().eq(SysDictB::getId,dto.getPid())
|
||||
.count() == 0) {
|
||||
throw new IllegalArgumentException("当父级不存在");
|
||||
|
|
@ -70,11 +70,12 @@ public class SysDictBController {
|
|||
|
||||
if (StringUtils.isNotBlank(dto.getDictNm())){
|
||||
if (service.lambdaQuery().eq(SysDictB::getDictNm,dto.getDictNm())
|
||||
.ne(SysDictB::getId,dto.getId())
|
||||
.count() > 0) {
|
||||
throw new IllegalArgumentException("当前名称已存在");
|
||||
}
|
||||
}
|
||||
if (Objects.nonNull(dto.getPid())){
|
||||
if (Objects.nonNull(dto.getPid()) && !"0".equals(dto.getPid()) ){
|
||||
if (service.lambdaQuery().eq(SysDictB::getId,dto.getPid())
|
||||
.count() == 0) {
|
||||
throw new IllegalArgumentException("当父级不存在");
|
||||
|
|
@ -112,6 +113,9 @@ public class SysDictBController {
|
|||
LambdaQueryWrapper<SysDictB> queryWrapper = Wrappers.lambdaQuery();
|
||||
|
||||
Page<SysDictB> data = service.page(page.getPageSo().toPage(), queryWrapper.eq(SysDictB::getPid,0L));
|
||||
|
||||
data.getRecords().forEach( o-> o.setChildren(service.lambdaQuery().eq(SysDictB::getPid,o.getId()).list()));
|
||||
|
||||
return R.ok(data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
package com.gunshi.project.xyt.entity.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.gunshi.core.dateformat.DateFormatString;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 值班表人员参数
|
||||
* Created by wanyan on 2024/3/25
|
||||
*
|
||||
* @author wanyan
|
||||
* @version 1.0
|
||||
*/
|
||||
@Data
|
||||
public class RotaDto {
|
||||
|
||||
/**
|
||||
* 日期
|
||||
*/
|
||||
@Schema(description="日期",example = "2024-03-25")
|
||||
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD, timezone = "GMT+8")
|
||||
@NotNull(message = "日期不能为空")
|
||||
private Date rotaDate;
|
||||
|
||||
/**
|
||||
* 是否节假日(0否 1是)
|
||||
*/
|
||||
@Schema(description="是否节假日(0否 1是)")
|
||||
private Integer isHoliday;
|
||||
|
||||
@Schema(description = "值班人员")
|
||||
private List<RotaUserDto> userDtoList;
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package com.gunshi.project.xyt.entity.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 值班表参数
|
||||
* Created by wanyan on 2024/3/25
|
||||
*
|
||||
* @author wanyan
|
||||
* @version 1.0
|
||||
*/
|
||||
@Data
|
||||
public class RotaUserDto {
|
||||
|
||||
/**
|
||||
* 类型(1带班领导 2值班人员)
|
||||
*/
|
||||
@Schema(description="类型(1带班领导 2值班人员)")
|
||||
private Integer rotaType;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@Schema(description="用户id")
|
||||
private Long userId;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.gunshi.project.xyt.entity.so;
|
||||
|
||||
import com.gunshi.db.dto.DateRangeSo;
|
||||
import com.gunshi.db.dto.PageSo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Created by wanyan on 2024/3/19
|
||||
*
|
||||
* @author wanyan
|
||||
* @version 1.0
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "分页查询对象")
|
||||
public class CommonDataPageSo {
|
||||
|
||||
@NotNull(message = "分页参数不能为空")
|
||||
@Schema(description = "分页参数")
|
||||
private PageSo pageSo;
|
||||
|
||||
@Schema(description="名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "时间范围")
|
||||
private DateRangeSo dateSo;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.gunshi.project.xyt.entity.so;
|
||||
|
||||
import com.gunshi.db.dto.DateRangeSo;
|
||||
import com.gunshi.db.dto.PageSo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Created by wanyan on 2024/3/19
|
||||
*
|
||||
* @author wanyan
|
||||
* @version 1.0
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "值班日志分页查询对象")
|
||||
public class RotaLogPageSo {
|
||||
|
||||
@NotNull(message = "分页参数不能为空")
|
||||
@Schema(description = "分页参数")
|
||||
private PageSo pageSo;
|
||||
|
||||
@Schema(description = "时间范围")
|
||||
private DateRangeSo dateSo;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package com.gunshi.project.xyt.entity.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.gunshi.core.dateformat.DateFormatString;
|
||||
import com.gunshi.project.xyt.util.excel.LengthValid;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class RotaVo {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 值班开始时间
|
||||
*/
|
||||
@ExcelProperty({"${title}","值班开始时间"})
|
||||
@ColumnWidth(25)
|
||||
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD, timezone = "GMT+8")
|
||||
private Date stm;
|
||||
|
||||
/**
|
||||
* 值班结束时间
|
||||
*/
|
||||
@ExcelProperty({"${title}","值班结束时间"})
|
||||
@ColumnWidth(25)
|
||||
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD, timezone = "GMT+8")
|
||||
private Date etm;
|
||||
|
||||
/**
|
||||
* 值班领导手机号
|
||||
*/
|
||||
@LengthValid(length = 11,msg = "值班领导手机号长度不等于11!")
|
||||
@ColumnWidth(25)
|
||||
@ExcelProperty({"${title}","值班领导手机号"})
|
||||
private String leaderPhone;
|
||||
|
||||
/**
|
||||
* 值班人员手机号
|
||||
*/
|
||||
@LengthValid(length = 11,msg = "值班人员手机号长度不等于11!")
|
||||
@ColumnWidth(25)
|
||||
@ExcelProperty({"${title}","值班人员手机号"})
|
||||
private String dutyPhone;
|
||||
|
||||
private String errorMsg;
|
||||
|
||||
private Long leaderUserId;
|
||||
|
||||
private Long dutyUserId;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
package com.gunshi.project.xyt.listener;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.context.AnalysisContext;
|
||||
import com.alibaba.excel.event.AnalysisEventListener;
|
||||
import com.alibaba.excel.exception.ExcelDataConvertException;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.gunshi.project.xyt.entity.vo.RotaVo;
|
||||
import com.gunshi.project.xyt.service.RotaService;
|
||||
import com.gunshi.project.xyt.util.excel.LengthValid;
|
||||
import com.gunshi.project.xyt.util.spring.SpringUtils;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* 读取excel数据
|
||||
*/
|
||||
@Slf4j
|
||||
public class RotaImportListener extends AnalysisEventListener<RotaVo> {
|
||||
|
||||
private final RotaService rotaService;
|
||||
|
||||
|
||||
/**临时存储正常数据集合*/
|
||||
private List<RotaVo> successDataList = Lists.newArrayList();
|
||||
|
||||
/**临时存错误储数据集合*/
|
||||
private List<RotaVo> errorDataList = Lists.newArrayList();
|
||||
|
||||
/**自定义消费者函数接口用于自定义监听器中数据组装*/
|
||||
private final Consumer<List<RotaVo>> successConsumer;
|
||||
|
||||
private final Consumer<List<RotaVo>> errorConsumer;
|
||||
|
||||
public RotaImportListener(Consumer<List<RotaVo>> successConsumer, Consumer<List<RotaVo>> errorConsumer) {
|
||||
this.successConsumer = successConsumer;
|
||||
this.errorConsumer = errorConsumer;
|
||||
this.rotaService = SpringUtils.getBean(RotaService.class);
|
||||
}
|
||||
|
||||
/**手机号格式异常日志处理*/
|
||||
@Override
|
||||
public void onException(Exception exception, AnalysisContext context) {
|
||||
log.error("异常信息:{}", exception.getMessage());
|
||||
// 如果是某一个单元格的转换异常 能获取到具体行号,如果要获取头的信息 配合invokeHeadMap使用
|
||||
if (exception instanceof ExcelDataConvertException) {
|
||||
ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
|
||||
log.error("第{}行,第{}列解析异常,数据为:{}", excelDataConvertException.getRowIndex(), excelDataConvertException.getColumnIndex(), excelDataConvertException.getCellData());
|
||||
}else if (exception instanceof IllegalArgumentException){
|
||||
throw new IllegalArgumentException(exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 在这里进行模板的判断
|
||||
* @param headMap 存放着导入表格的表头,键是索引,值是名称
|
||||
* @param context
|
||||
*/
|
||||
@Override
|
||||
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
|
||||
//只校验第三行表头是否正确
|
||||
Integer rowNum = context.getCurrentRowNum();
|
||||
if (rowNum == 2) {
|
||||
// 获取数据实体的字段列表
|
||||
Field[] fields = RotaVo.class.getDeclaredFields();
|
||||
// 遍历字段进行判断
|
||||
for (Field field : fields) {
|
||||
// 获取当前字段上的ExcelProperty注解信息
|
||||
ExcelProperty fieldAnnotation = field.getAnnotation(ExcelProperty.class);
|
||||
// 判断当前字段上是否存在ExcelProperty注解
|
||||
if (fieldAnnotation != null) {
|
||||
String value = fieldAnnotation.value()[1];
|
||||
// 存在ExcelProperty注解则根据注解的value值到表格中对比是否存在对应的表头
|
||||
if(!headMap.containsValue(value)){
|
||||
// 如果表格不包含模版类字段中的表头,则抛出异常不再往下执行
|
||||
throw new RuntimeException("模板错误,请检查导入模板");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**每行读取监听触发逻辑*/
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void invoke(RotaVo rotaVo, AnalysisContext analysisContext) {
|
||||
//获取总行数
|
||||
Integer rowNumber = analysisContext.readSheetHolder().getApproximateTotalRowNumber();
|
||||
//行数
|
||||
int row = analysisContext.readRowHolder().getRowIndex() + 1;
|
||||
log.info("第" + row + "行数据进行处理");
|
||||
// 手机号格式校验
|
||||
if(validParam(rotaVo,row)){
|
||||
successDataList.add(rotaVo);
|
||||
}else{
|
||||
errorDataList.add(rotaVo);
|
||||
}
|
||||
}
|
||||
|
||||
private Boolean validParam(RotaVo rotaVo, int row) throws IllegalAccessException {
|
||||
// 参数校验
|
||||
Field[] fields = rotaVo.getClass().getDeclaredFields();
|
||||
Boolean flag = true;
|
||||
String msg = "";
|
||||
for (Field field : fields) {
|
||||
//设置可访问
|
||||
field.setAccessible(true);
|
||||
//判断字段是否添加校验
|
||||
boolean valid = field.isAnnotationPresent(LengthValid.class);
|
||||
if (valid) {
|
||||
String name = field.getName();
|
||||
|
||||
//获取注解信息
|
||||
LengthValid annotation = field.getAnnotation(LengthValid.class);
|
||||
int cell = 4;
|
||||
if("leaderPhone".equals(name)){
|
||||
cell = 3;
|
||||
}
|
||||
//行数列数
|
||||
msg += "第" + row + "行的第" + cell + "列:";
|
||||
//值
|
||||
String value = (String) field.get(rotaVo);
|
||||
System.out.println("value = "+value);
|
||||
if(value.length() != annotation.length()){
|
||||
//错误信息
|
||||
msg += annotation.msg();
|
||||
flag = false;
|
||||
}
|
||||
Long userId = rotaService.checkPhone(value);
|
||||
if(userId == null){
|
||||
//错误信息
|
||||
String err = "手机号"+value+"未找到对应的系统用户,请先核实用户手机号再进行模板导入!";
|
||||
msg += err;
|
||||
flag = false;
|
||||
}else{
|
||||
if(cell == 3){
|
||||
rotaVo.setLeaderUserId(userId);
|
||||
}else {
|
||||
rotaVo.setDutyUserId(userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
rotaVo.setErrorMsg(msg);
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
|
||||
if (CollectionUtils.isNotEmpty(successDataList)) {
|
||||
successConsumer.accept(successDataList);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(errorDataList)) {
|
||||
errorConsumer.accept(errorDataList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*监听器的hasNext()方法时没有注意到默认返回的是false,导致一进监听器就判断已经没有下一条记录,直接跳出监听器,然后导入就完成,也不会报错,改成返回true即可解决
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext(AnalysisContext analysisContext) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -27,10 +27,10 @@ public interface GateValveCctvRelMapper extends BaseMapper<GateValveCctvRel> {
|
|||
LEFT JOIN public.att_cctv_base acb ON t.index_code = acb.index_code
|
||||
<where>
|
||||
<if test="obj.valveName != null and obj.valveName !=''">
|
||||
agv.valve_name LIKE concat('%',#{obj.valveName},'%')
|
||||
AND agv.valve_name LIKE '%'||#{obj.valveName}||'%'
|
||||
</if>
|
||||
<if test="obj.indexName != null and obj.indexName !=''">
|
||||
acb.name LIKE concat('%',#{obj.indexName},'%')
|
||||
AND acb.name LIKE '%'||#{obj.indexName}||'%'
|
||||
</if>
|
||||
</where>
|
||||
<if test="obj.orderField != null and obj.orderField !=''">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
package com.gunshi.project.xyt.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.gunshi.project.xyt.model.OriginMessage;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface OriginMessageMapper extends BaseMapper<OriginMessage> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.gunshi.project.xyt.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.gunshi.project.xyt.model.ProjectEvents;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface ProjectEventsMapper extends BaseMapper<ProjectEvents> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.gunshi.project.xyt.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.gunshi.project.xyt.model.RotaB;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface RotaBMapper extends BaseMapper<RotaB> {
|
||||
|
||||
|
||||
@Select("""
|
||||
<script>
|
||||
select t.*,s.user_name from public.rota_b t left join public.sys_user s on t.user_id = s.user_id
|
||||
where to_char(t.rota_date, 'YYYY-MM') = #{yearMonth}
|
||||
</script>
|
||||
""")
|
||||
List<RotaB> query(@Param("yearMonth") String yearMonth);
|
||||
|
||||
@Select("""
|
||||
<script>
|
||||
select t.*,s.user_name from public.rota_b t left join public.sys_user s on t.user_id = s.user_id
|
||||
where to_char(t.rota_date, 'YYYY-MM-DD') = #{rotaDate} order by rota_type
|
||||
</script>
|
||||
""")
|
||||
List<RotaB> dateList(@Param("rotaDate") String rotaDate);
|
||||
|
||||
@Select("""
|
||||
<script>
|
||||
select s.user_id from public.sys_user s where s.phonenumber = #{value}
|
||||
</script>
|
||||
""")
|
||||
Long queryUser(@Param("value") String value);
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package com.gunshi.project.xyt.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.gunshi.project.xyt.entity.so.RotaLogPageSo;
|
||||
import com.gunshi.project.xyt.model.RotaLog;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
@Mapper
|
||||
public interface RotaLogMapper extends BaseMapper<RotaLog> {
|
||||
|
||||
@Select("""
|
||||
<script>
|
||||
select t.*,s.user_name as leaderUserName,m.user_name as dutyUserName from public.rota_log t
|
||||
left join public.sys_user s on t.leader_user_id = s.user_id
|
||||
left join public.sys_user m on t.duty_user_id = m.user_id
|
||||
<where>
|
||||
<if test="obj.dateSo != null and obj.dateSo.start != null">
|
||||
t.rota_date <![CDATA[>=]]> #{obj.dateSo.start}
|
||||
</if>
|
||||
<if test="obj.dateSo != null and obj.dateSo.end != null">
|
||||
and t.rota_date <![CDATA[<=]]> #{obj.dateSo.end}
|
||||
</if>
|
||||
</where>
|
||||
order by t.rota_date desc
|
||||
</script>
|
||||
""")
|
||||
Page<RotaLog> queryPage(Page<RotaLog> page,@Param("obj") RotaLogPageSo rotaLogPageSo);
|
||||
}
|
||||
|
|
@ -111,6 +111,13 @@ public class AttCctvBase implements Serializable {
|
|||
@Schema(description="menu_id")
|
||||
private Long menuId;
|
||||
|
||||
/**
|
||||
* menu_id
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
@Schema(description="所在区域")
|
||||
private String menuName;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ public class CctvBMenu implements Serializable {
|
|||
*/
|
||||
@TableField(value="parent_id")
|
||||
@Schema(description="parent_id")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@ 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 com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.gunshi.core.dateformat.DateFormatString;
|
||||
import com.gunshi.project.xyt.validate.markers.Insert;
|
||||
import com.gunshi.project.xyt.validate.markers.Update;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
|
@ -45,7 +47,7 @@ public class GateValveCctvRel implements Serializable {
|
|||
*/
|
||||
@TableField(value="valve_code")
|
||||
@Schema(description="闸阀编号")
|
||||
@Size(max = 20,message = "闸阀编号最大长度要小于 20")
|
||||
@Size(max = 100,message = "闸阀编号最大长度要小于 100")
|
||||
@NotBlank(message = "闸阀编号不能为空", groups = {Insert.class,Update.class})
|
||||
private String valveCode;
|
||||
|
||||
|
|
@ -54,7 +56,7 @@ public class GateValveCctvRel implements Serializable {
|
|||
*/
|
||||
@TableField(value="index_code")
|
||||
@Schema(description="视频点")
|
||||
@Size(max = 150,message = "视频点最大长度要小于 150")
|
||||
@Size(max = 100,message = "视频点最大长度要小于 100")
|
||||
@NotBlank(message = "视频点不能为空", groups = {Insert.class,Update.class})
|
||||
private String indexCode;
|
||||
|
||||
|
|
@ -63,6 +65,7 @@ public class GateValveCctvRel implements Serializable {
|
|||
*/
|
||||
@TableField(value="create_time")
|
||||
@Schema(description="创建时间")
|
||||
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD_HH_MM_SS, timezone = "GMT+8")
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package com.gunshi.project.xyt.model;
|
||||
|
||||
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 com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.gunshi.core.dateformat.DateFormatString;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Created by wanyan on 2024/8/2
|
||||
*
|
||||
* @author wanyan
|
||||
* @version 1.0
|
||||
*/
|
||||
@Schema(description="原始报文表")
|
||||
@Data
|
||||
@TableName("public.origin_message")
|
||||
public class OriginMessage {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value="id", type= IdType.AUTO)
|
||||
@Schema(description="主键")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
@TableField(value="protocol")
|
||||
@Schema(description="协议")
|
||||
private String protocol;
|
||||
|
||||
@TableField(value="address")
|
||||
@Schema(description="设备地址")
|
||||
private String address;
|
||||
|
||||
@TableField(value="func_code")
|
||||
@Schema(description="功能码")
|
||||
private String funcCode;
|
||||
|
||||
@TableField(value="data_time")
|
||||
@Schema(description="数据时间")
|
||||
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD_HH_MM_SS, timezone = "GMT+8")
|
||||
private Date dataTime;
|
||||
|
||||
@TableField(value="message")
|
||||
@Schema(description="报文")
|
||||
private String message;
|
||||
|
||||
@TableField(value="tm")
|
||||
@Schema(description="时间戳")
|
||||
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD_HH_MM_SS, timezone = "GMT+8")
|
||||
private Date tm;
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
package com.gunshi.project.xyt.model;
|
||||
|
||||
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 com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.gunshi.core.dateformat.DateFormatString;
|
||||
import com.gunshi.project.xyt.validate.markers.Insert;
|
||||
import com.gunshi.project.xyt.validate.markers.Update;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 工程大事记
|
||||
*/
|
||||
@Schema(description="工程大事记")
|
||||
@Data
|
||||
@TableName(value = "public.project_events")
|
||||
public class ProjectEvents implements Serializable {
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.INPUT)
|
||||
@Schema(description="主键")
|
||||
@NotNull(message = "主键不能为空",groups = {Update.class})
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
@TableField(value = "name")
|
||||
@Schema(description="名称")
|
||||
@NotEmpty(message = "名称不可为空",groups = {Insert.class,Update.class})
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 发生日期
|
||||
*/
|
||||
@TableField(value = "events_date")
|
||||
@Schema(description="发生日期")
|
||||
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD, timezone = "GMT+8")
|
||||
@NotNull(message = "日期不能为空",groups = {Insert.class,Update.class})
|
||||
private Date eventsDate;
|
||||
|
||||
/**
|
||||
* 类型(1综合大事记 2专题大事记)
|
||||
*/
|
||||
@TableField(value = "events_type")
|
||||
@Schema(description="类型(1综合大事记 2专题大事记)")
|
||||
private Integer eventsType;
|
||||
|
||||
|
||||
@TableField(value = "events_desc")
|
||||
@Schema(description="事件内容描述")
|
||||
@NotEmpty(message = "事件内容描述不可为空",groups = {Insert.class,Update.class})
|
||||
private String eventsDesc;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "文件集合")
|
||||
private List<FileAssociations> files;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package com.gunshi.project.xyt.model;
|
||||
|
||||
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 com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.gunshi.core.dateformat.DateFormatString;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 值班表
|
||||
*/
|
||||
@Schema(description="值班表")
|
||||
@Data
|
||||
@TableName(value = "public.rota_b")
|
||||
public class RotaB implements Serializable {
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.INPUT)
|
||||
@Schema(description="主键")
|
||||
@NotNull(message = "主键不能为空")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 日期
|
||||
*/
|
||||
@TableField(value = "rota_date")
|
||||
@Schema(description="日期")
|
||||
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD, timezone = "GMT+8")
|
||||
@NotNull(message = "日期不能为空")
|
||||
private Date rotaDate;
|
||||
|
||||
/**
|
||||
* 类型(1带班领导 2值班人员)
|
||||
*/
|
||||
@TableField(value = "rota_type")
|
||||
@Schema(description="类型(1带班领导 2值班人员)")
|
||||
private Integer rotaType;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@TableField(value = "user_id")
|
||||
@Schema(description="用户id")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 是否节假日(0否 1是)
|
||||
*/
|
||||
@TableField(value = "is_holiday")
|
||||
@Schema(description="是否节假日(0否 1是)")
|
||||
private Integer isHoliday;
|
||||
|
||||
|
||||
@Schema(description="用户姓名")
|
||||
@TableField(exist = false)
|
||||
private String userName;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
package com.gunshi.project.xyt.model;
|
||||
|
||||
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 com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.gunshi.core.dateformat.DateFormatString;
|
||||
import com.gunshi.project.xyt.validate.markers.Insert;
|
||||
import com.gunshi.project.xyt.validate.markers.Update;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 值班日志
|
||||
*/
|
||||
@Schema(description="值班日志")
|
||||
@Data
|
||||
@TableName(value = "public.rota_log")
|
||||
public class RotaLog implements Serializable {
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.INPUT)
|
||||
@Schema(description="主键")
|
||||
@NotNull(message = "主键不能为空", groups = {Update.class})
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 日期
|
||||
*/
|
||||
@TableField(value = "rota_date")
|
||||
@Schema(description="日期")
|
||||
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD, timezone = "GMT+8")
|
||||
@NotNull(message = "日期不能为空", groups = {Insert.class, Update.class})
|
||||
private Date rotaDate;
|
||||
|
||||
@TableField(value = "weather")
|
||||
@Schema(description="天气")
|
||||
private String weather;
|
||||
|
||||
/**
|
||||
* 带班领导id
|
||||
*/
|
||||
@TableField(value = "leader_user_id")
|
||||
@Schema(description="带班领导id")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long leaderUserId;
|
||||
|
||||
@Schema(description="带班领导姓名")
|
||||
@TableField(exist = false)
|
||||
private String leaderUserName;
|
||||
|
||||
/**
|
||||
* 值班人员id
|
||||
*/
|
||||
@TableField(value = "duty_user_id")
|
||||
@Schema(description="值班人员id")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long dutyUserId;
|
||||
|
||||
@Schema(description="值班人员姓名")
|
||||
@TableField(exist = false)
|
||||
private String dutyUserName;
|
||||
|
||||
@TableField(value = "duty_situation")
|
||||
@Schema(description="值班情况")
|
||||
private String dutySituation;
|
||||
|
||||
@TableField(value = "todo_list")
|
||||
@Schema(description="待处理事项")
|
||||
private String todoList;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
|
|
@ -11,7 +11,6 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
|
@ -26,14 +25,15 @@ public class CctvBMenuService extends ServiceImpl<CctvBMenuMapper, CctvBMenu>
|
|||
{
|
||||
|
||||
public List<CctvBMenu> tree() {
|
||||
List<CctvBMenu> list = list(lambdaQuery().orderByDesc(CctvBMenu::getId));
|
||||
List<CctvBMenu> list = list();
|
||||
if (CollectionUtils.isEmpty(list)){
|
||||
return list;
|
||||
}
|
||||
|
||||
Map<Long, List<CctvBMenu>> listMap = list.stream().collect(Collectors.groupingBy(CctvBMenu::getParentId));
|
||||
|
||||
list.forEach(o -> o.setChildren(listMap.get(o.getId())));
|
||||
List<CctvBMenu> parentList = list.stream().filter(o -> Objects.isNull(o.getParentId())).collect(Collectors.toList());
|
||||
List<CctvBMenu> parentList = list.stream().filter(o -> 0L == o.getParentId()).collect(Collectors.toList());
|
||||
return sorted(parentList);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
package com.gunshi.project.xyt.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gunshi.project.xyt.entity.so.CommonDataPageSo;
|
||||
import com.gunshi.project.xyt.mapper.ProjectEventsMapper;
|
||||
import com.gunshi.project.xyt.model.ProjectEvents;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 描述: 水库历史水位表
|
||||
* author: xusan
|
||||
* date: 2024-07-08 17:30:38
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class ProjectEventsService extends ServiceImpl<ProjectEventsMapper, ProjectEvents> {
|
||||
|
||||
@Autowired
|
||||
private FileAssociationsService fileService;
|
||||
|
||||
public Page<ProjectEvents> pageQuery(CommonDataPageSo page) {
|
||||
LambdaQueryWrapper<ProjectEvents> query = Wrappers.lambdaQuery();
|
||||
if (ObjectUtils.isNotNull(page.getName())) {
|
||||
query.like(ProjectEvents::getName, page.getName());
|
||||
}
|
||||
if (page.getDateSo() != null && page.getDateSo().getStart() != null) {
|
||||
query.ge(ProjectEvents::getEventsDate, page.getDateSo().getStart());
|
||||
}
|
||||
if (page.getDateSo() != null && page.getDateSo().getEnd() != null) {
|
||||
query.le(ProjectEvents::getEventsDate, page.getDateSo().getEnd());
|
||||
}
|
||||
query.orderByDesc(ProjectEvents::getEventsDate);
|
||||
Page<ProjectEvents> res = this.page(page.getPageSo().toPage(), query);
|
||||
if (res.getRecords() != null) {
|
||||
fillAttach(res.getRecords());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private void fillAttach(List<ProjectEvents> ret) {
|
||||
for (ProjectEvents record : ret) {
|
||||
record.setFiles(fileService.getFiles(getGroupId(), String.valueOf(record.getId())));
|
||||
}
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return "ProjectEvents";
|
||||
}
|
||||
|
||||
public ProjectEvents saveData(ProjectEvents dto) {
|
||||
dto.setId(IdWorker.getId());
|
||||
boolean result = this.save(dto);
|
||||
if (result) {
|
||||
fileService.saveFile(dto.getFiles(), getGroupId(), String.valueOf(dto.getId()));
|
||||
}
|
||||
return dto;
|
||||
}
|
||||
|
||||
public ProjectEvents updateData(ProjectEvents dto) {
|
||||
if (Objects.isNull(this.getById(dto.getId()))) {
|
||||
throw new IllegalArgumentException("当前数据不存在");
|
||||
}
|
||||
boolean result = this.updateById(dto);
|
||||
if (result) {
|
||||
fileService.saveFile(dto.getFiles(), getGroupId(), String.valueOf(dto.getId()));
|
||||
}
|
||||
return dto;
|
||||
}
|
||||
|
||||
public Boolean delData(Serializable id) {
|
||||
if (Objects.isNull(this.getById(id))) {
|
||||
throw new IllegalArgumentException("当前数据不存在");
|
||||
}
|
||||
boolean data = this.removeById(id);
|
||||
if (data) {
|
||||
fileService.deleteFile(getGroupId(), id.toString());
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public List<ProjectEvents> queryList(CommonDataPageSo page) {
|
||||
LambdaQueryWrapper<ProjectEvents> query = Wrappers.lambdaQuery();
|
||||
if (ObjectUtils.isNotNull(page.getName())) {
|
||||
query.like(ProjectEvents::getName, page.getName());
|
||||
}
|
||||
if (page.getDateSo() != null && page.getDateSo().getStart() != null) {
|
||||
query.ge(ProjectEvents::getEventsDate, page.getDateSo().getStart());
|
||||
}
|
||||
if (page.getDateSo() != null && page.getDateSo().getEnd() != null) {
|
||||
query.le(ProjectEvents::getEventsDate, page.getDateSo().getEnd());
|
||||
}
|
||||
query.orderByDesc(ProjectEvents::getEventsDate);
|
||||
List<ProjectEvents> list = this.list(query);
|
||||
fillAttach(list);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.gunshi.project.xyt.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gunshi.project.xyt.entity.so.RotaLogPageSo;
|
||||
import com.gunshi.project.xyt.mapper.RotaLogMapper;
|
||||
import com.gunshi.project.xyt.model.RotaLog;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Created by wanyan on 2024/3/25
|
||||
*
|
||||
* @author wanyan
|
||||
* @version 1.0
|
||||
*/
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class RotaLogService extends ServiceImpl<RotaLogMapper, RotaLog> {
|
||||
|
||||
public Page<RotaLog> queryPage(RotaLogPageSo rotaLogPageSo) {
|
||||
return this.baseMapper.queryPage(rotaLogPageSo.getPageSo().toPage(),rotaLogPageSo);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
package com.gunshi.project.xyt.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gunshi.core.dateformat.DateFormatString;
|
||||
import com.gunshi.project.xyt.entity.dto.RotaDto;
|
||||
import com.gunshi.project.xyt.entity.dto.RotaUserDto;
|
||||
import com.gunshi.project.xyt.entity.vo.RotaVo;
|
||||
import com.gunshi.project.xyt.mapper.RotaBMapper;
|
||||
import com.gunshi.project.xyt.model.RotaB;
|
||||
import com.gunshi.project.xyt.util.DateUtil;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Created by wanyan on 2024/3/25
|
||||
*
|
||||
* @author wanyan
|
||||
* @version 1.0
|
||||
*/
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class RotaService extends ServiceImpl<RotaBMapper, RotaB> {
|
||||
|
||||
|
||||
public Map<String,List<RotaB>> query(String yearMonth) {
|
||||
List<RotaB> list = this.baseMapper.query(yearMonth);
|
||||
return list.stream().collect(Collectors.groupingBy(rota -> new SimpleDateFormat(DateFormatString.YYYY_MM_DD).format(rota.getRotaDate())));
|
||||
}
|
||||
|
||||
public String editInfo(RotaDto RotaDto) {
|
||||
Date rotaDate = RotaDto.getRotaDate();
|
||||
//先删除该日期的所有信息
|
||||
LambdaQueryWrapper<RotaB> queryWrapper = Wrappers.lambdaQuery();
|
||||
queryWrapper.eq(RotaB::getRotaDate,rotaDate);
|
||||
this.remove(queryWrapper);
|
||||
if(RotaDto.getIsHoliday() != null && RotaDto.getIsHoliday() == 1){
|
||||
RotaB rotaB = new RotaB();
|
||||
BeanUtils.copyProperties(RotaDto,rotaB,RotaB.class);
|
||||
rotaB.setId(IdWorker.getId());
|
||||
this.save(rotaB);
|
||||
return "设为放假日成功";
|
||||
}
|
||||
List<RotaUserDto> userDtoList = RotaDto.getUserDtoList();
|
||||
List<RotaB> list = userDtoList.stream().map(o -> {
|
||||
RotaB rotaB = new RotaB();
|
||||
rotaB.setId(IdWorker.getId());
|
||||
rotaB.setRotaDate(rotaDate);
|
||||
rotaB.setIsHoliday(0);
|
||||
rotaB.setRotaType(o.getRotaType());
|
||||
rotaB.setUserId(o.getUserId());
|
||||
return rotaB;
|
||||
}).collect(Collectors.toList());
|
||||
this.saveBatch(list);
|
||||
return "设置值班信息成功";
|
||||
}
|
||||
|
||||
public List<RotaB> dateList(String rotaDate) {
|
||||
return this.baseMapper.dateList(rotaDate);
|
||||
}
|
||||
|
||||
public Long checkPhone(String value){
|
||||
return this.baseMapper.queryUser(value);
|
||||
}
|
||||
|
||||
public void saveImportData(ArrayList<RotaVo> successArrayList) {
|
||||
List<RotaB> list = new ArrayList<>();
|
||||
for(RotaVo vo : successArrayList){
|
||||
Date stm = vo.getStm();
|
||||
Date etm = vo.getEtm();
|
||||
List<Date> dates = DateUtil.getDatesBetween(stm, etm);
|
||||
dates.stream().forEach(str->{
|
||||
RotaB rotaB = new RotaB();
|
||||
rotaB.setId(IdWorker.getId());
|
||||
rotaB.setRotaDate(str);
|
||||
rotaB.setIsHoliday(0);
|
||||
rotaB.setRotaType(1);
|
||||
rotaB.setUserId(vo.getLeaderUserId());
|
||||
list.add(rotaB);
|
||||
|
||||
RotaB rota = new RotaB();
|
||||
rota.setId(IdWorker.getId());
|
||||
rota.setRotaDate(str);
|
||||
rota.setIsHoliday(0);
|
||||
rota.setRotaType(2);
|
||||
rota.setUserId(vo.getDutyUserId());
|
||||
list.add(rota);
|
||||
});
|
||||
}
|
||||
this.saveOrUpdateBatch(list);
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,6 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
|
@ -27,14 +26,14 @@ public class SysDictBService extends ServiceImpl<SysDictBMapper, SysDictB>
|
|||
|
||||
|
||||
public List<SysDictB> tree() {
|
||||
List<SysDictB> list = list(lambdaQuery().orderByDesc(SysDictB::getId));
|
||||
List<SysDictB> list = list();
|
||||
if (CollectionUtils.isEmpty(list)){
|
||||
return list;
|
||||
}
|
||||
Map<Long, List<SysDictB>> listMap = list.stream().collect(Collectors.groupingBy(SysDictB::getPid));
|
||||
|
||||
list.forEach(o -> o.setChildren(listMap.get(o.getId())));
|
||||
List<SysDictB> parentList = list.stream().filter(o -> Objects.isNull(o.getPid())).collect(Collectors.toList());
|
||||
List<SysDictB> parentList = list.stream().filter(o -> 0L == o.getPid()).collect(Collectors.toList());
|
||||
return sorted(parentList);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -169,5 +169,18 @@ public class DateUtil {
|
|||
return dates;
|
||||
}
|
||||
|
||||
public static List<Date> getDatesBetween(Date startDate, Date endDate) {
|
||||
List<Date> dates = new ArrayList<>();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(startDate);
|
||||
|
||||
while (calendar.getTime().before(endDate)) {
|
||||
dates.add(calendar.getTime());
|
||||
calendar.add(Calendar.DATE, 1);
|
||||
}
|
||||
dates.add(endDate);
|
||||
return dates;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
package com.gunshi.project.xyt.util.excel;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Created by wanyan on 2024/8/19
|
||||
*
|
||||
* @author wanyan
|
||||
* @version 1.0
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
public @interface LengthValid {
|
||||
|
||||
int length() default 0;
|
||||
|
||||
String msg() default "";
|
||||
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue