src/main/java/com/ruoyi/basic/controller/StorageAttachmentController.java
@@ -1,16 +1,10 @@ package com.ruoyi.basic.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.basic.dto.StorageAttachmentDTO; import com.ruoyi.basic.dto.StorageBlobDTO; import com.ruoyi.basic.dto.SupplierManageDto; import com.ruoyi.basic.enums.ApplicationTypeEnum; import com.ruoyi.basic.enums.RecordTypeEnum; import com.ruoyi.basic.pojo.StorageAttachment; import com.ruoyi.basic.service.StorageAttachmentService; import com.ruoyi.common.constant.StorageAttachmentConstants; import com.ruoyi.common.enums.StorageAttachmentRecordType; import com.ruoyi.framework.web.domain.R; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -18,26 +12,31 @@ @RestController @AllArgsConstructor @RequestMapping("/basic/storage_attachment") @Tag(name = "éç¨ä¸ä¼ ") @RequestMapping("/storageAttachment") public class StorageAttachmentController { private StorageAttachmentService storageAttachmentService; /** * å页æ¥è¯¢éç¨æä»¶ä¸ä¼ çéä»¶ä¿¡æ¯ * * @param storageAttachmentDTO å ³èè®°å½ä¿¡æ¯ * @return åé¡µç»æ */ @GetMapping("/list") @Operation(summary = "å页æ¥è¯¢éç¨æä»¶ä¸ä¼ çéä»¶ä¿¡æ¯") public R list(StorageAttachmentDTO storageAttachmentDTO) { return R.ok(storageAttachmentService.list(storageAttachmentDTO)); } /** * å é¤éç¨æä»¶ä¸ä¼ çéä»¶ä¿¡æ¯ * * @param ids æä»¶idå表 * @return å é¤ç»æ */ @DeleteMapping("/delete") @Operation(summary = "å é¤éç¨æä»¶ä¸ä¼ çéä»¶ä¿¡æ¯") public R batchDelete(@RequestBody List<Long> ids) { return R.ok(storageAttachmentService.batchDeleteStorageAttachment(ids)); } @@ -46,6 +45,7 @@ * ä¿åéç¨æä»¶ä¸ä¼ çéä»¶ä¿¡æ¯ */ @PostMapping("/add") @Operation(summary = "ä¿åéç¨æä»¶ä¸ä¼ çéä»¶ä¿¡æ¯") public R add(@RequestBody StorageAttachmentDTO storageAttachmentDTO) { storageAttachmentService.saveStorageAttachment(storageAttachmentDTO); return R.ok(); src/main/java/com/ruoyi/production/bean/dto/ProductionAccountDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,63 @@ package com.ruoyi.production.bean.dto; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.production.pojo.ProductionAccount; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDate; @Data @Schema(name = "ProductionAccountDto", description = "production account query dto") public class ProductionAccountDto extends ProductionAccount { @Schema(description = "sales contract no") private String salesContractNo; @Schema(description = "customer contract no") private String customerContractNo; @Schema(description = "project name") private String projectName; @Schema(description = "customer name") private String customerName; @Schema(description = "product category") private String productCategory; @Schema(description = "specification model") private String specificationModel; @Schema(description = "scheduling user id") private Long schedulingUserId; @Schema(description = "scheduling user name") private String schedulingUserName; @Schema(description = "process") private String process; @Schema(description = "date type(day/month)") private String dateType; @Schema(description = "day query date") @JsonFormat(pattern = "yyyy-MM-dd") @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate entryDate; @Schema(description = "date range") @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate[] dateRange; @Schema(description = "start date") @JsonFormat(pattern = "yyyy-MM-dd") @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate entryDateStart; @Schema(description = "end date") @JsonFormat(pattern = "yyyy-MM-dd") @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate entryDateEnd; } src/main/java/com/ruoyi/production/bean/dto/ProductionOperationTaskDto.java
@@ -1,10 +1,34 @@ package com.ruoyi.production.bean.dto; import com.ruoyi.production.pojo.ProductionOperationTask; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import java.math.BigDecimal; @EqualsAndHashCode(callSuper = true) @Data public class ProductionOperationTaskDto extends ProductionOperationTask { @Schema(description = "å·¥åºåç§°") private String processName; @Schema(description = "ç产订åå·") private String productOrderNpsNo; @Schema(description = "产ååç§°") private String productName; @Schema(description = "è§æ ¼åå·") private String model; @Schema(description = "åä½") private String unit; @Schema(description = "æ¥åºæ°é") private BigDecimal scrapQty; @Schema(description = "宿è¿åº¦") private BigDecimal completionStatus; } src/main/java/com/ruoyi/production/bean/dto/ProductionProductMainDto.java
@@ -12,57 +12,63 @@ @EqualsAndHashCode(callSuper = true) @Data @Schema(name = "ProductionProductMainDto", description = "ç产æ¥å·¥æ¥è¯¢å¯¹è±¡") @Schema(name = "ProductionProductMainDto", description = "production report query dto") public class ProductionProductMainDto extends ProductionProductMain { @Schema(description = "产åå·¥èºè·¯çº¿æç»ID") @Schema(description = "product process route item id") private Long productProcessRouteItemId; @Schema(description = "ç产æ¥å·¥è¡¨id") @Schema(description = "production report id") private Long productMainId; @Schema(description = "ç§æ·ID") @Schema(description = "tenant id") private Long tenantId; @Schema(description = "å·¥åç¼å·") @Schema(description = "work order no") private String workOrderNo; @Schema(description = "å·¥åç¶æ") @Schema(description = "work order status") private String workOrderStatus; @Schema(description = "æµç§°") @Schema(description = "nick name") private String nickName; @Schema(description = "æ°é") @Schema(description = "quantity") private BigDecimal quantity; @Schema(description = "æ¥åºæ°é") @Schema(description = "scrap quantity") private BigDecimal scrapQty; @Schema(description = "产ååç§°") @Schema(description = "product name") private String productName; @Schema(description = "产ååå·åç§°") @Schema(description = "product model name") private String productModelName; @Schema(description = "åä½") @Schema(description = "unit") private String unit; @Schema(description = "éå®ååç¼å·") @Schema(description = "sales contract no") private String salesContractNo; @Schema(description = "æäº§æ¥æ") @Schema(description = "scheduling date") private LocalDate schedulingDate; @Schema(description = "æäº§äººååç§°") @Schema(description = "scheduling user name") private String schedulingUserName; @Schema(description = "客æ·åç§°") @Schema(description = "customer name") private String customerName; @Schema(description = "å·¥åº") @Schema(description = "process") private String process; @Schema(description = "å·¥åºåæ°å表") @Schema(description = "salary quota") private BigDecimal workHours; @Schema(description = "wages") private BigDecimal wages; @Schema(description = "operation param list") private List<ProductionOrderRoutingOperationParam> productionOperationParamList; } src/main/java/com/ruoyi/production/bean/vo/ProductionAccountVo.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,56 @@ package com.ruoyi.production.bean.vo; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.math.BigDecimal; import java.time.LocalDate; @Data @Schema(name = "ProductionAccountVo", description = "çäº§æ ¸ç®å页è¿å对象") public class ProductionAccountVo { @Schema(description = "客æ·ååå·") private String customerContractNo; @Schema(description = "项ç®åç§°") private String projectName; @Schema(description = "客æ·åç§°") private String customerName; @Schema(description = "产å大类") private String productCategory; @Schema(description = "è§æ ¼åå·") private String specificationModel; @Schema(description = "åä½") private String unit; @Schema(description = "ç产人ID") private Long schedulingUserId; @Schema(description = "ç产人åç§°") private String schedulingUserName; @Schema(description = "å·¥èµ") private BigDecimal wages; @Schema(description = "ç产æ°é") private BigDecimal finishedNum; @Schema(description = "å·¥æ¶å®é¢") private BigDecimal workHours; @Schema(description = "å·¥åº") private String process; @Schema(description = "çäº§æ¥æ") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate schedulingDate; @Schema(description = "ç产æä»½(yyyy-MM)") private String schedulingMonth; } src/main/java/com/ruoyi/production/bean/vo/ProductionOperationTaskVo.java
@@ -26,9 +26,12 @@ @Schema(description = "å·¥åºåç§°") private String operationName; @Schema(description = "å·¥åç±»å æ£å¸¸ /è¿å·¥è¿ä¿®") @Schema(description = "å·¥åç±»å æ£å¸¸/è¿å·¥è¿ä¿®") private String workOrderType; @Schema(description = "宿è¿åº¦") private BigDecimal completionStatus; @Schema(description = "æ¥å·¥äººååç§°ï¼å¤ä¸ªä½¿ç¨éå·åé") private String userNames; } src/main/java/com/ruoyi/production/controller/ProductionAccountController.java
@@ -1,5 +1,16 @@ package com.ruoyi.production.controller; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.framework.web.domain.R; import com.ruoyi.production.bean.dto.ProductionAccountDto; import com.ruoyi.production.bean.dto.ProductionProductMainDto; import com.ruoyi.production.bean.vo.ProductionAccountVo; import com.ruoyi.production.service.ProductionAccountService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -7,12 +18,24 @@ * <p> * çäº§æ ¸ç®è¡¨ å端æ§å¶å¨ * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-04-21 03:55:52 */ @RestController @RequestMapping("/productionAccount") @RequiredArgsConstructor @Tag(name = "çäº§æ ¸ç®") public class ProductionAccountController { private final ProductionAccountService productionAccountService; @GetMapping("/listPage") @Operation(summary = "çäº§æ ¸ç®å页æ¥è¯¢") public R<IPage<ProductionAccountVo>> listPage(Page<ProductionAccountDto> page, ProductionAccountDto dto) { return R.ok(productionAccountService.listPage(page, dto)); } @GetMapping("/listProductionDetails") @Operation(summary ="æ¥è¯¢å·¥äººç产工èµä¿¡æ¯") public R<IPage<ProductionProductMainDto>> listProductionDetails(ProductionAccountDto productionAccountDto, Page page) { return R.ok(productionAccountService.listProductionDetails(productionAccountDto,page)); } } src/main/java/com/ruoyi/production/controller/ProductionOperationTaskController.java
@@ -6,18 +6,11 @@ import com.ruoyi.production.bean.vo.ProductionOperationTaskVo; import com.ruoyi.production.pojo.ProductionOperationTask; import com.ruoyi.production.service.ProductionOperationTaskService; import io.swagger.annotations.ApiOperation; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -71,4 +64,20 @@ return R.ok(productionOperationTaskService.updateProductWorkOrder(dto)); } @Operation(summary = "ææ´¾æ¥å·¥äºº") @PostMapping("/assign") public R<Boolean> assign(@RequestBody ProductionOperationTaskDto dto) { return R.ok(productionOperationTaskService.assign(dto)); } /** * å·¥åæµè½¬å¡ä¸è½½ * @param response * @param dto */ @PostMapping("/down") public void down(HttpServletResponse response, @RequestBody ProductionOperationTaskDto dto) { productionOperationTaskService.down(response, dto); } } src/main/java/com/ruoyi/production/mapper/ProductionAccountMapper.java
@@ -1,7 +1,11 @@ package com.ruoyi.production.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.production.bean.dto.ProductionAccountDto; import com.ruoyi.production.bean.dto.UserAccountDto; import com.ruoyi.production.bean.vo.ProductionAccountVo; import com.ruoyi.production.pojo.ProductionAccount; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -19,6 +23,8 @@ */ @Mapper public interface ProductionAccountMapper extends BaseMapper<ProductionAccount> { IPage<ProductionAccountVo> listPage(Page<ProductionAccountDto> page, @Param("c") ProductionAccountDto dto); UserAccountDto selectUserAccount(@Param("userId") Long userId, @Param("date") String date); List<Map<String, Object>> selectDailyWagesStats(@Param("startDate") String startDate, @Param("endDate") String endDate); src/main/java/com/ruoyi/production/mapper/ProductionOperationTaskMapper.java
@@ -40,4 +40,5 @@ @Param("userId") Long userId, @Param("processIds") List<Long> processIds); ProductionOperationTaskDto getProductWorkOrderFlowCard(@Param("id") Long id); } src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
@@ -3,8 +3,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.production.bean.dto.ProductionAccountDto; import com.ruoyi.production.bean.dto.ProductionProductMainDto; import com.ruoyi.production.bean.dto.SalesLedgerProductionAccountingDto; import com.ruoyi.production.pojo.ProductionOrder; import com.ruoyi.production.pojo.ProductionProductMain; import org.apache.ibatis.annotations.Mapper; @@ -30,7 +30,7 @@ */ ProductionOrder getOrderByMainId(@Param("productMainId") Long productMainId); IPage<ProductionProductMainDto> listProductionDetails(@Param("ew") SalesLedgerProductionAccountingDto salesLedgerProductionAccountingDto, Page page); IPage<ProductionProductMainDto> listProductionDetails(@Param("c") ProductionAccountDto productionAccountDto, Page page); ArrayList<Long> listMain(List<Long> idList); } src/main/java/com/ruoyi/production/pojo/ProductionOrderRoutingOperationParam.java
@@ -90,4 +90,7 @@ @Schema(description = "ç产订åå·¥èºè·¯çº¿å·¥åºID") private Long productionOrderRoutingOperationId; @Schema(description = "ç产æ¥å·¥è¡¨ID") private Long productionProductMainId; } src/main/java/com/ruoyi/production/service/ProductionAccountService.java
@@ -1,5 +1,10 @@ package com.ruoyi.production.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.production.bean.dto.ProductionAccountDto; import com.ruoyi.production.bean.dto.ProductionProductMainDto; import com.ruoyi.production.bean.vo.ProductionAccountVo; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.production.pojo.ProductionAccount; @@ -12,5 +17,7 @@ * @since 2026-04-21 03:55:52 */ public interface ProductionAccountService extends IService<ProductionAccount> { IPage<ProductionAccountVo> listPage(Page<ProductionAccountDto> page, ProductionAccountDto dto); IPage<ProductionProductMainDto> listProductionDetails(ProductionAccountDto productionAccountDto, Page page); } src/main/java/com/ruoyi/production/service/ProductionOperationTaskService.java
@@ -6,6 +6,7 @@ import com.ruoyi.production.bean.dto.ProductionOperationTaskDto; import com.ruoyi.production.bean.vo.ProductionOperationTaskVo; import com.ruoyi.production.pojo.ProductionOperationTask; import jakarta.servlet.http.HttpServletResponse; import java.util.List; @@ -23,4 +24,8 @@ boolean removeProductionOperationTask(List<Long> ids); int updateProductWorkOrder(ProductionOperationTaskDto dto); boolean assign(ProductionOperationTaskDto dto); void down(HttpServletResponse response, ProductionOperationTaskDto dto); } src/main/java/com/ruoyi/production/service/impl/ProductionAccountServiceImpl.java
@@ -1,20 +1,73 @@ package com.ruoyi.production.service.impl; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.production.bean.dto.ProductionAccountDto; import com.ruoyi.production.bean.dto.ProductionProductMainDto; import com.ruoyi.production.bean.vo.ProductionAccountVo; import com.ruoyi.production.mapper.ProductionAccountMapper; import com.ruoyi.production.mapper.ProductionProductMainMapper; import com.ruoyi.production.pojo.ProductionAccount; import com.ruoyi.production.service.ProductionAccountService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; /** * <p> * çäº§æ ¸ç®è¡¨ æå¡å®ç°ç±» * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-04-21 03:55:52 */ import java.time.LocalDate; @Service @RequiredArgsConstructor public class ProductionAccountServiceImpl extends ServiceImpl<ProductionAccountMapper, ProductionAccount> implements ProductionAccountService { private final ProductionProductMainMapper productionProductMainMapper; @Override public IPage<ProductionAccountVo> listPage(Page<ProductionAccountDto> page, ProductionAccountDto dto) { ProductionAccountDto queryDto = normalizeDateQuery(dto); return baseMapper.listPage(page, queryDto); } @Override public IPage<ProductionProductMainDto> listProductionDetails(ProductionAccountDto dto, Page page) { return productionProductMainMapper.listProductionDetails(normalizeDateQuery(dto), page); } private ProductionAccountDto normalizeDateQuery(ProductionAccountDto dto) { if (dto == null) { return new ProductionAccountDto(); } LocalDate[] dateRange = dto.getDateRange(); if ((dto.getEntryDateStart() == null || dto.getEntryDateEnd() == null) && dateRange != null && dateRange.length > 0) { if (dto.getEntryDateStart() == null) { dto.setEntryDateStart(dateRange[0]); } if (dto.getEntryDateEnd() == null) { dto.setEntryDateEnd(dateRange.length > 1 ? dateRange[1] : dateRange[0]); } } String dateType = dto.getDateType(); if ("day".equalsIgnoreCase(dateType)) { if (dto.getEntryDate() == null && dateRange != null && dateRange.length > 0) { dto.setEntryDate(dateRange[0]); } if (dto.getEntryDate() == null) { dto.setEntryDate(dto.getEntryDateStart()); } dto.setEntryDateStart(null); dto.setEntryDateEnd(null); } else if ("month".equalsIgnoreCase(dateType)) { if ((dto.getEntryDateStart() == null || dto.getEntryDateEnd() == null) && dto.getEntryDate() != null) { LocalDate monthDate = dto.getEntryDate(); dto.setEntryDateStart(monthDate.withDayOfMonth(1)); dto.setEntryDateEnd(monthDate.withDayOfMonth(monthDate.lengthOfMonth())); } dto.setEntryDate(null); } return dto; } } src/main/java/com/ruoyi/production/service/impl/ProductionOperationTaskServiceImpl.java
@@ -1,42 +1,82 @@ package com.ruoyi.production.service.impl; import cn.hutool.core.bean.BeanUtil; import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.data.PictureRenderData; import com.deepoove.poi.data.PictureType; import com.deepoove.poi.data.Pictures; import com.ruoyi.basic.dto.StorageAttachmentDTO; import com.ruoyi.basic.dto.StorageBlobVO; import com.ruoyi.basic.enums.RecordTypeEnum; import com.ruoyi.basic.utils.FileUtil; import com.ruoyi.common.config.FileProperties; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.MatrixToImageWriter; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.production.bean.dto.ProductionOperationTaskDto; import com.ruoyi.production.bean.vo.ProductionOperationTaskVo; import com.ruoyi.production.mapper.ProductionOperationTaskMapper; import com.ruoyi.production.pojo.ProductionOperationTask; import com.ruoyi.production.service.ProductionOperationTaskService; import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.mapper.SysUserMapper; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.util.List; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import java.util.*; import java.util.stream.Collectors; @Service @RequiredArgsConstructor public class ProductionOperationTaskServiceImpl extends ServiceImpl<ProductionOperationTaskMapper, ProductionOperationTask> implements ProductionOperationTaskService { private final SysUserMapper sysUserMapper; private final FileUtil fileUtil; private final FileProperties fileProperties; @Value("${file.temp-dir}") private String tempDir; @Override public IPage<ProductionOperationTaskVo> pageProductionOperationTask(Page<ProductionOperationTaskDto> page, ProductionOperationTaskDto dto) { Page<ProductionOperationTaskVo> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal()); return baseMapper.pageProductionOperationTask(voPage, dto); IPage<ProductionOperationTaskVo> result = baseMapper.pageProductionOperationTask(voPage, dto); fillUserNames(result.getRecords()); return result; } @Override public List<ProductionOperationTaskVo> listProductionOperationTask(ProductionOperationTaskDto dto) { return BeanUtil.copyToList(this.list(buildQueryWrapper(dto)), ProductionOperationTaskVo.class); List<ProductionOperationTaskVo> result = BeanUtil.copyToList(this.list(buildQueryWrapper(dto)), ProductionOperationTaskVo.class); fillUserNames(result); return result; } @Override public ProductionOperationTaskVo getProductionOperationTaskInfo(Long id) { ProductionOperationTask item = this.getById(id); return item == null ? null : BeanUtil.copyProperties(item, ProductionOperationTaskVo.class); if (item == null) { return null; } ProductionOperationTaskVo vo = BeanUtil.copyProperties(item, ProductionOperationTaskVo.class); fillUserNames(Collections.singletonList(vo)); return vo; } @Override @@ -47,6 +87,27 @@ @Override public boolean removeProductionOperationTask(List<Long> ids) { return ids != null && !ids.isEmpty() && this.removeByIds(ids); } @Override public int updateProductWorkOrder(ProductionOperationTaskDto dto) { return baseMapper.updateById(dto); } @Override public boolean assign(ProductionOperationTaskDto dto) { if (dto == null || dto.getId() == null) { throw new ServiceException("å·¥åIDä¸è½ä¸ºç©º"); } ProductionOperationTask update = new ProductionOperationTask(); update.setId(dto.getId()); update.setUserIds(dto.getUserIds()); int rows = baseMapper.updateById(update); if (rows <= 0) { throw new ServiceException("å·¥åä¸å卿已å é¤"); } return true; } private LambdaQueryWrapper<ProductionOperationTask> buildQueryWrapper(ProductionOperationTaskDto dto) { @@ -62,8 +123,219 @@ .orderByDesc(ProductionOperationTask::getId); } private void fillUserNames(List<ProductionOperationTaskVo> voList) { if (voList == null || voList.isEmpty()) { return; } Set<Long> userIdSet = new LinkedHashSet<>(); for (ProductionOperationTaskVo vo : voList) { if (vo == null) { continue; } userIdSet.addAll(parseUserIdList(vo.getUserIds(), false)); } if (userIdSet.isEmpty()) { return; } List<SysUser> userList = sysUserMapper.selectUsersByIds(new ArrayList<>(userIdSet)); if (userList == null || userList.isEmpty()) { return; } Map<Long, String> userNameById = userList.stream() .filter(item -> item.getUserId() != null) .collect(Collectors.toMap(SysUser::getUserId, SysUser::getNickName, (left, right) -> left)); for (ProductionOperationTaskVo vo : voList) { if (vo == null) { continue; } List<Long> userIds = parseUserIdList(vo.getUserIds(), false); if (userIds.isEmpty()) { vo.setUserNames(null); continue; } String userNames = userIds.stream() .map(userNameById::get) .filter(StringUtils::isNotBlank) .collect(Collectors.joining(",")); vo.setUserNames(userNames); } } private List<Long> parseUserIdList(String userIds, boolean strict) { if (StringUtils.isBlank(userIds)) { if (strict) { throw new ServiceException("userIdsæ ¼å¼ä¸æ£ç¡®ï¼å¿ 须为JSONæ°åæ°ç»"); } return new ArrayList<>(); } String text = userIds.trim(); try { List<Long> parsed = JSON.parseArray(text, Long.class); LinkedHashSet<Long> idSet = parsed == null ? new LinkedHashSet<>() : parsed.stream() .filter(Objects::nonNull) .collect(Collectors.toCollection(LinkedHashSet::new)); if (strict && idSet.isEmpty()) { throw new ServiceException("userIdsæ ¼å¼ä¸æ£ç¡®ï¼å¿ 须为JSONæ°åæ°ç»"); } return new ArrayList<>(idSet); } catch (Exception e) { if (strict) { throw new ServiceException("userIdsæ ¼å¼ä¸æ£ç¡®ï¼å¿ 须为JSONæ°åæ°ç»"); } return new ArrayList<>(); } } @Override public int updateProductWorkOrder(ProductionOperationTaskDto dto) { return baseMapper.updateById(dto); public void down(HttpServletResponse response, ProductionOperationTaskDto dto) { if (dto == null || dto.getId() == null) { throw new ServiceException("å·¥åIDä¸è½ä¸ºç©º"); } ProductionOperationTaskDto taskDto = baseMapper.getProductWorkOrderFlowCard(dto.getId()); if (taskDto == null) { throw new ServiceException("å·¥åä¸åå¨ï¼ID=" + dto.getId()); } String codePath; try { codePath = new MatrixToImageWriter().code(taskDto.getId().toString(), tempDir); } catch (Exception e) { throw new ServiceException("çæäºç»´ç 失败"); } List<Map<String, Object>> images = buildTaskAttachmentImages(taskDto.getId()); Map<String, Object> renderData = new HashMap<>(); renderData.put("process", taskDto.getProcessName()); renderData.put("workOrderNo", taskDto.getWorkOrderNo()); renderData.put("productOrderNpsNo", taskDto.getProductOrderNpsNo()); renderData.put("productName", taskDto.getProductName()); renderData.put("planQuantity", taskDto.getPlanQuantity()); renderData.put("model", taskDto.getModel()); renderData.put("completeQuantity", taskDto.getCompleteQuantity()); renderData.put("scrapQty", taskDto.getScrapQty()); renderData.put("planStartTime", taskDto.getPlanStartTime()); renderData.put("planEndTime", taskDto.getPlanEndTime()); renderData.put("actualStartTime", taskDto.getActualStartTime()); renderData.put("actualEndTime", taskDto.getActualEndTime()); renderData.put("twoCode", Pictures.ofLocal(codePath).create()); renderData.put("images", images.isEmpty() ? null : images); try (InputStream inputStream = this.getClass().getResourceAsStream("/static/work-order-template.docx")) { if (inputStream == null) { throw new ServiceException("æµè½¬å¡æ¨¡æ¿ä¸åå¨"); } XWPFTemplate template = XWPFTemplate.compile(inputStream).render(renderData); response.setContentType("application/msword"); String fileName = URLEncoder.encode("æµè½¬å¡", "UTF-8"); response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".docx"); try (OutputStream os = response.getOutputStream()) { template.write(os); os.flush(); } } catch (Exception e) { throw new RuntimeException("导åºå¤±è´¥"); } } private List<Map<String, Object>> buildTaskAttachmentImages(Long taskId) { List<Map<String, Object>> images = new ArrayList<>(); StorageAttachmentDTO storageAttachmentDTO = new StorageAttachmentDTO(); storageAttachmentDTO.setRecordType(RecordTypeEnum.PRODUCTION_OPERATION_TASK.getType()); storageAttachmentDTO.setRecordId(taskId); List<StorageBlobVO> taskWorkOrderFiles = fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(storageAttachmentDTO); if (CollectionUtils.isEmpty(taskWorkOrderFiles)) { return images; } for (StorageBlobVO blobVO : taskWorkOrderFiles) { if (blobVO == null) { continue; } PictureType pictureType = resolvePictureType(blobVO); if (pictureType == null) { continue; } File imageFile = resolveImageFile(blobVO); if (imageFile == null || !imageFile.exists() || !imageFile.isFile()) { continue; } try (InputStream imageInputStream = new FileInputStream(imageFile)) { Map<String, Object> image = new HashMap<>(); PictureRenderData pictureRenderData = Pictures.ofStream(imageInputStream, pictureType) .sizeInCm(17, 20) .create(); image.put("url", pictureRenderData); images.add(image); } catch (Exception ignored) { // å个éä»¶è§£æå¤±è´¥æ¶è·³è¿ï¼é¿å å½±åæ´ä¸ªæµè½¬å¡å¯¼åº } } return images; } private File resolveImageFile(StorageBlobVO blobVO) { if (blobVO == null || StringUtils.isBlank(blobVO.getUidFilename())) { return null; } if (StringUtils.isBlank(blobVO.getPath())) { return new File(fileProperties.getPath(), blobVO.getUidFilename()); } return new File(new File(fileProperties.getPath(), blobVO.getPath()), blobVO.getUidFilename()); } private PictureType resolvePictureType(StorageBlobVO blobVO) { if (blobVO == null) { return null; } PictureType type = parsePictureTypeByFileName(blobVO.getOriginalFilename()); if (type != null) { return type; } type = parsePictureTypeByFileName(blobVO.getUidFilename()); if (type != null) { return type; } return parsePictureTypeByContentType(blobVO.getContentType()); } private PictureType parsePictureTypeByFileName(String fileName) { if (StringUtils.isBlank(fileName) || !fileName.contains(".")) { return null; } try { return PictureType.suggestFileType(fileName); } catch (Exception ex) { return null; } } private PictureType parsePictureTypeByContentType(String contentType) { if (StringUtils.isBlank(contentType)) { return null; } String normalized = contentType.trim().toLowerCase(Locale.ROOT); switch (normalized) { case "image/jpeg": case "image/jpg": case "image/pjpeg": return PictureType.JPEG; case "image/png": return PictureType.PNG; case "image/gif": return PictureType.GIF; case "image/bmp": case "image/x-ms-bmp": return PictureType.BMP; case "image/tiff": case "image/tif": return PictureType.TIFF; case "image/svg+xml": return PictureType.SVG; default: return null; } } } src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationParamServiceImpl.java
@@ -75,6 +75,10 @@ ProductionOrderRoutingOperationParam query = dto == null ? new ProductionOrderRoutingOperationParam() : dto; return Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery() .eq(query.getId() != null, ProductionOrderRoutingOperationParam::getId, query.getId()) .eq(query.getProductionProductMainId() != null, ProductionOrderRoutingOperationParam::getProductionProductMainId, query.getProductionProductMainId()) .isNull(query.getProductionProductMainId() == null, ProductionOrderRoutingOperationParam::getProductionProductMainId) .eq(query.getProductionOrderId() != null, ProductionOrderRoutingOperationParam::getProductionOrderId, query.getProductionOrderId()) .eq(query.getProductionOrderRoutingOperationId() != null, ProductionOrderRoutingOperationParam::getProductionOrderRoutingOperationId, query.getProductionOrderRoutingOperationId()) .eq(query.getTechnologyOperationId() != null, @@ -148,6 +152,7 @@ private void checkDuplicate(ProductionOrderRoutingOperationParam item) { boolean duplicate = productionOrderRoutingOperationParamMapper.selectCount( Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery() .isNull(ProductionOrderRoutingOperationParam::getProductionProductMainId) .eq(ProductionOrderRoutingOperationParam::getProductionOrderRoutingOperationId, item.getProductionOrderRoutingOperationId()) .eq(item.getTechnologyRoutingOperationParamId() != null, ProductionOrderRoutingOperationParam::getTechnologyRoutingOperationParamId, item.getTechnologyRoutingOperationParamId()) src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -40,10 +40,14 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; @Service @@ -75,7 +79,9 @@ @Override public IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, ProductionProductMainDto productionProductMainDto) { return productionProductMainMapper.listPageProductionProductMainDto(page, productionProductMainDto); IPage<ProductionProductMainDto> result = productionProductMainMapper.listPageProductionProductMainDto(page, productionProductMainDto); fillOperationParamList(result.getRecords()); return result; } @Override @@ -85,9 +91,119 @@ @Override public ProductionProductMainDto getProductionProductMainInfo(Long id) { return productionProductMainMapper.listPageProductionProductMainDto(new Page<>(1, 1), new ProductionProductMainDto() {{ return listPageProductionProductMainDto(new Page<>(1, 1), new ProductionProductMainDto() {{ setId(id); }}).getRecords().stream().findFirst().orElse(null); } private void fillOperationParamList(List<ProductionProductMainDto> recordList) { if (recordList == null || recordList.isEmpty()) { return; } Set<Long> mainIdSet = recordList.stream() .map(ProductionProductMainDto::getId) .filter(Objects::nonNull) .collect(Collectors.toCollection(LinkedHashSet::new)); if (mainIdSet.isEmpty()) { recordList.forEach(item -> item.setProductionOperationParamList(Collections.emptyList())); return; } List<ProductionOrderRoutingOperationParam> paramList = productionOrderRoutingOperationParamMapper.selectList( Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery() .in(ProductionOrderRoutingOperationParam::getProductionProductMainId, mainIdSet) .orderByAsc(ProductionOrderRoutingOperationParam::getId)); Map<Long, List<ProductionOrderRoutingOperationParam>> paramGroupMap = new HashMap<>(); for (ProductionOrderRoutingOperationParam param : paramList) { if (param == null || param.getProductionProductMainId() == null) { continue; } paramGroupMap.computeIfAbsent(param.getProductionProductMainId(), key -> new ArrayList<>()).add(param); } Set<Long> missingMainIdSet = new LinkedHashSet<>(); for (ProductionProductMainDto item : recordList) { Long mainId = item.getId(); if (mainId == null) { item.setProductionOperationParamList(Collections.emptyList()); continue; } List<ProductionOrderRoutingOperationParam> params = paramGroupMap.get(mainId); if (params != null && !params.isEmpty()) { item.setProductionOperationParamList(params); continue; } missingMainIdSet.add(mainId); } if (missingMainIdSet.isEmpty()) { return; } // å ¼å®¹å岿°æ®ï¼æ§æ¥å·¥è®°å½æ²¡æææ¥å·¥IDè½åæ°å¿«ç §æ¶ï¼åéå±ç¤ºå·¥åºæ¨¡æ¿åæ°ã List<ProductionProductMain> mainList = productionProductMainMapper.selectBatchIds(missingMainIdSet); Map<Long, Long> mainIdToTaskIdMap = mainList.stream() .filter(Objects::nonNull) .filter(item -> item.getId() != null) .collect(Collectors.toMap(ProductionProductMain::getId, ProductionProductMain::getProductionOperationTaskId, (left, right) -> left)); Set<Long> taskIdSet = mainIdToTaskIdMap.values().stream() .filter(Objects::nonNull) .collect(Collectors.toCollection(LinkedHashSet::new)); if (taskIdSet.isEmpty()) { for (ProductionProductMainDto item : recordList) { if (item.getId() != null && missingMainIdSet.contains(item.getId())) { item.setProductionOperationParamList(Collections.emptyList()); } } return; } List<ProductionOperationTask> taskList = productionOperationTaskMapper.selectList( Wrappers.<ProductionOperationTask>lambdaQuery() .in(ProductionOperationTask::getId, taskIdSet)); Map<Long, Long> taskIdToRoutingOperationIdMap = taskList.stream() .filter(Objects::nonNull) .filter(item -> item.getId() != null) .collect(Collectors.toMap(ProductionOperationTask::getId, ProductionOperationTask::getProductionOrderRoutingOperationId, (left, right) -> left)); Set<Long> routingOperationIdSet = taskIdToRoutingOperationIdMap.values().stream() .filter(Objects::nonNull) .collect(Collectors.toCollection(LinkedHashSet::new)); if (routingOperationIdSet.isEmpty()) { for (ProductionProductMainDto item : recordList) { if (item.getId() != null && missingMainIdSet.contains(item.getId())) { item.setProductionOperationParamList(Collections.emptyList()); } } return; } List<ProductionOrderRoutingOperationParam> fallbackParamList = productionOrderRoutingOperationParamMapper.selectList( Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery() .in(ProductionOrderRoutingOperationParam::getProductionOrderRoutingOperationId, routingOperationIdSet) .isNull(ProductionOrderRoutingOperationParam::getProductionProductMainId) .orderByAsc(ProductionOrderRoutingOperationParam::getId)); Map<Long, List<ProductionOrderRoutingOperationParam>> fallbackGroupMap = new HashMap<>(); for (ProductionOrderRoutingOperationParam param : fallbackParamList) { if (param == null || param.getProductionOrderRoutingOperationId() == null) { continue; } fallbackGroupMap.computeIfAbsent(param.getProductionOrderRoutingOperationId(), key -> new ArrayList<>()).add(param); } for (ProductionProductMainDto item : recordList) { Long mainId = item.getId(); if (mainId == null || !missingMainIdSet.contains(mainId)) { continue; } Long taskId = mainIdToTaskIdMap.get(mainId); Long routingOperationId = taskId == null ? null : taskIdToRoutingOperationIdMap.get(taskId); if (routingOperationId == null) { item.setProductionOperationParamList(Collections.emptyList()); continue; } item.setProductionOperationParamList(fallbackGroupMap.getOrDefault(routingOperationId, Collections.emptyList())); } } @Override @@ -132,7 +248,6 @@ if (productionOrder == null) { throw new ServiceException("ç产订åä¸åå¨"); } syncOperationParamInputValue(dto, routingOperation.getId()); TechnologyRoutingOperation technologyRoutingOperation = technologyRoutingOperationMapper.selectById(routingOperation.getTechnologyRoutingOperationId()); TechnologyOperation technologyOperation = technologyRoutingOperation == null ? null : technologyOperationMapper.selectById(technologyRoutingOperation.getTechnologyOperationId()); @@ -149,11 +264,16 @@ productionProductMain.setProductionOperationTaskId(taskId); productionProductMain.setStatus(0); productionProductMainMapper.insert(productionProductMain); syncOperationParamInputValue(dto, routingOperation.getId(), productionProductMain.getId()); List<ProductStructureDto> productStructureDtos = resolveInputStructures( productionOrder.getId(), routingOperation, productModel.getId()); // å¦ææ²¡æbomåèç¹äºï¼é£ä¹æå ¥å°±æ¯ä»æ¬èº« if (productStructureDtos.isEmpty()) { throw new ServiceException("æªæ¾å°å½åå·¥åºå¯¹åºçBOMæå ¥èç¹"); ProductStructureDto fallbackInput = new ProductStructureDto(); fallbackInput.setProductModelId(productModel.getId()); fallbackInput.setUnitQuantity(BigDecimal.ONE); productStructureDtos.add(fallbackInput); } for (ProductStructureDto item : productStructureDtos) { // å½åå®ç°æå·¥åºæåç´æ¥ä½ä¸ºæå ¥ï¼åç»è¥æ¥å ¥é¢æè®°å½å¯å¨è¿éæ¿æ¢æ¥æºã @@ -199,7 +319,7 @@ qualityInspect.setProductModelId(productModel.getId()); qualityInspectMapper.insert(qualityInspect); List<QualityTestStandard> qualityTestStandard = qualityTestStandardMapper.getQualityTestStandardByProductId(product.getId(), inspectType, process); if (qualityTestStandard.size() > 0) { if (!qualityTestStandard.isEmpty()) { qualityInspect.setTestStandardId(qualityTestStandard.get(0).getId()); qualityInspectMapper.updateById(qualityInspect); qualityTestStandardParamMapper.selectList(Wrappers.<QualityTestStandardParam>lambdaQuery() @@ -270,20 +390,33 @@ return true; } private void syncOperationParamInputValue(ProductionProductMainDto dto, Long productionOrderRoutingOperationId) { if (dto == null || productionOrderRoutingOperationId == null) { private void syncOperationParamInputValue(ProductionProductMainDto dto, Long productionOrderRoutingOperationId, Long productionProductMainId) { if (dto == null || productionOrderRoutingOperationId == null || productionProductMainId == null) { return; } List<ProductionOrderRoutingOperationParam> paramList = dto.getProductionOperationParamList(); if (paramList == null || paramList.isEmpty()) { return; } Set<Long> sourceParamIdSet = paramList.stream() .filter(Objects::nonNull) .map(ProductionOrderRoutingOperationParam::getId) .filter(Objects::nonNull) .collect(Collectors.toCollection(LinkedHashSet::new)); if (sourceParamIdSet.isEmpty()) { return; } List<ProductionOrderRoutingOperationParam> dbParamList = productionOrderRoutingOperationParamMapper.selectList( Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery() .in(ProductionOrderRoutingOperationParam::getId, sourceParamIdSet) .eq(ProductionOrderRoutingOperationParam::getProductionOrderRoutingOperationId, productionOrderRoutingOperationId)); if (dbParamList == null || dbParamList.isEmpty()) { return; } Map<Long, ProductionOrderRoutingOperationParam> dbParamMap = dbParamList.stream() .filter(item -> item != null && item.getId() != null) .collect(Collectors.toMap(ProductionOrderRoutingOperationParam::getId, item -> item, (left, right) -> left)); @@ -295,14 +428,31 @@ if (dbParam == null) { throw new ServiceException("å·¥åºåæ°ä¸å卿ä¸å±äºå½åå·¥åå·¥åºï¼ID=" + param.getId()); } if (Objects.equals(dbParam.getInputValue(), param.getInputValue())) { continue; } ProductionOrderRoutingOperationParam updateParam = new ProductionOrderRoutingOperationParam(); updateParam.setId(dbParam.getId()); updateParam.setInputValue(param.getInputValue()); productionOrderRoutingOperationParamMapper.updateById(updateParam); productionOrderRoutingOperationParamMapper.insert(buildReportParamSnapshot(dbParam, param.getInputValue(), productionProductMainId)); } } private ProductionOrderRoutingOperationParam buildReportParamSnapshot(ProductionOrderRoutingOperationParam source, String inputValue, Long productionProductMainId) { ProductionOrderRoutingOperationParam target = new ProductionOrderRoutingOperationParam(); target.setProductionOrderId(source.getProductionOrderId()); target.setTechnologyRoutingOperationParamId(source.getTechnologyRoutingOperationParamId()); target.setParamCode(source.getParamCode()); target.setParamName(source.getParamName()); target.setParamType(source.getParamType()); target.setParamFormat(source.getParamFormat()); target.setUnit(source.getUnit()); target.setIsRequired(source.getIsRequired()); target.setRemark(source.getRemark()); target.setParamId(source.getParamId()); target.setTechnologyOperationId(source.getTechnologyOperationId()); target.setTechnologyOperationParamId(source.getTechnologyOperationParamId()); target.setStandardValue(source.getStandardValue()); target.setInputValue(inputValue); target.setProductionOrderRoutingOperationId(source.getProductionOrderRoutingOperationId()); target.setProductionProductMainId(productionProductMainId); return target; } private List<ProductStructureDto> resolveInputStructures(Long productionOrderId, @@ -431,6 +581,9 @@ .eq(ProductionProductOutput::getProductionProductMainId, productionProductMain.getId())); productionProductInputMapper.delete(new LambdaQueryWrapper<ProductionProductInput>() .eq(ProductionProductInput::getProductionProductMainId, productionProductMain.getId())); productionOrderRoutingOperationParamMapper.delete( Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery() .eq(ProductionOrderRoutingOperationParam::getProductionProductMainId, productionProductMain.getId())); stockUtils.deleteStockInRecord(productionProductMain.getId(), StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode()); stockUtils.deleteStockInRecord(productionProductMain.getId(), StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode()); stockUtils.deleteStockOutRecord(productionProductMain.getId(), StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode()); src/main/java/com/ruoyi/technology/service/impl/TechnologyRoutingServiceImpl.java
@@ -122,7 +122,7 @@ throw new ServiceException("bom产åç»æä¸ºç©ºï¼"); } // åä¸ä¸ª BOM ä¸å¯è½éå¤å¼ç¨ç¸åå·¥åºï¼è¿éæé¦æ¬¡åºç°é¡ºåºå»éã // åä¸ä¸ª BOM ä¸å¯è½éå¤å¼ç¨ç¸åå·¥åºï¼æç §ä¸ä¸å±çç¶èç¹çäº§åæ¯å¦ç¸ååå·¥åºæ¯å¦ç¸å Map<Long, TechnologyBomStructure> structureById = new HashMap<>(); for (TechnologyBomStructure bomStructure : bomStructures) { if (bomStructure != null && bomStructure.getId() != null) { src/main/resources/mapper/production/ProductionAccountMapper.xml
@@ -21,6 +21,74 @@ <result column="dept_id" property="deptId" /> </resultMap> <select id="listPage" resultType="com.ruoyi.production.bean.vo.ProductionAccountVo"> select group_concat(distinct p_parent.product_name order by p_parent.product_name separator ',') as productCategory, group_concat(distinct pm.model order by pm.model separator ',') as specificationModel, group_concat(distinct pm.unit order by pm.unit separator ',') as unit, pa.scheduling_user_id as schedulingUserId, pa.scheduling_user_name as schedulingUserName, cast(sum( ifnull(pa.work_hours, 0) * ifnull(pa.finished_num, 0) * case when substring_index(pm.model, '*', -1) regexp '^[0-9]+(\\.[0-9]+)?$' then cast(substring_index(pm.model, '*', -1) as decimal(18,4)) else 1 end ) as decimal(18,4)) as wages, cast(sum(ifnull(pa.finished_num, 0)) as decimal(18,4)) as finishedNum, cast(sum(ifnull(pa.work_hours, 0)) as decimal(18,4)) as workHours, group_concat(distinct pa.technology_operation_name order by pa.technology_operation_name separator ',') as process, case when count(distinct date(pa.scheduling_date)) = 1 then min(date(pa.scheduling_date)) else null end as schedulingDate, case when count(distinct date_format(pa.scheduling_date, '%Y-%m')) = 1 then min(date_format(pa.scheduling_date, '%Y-%m')) else null end as schedulingMonth from production_account pa left join production_product_main ppm on ppm.id = pa.production_product_main_id left join production_operation_task pot on ppm.production_operation_task_id = pot.id left join production_order po on pot.production_order_id = po.id left join production_order_routing_operation poro on pot.production_order_routing_operation_id = poro.id left join product_model pm on pm.id = ifnull(poro.product_model_id, po.product_model_id) left join product p on pm.product_id = p.id left join product p_parent on p_parent.id = p.parent_id <where> <if test="c != null"> <if test="c.productCategory != null and c.productCategory != ''"> and p_parent.product_name like concat('%', #{c.productCategory}, '%') </if> <if test="c.specificationModel != null and c.specificationModel != ''"> and pm.model like concat('%', #{c.specificationModel}, '%') </if> <if test="c.schedulingUserId != null"> and pa.scheduling_user_id = #{c.schedulingUserId} </if> <if test="c.schedulingUserName != null and c.schedulingUserName != ''"> and pa.scheduling_user_name like concat('%', #{c.schedulingUserName}, '%') </if> <if test="c.process != null and c.process != ''"> and pa.technology_operation_name like concat('%', #{c.process}, '%') </if> <if test="c.entryDate != null"> and date(pa.scheduling_date) = #{c.entryDate} </if> <if test="c.entryDateStart != null"> and date(pa.scheduling_date) >= #{c.entryDateStart} </if> <if test="c.entryDateEnd != null"> and date(pa.scheduling_date) <= #{c.entryDateEnd} </if> </if> </where> group by pa.scheduling_user_id, pa.scheduling_user_name order by wages desc, pa.scheduling_user_id asc </select> <select id="selectUserAccount" resultType="com.ruoyi.production.bean.dto.UserAccountDto"> select ifnull(sum(finished_num), 0) as accountBalance, ifnull(sum(work_hours), 0) as account src/main/resources/mapper/production/ProductionOperationTaskMapper.xml
@@ -120,4 +120,28 @@ group by poro.technology_operation_id, poro.operation_name </select> <select id="getProductWorkOrderFlowCard" resultType="com.ruoyi.production.bean.dto.ProductionOperationTaskDto"> SELECT pot.*, poro.operation_name AS processName, pm.model AS model, pm.unit AS unit, p.product_name AS productName, po.nps_no AS productOrderNpsNo, ROUND(IFNULL(pot.complete_quantity, 0) / NULLIF(pot.plan_quantity, 0) * 100, 2) AS completionStatus, IFNULL(scrapStat.scrapQty, 0) AS scrapQty FROM production_operation_task pot LEFT JOIN production_order po ON pot.production_order_id = po.id LEFT JOIN production_order_routing_operation poro ON pot.production_order_routing_operation_id = poro.id LEFT JOIN product_model pm ON pm.id = ifnull(poro.product_model_id, po.product_model_id) LEFT JOIN product p ON p.id = pm.product_id LEFT JOIN ( SELECT ppm.production_operation_task_id AS taskId, SUM(IFNULL(ppo.scrap_qty, 0)) AS scrapQty FROM production_product_main ppm LEFT JOIN production_product_output ppo ON ppo.production_product_main_id = ppm.id GROUP BY ppm.production_operation_task_id ) scrapStat ON scrapStat.taskId = pot.id WHERE pot.id = #{id} </select> </mapper> src/main/resources/mapper/production/ProductionProductMainMapper.xml
@@ -95,17 +95,59 @@ p.product_name as productName, pm.model as productModelName, pm.unit, poro.operation_name as process, pa.technology_operation_name as process, ifnull(ppo.quantity, 0) as quantity, ifnull(ppo.scrap_qty, 0) as scrapQty from production_product_main ppm ifnull(ppo.scrap_qty, 0) as scrapQty, date(pa.scheduling_date) as schedulingDate, pa.scheduling_user_name as schedulingUserName, cast(ifnull(pa.work_hours, 0) as decimal(18,4)) as workHours, cast( ifnull(pa.work_hours, 0) * ifnull(pa.finished_num, 0) * case when substring_index(pm.model, '*', -1) regexp '^[0-9]+(\\.[0-9]+)?$' then cast(substring_index(pm.model, '*', -1) as decimal(18,4)) else 1 end as decimal(18,4) ) as wages from production_account pa left join production_product_main ppm on ppm.id = pa.production_product_main_id left join production_operation_task pot on ppm.production_operation_task_id = pot.id left join production_order po on pot.production_order_id = po.id left join production_order_routing_operation poro on pot.production_order_routing_operation_id = poro.id left join product_model pm on pm.id = ifnull(poro.product_model_id, po.product_model_id) left join product p on pm.product_id = p.id left join product p_parent on p_parent.id = p.parent_id left join production_product_output ppo on ppo.production_product_main_id = ppm.id order by ppm.create_time desc <where> <if test="c != null"> <if test="c.productCategory != null and c.productCategory != ''"> and p_parent.product_name like concat('%', #{c.productCategory}, '%') </if> <if test="c.specificationModel != null and c.specificationModel != ''"> and pm.model like concat('%', #{c.specificationModel}, '%') </if> <if test="c.schedulingUserId != null"> and pa.scheduling_user_id = #{c.schedulingUserId} </if> <if test="c.schedulingUserName != null and c.schedulingUserName != ''"> and pa.scheduling_user_name like concat('%', #{c.schedulingUserName}, '%') </if> <if test="c.process != null and c.process != ''"> and pa.technology_operation_name like concat('%', #{c.process}, '%') </if> <if test="c.entryDate != null"> and date(pa.scheduling_date) = #{c.entryDate} </if> <if test="c.entryDateStart != null"> and date(pa.scheduling_date) >= #{c.entryDateStart} </if> <if test="c.entryDateEnd != null"> and date(pa.scheduling_date) <= #{c.entryDateEnd} </if> </if> </where> order by pa.scheduling_date desc, pa.id desc </select> <select id="listMain" resultType="java.lang.Long">