完成 SN 溯源、销售管理和维修记录。

This commit is contained in:
c
2026-03-12 16:26:41 +08:00
parent a9d8c0f7e7
commit 8504fa121d
24 changed files with 574 additions and 499 deletions

View File

@@ -131,7 +131,7 @@ public class FinishedProductShipmentServiceImpl extends ServiceImpl<DocumentMapp
entity.setStatus(0); entity.setStatus(0);
// 根据出库类型设置不同的单据类型:物料出库使用 WAREHOUSE_ISSUE(4),成品出库使用 FINISHED_PRODUCT_SHIPMENT(7) // 根据出库类型设置不同的单据类型:物料出库使用 WAREHOUSE_ISSUE(4),成品出库使用 FINISHED_PRODUCT_SHIPMENT(7)
// 注意Spring 默认使用枚举的 ordinal 值转换,所以 1 对应 FINISHED_PRODUCT (ordinal=1),需要用 code 比较 // 注意Spring 默认使用枚举的 ordinal 值转换,所以 1 对应 FINISHED_PRODUCT (ordinal=1),需要用 code 比较
if (dto.outStockType() != null && dto.outStockType().getCode() == 1) { if ( dto.outStockType().getCode() == 1) {
entity.setFormType(DocumentType.WAREHOUSE_ISSUE); entity.setFormType(DocumentType.WAREHOUSE_ISSUE);
} else { } else {
entity.setFormType(DocumentType.FINISHED_PRODUCT_SHIPMENT); entity.setFormType(DocumentType.FINISHED_PRODUCT_SHIPMENT);
@@ -139,7 +139,7 @@ public class FinishedProductShipmentServiceImpl extends ServiceImpl<DocumentMapp
entity.setFormStatus(FormStatus.NO_APPROVE); entity.setFormStatus(FormStatus.NO_APPROVE);
entity.setTotalValue(Double.valueOf(shipmentItems.size())); entity.setTotalValue(Double.valueOf(shipmentItems.size()));
entity.setCustomerId(SecurityUtils.getCustomerId()); entity.setCustomerId(SecurityUtils.getCustomerId());
entity.setReserve1(dto.outStockType() != null ? dto.outStockType().getValue() : null); entity.setReserve1(dto.outStockType().getValue());
this.baseMapper.insert(entity); this.baseMapper.insert(entity);
List<DocumentMaterial> materialEntities = finishedProductShipmentConverter.toMaterialEntityList(shipmentItems); List<DocumentMaterial> materialEntities = finishedProductShipmentConverter.toMaterialEntityList(shipmentItems);

View File

@@ -1,30 +1,22 @@
package com.niuan.erp.module.sale.controller; package com.niuan.erp.module.sale.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.niuan.erp.common.annotation.ApiLog;
import com.niuan.erp.common.annotation.ModuleLog; import com.niuan.erp.common.annotation.ModuleLog;
import com.niuan.erp.common.base.BaseDeleteBody;
import com.niuan.erp.common.base.BasePageReqParams; import com.niuan.erp.common.base.BasePageReqParams;
import com.niuan.erp.common.base.BaseResult; import com.niuan.erp.common.base.BaseResult;
import com.niuan.erp.common.base.BaseSelectDto;
import com.niuan.erp.common.base.CommonValidateGroup.*; import com.niuan.erp.common.base.CommonValidateGroup.*;
import com.niuan.erp.common.base.OperationType; import com.niuan.erp.module.sale.controller.dto.DeviceQueryDto;
import com.niuan.erp.module.sale.controller.dto.DeviceDto; import com.niuan.erp.module.sale.controller.dto.DeviceResultDto;
import com.niuan.erp.module.sale.entity.Device;
import com.niuan.erp.module.sale.service.DeviceService; import com.niuan.erp.module.sale.service.DeviceService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List; @Tag(name = "SN溯源")
@ModuleLog("SN溯源管理")
@Tag(name = "Device")
@ModuleLog("Device管理")
@RestController @RestController
@RequestMapping("/sale/device") @RequestMapping("/sale/device")
@RequiredArgsConstructor @RequiredArgsConstructor
@@ -32,81 +24,11 @@ public class DeviceController {
private final DeviceService deviceService; private final DeviceService deviceService;
@Operation(summary = "分页查询Device数据", operationId = "getDevicePage") @Operation(summary = "分页查询SN溯源数据", operationId = "getDeviceSnPage")
@GetMapping("/getDevicePage") @GetMapping("/getDeviceSnPage")
@PreAuthorize("hasAuthority('device:index')") @PreAuthorize("hasAuthority('device_sn:index')")
public BaseResult<IPage<DeviceDto>> getDevicePage(@Validated BasePageReqParams pageParams, public BaseResult<IPage<DeviceResultDto>> getDeviceSnPage(@Validated BasePageReqParams pageParams,
@Validated(Get.class) DeviceDto searchParams) { @Validated(Get.class) DeviceQueryDto searchParams) {
var wrapper = new LambdaQueryWrapper<Device>(); return BaseResult.successWithData(deviceService.getDeviceSnPage(pageParams, searchParams));
if (searchParams != null) {
if (StringUtils.hasText(searchParams.searchCode())) {
wrapper.like(Device::getProductSn, searchParams.searchCode())
.or().like(Device::getMac, searchParams.searchCode());
}
if (searchParams.keyAccountId() != null) {
wrapper.eq(Device::getKeyAccountId, searchParams.keyAccountId());
}
if (searchParams.status() != null) {
wrapper.eq(Device::getStatus, searchParams.status());
}
if (searchParams.startDate() != null) {
wrapper.gt(Device::getCreateDate, searchParams.startDate());
}
if (searchParams.endDate() != null) {
wrapper.lt(Device::getCreateDate, searchParams.endDate());
}
if (StringUtils.hasText(searchParams.orderFiled())) {
boolean isDesc = "desc".equalsIgnoreCase(searchParams.orderByType());
if (isDesc) {
wrapper.orderByDesc(true, Device::getId);
} else {
wrapper.orderByAsc(true, Device::getId);
}
}
}
return BaseResult.successWithData(deviceService.getDevicePage(pageParams, wrapper));
}
@Operation(summary = "获取客户信息", operationId = "getKeyAccount")
@GetMapping("/getKeyAccount")
@PreAuthorize("hasAuthority('device:index')")
public BaseResult<List<BaseSelectDto>> getKeyAccount() {
return BaseResult.successWithData(deviceService.getKeyAccount());
}
@ApiLog(type = OperationType.ADD, remark = "新增一条Device记录")
@Operation(summary = "新增Device", operationId = "addDevice")
@PostMapping("/addDevice")
@PreAuthorize("hasAuthority('device:add')")
public BaseResult<?> addDevice(@Validated(Add.class) @RequestBody DeviceDto dto) {
deviceService.addDevice(dto);
return BaseResult.success();
}
@ApiLog(type = OperationType.UPDATE, remark = "更新一条Device记录")
@Operation(summary = "更新Device", operationId = "updateDevice")
@PostMapping("/updateDevice")
@PreAuthorize("hasAuthority('device:update')")
public BaseResult<?> updateDevice(@Validated(Update.class) @RequestBody DeviceDto dto) {
deviceService.updateDevice(dto);
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "删除一条Device记录")
@Operation(summary = "删除Device", operationId = "deleteDevice")
@PostMapping("/deleteDevice")
@PreAuthorize("hasAuthority('device:delete')")
public BaseResult<?> deleteDevice(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) {
deviceService.deleteDevice(req.id());
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "批量删除Device记录")
@Operation(summary = "批量删除Device", operationId = "deleteDeviceBatch")
@PostMapping("/deleteDeviceBatch")
@PreAuthorize("hasAuthority('device:deleteBatch')")
public BaseResult<?> deleteDeviceBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) {
deviceService.deleteBatch(req.ids());
return BaseResult.success();
} }
} }

View File

