设计管理设计出图导入导出

This commit is contained in:
2025-09-06 12:52:12 +08:00
parent ab5cd491d6
commit 2cea57646d
34 changed files with 604 additions and 160 deletions

View File

@ -67,6 +67,16 @@ public class BusPurchaseDocController extends BaseController {
return busPurchaseDocService.queryPageList(bo, pageQuery); return busPurchaseDocService.queryPageList(bo, pageQuery);
} }
/**
* 查询物资-采购联系单列表
*/
@SaCheckPermission("cailiaoshebei:purchaseDoc:list")
@GetMapping("/getList")
public R<List<BusPurchaseDocVo>> getList(BusPurchaseDocBo bo) {
return R.ok(busPurchaseDocService.queryList(bo));
}
/** /**
* 导出物资-采购联系单列表 * 导出物资-采购联系单列表
*/ */

View File

@ -28,6 +28,11 @@ public class BusTotalsupplyplanBo extends BaseEntity {
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) @NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
private Long id; private Long id;
/**
* 项目Id
*/
private Long projectId;
/** /**
* 批次号 * 批次号
*/ */

View File

@ -104,6 +104,7 @@ public class BusTotalsupplyplanServiceImpl extends ServiceImpl<BusTotalsupplypla
private LambdaQueryWrapper<BusTotalsupplyplan> buildQueryWrapper(BusTotalsupplyplanBo bo) { private LambdaQueryWrapper<BusTotalsupplyplan> buildQueryWrapper(BusTotalsupplyplanBo bo) {
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<BusTotalsupplyplan> lqw = Wrappers.lambdaQuery(); LambdaQueryWrapper<BusTotalsupplyplan> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getProjectId() != null ,BusTotalsupplyplan::getProjectId,bo.getProjectId());
lqw.eq(StringUtils.isNotBlank(bo.getTexture()), BusTotalsupplyplan::getTexture, bo.getTexture()); lqw.eq(StringUtils.isNotBlank(bo.getTexture()), BusTotalsupplyplan::getTexture, bo.getTexture());
lqw.eq(StringUtils.isNotBlank(bo.getBrand()), BusTotalsupplyplan::getBrand, bo.getBrand()); lqw.eq(StringUtils.isNotBlank(bo.getBrand()), BusTotalsupplyplan::getBrand, bo.getBrand());
lqw.eq(StringUtils.isNotBlank(bo.getQualityStandard()), BusTotalsupplyplan::getQualityStandard, bo.getQualityStandard()); lqw.eq(StringUtils.isNotBlank(bo.getQualityStandard()), BusTotalsupplyplan::getQualityStandard, bo.getQualityStandard());

View File

@ -159,7 +159,7 @@ public class DesVolumeCatalogController extends BaseController {
/** /**
* 收资清单模板导出 * 收资清单模板导出
*/ */
@SaCheckPermission("design:collect:exportExcel") @SaCheckPermission("design:volumeCatalog:exportExcel")
@Log(title = "收资清单", businessType = BusinessType.EXPORT) @Log(title = "收资清单", businessType = BusinessType.EXPORT)
@PostMapping("/exportExcel") @PostMapping("/exportExcel")
public void exportExcelByProjectId(@RequestParam("projectId") Long projectId, HttpServletResponse response){ public void exportExcelByProjectId(@RequestParam("projectId") Long projectId, HttpServletResponse response){
@ -181,11 +181,14 @@ public class DesVolumeCatalogController extends BaseController {
List<ExcelData> dataList = readExcel(file); List<ExcelData> dataList = readExcel(file);
List<DesVolumeCatalogCreateReq> desVolumeCatalogCreateReqs = BeanUtil.copyToList(dataList, DesVolumeCatalogCreateReq.class); List<DesVolumeCatalogCreateReq> desVolumeCatalogCreateReqs = BeanUtil.copyToList(dataList, DesVolumeCatalogCreateReq.class);
Collections.reverse(desVolumeCatalogCreateReqs); Collections.reverse(desVolumeCatalogCreateReqs);
List<DesVolumeCatalogCreateReq> list = new ArrayList<>();
for (DesVolumeCatalogCreateReq desVolumeCatalogCreateReq : desVolumeCatalogCreateReqs) { for (DesVolumeCatalogCreateReq desVolumeCatalogCreateReq : desVolumeCatalogCreateReqs) {
desVolumeCatalogCreateReq.setProjectId(projectId); desVolumeCatalogCreateReq.setProjectId(projectId);
desVolumeCatalogCreateReq.setDesignState("2"); desVolumeCatalogCreateReq.setDesignState("2");
desVolumeCatalogService.insertByBo(desVolumeCatalogCreateReq); list.add(desVolumeCatalogCreateReq);
// desVolumeCatalogService.insertByBo(desVolumeCatalogCreateReq);
} }
desVolumeCatalogService.insertBatchByBo(list);
return toAjax(true); return toAjax(true);
} }
@ -235,17 +238,18 @@ public class DesVolumeCatalogController extends BaseController {
// 从第二行(index=1)开始读取数据,跳过表头 // 从第二行(index=1)开始读取数据,跳过表头
for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) { for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
Row row = sheet.getRow(rowIndex); Row row = sheet.getRow(rowIndex);
if (row != null) { if (hasValidData(row)) {
String designSubitem = getCellValue(row.getCell(0)); String designSubitem = getCellValue(row.getCell(0));
// String designState = getCellValue(row.getCell(1)); String specialty = getCellValue(row.getCell(1));
// String specialty = getCellValue(row.getCell(2)); String specialtyId = getCellValue(row.getCell(2));
// String principal = getCellValue(row.getCell(3)); String principal = getCellValue(row.getCell(3));
String volumeNumber = getCellValue(row.getCell(1)); String principalId = getCellValue(row.getCell(4));
String documentName = getCellValue(row.getCell(2)); String volumeNumber = getCellValue(row.getCell(5));
LocalDate plannedCompletion = getLocalDateValue(row.getCell(3)); String documentName = getCellValue(row.getCell(6));
LocalDate plannedCompletion = getLocalDateValue(row.getCell(7));
ExcelData excelData = new ExcelData( ExcelData excelData = new ExcelData(
designSubitem, volumeNumber, documentName, designSubitem,specialtyId,principalId, volumeNumber, documentName,
plannedCompletion plannedCompletion
); );
dataList.add(excelData); dataList.add(excelData);
@ -255,6 +259,19 @@ public class DesVolumeCatalogController extends BaseController {
return dataList; return dataList;
} }
private static boolean hasValidData(Row row) {
// 遍历行中的所有单元格
for (int cellIndex = 0; cellIndex < row.getLastCellNum(); cellIndex++) {
Cell cell = row.getCell(cellIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
String cellValue = getCellValue(cell).trim();
// 只要有一个单元格有非空值,就认为是有效行
if (!cellValue.isEmpty()) {
return true;
}
}
return false;
}
private static String getCellValue(Cell cell) { private static String getCellValue(Cell cell) {
if (cell == null) { if (cell == null) {

View File

@ -29,6 +29,11 @@ public class DesVolumeCatalog extends BaseEntity {
@TableId(value = "design") @TableId(value = "design")
private Long design; private Long design;
/**
* 序号
*/
private Long serialNumber;
/** /**
* 项目ID * 项目ID
*/ */

View File

@ -1,5 +1,7 @@
package org.dromara.design.domain.dto; package org.dromara.design.domain.dto;
import lombok.Data;
import java.time.LocalDate; import java.time.LocalDate;
/** /**
@ -7,34 +9,37 @@ import java.time.LocalDate;
* @Date 2025/8/12 22:53 * @Date 2025/8/12 22:53
* @Version 1.0 * @Version 1.0
*/ */
@Data
public class ExcelData { public class ExcelData {
private String designSubitem; private String designSubitem;
// private String designState; private String specialty;
// private String specialty; // private String specialtyId;
// private String principal; private String principal;
// private Long principalId;
private String volumeNumber; private String volumeNumber;
private String documentName; private String documentName;
private LocalDate plannedCompletion; private LocalDate plannedCompletion;
// 构造函数 // 构造函数
public ExcelData(String designSubitem, String volumeNumber, String documentName, LocalDate plannedCompletion) { public ExcelData(String designSubitem, String specialty, String principal, String volumeNumber, String documentName, LocalDate plannedCompletion) {
this.designSubitem = designSubitem; this.designSubitem = designSubitem;
// this.designState = designState; this.specialty = specialty;
// this.specialty = specialty; // this.specialtyId = specialtyId;
// this.principal = principal; this.principal = principal;
// this.principalId = principalId;
this.volumeNumber = volumeNumber; this.volumeNumber = volumeNumber;
this.documentName = documentName; this.documentName = documentName;
this.plannedCompletion = plannedCompletion; this.plannedCompletion = plannedCompletion;
} }
// Getter和Setter方法 // Getter和Setter方法
public String getDesignSubitem() { // public String getDesignSubitem() {
return designSubitem; // return designSubitem;
} // }
//
public void setDesignSubitem(String designSubitem) { // public void setDesignSubitem(String designSubitem) {
this.designSubitem = designSubitem; // this.designSubitem = designSubitem;
} // }
// public String getDesignState() { // public String getDesignState() {
// return designState; // return designState;
@ -60,27 +65,27 @@ public class ExcelData {
// this.principal = principal; // this.principal = principal;
// } // }
public String getVolumeNumber() { // public String getVolumeNumber() {
return volumeNumber; // return volumeNumber;
} // }
//
public void setVolumeNumber(String volumeNumber) { // public void setVolumeNumber(String volumeNumber) {
this.volumeNumber = volumeNumber; // this.volumeNumber = volumeNumber;
} // }
//
public String getDocumentName() { // public String getDocumentName() {
return documentName; // return documentName;
} // }
//
public void setDocumentName(String documentName) { // public void setDocumentName(String documentName) {
this.documentName = documentName; // this.documentName = documentName;
} // }
//
public LocalDate getPlannedCompletion() { // public LocalDate getPlannedCompletion() {
return plannedCompletion; // return plannedCompletion;
} // }
//
public void setPlannedCompletion(LocalDate plannedCompletion) { // public void setPlannedCompletion(LocalDate plannedCompletion) {
this.plannedCompletion = plannedCompletion; // this.plannedCompletion = plannedCompletion;
} // }
} }

View File

@ -34,6 +34,11 @@ public class DesVolumeCatalogVo implements Serializable {
*/ */
private Long design; private Long design;
/**
* 序号
*/
private Long serialNumber;
/** /**
* 项目ID * 项目ID
*/ */

View File

@ -1,5 +1,6 @@
package org.dromara.design.service; package org.dromara.design.service;
import jakarta.validation.constraints.NotNull;
import org.dromara.design.domain.dto.desUser.DesUserBatchDto; import org.dromara.design.domain.dto.desUser.DesUserBatchDto;
import org.dromara.design.domain.vo.DesUserVo; import org.dromara.design.domain.vo.DesUserVo;
import org.dromara.design.domain.bo.DesUserBo; import org.dromara.design.domain.bo.DesUserBo;
@ -8,10 +9,10 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 设计人员Service接口 * 设计人员Service接口
@ -84,4 +85,15 @@ public interface IDesUserService extends IService<DesUser>{
* 查询用户对应专业 * 查询用户对应专业
*/ */
List<String> selectUserMajors(Long userId); List<String> selectUserMajors(Long userId);
/**
* 查询专业和专业名
* @param desUserBo
* @return
*/
Map<String, String> getUserMajor(DesUserBo desUserBo);
Map<String, String> getUserList(DesUserBo desUserBo);
Long getCount(String principal, String specialty, Long projectId);
} }

View File

@ -122,4 +122,6 @@ public interface IDesVolumeCatalogService extends IService<DesVolumeCatalog> {
List<DesVolumeCatalogVo> catalogList(Long projectId); List<DesVolumeCatalogVo> catalogList(Long projectId);
void exportExcelByProjectId(Long projectId, HttpServletResponse response); void exportExcelByProjectId(Long projectId, HttpServletResponse response);
void insertBatchByBo(List<DesVolumeCatalogCreateReq> list);
} }

View File

@ -10,6 +10,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.dromara.design.domain.dto.desUser.DesUserBatchDto; import org.dromara.design.domain.dto.desUser.DesUserBatchDto;
import org.dromara.system.domain.vo.SysDictDataVo;
import org.dromara.system.service.ISysDictDataService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.dromara.design.domain.bo.DesUserBo; import org.dromara.design.domain.bo.DesUserBo;
import org.dromara.design.domain.vo.DesUserVo; import org.dromara.design.domain.vo.DesUserVo;
@ -17,9 +19,8 @@ import org.dromara.design.domain.DesUser;
import org.dromara.design.mapper.DesUserMapper; import org.dromara.design.mapper.DesUserMapper;
import org.dromara.design.service.IDesUserService; import org.dromara.design.service.IDesUserService;
import java.util.List; import java.util.*;
import java.util.Map; import java.util.stream.Collectors;
import java.util.Collection;
/** /**
* 设计人员Service业务层处理 * 设计人员Service业务层处理
@ -33,6 +34,8 @@ public class DesUserServiceImpl extends ServiceImpl<DesUserMapper, DesUser> impl
private final DesUserMapper baseMapper; private final DesUserMapper baseMapper;
private final ISysDictDataService sysDictDataService;
/** /**
* 查询设计人员 * 查询设计人员
* *
@ -146,4 +149,41 @@ public class DesUserServiceImpl extends ServiceImpl<DesUserMapper, DesUser> impl
public List<String> selectUserMajors(Long userId){ public List<String> selectUserMajors(Long userId){
return baseMapper.selectUserMajors(userId); return baseMapper.selectUserMajors(userId);
} }
@Override
public Map<String, String> getUserMajor(DesUserBo desUserBo) {
List<DesUserVo> desUserVos = baseMapper.selectVoList(new LambdaQueryWrapper<DesUser>()
.eq(DesUser::getProjectId, desUserBo.getProjectId())
.groupBy(DesUser::getUserMajor));
List<SysDictDataVo> list = sysDictDataService.selectByDictType("des_user_major");
Map<String, String> dictMap = list.stream().filter(Objects::nonNull).collect(Collectors
.toMap(SysDictDataVo::getDictValue, SysDictDataVo::getDictLabel, (existing, existing1) -> existing));
Map<String, String> map = new HashMap<>();
for (DesUserVo desUserVo : desUserVos) {
if (desUserVo !=null){
map.put(desUserVo.getUserMajor(), dictMap.get(desUserVo.getUserMajor()));
}
}
return map;
}
@Override
public Map<String, String> getUserList(DesUserBo desUserBo) {
List<DesUserVo> desUserVos = baseMapper.selectVoList(new LambdaQueryWrapper<DesUser>()
.eq(DesUser::getProjectId, desUserBo.getProjectId())
.groupBy(DesUser::getUserId));
Map<String, String> map = new HashMap<>();
for (DesUserVo desUserVo : desUserVos) {
map.put(desUserVo.getUserId().toString(), desUserVo.getUserName());
}
return map;
}
@Override
public Long getCount(String principal, String specialty, Long projectId) {
return baseMapper.selectCount(new LambdaQueryWrapper<DesUser>()
.eq(DesUser::getProjectId, projectId)
.eq(DesUser::getUserId, Long.valueOf(principal))
.eq(DesUser::getUserMajor, specialty));
}
} }

View File

@ -10,10 +10,9 @@ import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList; import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.dromara.cailiaoshebei.domain.BusCailiaoshebeiPici;
import org.dromara.common.core.constant.HttpStatus; import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.event.ProcessDeleteEvent; import org.dromara.common.core.domain.event.ProcessDeleteEvent;
import org.dromara.common.core.domain.event.ProcessEvent; import org.dromara.common.core.domain.event.ProcessEvent;
import org.dromara.common.core.domain.event.ProcessTaskEvent; import org.dromara.common.core.domain.event.ProcessTaskEvent;
@ -23,21 +22,21 @@ import org.dromara.common.core.utils.ObjectUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.design.domain.*; import org.dromara.design.domain.*;
import org.dromara.design.domain.bo.DesUserBo; import org.dromara.design.domain.bo.DesUserBo;
import org.dromara.design.domain.dto.volumecatalog.DesVolumeCatalogCreateReq; import org.dromara.design.domain.dto.volumecatalog.DesVolumeCatalogCreateReq;
import org.dromara.design.domain.dto.volumecatalog.DesVolumeCatalogQueryReq; import org.dromara.design.domain.dto.volumecatalog.DesVolumeCatalogQueryReq;
import org.dromara.design.domain.dto.volumecatalog.DesVolumeCatalogUpdateReq; import org.dromara.design.domain.dto.volumecatalog.DesVolumeCatalogUpdateReq;
import org.dromara.design.domain.vo.DesUserVo;
import org.dromara.design.domain.vo.volumecatalog.DesVolumeCatalogVo; import org.dromara.design.domain.vo.volumecatalog.DesVolumeCatalogVo;
import org.dromara.design.mapper.DesVolumeCatalogMapper; import org.dromara.design.mapper.DesVolumeCatalogMapper;
import org.dromara.design.service.*; import org.dromara.design.service.*;
import org.dromara.project.service.IBusProjectService; import org.dromara.project.service.IBusProjectService;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.vo.SysUserVo; import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.service.ISysUserService; import org.dromara.system.service.ISysUserService;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.context.event.EventListener; import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -148,6 +147,11 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
*/ */
@Override @Override
public Boolean insertByBo(DesVolumeCatalogCreateReq req) { public Boolean insertByBo(DesVolumeCatalogCreateReq req) {
Object object = RedisUtils.getCacheObject("DesVolumeCatalog:serialNumber");
long serialNumber = 0L;
if (ObjectUtils.isNotEmpty(object)) {
serialNumber = ((Integer) object).longValue();
}
Long projectId = req.getProjectId(); Long projectId = req.getProjectId();
if (projectService.getById(projectId) == null) { if (projectService.getById(projectId) == null) {
throw new ServiceException("对应项目不存在", HttpStatus.NOT_FOUND); throw new ServiceException("对应项目不存在", HttpStatus.NOT_FOUND);
@ -163,15 +167,61 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
if (count > 0) { if (count > 0) {
throw new ServiceException("卷册目录已存在", HttpStatus.BAD_REQUEST); throw new ServiceException("卷册目录已存在", HttpStatus.BAD_REQUEST);
} }
long count1 = desUserService.count(new LambdaQueryWrapper<DesUser>()
.eq(DesUser::getUserMajor, req.getSpecialty())
.eq(DesUser::getUserId, req.getPrincipal()));
if (count1 == 0) {
throw new ServiceException("所选专业不包含该人员");
}
DesVolumeCatalog volumeCatalog = new DesVolumeCatalog(); DesVolumeCatalog volumeCatalog = new DesVolumeCatalog();
BeanUtils.copyProperties(req, volumeCatalog); BeanUtils.copyProperties(req, volumeCatalog);
volumeCatalog.setSerialNumber(serialNumber);
boolean save = this.save(volumeCatalog); boolean save = this.save(volumeCatalog);
if (!save) { if (!save) {
RedisUtils.setCacheObject("DesVolumeCatalog:serialNumber",serialNumber);
throw new ServiceException("卷册目录新增失败", HttpStatus.ERROR); throw new ServiceException("卷册目录新增失败", HttpStatus.ERROR);
} }
return true; return true;
} }
@Override
@Transactional(rollbackFor = Exception.class)
public void insertBatchByBo(List<DesVolumeCatalogCreateReq> list) {
Object object = RedisUtils.getCacheObject("DesVolumeCatalog:serialNumber");
long serialNumber = 0L;
if (ObjectUtils.isNotEmpty(object)) {
serialNumber = ((Integer) object).longValue();
}
List<DesVolumeCatalog> desVolumeCatalogs = new ArrayList<>();
for (DesVolumeCatalogCreateReq req : list) {
Long projectId = req.getProjectId();
if (projectService.getById(projectId) == null) {
throw new ServiceException("对应项目不存在", HttpStatus.NOT_FOUND);
}
// 判断是否重名
Long count = this.lambdaQuery()
.eq(DesVolumeCatalog::getProjectId, projectId)
.and(lqw -> lqw
.eq(DesVolumeCatalog::getVolumeNumber, req.getVolumeNumber())
.or()
.eq(DesVolumeCatalog::getDocumentName, req.getDocumentName()))
.count();
if (count > 0) {
throw new ServiceException("卷册目录已存在", HttpStatus.BAD_REQUEST);
}
Long count1 = desUserService.getCount(req.getPrincipal(),req.getSpecialty(),req.getProjectId());
if (count1 == 0) {
throw new ServiceException("所选专业不包含该人员");
}
DesVolumeCatalog volumeCatalog = new DesVolumeCatalog();
BeanUtils.copyProperties(req, volumeCatalog);
volumeCatalog.setSerialNumber(serialNumber++);
desVolumeCatalogs.add(volumeCatalog);
}
baseMapper.insertBatch(desVolumeCatalogs);
RedisUtils.setCacheObject("DesVolumeCatalog:serialNumber",serialNumber);
}
/** /**
* 修改卷册目录 * 修改卷册目录
* *
@ -286,8 +336,8 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
String volumeNumber = req.getVolumeNumber(); String volumeNumber = req.getVolumeNumber();
String documentName = req.getDocumentName(); String documentName = req.getDocumentName();
String auditStatus = req.getAuditStatus(); String auditStatus = req.getAuditStatus();
lqw.orderByDesc(DesVolumeCatalog::getCreateTime); // lqw.orderByDesc(DesVolumeCatalog::getCreateTime);
lqw.orderByAsc(DesVolumeCatalog::getVolumeNumber); lqw.orderByAsc(DesVolumeCatalog::getSerialNumber);
lqw.like(StringUtils.isNotBlank(documentName), DesVolumeCatalog::getDocumentName, documentName); lqw.like(StringUtils.isNotBlank(documentName), DesVolumeCatalog::getDocumentName, documentName);
lqw.eq(StringUtils.isNotBlank(volumeNumber), DesVolumeCatalog::getVolumeNumber, volumeNumber); lqw.eq(StringUtils.isNotBlank(volumeNumber), DesVolumeCatalog::getVolumeNumber, volumeNumber);
lqw.eq(ObjectUtils.isNotEmpty(projectId), DesVolumeCatalog::getProjectId, projectId); lqw.eq(ObjectUtils.isNotEmpty(projectId), DesVolumeCatalog::getProjectId, projectId);
@ -368,23 +418,11 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
public void exportExcelByProjectId(Long projectId, HttpServletResponse response) { public void exportExcelByProjectId(Long projectId, HttpServletResponse response) {
DesUserBo desUserBo = new DesUserBo(); DesUserBo desUserBo = new DesUserBo();
desUserBo.setProjectId(projectId); desUserBo.setProjectId(projectId);
Map<String, List<String>> majorToNames = new HashMap<>(); Map<String, String> uniqueMajors = desUserService.getUserMajor(desUserBo);
List<DesUserVo> desUserVos = desUserService.queryList(desUserBo); Map<String, String> userList = desUserService.getUserList(desUserBo);
List<DesUserVo> uniqueMajors = new ArrayList<>(desUserVos.stream()
.collect(Collectors.toMap(
DesUserVo::getUserMajor,
user -> user,
(existing, replacement) -> existing
))
.values());
uniqueMajors.forEach(desUserVo -> {
desUserBo.setUserMajor(desUserVo.getUserMajor());
List<DesUserVo> desUserVos1 = desUserService.queryList(desUserBo);
List<String> names = desUserVos1.stream()
.map(DesUserVo::getUserName)
.collect(Collectors.toList());
majorToNames.put(desUserVo.getUserMajorName(), names);
});
//TODO 数据绑定下拉 //TODO 数据绑定下拉
// String[] namesArray = names.toArray(String[]::new); // String[] namesArray = names.toArray(String[]::new);
@ -398,48 +436,117 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
Workbook workbook = new XSSFWorkbook(); Workbook workbook = new XSSFWorkbook();
// 创建主 Sheet 和隐藏 Sheet // 创建主 Sheet 和隐藏 Sheet
Sheet mainSheet = workbook.createSheet("收资清单模板"); Sheet mainSheet = workbook.createSheet("收资清单模板");
Sheet dropdownSheet = workbook.createSheet("DropdownData"); Sheet dataSheet = workbook.createSheet("DropdownData");
workbook.setSheetHidden(workbook.getSheetIndex(dropdownSheet), true); workbook.setSheetHidden(workbook.getSheetIndex(dataSheet), true);
// 3. 创建单元格样式
//设置下拉列表数据 CellStyle editableStyle = createEditableCellStyle(workbook); // 可编辑单元格样式
// for (int i = 0; i < namesArray.length; i++) { CellStyle protectedStyle = createProtectedCellStyle(workbook); // 受保护单元格样式ID列用
// dropdownSheet.createRow(i).createCell(1).setCellValue(namesArray[i]); // 存到B列
// } //填充隐藏数据Sheet
// int rowIdx = 0; int rowIndex = 0;
// for (Map.Entry<Long, String> entry : userIdToNameMapByDept.entrySet()) {
// Row row = dropdownSheet.createRow(rowIdx++); // 填充专业和专业IDA列和B列
// row.createCell(0).setCellValue(entry.getKey().toString()); for (Map.Entry<String, String> entry : uniqueMajors.entrySet()) {
// row.createCell(1).setCellValue(entry.getValue()); Row row = dataSheet.createRow(rowIndex++);
// } row.createCell(0).setCellValue(entry.getValue()); // A列专业ID
row.createCell(1).setCellValue(entry.getKey()); // B列专业名称
}
// 重置行索引填充人员和人员IDC列和D列
rowIndex = 0;
for (Map.Entry<String, String> entry : userList.entrySet()) {
Row row = dataSheet.getRow(rowIndex);
if (row == null) {
row = dataSheet.createRow(rowIndex);
}
row.createCell(2).setCellValue(entry.getValue()); // C列人员ID
row.createCell(3).setCellValue(entry.getKey()); // D列人员名称
rowIndex++;
}
// 主 Sheet 设置表头 // 主 Sheet 设置表头
Row sheetRow = mainSheet.createRow(0); Row sheetRow = mainSheet.createRow(0);
sheetRow.createCell(0).setCellValue("子项名称"); String[] headers = {"子项名称", "专业", "专业编码",
sheetRow.createCell(1).setCellValue("卷册号"); "人员", "人员编码", "卷册号","资料名称","计划出图时间"};
sheetRow.createCell(2).setCellValue("资料名称"); for (int i = 0; i < headers.length; i++) {
sheetRow.createCell(3).setCellValue("计划出图时间"); Cell cell = sheetRow.createCell(i);
sheetRow.createCell(4).setCellValue("专业"); cell.setCellValue(headers[i]);
sheetRow.createCell(5).setCellValue("人员"); }
// 6. 设置专业下拉列表(第二列)
setMajorDropdown(mainSheet,uniqueMajors.size());
// 8. 设置人员下拉列表(第四列)
setPersonDropdown(mainSheet, userList.size());
String formulaTemplate = "IFERROR(INDEX(DropdownData!$B$1:$B$" + uniqueMajors.size() + ", MATCH(B{rowNum}, DropdownData!$A$1:$A$" + uniqueMajors.size()+ ", 0)),\"\")";
String formulaTemplate1 = "IFERROR(INDEX(DropdownData!$D$1:$D$" + userList.size() + ", MATCH(D{rowNum}, DropdownData!$C$1:$C$" + userList.size()+ ", 0)),\"\")";
for (int i = 1; i <= 100; i++) { // 从第2行到101行
Row row = mainSheet.createRow(i);
int currentRowNum = i + 1; // Excel行号从1开始
String formula = formulaTemplate.replace("{rowNum}", String.valueOf(currentRowNum));
Cell cell = row.createCell(1);
cell.setCellStyle(editableStyle); //专业不锁定
Cell idCell = row.createCell(2);
idCell.setCellFormula(formula);
idCell.setCellStyle(protectedStyle); // 应用隐藏公式样式
String formula1 = formulaTemplate1.replace("{rowNum}", String.valueOf(currentRowNum));
Cell cell2 = row.createCell(3);
cell2.setCellStyle(editableStyle);
Cell idCell2 = row.createCell(4);
idCell2.setCellFormula(formula1);
idCell2.setCellStyle(protectedStyle);
}
for (int i = 1; i <= 100; i++) {
Row row = mainSheet.getRow(i);
if (row == null) {
row = mainSheet.createRow(i);
}
Cell cell = row.createCell(0);
cell.setCellStyle(editableStyle);
Cell cell1 = row.createCell(5);
cell1.setCellStyle(editableStyle);
Cell cell2 = row.createCell(6);
cell2.setCellStyle(editableStyle);
Cell cell3 = row.createCell(7);
cell3.setCellStyle(editableStyle);
}
// 保护工作表,仅允许编辑未锁定的单元格
mainSheet.protectSheet("123456"); // 空密码
// 核心锁定表头第1行和前1列包含ID列 // 核心锁定表头第1行和前1列包含ID列
mainSheet.createFreezePane(0, 1, 0, 0); mainSheet.createFreezePane(0, 1, 0, 1);
// 绑定下拉列表(关联隐藏 Sheet
DataValidationHelper helper = mainSheet.getDataValidationHelper(); //为主Sheet第二列设置下拉列表关联隐藏Sheet的B列
// String range = "DropdownData!$B$1:$B$" + namesArray.length; //引用隐藏Sheet的B列数据范围DropdownData!$B$1:$B$
// DataValidationConstraint constraint = helper.createFormulaListConstraint(range); //创建下拉约束
CellRangeAddressList addressList = new CellRangeAddressList(1, 300, 1, 1); // 支持100行数据
//添加验证规则
// DataValidation validation = helper.createValidation(constraint, addressList);
// validation.setShowErrorBox(true);
// mainSheet.addValidationData(validation);
// 调整列宽 // 调整列宽
mainSheet.setColumnWidth(0, 20 * 256); mainSheet.setColumnWidth(0, 20 * 256);
mainSheet.setColumnWidth(1, 20 * 100); mainSheet.setColumnWidth(1, 20 * 200);
mainSheet.setColumnWidth(2, 20 * 200); mainSheet.setColumnWidth(2, 20 * 200);
mainSheet.setColumnWidth(3, 20 * 200); mainSheet.setColumnWidth(3, 20 * 200);
mainSheet.setColumnWidth(4, 20 * 200);
mainSheet.setColumnWidth(5, 20 * 200);
mainSheet.setColumnWidth(6, 20 * 200);
mainSheet.setColumnWidth(7, 20 * 200);
// 直接写入响应输出流 // 直接写入响应输出流
try { try {
@ -451,6 +558,71 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
} }
/**
* 创建可编辑单元格样式
*/
private CellStyle createEditableCellStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
style.setLocked(false); // 关键:允许编辑
return style;
}
/**
* 创建受保护单元格样式用于ID列
*/
private CellStyle createProtectedCellStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
DataFormat dataFormat = workbook.createDataFormat();
short formatIndex = dataFormat.getFormat("0"); // 匹配“自定义→0”格式
style.setDataFormat(formatIndex);
style.setHidden(true); // 隐藏公式
style.setLocked(true);
return style;
}
/**
* 设置专业下拉列表第二列索引1
*/
private void setMajorDropdown(Sheet mainSheet,int majorCount) {
DataValidationHelper helper = mainSheet.getDataValidationHelper();
// 专业数据范围数据Sheet的A列从第1行到专业数量行
String majorRange = "DropdownData!$A$1:$A$" + majorCount;
DataValidationConstraint constraint = helper.createFormulaListConstraint(majorRange);
// 作用范围第2行到100行第二列
CellRangeAddressList addressList = new CellRangeAddressList(1, 100, 1, 1);
DataValidation validation = helper.createValidation(constraint, addressList);
validation.setShowErrorBox(true);
mainSheet.addValidationData(validation);
}
/**
* 设置人员下拉列表第四列索引3
*/
private void setPersonDropdown(Sheet mainSheet, int personCount) {
DataValidationHelper helper = mainSheet.getDataValidationHelper();
// 人员数据范围数据Sheet的C列从第1行到人员数量行
String personRange = "DropdownData!$C$1:$C$" + personCount;
DataValidationConstraint constraint = helper.createFormulaListConstraint(personRange);
// 作用范围第2行到100行第四列
CellRangeAddressList addressList = new CellRangeAddressList(1, 100, 3, 3);
DataValidation validation = helper.createValidation(constraint, addressList);
validation.setShowErrorBox(true);
mainSheet.addValidationData(validation);
}
/** /**
* 总体流程监听(例如: 草稿,撤销,退回,作废,终止,已完成,单任务完成等) * 总体流程监听(例如: 草稿,撤销,退回,作废,终止,已完成,单任务完成等)
* 正常使用只需#processEvent.flowCode=='leave1' * 正常使用只需#processEvent.flowCode=='leave1'

View File

@ -10,14 +10,18 @@ import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*; import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.contractor.domain.SubConstructionUser; import org.dromara.contractor.domain.SubConstructionUser;
import org.dromara.contractor.domain.dto.constructionuser.SubConstructionUserQueryReq; import org.dromara.contractor.domain.dto.constructionuser.SubConstructionUserQueryReq;
import org.dromara.contractor.domain.exportvo.BusConstructionUserExportVo; import org.dromara.contractor.domain.exportvo.BusConstructionUserExportVo;
import org.dromara.contractor.domain.vo.constructionuser.SubConstructionUserVo; import org.dromara.contractor.domain.vo.constructionuser.SubConstructionUserVo;
import org.dromara.contractor.service.ISubConstructionUserService; import org.dromara.contractor.service.ISubConstructionUserService;
import org.dromara.gps.domain.vo.ConstructionUser; import org.dromara.gps.domain.vo.ConstructionUser;
import org.dromara.gps.domain.vo.GpsProjectVo;
import org.dromara.gps.domain.vo.GpsUserVo; import org.dromara.gps.domain.vo.GpsUserVo;
import org.dromara.project.service.IBusProjectService; import org.dromara.project.service.IBusProjectService;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.vo.SysUserVo;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit; import org.dromara.common.idempotent.annotation.RepeatSubmit;
@ -134,6 +138,11 @@ public class GpsEquipmentController extends BaseController {
/** /**
* 项目列表 * 项目列表
*/ */
@SaCheckPermission("gps:equipment:getProjectList")
@GetMapping("/getProjectList")
public R<List<GpsProjectVo>> getProjectList() {
return R.ok(gpsEquipmentService.getProjectList());
}
@ -145,6 +154,9 @@ public class GpsEquipmentController extends BaseController {
@RepeatSubmit() @RepeatSubmit()
@PostMapping("/bindManmachine") @PostMapping("/bindManmachine")
public R<Void> bindManmachine(@RequestBody GpsEquipmentBo bo) { public R<Void> bindManmachine(@RequestBody GpsEquipmentBo bo) {
if (bo.getClientId() == null) {
throw new ServiceException("设备id不能为空");
}
return toAjax(gpsEquipmentService.bindManmachine(bo)); return toAjax(gpsEquipmentService.bindManmachine(bo));
} }
@ -170,6 +182,9 @@ public class GpsEquipmentController extends BaseController {
@RepeatSubmit() @RepeatSubmit()
@PostMapping("/unbindManmachine") @PostMapping("/unbindManmachine")
public R<Void> unbindManmachine(@RequestBody GpsEquipmentBo bo) { public R<Void> unbindManmachine(@RequestBody GpsEquipmentBo bo) {
if (bo.getClientId() == null) {
throw new ServiceException("设备id不能为空");
}
return toAjax(gpsEquipmentService.unbindManmachine(bo)); return toAjax(gpsEquipmentService.unbindManmachine(bo));
} }

View File

@ -45,6 +45,15 @@ public class GpsEquipmentSonController extends BaseController {
return gpsEquipmentSonService.queryPageList(bo, pageQuery); return gpsEquipmentSonService.queryPageList(bo, pageQuery);
} }
/**
* 查询GPS设备定位信息列表
*/
@SaCheckPermission("gps:equipmentSon:list")
@GetMapping("/getList")
public R<List<GpsEquipmentSonVo>> getList(GpsEquipmentSonBo bo) {
return R.ok(gpsEquipmentSonService.queryList(bo));
}
/** /**
* 导出GPS设备定位信息列表 * 导出GPS设备定位信息列表
*/ */

View File

@ -76,5 +76,6 @@ public class GpsEquipmentBo extends BaseEntity {
*/ */
private String remark; private String remark;
private Integer type;
} }

View File

@ -47,6 +47,8 @@ public class GpsEquipmentSonVo implements Serializable {
@ExcelProperty(value = "设备标识") @ExcelProperty(value = "设备标识")
private String clientId; private String clientId;
private Long projectId;
/** /**
* 设备名称 * 设备名称
*/ */

View File

@ -40,12 +40,16 @@ public class GpsEquipmentVo implements Serializable {
@ExcelProperty(value = "项目ID") @ExcelProperty(value = "项目ID")
private Long projectId; private Long projectId;
private String projectName;
/** /**
* 用户id * 用户id
*/ */
@ExcelProperty(value = "用户id") @ExcelProperty(value = "用户id")
private Long userId; private Long userId;
private String userName;
/** /**
* 设备标识 * 设备标识
*/ */
@ -96,4 +100,7 @@ public class GpsEquipmentVo implements Serializable {
private String remark; private String remark;
private Integer type;
} }

View File

@ -0,0 +1,30 @@
package org.dromara.gps.domain.vo;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* GPS人机关联视图对象 gps_manmachine
*
* @author Lion Li
* @date 2025-08-28
*/
@Data
public class GpsProjectVo implements Serializable {
/**
*
*/
// @ExcelProperty(value = "")
private Long projectId;
/**
* 用户名
*/
private String projectName;
}

View File

@ -1,6 +1,5 @@
package org.dromara.gps.service; package org.dromara.gps.service;
import org.dromara.common.core.domain.R;
import org.dromara.gps.domain.vo.GpsEquipmentVo; import org.dromara.gps.domain.vo.GpsEquipmentVo;
import org.dromara.gps.domain.bo.GpsEquipmentBo; import org.dromara.gps.domain.bo.GpsEquipmentBo;
import org.dromara.gps.domain.GpsEquipment; import org.dromara.gps.domain.GpsEquipment;
@ -8,6 +7,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import org.dromara.gps.domain.vo.GpsProjectVo;
import org.dromara.gps.domain.vo.GpsUserVo; import org.dromara.gps.domain.vo.GpsUserVo;
import java.util.Collection; import java.util.Collection;
@ -92,4 +92,6 @@ public interface IGpsEquipmentService extends IService<GpsEquipment>{
Boolean unbindManmachine(GpsEquipmentBo bo); Boolean unbindManmachine(GpsEquipmentBo bo);
List<GpsUserVo> getUserList(GpsEquipmentBo bo); List<GpsUserVo> getUserList(GpsEquipmentBo bo);
List<GpsProjectVo> getProjectList();
} }

View File

@ -6,7 +6,6 @@ import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
@ -17,15 +16,19 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.gps.domain.GpsEquipmentSon;
import org.dromara.gps.domain.GpsManmachine; import org.dromara.gps.domain.GpsManmachine;
import org.dromara.gps.domain.bo.GpsEquipmentSonBo; import org.dromara.gps.domain.bo.GpsEquipmentSonBo;
import org.dromara.gps.domain.vo.GpsProjectVo;
import org.dromara.gps.domain.vo.GpsUserVo; import org.dromara.gps.domain.vo.GpsUserVo;
import org.dromara.gps.mapper.GpsManmachineMapper; import org.dromara.gps.mapper.GpsManmachineMapper;
import org.dromara.gps.service.IGpsEquipmentSonService; import org.dromara.gps.service.IGpsEquipmentSonService;
import org.dromara.gps.service.IGpsManmachineService; import org.dromara.project.domain.vo.project.BusProjectVo;
import org.plutext.jaxb.svg11.G; import org.dromara.project.service.IBusProjectService;
import org.redisson.api.ObjectListener; import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.service.ISysUserService;
import org.redisson.api.DeletedObjectListener;
import org.redisson.api.ExpiredObjectListener;
import org.redisson.api.listener.SetObjectListener;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.dromara.gps.domain.bo.GpsEquipmentBo; import org.dromara.gps.domain.bo.GpsEquipmentBo;
@ -33,10 +36,12 @@ import org.dromara.gps.domain.vo.GpsEquipmentVo;
import org.dromara.gps.domain.GpsEquipment; import org.dromara.gps.domain.GpsEquipment;
import org.dromara.gps.mapper.GpsEquipmentMapper; import org.dromara.gps.mapper.GpsEquipmentMapper;
import org.dromara.gps.service.IGpsEquipmentService; import org.dromara.gps.service.IGpsEquipmentService;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.Duration; import java.time.Duration;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
/** /**
* GPS设备详细Service业务层处理 * GPS设备详细Service业务层处理
@ -55,6 +60,10 @@ public class GpsEquipmentServiceImpl extends ServiceImpl<GpsEquipmentMapper, Gps
private IGpsEquipmentSonService gpsEquipmentSonService; private IGpsEquipmentSonService gpsEquipmentSonService;
@Autowired @Autowired
private GpsManmachineMapper gpsManmachineMapper; private GpsManmachineMapper gpsManmachineMapper;
@Autowired
private IBusProjectService projectService;
@Autowired
private ISysUserService userService;
/** /**
* 查询GPS设备详细 * 查询GPS设备详细
@ -78,6 +87,40 @@ public class GpsEquipmentServiceImpl extends ServiceImpl<GpsEquipmentMapper, Gps
public TableDataInfo<GpsEquipmentVo> queryPageList(GpsEquipmentBo bo, PageQuery pageQuery) { public TableDataInfo<GpsEquipmentVo> queryPageList(GpsEquipmentBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<GpsEquipment> lqw = buildQueryWrapper(bo); LambdaQueryWrapper<GpsEquipment> lqw = buildQueryWrapper(bo);
Page<GpsEquipmentVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); Page<GpsEquipmentVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
if (bo.getType() == 1){
List<GpsEquipmentVo> list = result.getRecords().stream()
.filter(gpsEquipment -> gpsEquipment.getProjectId() != null)
.toList();
list.forEach(item -> {
if (item.getUserId() != null){
item.setType(1);
}else{
item.setType(2);
}
SysUserVo sysUserVo = userService.queryById(item.getUserId());
if (sysUserVo != null) {
item.setUserName(sysUserVo.getUserName());
}
BusProjectVo busProjectVo = projectService.selectById(item.getProjectId());
if (busProjectVo != null) {
item.setProjectName(busProjectVo.getProjectName());
}
});
result.setRecords(list);
}else if (bo.getType() == 2){
List<GpsEquipmentVo> list = result.getRecords().stream()
.filter(gpsEquipment -> gpsEquipment.getProjectId() == null).toList();
list.forEach(item ->{
if (item.getProjectId() != null) {
BusProjectVo busProjectVo = projectService.selectById(item.getProjectId());
if (busProjectVo != null) {
item.setProjectName(busProjectVo.getProjectName());
}
}
item.setType(2);
});
result.setRecords(list);
}
return TableDataInfo.build(result); return TableDataInfo.build(result);
} }
@ -197,37 +240,47 @@ public class GpsEquipmentServiceImpl extends ServiceImpl<GpsEquipmentMapper, Gps
} }
private static final int DEVICE_ALIVE_TIMEOUT = 180; // 5分钟 private static final int DEVICE_ALIVE_TIMEOUT = 120; // 5分钟
/** /**
* 更新设备存活状态到Redis并添加过期监听 * 更新设备存活状态到Redis并添加过期监听
* @param clientId 设备ID * @param clientId 设备ID
*/ */
private void updateDeviceAliveStatus(String clientId) { private void updateDeviceAliveStatus(String clientId) {
// String key = "gps_device_alive:" + clientId; String key = "gps_device_alive:" + clientId;
//
// // 先删除可能存在的旧监听器 // 先删除可能存在的旧监听器
// if (RedisUtils.isExistsObject(key)) { if (RedisUtils.isExistsObject(key)) {
// RedisUtils.deleteObject(key); RedisUtils.deleteObject(key);
// } }
//
// // 设置缓存对象和过期时间 // 注册监听器
// RedisUtils.setCacheObject(key, "ALIVE", Duration.ofSeconds(DEVICE_ALIVE_TIMEOUT)); RedisUtils.addObjectListener(key, new SetObjectListener() {
// @Override
// // 添加过期监听器 public void onSet(String key) {
// RedisUtils.addObjectListener(key, new ObjectListener() { // 业务逻辑,例如刷新缓存
// @Override // 设置缓存对象和过期时间
// public void onExpired(String name) { RedisUtils.setCacheObject(key, "ALIVE", Duration.ofSeconds(DEVICE_ALIVE_TIMEOUT));
// log.info("Device {} is offline due to key expiration", clientId); }
// handleDeviceOffline(clientId); });
// }
// RedisUtils.addObjectListener(key, new ExpiredObjectListener() {
// @Override @Override
// public void onDeleted(String name) { public void onExpired(String key) {
// // 可选:处理手动删除的情况 // 业务逻辑,例如记录日志
// } handleDeviceOffline(clientId);
// }); }
});
RedisUtils.addObjectListener(key, new DeletedObjectListener() {
@Override
public void onDeleted(String key) {
// 业务逻辑,例如通知其他系统
}
});
} }
/** /**
* 处理设备离线 * 处理设备离线
* @param clientId 设备ID * @param clientId 设备ID
@ -252,9 +305,17 @@ public class GpsEquipmentServiceImpl extends ServiceImpl<GpsEquipmentMapper, Gps
@Override @Override
@Transactional(rollbackFor = Exception.class)
public Boolean bindManmachine(GpsEquipmentBo bo) { public Boolean bindManmachine(GpsEquipmentBo bo) {
if (bo.getProjectId() == null) {
throw new ServiceException("请选择绑定项目");
}
if (bo.getUserId() == null) {
throw new ServiceException("请选择绑定用户");
}
baseMapper.update(new LambdaUpdateWrapper<GpsEquipment>() baseMapper.update(new LambdaUpdateWrapper<GpsEquipment>()
.set(GpsEquipment::getUserId,bo.getUserId()) .set(GpsEquipment::getUserId,bo.getUserId())
.set(GpsEquipment::getProjectId,bo.getProjectId())
.eq(GpsEquipment::getId,bo.getId())); .eq(GpsEquipment::getId,bo.getId()));
//只能绑定一个设备 //只能绑定一个设备
List<GpsManmachine> gpsManmachines = gpsManmachineMapper.selectList(Wrappers.<GpsManmachine>lambdaQuery() List<GpsManmachine> gpsManmachines = gpsManmachineMapper.selectList(Wrappers.<GpsManmachine>lambdaQuery()
@ -271,16 +332,15 @@ public class GpsEquipmentServiceImpl extends ServiceImpl<GpsEquipmentMapper, Gps
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public Boolean unbindManmachine(GpsEquipmentBo bo) { public Boolean unbindManmachine(GpsEquipmentBo bo) {
baseMapper.update(new LambdaUpdateWrapper<GpsEquipment>() baseMapper.update(new LambdaUpdateWrapper<GpsEquipment>()
.set(GpsEquipment::getUserId,null) .set(GpsEquipment::getUserId,null)
.eq(GpsEquipment::getId,bo.getId())); .eq(GpsEquipment::getId,bo.getId()));
GpsManmachine gpsManmachine = new GpsManmachine(); GpsManmachine gpsManmachine = new GpsManmachine();
gpsManmachine.setClientId(bo.getClientId()); gpsManmachine.setClientId(bo.getClientId());
gpsManmachine.setUserId(bo.getUserId());
return gpsManmachineMapper.delete(new LambdaQueryWrapper<GpsManmachine>() return gpsManmachineMapper.delete(new LambdaQueryWrapper<GpsManmachine>()
.eq(GpsManmachine::getClientId, gpsManmachine.getClientId()) .eq(GpsManmachine::getClientId, gpsManmachine.getClientId()))> 0;
.eq(GpsManmachine::getUserId,gpsManmachine.getUserId()))> 0;
} }
/** /**
@ -306,4 +366,20 @@ public class GpsEquipmentServiceImpl extends ServiceImpl<GpsEquipmentMapper, Gps
} }
return list; return list;
} }
@Override
public List<GpsProjectVo> getProjectList() {
List<BusProjectVo> projectVos = projectService.selectProjectVoList();
if (projectVos == null || projectVos.isEmpty()) {
return null;
}
List<GpsProjectVo> list = new ArrayList<>();
projectVos.forEach(item -> {
GpsProjectVo vo = new GpsProjectVo();
vo.setProjectId(item.getId());
vo.setProjectName(item.getProjectName());
list.add(vo);
});
return list;
}
} }

View File

@ -72,23 +72,10 @@ public class GpsEquipmentSonServiceImpl extends ServiceImpl<GpsEquipmentSonMappe
private LambdaQueryWrapper<GpsEquipmentSon> buildQueryWrapper(GpsEquipmentSonBo bo) { private LambdaQueryWrapper<GpsEquipmentSon> buildQueryWrapper(GpsEquipmentSonBo bo) {
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<GpsEquipmentSon> lqw = Wrappers.lambdaQuery(); LambdaQueryWrapper<GpsEquipmentSon> lqw = Wrappers.lambdaQuery();
lqw.orderByDesc(GpsEquipmentSon::getId); lqw.orderByDesc(GpsEquipmentSon::getCreateTime);
lqw.eq(bo.getProjectId() != null, GpsEquipmentSon::getProjectId, bo.getProjectId());
lqw.eq(bo.getUserId() != null, GpsEquipmentSon::getUserId, bo.getUserId()); lqw.eq(bo.getUserId() != null, GpsEquipmentSon::getUserId, bo.getUserId());
lqw.eq(StringUtils.isNotBlank(bo.getClientId()), GpsEquipmentSon::getClientId, bo.getClientId()); lqw.eq(StringUtils.isNotBlank(bo.getClientId()), GpsEquipmentSon::getClientId, bo.getClientId());
lqw.like(StringUtils.isNotBlank(bo.getDeviceName()), GpsEquipmentSon::getDeviceName, bo.getDeviceName());
lqw.eq(StringUtils.isNotBlank(bo.getDeviceId()), GpsEquipmentSon::getDeviceId, bo.getDeviceId());
lqw.eq(StringUtils.isNotBlank(bo.getMobileNo()), GpsEquipmentSon::getMobileNo, bo.getMobileNo());
lqw.eq(StringUtils.isNotBlank(bo.getPlateNo()), GpsEquipmentSon::getPlateNo, bo.getPlateNo());
lqw.eq(bo.getProtocolVersion() != null, GpsEquipmentSon::getProtocolVersion, bo.getProtocolVersion());
lqw.eq(bo.getLocWarnBit() != null, GpsEquipmentSon::getLocWarnBit, bo.getLocWarnBit());
lqw.eq(bo.getLocStatusBit() != null, GpsEquipmentSon::getLocStatusBit, bo.getLocStatusBit());
lqw.eq(bo.getLocLatitude() != null, GpsEquipmentSon::getLocLatitude, bo.getLocLatitude());
lqw.eq(bo.getLocLongitude() != null, GpsEquipmentSon::getLocLongitude, bo.getLocLongitude());
lqw.eq(bo.getLocAltitude() != null, GpsEquipmentSon::getLocAltitude, bo.getLocAltitude());
lqw.eq(bo.getLocSpeed() != null, GpsEquipmentSon::getLocSpeed, bo.getLocSpeed());
lqw.eq(bo.getLocSpeedKph() != null, GpsEquipmentSon::getLocSpeedKph, bo.getLocSpeedKph());
lqw.eq(bo.getLocDirection() != null, GpsEquipmentSon::getLocDirection, bo.getLocDirection());
lqw.eq(bo.getLocDeviceTime() != null, GpsEquipmentSon::getLocDeviceTime, bo.getLocDeviceTime());
return lqw; return lqw;
} }

View File

@ -20,4 +20,14 @@ public class UnitBo {
*/ */
private String unitProjectName; private String unitProjectName;
/**
* 单位工程工区
*/
private String unitProjectArea;
/**
* 单位工程状态
*/
private String unitProjectStatus;
} }

View File

@ -7,7 +7,7 @@ import lombok.Data;
import org.dromara.common.excel.annotation.ExcelDictFormat; import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert; import org.dromara.common.excel.convert.ExcelDictConvert;
import org.dromara.materials.domain.MatMaterials; import org.dromara.materials.domain.MatMaterials;
import org.dromara.materials.domain.vo.company.MatCompanyVo; import org.dromara.tender.domain.vo.TenderSupplierInputVo;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
@ -51,7 +51,7 @@ public class MatMaterialsVo implements Serializable {
* 公司信息 * 公司信息
*/ */
@ExcelProperty(value = "公司信息") @ExcelProperty(value = "公司信息")
private MatCompanyVo companyVo; private TenderSupplierInputVo companyVo;
/** /**
* 项目id * 项目id

View File

@ -39,6 +39,7 @@ import org.dromara.materials.service.IMatMaterialsInventoryService;
import org.dromara.materials.service.IMatMaterialsService; import org.dromara.materials.service.IMatMaterialsService;
import org.dromara.project.domain.BusProject; import org.dromara.project.domain.BusProject;
import org.dromara.project.service.IBusProjectService; import org.dromara.project.service.IBusProjectService;
import org.dromara.tender.service.ITenderSupplierInputService;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
@ -60,7 +61,7 @@ public class MatMaterialsServiceImpl extends ServiceImpl<MatMaterialsMapper, Mat
implements IMatMaterialsService { implements IMatMaterialsService {
@Resource @Resource
private IMatCompanyService companyService; private ITenderSupplierInputService tenderSupplierInputService;
@Resource @Resource
private IBusProjectService projectService; private IBusProjectService projectService;
@ -228,7 +229,7 @@ public class MatMaterialsServiceImpl extends ServiceImpl<MatMaterialsMapper, Mat
if (companyId == null) { if (companyId == null) {
throw new ServiceException("请填写公司ID", HttpStatus.BAD_REQUEST); throw new ServiceException("请填写公司ID", HttpStatus.BAD_REQUEST);
} }
if (companyService.getById(companyId) == null) { if (tenderSupplierInputService.getById(companyId) == null) {
throw new ServiceException("对应公司不存在", HttpStatus.BAD_REQUEST); throw new ServiceException("对应公司不存在", HttpStatus.BAD_REQUEST);
} }
if (projectId == null) { if (projectId == null) {
@ -286,7 +287,7 @@ public class MatMaterialsServiceImpl extends ServiceImpl<MatMaterialsMapper, Mat
// 关联查询项目信息 // 关联查询项目信息
Long companyId = materials.getCompanyId(); Long companyId = materials.getCompanyId();
if (companyId != null) { if (companyId != null) {
materialsVo.setCompanyVo(companyService.queryById(companyId)); materialsVo.setCompanyVo(tenderSupplierInputService.queryById(companyId));
} }
// 关联对象存储文件信息 // 关联对象存储文件信息
String fileOssId = materials.getFileOssId(); String fileOssId = materials.getFileOssId();

View File

@ -410,6 +410,7 @@ public class OutTableController extends BaseController {
.eq(OutMonthPlan::getPlanMonth, bo.getMonth()) .eq(OutMonthPlan::getPlanMonth, bo.getMonth())
.eq(OutMonthPlan::getValueType, bo.getValueType()) .eq(OutMonthPlan::getValueType, bo.getValueType())
.eq(OutMonthPlan::getPlanAuditStatus, BusinessStatusEnum.FINISH.getStatus()) .eq(OutMonthPlan::getPlanAuditStatus, BusinessStatusEnum.FINISH.getStatus())
.eq(OutMonthPlan::getType,bo.getType())
); );
// List<OutMonthPlan> matchedPlans = list.stream() // List<OutMonthPlan> matchedPlans = list.stream()
// .filter(plan -> plan.getPlanMonth() != null // .filter(plan -> plan.getPlanMonth() != null

View File

@ -204,4 +204,8 @@ public interface IBusProjectService extends IService<BusProject> {
* @return 是否成功 * @return 是否成功
*/ */
Boolean changeUserProject(Long id); Boolean changeUserProject(Long id);
BusProjectVo selectById(Long projectId);
List<BusProjectVo> selectProjectVoList();
} }

View File

@ -1082,6 +1082,16 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
return false; return false;
} }
@Override
public BusProjectVo selectById(Long projectId) {
return baseMapper.selectVoById(projectId);
}
@Override
public List<BusProjectVo> selectProjectVoList() {
return baseMapper.selectVoList();
}
/** /**
* 构造分项工程树 * 构造分项工程树
*/ */

View File

@ -73,4 +73,5 @@ public interface ISysDictDataService {
*/ */
boolean checkDictDataUnique(SysDictDataBo dict); boolean checkDictDataUnique(SysDictDataBo dict);
List<SysDictDataVo> selectByDictType(String desUserMajor);
} }

View File

@ -258,4 +258,6 @@ public interface ISysUserService {
* 获取指定部门的用户名称列表(用于 Excel 下拉框) * 获取指定部门的用户名称列表(用于 Excel 下拉框)
*/ */
List<String> getUserNamesByDept(Long deptId); List<String> getUserNamesByDept(Long deptId);
SysUserVo queryById(Long userId);
} }

View File

@ -154,4 +154,9 @@ public class SysDictDataServiceImpl implements ISysDictDataService {
return true; return true;
} }
@Override
public List<SysDictDataVo> selectByDictType(String desUserMajor) {
return baseMapper.selectVoList(new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getDictType, desUserMajor));
}
} }

