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

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);
}
/**
* 查询物资-采购联系单列表
*/
@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 })
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) {
Map<String, Object> params = bo.getParams();
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.getBrand()), BusTotalsupplyplan::getBrand, bo.getBrand());
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)
@PostMapping("/exportExcel")
public void exportExcelByProjectId(@RequestParam("projectId") Long projectId, HttpServletResponse response){
@ -181,11 +181,14 @@ public class DesVolumeCatalogController extends BaseController {
List<ExcelData> dataList = readExcel(file);
List<DesVolumeCatalogCreateReq> desVolumeCatalogCreateReqs = BeanUtil.copyToList(dataList, DesVolumeCatalogCreateReq.class);
Collections.reverse(desVolumeCatalogCreateReqs);
List<DesVolumeCatalogCreateReq> list = new ArrayList<>();
for (DesVolumeCatalogCreateReq desVolumeCatalogCreateReq : desVolumeCatalogCreateReqs) {
desVolumeCatalogCreateReq.setProjectId(projectId);
desVolumeCatalogCreateReq.setDesignState("2");
desVolumeCatalogService.insertByBo(desVolumeCatalogCreateReq);
list.add(desVolumeCatalogCreateReq);
// desVolumeCatalogService.insertByBo(desVolumeCatalogCreateReq);
}
desVolumeCatalogService.insertBatchByBo(list);
return toAjax(true);
}
@ -235,17 +238,18 @@ public class DesVolumeCatalogController extends BaseController {
// 从第二行(index=1)开始读取数据,跳过表头
for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
Row row = sheet.getRow(rowIndex);
if (row != null) {
if (hasValidData(row)) {
String designSubitem = getCellValue(row.getCell(0));
// String designState = getCellValue(row.getCell(1));
// String specialty = getCellValue(row.getCell(2));
// String principal = getCellValue(row.getCell(3));
String volumeNumber = getCellValue(row.getCell(1));
String documentName = getCellValue(row.getCell(2));
LocalDate plannedCompletion = getLocalDateValue(row.getCell(3));
String specialty = getCellValue(row.getCell(1));
String specialtyId = getCellValue(row.getCell(2));
String principal = getCellValue(row.getCell(3));
String principalId = getCellValue(row.getCell(4));
String volumeNumber = getCellValue(row.getCell(5));
String documentName = getCellValue(row.getCell(6));
LocalDate plannedCompletion = getLocalDateValue(row.getCell(7));
ExcelData excelData = new ExcelData(
designSubitem, volumeNumber, documentName,
designSubitem,specialtyId,principalId, volumeNumber, documentName,
plannedCompletion
);
dataList.add(excelData);
@ -255,6 +259,19 @@ public class DesVolumeCatalogController extends BaseController {
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) {
if (cell == null) {

View File

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

View File

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

View File

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

View File

@ -1,5 +1,6 @@
package org.dromara.design.service;
import jakarta.validation.constraints.NotNull;
import org.dromara.design.domain.dto.desUser.DesUserBatchDto;
import org.dromara.design.domain.vo.DesUserVo;
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 com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 设计人员Service接口
@ -84,4 +85,15 @@ public interface IDesUserService extends IService<DesUser>{
* 查询用户对应专业
*/
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);
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 lombok.RequiredArgsConstructor;
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.dromara.design.domain.bo.DesUserBo;
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.service.IDesUserService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.*;
import java.util.stream.Collectors;
/**
* 设计人员Service业务层处理
@ -33,6 +34,8 @@ public class DesUserServiceImpl extends ServiceImpl<DesUserMapper, DesUser> impl
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){
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 org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFSheet;
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.domain.R;
import org.dromara.common.core.domain.event.ProcessDeleteEvent;
import org.dromara.common.core.domain.event.ProcessEvent;
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.mybatis.core.page.PageQuery;
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.design.domain.*;
import org.dromara.design.domain.bo.DesUserBo;
import org.dromara.design.domain.dto.volumecatalog.DesVolumeCatalogCreateReq;
import org.dromara.design.domain.dto.volumecatalog.DesVolumeCatalogQueryReq;
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.mapper.DesVolumeCatalogMapper;
import org.dromara.design.service.*;
import org.dromara.project.service.IBusProjectService;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.service.ISysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
@ -148,6 +147,11 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
*/
@Override
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();
if (projectService.getById(projectId) == null) {
throw new ServiceException("对应项目不存在", HttpStatus.NOT_FOUND);
@ -163,15 +167,61 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
if (count > 0) {
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();
BeanUtils.copyProperties(req, volumeCatalog);
volumeCatalog.setSerialNumber(serialNumber);
boolean save = this.save(volumeCatalog);
if (!save) {
RedisUtils.setCacheObject("DesVolumeCatalog:serialNumber",serialNumber);
throw new ServiceException("卷册目录新增失败", HttpStatus.ERROR);
}
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 documentName = req.getDocumentName();
String auditStatus = req.getAuditStatus();
lqw.orderByDesc(DesVolumeCatalog::getCreateTime);
lqw.orderByAsc(DesVolumeCatalog::getVolumeNumber);
// lqw.orderByDesc(DesVolumeCatalog::getCreateTime);
lqw.orderByAsc(DesVolumeCatalog::getSerialNumber);
lqw.like(StringUtils.isNotBlank(documentName), DesVolumeCatalog::getDocumentName, documentName);
lqw.eq(StringUtils.isNotBlank(volumeNumber), DesVolumeCatalog::getVolumeNumber, volumeNumber);
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) {
DesUserBo desUserBo = new DesUserBo();
desUserBo.setProjectId(projectId);
Map<String, List<String>> majorToNames = new HashMap<>();
List<DesUserVo> desUserVos = desUserService.queryList(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);
});
Map<String, String> uniqueMajors = desUserService.getUserMajor(desUserBo);
Map<String, String> userList = desUserService.getUserList(desUserBo);
//TODO 数据绑定下拉
// String[] namesArray = names.toArray(String[]::new);
@ -398,48 +436,117 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
Workbook workbook = new XSSFWorkbook();
// 创建主 Sheet 和隐藏 Sheet
Sheet mainSheet = workbook.createSheet("收资清单模板");
Sheet dropdownSheet = workbook.createSheet("DropdownData");
workbook.setSheetHidden(workbook.getSheetIndex(dropdownSheet), true);
Sheet dataSheet = workbook.createSheet("DropdownData");
workbook.setSheetHidden(workbook.getSheetIndex(dataSheet), true);
// 3. 创建单元格样式
//设置下拉列表数据
// for (int i = 0; i < namesArray.length; i++) {
// dropdownSheet.createRow(i).createCell(1).setCellValue(namesArray[i]); // 存到B列
// }
// int rowIdx = 0;
// for (Map.Entry<Long, String> entry : userIdToNameMapByDept.entrySet()) {
// Row row = dropdownSheet.createRow(rowIdx++);
// row.createCell(0).setCellValue(entry.getKey().toString());
// row.createCell(1).setCellValue(entry.getValue());
// }
CellStyle editableStyle = createEditableCellStyle(workbook); // 可编辑单元格样式
CellStyle protectedStyle = createProtectedCellStyle(workbook); // 受保护单元格样式ID列用
//填充隐藏数据Sheet
int rowIndex = 0;
// 填充专业和专业IDA列和B列
for (Map.Entry<String, String> entry : uniqueMajors.entrySet()) {
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 设置表头
Row sheetRow = mainSheet.createRow(0);
sheetRow.createCell(0).setCellValue("子项名称");
sheetRow.createCell(1).setCellValue("卷册号");
sheetRow.createCell(2).setCellValue("资料名称");
sheetRow.createCell(3).setCellValue("计划出图时间");
sheetRow.createCell(4).setCellValue("专业");
sheetRow.createCell(5).setCellValue("人员");
String[] headers = {"子项名称", "专业", "专业编码",
"人员", "人员编码", "卷册号","资料名称","计划出图时间"};
for (int i = 0; i < headers.length; i++) {
Cell cell = sheetRow.createCell(i);
cell.setCellValue(headers[i]);
}
// 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列
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(1, 20 * 100);
mainSheet.setColumnWidth(1, 20 * 200);
mainSheet.setColumnWidth(2, 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 {
@ -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'

View File

@ -10,14 +10,18 @@ import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.contractor.domain.SubConstructionUser;
import org.dromara.contractor.domain.dto.constructionuser.SubConstructionUserQueryReq;
import org.dromara.contractor.domain.exportvo.BusConstructionUserExportVo;
import org.dromara.contractor.domain.vo.constructionuser.SubConstructionUserVo;
import org.dromara.contractor.service.ISubConstructionUserService;
import org.dromara.gps.domain.vo.ConstructionUser;
import org.dromara.gps.domain.vo.GpsProjectVo;
import org.dromara.gps.domain.vo.GpsUserVo;
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.validation.annotation.Validated;
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()
@PostMapping("/bindManmachine")
public R<Void> bindManmachine(@RequestBody GpsEquipmentBo bo) {
if (bo.getClientId() == null) {
throw new ServiceException("设备id不能为空");
}
return toAjax(gpsEquipmentService.bindManmachine(bo));
}
@ -170,6 +182,9 @@ public class GpsEquipmentController extends BaseController {
@RepeatSubmit()
@PostMapping("/unbindManmachine")
public R<Void> unbindManmachine(@RequestBody GpsEquipmentBo bo) {
if (bo.getClientId() == null) {
throw new ServiceException("设备id不能为空");
}
return toAjax(gpsEquipmentService.unbindManmachine(bo));
}

View File

@ -45,6 +45,15 @@ public class GpsEquipmentSonController extends BaseController {
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设备定位信息列表
*/

View File

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

View File

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

View File

@ -40,12 +40,16 @@ public class GpsEquipmentVo implements Serializable {
@ExcelProperty(value = "项目ID")
private Long projectId;
private String projectName;
/**
* 用户id
*/
@ExcelProperty(value = "用户id")
private Long userId;
private String userName;
/**
* 设备标识
*/
@ -96,4 +100,7 @@ public class GpsEquipmentVo implements Serializable {
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;
import org.dromara.common.core.domain.R;
import org.dromara.gps.domain.vo.GpsEquipmentVo;
import org.dromara.gps.domain.bo.GpsEquipmentBo;
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 com.baomidou.mybatisplus.extension.service.IService;
import org.dromara.gps.domain.vo.GpsProjectVo;
import org.dromara.gps.domain.vo.GpsUserVo;
import java.util.Collection;
@ -92,4 +92,6 @@ public interface IGpsEquipmentService extends IService<GpsEquipment>{
Boolean unbindManmachine(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.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
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 lombok.RequiredArgsConstructor;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.gps.domain.GpsEquipmentSon;
import org.dromara.gps.domain.GpsManmachine;
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.mapper.GpsManmachineMapper;
import org.dromara.gps.service.IGpsEquipmentSonService;
import org.dromara.gps.service.IGpsManmachineService;
import org.plutext.jaxb.svg11.G;
import org.redisson.api.ObjectListener;
import org.dromara.project.domain.vo.project.BusProjectVo;
import org.dromara.project.service.IBusProjectService;
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.stereotype.Service;
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.mapper.GpsEquipmentMapper;
import org.dromara.gps.service.IGpsEquipmentService;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;
/**
* GPS设备详细Service业务层处理
@ -55,6 +60,10 @@ public class GpsEquipmentServiceImpl extends ServiceImpl<GpsEquipmentMapper, Gps
private IGpsEquipmentSonService gpsEquipmentSonService;
@Autowired
private GpsManmachineMapper gpsManmachineMapper;
@Autowired
private IBusProjectService projectService;
@Autowired
private ISysUserService userService;
/**
* 查询GPS设备详细
@ -78,6 +87,40 @@ public class GpsEquipmentServiceImpl extends ServiceImpl<GpsEquipmentMapper, Gps
public TableDataInfo<GpsEquipmentVo> queryPageList(GpsEquipmentBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<GpsEquipment> lqw = buildQueryWrapper(bo);
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);
}
@ -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并添加过期监听
* @param clientId 设备ID
*/
private void updateDeviceAliveStatus(String clientId) {
// String key = "gps_device_alive:" + clientId;
//
// // 先删除可能存在的旧监听器
// if (RedisUtils.isExistsObject(key)) {
// RedisUtils.deleteObject(key);
// }
//
// // 设置缓存对象和过期时间
// RedisUtils.setCacheObject(key, "ALIVE", Duration.ofSeconds(DEVICE_ALIVE_TIMEOUT));
//
// // 添加过期监听器
// RedisUtils.addObjectListener(key, new ObjectListener() {
// @Override
// public void onExpired(String name) {
// log.info("Device {} is offline due to key expiration", clientId);
// handleDeviceOffline(clientId);
// }
//
// @Override
// public void onDeleted(String name) {
// // 可选:处理手动删除的情况
// }
// });
String key = "gps_device_alive:" + clientId;
// 先删除可能存在的旧监听器
if (RedisUtils.isExistsObject(key)) {
RedisUtils.deleteObject(key);
}
// 注册监听器
RedisUtils.addObjectListener(key, new SetObjectListener() {
@Override
public void onSet(String key) {
// 业务逻辑,例如刷新缓存
// 设置缓存对象和过期时间
RedisUtils.setCacheObject(key, "ALIVE", Duration.ofSeconds(DEVICE_ALIVE_TIMEOUT));
}
});
RedisUtils.addObjectListener(key, new ExpiredObjectListener() {
@Override
public void onExpired(String key) {
// 业务逻辑,例如记录日志
handleDeviceOffline(clientId);
}
});
RedisUtils.addObjectListener(key, new DeletedObjectListener() {
@Override
public void onDeleted(String key) {
// 业务逻辑,例如通知其他系统
}
});
}
/**
* 处理设备离线
* @param clientId 设备ID
@ -252,9 +305,17 @@ public class GpsEquipmentServiceImpl extends ServiceImpl<GpsEquipmentMapper, Gps
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean bindManmachine(GpsEquipmentBo bo) {
if (bo.getProjectId() == null) {
throw new ServiceException("请选择绑定项目");
}
if (bo.getUserId() == null) {
throw new ServiceException("请选择绑定用户");
}
baseMapper.update(new LambdaUpdateWrapper<GpsEquipment>()
.set(GpsEquipment::getUserId,bo.getUserId())
.set(GpsEquipment::getProjectId,bo.getProjectId())
.eq(GpsEquipment::getId,bo.getId()));
//只能绑定一个设备
List<GpsManmachine> gpsManmachines = gpsManmachineMapper.selectList(Wrappers.<GpsManmachine>lambdaQuery()
@ -271,16 +332,15 @@ public class GpsEquipmentServiceImpl extends ServiceImpl<GpsEquipmentMapper, Gps
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean unbindManmachine(GpsEquipmentBo bo) {
baseMapper.update(new LambdaUpdateWrapper<GpsEquipment>()
.set(GpsEquipment::getUserId,null)
.eq(GpsEquipment::getId,bo.getId()));
GpsManmachine gpsManmachine = new GpsManmachine();
gpsManmachine.setClientId(bo.getClientId());
gpsManmachine.setUserId(bo.getUserId());
return gpsManmachineMapper.delete(new LambdaQueryWrapper<GpsManmachine>()
.eq(GpsManmachine::getClientId, gpsManmachine.getClientId())
.eq(GpsManmachine::getUserId,gpsManmachine.getUserId()))> 0;
.eq(GpsManmachine::getClientId, gpsManmachine.getClientId()))> 0;
}
/**
@ -306,4 +366,20 @@ public class GpsEquipmentServiceImpl extends ServiceImpl<GpsEquipmentMapper, Gps
}
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) {
Map<String, Object> params = bo.getParams();
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(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;
}

View File

@ -20,4 +20,14 @@ public class UnitBo {
*/
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.convert.ExcelDictConvert;
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.Serializable;
@ -51,7 +51,7 @@ public class MatMaterialsVo implements Serializable {
* 公司信息
*/
@ExcelProperty(value = "公司信息")
private MatCompanyVo companyVo;
private TenderSupplierInputVo companyVo;
/**
* 项目id

View File

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

View File

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

View File

@ -204,4 +204,8 @@ public interface IBusProjectService extends IService<BusProject> {
* @return 是否成功
*/
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;
}
@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);
List<SysDictDataVo> selectByDictType(String desUserMajor);
}

View File

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

View File

@ -154,4 +154,9 @@ public class SysDictDataServiceImpl implements ISysDictDataService {
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());
}
@Override
public SysUserVo queryById(Long userId) {
return baseMapper.selectVoById(userId);
}
/**
* 通过用户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 = "税率")
private int taxRate;
@ExcelProperty(value = "税率(%)")
private BigDecimal taxRate;
/**
* 总价

View File

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