@@ -1,26 +1,25 @@
package com.niuan.erp.module.sale.controller; package com.niuan.erp.module.sale.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.niuan.erp.common.annotation.ApiLog; import com.niuan.erp.common.annotation.ApiLog;
import com.niuan.erp.common.annotation.ModuleLog; import com.niuan.erp.common.annotation.ModuleLog;
import com.niuan.erp.common.base.*; import com.niuan.erp.common.base.BasePageReqParams;
import com.niuan.erp.common.base.BaseResult;
import com.niuan.erp.common.base.CommonValidateGroup.*; import com.niuan.erp.common.base.CommonValidateGroup.*;
import com.niuan.erp.common.base.OperationType;
import com.niuan.erp.module.sale.controller.dto.RepairRecordDto; import com.niuan.erp.module.sale.controller.dto.RepairRecordDto;
import com.niuan.erp.module.sale.controller.dto.RepairRecordQueryDto;
import com.niuan.erp.module.sale.controller.dto.RepairRecordResultDto;
import com.niuan.erp.module.sale.service.RepairRecordService; import com.niuan.erp.module.sale.service.RepairRecordService;
import com.niuan.erp.module.sale.entity.RepairRecord;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import java.util.List; @Tag(name = "返修报表")
@ModuleLog("返修报表管理")
@Tag(name = "RepairRecord")
@ModuleLog("RepairRecord管理")
@RestController @RestController
@RequestMapping("/sale/repairrecord") @RequestMapping("/sale/repairrecord")
@RequiredArgsConstructor @RequiredArgsConstructor
@@ -28,46 +27,12 @@ public class RepairRecordController {
private final RepairRecordService repairRecordService; private final RepairRecordService repairRecordService;
@Operation(summary = "分页查询RepairRecord数据", operationId = "getRepairRecordPage") @Operation(summary = "分页查询返修报表数据", operationId = "getRepairReportPage")
@GetMapping("/getRepairRecordPage") @GetMapping("/getRepairReportPage")
@PreAuthorize("hasAuthority('repair_record:index')") @PreAuthorize("hasAuthority('repair_record:index')")
public BaseResult<IPage<RepairRecordDto>> getRepairRecordPage(@Validated BasePageReqParams pageParams, public BaseResult<IPage<RepairRecordResultDto>> getRepairReportPage(@Validated BasePageReqParams pageParams,
@Validated(Get.class) RepairRecordDto searchParams) { @Validated(Get.class) RepairRecordQueryDto searchParams) {
var wrapper = new LambdaQueryWrapper<RepairRecord>(); return BaseResult.successWithData(repairRecordService.getRepairReportPage(pageParams, searchParams));
if (searchParams != null) {
if (StringUtils.hasText(searchParams.searchCode())) {
wrapper.like(RepairRecord::getProductSn, searchParams.searchCode())
.or().like(RepairRecord::getMac, searchParams.searchCode());
}
if (searchParams.keyAccountIdSearch() != null) {
wrapper.eq(RepairRecord::getKeyAccountId, searchParams.keyAccountIdSearch());
}
if (searchParams.status() != null) {
wrapper.eq(RepairRecord::getStatus, searchParams.status());
}
if (searchParams.startDate() != null) {
wrapper.gt(RepairRecord::getCreateDate, searchParams.startDate());
}
if (searchParams.endDate() != null) {
wrapper.lt(RepairRecord::getCreateDate, searchParams.endDate());
}
if (StringUtils.hasText(searchParams.orderFiled())) {
boolean isDesc = "desc".equalsIgnoreCase(searchParams.orderByType());
if (isDesc) {
wrapper.orderByDesc(true, RepairRecord::getId);
} else {
wrapper.orderByAsc(true, RepairRecord::getId);
}
}
}
return BaseResult.successWithData(repairRecordService.getRepairRecordPage(pageParams, wrapper));
}
@Operation(summary = "获取客户信息", operationId = "getKeyAccount")
@GetMapping("/getKeyAccount")
@PreAuthorize("hasAuthority('repair_record:index')")
public BaseResult<List<BaseSelectDto>> getKeyAccount() {
return BaseResult.successWithData(repairRecordService.getKeyAccount());
} }
@ApiLog(type = OperationType.ADD, remark = "新增一条RepairRecord记录") @ApiLog(type = OperationType.ADD, remark = "新增一条RepairRecord记录")
@@ -78,31 +43,4 @@ public class RepairRecordController {
repairRecordService.addRepairRecord(dto); repairRecordService.addRepairRecord(dto);
return BaseResult.success(); return BaseResult.success();
} }
@ApiLog(type = OperationType.UPDATE, remark = "更新一条RepairRecord记录")
@Operation(summary = "更新RepairRecord", operationId = "updateRepairRecord")
@PostMapping("/updateRepairRecord")
@PreAuthorize("hasAuthority('repair_record:update')")
public BaseResult<?> updateRepairRecord(@Validated(Update.class) @RequestBody RepairRecordDto dto) {
repairRecordService.updateRepairRecord(dto);
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "删除一条RepairRecord记录")
@Operation(summary = "删除RepairRecord", operationId = "deleteRepairRecord")
@PostMapping("/deleteRepairRecord")
@PreAuthorize("hasAuthority('repair_record:delete')")
public BaseResult<?> deleteRepairRecord(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) {
repairRecordService.deleteRepairRecord(req.id());
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "批量删除RepairRecord记录")
@Operation(summary = "批量删除RepairRecord", operationId = "deleteRepairRecordBatch")
@PostMapping("/deleteRepairRecordBatch")
@PreAuthorize("hasAuthority('repair_record:deleteBatch')")
public BaseResult<?> deleteRepairRecordBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) {
repairRecordService.deleteBatch(req.ids());
return BaseResult.success();
}
} }

