From b0dbd5dcde6cba570b5858312b2d65aee3b74c9f Mon Sep 17 00:00:00 2001 From: qinyulong Date: Mon, 19 Jan 2026 10:47:28 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BD=AC=E5=B2=97=E7=AE=A1=E7=90=86=EF=BC=9A?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E7=BB=B4=E6=8A=A4=E5=AF=BC=E5=85=A5=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../excel/EquipmentMaintenanceImport.java | 42 +++++++++ .../impl/IMeasurementRecordsServiceImpl.java | 6 +- .../EquipmentMaintenanceController.java | 35 ++++++++ .../service/IEquipmentMaintenanceService.java | 10 +++ .../impl/EquipmentMaintenanceServiceImpl.java | 85 +++++++++++++++++- .../jobTransfer/设备维护导入模板.xls | Bin 0 -> 20480 bytes .../src/main/resources/application-dev.yml | 2 +- 7 files changed, 175 insertions(+), 5 deletions(-) create mode 100644 blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobtransfer/pojo/excel/EquipmentMaintenanceImport.java create mode 100644 blade-service/blade-desk/src/main/resources/Excel/jobTransfer/设备维护导入模板.xls diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobtransfer/pojo/excel/EquipmentMaintenanceImport.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobtransfer/pojo/excel/EquipmentMaintenanceImport.java new file mode 100644 index 00000000..28269c29 --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobtransfer/pojo/excel/EquipmentMaintenanceImport.java @@ -0,0 +1,42 @@ +package org.springblade.desk.jobtransfer.pojo.excel; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.format.DateTimeFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springblade.core.mp.base.BaseEntity; + +import java.util.Date; + +/** + * 设备维护导入 + * + * @author qyl + * @since 2026-01-19 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class EquipmentMaintenanceImport extends BaseEntity { + + /** + * 用户code + */ + @ExcelProperty(index = 0) + private String userCode; + /** + * 设备编号 + */ + @ExcelProperty(index = 1) + private String deviceCode; + /** + * 设备有效期 + */ + @ExcelProperty(index = 2) + private Integer equipmentValidityPeriod; + /** + * 设备日期 + */ + @ExcelProperty(index = 3) + @DateTimeFormat("yyyy/MM/dd") + private Date equipmentDate; +} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/impl/IMeasurementRecordsServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/impl/IMeasurementRecordsServiceImpl.java index 6d01149b..bf57fd98 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/impl/IMeasurementRecordsServiceImpl.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/impl/IMeasurementRecordsServiceImpl.java @@ -54,7 +54,7 @@ public class IMeasurementRecordsServiceImpl implements IMeasurementRecordsServic return processResponse(response, page); } catch (Exception e) { - log.error("获取量具库存记录数据接口调用失败: {}", e.getMessage(), e); + log.error("获取计量记录记录数据接口调用失败: {}", e.getMessage(), e); return page.setRecords(List.of()); // 返回空列表而不是null } } @@ -91,11 +91,11 @@ public class IMeasurementRecordsServiceImpl implements IMeasurementRecordsServic try { JSONObject result = JSONObject.parseObject(responseBody); - if (result != null && result.getInteger("code") != null && result.getInteger("code").equals(200)) { + if (result != null && result.getBoolean("success")) { JSONObject data = result.getJSONObject("data"); if (data != null) { List records = JSONArray.parseArray(data.toJSONString(), JSONObject.class); - log.info("成功获取{}条量具库存记录", records != null ? records.size() : 0); + log.info("成功获取{}条计量记录记录", records != null ? records.size() : 0); return page.setRecords(records != null ? records : List.of()); } } else { diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/jobtransfer/controller/EquipmentMaintenanceController.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/jobtransfer/controller/EquipmentMaintenanceController.java index a89aef12..b9a76a7d 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/jobtransfer/controller/EquipmentMaintenanceController.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/jobtransfer/controller/EquipmentMaintenanceController.java @@ -16,10 +16,15 @@ import org.springblade.core.mp.support.Condition; import org.springblade.core.mp.support.Query; import org.springblade.core.tool.api.R; import org.springblade.core.tool.utils.Func; +import org.springblade.desk.basic.util.ExcelExtUtil; +import org.springblade.desk.jobtransfer.pojo.excel.CertificateMaintenanceImport; import org.springblade.desk.jobtransfer.pojo.excel.EquipmentMaintenanceExcel; +import org.springblade.desk.jobtransfer.pojo.excel.EquipmentMaintenanceImport; import org.springblade.desk.jobtransfer.pojo.request.EquipmentMaintenanceQuery; import org.springblade.desk.jobtransfer.pojo.vo.*; import org.springframework.beans.BeanUtils; +import org.springframework.core.io.Resource; +import org.springframework.http.ResponseEntity; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.web.bind.annotation.*; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -34,6 +39,7 @@ import java.util.ArrayList; import java.util.List; import jakarta.servlet.http.HttpServletResponse; +import org.springframework.web.multipart.MultipartFile; /** * 岗位设备维护 控制器 @@ -166,6 +172,35 @@ public class EquipmentMaintenanceController extends BladeController { ExcelUtil.export(response, "岗位设备维护数据" + DateUtil.time(), "岗位设备维护数据表", excels, EquipmentMaintenanceExcel.class); } + /** + * 下载Excel模板 + */ + @GetMapping("/downloadExcelTemplate") + @ApiOperationSupport(order = 10) + @Operation(summary = "下载Excel模板", description = "") + public ResponseEntity downloadExcelTemplate() { + return ExcelExtUtil.downloadXlsTemplate( + "Excel/jobtransfer/设备维护导入模板.xls", + "设备维护导入模板.xls"); + } + + /** + * 导入Excel + */ + @PostMapping("/importExcel") + @ApiOperationSupport(order = 11) + @Operation(summary = "导入Excel", description = "MultipartFile") + public R importExcel(@RequestParam("file") MultipartFile file) { + R checkR = ExcelExtUtil.importExcelCheck(file); + if (checkR != null) { + return checkR; + } + List importList = ExcelUtil.read( + file, 0, 1, EquipmentMaintenanceImport.class + ); + return equipmentMaintenanceService.saveExcelData(importList); + } + @PostConstruct // 项目启动后立即执行一次 public void init() { updateMaintenanceStatus(); diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/jobtransfer/service/IEquipmentMaintenanceService.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/jobtransfer/service/IEquipmentMaintenanceService.java index b76f9f01..a656f8b8 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/jobtransfer/service/IEquipmentMaintenanceService.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/jobtransfer/service/IEquipmentMaintenanceService.java @@ -1,8 +1,10 @@ package org.springblade.desk.jobtransfer.service; import com.baomidou.mybatisplus.core.conditions.Wrapper; +import org.springblade.core.tool.api.R; import org.springblade.desk.jobtransfer.pojo.entity.EquipmentMaintenanceEntity; import org.springblade.desk.jobtransfer.pojo.excel.EquipmentMaintenanceExcel; +import org.springblade.desk.jobtransfer.pojo.excel.EquipmentMaintenanceImport; import org.springblade.desk.jobtransfer.pojo.request.EquipmentMaintenanceQuery; import org.springblade.desk.jobtransfer.pojo.vo.EquipmentMaintenanceListVO; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -47,4 +49,12 @@ public interface IEquipmentMaintenanceService extends BaseService importList); } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/jobtransfer/service/impl/EquipmentMaintenanceServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/jobtransfer/service/impl/EquipmentMaintenanceServiceImpl.java index d8e040b6..177350b1 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/jobtransfer/service/impl/EquipmentMaintenanceServiceImpl.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/jobtransfer/service/impl/EquipmentMaintenanceServiceImpl.java @@ -1,17 +1,35 @@ package org.springblade.desk.jobtransfer.service.impl; +import com.alibaba.nacos.common.utils.CollectionUtils; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import jakarta.annotation.Resource; +import org.springblade.core.tool.api.R; +import org.springblade.desk.device.mapper.EquipmentMapper; +import org.springblade.desk.device.pojo.entity.EquipmentEntity; +import org.springblade.desk.jobtransfer.mapper.PostHandleMapper; +import org.springblade.desk.jobtransfer.pojo.entity.CertificateMaintenanceEntity; +import org.springblade.desk.jobtransfer.pojo.entity.CertificateTypeEntity; import org.springblade.desk.jobtransfer.pojo.entity.EquipmentMaintenanceEntity; +import org.springblade.desk.jobtransfer.pojo.entity.PostHandleEntity; +import org.springblade.desk.jobtransfer.pojo.enums.MaintenanceStatusEnum; +import org.springblade.desk.jobtransfer.pojo.enums.PostHandleStatusEnum; +import org.springblade.desk.jobtransfer.pojo.enums.StaffTypeEnum; +import org.springblade.desk.jobtransfer.pojo.excel.CertificateMaintenanceImport; import org.springblade.desk.jobtransfer.pojo.excel.EquipmentMaintenanceExcel; +import org.springblade.desk.jobtransfer.pojo.excel.EquipmentMaintenanceImport; import org.springblade.desk.jobtransfer.pojo.request.EquipmentMaintenanceQuery; import org.springblade.desk.jobtransfer.pojo.vo.EquipmentMaintenanceListVO; import org.springblade.desk.jobtransfer.mapper.EquipmentMaintenanceMapper; import org.springblade.desk.jobtransfer.service.IEquipmentMaintenanceService; +import org.springblade.system.cache.UserCache; +import org.springblade.system.pojo.entity.UserInfo; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import org.springblade.core.mp.base.BaseServiceImpl; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; /** * 岗位设备维护 服务实现类 @@ -22,6 +40,12 @@ import java.util.List; @Service public class EquipmentMaintenanceServiceImpl extends BaseServiceImpl implements IEquipmentMaintenanceService { + @Resource + private PostHandleMapper postHandleMapper; + + @Resource + private EquipmentMapper equipmentMapper; + @Override public IPage selectEquipmentMaintenancePage(IPage page, EquipmentMaintenanceQuery equipmentMaintenanceQuery) { return page.setRecords(baseMapper.selectEquipmentMaintenancePage(page, equipmentMaintenanceQuery)); @@ -50,4 +74,63 @@ public class EquipmentMaintenanceServiceImpl extends BaseServiceImpl importList) { + //获取全部用户codes,通过code获取用户ID, + Set codes = importList.stream().map(EquipmentMaintenanceImport::getUserCode) + .collect(Collectors.toSet()); + Map idCodeMap = codes.stream() + .map(code -> { + UserInfo userInfo = UserCache.getUserByCode(code); + return (userInfo != null && userInfo.getUser() != null) ? + new AbstractMap.SimpleEntry<>(code, userInfo.getUser().getId()) : null; + }) + .filter(Objects::nonNull) + .collect(Collectors.toMap(AbstractMap.SimpleEntry::getValue, AbstractMap.SimpleEntry::getKey)); + //根据用户id获取人员岗位数据 + Collection values = idCodeMap.keySet(); + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.in(PostHandleEntity::getUserId, values) + .eq(PostHandleEntity::getStaffType, StaffTypeEnum.FORMAL.getCode().shortValue()) + .ne(PostHandleEntity::getPhStatus, PostHandleStatusEnum.DEPART.getCode().shortValue()); // 使用实体类的get方法引用 + List postHandleEntities = postHandleMapper.selectList(lambdaQueryWrapper); + Map idMap = postHandleEntities.stream().collect(Collectors.toMap( + entity -> entity.getUserId(), + entity -> entity.getId())); + //整合成一个用户code和PostHandleEntityId的map + Map codePostHandleIdMap = new HashMap<>(); + for (Long l : idMap.keySet()) { + codePostHandleIdMap.put(idCodeMap.get(l), idMap.get(l)); + } + codes.removeAll(codePostHandleIdMap.keySet()); + if (codes.size() > 0) { + return R.fail("工号:" + String.join(",", codes) + "不存在。"); + } + //查询设备信息 + Set deviceCode = importList.stream().map(EquipmentMaintenanceImport::getDeviceCode) + .collect(Collectors.toSet()); + LambdaQueryWrapper equipmentEntityLambdaQueryWrapper = new LambdaQueryWrapper<>(); + equipmentEntityLambdaQueryWrapper.in(CollectionUtils.isNotEmpty(deviceCode), EquipmentEntity::getDeviceCode, deviceCode); // [8](@ref) + List equipmentEntities = equipmentMapper.selectList(equipmentEntityLambdaQueryWrapper); + Map deviceNameIds = equipmentEntities.stream().collect(Collectors.toMap( + entity -> entity.getDeviceCode(), + entity -> entity.getId())); + deviceCode.removeAll(deviceNameIds.keySet()); + if (deviceCode.size() > 0) { + return R.fail("设备:" + String.join(",", deviceCode) + "不存在。"); + } + List saves = new ArrayList<>(); + importList.forEach(e -> { + EquipmentMaintenanceEntity entity = new EquipmentMaintenanceEntity(); + entity.setPhId(codePostHandleIdMap.get(e.getUserCode())); + entity.setEquipmentId(deviceNameIds.get(e.getDeviceCode())); + entity.setEquipmentDate(e.getEquipmentDate()); + entity.setEquipmentValidityPeriod(e.getEquipmentValidityPeriod()); + entity.setMaintenanceStatus(MaintenanceStatusEnum.NORMAL.getCode().shortValue()); + saves.add(entity); + }); + boolean saved = this.saveBatch(saves); + return R.status(saved); + } + } diff --git a/blade-service/blade-desk/src/main/resources/Excel/jobTransfer/设备维护导入模板.xls b/blade-service/blade-desk/src/main/resources/Excel/jobTransfer/设备维护导入模板.xls new file mode 100644 index 0000000000000000000000000000000000000000..a49665048f6344e72f015fb6c22aeaa45d670235 GIT binary patch literal 20480 zcmeG^2UrwY(r<rGw&ga+AUYYO!N5I@j3c8cImXezMjTBEpQjD@G6QH* z74a_y(3oLl0JMAxv^0j(y`UNo6R#=|d;(tR(m zLIR}|grt+PaGl%$B}d?oe6jCp${+i3nUp5Vj-sIaNCS1l)&H?iGW$Q?tLy(*hW#JU z|4aY3HJ~RnCOjQtl+V9|A)ku*pNvNE6VBcV>;oQ^1rAao_3D538Rd~rIM7issXIdv zL%#J-DP;P*VU9R?Q zD=k+(*BfCh(IaQN5i-k_o?!ssA4q?K?)9k%rd%1=lFHfNz5N)OX#D+BA#rv%c;6jh z1(4Cvu{;Pe`aw^~IM*2f8Rs(bkWs#Aka4~<4>Hbg@*rcZ+z!DK=P+0|F*TLC#`?G3 zJbfy<@FR7Pu`y!o=(LoHDGBMKuqmU(NfbX4+|=UacQ<%JP@X+tykb0r`+p>S4&mydfw0jAA@VgDyO+T^RqtGbtGoT1wK80y53R2&!L zrX3Z2 zqO1pm+XyV6UqNKCE3|9l(x#2OA6&$Ape}6$t%we;pyXx4qQvpTnFuxz$Y6OTLvVFx z)`vSAK^ss#1S%#5iwcG2L)sHhLSjXL*j_}jj}`ezZ>91m0CpYhsGFczk&VEWIKdC9 zGV8S$F)OtfDb)xhE~JYxGY~>SURqTN1_S~F6->Q}Gx1UG0hNNY+N%RmoePdLQwpAEVzSC$l>rgZ`p2C-8lI3)Y+Gzg1U{6U zI3uRuEIDyT%mp`-!Eck1L82fCsIq?KOyjG_>BI@gokWVhTyL~L;O-(Vr-=zICoMnj zILP31yJ&v{MbU7U{Hp$=&aXOAdQiou^`i>+QiC6$1}^hkshkBSCguj_U>7<*Si)Gx zBX;!mDYS)1y`f zQ57&=H>v^}wow(ZL5-?_p{G$5FeWvs0tTf~5Km^@YJrRt` z8W2GjR!;;&vIa!Zt<@93`2Cke%EBAA4hDM-h%{^+43HWSY1lgW2bTs!8nzDpL#6?d zhOL8tv1vf0Ve7P1A_6zcahUEqo?Z=G2mj<#NTQZV!`8taHVue0Y#m$8h%{^+k!D01 zwoYr!h$vf!Jxao;-f$>nS7@VD0srJ-4Xf<1XRjotN(G^GfNt3SZT}TS+G#>W5~wT* zyZsJ8L@{=#G)Fb;JIcA@y10PoNR$+Y{*MKc3)duy5Xa`~B=4KuKs=`v1=pKHGr1{G2gMODyvXzBWb)(LJ z_Lsvq{U4elkg|;o8^xLsX?P;xrx}rkCldae5ovfL(N!}d4NoKjG$W!skzo5+AP}J) zpR<3;9A6?SQ}M9_2M(yjHYQBw_y_|oRFcIuCM;9v$QlKL0GG!(fT`kkYXoj^1GxSy z8A1S;d#qFFgh*gSrxcSZWY-UEu)Y?#S_=p`BT!R6tdaHEI_wVhHPvAcwYbaqmhg0+ zKH+&1chZ)KNC(J4lhbC1U=wMXum@zQD@{CsjYJ>*KvKoT&dYmEmT~hj4e&8ImxA8!sm zo}7Gekd?MaPn_`h^-tV<%#lw=4lh#mH(TJtg(>GFC<{Mz?-e(n7TkQe{H+ZqAEv*R zg@3rRo12dXHywA`hDLlZay~Le7OA0k&_S8-#oo8UAn~0$CjH9m%q7i@?rX$ zrxr>!l~BGWT;qHd2v&~m;WJP8laCFv%vUcF4{tcB;gY*!6^zgmcryM zbimg#Uo(U!=mm6LdYtacs&5RB31fXMMc-ASp$pIU>%xx8u(fx9)pEWe4E}P8=&@{y zCUT0jmuf(`SOL}7_%4unO8VkRuTDOY?1QQh5vU!=FFk0GFySnnM0W}od0Wt7#j1i`Tc7ipBvn1bstJcS2K35DP2fZqs+OSS+SWu@FG zZ2^#USj-!N4MD69*}8xwVqximsE9QTf-`8I!qp?LDCx$9tEMg!rYKk7n*&)a!8Hxe zXHZkPW|y@XH!&!!q10H2n?|(MiaViFnV!5vdcEx03b?0qK~n1DN(K zOdW}?98=kkI-wu&b3621CiGFR#A^wDgeA$lFd+as%a{DoU)3L* z105`3`T)}((U401hyaB@(sxWB;K4I3w1((194CBe{$dXPW)y$15`Ww-lC>i+FhiMt z>J6QuQNKIVo~X*Yz#pwu(hmIW)Ruf zgbl&17I|mFp{k359u8G(dadR3m=h{OUS@hwicz8Gr=W)e6`NjLIX&jYi4a+5SE1*x zpoha0o1T-L9&>^OZ7d<&@^w|vLo2Z9b&%6zPK02>kam`vUVwrgPJY<*JmmD46COfR zclY3;rw5PILI?RZ>GINL!Vy4^8J_gPL9qm$N0$d|+!B$+MBFD*^auJ*)*t9QS%0AK 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