View File

@ -773,6 +773,12 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@Override
public SysUserVo queryById(Long userId) {
return baseMapper.selectVoById(userId);
}
/** /**
* 通过用户ID查询用户账户 * 通过用户ID查询用户账户
* *

View File

@ -93,7 +93,7 @@ public class BusBillofquantitiesLimitList extends BaseEntity {
/** /**
* 税率 * 税率
*/ */
private int taxRate; private BigDecimal taxRate;
/** /**
* 总价 * 总价

View File

@ -93,7 +93,7 @@ public class BusBillofquantitiesLimitListBo extends BaseEntity {
/** /**
* 税率 * 税率
*/ */
private int taxRate; private BigDecimal taxRate;
/** /**
* 总价 * 总价

View File

@ -118,8 +118,8 @@ public class BusBillofquantitiesLimitListVo implements Serializable {
/** /**
* 税率 * 税率
*/ */
@ExcelProperty(value = "税率") @ExcelProperty(value = "税率(%)")
private int taxRate; private BigDecimal taxRate;
/** /**
* 总价 * 总价

View File

@ -259,6 +259,7 @@ public class BusBillofquantitiesLimitListServiceImpl extends ServiceImpl<BusBill
limitList.setProjectId(bo.getProjectId()); limitList.setProjectId(bo.getProjectId());
limitList.setType(bo.getType()); limitList.setType(bo.getType());
limitList.setUnitPrice(item.getUnitPrice()); limitList.setUnitPrice(item.getUnitPrice());
limitList.setTaxRate(item.getTaxRate());
busBillofquantities.add(limitList); busBillofquantities.add(limitList);
}); });