View File

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.niuan.erp.common.annotation.ApiLog; import com.niuan.erp.common.annotation.ApiLog;
import com.niuan.erp.common.annotation.ModuleLog; import com.niuan.erp.common.annotation.ModuleLog;
import com.niuan.erp.common.base.BaseApproveAndRejectDto;
import com.niuan.erp.common.base.BaseDeleteBody; import com.niuan.erp.common.base.BaseDeleteBody;
import com.niuan.erp.common.base.BasePageReqParams; import com.niuan.erp.common.base.BasePageReqParams;
import com.niuan.erp.common.base.BaseResult; import com.niuan.erp.common.base.BaseResult;
@@ -13,6 +14,7 @@ import com.niuan.erp.module.common.entity.Document;
import com.niuan.erp.module.sale.controller.dto.SaleOrderAddDto; import com.niuan.erp.module.sale.controller.dto.SaleOrderAddDto;
import com.niuan.erp.module.sale.controller.dto.SaleOrderDto; import com.niuan.erp.module.sale.controller.dto.SaleOrderDto;
import com.niuan.erp.module.sale.controller.dto.SaleOrderItemDto; import com.niuan.erp.module.sale.controller.dto.SaleOrderItemDto;
import com.niuan.erp.module.sale.controller.dto.SaleOrderUpdateDto;
import com.niuan.erp.module.sale.service.SaleOrderService; import com.niuan.erp.module.sale.service.SaleOrderService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
@@ -26,8 +28,8 @@ import org.springframework.web.multipart.MultipartFile;
import java.util.List; import java.util.List;
@Tag(name = "SaleOrder") @Tag(name = "销售订单")
@ModuleLog("SaleOrder管理") @ModuleLog("销售订单管理")
@RestController @RestController
@RequestMapping("/sale/saleorder") @RequestMapping("/sale/saleorder")
@RequiredArgsConstructor @RequiredArgsConstructor
@@ -35,23 +37,23 @@ public class SaleOrderController {
private final SaleOrderService saleOrderService; private final SaleOrderService saleOrderService;
@Operation(summary = "分页查询SaleOrder数据", operationId = "getSaleOrderPage") @Operation(summary = "分页查询销售订单数据", operationId = "getSaleOrderPage")
@GetMapping("/getSaleOrderPage") @GetMapping("/getSaleOrderPage")
@PreAuthorize("hasAuthority('sale_order:index')") @PreAuthorize("hasAuthority('sale_order:index')")
public BaseResult<IPage<SaleOrderDto>> getSaleOrderPage(@Validated BasePageReqParams pageParams, public BaseResult<IPage<SaleOrderDto>> getSaleOrderPage(@Validated BasePageReqParams pageParams,
@Validated(Get.class) SaleOrderDto searchParams) { @Validated(Get.class) SaleOrderDto searchParams) {
var wrapper = new LambdaQueryWrapper<Document>(); var wrapper = new LambdaQueryWrapper<Document>();
if (searchParams != null) { if (searchParams != null) {
if (StringUtils.hasText(searchParams.customerName())) { if (StringUtils.hasText(searchParams.customerName())) {
wrapper.like(Document::getCustomerId, searchParams.customerId()); wrapper.like(Document::getStoreName, searchParams.customerName());
}
} }
}
return BaseResult.successWithData(saleOrderService.getSaleOrderPage(pageParams, wrapper)); return BaseResult.successWithData(saleOrderService.getSaleOrderPage(pageParams, wrapper));
} }
@ApiLog(type = OperationType.ADD, remark = "新增一条SaleOrder记录") @ApiLog(type = OperationType.ADD, remark = "新增一条销售订单记录")
@Operation(summary = "新增SaleOrder", operationId = "addSaleOrder") @Operation(summary = "新增销售订单", operationId = "addSaleOrder")
@PostMapping("/addSaleOrder") @PostMapping("/addSaleOrder")
@PreAuthorize("hasAuthority('sale_order:add')") @PreAuthorize("hasAuthority('sale_order:add')")
public BaseResult<?> addSaleOrder(@Validated(Add.class) @RequestBody SaleOrderAddDto dto) { public BaseResult<?> addSaleOrder(@Validated(Add.class) @RequestBody SaleOrderAddDto dto) {
@@ -59,62 +61,60 @@ public class SaleOrderController {
return BaseResult.success(); return BaseResult.success();
} }
@ApiLog(type = OperationType.UPDATE, remark = "更新一条SaleOrder记录") @ApiLog(type = OperationType.UPDATE, remark = "更新一条销售订单记录")
@Operation(summary = "更新SaleOrder", operationId = "updateSaleOrder") @Operation(summary = "更新销售订单", operationId = "updateSaleOrder")
@PostMapping("/updateSaleOrder") @PostMapping("/updateSaleOrder")
@PreAuthorize("hasAuthority('sale_order:update')") @PreAuthorize("hasAuthority('sale_order:edit')")
public BaseResult<?> updateSaleOrder(@Validated(Update.class) @RequestBody SaleOrderDto dto) { public BaseResult<?> updateSaleOrder(@Validated(Update.class) @RequestBody SaleOrderUpdateDto dto) {
saleOrderService.updateSaleOrder(dto); saleOrderService.updateSaleOrder(dto);
return BaseResult.success(); return BaseResult.success();
} }
@ApiLog(type = OperationType.DELETE, remark = "删除一条SaleOrder记录") @ApiLog(type = OperationType.DELETE, remark = "删除一条销售订单记录")
@Operation(summary = "删除SaleOrder", operationId = "deleteSaleOrder") @Operation(summary = "删除销售订单", operationId = "deleteSaleOrder")
@PostMapping("/deleteSaleOrder") @PostMapping("/deleteSaleOrder")
@PreAuthorize("hasAuthority('sale_order:delete')") @PreAuthorize("hasAuthority('sale_order:remove')")
public BaseResult<?> deleteSaleOrder(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) { public BaseResult<?> deleteSaleOrder(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) {
saleOrderService.deleteSaleOrder(req.id()); saleOrderService.deleteSaleOrder(req.id());
return BaseResult.success(); return BaseResult.success();
} }
@ApiLog(type = OperationType.DELETE, remark = "批量删除SaleOrder记录") @ApiLog(type = OperationType.DELETE, remark = "批量删除销售订单记录")
@Operation(summary = "批量删除SaleOrder", operationId = "deleteSaleOrderBatch") @Operation(summary = "批量删除销售订单", operationId = "deleteSaleOrderBatch")
@PostMapping("/deleteSaleOrderBatch") @PostMapping("/deleteSaleOrderBatch")
@PreAuthorize("hasAuthority('sale_order:deleteBatch')") @PreAuthorize("hasAuthority('sale_order:remove')")
public BaseResult<?> deleteSaleOrderBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) { public BaseResult<?> deleteSaleOrderBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) {
saleOrderService.deleteBatch(req.ids()); saleOrderService.deleteBatch(req.ids());
return BaseResult.success(); return BaseResult.success();
} }
@ApiLog(type = OperationType.UPDATE, remark = "审核SaleOrder") @ApiLog(type = OperationType.UPDATE, remark = "审核销售订单")
@Operation(summary = "审核SaleOrder", operationId = "approveSaleOrder") @Operation(summary = "审核销售订单", operationId = "approveSaleOrder")
@PostMapping("/approveSaleOrder") @PostMapping("/approveSaleOrder")
@PreAuthorize("hasAuthority('sale_order:approve')") @PreAuthorize("hasAuthority('sale_order:approve')")
public BaseResult<?> approveSaleOrder( public BaseResult<?> approveSaleOrder(@Validated @RequestBody BaseApproveAndRejectDto dto) {
@Parameter(description = "销售订单ID") @RequestParam Long id) { saleOrderService.approve(dto.id());
saleOrderService.approve(id);
return BaseResult.success(); return BaseResult.success();
} }
@ApiLog(type = OperationType.UPDATE, remark = "反审核SaleOrder") @ApiLog(type = OperationType.UPDATE, remark = "反审核销售订单")
@Operation(summary = "反审核SaleOrder", operationId = "unapproveSaleOrder") @Operation(summary = "反审核销售订单", operationId = "unapproveSaleOrder")
@PostMapping("/unapproveSaleOrder") @PostMapping("/unapproveSaleOrder")
@PreAuthorize("hasAuthority('sale_order:unapprove')") @PreAuthorize("hasAuthority('sale_order:reject')")
public BaseResult<?> unapproveSaleOrder( public BaseResult<?> unapproveSaleOrder(@Validated @RequestBody BaseApproveAndRejectDto dto) {
@Parameter(description = "销售订单ID") @RequestParam Long id) { saleOrderService.unapprove(dto.id());
saleOrderService.unapprove(id);
return BaseResult.success(); return BaseResult.success();
} }
@Operation(summary = "获取SaleOrder明细", operationId = "getSaleOrderDetail") @Operation(summary = "获取销售订单明细列表", operationId = "getSaleOrderItemList")
@GetMapping("/getSaleOrderDetail") @GetMapping("/getSaleOrderItemList")
@PreAuthorize("hasAuthority('saleorder:index')") @PreAuthorize("hasAuthority('sale_order:showItem')")
public BaseResult<List<SaleOrderItemDto>> getSaleOrderDetail( public BaseResult<List<SaleOrderItemDto>> getSaleOrderItemList(
@Parameter(description = "销售订单ID") @RequestParam Long id) { @Parameter(description = "销售订单ID") @RequestParam("saleOrderId") Long saleOrderId) {
return BaseResult.successWithData(saleOrderService.getDetail(id)); return BaseResult.successWithData(saleOrderService.getDetail(saleOrderId));
} }
@Operation(summary = "导入SaleOrder明细", operationId = "importSaleOrderItems") @Operation(summary = "导入销售订单明细", operationId = "importSaleOrderItems")
@PostMapping("/importSaleOrderItems") @PostMapping("/importSaleOrderItems")
@PreAuthorize("hasAuthority('sale_order:import')") @PreAuthorize("hasAuthority('sale_order:import')")
public BaseResult<List<SaleOrderItemDto>> importSaleOrderItems( public BaseResult<List<SaleOrderItemDto>> importSaleOrderItems(

View File

@@ -4,27 +4,9 @@ import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@Schema(description = "设备DTO") @Schema(description = "SN溯源DTO")
public record DeviceDto( public record DeviceDto(
@Schema(description = "ID") @Schema(description = "产品类型/型号")
Long id,
@Schema(description = "状态")
Integer status,
@Schema(description = "创建时间")
LocalDateTime createDate,
@Schema(description = "创建用户ID")
Long createUserId,
@Schema(description = "创建用户名")
String createUserName,
@Schema(description = "更新时间")
LocalDateTime updateDate,
@Schema(description = "更新用户ID")
Long updateUserId,
@Schema(description = "更新用户名")
String updateUserName,
@Schema(description = "单据编号")
Integer documentNo,
@Schema(description = "产品类型")
String productType, String productType,
@Schema(description = "产品SN") @Schema(description = "产品SN")
String productSn, String productSn,
@@ -34,36 +16,10 @@ public record DeviceDto(
String serialNum, String serialNum,
@Schema(description = "软件版本") @Schema(description = "软件版本")
String softVersion, String softVersion,
@Schema(description = "AL版本") @Schema(description = "算法版本")
String alVersion, String alVersion,
@Schema(description = "AL编号") @Schema(description = "出库日期/出货日期")
String alNum,
@Schema(description = "AL状态")
Boolean alStatus,
@Schema(description = "维修状态")
Integer repairStatus,
@Schema(description = "备注")
String mark,
@Schema(description = "客户ID")
Integer customerId,
@Schema(description = "出库状态")
Boolean outStatus,
@Schema(description = "出库日期")
LocalDateTime outProductDate, LocalDateTime outProductDate,
@Schema(description = "维修备注") @Schema(description = "返修记录拼接字符串")
String repairMark, String repairRecords
@Schema(description = "产品SN显示")
String productSnDisplay,
@Schema(description = "搜索代码")
String searchCode,
@Schema(description = "客户ID")
Integer keyAccountId,
@Schema(description = "开始日期")
LocalDateTime startDate,
@Schema(description = "结束日期")
LocalDateTime endDate,
@Schema(description = "排序字段")
String orderFiled,
@Schema(description = "排序类型")
String orderByType
) {} ) {}

View File

@@ -4,60 +4,26 @@ import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@Schema(description = "返修记录DTO") @Schema(description = "返修报表DTO")
public record RepairRecordDto( public record RepairRecordDto(
@Schema(description = "ID") @Schema(description = "产品类型/型号")
Long id,
@Schema(description = "状态")
Integer status,
@Schema(description = "创建时间")
LocalDateTime createDate,
@Schema(description = "创建用户ID")
Long createUserId,
@Schema(description = "创建用户名")
String createUserName,
@Schema(description = "更新时间")
LocalDateTime updateDate,
@Schema(description = "更新用户ID")
Long updateUserId,
@Schema(description = "更新用户名")
String updateUserName,
@Schema(description = "产品类型")
String productType, String productType,
@Schema(description = "产品SN") @Schema(description = "产品SN")
String productSn, String productSn,
@Schema(description = "MAC地址") @Schema(description = "MAC地址")
String mac, String mac,
@Schema(description = "维修状态") @Schema(description = "序列号")
Integer repairStatus, String serialNum,
@Schema(description = "备注") @Schema(description = "软件版本")
String mark, String softVersion,
@Schema(description = "保留字段1") @Schema(description = "算法版本")
Integer reserve1, String alVersion,
@Schema(description = "保留字段2") @Schema(description = "出库日期/出货日期")
String reserve2,
@Schema(description = "客户ID")
Integer keyAccountId,
@Schema(description = "客户ID")
Integer customerId,
@Schema(description = "出库状态")
Boolean outStatus,
@Schema(description = "出库日期")
LocalDateTime outProductDate, LocalDateTime outProductDate,
@Schema(description = "维修日期") @Schema(description = "创建时间")
LocalDateTime repairDate, LocalDateTime createDate,
@Schema(description = "维修备注") @Schema(description = "维修次数")
String repairMark, Integer repairCount,
@Schema(description = "搜索代码") @Schema(description = "返修记录")
String searchCode, String repairMark
@Schema(description = "客户ID")
Integer keyAccountIdSearch,
@Schema(description = "开始日期")
LocalDateTime startDate,
@Schema(description = "结束日期")
LocalDateTime endDate,
@Schema(description = "排序字段")
String orderFiled,
@Schema(description = "排序类型")
String orderByType
) {} ) {}

View File

@@ -1,30 +1,21 @@
package com.niuan.erp.module.sale.controller.dto; package com.niuan.erp.module.sale.controller.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/**
* 销售订单返回 DTO - 前端展示用
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public record SaleOrderDto( public record SaleOrderDto(
Long id, Long id,
Integer status,
LocalDateTime createDate, LocalDateTime createDate,
Long createUserId,
String createUserName,
LocalDateTime updateDate,
Long updateUserId,
String updateUserName,
Integer storeNo,
String storeName,
Integer formType,
String formCode, String formCode,
String formName, String formName,
Integer formStatus,
String formMark, String formMark,
Integer reserve1, Integer formStatus,
String reserve2,
Integer vendorNo,
String vendorName,
Double totalValue,
Integer outStoreNo,
String outStoreName,
Integer groupId,
Integer customerId, Integer customerId,
String customerName) {} String customerName,
Double totalValue
) {}

View File

@@ -1,24 +1,18 @@
package com.niuan.erp.module.sale.controller.dto; package com.niuan.erp.module.sale.controller.dto;
import java.time.LocalDateTime; import com.fasterxml.jackson.annotation.JsonInclude;
/**
* 销售订单明细返回 DTO - 前端展示用
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public record SaleOrderItemDto( public record SaleOrderItemDto(
Long id, Long id,
Integer status,
LocalDateTime createDate,
Long createUserId,
String createUserName,
LocalDateTime updateDate,
Long updateUserId,
String updateUserName,
Integer documentNo,
String documentCode,
String projectName,
String partNumber, String partNumber,
String productSpecs,
Integer saleCount, Integer saleCount,
Double price, Double price,
Double totalPrice, Double totalPrice,
Integer sendCount, Integer sendCount,
String saleMark, String saleMark
Integer reserve1, ) {}
String reserve2) {}

View File

@@ -1,26 +1,39 @@
package com.niuan.erp.module.sale.converter; package com.niuan.erp.module.sale.converter;
import com.niuan.erp.module.common.entity.Document; import com.niuan.erp.module.common.entity.Document;
import com.niuan.erp.module.sale.controller.dto.SaleOrderAddDto;
import com.niuan.erp.module.sale.controller.dto.SaleOrderDto; import com.niuan.erp.module.sale.controller.dto.SaleOrderDto;
import com.niuan.erp.module.sale.controller.dto.SaleOrderItemAddDto;
import com.niuan.erp.module.sale.controller.dto.SaleOrderItemDto; import com.niuan.erp.module.sale.controller.dto.SaleOrderItemDto;
import com.niuan.erp.module.sale.entity.SaleOrderItem; import com.niuan.erp.module.sale.entity.SaleOrderItem;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.ReportingPolicy; import org.mapstruct.ReportingPolicy;
import java.util.List; import java.util.List;
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface SaleOrderConverter { public interface SaleOrderConverter {
Document toEntity(SaleOrderDto dto);
Document toEntity(SaleOrderAddDto dto); @Mapping(source = "id", target = "id")
@Mapping(source = "createDate", target = "createDate")
@Mapping(source = "formCode", target = "formCode")
@Mapping(source = "formName", target = "formName")
@Mapping(source = "formMark", target = "formMark")
@Mapping(source = "formStatus.value", target = "formStatus")
@Mapping(source = "customerId", target = "customerId")
@Mapping(source = "storeName", target = "customerName")
@Mapping(source = "totalValue", target = "totalValue")
SaleOrderDto toDto(Document entity); SaleOrderDto toDto(Document entity);
List<SaleOrderDto> toDtoList(List<Document> entities); List<SaleOrderDto> toDtoList(List<Document> entities);
SaleOrderItem toEntity(SaleOrderItemAddDto dto); @Mapping(source = "id", target = "id")
List<SaleOrderItem> toEntityList(List<SaleOrderItemAddDto> dtoList); @Mapping(source = "partNumber", target = "partNumber")
@Mapping(source = "saleCount", target = "saleCount")
@Mapping(source = "price", target = "price")
@Mapping(source = "totalPrice", target = "totalPrice")
@Mapping(source = "sendCount", target = "sendCount")
@Mapping(source = "saleMark", target = "saleMark")
SaleOrderItemDto toDto(SaleOrderItem entity); SaleOrderItemDto toDto(SaleOrderItem entity);
List<SaleOrderItemDto> toSaleOrderItemDtoList(List<SaleOrderItem> entities); List<SaleOrderItemDto> toSaleOrderItemDtoList(List<SaleOrderItem> entities);
} }

View File

@@ -1,9 +1,20 @@
package com.niuan.erp.module.sale.mapper; package com.niuan.erp.module.sale.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.niuan.erp.module.sale.controller.dto.DeviceResultDto;
import com.niuan.erp.module.sale.entity.Device; import com.niuan.erp.module.sale.entity.Device;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper @Mapper
public interface DeviceMapper extends BaseMapper<Device> { public interface DeviceMapper extends BaseMapper<Device> {
/**
* SN溯源分页查询
*/
IPage<DeviceResultDto> selectDeviceSnPage(Page<DeviceResultDto> page,
@Param("searchCode") String searchCode,
@Param("keyAccountId") Integer keyAccountId);
} }

View File

@@ -1,7 +1,11 @@
package com.niuan.erp.module.sale.mapper; package com.niuan.erp.module.sale.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.niuan.erp.module.sale.controller.dto.RepairRecordResultDto;
import com.niuan.erp.module.sale.entity.RepairRecord; import com.niuan.erp.module.sale.entity.RepairRecord;
import org.apache.ibatis.annotations.Param;
/** /**
* <p> * <p>
@@ -13,4 +17,10 @@ import com.niuan.erp.module.sale.entity.RepairRecord;
*/ */
public interface RepairRecordMapper extends BaseMapper<RepairRecord> { public interface RepairRecordMapper extends BaseMapper<RepairRecord> {
/**
* 返修报表分页查询
*/
IPage<RepairRecordResultDto> selectRepairReportPage(Page<RepairRecordResultDto> page,
@Param("searchCode") String searchCode,
@Param("keyAccountIdSearch") Integer keyAccountIdSearch);
} }

View File

@@ -1,25 +1,11 @@
package com.niuan.erp.module.sale.service; package com.niuan.erp.module.sale.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.niuan.erp.common.base.BasePageReqParams; import com.niuan.erp.common.base.BasePageReqParams;
import com.niuan.erp.common.base.BaseSelectDto; import com.niuan.erp.module.sale.controller.dto.DeviceQueryDto;
import com.niuan.erp.module.sale.controller.dto.DeviceDto; import com.niuan.erp.module.sale.controller.dto.DeviceResultDto;
import com.niuan.erp.module.sale.entity.Device;
import java.util.List;
public interface DeviceService { public interface DeviceService {
IPage<DeviceDto> getDevicePage(BasePageReqParams pageParams, LambdaQueryWrapper<Device> wrapper); IPage<DeviceResultDto> getDeviceSnPage(BasePageReqParams pageParams, DeviceQueryDto searchParams);
void addDevice(DeviceDto dto);
void updateDevice(DeviceDto dto);
void deleteDevice(long id);
void deleteBatch(List<Long> ids);
List<BaseSelectDto> getKeyAccount();
} }

View File

@@ -1,25 +1,14 @@
package com.niuan.erp.module.sale.service; package com.niuan.erp.module.sale.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.niuan.erp.common.base.BasePageReqParams; import com.niuan.erp.common.base.BasePageReqParams;
import com.niuan.erp.common.base.BaseSelectDto;
import com.niuan.erp.module.sale.controller.dto.RepairRecordDto; import com.niuan.erp.module.sale.controller.dto.RepairRecordDto;
import com.niuan.erp.module.sale.entity.RepairRecord; import com.niuan.erp.module.sale.controller.dto.RepairRecordQueryDto;
import com.niuan.erp.module.sale.controller.dto.RepairRecordResultDto;
import java.util.List;
public interface RepairRecordService { public interface RepairRecordService {
IPage<RepairRecordDto> getRepairRecordPage(BasePageReqParams pageParams, LambdaQueryWrapper<RepairRecord> wrapper); IPage<RepairRecordResultDto> getRepairReportPage(BasePageReqParams pageParams, RepairRecordQueryDto searchParams);
void addRepairRecord(RepairRecordDto dto); void addRepairRecord(RepairRecordDto dto);
void updateRepairRecord(RepairRecordDto dto);
void deleteRepairRecord(long id);
void deleteBatch(List<Long> ids);
List<BaseSelectDto> getKeyAccount();
} }

View File

@@ -7,6 +7,7 @@ import com.niuan.erp.module.common.entity.Document;
import com.niuan.erp.module.sale.controller.dto.SaleOrderAddDto; import com.niuan.erp.module.sale.controller.dto.SaleOrderAddDto;
import com.niuan.erp.module.sale.controller.dto.SaleOrderDto; import com.niuan.erp.module.sale.controller.dto.SaleOrderDto;
import com.niuan.erp.module.sale.controller.dto.SaleOrderItemDto; import com.niuan.erp.module.sale.controller.dto.SaleOrderItemDto;
import com.niuan.erp.module.sale.controller.dto.SaleOrderUpdateDto;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.util.List; import java.util.List;
@@ -17,7 +18,7 @@ public interface SaleOrderService {
void addSaleOrder(SaleOrderAddDto dto); void addSaleOrder(SaleOrderAddDto dto);
void updateSaleOrder(SaleOrderDto dto); void updateSaleOrder(SaleOrderUpdateDto dto);
void deleteSaleOrder(long id); void deleteSaleOrder(long id);

View File

@@ -1,24 +1,18 @@
package com.niuan.erp.module.sale.service.impl; package com.niuan.erp.module.sale.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.niuan.erp.common.base.BasePageReqParams; import com.niuan.erp.common.base.BasePageReqParams;
import com.niuan.erp.common.base.BaseSelectDto; import com.niuan.erp.common.exception.BusinessException;
import com.niuan.erp.common.utils.SecurityUtils; import com.niuan.erp.module.sale.controller.dto.DeviceQueryDto;
import com.niuan.erp.module.sale.controller.dto.DeviceDto; import com.niuan.erp.module.sale.controller.dto.DeviceResultDto;
import com.niuan.erp.module.sale.converter.DeviceConverter;
import com.niuan.erp.module.sale.entity.Device; import com.niuan.erp.module.sale.entity.Device;
import com.niuan.erp.module.sale.mapper.DeviceMapper; import com.niuan.erp.module.sale.mapper.DeviceMapper;
import com.niuan.erp.module.sale.service.DeviceService; import com.niuan.erp.module.sale.service.DeviceService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.List;
@Service @Service
@@ -26,53 +20,16 @@ import java.util.List;
@RequiredArgsConstructor @RequiredArgsConstructor
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements DeviceService { public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements DeviceService {
private final DeviceConverter deviceConverter;
@Override @Override
public IPage<DeviceDto> getDevicePage(BasePageReqParams pageParams, LambdaQueryWrapper<Device> wrapper) { public IPage<DeviceResultDto> getDeviceSnPage(BasePageReqParams pageParams, DeviceQueryDto searchParams) {
IPage<Device> result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper); if (pageParams == null) {
return result.convert(deviceConverter::toDto); throw new BusinessException("common.validate.page_params.not_null");
} }
String searchCode = searchParams != null ? searchParams.searchCode() : null;
@Override Integer keyAccountId = searchParams != null ? searchParams.keyAccountId() : null;
public void addDevice(DeviceDto dto) { return this.baseMapper.selectDeviceSnPage(
Device entity = deviceConverter.toEntity(dto); new Page<>(pageParams.page(), pageParams.pageSize()),
entity.setCreateUserId(SecurityUtils.getUserId()); searchCode,
entity.setCreateUserName(SecurityUtils.getUserName()); keyAccountId);
entity.setCreateDate(LocalDateTime.now());
entity.setStatus(0);
this.baseMapper.insert(entity);
}
@Override
public void updateDevice(DeviceDto dto) {
Device entity = deviceConverter.toEntity(dto);
entity.setUpdateUserId(SecurityUtils.getUserId());
entity.setUpdateUserName(SecurityUtils.getUserName());
entity.setUpdateDate(LocalDateTime.now());
this.baseMapper.updateById(entity);
}
@Override
public void deleteDevice(long id) {
this.baseMapper.deleteById(id);
}
@Override
public void deleteBatch(List<Long> ids) {
this.baseMapper.deleteBatchIds(ids);
}
@Override
public List<BaseSelectDto> getKeyAccount() {
LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<>();
wrapper.select(Device::getKeyAccountId);
wrapper.isNotNull(Device::getKeyAccountId);
wrapper.groupBy(Device::getKeyAccountId);
List<Device> devices = this.baseMapper.selectList(wrapper);
return devices.stream()
.map(device -> new BaseSelectDto(device.getKeyAccountId().toString(), device.getKeyAccountId().toString()))
.toList();
} }
} }

View File

@@ -5,19 +5,22 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.niuan.erp.common.base.BasePageReqParams; import com.niuan.erp.common.base.BasePageReqParams;
import com.niuan.erp.common.base.BaseSelectDto; import com.niuan.erp.common.exception.BusinessException;
import com.niuan.erp.common.utils.SecurityUtils; import com.niuan.erp.common.utils.SecurityUtils;
import com.niuan.erp.module.sale.controller.dto.RepairRecordDto; import com.niuan.erp.module.sale.controller.dto.RepairRecordDto;
import com.niuan.erp.module.sale.converter.RepairRecordConverter; import com.niuan.erp.module.sale.controller.dto.RepairRecordQueryDto;
import com.niuan.erp.module.sale.controller.dto.RepairRecordResultDto;
import com.niuan.erp.module.sale.entity.Device;
import com.niuan.erp.module.sale.entity.RepairRecord; import com.niuan.erp.module.sale.entity.RepairRecord;
import com.niuan.erp.module.sale.mapper.DeviceMapper;
import com.niuan.erp.module.sale.mapper.RepairRecordMapper; import com.niuan.erp.module.sale.mapper.RepairRecordMapper;
import com.niuan.erp.module.sale.service.RepairRecordService; import com.niuan.erp.module.sale.service.RepairRecordService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
@Service @Service
@@ -25,53 +28,101 @@ import java.util.List;
@RequiredArgsConstructor @RequiredArgsConstructor
public class RepairRecordServiceImpl extends ServiceImpl<RepairRecordMapper, RepairRecord> implements RepairRecordService { public class RepairRecordServiceImpl extends ServiceImpl<RepairRecordMapper, RepairRecord> implements RepairRecordService {
private final DeviceMapper deviceMapper;
private final RepairRecordConverter repairRecordConverter;
@Override @Override
public IPage<RepairRecordDto> getRepairRecordPage(BasePageReqParams pageParams, LambdaQueryWrapper<RepairRecord> wrapper) { public IPage<RepairRecordResultDto> getRepairReportPage(BasePageReqParams pageParams, RepairRecordQueryDto searchParams) {
IPage<RepairRecord> result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper); if (pageParams == null) {
return result.convert(repairRecordConverter::toDto); throw new BusinessException("common.validate.page_params.not_null");
}
String searchCode = searchParams != null ? searchParams.searchCode() : null;
Integer keyAccountIdSearch = searchParams != null ? searchParams.keyAccountIdSearch() : null;
return this.baseMapper.selectRepairReportPage(
new Page<>(pageParams.page(), pageParams.pageSize()),
searchCode,
keyAccountIdSearch);
} }
@Override @Override
public void addRepairRecord(RepairRecordDto dto) { public void addRepairRecord(RepairRecordDto dto) {
RepairRecord entity = repairRecordConverter.toEntity(dto); // 从 Device 查询补充信息
Device device = findDevice(dto);
// 构建 RepairRecord 实体
RepairRecord entity = new RepairRecord();
entity.setProductSn(StringUtils.hasText(dto.productSn()) ? dto.productSn() : (device != null ? device.getProductSn() : null));
entity.setMac(StringUtils.hasText(dto.mac()) ? dto.mac() : (device != null ? device.getMac() : null));
entity.setProductType(StringUtils.hasText(dto.productType()) ? dto.productType() : (device != null ? device.getProductType() : null));
entity.setOutProductDate(dto.outProductDate() != null ? dto.outProductDate() : (device != null ? device.getOutProductDate() : null));
entity.setRepairMark(dto.repairMark());
entity.setCreateUserId(SecurityUtils.getUserId()); entity.setCreateUserId(SecurityUtils.getUserId());
entity.setCreateUserName(SecurityUtils.getUserName()); entity.setCreateUserName(SecurityUtils.getUserName());
entity.setCreateDate(LocalDateTime.now()); entity.setCreateDate(LocalDateTime.now());
entity.setStatus(0); entity.setStatus(0);
// 设置客户ID从 Device 获取)
if (device != null && device.getKeyAccountId() != null) {
entity.setKeyAccountId(device.getKeyAccountId());
}
this.baseMapper.insert(entity); this.baseMapper.insert(entity);
// 更新 Device 信息(前端有值则覆盖)
if (device != null) {
updateDeviceInfo(dto, device);
}
} }
@Override private Device findDevice(RepairRecordDto dto) {
public void updateRepairRecord(RepairRecordDto dto) { LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<>();
RepairRecord entity = repairRecordConverter.toEntity(dto); if (StringUtils.hasText(dto.productSn())) {
entity.setUpdateUserId(SecurityUtils.getUserId()); wrapper.eq(Device::getProductSn, dto.productSn());
entity.setUpdateUserName(SecurityUtils.getUserName()); } else if (StringUtils.hasText(dto.mac())) {
entity.setUpdateDate(LocalDateTime.now()); wrapper.eq(Device::getMac, dto.mac());
this.baseMapper.updateById(entity); } else if (StringUtils.hasText(dto.serialNum())) {
wrapper.eq(Device::getSerialNum, dto.serialNum());
} else {
return null;
}
// MAC可能重复取第一条
wrapper.orderByAsc(Device::getId);
wrapper.last("LIMIT 1");
return deviceMapper.selectOne(wrapper);
} }
@Override private void updateDeviceInfo(RepairRecordDto dto, Device device) {
public void deleteRepairRecord(long id) { boolean updated = false;
this.baseMapper.deleteById(id);
}
@Override if (StringUtils.hasText(dto.productType())) {
public void deleteBatch(List<Long> ids) { device.setProductType(dto.productType());
this.baseMapper.deleteBatchIds(ids); updated = true;
} }
if (StringUtils.hasText(dto.mac())) {
device.setMac(dto.mac());
updated = true;
}
if (StringUtils.hasText(dto.serialNum())) {
device.setSerialNum(dto.serialNum());
updated = true;
}
if (StringUtils.hasText(dto.softVersion())) {
device.setSoftVersion(dto.softVersion());
updated = true;
}
if (StringUtils.hasText(dto.alVersion())) {
device.setAlVersion(dto.alVersion());
updated = true;
}
if (dto.outProductDate() != null) {
device.setOutProductDate(dto.outProductDate());
updated = true;
}
@Override if (updated) {
public List<BaseSelectDto> getKeyAccount() { device.setUpdateUserId(SecurityUtils.getUserId());
LambdaQueryWrapper<RepairRecord> wrapper = new LambdaQueryWrapper<>(); device.setUpdateUserName(SecurityUtils.getUserName());
wrapper.select(RepairRecord::getKeyAccountId); device.setUpdateDate(LocalDateTime.now());
wrapper.isNotNull(RepairRecord::getKeyAccountId); deviceMapper.updateById(device);
wrapper.groupBy(RepairRecord::getKeyAccountId); }
List<RepairRecord> repairRecords = this.baseMapper.selectList(wrapper);
return repairRecords.stream()
.map(repairRecord -> new BaseSelectDto(repairRecord.getKeyAccountId().toString(), repairRecord.getKeyAccountId().toString()))
.toList();
} }
} }

