Merge remote-tracking branch 'origin/main'

This commit is contained in:
liuzhaotian
2024-07-18 18:39:30 +08:00
38 changed files with 904 additions and 319 deletions
@@ -67,6 +67,7 @@ public interface ErrorCodeConstants {
ErrorCode FILE_UPLOAD_ERR = new ErrorCode(1_002_029_012, "文件内容为空");
ErrorCode ORDER_STATUS_CONFLICT = new ErrorCode(1_002_029_006, "生产单状态冲突,禁止投入生产");
ErrorCode ORDER_READ_ERR = new ErrorCode(1_002_029_006, "订单列表获取失败,请刷新重试");
ErrorCode ORDER_DATE_ERR = new ErrorCode(1_002_029_006, "获取订单列表,时间超出范围,请在30天范围内选择");
ErrorCode SOURCE_NOT_EXITS_ERROR = new ErrorCode(1_002_029_013, "源数据查询失败");
ErrorCode ORDER_CAN_NOT_DELETE = new ErrorCode(1_002_029_013, "存在状态不符合强制删除的生产单,禁止删除");
@@ -153,6 +153,7 @@ public class OrderController {
List<OrderBodyRespVO> orderBodyMap = orderService.getOrderBody(orderId);
return success(orderBodyMap);
}
@GetMapping("/get-roomToString")
@Operation(summary = "生产单详情-房间和柜体id(toString)")
@Parameter(name = "orderId", description = "生产单编号", required = true, example = "1024")
@@ -181,24 +182,6 @@ public class OrderController {
return success(moduleDOList);
}
@GetMapping("/get-platesDetails")
@Operation(summary = "生产单详情-板材详细信息")
@Parameters({
@Parameter(name = "orderId", description = "生产单编号", example = "1024"),
@Parameter(name = "roomId", description = "房间编号", example = "1024"),
@Parameter(name = "bodyId", description = "柜体编号", example = "1024"),
@Parameter(name = "groupId", description = "加工组编号", example = "1024"),
@Parameter(name = "groupName", description = "加工组名称", example = "弧形")
})
@PreAuthorize("@ss.hasPermission('production:manager-list:detail')")
public CommonResult<List<OrderPlatesDetailReqVO>> platesDetails(@RequestParam("orderId") Long orderId,
@RequestParam(value = "roomId", required = false) Long roomId,
@RequestParam(value = "bodyId", required = false) Long bodyId,
@RequestParam(value = "groupId", required = false) Long groupId,
@RequestParam(value = "groupName", required = false) String groupName) {
List<OrderPlatesDetailReqVO> moduleDOList = orderService.getPlatesDetail(orderId, roomId, bodyId, groupId, groupName);
return success(moduleDOList);
}
@GetMapping("/get-platesDetailsPage")
@Operation(summary = "生产单详情-板材详细信息(分页)")
@Parameters({
@@ -209,35 +192,19 @@ public class OrderController {
@Parameter(name = "groupName", description = "加工组名称", example = "弧形"),
@Parameter(name = "pageNo", description = "第几页", example = "1"),
@Parameter(name = "pageSize", description = "条数", example = "10")
})
@PreAuthorize("@ss.hasPermission('production:manager-list:detail')")
public CommonResult<PageResult<OrderPlatesDetailReqVO>> platesDetails(@RequestParam("orderId") Long orderId,
@RequestParam(value = "roomId", required = false) Long roomId,
@RequestParam(value = "bodyId", required = false) Long bodyId,
@RequestParam(value = "groupId", required = false) Long groupId,
@RequestParam(value = "groupName", required = false) String groupName,
@RequestParam(value = "pageNo") Integer pageNo,
@RequestParam(value = "pageSize") Integer pageSize) {
@RequestParam(value = "roomId", required = false) Long roomId,
@RequestParam(value = "bodyId", required = false) Long bodyId,
@RequestParam(value = "groupId", required = false) Long groupId,
@RequestParam(value = "groupName", required = false) String groupName,
@RequestParam(value = "pageNo") Integer pageNo,
@RequestParam(value = "pageSize") Integer pageSize) {
PageResult<OrderPlatesDetailReqVO> moduleDOList = orderService.getPlatesDetail(orderId, roomId, bodyId, groupId, groupName, pageNo, pageSize);
return success(moduleDOList);
}
@GetMapping("/get-partsDetails")
@Operation(summary = "生产单详情-配件详细信息")
@Parameters({
@Parameter(name = "orderId", description = "生产单编号", example = "1024"),
@Parameter(name = "roomId", description = "房间编号", example = "1024"),
@Parameter(name = "bodyId", description = "柜体编号", example = "1024"),
@Parameter(name = "name", description = "配件名称", example = "1024")
})
@PreAuthorize("@ss.hasPermission('production:manager-list:detail')")
public CommonResult<List<OrderPartsRespVO>> partsDetails(@RequestParam("orderId") Long orderId,
@RequestParam(value = "roomId", required = false) Long roomId,
@RequestParam(value = "bodyId", required = false) Long bodyId,
@RequestParam(value = "name", required = false) String name) {
List<OrderPartsRespVO> moduleDOList = orderService.getPartsDetail(orderId, roomId, bodyId, name);
return success(moduleDOList);
}
@GetMapping("/get-partsDetailsPage")
@Operation(summary = "生产单详情-配件详细信息(分页)")
@Parameters({
@@ -250,14 +217,15 @@ public class OrderController {
})
@PreAuthorize("@ss.hasPermission('production:manager-list:detail')")
public CommonResult<PageResult<OrderPartsRespVO>> partsDetails(@RequestParam("orderId") Long orderId,
@RequestParam(value = "roomId", required = false) Long roomId,
@RequestParam(value = "bodyId", required = false) Long bodyId,
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "pageNo") Integer pageNo,
@RequestParam(value = "pageSize") Integer pageSize) {
@RequestParam(value = "roomId", required = false) Long roomId,
@RequestParam(value = "bodyId", required = false) Long bodyId,
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "pageNo") Integer pageNo,
@RequestParam(value = "pageSize") Integer pageSize) {
PageResult<OrderPartsRespVO> moduleDOList = orderService.getPartsDetail(orderId, roomId, bodyId, name, pageNo, pageSize);
return success(moduleDOList);
}
// 柜体数据获取,需要加上柜体的属性
@GetMapping("/get-body")
@Operation(summary = "生产单柜体数据获取")
@@ -300,59 +268,121 @@ public class OrderController {
return success(orderService.importApiData(listMap));
}
// @PostMapping("/importFile")
// @Operation(summary = "生产单文件导入新增")
// @Parameters({
// @Parameter(name = "file", description = "文件", required = true),
// @Parameter(name = "type", description = "文件类型", required = true)
// })
// @PreAuthorize("@ss.hasPermission('production:manager-list:create')")
// @OperateLog(type = IMPORT)
// public void exportTest(@RequestPart("file") MultipartFile file,
// @RequestParam(value = "type", required = false, defaultValue = "true") Integer type,
// HttpServletResponse response) throws IOException {
// try {
//
// List<?> list = null;
// OrderDO orderDO = new OrderDO();
// if (type == 0) { //excel
// // 读取文件
// excelReadUtil.setErr(0);
// Map<String, Object> map = excelReadUtil.read(file);
// System.err.println(excelReadUtil.isErr());
// // 判断是否读取有误
// if (excelReadUtil.isErr() == -1) { // 文件为空
// ExcelWriterUtil.writeErr(response, "生产单内容为空", orderService.getSavePath() + File.separator + "order_err.xlsx");
// return;
// } else if (excelReadUtil.isErr() > 0) {
// // 返回文件
// ExcelWriterUtil.write(response, (Map<Object, Object>) map.get("order"), (List<OrderPlateImportExcelVO>) map.get("plate"), orderService.getSavePath() + File.separator + "order_add_excel_err.xlsx");
// return;
// } else {
// // 获取数据
// list = (List<?>) map.get("plate");
// Map<String, Object> mapOrder = excelReadUtil.changeOrderDO((Map<Object, Object>) map.get("order"));
// if (list.size() == 0) {
// orderDO.setStatus(0);
// }
// orderDO = ((OrderDO) mapOrder.get("order")).setOrderType(OrderTypeEnum.MAIN_ORDER.getStatus()).setStatus(1);
// String err = ((String) mapOrder.get("error"));
//
// if (!orderService.customOrderNoIsExists(orderDO.getCustomOrderNo())) {
// err += orderDO.getCustomOrderNo() + "-自定义生产单号已存在;";
// }
// if (!err.equals("")) {
// ExcelWriterUtil.writeErr(response, err, orderService.getSavePath() + File.separator + "order_err.xlsx");
// }
//
// }
// } else if (type == 1) { // json
//
// } else if (type == 2) { // xml
//
// }
// orderService.importExcelData(orderDO, list, 0);
// } catch (Exception e) {
// ExcelWriterUtil.writeErr(response, "系统出现未知错误,请下载模板,按照模板重新上传文件", orderService.getSavePath() + File.separator + "order_err.xlsx");
// }
// }
@PostMapping("/importFile")
@Operation(summary = "生产单文件导入新增")
@Operation(summary = "生产单文件导入新增/导入板材")
@Parameters({
@Parameter(name = "file", description = "文件", required = true),
@Parameter(name = "type", description = "文件类型", required = true)
@Parameter(name = "type", description = "文件类型", required = true),
@Parameter(name = "index", description = "导入范围 0:全部,1:板材,默认为全部", required = false),
@Parameter(name = "id", description = "生产单id", required = false)
})
@PreAuthorize("@ss.hasPermission('production:manager-list:create')")
@OperateLog(type = IMPORT)
public void exportTest(@RequestPart("file") MultipartFile file,
@RequestParam(value = "type", required = false, defaultValue = "true") Integer type,
HttpServletResponse response) throws IOException {
@PreAuthorize("@ss.hasPermission('production:manager-list:create')")
public void exportTestTwo(@RequestPart("file") MultipartFile file,
@RequestParam(value = "type") Integer type,
@RequestParam(value = "index", required = false, defaultValue = "0") Integer index,
@RequestParam(value = "id", required = false, defaultValue = "0") Long orderId,
HttpServletResponse response) throws IOException {
try {
List<?> list = null;
OrderDO orderDO = new OrderDO();
if (type == 0) { //excel
// 读取文件
// 读取文件
excelReadUtil.setErr(0);
Map<String, Object> map = excelReadUtil.read(file);
// System.out.println(" map " + map);
System.err.println(excelReadUtil.isErr());
// 判断是否读取有误
if (excelReadUtil.isErr() == -1) { // 文件为空
ExcelWriterUtil.writeErr(response, "生产单内容为空", orderService.getSavePath() + File.separator + "order_err.xlsx");
System.out.println(" map + " + map);
// 判断是否读取有误
if (excelReadUtil.isErr() > 0) {
// 板材数据格式错误
ExcelWriterUtil.write(response, (Map<Object, Object>) map.get("order"), (List<OrderPlateImportExcelVO>) map.get("plate"),
orderService.getSavePath() + File.separator + "order_add_excel_err.xlsx");
return;
} else if (excelReadUtil.isErr() > 0) {
// 返回文件
ExcelWriterUtil.write(response, (Map<Object, Object>) map.get("order"), (List<OrderPlateImportExcelVO>) map.get("plate"), orderService.getSavePath() + File.separator + "order_add_excel_err.xlsx");
return;
} else {
// 获取数据
}else {
list = (List<?>) map.get("plate");
Map<String, Object> mapOrder = excelReadUtil.changeOrderDO((Map<Object, Object>) map.get("order"));
if (list.size() == 0) {
orderDO.setStatus(0);
}
orderDO = ((OrderDO) mapOrder.get("order")).setOrderType(OrderTypeEnum.MAIN_ORDER.getStatus()).setStatus(1);
String err = ((String) mapOrder.get("error"));
if (!orderService.customOrderNoIsExists(orderDO.getCustomOrderNo())) {
err += orderDO.getCustomOrderNo() + "-自定义生产单号已存在;";
}
if (!err.equals("")) {
ExcelWriterUtil.writeErr(response, err, orderService.getSavePath() + File.separator + "order_err.xlsx");
}
if (index == null || index == 0) { // 全部导入
Map<String, Object> mapOrder = excelReadUtil.changeOrderDO((Map<Object, Object>) map.get("order"));
if (list.size() == 0) {
orderDO.setStatus(0);
}
orderDO = ((OrderDO) mapOrder.get("order")).setOrderType(OrderTypeEnum.MAIN_ORDER.getStatus());
String err = ((String) mapOrder.get("error"));
if (!orderService.customOrderNoIsExists(orderDO.getCustomOrderNo())) {
err += orderDO.getCustomOrderNo() + "-自定义生产单号已存在;";
}
if (!err.equals("")) {
ExcelWriterUtil.writeErr(response, err, orderService.getSavePath() + File.separator + "order_err.xlsx");
}
}else { // 板材导入
orderDO.setId(orderId);
}
}
} else if (type == 1) { // json
} else if (type == 2) { // xml
}
orderService.importExcelData(orderDO, list);
orderService.importExcelData(orderDO, list, index);
} catch (Exception e) {
ExcelWriterUtil.writeErr(response, "系统出现未知错误,请下载模板,按照模板重新上传文件", orderService.getSavePath() + File.separator + "order_err.xlsx");
}
@@ -392,7 +422,7 @@ public class OrderController {
return success(orderService.getPrintDataMap(orderId, type, response));
}
// 获取api订单接口
// 获取api订单接口
@GetMapping("/getApiOrder")
@Operation(summary = "获取api订单接口")
@Parameters({
@@ -411,38 +441,21 @@ public class OrderController {
JSONObject oauth = apiDataAchieve.getApiToken(organId).get();
String token = oauth.getJSONObject("info").getString("access_token");
String shopId = oauth.getJSONObject("info").getString("shop_id");
JSONObject orderList = apiDataAchieve.getApiOrderList(token,shopId,startTime,endTime,orderNo,customOrderNo).get();
JSONObject orderList = apiDataAchieve.getApiOrderList(token, shopId, startTime, endTime, orderNo, customOrderNo).get();
return success(orderService.getApiOrderList(orderList));
}
// 统计
// 生产单状态分组统计返回
@GetMapping("/getOrderStatusCount")
@Operation(summary = "生产单状态分组统计返回")
@Parameter(name = "startTerm", description = "按周,按月,按年", required = false, example = "1,2,3")
@PreAuthorize("@ss.hasPermission('productManager:List')")
public CommonResult<List<OrderStatusRespVO>> getOrderStatusCount(@RequestParam(value = "startTerm", required = false) Integer startTerm) {
return success(orderService.getOrderStatusCount(startTerm));
}
// 小板数据分析
@GetMapping("/getOrderPlateAnalysisCount")
@Operation(summary = "小板数据分析统计(小板数量、小班面积)")
@PreAuthorize("@ss.hasPermission('productManager:List')")
public CommonResult<List<OrderGoodsPlateRespVO>> getOrderPlateAnalysisCount() {
return success(orderService.getOrderPlateAnalysisCount());
}
// 统计
// 生产单超期/到期告警 (工作台)
@GetMapping("/getOrderWarn")
@Operation(summary = "生产单警告")
@Operation(summary = "生产单超期/到期告警 (工作台)")
@PreAuthorize("@ss.hasPermission('productManager:List')")
public CommonResult<Map<String,List<OrderOverdueRespVO>>> getOrderOverdue() {
public CommonResult<Map<String, List<OrderOverdueRespVO>>> getOrderOverdue() {
return success(orderService.getOrderWarn());
}
// 生产单总数
// 生产单总数
@GetMapping("/orderCount")
@Operation(summary = "生产单总数")
@PreAuthorize("@ss.hasPermission('productManager:List')")
@@ -450,7 +463,7 @@ public class OrderController {
return success(orderService.orderCount());
}
// 今日新增生产单总数
// 今日新增生产单总数
@GetMapping("/orderCountToday")
@Operation(summary = "今日新增生产单总数")
@PreAuthorize("@ss.hasPermission('productManager:List')")
@@ -458,7 +471,7 @@ public class OrderController {
return success(orderService.orderCountToday());
}
// 今日生产单完成总数
// 今日生产单完成总数
@GetMapping("/orderCountTodayFinish")
@Operation(summary = "今日生产单完成总数")
@PreAuthorize("@ss.hasPermission('productManager:List')")
@@ -466,7 +479,7 @@ public class OrderController {
return success(orderService.orderCountTodayFinish());
}
// 生产中生产单总数
// 生产中生产单总数
@GetMapping("/orderCountProduce")
@Operation(summary = "生产中生产单总数")
@PreAuthorize("@ss.hasPermission('productManager:List')")
@@ -474,7 +487,7 @@ public class OrderController {
return success(orderService.orderCountProduce());
}
// 生产中生产平方数
// 生产中生产平方数
@GetMapping("/orderSquareProduce")
@Operation(summary = "生产中生产平方数")
@PreAuthorize("@ss.hasPermission('productManager:List')")
@@ -482,20 +495,50 @@ public class OrderController {
return success(orderService.orderSquareProduce());
}
// 小板数量
// 生产单状态分组统计返回
@GetMapping("/getOrderStatusCount")
@Operation(summary = "生产单状态分组统计返回")
@Parameters({
@Parameter(name = "startTime", description = "开始时间", example = "2024-07-15"),
@Parameter(name = "endTime", description = "结束时间", example = "2024-07-16")
})
@PreAuthorize("@ss.hasPermission('productManager:List')")
public CommonResult<List<OrderStatusRespVO>> getOrderStatusCount(@RequestParam(value = "startTime") String startTime,
@RequestParam(value = "endTime") String endTime) {
return success(orderService.getOrderStatusCount(startTime + " 00:00:00", endTime + " 23:59:59"));
}
// 小板数量 <集合>
@GetMapping("/getPlateCount")
@Operation(summary = "小板数量")
@Parameters({
@Parameter(name = "startTime", description = "开始时间", required = false),
@Parameter(name = "endTime", description = "结束时间", required = false),
@Parameter(name = "goodsId", description = "材料id", required = true),
@Parameter(name = "organId", description = "组织id", required = false, example = "1")
@Parameter(name = "startTime", description = "开始时间", example = "2024-07-15"),
@Parameter(name = "endTime", description = "结束时间", example = "2024-07-16"),
@Parameter(name = "pageNo", description = "第几页", example = "1"),
@Parameter(name = "pageSize", description = "每页条数", example = "10")
})
@PreAuthorize("@ss.hasPermission('productManager:List')")
public CommonResult<Integer> getPlateCount(@RequestParam(value = "startTime", required = false) String startTime,
@RequestParam(value = "endTime", required = false) String endTime,
@RequestParam(value = "goodsId", required = false) Set<String> goodsId,
@RequestParam("orderId") Long organId) {
return success(orderService.plateCount());
public CommonResult<PageResult<OrderGoodsPlateRespVO>> getPlateCount(@RequestParam(value = "startTime") String startTime,
@RequestParam(value = "endTime") String endTime,
@RequestParam(value = "pageNo") Integer pageNo,
@RequestParam(value = "pageSize") Integer pageSize) {
return success(orderService.plateCount(startTime + " 00:00:00", endTime + " 23:59:59", pageNo, pageSize));
}
// 小板面积 <集合>
@GetMapping("/getPlateArea")
@Operation(summary = "小板面积")
@Parameters({
@Parameter(name = "startTime", description = "开始时间", example = "2024-07-15"),
@Parameter(name = "endTime", description = "结束时间", example = "2024-07-16"),
@Parameter(name = "pageNo", description = "第几页", example = "1"),
@Parameter(name = "pageSize", description = "每页条数", example = "10")
})
@PreAuthorize("@ss.hasPermission('productManager:List')")
public CommonResult<PageResult<OrderGoodsPlateRespVO>> getPlateArea(@RequestParam(value = "startTime") String startTime,
@RequestParam(value = "endTime") String endTime,
@RequestParam(value = "pageNo") Integer pageNo,
@RequestParam(value = "pageSize") Integer pageSize) {
return success(orderService.plateArea(startTime + " 00:00:00", endTime + " 23:59:59", pageNo, pageSize));
}
}
@@ -24,7 +24,7 @@ public class OrderRespVO {
private String apiOrderId;
@Schema(description = "生产单日期", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("交付日期")
@ExcelProperty("生产单日期")
private LocalDateTime orderDate;
@Schema(description = "交付日期", requiredMode = Schema.RequiredMode.REQUIRED)
@@ -3,6 +3,8 @@ package com.cf.imes.module.executor.controller.admin.order.vo.order;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 生产单状态统计")
@Data
@Builder
@@ -15,4 +17,7 @@ public class OrderStatusRespVO {
@Schema(description = "订单数量")
private Integer orderCount;
@Schema(description = "生产单时间")
private LocalDateTime orderDate;
}
@@ -140,7 +140,7 @@ public interface OrderMapper extends BaseMapperX<OrderDO> {
List<Long> selectOrderIds(@Param(Constants.WRAPPER) Wrapper<OrderDO> wrapper);
// 生产单状态统计
List<OrderStatusRespVO> selectOrderStatusCount(@Param("organId")Long organId, @Param("orderDate") LocalDateTime orderDate);
List<OrderStatusRespVO> selectOrderStatusCount(@Param("organId")Long organId, @Param("startTime")String startTime, @Param("endTime")String endTime);
// 生产单预警统计
List<OrderOverdueRespVO> selectOrderNear(@Param("today") LocalDateTime today, @Param("orderDate") LocalDateTime orderDate, @Param("organId") Long organId);
@@ -7,6 +7,7 @@ import com.cf.imes.module.executor.dal.dataobject.plate.PlateGoodDO;
import org.apache.ibatis.annotations.Mapper;
import java.math.BigDecimal;
import java.util.List;
/**
* 板材信息 Mapper plate
@@ -25,9 +26,9 @@ public interface PlateGoodMapper extends BaseMapperX<PlateGoodDO> {
}
// 其他信息匹配
default PlateGoodDO selectGood(String goodsName, String material, String color, Boolean texture, BigDecimal width,
BigDecimal thickness, BigDecimal height, String brand, String spec, Long organId) {
return selectOne(new LambdaQueryWrapper<PlateGoodDO>()
default List<PlateGoodDO> selectGood(String goodsName, String material, String color, Boolean texture, BigDecimal width,
BigDecimal thickness, BigDecimal height, String brand, String spec, Long organId) {
LambdaQueryWrapper<PlateGoodDO> queryWrapper = new LambdaQueryWrapper<PlateGoodDO>()
.eq(PlateGoodDO::getGoodsName, goodsName)
.eq(PlateGoodDO::getMaterial, material)
.eq(PlateGoodDO::getColor, color)
@@ -35,9 +36,15 @@ public interface PlateGoodMapper extends BaseMapperX<PlateGoodDO> {
.eq(PlateGoodDO::getWidth, width)
.eq(PlateGoodDO::getHeight, height)
.eq(PlateGoodDO::getThickness, thickness)
.eq(PlateGoodDO::getBrand, brand)
.eq(PlateGoodDO::getSpec, spec)
.eq(PlateGoodDO::getDeleted, 0)
.eq(PlateGoodDO::getOrganId, organId));
}
.eq(PlateGoodDO::getOrganId, organId);
if (brand == null) {
queryWrapper.eq(PlateGoodDO::getBrand,"");
}else {
queryWrapper.eq(PlateGoodDO::getBrand, brand);
}
return selectList(queryWrapper);
}
}
@@ -137,5 +137,9 @@ public interface PlateMapper extends BaseMapperX<PlateDO> {
List<GoodsNum> selectGoodsNum(@Param("orderIds") List<Long> orderIds,@Param("organId") Long organId);
// 小板数据分析
List<OrderGoodsPlateRespVO> selectPlateAnalysisList(@Param("organId") Long organId, @Param("orderDate") LocalDateTime orderDate);
// List<OrderGoodsPlateRespVO> selectPlateAnalysisListByCount(@Param("organId") Long organId, @Param("startTime") String startTime, @Param("endTime") String endTime); // 数量
IPage<OrderGoodsPlateRespVO> selectPlateAnalysisListByCount(@Param("page") IPage<OrderGoodsPlateRespVO> page, @Param("organId") Long organId, @Param("startTime") String startTime, @Param("endTime") String endTime); // 数量
// List<OrderGoodsPlateRespVO> selectPlateAnalysisListByArea(@Param("organId") Long organId, @Param("startTime") String startTime, @Param("endTime") String endTime); // 面积
IPage<OrderGoodsPlateRespVO> selectPlateAnalysisListByArea(@Param("page") IPage<OrderGoodsPlateRespVO> page, @Param("organId") Long organId, @Param("startTime") String startTime, @Param("endTime") String endTime); // 面积
}
@@ -96,13 +96,12 @@ public class OrderInputProcessor {
* @param itemDOS
*/
@Transactional(rollbackFor = Exception.class)
public Long batchInsert(Collection<RawGoodsDO> rawGoodsDOS, Collection<OrderBodyDO> orderBodyDOS,
public void batchInsert(Collection<RawGoodsDO> rawGoodsDOS, Collection<OrderBodyDO> orderBodyDOS,
Collection<OrderGroupDO> orderGroupDOS, Collection<OrderPartsDO> orderPartsDOS,
Collection<PlateDO> plateDOS, Collection<OrderModuleExtraDO> orderModuleExtraDOS,
Collection<OrderItemDO> itemDOS, OrderDO orderDO,
Collection<OrderItemDO> itemDOS,
Collection<GoodsDO> goodsDOS, Collection<PlateGoodDO> plateGoodDOS) {
if (orderDO != null)
orderMapper.insert(orderDO);
if (rawGoodsDOS != null)
for (int i = 0; i < rawGoodsDOS.size(); i += 1000) {
@@ -151,7 +150,6 @@ public class OrderInputProcessor {
//plateMapper.insertBatch(plateDOS);
//orderModuleExtraMapper.insertBatch(orderModuleExtraDOS);
//orderItemMapper.insertBatch(itemDOS);
return orderDO.getId();
}
/**
@@ -77,6 +77,7 @@ public interface OrderService {
* @return List<OrderBodyRespVO>
*/
List<OrderBodyRespVO> getOrderBody(Long orderId);
String getOrderBodyToString(Long orderId);
List<OrderRoomBodyRespVO> getRoomAndBody(Long planId);
@@ -95,7 +96,6 @@ public interface OrderService {
* @return List<OrderPlatesDetailReqVO>
* 需要修改返回值
*/
List<OrderPlatesDetailReqVO> getPlatesDetail(Long orderId, Long roomId , Long bodyId , Long groupId, String groupName);
PageResult<OrderPlatesDetailReqVO> getPlatesDetail(Long orderId, Long roomId, Long bodyId, Long groupId, String groupName, Integer pageNo, Integer pageSize);
/**
@@ -105,7 +105,6 @@ public interface OrderService {
* @return List<OrderPartsRespVO>
* 需要修改返回值
*/
List<OrderPartsRespVO> getPartsDetail(Long orderId, Long roomId , Long bodyId , String name);
PageResult<OrderPartsRespVO> getPartsDetail(Long orderId, Long roomId , Long bodyId , String name, Integer pageNo, Integer pageSize);
/**
@@ -140,7 +139,7 @@ public interface OrderService {
/**
* 文件数据导入
*/
void importExcelData(OrderDO orderDO, List<?> list);
void importExcelData(OrderDO orderDO, List<?> list, Integer index);
/**
* 模板文件导入保存
@@ -177,25 +176,13 @@ public interface OrderService {
/**
* 生产单状态统计
*/
List<OrderStatusRespVO> getOrderStatusCount(Integer startTerm);
/**
* 小板数据分析统计
*/
List<OrderGoodsPlateRespVO> getOrderPlateAnalysisCount();
List<OrderStatusRespVO> getOrderStatusCount(String startTime, String endTime);
/**
* 生产单超期告警分析统计
*/
Map<String,List<OrderOverdueRespVO>> getOrderWarn();
/**
* 今日要完成生产单数
*/
List<OrderRespVO> getOrderOverdue();
String getOrderBodyToString(Long orderId);
/**
* 生产单总数统计
*/
@@ -224,5 +211,10 @@ public interface OrderService {
/**
* 小板数量
*/
Integer plateCount();
PageResult<OrderGoodsPlateRespVO> plateCount(String startTime, String endTime, Integer pageNo, Integer pageSize);
/**
* 小板面积
*/
PageResult<OrderGoodsPlateRespVO> plateArea(String startTime, String endTime, Integer pageNo, Integer pageSize);
}
@@ -280,7 +280,6 @@ public class OrderServiceImpl implements OrderService {
// 判断生产单是否删除
Integer deleted = getOrderDeleted(orderId);
List<OrderBodyRespVO> orderBodyRespVOList = BeanUtils.toBean(
orderBodyMapper.selectList(orderId, deleted, SecurityFrameworkUtils.getLoginUser().getOrganId()), OrderBodyRespVO.class);
return orderBodyRespVOList;
@@ -354,8 +353,35 @@ public class OrderServiceImpl implements OrderService {
}
@Override
public Integer plateCount() {
return null;
public PageResult<OrderGoodsPlateRespVO> plateCount(String startTime, String endTime, Integer pageNo, Integer pageSize) {
// 角色判断
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
// 数据查询
PageDTO<OrderGoodsPlateRespVO> page = new PageDTO<>(pageNo, pageSize);
IPage<OrderGoodsPlateRespVO> orderDetail;
if (loginUser.getIsSupAdmin()){
orderDetail = plateMapper.selectPlateAnalysisListByCount(page,null, startTime, endTime);
}else {
orderDetail = plateMapper.selectPlateAnalysisListByCount(page,OrganContextHolder.getOrganId(), startTime, endTime);
}
PageResult<OrderGoodsPlateRespVO> pageResult = new PageResult(orderDetail.getRecords(), orderDetail.getTotal());
return pageResult;
}
@Override
public PageResult<OrderGoodsPlateRespVO> plateArea(String startTime, String endTime, Integer pageNo, Integer pageSize) {
// 角色判断
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
// 数据查询
PageDTO<OrderGoodsPlateRespVO> page = new PageDTO<>(pageNo, pageSize);
IPage<OrderGoodsPlateRespVO> orderDetail;
if (loginUser.getIsSupAdmin()){
orderDetail = plateMapper.selectPlateAnalysisListByArea(page,null, startTime, endTime);
}else {
orderDetail = plateMapper.selectPlateAnalysisListByArea(page,OrganContextHolder.getOrganId(), startTime, endTime);
}
PageResult<OrderGoodsPlateRespVO> pageResult = new PageResult(orderDetail.getRecords(), orderDetail.getTotal());
return pageResult;
}
@Override
@@ -386,23 +412,6 @@ public class OrderServiceImpl implements OrderService {
return map;
}
@Override
public List<OrderPlatesDetailReqVO> getPlatesDetail(Long orderId, Long roomId, Long bodyId, Long groupId, String groupName) {
// 判断生产单是否删除 (包含判断存在)
Integer deleted = getOrderDeleted(orderId);
List<PlateRespVO> orderDetail = orderItemMapper.selectPlatesDetailByOrderId(orderId, roomId, bodyId, groupId,
groupName, SecurityFrameworkUtils.getLoginUser().getOrganId(), deleted);
List<OrderPlatesDetailReqVO> platesDetailReqVOS = new ArrayList<>();
orderDetail.forEach(orderPlatesDetailRespVO -> {
OrderPlatesDetailReqVO orderPlatesDetailReqVO = BeanUtils.toBean(orderPlatesDetailRespVO, OrderPlatesDetailReqVO.class)
.setIsRowHole(false);
if (orderPlatesDetailRespVO.getUnregularPointCount() > 0 || orderPlatesDetailRespVO.getFrontHoleCount() > 0
|| orderPlatesDetailRespVO.getBackHoleCount() > 0 || orderPlatesDetailRespVO.getSideHoleCount() > 0)
orderPlatesDetailReqVO.setIsRowHole(true);
platesDetailReqVOS.add(orderPlatesDetailReqVO);
});
return platesDetailReqVOS;
}
@Override
public PageResult<OrderPlatesDetailReqVO> getPlatesDetail(Long orderId, Long roomId, Long bodyId, Long groupId, String groupName, Integer pageNo, Integer pageSize) {
PageDTO<OrderRespVOCopy> page = new PageDTO<>(pageNo, pageSize);
@@ -416,14 +425,6 @@ public class OrderServiceImpl implements OrderService {
return pageResult;
}
@Override
public List<OrderPartsRespVO> getPartsDetail(Long orderId, Long roomId, Long bodyId, String name) {
// 判断生产单是否删除 (包含判断存在)
Integer deleted = getOrderDeleted(orderId);
List<OrderPartsRespVO> orderDetail = orderItemMapper.selectPartsDetailByOrderId(orderId, roomId, bodyId, name,
SecurityFrameworkUtils.getLoginUser().getOrganId(), deleted);
return orderDetail;
}
@Override
public PageResult<OrderPartsRespVO> getPartsDetail(Long orderId, Long roomId, Long bodyId, String name, Integer pageNo, Integer pageSize) {
PageDTO<OrderRespVOCopy> page = new PageDTO<>(pageNo, pageSize);
@@ -519,7 +520,10 @@ public class OrderServiceImpl implements OrderService {
String nickName = SecurityFrameworkUtils.getLoginUser().getNickname();
OrderDO orderDO = order.get(0).setSalesman(nickName).setSplitter(nickName);
orderInputProcessor.batchInsert(rawGoodsDO, bodyDO, groupDO, partsDO, plateDO, null, itemDO, orderDO, goodsDO, plateGoodDOS);
if (orderDO != null){
orderMapper.insert(orderDO);
}
orderInputProcessor.batchInsert(rawGoodsDO, bodyDO, groupDO, partsDO, plateDO, null, itemDO, goodsDO, plateGoodDOS);
List<OrderModelDO> orderModelDOs = BeanUtils.toBean(plateDetail, OrderModelDO.class);
if (orderModelDOs.size() > 0) {
@@ -546,18 +550,21 @@ public class OrderServiceImpl implements OrderService {
List<PlateGoodDO> plateGoodLists = new ArrayList<>();
for (GoodsDO goodsDO : goodsLists) {
PlateGoodDO plateGoodDO;
PlateGoodDO plateGoodDO = null;
List<PlateGoodDO> plateGoodDOS = null;
if (goodsDO.getGoodsId() != null) { // 有goodsId
plateGoodDO = plateGoodMapper.selectGoodOne(goodsDO.getGoodsId(), SecurityFrameworkUtils.getLoginUser().getOrganId());
} else { // 没有goodsId 其他信息匹配
plateGoodDO = plateGoodMapper.selectGood(goodsDO.getGoodsName(), goodsDO.getMaterial(), goodsDO.getColor(),
goodsDO.getTexture(), goodsDO.getWidth(), goodsDO.getWidth(), goodsDO.getHeight(), goodsDO.getSpec(),
goodsDO.getBrand(), SecurityFrameworkUtils.getLoginUser().getOrganId());
plateGoodDOS = plateGoodMapper.selectGood(goodsDO.getGoodsName(), goodsDO.getMaterial(), goodsDO.getColor(),
goodsDO.getTexture(), goodsDO.getWidth(), goodsDO.getThickness(), goodsDO.getHeight(), goodsDO.getBrand(),
goodsDO.getSpec(), SecurityFrameworkUtils.getLoginUser().getOrganId());
}
if (plateGoodDO != null) {//存在板材
goodsDO.setGoodsId(plateGoodDO.getGoodsId());
if (plateGoodDOS != null && plateGoodDOS.size() > 0) {//存在板材
goodsDO.setGoodsId(plateGoodDOS.get(0).getGoodsId());
break;
} else if (plateGoodDO != null) { // 存在板材
goodsDO.setGoodsId(plateGoodDO.getGoodsId());
} else { // 不存在板材
Long plateGoods = (Long) identifierGenerator.nextId(null);
Long goodsId = (Long) identifierGenerator.nextId(null);
@@ -576,7 +583,6 @@ public class OrderServiceImpl implements OrderService {
}
map.put("goodsDO", goodsLists);
map.put("plateGoodDOLists", plateGoodLists);
// System.err.println(" map " + map);
return map;
}
@@ -673,39 +679,12 @@ public class OrderServiceImpl implements OrderService {
}
@Override
public List<OrderStatusRespVO> getOrderStatusCount(Integer startTerm) {
// 根据开始条件选择
LocalDateTime orderDate = null;
if (startTerm != null){
switch (startTerm) {
case 2: // 月
orderDate = LocalDate.now().withDayOfMonth(1).atStartOfDay();
break;
case 3: // 年
orderDate = LocalDate.now().withMonth(1).withDayOfMonth(1).atStartOfDay();
break;
default: // 周
orderDate = LocalDate.now().with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).atStartOfDay();
break;
}
}else {
orderDate = LocalDate.now().with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).atStartOfDay();
}
List<OrderStatusRespVO> orderStatusRespVOS = orderMapper.selectOrderStatusCount(OrganContextHolder.getOrganId(), orderDate);
public List<OrderStatusRespVO> getOrderStatusCount(String startTime, String endTime) {
List<OrderStatusRespVO> orderStatusRespVOS = orderMapper.selectOrderStatusCount(OrganContextHolder.getOrganId(), startTime, endTime);
orderStatusRespVOS.removeIf(obj -> obj.getOrderState() == OrderStatusEnum.EMPTY.getStatus());
return orderStatusRespVOS;
}
@Override
public List<OrderGoodsPlateRespVO> getOrderPlateAnalysisCount() {
LocalDateTime orderDate = LocalDate.now().withDayOfMonth(1).atStartOfDay();
List<OrderGoodsPlateRespVO> orderGoodsPlateRespVOS = plateMapper.selectPlateAnalysisList(OrganContextHolder.getOrganId(), orderDate);
return orderGoodsPlateRespVOS;
}
@Override
public Map<String,List<OrderOverdueRespVO>> getOrderWarn() {
Map<String,List<OrderOverdueRespVO>> map = new HashMap<>();
@@ -724,11 +703,6 @@ public class OrderServiceImpl implements OrderService {
return map;
}
@Override
public List<OrderRespVO> getOrderOverdue() {
return null;
}
// 判断是否已经导入
private Boolean validateOrderNoExists(String orderNo, Long organId) {
if (orderMapper.selectCount(new LambdaQueryWrapper<OrderDO>()
@@ -782,34 +756,39 @@ public class OrderServiceImpl implements OrderService {
}
@Override
public void importExcelData(OrderDO orderDO, List<?> list) {
orderDO.setId((Long) snowFlakeGenerator.nextId(null));
@Transactional(rollbackFor = Exception.class)
public void importExcelData(OrderDO orderDO, List<?> list, Integer index) {
if (index == 0){
orderDO.setId((Long) snowFlakeGenerator.nextId(null));
orderMapper.insert(orderDO);
}
Map<String, List<?>> listMap = excelTypeRealize.changeDate(list, orderDO.getId());
List<RawGoodsDO> rawGoodsDO = (List<RawGoodsDO>) listMap.get("rawGoodsDOS");
List<GoodsDO> goodsDO = (List<GoodsDO>) listMap.get("goodsDOS");
if (list.size() > 0) {
Map<String, List<?>> listMap = excelTypeRealize.changeDate(list, orderDO.getId());
List<RawGoodsDO> rawGoodsDO = (List<RawGoodsDO>) listMap.get("rawGoodsDOS");
List<GoodsDO> goodsDO = (List<GoodsDO>) listMap.get("goodsDOS");
// List<PlateGoodDO> plateGoodDOS = (List<PlateGoodDO>) listMap.get("plateGoodDOS");
List<OrderBodyDO> bodyDO = (List<OrderBodyDO>) listMap.get("orderBodyDOS");
List<OrderGroupDO> groupDO = (List<OrderGroupDO>) listMap.get("orderGroupDOS");
List<PlateDO> plateDO = (List<PlateDO>) listMap.get("plateDOS");
List<OrderPartsDO> partsDO = (List<OrderPartsDO>) listMap.get("orderPartsDOS");
List<OrderItemDO> itemDO = (List<OrderItemDO>) listMap.get("orderItemDOS");
List<OrderModelDO> orderModelDOS = (List<OrderModelDO>) listMap.get("orderModelDOS");
List<OrderPartsRemark> orderPartsRemarks = (List<OrderPartsRemark>) listMap.get("orderPartsRemarks");
// 板材库匹配
Map<String, List<?>> map = getPlateGoods(goodsDO);// 检验商品板材信息是否存在
goodsDO = (List<GoodsDO>) map.get("goodsDO");
List<PlateGoodDO> plateGoodDOS = (List<PlateGoodDO>) map.get("plateGoodDOLists");
List<OrderBodyDO> bodyDO = (List<OrderBodyDO>) listMap.get("orderBodyDOS");
List<OrderGroupDO> groupDO = (List<OrderGroupDO>) listMap.get("orderGroupDOS");
List<PlateDO> plateDO = (List<PlateDO>) listMap.get("plateDOS");
List<OrderPartsDO> partsDO = (List<OrderPartsDO>) listMap.get("orderPartsDOS");
List<OrderItemDO> itemDO = (List<OrderItemDO>) listMap.get("orderItemDOS");
List<OrderModelDO> orderModelDOS = (List<OrderModelDO>) listMap.get("orderModelDOS");
List<OrderPartsRemark> orderPartsRemarks = (List<OrderPartsRemark>) listMap.get("orderPartsRemarks");
// 板材库匹配
Map<String, List<?>> map = getPlateGoods(goodsDO);// 检验商品板材信息是否存在 excel
goodsDO = (List<GoodsDO>) map.get("goodsDO");
List<PlateGoodDO> plateGoodDOS = (List<PlateGoodDO>) map.get("plateGoodDOLists");
// validateCustomOrderNoExists(orderDO.getCustomOrderNo());
orderInputProcessor.batchInsert(rawGoodsDO, bodyDO, groupDO, partsDO, plateDO, null, itemDO, orderDO, goodsDO, plateGoodDOS);
if (orderModelDOS.size() > 0) {
orderInputProcessor.batchSaveModel(orderModelDOS);
orderInputProcessor.batchInsert(rawGoodsDO, bodyDO, groupDO, partsDO, plateDO, null, itemDO, goodsDO, plateGoodDOS);
if (orderModelDOS.size() > 0) {
orderInputProcessor.batchSaveModel(orderModelDOS);
}
if (orderPartsRemarks.size() > 0) {
orderInputProcessor.batchSaveOrderPartsModel(orderPartsRemarks);
}
}
if (orderPartsRemarks.size() > 0) {
orderInputProcessor.batchSaveOrderPartsModel(orderPartsRemarks);
}
}
@Override
@@ -1,5 +1,6 @@
package com.cf.imes.module.executor.util.fileConversion.admin.api.webcad;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
@@ -12,6 +13,9 @@ import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.Future;
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -170,10 +174,19 @@ public class ApiDataAchieve {
// 订单列表
public Future<JSONObject> getApiOrderList(String token,String shopId,String createDateMin, String createDateMax, String orderNo, String customOrderNo) {
JSONObject jsonOrders = new JSONObject();
if (createDateMin != null){
if (createDateMin != null && createDateMax != null){
// 定义日期格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// 将字符串转换为LocalDate对象
LocalDate startTime = LocalDate.parse(createDateMin, formatter);
LocalDate endTime = LocalDate.parse(createDateMax, formatter);
long daysBetweenSimple = ChronoUnit.DAYS.between(startTime, endTime);
if (daysBetweenSimple > 30) {
throw exception(ORDER_DATE_ERR);
}
jsonOrders.put("create_date_min", createDateMin + " 00:00:00");
}
if (createDateMax != null) {
jsonOrders.put("create_date_max", createDateMax + " 23:59:59");
}
@@ -66,9 +66,9 @@ public class ExcelReadUtil { // 文件读取
}
);
index.set(true);
if (MapUtil.isEmpty(orderMap) || CollectionUtil.isEmpty(list)) {
isErr.set(-1);
}
// if (MapUtil.isEmpty(orderMap) || CollectionUtil.isEmpty(list)) {
// isErr.set(-1);
// }
map.put("order", orderMap);
map.put("plate", list);
return map;
@@ -78,35 +78,56 @@ public class ExcelReadUtil { // 文件读取
// order 数据转换
public Map<String, Object> changeOrderDO(Map<Object, Object> orderMap) {
Map<String, Object> map = new HashMap<>();
String s = (String) orderMap.get("出货日期");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// string 拼接
String error = "";
// 电话校验
if (!validatePhoneNumber((String) orderMap.get("客户电话"))) {
error += (String) orderMap.get("客户电话")+ "-客户电话格式错误";
// 判断是否为空
if ( orderMap.get("客户") == null){
error += "客户不能为空";
}
if (!validatePhoneNumber((String) orderMap.get("经销商电话"))) {
error += (String) orderMap.get("经销商电话")+ "-经销商电话格式错误";
if (orderMap.get("经销商") == null){
error += "经销商不能为空";
}
if (orderMap.get("客户地址") == null){
error += "客户地址不能为空;";
}
if (orderMap.get("出货日期") == null){
error += "出货日期不能为空;";
}
if (orderMap.get("客户电话") == null){
error += "客户电话不能为空;";
} else {
if (!validatePhoneNumber((String) orderMap.get("客户电话"))) {
error += orderMap.get("客户电话")+ "-客户电话格式错误;";
}
}
if (orderMap.get("经销商电话") != null){
if (!validatePhoneNumber((String) orderMap.get("经销商电话"))) {
error += orderMap.get("经销商电话")+ "-经销商电话格式错误;";
}
}
OrderDO orderDO = OrderDO.builder()
.organId(OrganContextHolder.getOrganId())
.dataType(0)
.customer((String) orderMap.get("客户"))
.customer((String) orderMap.get("客户")) //
.customOrderNo((String) orderMap.get("自定义单号"))
.dealer((String) orderMap.get("经销商"))
.dealer((String) orderMap.get("经销商")) //
.dealerPhoneNumber((String) orderMap.get("经销商电话"))
.address((String) orderMap.get("客户地址"))
.phoneNumber((String) orderMap.get("客户电话"))
.address((String) orderMap.get("客户地址")) //
.phoneNumber((String) orderMap.get("客户电话")) //
.salesman((String) orderMap.get("业务员"))
.splitter((String) orderMap.get("拆单员"))
.remark((String) orderMap.get("备注"))
.build();
try {
LocalDate orderDate = LocalDate.parse(s, formatter);
orderDO.setDeliveryDate(orderDate.atStartOfDay());
} catch (DateTimeParseException e) {
error += s + "-出货日期格式错误;";
if (orderMap.get("出货日期") == null){
error += "出货日期不能为空;";
}else {
String s = (String) orderMap.get("出货日期");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
try {
LocalDate orderDate = LocalDate.parse(s, formatter);
orderDO.setDeliveryDate(orderDate.atStartOfDay()); //
} catch (DateTimeParseException e) {
error += s + "-出货日期格式错误;";
}
}
map.put("order", orderDO);
map.put("error", error);
@@ -382,6 +403,13 @@ public class ExcelReadUtil { // 文件读取
errList.add("成品宽数据长度错误");
}
}
if (flag) {
Double plateHeight = Double.parseDouble(vo.getHeight());
Double plateWidth = Double.parseDouble(vo.getWidth());
vo.setArea(plateHeight * plateWidth * 0.000001);
}
if (!convertToDouble(vo.getSplitHeight())) {
flag = false;
errList.add("拆单长数据类型错误");
@@ -139,7 +139,6 @@ public class ExcelTypeRealize {
excelVO -> excelVO.getRoomsName() != null ? excelVO.getRoomsName() : " ",
Collectors.toList()
));
System.out.println("roomCollect " + roomCollect);
roomCollect.forEach((roomName, listRoom) -> {
Long roomId = (Long) snowFlakeGenerator.nextId(null);
@@ -161,12 +160,12 @@ public class ExcelTypeRealize {
// 加工组类型为条件进行分组
Map<String, List<OrderPlateImportExcelVO>> synthesisCollect = listBody.stream()
.collect(Collectors.groupingBy(
excelVO -> excelVO.getSynthesis() != null ? excelVO.getSynthesis() : " ",
excelVO -> excelVO.getSynthesisTypeName() != null ? excelVO.getSynthesisTypeName() : " ",
Collectors.toList()
));
Long groupTypeId = (Long) snowFlakeGenerator.nextId(null);
synthesisCollect.forEach((synthesis, listSynthesis) -> {
synthesisCollect.forEach((synthesisTypeName, listSynthesis) -> {
// 加工组名称为条件进行分组
Map<String, List<OrderPlateImportExcelVO>> combinationNameCollect = listSynthesis.stream()
.collect(Collectors.groupingBy(
@@ -174,12 +173,12 @@ public class ExcelTypeRealize {
Collectors.toList()
));
combinationNameCollect.forEach((combinationName, listCombinationName) -> {
Long groupId = (Long) snowFlakeGenerator.nextId(null);
// 板数量
final Double[] plateCountByCombination = {0.0};
OrderGroupDO orderGroupDO = OrderGroupDO.builder().id(groupId).orderId(orderId).organId(organId).bodyId(bodyId)
.groupTypeId(groupTypeId).groupTypeName(synthesis).name(combinationName).width(0.0).height(0.0)
.depth(0.0).multiNum(0).plateNum(0).unregularNum(0).filename("").remark("").build();
Long groupId = (Long) snowFlakeGenerator.nextId(null);
OrderGroupDO orderGroupDO = OrderGroupDO.builder().id(groupId).orderId(orderId).organId(organId).bodyId(bodyId)
.groupTypeId(groupTypeId).groupTypeName(synthesisTypeName).name(combinationName != " " ? combinationName : synthesisTypeName).width(0.0).height(0.0)
.depth(0.0).multiNum(0).plateNum(0).unregularNum(0).filename("").remark("").build();
listCombinationName.forEach(combination -> {
@@ -207,7 +206,7 @@ public class ExcelTypeRealize {
.plateNo(combination.getPlateNo())
.goodsId(combination.getGoodId())
.width(BigDecimal.valueOf(Double.parseDouble(combination.getWidth())))
.plateNo(((obtainingTime)+ Long.toString(plateNo).substring(2)))
.plateNo(((obtainingTime) + Long.toString(plateNo).substring(2)))
.height(BigDecimal.valueOf(Double.parseDouble(combination.getHeight())))
.thickness(BigDecimal.valueOf(Double.parseDouble(combination.getThickness())))
.splitWidth(BigDecimal.valueOf(Double.parseDouble(combination.getSplitWidth())))
@@ -229,7 +228,7 @@ public class ExcelTypeRealize {
OrderItemDO orderItemDO = OrderItemDO.builder().orderId(orderId).type(OrderItemTypeEnum.PLATE_ITEM.getStatus())
.roomId(roomId).bodyId(bodyId).plateId(plateId)
.num(1.0).groupId(groupId).build();
.num(1.0).groupId(synthesisTypeName != " " ? groupId : null).build();
orderItemDOS.add(orderItemDO);
orderModelDOS.add(OrderModelDO.builder().orderId(orderId).plateId(plateId)
.typographicFace(Integer.valueOf(typographyDTO.getValue())).build());
@@ -249,14 +248,14 @@ public class ExcelTypeRealize {
.remark(remarkExtract(combination.remarkJSON())).build();
orderPartsRemarks.add(orderPartsRemark);
OrderItemDO orderItemDO = OrderItemDO.builder().orderId(orderId).type(OrderItemTypeEnum.PARTS_ITEM.getStatus())
.roomId(roomId).bodyId(bodyId).partsId(partsId).groupId(groupId)
.roomId(roomId).bodyId(bodyId).partsId(partsId).groupId(synthesisTypeName != " " ? groupId : null)
.num(Double.valueOf(combination.getGoodsNumber())).build();
orderItemDOS.add(orderItemDO);
}
});
orderGroupDO.setPlateNum(plateCountByCombination[0].intValue());
if (orderGroupDO.getName() != null && !orderGroupDO.getName().trim().isEmpty()) {
if (orderGroupDO.getGroupTypeName() != null && !orderGroupDO.getGroupTypeName().trim().isEmpty()) {
orderGroupDOS.add(orderGroupDO);
}
});
@@ -279,8 +278,6 @@ public class ExcelTypeRealize {
map.put("orderModuleExtraDOS", orderModuleExtraDOS);
map.put("orderModelDOS", orderModelDOS);
map.put("orderPartsRemarks", orderPartsRemarks);
System.out.println(" goodsDOS " + goodsDOS);
System.out.println(" rawGoodsDOS " + rawGoodsDOS);
return map;
}
@@ -102,12 +102,12 @@ public class OrderPlateImportExcelVO {
@JsonIgnore
private String cabinetsName;
@ExcelProperty(value = "加工组类型")
@ExcelIgnore
@JsonIgnore
private String synthesis;
@JsonIgnore
@ExcelIgnore
@ExcelProperty(value = "加工组类型")
private String synthesisTypeName;//加工组类型的名称
@ExcelProperty(value = "加工组名称")
@@ -208,6 +208,10 @@ public class OrderPlateImportExcelVO {
@ExcelIgnore
private String remark;
@JsonIgnore
@ExcelIgnore
private Double area; //面积
//备注转json数据
public String remarkJSON() {
ObjectMapper objectMapper = new ObjectMapper();
@@ -84,12 +84,13 @@
<select id="selectOrderStatusCount" resultType="com.cf.imes.module.executor.controller.admin.order.vo.order.OrderStatusRespVO">
select
o.status as orderState,
count(o.id) as orderCount
count(o.id) as orderCount,
o.order_date
from orders o
where o.organ_id = #{organId}
and DATE(o.order_date) >= #{orderDate}
and DATE(o.order_date) between #{startTime} and #{endTime}
and o.deleted = 0
group by o.status
group by o.status, o.order_date
</select>
<select id="selectOrderNear" resultType="com.cf.imes.module.executor.controller.admin.order.vo.order.OrderOverdueRespVO">
@@ -605,7 +605,7 @@
</select>
<select id="selectPlateAnalysisList" resultType="com.cf.imes.module.executor.controller.admin.order.vo.order.OrderGoodsPlateRespVO">
<select id="selectPlateAnalysisListByCount" resultType="com.cf.imes.module.executor.controller.admin.order.vo.order.OrderGoodsPlateRespVO">
SELECT
MIN(g.brand) AS brand,
@@ -626,10 +626,50 @@
LEFT JOIN order_plate a ON g.id = a.goods_id AND g.organ_id = a.organ_id
LEFT JOIN orders o ON o.id = a.order_id
WHERE
o.organ_id = #{organId}
AND a.deleted = 0
AND DATE(o.order_date) >= #{orderDate}
a.deleted = 0
AND DATE(o.order_date) BETWEEN #{startTime} AND #{endTime}
<if test="organId != null">
AND o.organ_id = #{organId}
</if>
GROUP BY
g.goods_id
HAVING
SUM(a.area) > 0
ORDER BY
orderCount DESC;
</select>
<select id="selectPlateAnalysisListByArea" resultType="com.cf.imes.module.executor.controller.admin.order.vo.order.OrderGoodsPlateRespVO">
SELECT
MIN(g.brand) AS brand,
MIN(g.color) AS color,
g.goods_id,
MIN(g.goods_name) AS goods_name,
MIN(g.height) AS height,
MIN(g.material) AS material,
MIN(g.spec) AS spec,
MIN(g.texture) AS texture,
MIN(g.thickness) AS thickness,
MIN(g.width) AS width,
MIN(o.order_date) AS orderDate,
SUM(a.area) AS orderArea,
COUNT(a.id) AS orderCount
FROM
order_goods g
LEFT JOIN order_plate a ON g.id = a.goods_id AND g.organ_id = a.organ_id
LEFT JOIN orders o ON o.id = a.order_id
WHERE
a.deleted = 0
AND DATE(o.order_date) BETWEEN #{startTime} AND #{endTime}
<if test="organId != null">
AND o.organ_id = #{organId}
</if>
GROUP BY
g.goods_id
HAVING
SUM(a.area) > 0
ORDER BY
orderArea DESC;
</select>
</mapper>
@@ -10,13 +10,13 @@ import com.cf.imes.framework.common.exception.ErrorCode;
*/
public interface ErrorCodeConstants {
// ========== GoView 模块 1-003-000-000 ==========
ErrorCode GO_VIEW_PROJECT_NOT_EXISTS = new ErrorCode(1_003_000_000, "GoView 项目不存在");
// ========== UREPORT 模块 1-003-001-000 ==========
ErrorCode UREPORT_DATA_NOT_EXISTS = new ErrorCode(1_003_001_001, "Ureport2 报表不存在");
ErrorCode UREPORT_DATABASE_NOT_EXISTS = new ErrorCode(1_003_001_002, "Ureport2 报表数据源不存在");
ErrorCode TEMPLATE_NOT_EXISTS = new ErrorCode(1_003_001_003, "报表模板信息不存在");
ErrorCode DATASOURCE_NOT_EXISTS = new ErrorCode(1_003_001_004, "报表数据不存在");
ErrorCode DATASET_NOT_EXISTS = new ErrorCode(1_003_001_005, "报表数据集不存在");
ErrorCode TEMPLATE_NOT_EXISTS = new ErrorCode(1_003_001_001, "报表模板信息不存在");
ErrorCode DATASOURCE_NOT_EXISTS = new ErrorCode(1_003_001_002, "报表数据源不存在");
ErrorCode DATASOURCE_CONNECT_FAIL = new ErrorCode(1_003_001_003, "报表数据源连接失败");
ErrorCode DATASET_NOT_EXISTS = new ErrorCode(1_003_001_004, "报表数据不存在");
ErrorCode DATASET_SQL_INJECTION_RISK = new ErrorCode(1_003_001_005, "存在SQL注入风险");
ErrorCode DATASET_SQL_REQUIRED = new ErrorCode(1_003_001_006, "SQL语句不能为空");
ErrorCode DATASET_SQL_ILLEGAL = new ErrorCode(1_003_001_007, "SQL语句非法");
ErrorCode DATASET_GET_FIELDS_ERROR = new ErrorCode(1_003_001_008, "获取表字段");
}
@@ -103,6 +103,13 @@
<artifactId>cf-spring-boot-starter-monitor</artifactId>
</dependency>
<dependency>
<groupId>com.ureport</groupId>
<artifactId>ureport-core</artifactId>
<version>2.3.0-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/ureport-core-2.3.0-SNAPSHOT.jar</systemPath>
</dependency>
</dependencies>
<build>
<!-- 设置构建的 jar 包名 -->
@@ -7,6 +7,9 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
@@ -18,8 +21,11 @@ import java.util.List;
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ReportDatasetSaveReqVO {
@Schema(description = "数据集id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
public class ReportDatasetSaveReqVO implements Serializable {
@Serial
private static final long serialVersionUID = -2253718976788111670L;
@Schema(description = "数据集id", example = "1")
private Long id;
@Schema(description = "数据集名称", example = "测试数据集")
@@ -33,8 +39,8 @@ public class ReportDatasetSaveReqVO {
private String sql;
@Schema(description = "参数列表")
private List<ReportDatasetParameterVO> parameters;
private List<ReportDatasetParameterVO> parameters = new ArrayList<>();
@Schema(description = "字段列表")
private List<ReportDatasetFieldVO> fields;
private List<ReportDatasetFieldVO> fields = new ArrayList<>();
}
@@ -2,10 +2,12 @@ package com.cf.imes.module.report.controller.admin.datasource;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetFieldVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportBeanDatasourceRespVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceReqVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceRespVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceSaveReqVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceTestConnReqVO;
import com.cf.imes.module.report.dal.dataobject.datasource.ReportDatasourceDO;
import com.cf.imes.module.report.service.datasource.ReportDatasourceService;
import io.swagger.v3.oas.annotations.Operation;
@@ -19,8 +21,11 @@ import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
import static com.cf.imes.framework.common.pojo.CommonResult.error;
import static com.cf.imes.framework.common.pojo.CommonResult.success;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASOURCE_CONNECT_FAIL;
/**
* 报表数据源控制器
@@ -30,7 +35,7 @@ import static com.cf.imes.framework.common.pojo.CommonResult.success;
*/
@Tag(name = "管理后台 - 报表数据源")
@RestController
@RequestMapping("/report/datasource")
@RequestMapping("/report")
@Validated
public class ReportDatasourceController {
@Resource
@@ -61,7 +66,7 @@ public class ReportDatasourceController {
}
@GetMapping("/datasource/{id}")
@Operation(summary = "报表数据源")
@Operation(summary = "报表数据源")
@Parameter(name = "id", description = "编号", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('report:datasource:query')")
public CommonResult<ReportDatasourceRespVO> getDatasource(@PathVariable("id") Long id) {
@@ -69,14 +74,11 @@ public class ReportDatasourceController {
return success(BeanUtils.toBean(datasource, ReportDatasourceRespVO.class));
}
@GetMapping("/datasources")
@GetMapping("/{templateId}/datasources")
@Operation(summary = "获取报表模板下的报表数据源")
@PreAuthorize("@ss.hasPermission('report:datasource:query')")
public CommonResult<List<ReportDatasourceRespVO>> getDatasourcePage(@RequestParam(value = "reportId") Long reportId,
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "type", required = false) Integer type) {
ReportDatasourceReqVO reqVO = new ReportDatasourceReqVO(reportId, name, type);
return success(BeanUtils.toBean(datasourceService.getTemplateDatasourceList(reqVO), ReportDatasourceRespVO.class));
public CommonResult<List<ReportDatasourceRespVO>> getDatasourcePage(@PathVariable(value = "templateId") Long templateId) {
return success(BeanUtils.toBean(datasourceService.getTemplateDatasourceList(ReportDatasourceReqVO.builder().templateId(templateId).build()), ReportDatasourceRespVO.class));
}
@GetMapping("/datasource/beans")
@@ -92,4 +94,26 @@ public class ReportDatasourceController {
public CommonResult<List<String>> getBeanDatasourceList(@RequestParam(value = "beanId") String beanId) {
return success(datasourceService.loadBeanMethods(beanId));
}
@PostMapping("/datasource/connect")
@Operation(summary = "测试数据源连接")
@PreAuthorize("@ss.hasPermission('report:datasource:query')")
public CommonResult<Boolean> testDatasourceConnect(@RequestBody ReportDatasourceTestConnReqVO reqVO) {
boolean connResult = datasourceService.testConnect(reqVO);
return connResult ? success(true) : error(DATASOURCE_CONNECT_FAIL);
}
@PostMapping("/datasource/tables")
@Operation(summary = "获取数据源表列表")
@PreAuthorize("@ss.hasPermission('report:datasource:query')")
public CommonResult<List<Map<String, String>>> getDatasourceTables(@RequestBody ReportDatasourceTestConnReqVO reqVO) {
return success(datasourceService.getDatasourceTables(reqVO));
}
@PostMapping("/datasource/table/fields")
@Operation(summary = "获取数据源表字段")
@PreAuthorize("@ss.hasPermission('report:datasource:query')")
public CommonResult<List<ReportDatasetFieldVO>> getDatasourceTableFields(@RequestBody ReportDatasourceTestConnReqVO reqVO) {
return success(datasourceService.getTableFields(reqVO));
}
}
@@ -7,6 +7,9 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.io.Serial;
import java.io.Serializable;
/**
* @author Gqr
* @since 2024/7/8 11:01
@@ -17,13 +20,16 @@ import lombok.ToString;
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ReportDatasourceReqVO {
public class ReportDatasourceReqVO implements Serializable {
@Serial
private static final long serialVersionUID = 4591901987664100102L;
@Schema(description = "模板id", example = "1", requiredMode = Schema.RequiredMode.REQUIRED)
private Long templateId;
@Schema(description = "数据源名称", example = "测试库")
private String name;
@Schema(description = "数据源类型,jdbc、buildin", example = "jdbc")
@Schema(description = "数据源类型,0 jdbc、1 buildin、2 spring", example = "jdbc")
private Integer type;
}
@@ -1,6 +1,7 @@
package com.cf.imes.module.report.controller.admin.datasource.vo;
import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetRespVO;
import com.cf.imes.module.report.enums.datasource.ReportDatasourceTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
@@ -27,8 +28,8 @@ public class ReportDatasourceRespVO {
@Schema(description = "数据源名称", example = "测试库")
private String name;
@Schema(description = "数据源类型,jdbc、buildin", example = "jdbc")
private String type;
@Schema(description = "数据源类型,jdbc、buildin、spring", example = "jdbc")
private ReportDatasourceTypeEnum type;
@Schema(description = "数据源驱动类",example = "com.mysql.cj.jdbc.Driver")
private String driver;
@@ -1,6 +1,7 @@
package com.cf.imes.module.report.controller.admin.datasource.vo;
import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetSaveReqVO;
import com.cf.imes.module.report.validation.datasource.ReportDatasourceTypeInEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
@@ -8,6 +9,9 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
@@ -19,7 +23,10 @@ import java.util.List;
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ReportDatasourceSaveReqVO {
public class ReportDatasourceSaveReqVO implements Serializable {
@Serial
private static final long serialVersionUID = -1738392826420649562L;
@Schema(description = "数据源id", example = "1")
private Long id;
@@ -30,9 +37,13 @@ public class ReportDatasourceSaveReqVO {
@Schema(description = "数据源名称", example = "测试库")
private String name;
@Schema(description = "数据源类型,jdbc、buildin", example = "jdbc")
@Schema(description = "数据源类型,jdbc、buildin、spring", example = "jdbc")
@ReportDatasourceTypeInEnum
private String type;
@Schema(description = "spring型数据源id")
private String beanId;
@Schema(description = "数据源驱动类",example = "com.mysql.cj.jdbc.Driver")
private String driver;
@@ -49,5 +60,5 @@ public class ReportDatasourceSaveReqVO {
private String remark;
@Schema(description = "数据集")
private List<ReportDatasetSaveReqVO> datasets;
private List<ReportDatasetSaveReqVO> datasets = new ArrayList<>();
}
@@ -0,0 +1,44 @@
package com.cf.imes.module.report.controller.admin.datasource.vo;
import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetParameterVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
/**
* @author Gqr
* @since 2024/7/8 11:01
*/
@Schema(description = "管理后台 - 报表数据源测试连接 Request VO")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ReportDatasourceTestConnReqVO {
@Schema(description = "数据源驱动类",example = "com.mysql.cj.jdbc.Driver")
private String driver;
@Schema(description = "数据源地址", example = "https://www.cf.com")
private String url;
@Schema(description = "数据源用户名", example = "晨丰")
private String userName;
@Schema(description = "数据源密码", example = "晨丰")
private String password;
@Schema(description = "数据源id", example = "1")
private Long datasourceId;
@Schema(description = "数据库语句")
private String sql;
@Schema(description = "参数列表")
private List<ReportDatasetParameterVO> parameters = new ArrayList<>();
}
@@ -7,6 +7,7 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
/**
@@ -30,7 +31,7 @@ public class ReportTemplateSaveReqVO {
private String content;
@Schema(description = "数据源")
private List<ReportDatasourceSaveReqVO> datasource;
private List<ReportDatasourceSaveReqVO> datasource = new ArrayList<>();
@Schema(description = "模板类型,0内置、1自定义", example = "1")
private Integer type;
@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
import com.cf.imes.module.report.dal.dataobject.dataset.ReportDatasetDO;
import com.cf.imes.module.report.enums.datasource.ReportDatasourceTypeEnum;
import lombok.*;
import java.util.List;
@@ -39,9 +40,13 @@ public class ReportDatasourceDO extends BaseDO {
*/
private String name;
/**
* 模板类型,jdbc、buildin
* 模板类型,jdbc、buildin、spring
*/
private String type;
private ReportDatasourceTypeEnum type;
/**
* spring型数据源id
*/
private String beanId;
/**
* 数据源驱动类
*/
@@ -0,0 +1,41 @@
package com.cf.imes.module.report.enums.datasource;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author Gqr
* @since 2024/7/17 9:43
*/
@Getter
@AllArgsConstructor
public enum ReportDatasourceTypeEnum {
JDBC(0,"jdbc"),
BUILDIN(1,"buildin"),
SPRING(2,"spring");
@EnumValue
private final Integer code;
@JsonValue
private final String desc;
/**
* 匹配枚举
*
* @param desc
* @return
*/
@JsonCreator
public static ReportDatasourceTypeEnum fromDesc(String desc) {
for (ReportDatasourceTypeEnum value : ReportDatasourceTypeEnum.values()) {
if (value.getDesc().equals(desc)) {
return value;
}
}
return null;
}
}
@@ -1,12 +1,15 @@
package com.cf.imes.module.report.service.datasource;
import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetFieldVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportBeanDatasourceRespVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceReqVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceSaveReqVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceTestConnReqVO;
import com.cf.imes.module.report.dal.dataobject.datasource.ReportDatasourceDO;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
/**
* 报表数据源 Service 接口
@@ -67,4 +70,28 @@ public interface ReportDatasourceService {
* @return
*/
List<String> loadBeanMethods(String beanId);
/**
* 测试数据源连接
*
* @param reqVO 连接信息请求
* @return
*/
boolean testConnect(ReportDatasourceTestConnReqVO reqVO);
/**
* 获取数据源表列表
*
* @param reqVO 连接信息请求
* @return
*/
List<Map<String, String>> getDatasourceTables(ReportDatasourceTestConnReqVO reqVO);
/**
* 获取数据源表字段
*
* @param reqVO 连接信息请求
* @return
*/
List<ReportDatasetFieldVO> getTableFields(ReportDatasourceTestConnReqVO reqVO);
}
@@ -1,25 +1,53 @@
package com.cf.imes.module.report.service.datasource;
import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.util.ObjectUtil;
import com.bstek.ureport.definition.dataset.Field;
import com.bstek.ureport.definition.dataset.Parameter;
import com.bstek.ureport.definition.dataset.SqlDatasetDefinition;
import com.bstek.ureport.utils.ProcedureUtils;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetFieldVO;
import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetParameterVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportBeanDatasourceRespVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceReqVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceSaveReqVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceTestConnReqVO;
import com.cf.imes.module.report.dal.dataobject.datasource.ReportDatasourceDO;
import com.cf.imes.module.report.dal.mysql.datasource.ReportDatasourceMapper;
import com.cf.imes.module.report.framework.ureport.annotation.CfReportSpringbeanDatasource;
import com.cf.imes.module.report.util.SqlInjectionUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.SingleConnectionDataSource;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASET_GET_FIELDS_ERROR;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASET_SQL_ILLEGAL;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASET_SQL_INJECTION_RISK;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASET_SQL_REQUIRED;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASOURCE_NOT_EXISTS;
/**
@@ -30,6 +58,7 @@ import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASOURCE_NOT_
*/
@Service
@Validated
@Slf4j
public class ReportDatasourceServiceImpl implements ReportDatasourceService {
@Resource
private ReportDatasourceMapper datasourceMapper;
@@ -84,11 +113,12 @@ public class ReportDatasourceServiceImpl implements ReportDatasourceService {
@Override
public List<ReportDatasourceDO> getTemplateDatasourceList(ReportDatasourceReqVO reqVO) {
return datasourceMapper.selectList(new LambdaQueryWrapperX<ReportDatasourceDO>()
List<ReportDatasourceDO> reportDatasourceDOS = datasourceMapper.selectList(new LambdaQueryWrapperX<ReportDatasourceDO>()
.eqIfPresent(ReportDatasourceDO::getTemplateId, reqVO.getTemplateId())
.likeIfPresent(ReportDatasourceDO::getName, reqVO.getName())
.eqIfPresent(ReportDatasourceDO::getType, reqVO.getType())
.orderByDesc(ReportDatasourceDO::getCreateTime));
return reportDatasourceDOS;
}
@Override
@@ -133,4 +163,133 @@ public class ReportDatasourceServiceImpl implements ReportDatasourceService {
}
return result;
}
@Override
public boolean testConnect(ReportDatasourceTestConnReqVO reqVO) {
Connection conn = null;
try {
// 获取数据库连接
conn = buildConn(reqVO);
} catch (Exception ex) {
log.error("[testConnect][报表数据源测试连接失败:{}]", ex.getMessage());
return false;
} finally {
JdbcUtils.closeConnection(conn);
}
return true;
}
@Override
public List<Map<String, String>> getDatasourceTables(ReportDatasourceTestConnReqVO reqVO) {
Connection conn = null;
ResultSet rs = null;
List<Map<String, String>> tables = new ArrayList<Map<String, String>>();
try {
// 获取数据库连接
conn = buildConn(reqVO);
DatabaseMetaData metaData = conn.getMetaData();
String url = metaData.getURL();
String schema = null;
if (url.toLowerCase().contains("oracle")) {
schema = metaData.getUserName();
}
rs = metaData.getTables(conn.getCatalog(), schema, null, new String[]{"TABLE", "VIEW"});
// 轮询获取表信息
while (rs.next()) {
Map<String, String> table = new HashMap<String, String>();
table.put("name", rs.getString("TABLE_NAME"));
table.put("type", rs.getString("TABLE_TYPE"));
tables.add(table);
}
} catch (Exception ex) {
log.error("[testConnect][报表数据源库表失败:{}]", ex.getMessage());
} finally {
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeConnection(conn);
}
return tables;
}
@Override
public List<ReportDatasetFieldVO> getTableFields(ReportDatasourceTestConnReqVO reqVO) {
Connection conn = null;
String sql = reqVO.getSql();
List<ReportDatasetParameterVO> parameters = reqVO.getParameters();
try {
if(StringUtils.isEmpty(sql)) {
throw exception(DATASET_SQL_REQUIRED);
}
// 获取数据库连接
conn = buildConn(reqVO);
// 校验sql
if (SqlInjectionUtil.checkEditSql(sql)) {
throw exception(DATASET_SQL_ILLEGAL);
}
// 检查参数sql注入
for (ReportDatasetParameterVO parameterVO : parameters) {
if (SqlInjectionUtil.checkParam(parameterVO.getDefaultValue())) {
throw exception(DATASET_SQL_INJECTION_RISK);
}
}
// 准备sql执行参数
SqlDatasetDefinition sqlDatasetDefinition = new SqlDatasetDefinition();
sqlDatasetDefinition.setSql(sql);
sqlDatasetDefinition.setParameters(BeanUtils.toBean(parameters, Parameter.class));
Map<String, Object> params = new HashMap<String, Object>();
Map<String, Object> pmap = sqlDatasetDefinition.buildParameters(params);
String sqlForUse = sqlDatasetDefinition.parseSql(pmap);
if (ProcedureUtils.isProcedure(sqlForUse)) {
List<Field> fields = ProcedureUtils.procedureColumnsQuery(sqlForUse, pmap, conn);
return BeanUtils.toBean(fields, ReportDatasetFieldVO.class);
}
DataSource dataSource = new SingleConnectionDataSource(conn, false);
NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
final List<ReportDatasetFieldVO> fields = new ArrayList<>();
jdbcTemplate.query(sqlForUse, pmap, (ResultSetExtractor<Integer>) rs -> {
ResultSetMetaData metadata = rs.getMetaData();
List<String> metadataList = new ArrayList<>();
for (int i = 1; i <= metadata.getColumnCount(); i++) {
String columnName = metadata.getColumnLabel(i);
metadataList.add(columnName);
fields.add(new ReportDatasetFieldVO(columnName));
}
return null;
});
return fields;
} catch (ServiceException sex) {
throw sex;
} catch (Exception ex) {
log.error("[getTableFields][报表数据源获取表字段异常]", ex);
throw new ServiceException(DATASET_GET_FIELDS_ERROR);
} finally {
JdbcUtils.closeConnection(conn);
}
}
/**
* 构建数据库连接
* 有数据源id从库里查数据源信息
* 没有数据源id用请求中的driver等连接
* @param reqVO
* @return
* @throws ClassNotFoundException
* @throws SQLException
*/
private Connection buildConn(ReportDatasourceTestConnReqVO reqVO) throws ClassNotFoundException, SQLException {
Long datasourceId = reqVO.getDatasourceId();
Connection conn = null;
if (ObjectUtil.isNotNull(datasourceId)) {
ReportDatasourceDO datasourceDO = datasourceMapper.selectById(datasourceId);
if (ObjectUtil.isNotNull(datasourceDO)) {
Class.forName(datasourceDO.getDriver());
conn = DriverManager.getConnection(datasourceDO.getUrl(), datasourceDO.getUsername(), datasourceDO.getPassword());
}
} else {
Class.forName(reqVO.getDriver());
conn = DriverManager.getConnection(reqVO.getUrl(), reqVO.getUserName(), reqVO.getPassword());
}
return conn;
}
}
@@ -0,0 +1,63 @@
package com.cf.imes.module.report.util;
import java.util.Objects;
import java.util.regex.Pattern;
/**
* SQL 注入验证工具类
* from com.baomidou.mybatisplus.core.toolkit.sql.SqlInjectionUtil
* @author Gqr
* @since 2024/7/18 11:09
*/
public class SqlInjectionUtil {
/**
* SQL语法检查正则:符合两个关键字(有先后顺序)才算匹配
*/
private static final Pattern SQL_EDIT_PATTERN = Pattern.compile("(insert|delete|update|create|drop|truncate|grant|alter|deny|revoke|call|execute|exec|declare|show|rename|set)" +
"\\s+.*(into|from|set|where|table|database|view|index|on|cursor|procedure|trigger|for|password|union|and|or)", Pattern.CASE_INSENSITIVE);
/**
* SQL语法检查正则:符合两个关键字(有先后顺序)才算匹配
*/
private static final Pattern SQL_SYNTAX_PATTERN = Pattern.compile("(insert|delete|update|select|create|drop|truncate|grant|alter|deny|revoke|call|execute|exec|declare|show|rename|set)" +
"\\s+.*(into|from|set|where|table|database|view|index|on|cursor|procedure|trigger|for|password|union|and|or)|(select\\s*\\*\\s*from\\s+)|(and|or)\\s+.*(like|=|>|<|in|between|is|not|exists)", Pattern.CASE_INSENSITIVE);
/**
* 使用'、;或注释截断SQL检查正则
*/
private static final Pattern SQL_COMMENT_PATTERN = Pattern.compile("'.*(or|union|--|#|/\\*|;)", Pattern.CASE_INSENSITIVE);
/**
* 检查SQL 不允许修改结构或数据
*
* @param sql sql语句
* @return true 非法 false 合法
*/
public static boolean checkEditSql(String sql) {
Objects.requireNonNull(sql);
return SQL_COMMENT_PATTERN.matcher(sql).find() || SQL_EDIT_PATTERN.matcher(sql).find();
}
/**
* 检查参数是否存在 SQL 注入
*
* @param value 检查参数
* @return true 非法 false 合法
*/
public static boolean checkParam(String value) {
Objects.requireNonNull(value);
// 处理是否包含SQL注释字符 || 检查是否包含SQL注入敏感字符
return SQL_COMMENT_PATTERN.matcher(value).find() || SQL_SYNTAX_PATTERN.matcher(value).find();
}
/**
* 刪除字段转义符单引号双引号
*
* @param text 待处理字段
* @return
*/
public static String removeEscapeCharacter(String text) {
Objects.nonNull(text);
return text.replace("\"", "").replace("'", "");
}
}
@@ -0,0 +1,37 @@
package com.cf.imes.module.report.validation.datasource;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义报表数据源类型入参校验注解
*
* @author Gqr
* @since 2024/7/17 9:33
*/
@Target({
ElementType.METHOD,
ElementType.FIELD,
ElementType.ANNOTATION_TYPE,
ElementType.CONSTRUCTOR,
ElementType.PARAMETER,
ElementType.TYPE_USE
})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
validatedBy = {ReportDatasourceTypeInEnumValidator.class}
)
public @interface ReportDatasourceTypeInEnum {
String message() default "数据源类型[type]错误,请检查是否jdbc/buildin/spring";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
@@ -0,0 +1,38 @@
package com.cf.imes.module.report.validation.datasource;
import cn.hutool.core.util.ObjectUtil;
import com.cf.imes.module.report.enums.datasource.ReportDatasourceTypeEnum;
import org.apache.commons.lang3.StringUtils;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* 自定义报表数据源类型入参校验器
*
* @author Gqr
* @since 2024/7/17 9:33
*/
public class ReportDatasourceTypeInEnumValidator implements ConstraintValidator<ReportDatasourceTypeInEnum, String> {
@Override
public void initialize(ReportDatasourceTypeInEnum constraintAnnotation) {
ConstraintValidator.super.initialize(constraintAnnotation);
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (StringUtils.isEmpty(value)) {
return true;
} else {
ReportDatasourceTypeEnum byType = ReportDatasourceTypeEnum.fromDesc(value);
if (ObjectUtil.isNotNull(byType)) {
return true;
} else {
return false;
}
}
}
}
@@ -7,6 +7,7 @@ import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetParame
import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetSaveReqVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceSaveReqVO;
import com.cf.imes.module.report.controller.admin.template.vo.ReportTemplateSaveReqVO;
import com.cf.imes.module.report.enums.datasource.ReportDatasourceTypeEnum;
import com.cf.imes.module.report.enums.template.ReportTemplateTypeEnum;
import java.util.ArrayList;
@@ -31,6 +32,7 @@ public abstract class ReportCommonServiceImplTest {
.content(JsonUtil.zipString(TEMPLATE))
.type(ReportTemplateTypeEnum.SYSTEM.getType())
.remark(RandomUtils.randomString())
.datasource(new ArrayList<>())
.build();
}
@@ -40,12 +42,13 @@ public abstract class ReportCommonServiceImplTest {
.id(id)
.name("单元测试数据源")
.templateId(reportId)
.type("jdbc")
.type(ReportDatasourceTypeEnum.SPRING.getDesc())
.driver("com.mysql.cj.jdbc.Driver")
.url("jdbc:mysql://192.168.1.205:3307/imes_base?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true")
.username("root")
.password("root")
.remark(RandomUtils.randomString())
.datasets(new ArrayList<>())
.build();
}
@@ -4,7 +4,7 @@ import com.cf.imes.framework.test.core.util.RandomUtils;
import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetReqVO;
import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetSaveReqVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceSaveReqVO;
import com.cf.imes.module.report.controller.admin.template.vo.*;
import com.cf.imes.module.report.controller.admin.template.vo.ReportTemplateSaveReqVO;
import com.cf.imes.module.report.dal.dataobject.dataset.ReportDatasetDO;
import com.cf.imes.module.report.dal.dataobject.datasource.ReportDatasourceDO;
import com.cf.imes.module.report.dal.dataobject.template.ReportTemplateDO;
@@ -6,7 +6,7 @@ import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasource
import com.cf.imes.module.report.controller.admin.template.vo.ReportTemplateSaveReqVO;
import com.cf.imes.module.report.dal.dataobject.datasource.ReportDatasourceDO;
import com.cf.imes.module.report.dal.dataobject.template.ReportTemplateDO;
import com.cf.imes.module.report.enums.template.ReportTemplateTypeEnum;
import com.cf.imes.module.report.enums.datasource.ReportDatasourceTypeEnum;
import com.cf.imes.module.report.service.datasource.ReportDatasourceService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@@ -68,7 +68,7 @@ public class ReportDatasourceServiceImplTest extends ReportCommonServiceImplTest
// 列表查询参数准备
ReportDatasourceReqVO reqVO = new ReportDatasourceReqVO();
reqVO.setTemplateId(templateId);
reqVO.setType(ReportTemplateTypeEnum.SYSTEM.getType());
reqVO.setType(ReportDatasourceTypeEnum.JDBC.getCode());
reqVO.setName(updateReqVO.getName());
List<ReportDatasourceDO> templateDatasourceList = reportDatasourceService.getTemplateDatasourceList(reqVO);