View File

@@ -16,10 +16,16 @@ import com.niuan.erp.module.sale.controller.dto.SaleOrderAddDto;
import com.niuan.erp.module.sale.controller.dto.SaleOrderDto; import com.niuan.erp.module.sale.controller.dto.SaleOrderDto;
import com.niuan.erp.module.sale.controller.dto.SaleOrderItemAddDto; import com.niuan.erp.module.sale.controller.dto.SaleOrderItemAddDto;
import com.niuan.erp.module.sale.controller.dto.SaleOrderItemDto; import com.niuan.erp.module.sale.controller.dto.SaleOrderItemDto;
import com.niuan.erp.module.sale.controller.dto.SaleOrderItemUpdateDto;
import com.niuan.erp.module.sale.controller.dto.SaleOrderUpdateDto;
import com.niuan.erp.module.sale.converter.SaleOrderConverter; import com.niuan.erp.module.sale.converter.SaleOrderConverter;
import com.niuan.erp.module.sale.entity.SaleOrderItem; import com.niuan.erp.module.sale.entity.SaleOrderItem;
import com.niuan.erp.module.sale.mapper.SaleOrderItemMapper; import com.niuan.erp.module.sale.mapper.SaleOrderItemMapper;
import com.niuan.erp.module.sale.service.SaleOrderService; import com.niuan.erp.module.sale.service.SaleOrderService;
import com.niuan.erp.module.warehouse.entity.Stock;
import com.niuan.erp.module.warehouse.entity.WarehouseItem;
import com.niuan.erp.module.warehouse.mapper.StockMapper;
import com.niuan.erp.module.warehouse.mapper.WarehouseItemMapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.usermodel.*;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -29,7 +35,10 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.IOException; import java.io.IOException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -43,10 +52,17 @@ public class SaleOrderServiceImpl extends ServiceImpl<DocumentMapper, Document>
private final SaleOrderItemMapper saleOrderItemMapper; private final SaleOrderItemMapper saleOrderItemMapper;
private final StockMapper stockMapper;
private final WarehouseItemMapper warehouseItemMapper;
@Override @Override
public IPage<SaleOrderDto> getSaleOrderPage(BasePageReqParams pageParams, LambdaQueryWrapper<Document> wrapper) { public IPage<SaleOrderDto> getSaleOrderPage(BasePageReqParams pageParams, LambdaQueryWrapper<Document> wrapper) {
wrapper.eq(Document::getFormType, DocumentType.SALES_ORDER); wrapper.eq(Document::getFormType, DocumentType.SALES_ORDER);
IPage<Document> result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper); IPage<Document> result = this.baseMapper.selectPage(
new Page<>(pageParams.page(), pageParams.pageSize()),
wrapper
);
return result.convert(saleOrderConverter::toDto); return result.convert(saleOrderConverter::toDto);
} }
@@ -54,37 +70,52 @@ public class SaleOrderServiceImpl extends ServiceImpl<DocumentMapper, Document>
public void addSaleOrder(SaleOrderAddDto dto) { public void addSaleOrder(SaleOrderAddDto dto) {
List<SaleOrderItemAddDto> saleOrderItems = dto.saleOrderItems(); List<SaleOrderItemAddDto> saleOrderItems = dto.saleOrderItems();
if (saleOrderItems == null || saleOrderItems.isEmpty()) { // 计算订单总额
throw new BusinessException("sale.sale_order.exception.no_sale_order_items"); double totalValue = saleOrderItems.stream()
} .mapToDouble(item -> item.saleCount() * item.price())
.sum();
Document entity = saleOrderConverter.toEntity(dto); // 创建主单据
Document entity = new Document();
entity.setFormCode(dto.formCode());
entity.setFormName(dto.formName());
entity.setFormMark(dto.formMark());
entity.setCustomerId(dto.customerId());
entity.setStoreName(dto.customerName());
entity.setTotalValue(totalValue);
entity.setFormType(DocumentType.SALES_ORDER);
entity.setFormStatus(FormStatus.NO_APPROVE);
entity.setStatus(0);
entity.setCreateUserId(SecurityUtils.getUserId()); entity.setCreateUserId(SecurityUtils.getUserId());
entity.setCreateUserName(SecurityUtils.getUserName()); entity.setCreateUserName(SecurityUtils.getUserName());
entity.setCreateDate(LocalDateTime.now()); entity.setCreateDate(LocalDateTime.now());
entity.setStatus(0);
entity.setFormType(DocumentType.SALES_ORDER);
entity.setFormStatus(FormStatus.NO_APPROVE);
entity.setCustomerId(SecurityUtils.getCustomerId());
this.baseMapper.insert(entity); this.baseMapper.insert(entity);
List<SaleOrderItem> saleOrderItemEntities = saleOrderConverter.toEntityList(saleOrderItems); // 创建明细
List<SaleOrderItem> itemEntities = new ArrayList<>();
for (SaleOrderItem saleOrderItem : saleOrderItemEntities) { for (SaleOrderItemAddDto itemDto : saleOrderItems) {
saleOrderItem.setDocumentNo(entity.getId().intValue()); SaleOrderItem item = new SaleOrderItem();
saleOrderItem.setDocumentCode(entity.getFormCode()); item.setDocumentNo(entity.getId().intValue());
saleOrderItem.setCreateDate(LocalDateTime.now()); item.setDocumentCode(entity.getFormCode());
saleOrderItem.setCreateUserId(SecurityUtils.getUserId()); item.setPartNumber(itemDto.partNumber());
saleOrderItem.setCreateUserName(SecurityUtils.getUserName()); item.setSaleCount(itemDto.saleCount());
saleOrderItem.setStatus(0); item.setPrice(itemDto.price());
saleOrderItem.setSendCount(0); item.setTotalPrice(itemDto.saleCount() * itemDto.price());
item.setSaleMark(itemDto.saleMark());
item.setSendCount(0);
item.setStatus(0);
item.setCreateUserId(SecurityUtils.getUserId());
item.setCreateUserName(SecurityUtils.getUserName());
item.setCreateDate(LocalDateTime.now());
itemEntities.add(item);
} }
saleOrderItemMapper.insert(saleOrderItemEntities); saleOrderItemMapper.insert(itemEntities);
} }
@Override @Override
public void updateSaleOrder(SaleOrderDto dto) { public void updateSaleOrder(SaleOrderUpdateDto dto) {
Document existingEntity = this.baseMapper.selectById(dto.id()); Document existingEntity = this.baseMapper.selectById(dto.id());
if (existingEntity == null) { if (existingEntity == null) {
throw new BusinessException("sale.sale_order.exception.not_found"); throw new BusinessException("sale.sale_order.exception.not_found");
@@ -93,11 +124,48 @@ public class SaleOrderServiceImpl extends ServiceImpl<DocumentMapper, Document>
throw new BusinessException("sale.sale_order.exception.cannot_update_approved"); throw new BusinessException("sale.sale_order.exception.cannot_update_approved");
} }
Document entity = saleOrderConverter.toEntity(dto); // 计算新的订单总额
entity.setUpdateUserId(SecurityUtils.getUserId()); double totalValue = dto.saleOrderItems().stream()
entity.setUpdateUserName(SecurityUtils.getUserName()); .mapToDouble(item -> item.saleCount() * item.price())
entity.setUpdateDate(LocalDateTime.now()); .sum();
this.baseMapper.updateById(entity);
// 更新主单据
existingEntity.setFormName(dto.formName());
existingEntity.setFormMark(dto.formMark());
existingEntity.setCustomerId(dto.customerId());
existingEntity.setStoreName(dto.customerName());
existingEntity.setTotalValue(totalValue);
existingEntity.setUpdateUserId(SecurityUtils.getUserId());
existingEntity.setUpdateUserName(SecurityUtils.getUserName());
existingEntity.setUpdateDate(LocalDateTime.now());
this.baseMapper.updateById(existingEntity);
// 删除旧明细
LambdaQueryWrapper<SaleOrderItem> deleteWrapper = new LambdaQueryWrapper<>();
deleteWrapper.eq(SaleOrderItem::getDocumentNo, dto.id());
saleOrderItemMapper.delete(deleteWrapper);
// 插入新明细
List<SaleOrderItem> itemEntities = new ArrayList<>();
for (SaleOrderItemUpdateDto itemDto : dto.saleOrderItems()) {
SaleOrderItem item = new SaleOrderItem();
item.setDocumentNo(existingEntity.getId().intValue());
item.setDocumentCode(existingEntity.getFormCode());
item.setPartNumber(itemDto.partNumber());
item.setSaleCount(itemDto.saleCount());
item.setPrice(itemDto.price());
item.setTotalPrice(itemDto.saleCount() * itemDto.price());
item.setSaleMark(itemDto.saleMark());
item.setSendCount(0);
item.setStatus(0);
item.setCreateUserId(SecurityUtils.getUserId());
item.setCreateUserName(SecurityUtils.getUserName());
item.setCreateDate(LocalDateTime.now());
itemEntities.add(item);
}
saleOrderItemMapper.insert(itemEntities);
} }
@Override @Override
@@ -155,6 +223,50 @@ public class SaleOrderServiceImpl extends ServiceImpl<DocumentMapper, Document>
throw new BusinessException("sale.sale_order.exception.no_sale_order_items"); throw new BusinessException("sale.sale_order.exception.no_sale_order_items");
} }
// 验证并扣除库存
for (SaleOrderItem item : items) {
LambdaQueryWrapper<Stock> stockWrapper = new LambdaQueryWrapper<>();
stockWrapper.eq(Stock::getPartNumber, item.getPartNumber());
// 如果指定了仓库,则按仓库查询
if (entity.getStoreNo() != null) {
stockWrapper.eq(Stock::getStoreNo, entity.getStoreNo());
}
Stock stock;
if (entity.getStoreNo() != null) {
// 指定了仓库,使用 selectOne
stock = stockMapper.selectOne(stockWrapper);
} else {
// 未指定仓库,查询所有仓库库存并汇总
List<Stock> stockList = stockMapper.selectList(stockWrapper);
if (stockList == null || stockList.isEmpty()) {
stock = null;
} else if (stockList.size() == 1) {
stock = stockList.get(0);
} else {
// 多条记录,取第一条并汇总数量
stock = stockList.get(0);
int totalCount = stockList.stream().mapToInt(Stock::getProductCount).sum();
stock.setProductCount(totalCount);
}
}
if (stock == null) {
throw new BusinessException("warehouse.stock_transfer_order.exception.stock_not_found");
}
if (stock.getProductCount() < item.getSaleCount()) {
throw new BusinessException("warehouse.stock_transfer_order.exception.insufficient_stock");
}
// 扣除库存 - 如果有多条记录,只更新第一条
stock.setProductCount(stock.getProductCount() - item.getSaleCount());
stock.setUpdateDate(LocalDateTime.now());
stock.setUpdateUserId(SecurityUtils.getUserId());
stock.setUpdateUserName(SecurityUtils.getUserName());
stockMapper.updateById(stock);
}
entity.setFormStatus(FormStatus.APPROVE); entity.setFormStatus(FormStatus.APPROVE);
entity.setUpdateDate(LocalDateTime.now()); entity.setUpdateDate(LocalDateTime.now());
entity.setUpdateUserId(SecurityUtils.getUserId()); entity.setUpdateUserId(SecurityUtils.getUserId());
@@ -183,6 +295,7 @@ public class SaleOrderServiceImpl extends ServiceImpl<DocumentMapper, Document>
itemWrapper.eq(SaleOrderItem::getDocumentNo, id); itemWrapper.eq(SaleOrderItem::getDocumentNo, id);
List<SaleOrderItem> items = saleOrderItemMapper.selectList(itemWrapper); List<SaleOrderItem> items = saleOrderItemMapper.selectList(itemWrapper);
// 检查是否有已出货数量
Long shippedCount = items.stream() Long shippedCount = items.stream()
.filter(item -> item.getSendCount() != null && item.getSendCount() > 0) .filter(item -> item.getSendCount() != null && item.getSendCount() > 0)
.count(); .count();
@@ -191,6 +304,42 @@ public class SaleOrderServiceImpl extends ServiceImpl<DocumentMapper, Document>
throw new BusinessException("sale.sale_order.exception.cannot_unapprove_with_shipped"); throw new BusinessException("sale.sale_order.exception.cannot_unapprove_with_shipped");
} }
// 恢复库存
for (SaleOrderItem item : items) {
LambdaQueryWrapper<Stock> stockWrapper = new LambdaQueryWrapper<>();
stockWrapper.eq(Stock::getPartNumber, item.getPartNumber());
// 如果指定了仓库,则按仓库查询
if (entity.getStoreNo() != null) {
stockWrapper.eq(Stock::getStoreNo, entity.getStoreNo());
}
Stock stock;
if (entity.getStoreNo() != null) {
// 指定了仓库,使用 selectOne
stock = stockMapper.selectOne(stockWrapper);
} else {
// 未指定仓库,查询所有仓库库存
List<Stock> stockList = stockMapper.selectList(stockWrapper);
if (stockList == null || stockList.isEmpty()) {
stock = null;
} else {
// 取第一条记录
stock = stockList.get(0);
}
}
if (stock == null) {
throw new BusinessException("warehouse.stock_transfer_order.exception.stock_not_found");
}
// 恢复库存 - 只更新第一条记录
stock.setProductCount(stock.getProductCount() + item.getSaleCount());
stock.setUpdateDate(LocalDateTime.now());
stock.setUpdateUserId(SecurityUtils.getUserId());
stock.setUpdateUserName(SecurityUtils.getUserName());
stockMapper.updateById(stock);
}
entity.setFormStatus(FormStatus.NO_APPROVE); entity.setFormStatus(FormStatus.NO_APPROVE);
entity.setUpdateDate(LocalDateTime.now()); entity.setUpdateDate(LocalDateTime.now());
entity.setUpdateUserId(SecurityUtils.getUserId()); entity.setUpdateUserId(SecurityUtils.getUserId());
@@ -210,7 +359,40 @@ public class SaleOrderServiceImpl extends ServiceImpl<DocumentMapper, Document>
LambdaQueryWrapper<SaleOrderItem> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SaleOrderItem> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SaleOrderItem::getDocumentNo, id); wrapper.eq(SaleOrderItem::getDocumentNo, id);
List<SaleOrderItem> items = saleOrderItemMapper.selectList(wrapper); List<SaleOrderItem> items = saleOrderItemMapper.selectList(wrapper);
return saleOrderConverter.toSaleOrderItemDtoList(items);
// 获取所有物料编号
List<String> partNumbers = items.stream()
.map(SaleOrderItem::getPartNumber)
.filter(StringUtils::hasText)
.distinct()
.toList();
// 查询物料型号信息
Map<String, String> productSpecsMap = new HashMap<>();
if (!partNumbers.isEmpty()) {
LambdaQueryWrapper<WarehouseItem> warehouseWrapper = new LambdaQueryWrapper<>();
warehouseWrapper.in(WarehouseItem::getPartNumber, partNumbers);
List<WarehouseItem> warehouseItems = warehouseItemMapper.selectList(warehouseWrapper);
productSpecsMap = warehouseItems.stream()
.collect(Collectors.toMap(
WarehouseItem::getPartNumber,
WarehouseItem::getProductSpecs,
(a, b) -> a
));
}
// 转换为 DTO 并设置 productSpecs
Map<String, String> finalProductSpecsMap = productSpecsMap;
return items.stream().map(item -> new SaleOrderItemDto(
item.getId(),
item.getPartNumber(),
finalProductSpecsMap.getOrDefault(item.getPartNumber(), ""),
item.getSaleCount(),
item.getPrice(),
item.getTotalPrice(),
item.getSendCount(),
item.getSaleMark()
)).toList();
} }
@Override @Override
@@ -228,19 +410,19 @@ public class SaleOrderServiceImpl extends ServiceImpl<DocumentMapper, Document>
if (row == null) continue; if (row == null) continue;
String partNumber = getCellValueAsString(row.getCell(0)); String partNumber = getCellValueAsString(row.getCell(0));
String saleCountStr = getCellValueAsString(row.getCell(1)); String productSpecs = getCellValueAsString(row.getCell(1));
String priceStr = getCellValueAsString(row.getCell(2)); String saleCountStr = getCellValueAsString(row.getCell(2));
String saleMark = getCellValueAsString(row.getCell(3)); String priceStr = getCellValueAsString(row.getCell(3));
String saleMark = getCellValueAsString(row.getCell(4));
if (!StringUtils.hasText(partNumber)) continue; if (!StringUtils.hasText(partNumber)) continue;
Integer saleCount = StringUtils.hasText(saleCountStr) ? Integer.parseInt(saleCountStr) : 0; Integer saleCount = StringUtils.hasText(saleCountStr) ? Integer.parseInt(saleCountStr) : 0;
Double price = StringUtils.hasText(priceStr) ? Double.parseDouble(priceStr) : 0.0; Double price = StringUtils.hasText(priceStr) ? Double.parseDouble(priceStr) : 0.0;
Double totalPrice = saleCount * price;
SaleOrderItemDto item = new SaleOrderItemDto( SaleOrderItemDto item = new SaleOrderItemDto(
null, null, null, null, null, null, null, null, null, partNumber, productSpecs, saleCount, price, totalPrice, 0, saleMark
null, null, null, partNumber, saleCount, price,
saleCount * price, 0, saleMark, null, null
); );
items.add(item); items.add(item);
} }
@@ -262,4 +444,4 @@ public class SaleOrderServiceImpl extends ServiceImpl<DocumentMapper, Document>
default -> ""; default -> "";
}; };
} }
} }

View File

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.niuan.erp.common.base.BaseDeleteBody; import com.niuan.erp.common.base.BaseDeleteBody;
import com.niuan.erp.common.base.BasePageReqParams; import com.niuan.erp.common.base.BasePageReqParams;
import com.niuan.erp.common.base.BaseResult; import com.niuan.erp.common.base.BaseResult;
import com.niuan.erp.common.base.BaseTree;
import com.niuan.erp.common.base.CommonValidateGroup.DeleteBatch; import com.niuan.erp.common.base.CommonValidateGroup.DeleteBatch;
import com.niuan.erp.common.base.CommonValidateGroup.DeleteOne; import com.niuan.erp.common.base.CommonValidateGroup.DeleteOne;
import com.niuan.erp.common.base.BaseSelectDto; import com.niuan.erp.common.base.BaseSelectDto;
@@ -45,6 +46,13 @@ public class KeyAccountController {
return BaseResult.successWithData(keyAccountService.getKeyAccountSelectList()); return BaseResult.successWithData(keyAccountService.getKeyAccountSelectList());
} }
@Operation(summary = "查询客户树结构", operationId = "getKeyAccountTree")
@GetMapping("/getKeyAccountTree")
@PreAuthorize("hasAnyAuthority('device_sn:index', 'repair_record:index')")
public BaseResult<List<BaseTree>> getKeyAccountTree() {
return BaseResult.successWithData(keyAccountService.getKeyAccountTree());
}
@PostMapping("/addKeyAccount") @PostMapping("/addKeyAccount")
public BaseResult<?> addKeyAccount(@Valid @RequestBody KeyAccountDto dto) { public BaseResult<?> addKeyAccount(@Valid @RequestBody KeyAccountDto dto) {
keyAccountService.addKeyAccount(dto); keyAccountService.addKeyAccount(dto);

View File

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.niuan.erp.common.base.BasePageReqParams; import com.niuan.erp.common.base.BasePageReqParams;
import com.niuan.erp.common.base.BaseSelectDto; import com.niuan.erp.common.base.BaseSelectDto;
import com.niuan.erp.common.base.BaseTree;
import com.niuan.erp.module.sys.controller.dto.KeyAccountDto; import com.niuan.erp.module.sys.controller.dto.KeyAccountDto;
import com.niuan.erp.module.sys.entity.KeyAccount; import com.niuan.erp.module.sys.entity.KeyAccount;
@@ -15,6 +16,8 @@ public interface KeyAccountService {
List<BaseSelectDto> getKeyAccountSelectList(); List<BaseSelectDto> getKeyAccountSelectList();
List<BaseTree> getKeyAccountTree();
void addKeyAccount(KeyAccountDto dto); void addKeyAccount(KeyAccountDto dto);
void updateKeyAccount(KeyAccountDto dto); void updateKeyAccount(KeyAccountDto dto);

View File

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.niuan.erp.common.base.BasePageReqParams; import com.niuan.erp.common.base.BasePageReqParams;
import com.niuan.erp.common.base.BaseSelectDto; import com.niuan.erp.common.base.BaseSelectDto;
import com.niuan.erp.common.base.BaseTree;
import com.niuan.erp.common.utils.SecurityUtils; import com.niuan.erp.common.utils.SecurityUtils;
import com.niuan.erp.module.sys.controller.dto.KeyAccountDto; import com.niuan.erp.module.sys.controller.dto.KeyAccountDto;
import com.niuan.erp.module.sys.converter.KeyAccountConverter; import com.niuan.erp.module.sys.converter.KeyAccountConverter;
@@ -17,7 +18,10 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service @Service
@@ -39,6 +43,33 @@ public class KeyAccountServiceImpl extends ServiceImpl<KeyAccountMapper, KeyAcco
return this.baseMapper.getKeyAccountSelectList(); return this.baseMapper.getKeyAccountSelectList();
} }
@Override
public List<BaseTree> getKeyAccountTree() {
LambdaQueryWrapper<KeyAccount> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(KeyAccount::getStatus, 1);
wrapper.orderByAsc(KeyAccount::getLevelPath);
List<KeyAccount> keyAccounts = this.baseMapper.selectList(wrapper);
Map<Long, List<KeyAccount>> parentMap = keyAccounts.stream()
.collect(Collectors.groupingBy(ka -> ka.getParentId() != null ? ka.getParentId() : 0L));
return buildTree(parentMap, 0L);
}
private List<BaseTree> buildTree(Map<Long, List<KeyAccount>> parentMap, Long parentId) {
List<KeyAccount> children = parentMap.get(parentId);
if (children == null || children.isEmpty()) {
return new ArrayList<>();
}
List<BaseTree> treeList = new ArrayList<>();
for (KeyAccount ka : children) {
List<BaseTree> childTrees = buildTree(parentMap, ka.getId());
treeList.add(new BaseTree(ka.getId(), ka.getKeyAccountName(), childTrees));
}
return treeList;
}
@Override @Override
public void addKeyAccount(KeyAccountDto dto) { public void addKeyAccount(KeyAccountDto dto) {
KeyAccount entity = keyAccountConverter.toEntity(dto); KeyAccount entity = keyAccountConverter.toEntity(dto);

View File

@@ -1,5 +1,6 @@
result.success=请求成功 result.success=请求成功
result.error=请求失败 result.error=请求失败
common.validate.page_params.not_null=分页参数不能为空
production.productionreturn.exception.not_exist=退料单不存在 production.productionreturn.exception.not_exist=退料单不存在
production.productionreturn.exception.already_approved=退料单已经审核 production.productionreturn.exception.already_approved=退料单已经审核
production.productionreturn.exception.no_material=退料单没有明细 production.productionreturn.exception.no_material=退料单没有明细
@@ -166,7 +167,10 @@ production.devicesn.exception.not_found=SN号不存在
production.repair_record.validate.product_sn.not_null=SN号不能为空 production.repair_record.validate.product_sn.not_null=SN号不能为空
production.repair_record.validate.mac.not_null=MAC地址不能为空 production.repair_record.validate.mac.not_null=MAC地址不能为空
production.repair_record.validate.repair_status.not_null=维修状态不能为空 production.repair_record.validate.repair_status.not_null=维修状态不能为空
production.repair_record.validate.repair_mark.not_null=返修记录不能为空
production.repair_record.validate.identifier.not_null=SN号、MAC地址、序列号至少填写一个
production.repair_record.exception.not_found=维修记录不存在 production.repair_record.exception.not_found=维修记录不存在
production.repair_record.exception.device_not_found=设备不存在
purchase.purchase_order.validate.id.not_null=订单ID不能为空 purchase.purchase_order.validate.id.not_null=订单ID不能为空
purchase.purchase_order.validate.vendor_name.not_blank=供应商名称不能为空 purchase.purchase_order.validate.vendor_name.not_blank=供应商名称不能为空
purchase.purchase_order.validate.vendor_name.not_null=供应商名称不能为空 purchase.purchase_order.validate.vendor_name.not_null=供应商名称不能为空

View File

@@ -32,4 +32,33 @@
<result column="RepairMark" property="repairMark" /> <result column="RepairMark" property="repairMark" />
</resultMap> </resultMap>
<!-- SN溯源查询 - 只查询展示字段 -->
<select id="selectDeviceSnPage" resultType="com.niuan.erp.module.sale.controller.dto.DeviceResultDto">
SELECT
d.ProductType AS productType,
d.ProductSn AS productSn,
d.Mac AS mac,
d.SerialNum AS serialNum,
d.SoftVersion AS softVersion,
d.AlVersion AS alVersion,
d.OutProductDate AS outProductDate,
(SELECT GROUP_CONCAT(rr.RepairMark SEPARATOR '; ')
FROM repairrecord rr
WHERE rr.ProductSn = d.ProductSn
AND rr.RepairMark IS NOT NULL
AND rr.RepairMark != '') AS repairRecords
FROM modulesn d
<where>
<if test="searchCode != null and searchCode != ''">
AND (d.ProductSn LIKE CONCAT('%', #{searchCode}, '%')
OR d.Mac LIKE CONCAT('%', #{searchCode}, '%')
OR d.SerialNum LIKE CONCAT('%', #{searchCode}, '%'))
</if>
<if test="keyAccountId != null">
AND d.KeyAccountId = #{keyAccountId}
</if>
</where>
ORDER BY d.CreateDate DESC
</select>
</mapper> </mapper>

View File

@@ -27,4 +27,37 @@
<result column="RepairMark" property="repairMark" /> <result column="RepairMark" property="repairMark" />
</resultMap> </resultMap>
<!-- 返修报表查询 - 只查询展示字段 -->
<select id="selectRepairReportPage" resultType="com.niuan.erp.module.sale.controller.dto.RepairRecordResultDto">
SELECT
rr.ProductType AS productType,
rr.ProductSn AS productSn,
rr.Mac AS mac,
d.SerialNum AS serialNum,
d.SoftVersion AS softVersion,
d.AlVersion AS alVersion,
rr.OutProductDate AS outProductDate,
rr.CreateDate AS createDate,
(SELECT COUNT(*)
FROM repairrecord rr3
WHERE rr3.ProductSn = rr.ProductSn) AS repairCount,
(SELECT GROUP_CONCAT(rr2.RepairMark SEPARATOR '; ')
FROM repairrecord rr2
WHERE rr2.ProductSn = rr.ProductSn
AND rr2.RepairMark IS NOT NULL
AND rr2.RepairMark != '') AS repairRecords
FROM repairrecord rr
LEFT JOIN modulesn d ON d.ProductSn = rr.ProductSn
<where>
<if test="searchCode != null and searchCode != ''">
AND (rr.ProductSn LIKE CONCAT('%', #{searchCode}, '%')
OR rr.Mac LIKE CONCAT('%', #{searchCode}, '%'))
</if>
<if test="keyAccountIdSearch != null">
AND rr.KeyAccountId = #{keyAccountIdSearch}
</if>
</where>
ORDER BY rr.CreateDate DESC
</select>
</mapper> </mapper>

View File

@@ -17,7 +17,7 @@ CREATE TABLE IF NOT EXISTS sys_permission (
permission_code VARCHAR(50) DEFAULT NULL COMMENT '后端鉴权用的权限编码', permission_code VARCHAR(50) DEFAULT NULL COMMENT '后端鉴权用的权限编码',
event_name VARCHAR(50) DEFAULT NULL COMMENT '前端按钮绑定的方法名', event_name VARCHAR(50) DEFAULT NULL COMMENT '前端按钮绑定的方法名',
class_name VARCHAR(30) DEFAULT NULL COMMENT '前端样式类名', class_name VARCHAR(30) DEFAULT NULL COMMENT '前端样式类名',
icon_name VARCHAR(30) DEFAULT NULL COMMENT '前端图标名称', icon_name VARCHAR(100) DEFAULT NULL COMMENT '前端图标名称',
sort INT NOT NULL DEFAULT 0 COMMENT '排序值,越小越靠前' sort INT NOT NULL DEFAULT 0 COMMENT '排序值,越小越靠前'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统权限表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统权限表';