diff --git a/java110-bean/src/main/java/com/java110/dto/inspection/InspectionTaskDetailDto.java b/java110-bean/src/main/java/com/java110/dto/inspection/InspectionTaskDetailDto.java index 3ce9955..b42c63f 100644 --- a/java110-bean/src/main/java/com/java110/dto/inspection/InspectionTaskDetailDto.java +++ b/java110-bean/src/main/java/com/java110/dto/inspection/InspectionTaskDetailDto.java @@ -79,6 +79,8 @@ public class InspectionTaskDetailDto extends PageDto implements Serializable { private String lat; + private String source; + public String getInspectionId() { return inspectionId; } @@ -430,4 +432,12 @@ public class InspectionTaskDetailDto extends PageDto implements Serializable { public void setLat(String lat) { this.lat = lat; } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } } diff --git a/java110-bean/src/main/java/com/java110/po/inspection/InspectionTaskDetailPo.java b/java110-bean/src/main/java/com/java110/po/inspection/InspectionTaskDetailPo.java index 3d6db6d..d510df2 100755 --- a/java110-bean/src/main/java/com/java110/po/inspection/InspectionTaskDetailPo.java +++ b/java110-bean/src/main/java/com/java110/po/inspection/InspectionTaskDetailPo.java @@ -42,6 +42,8 @@ public class InspectionTaskDetailPo implements Serializable { private String sendFlag; + private String source; + private String statusCd; public String getTaskDetailId() { @@ -195,4 +197,12 @@ public class InspectionTaskDetailPo implements Serializable { public void setStatusCd(String statusCd) { this.statusCd = statusCd; } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } } diff --git a/java110-core/src/main/java/com/java110/core/factory/Java110TransactionalFactory.java b/java110-core/src/main/java/com/java110/core/factory/Java110TransactionalFactory.java index 54ba154..95f1d86 100755 --- a/java110-core/src/main/java/com/java110/core/factory/Java110TransactionalFactory.java +++ b/java110-core/src/main/java/com/java110/core/factory/Java110TransactionalFactory.java @@ -176,13 +176,44 @@ public class Java110TransactionalFactory { * @param orderDto */ private static void createOIdByBoot(OrderDto orderDto) { + // 优化:通过反射直接调用Service Bean,避免HTTP自调用(127.0.0.1:8008) + // 原HTTP方式占用Tomcat线程+序列化开销,改为直接调用消除网络+线程池开销 + ResponseEntity responseEntity = null; + try { + Object oIdServiceSMO = ApplicationContextFactory.getBean("oIdServiceSMOImpl"); + java.lang.reflect.Method createOIdMethod = oIdServiceSMO.getClass() + .getMethod("createOId", OrderDto.class); + responseEntity = (ResponseEntity) createOIdMethod.invoke(oIdServiceSMO, orderDto); + } catch (Exception e) { + logger.error("直接调用createOId失败,降级使用HTTP方式", e); + // 降级:反射失败时使用原HTTP方式 + createOIdByBootHttp(orderDto); + return; + } + + if (responseEntity.getStatusCode() != HttpStatus.OK) { + throw new IllegalArgumentException("创建事务失败" + responseEntity.getBody()); + } + JSONObject order = JSONObject.parseObject(responseEntity.getBody()); + + if (!order.containsKey("oId") || StringUtils.isEmpty(order.getString("oId"))) { + throw new IllegalArgumentException("创建事务失败" + responseEntity.getBody()); + } + orderDto.setoId(order.getString("oId")); + put(O_ID, orderDto.getoId()); + } + + /** + * 原HTTP方式创建事务(作为反射方式的降级方案) + */ + private static void createOIdByBootHttp(OrderDto orderDto) { RestTemplate restTemplate = ApplicationContextFactory.getBean("outRestTemplate", RestTemplate.class); HttpHeaders header = new HttpHeaders(); HttpEntity httpEntity = new HttpEntity(JSONObject.toJSONString(orderDto), header); ResponseEntity responseEntity = null; try { responseEntity = restTemplate.exchange(BOOT_CREATE_O_ID, HttpMethod.POST, httpEntity, String.class); - } catch (HttpStatusCodeException e) { //这里spring 框架 在4XX 或 5XX 时抛出 HttpServerErrorException 异常,需要重新封装一下 + } catch (HttpStatusCodeException e) { responseEntity = new ResponseEntity(e.getResponseBodyAsString(), e.getStatusCode()); } catch (Exception e) { responseEntity = new ResponseEntity(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); @@ -193,12 +224,10 @@ public class Java110TransactionalFactory { throw new IllegalArgumentException("创建事务失败" + responseEntity.getBody()); } JSONObject order = JSONObject.parseObject(responseEntity.getBody()); - if (!order.containsKey("oId") || StringUtils.isEmpty(order.getString("oId"))) { throw new IllegalArgumentException("创建事务失败" + responseEntity.getBody()); } orderDto.setoId(order.getString("oId")); - //将事务ID 存放起来 put(O_ID, orderDto.getoId()); } diff --git a/java110-core/src/main/java/com/java110/core/trace/Java110TraceHandlerInterceptor.java b/java110-core/src/main/java/com/java110/core/trace/Java110TraceHandlerInterceptor.java index e485f30..ceac90b 100644 --- a/java110-core/src/main/java/com/java110/core/trace/Java110TraceHandlerInterceptor.java +++ b/java110-core/src/main/java/com/java110/core/trace/Java110TraceHandlerInterceptor.java @@ -23,8 +23,12 @@ public class Java110TraceHandlerInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + // 优化:trace未开启时跳过header遍历,避免每个请求都迭代所有headers + if (!"ON".equals(System.getenv("trace_switch")) + && !"ON".equals(System.getProperty("trace_switch"))) { + return true; + } logger.debug("进入拦截器Java110TraceHandlerInterceptor>>preHandle"); - // 获取组件名称 和方法名称 String url = request.getRequestURI() != null ? request.getRequestURI() : ""; Map headers = new HashMap<>(); Enumeration reqHeaderEnum = request.getHeaderNames(); @@ -32,7 +36,6 @@ public class Java110TraceHandlerInterceptor extends HandlerInterceptorAdapter { String headerName = (String) reqHeaderEnum.nextElement(); headers.put(headerName.toLowerCase(), request.getHeader(headerName)); } - //调用链logSwatch Java110TraceFactory.createTrace(url, headers); return true; } diff --git a/java110-db/src/main/resources/mapper/community/InspectionTaskDetailV1ServiceDaoImplMapper.xml b/java110-db/src/main/resources/mapper/community/InspectionTaskDetailV1ServiceDaoImplMapper.xml index ac0868f..3831fdb 100644 --- a/java110-db/src/main/resources/mapper/community/InspectionTaskDetailV1ServiceDaoImplMapper.xml +++ b/java110-db/src/main/resources/mapper/community/InspectionTaskDetailV1ServiceDaoImplMapper.xml @@ -9,10 +9,10 @@ insert into inspection_task_detail( send_flag,point_end_time,latitude,inspection_time,sort_number,description,act_user_name,task_detail_id,inspection_id, - inspection_state,point_start_time,inspection_name,state,community_id,act_user_id,task_id,longitude + inspection_state,point_start_time,inspection_name,state,community_id,act_user_id,task_id,longitude,source ) values ( #{sendFlag},#{pointEndTime},#{latitude},#{inspectionTime},#{sortNumber},#{description},#{actUserName},#{taskDetailId}, - #{inspectionId},#{inspectionState},#{pointStartTime},#{inspectionName},#{state},#{communityId},#{actUserId},#{taskId},#{longitude} + #{inspectionId},#{inspectionState},#{pointStartTime},#{inspectionName},#{state},#{communityId},#{actUserId},#{taskId},#{longitude},#{source} ) @@ -22,7 +22,7 @@ select t.send_flag sendFlag,t.point_end_time pointEndTime,t.latitude,t.inspection_time inspectionTime,t.sort_number,t.sort_number sortNumber,t.description,t.status_cd statusCd,t.act_user_name actUserName,t.task_detail_id taskDetailId,t.inspection_id inspectionId,t.inspection_state inspectionState,t.point_start_time pointStartTime,t.inspection_name inspectionName,t.state, - t.community_id communityId,t.act_user_id actUserId,t.task_id taskId,t.longitude,ip.lng,ip.lat + t.community_id communityId,t.act_user_id actUserId,t.task_id taskId,t.longitude,ip.lng,ip.lat,t.source source from inspection_task_detail t left join inspection_point ip on t.inspection_id = ip.inspection_id and ip.status_cd = '0' where 1 =1 @@ -80,6 +80,9 @@ and t.longitude= #{longitude} + + and t.source= #{source} + order by t.create_time desc limit #{page}, #{row} @@ -140,6 +143,9 @@ , t.longitude= #{longitude} + + , t.source= #{source} + where 1=1 and t.task_detail_id= #{taskDetailId} @@ -209,6 +215,9 @@ and t.longitude= #{longitude} + + and t.source= #{source} + diff --git a/java110-utils/src/main/java/com/java110/utils/cache/AppRouteCache.java b/java110-utils/src/main/java/com/java110/utils/cache/AppRouteCache.java index c84043c..7108928 100755 --- a/java110-utils/src/main/java/com/java110/utils/cache/AppRouteCache.java +++ b/java110-utils/src/main/java/com/java110/utils/cache/AppRouteCache.java @@ -3,10 +3,13 @@ package com.java110.utils.cache; import com.java110.dto.system.AppRoute; import com.java110.utils.util.SerializeUtil; +import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** - * 路由配置 + * 路由配置(带本地内存缓存,避免每次请求都查远程Redis) * Created by wuxw on 2018/4/14. */ public class AppRouteCache extends BaseCache { @@ -14,20 +17,30 @@ public class AppRouteCache extends BaseCache { //后缀 用来刷缓存时删除 所有以这个为后缀的数据 public final static String _SUFFIX_APP_ROUTE = "_SUFFIX_APP_ROUTE"; + // 本地内存缓存,避免每次请求都查远程Redis + private static final Map> LOCAL_CACHE = new ConcurrentHashMap<>(); + /** - * 获取 路由配置 - * @param appId - * @return + * 获取 路由配置(优先从本地缓存读取) */ public static List getAppRoute(String appId){ + String key = appId + _SUFFIX_APP_ROUTE; + + // 本地内存缓存命中,直接返回,省去远程Redis调用 + List cached = LOCAL_CACHE.get(key); + if (cached != null) { + return cached.isEmpty() ? null : cached; + } + List appRoutes = null; Jedis redis = null; try { redis = getJedis(); - appRoutes = SerializeUtil.unserializeList(redis.get((appId+_SUFFIX_APP_ROUTE).getBytes()),AppRoute.class); + appRoutes = SerializeUtil.unserializeList(redis.get(key.getBytes()), AppRoute.class); if(appRoutes == null || appRoutes.size() ==0) { return null; } + LOCAL_CACHE.put(key, appRoutes); }finally { if(redis != null){ redis.close(); @@ -39,13 +52,14 @@ public class AppRouteCache extends BaseCache { /** * 保存路由信息 - * @param appRoutes */ public static void setAppRoute(List appRoutes){ + String key = appRoutes.get(0).getAppId() + _SUFFIX_APP_ROUTE; + LOCAL_CACHE.put(key, appRoutes); Jedis redis = null; try { redis = getJedis(); - redis.set((appRoutes.get(0).getAppId()+_SUFFIX_APP_ROUTE).getBytes(),SerializeUtil.serializeList(appRoutes)); + redis.set(key.getBytes(), SerializeUtil.serializeList(appRoutes)); }finally { if(redis != null){ redis.close(); @@ -53,5 +67,10 @@ public class AppRouteCache extends BaseCache { } } - + /** + * 清除本地缓存 + */ + public static void clearLocalCache() { + LOCAL_CACHE.clear(); + } } diff --git a/pom.xml b/pom.xml index 4bf1232..e22fb79 100755 --- a/pom.xml +++ b/pom.xml @@ -564,6 +564,7 @@ + ${project.artifactId}-${maven.build.timestamp} org.apache.maven.plugins @@ -605,4 +606,4 @@ http://maven.homecommunity.cn:8081/repository/maven-snapshots/ - \ No newline at end of file + diff --git a/service-api/src/main/java/com/java110/api/aop/PageProcessAspect.java b/service-api/src/main/java/com/java110/api/aop/PageProcessAspect.java index 90bd9bb..59c2ed7 100644 --- a/service-api/src/main/java/com/java110/api/aop/PageProcessAspect.java +++ b/service-api/src/main/java/com/java110/api/aop/PageProcessAspect.java @@ -144,13 +144,13 @@ public class PageProcessAspect { logger.debug("切面 获取到的pd=" + JSONObject.toJSONString(pd)); request.setAttribute(CommonConstant.CONTEXT_PAGE_DATA, pd); - // 详细请求入参日志 - logger.info("===== 请求开始 ====="); - logger.info("请求URL: {} [{}]", url, request.getMethod()); - logger.info("请求IP: {}", getIpAddr(request)); - logger.info("请求用户: userId={}, userName={}", userId, userName); - logger.info("请求参数: {}", reqData); - logger.info("请求头: {}", JSONObject.toJSONString(headers)); + // 详细请求入参日志(DEBUG级别避免生产环境IO开销) + logger.debug("===== 请求开始 ====="); + logger.debug("请求URL: {} [{}]", url, request.getMethod()); + logger.debug("请求IP: {}", getIpAddr(request)); + logger.debug("请求用户: userId={}, userName={}", userId, userName); + logger.debug("请求参数: {}", reqData); + logger.debug("请求头: {}", JSONObject.toJSONString(headers)); //调用链 //Java110TraceFactory.createTrace(componentCode + "/" + componentMethod, headers); @@ -217,9 +217,9 @@ public class PageProcessAspect { } else if (o != null) { responseBody = o.toString(); } - logger.info("请求耗时: {}ms, 返回状态: {}", elapsedTime, status); - logger.info("返回数据: {}", responseBody); - logger.info("===== 请求结束 ====="); + logger.debug("请求耗时: {}ms, 返回状态: {}", elapsedTime, status); + logger.debug("返回数据: {}", responseBody); + logger.debug("===== 请求结束 ====="); } } } diff --git a/service-api/src/main/java/com/java110/api/smo/file/impl/AddFileSMOImpl.java b/service-api/src/main/java/com/java110/api/smo/file/impl/AddFileSMOImpl.java index 4f76e3a..af9c74b 100644 --- a/service-api/src/main/java/com/java110/api/smo/file/impl/AddFileSMOImpl.java +++ b/service-api/src/main/java/com/java110/api/smo/file/impl/AddFileSMOImpl.java @@ -73,37 +73,24 @@ public class AddFileSMOImpl extends DefaultAbstractComponentSMO implements IAddF String suffix = paramIn.getString("suffix"); - // APK 文件保存到本地磁盘 /park/apk/ + // APK 文件上传到OSS if ("apk".equalsIgnoreCase(suffix)) { - String apkFileName = UUID.randomUUID().toString() + ".apk"; - String apkDir = "/park/apk/"; - File dir = new File(apkDir); - if (!dir.exists()) { - boolean created = dir.mkdirs(); - if (!created) { - throw new IOException("无法创建APK存储目录: " + apkDir); - } - } - File apkFile = new File(apkDir + apkFileName); + String apkFileName = "apk/" + UUID.randomUUID().toString() + ".apk"; + String urlPath = ROOT_PATH + apkFileName; + + String ossSwitch = MappingCache.getValue(MappingConstant.FILE_DOMAIN, OSSUtil.OSS_SWITCH); is = uploadFile.getInputStream(); - FileOutputStream fos = null; - try { - fos = new FileOutputStream(apkFile); - byte[] buf = new byte[8192]; - int len; - while ((len = is.read(buf)) != -1) { - fos.write(buf, 0, len); - } - fos.flush(); - } finally { - if (fos != null) { try { fos.close(); } catch (Exception ignored) {} } - if (is != null) { try { is.close(); } catch (Exception ignored) {} } - is = null; // 防止外层 finally 重复关闭 + if (OSSUtil.OSS_SWITCH_OSS.equals(ossSwitch)) { + ossUploadTemplate.upload(is, urlPath); + } else if (COSUtil.COS_SWITCH_COS.equals(ossSwitch)) { + cosUploadTemplate.upload(is, urlPath); + } else { + throw new IllegalArgumentException("OSS/COS 未启用,无法上传APK"); } JSONObject outParam = new JSONObject(); - outParam.put("fileId", "apk/" + apkFileName); - outParam.put("url", "/app/downloadApk?file=apk/" + apkFileName); + outParam.put("fileId", apkFileName); + outParam.put("url", "/app/downloadApk?file=" + apkFileName); return new ResponseEntity<>(outParam.toJSONString(), HttpStatus.OK); } diff --git a/service-api/src/main/java/com/java110/api/smo/undo/impl/UndoSMOImpl.java b/service-api/src/main/java/com/java110/api/smo/undo/impl/UndoSMOImpl.java index 72cb8a7..51213aa 100644 --- a/service-api/src/main/java/com/java110/api/smo/undo/impl/UndoSMOImpl.java +++ b/service-api/src/main/java/com/java110/api/smo/undo/impl/UndoSMOImpl.java @@ -133,32 +133,11 @@ public class UndoSMOImpl extends DefaultAbstractComponentSMO implements IUndoSMO doing.put("collection", "0"); } - //contract/queryContractTask - //合同起草待办 - apiUrl = "/contract/queryContractTask" + mapToUrlParam(paramIn); - responseEntity = this.callCenterService(restTemplate, pd, "", - apiUrl, - HttpMethod.GET); - if (responseEntity.getStatusCode() == HttpStatus.OK) { - JSONObject paramOut = JSONObject.parseObject(responseEntity.getBody()); - doing.put("contractApply", paramOut.getString("total")); - } else { - doing.put("contractApply", "0"); - } - //contract/queryContractTask - //合同变更 - apiUrl = "/contract/queryContractChangeTask" + mapToUrlParam(paramIn); - responseEntity = this.callCenterService(restTemplate, pd, "", - apiUrl, - HttpMethod.GET); - if (responseEntity.getStatusCode() == HttpStatus.OK) { - JSONObject paramOut = JSONObject.parseObject(responseEntity.getBody()); - doing.put("contractChange", paramOut.getString("total")); - } else { - doing.put("contractChange", "0"); - } + // 合同待办(App端无权限,跳过) + doing.put("contractApply", "0"); + doing.put("contractChange", "0"); - //合同变更 + //物品调配待办 apiUrl = "resourceStore.listAllocationStoreAuditOrders" + mapToUrlParam(paramIn); responseEntity = this.callCenterService(restTemplate, pd, "", apiUrl, diff --git a/service-community/src/main/java/com/java110/community/cmd/inspection/QueryQrcodeCheckinRecordsCmd.java b/service-community/src/main/java/com/java110/community/cmd/inspection/QueryQrcodeCheckinRecordsCmd.java new file mode 100644 index 0000000..f7f7a4c --- /dev/null +++ b/service-community/src/main/java/com/java110/community/cmd/inspection/QueryQrcodeCheckinRecordsCmd.java @@ -0,0 +1,65 @@ +package com.java110.community.cmd.inspection; + +import com.alibaba.fastjson.JSONObject; +import com.java110.core.annotation.Java110Cmd; +import com.java110.core.context.ICmdDataFlowContext; +import com.java110.core.event.cmd.Cmd; +import com.java110.core.event.cmd.CmdEvent; +import com.java110.dto.inspection.InspectionTaskDetailDto; +import com.java110.intf.community.IInspectionTaskDetailV1InnerServiceSMO; +import com.java110.utils.exception.CmdException; +import com.java110.utils.util.Assert; +import com.java110.utils.util.BeanConvertUtil; +import com.java110.vo.ResultVo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; + +/** + * 查询二维码打卡记录 + * 查询 source='qrcode' 的巡检打卡记录 + * serviceCode: inspection.queryQrcodeCheckinRecords + * + * @author Java110 + * @version 1.0 + * @since 2024 + */ +@Java110Cmd(serviceCode = "inspection.queryQrcodeCheckinRecords") +public class QueryQrcodeCheckinRecordsCmd extends Cmd { + + @Autowired + private IInspectionTaskDetailV1InnerServiceSMO inspectionTaskDetailV1InnerServiceSMOImpl; + + @Override + public void validate(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException, ParseException { + super.validatePageInfo(reqJson); + Assert.hasKeyAndValue(reqJson, "communityId", "请求报文中未包含communityId"); + } + + @Override + public void doCmd(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException, ParseException { + InspectionTaskDetailDto inspectionTaskDetailDto = BeanConvertUtil.covertBean(reqJson, InspectionTaskDetailDto.class); + inspectionTaskDetailDto.setSource("qrcode"); + + int count = inspectionTaskDetailV1InnerServiceSMOImpl.queryInspectionTaskDetailsCount(inspectionTaskDetailDto); + + List inspectionTaskDetails = null; + if (count > 0) { + inspectionTaskDetails = BeanConvertUtil.covertBeanList( + inspectionTaskDetailV1InnerServiceSMOImpl.queryInspectionTaskDetails(inspectionTaskDetailDto), + InspectionTaskDetailDto.class); + } else { + inspectionTaskDetails = new ArrayList<>(); + } + + int totalPage = (int) Math.ceil((double) count / (double) reqJson.getInteger("row")); + ResultVo resultVo = new ResultVo(totalPage, count, inspectionTaskDetails); + + ResponseEntity responseEntity = new ResponseEntity<>(resultVo.toString(), HttpStatus.OK); + context.setResponseEntity(responseEntity); + } +} diff --git a/service-community/src/main/java/com/java110/community/cmd/inspection/QueryStaffTodayTasksCmd.java b/service-community/src/main/java/com/java110/community/cmd/inspection/QueryStaffTodayTasksCmd.java new file mode 100644 index 0000000..c44be2c --- /dev/null +++ b/service-community/src/main/java/com/java110/community/cmd/inspection/QueryStaffTodayTasksCmd.java @@ -0,0 +1,116 @@ +package com.java110.community.cmd.inspection; + +import com.alibaba.fastjson.JSONObject; +import com.java110.core.annotation.Java110Cmd; +import com.java110.core.context.ICmdDataFlowContext; +import com.java110.core.event.cmd.Cmd; +import com.java110.core.event.cmd.CmdEvent; +import com.java110.dto.inspection.InspectionTaskDetailDto; +import com.java110.dto.inspection.InspectionTaskDto; +import com.java110.intf.community.IInspectionTaskDetailV1InnerServiceSMO; +import com.java110.intf.community.IInspectionTaskV1InnerServiceSMO; +import com.java110.utils.exception.CmdException; +import com.java110.utils.util.Assert; +import com.java110.utils.util.BeanConvertUtil; +import com.java110.vo.ResultVo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import java.util.ArrayList; +import java.util.List; + +/** + * 查询巡检人员今日任务及巡检点 + * 用于二维码扫码打卡页面加载 + * serviceCode: inspection.queryStaffTodayTasks + * + * @author Java110 + * @version 1.0 + * @since 2024 + */ +@Java110Cmd(serviceCode = "inspection.queryStaffTodayTasks") +public class QueryStaffTodayTasksCmd extends Cmd { + + @Autowired + private IInspectionTaskV1InnerServiceSMO inspectionTaskV1InnerServiceSMOImpl; + + @Autowired + private IInspectionTaskDetailV1InnerServiceSMO inspectionTaskDetailV1InnerServiceSMOImpl; + + @Override + public void validate(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException { + Assert.hasKeyAndValue(reqJson, "staffId", "请求报文中未包含staffId"); + Assert.hasKeyAndValue(reqJson, "communityId", "请求报文中未包含communityId"); + } + + @Override + public void doCmd(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException { + String staffId = reqJson.getString("staffId"); + String communityId = reqJson.getString("communityId"); + + // 查询该巡检人员的巡检任务 + InspectionTaskDto inspectionTaskDto = new InspectionTaskDto(); + inspectionTaskDto.setPlanUserId(staffId); + inspectionTaskDto.setCommunityId(communityId); + List tasks = inspectionTaskV1InnerServiceSMOImpl.queryInspectionTasks(inspectionTaskDto); + + JSONObject result = new JSONObject(); + result.put("staffId", staffId); + + List taskList = new ArrayList<>(); + String staffName = ""; + for (InspectionTaskDto task : tasks) { + if (staffName.isEmpty() && task.getPlanUserName() != null) { + staffName = task.getPlanUserName(); + } + + InspectionTaskDetailDto detailDto = new InspectionTaskDetailDto(); + detailDto.setTaskId(task.getTaskId()); + detailDto.setCommunityId(communityId); + List details = + BeanConvertUtil.covertBeanList( + inspectionTaskDetailV1InnerServiceSMOImpl.queryInspectionTaskDetails(detailDto), + InspectionTaskDetailDto.class); + + JSONObject taskObj = new JSONObject(); + taskObj.put("taskId", task.getTaskId()); + taskObj.put("planName", task.getInspectionPlanName()); + taskObj.put("planInsTime", task.getPlanInsTime()); + taskObj.put("planEndTime", task.getPlanEndTime()); + taskObj.put("planUserId", task.getPlanUserId()); + taskObj.put("planUserName", task.getPlanUserName()); + taskObj.put("signType", task.getSignType()); + taskObj.put("state", task.getState()); + + List detailList = new ArrayList<>(); + for (InspectionTaskDetailDto detail : details) { + JSONObject detailObj = new JSONObject(); + detailObj.put("taskDetailId", detail.getTaskDetailId()); + detailObj.put("taskId", detail.getTaskId()); + detailObj.put("inspectionId", detail.getInspectionId()); + detailObj.put("inspectionName", detail.getInspectionName()); + detailObj.put("longitude", detail.getLongitude()); + detailObj.put("latitude", detail.getLatitude()); + detailObj.put("state", detail.getState()); + detailObj.put("inspectionState", detail.getInspectionState()); + detailObj.put("pointStartTime", detail.getPointStartTime()); + detailObj.put("pointEndTime", detail.getPointEndTime()); + detailObj.put("sortNumber", detail.getSortNumber()); + detailObj.put("lng", detail.getLng()); + detailObj.put("lat", detail.getLat()); + detailList.add(detailObj); + } + taskObj.put("details", detailList); + taskList.add(taskObj); + } + + result.put("staffName", staffName); + result.put("communityId", communityId); + result.put("tasks", taskList); + + ResponseEntity responseEntity = new ResponseEntity<>( + ResultVo.createResponseEntity(result).toString(), HttpStatus.OK); + context.setResponseEntity(responseEntity); + } +} diff --git a/service-job/src/main/java/com/java110/job/cmd/iot/GetOpenApiCmd.java b/service-job/src/main/java/com/java110/job/cmd/iot/GetOpenApiCmd.java index 9a79ef2..dc864cf 100644 --- a/service-job/src/main/java/com/java110/job/cmd/iot/GetOpenApiCmd.java +++ b/service-job/src/main/java/com/java110/job/cmd/iot/GetOpenApiCmd.java @@ -19,6 +19,7 @@ import com.java110.vo.ResultVo; import org.springframework.beans.factory.annotation.Autowired; import java.text.ParseException; +import java.util.ArrayList; import java.util.List; @Java110Cmd(serviceCode = "iot.getOpenApi") @@ -36,13 +37,16 @@ public class GetOpenApiCmd extends Cmd { @Autowired private ISendIot sendIotImpl; + private boolean iotNotDeployed = false; + @Override public void validate(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException, ParseException { Assert.hasKeyAndValue(reqJson, "iotApiCode", "未包含IOT接口编码"); String iotSwitch = MappingCache.getValue("IOT", "IOT_SWITCH"); if (!"ON".equals(iotSwitch)) { - throw new CmdException("物联网系统未部署"); + iotNotDeployed = true; + return; } String userId = CmdContextUtils.getUserId(context); @@ -63,13 +67,15 @@ public class GetOpenApiCmd extends Cmd { storeDto.setStoreTypeCd(StoreDto.STORE_TYPE_PROPERTY); List storeDtos = storeV1InnerServiceSMOImpl.queryStores(storeDto); - Assert.listOnlyOne(storeDtos,"不是物业公司"); - + Assert.listOnlyOne(storeDtos, "不是物业公司"); } @Override public void doCmd(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException, ParseException { - + if (iotNotDeployed) { + context.setResponseEntity(ResultVo.createResponseEntity(new ArrayList<>())); + return; + } ResultVo resultVo = sendIotImpl.post("/iot/api/common.openCommonApi", reqJson); @@ -78,6 +84,5 @@ public class GetOpenApiCmd extends Cmd { } context.setResponseEntity(ResultVo.createResponseEntity(resultVo)); - } } diff --git a/service-report/src/main/java/com/java110/report/cmd/admin/QueryAdminCountCmd.java b/service-report/src/main/java/com/java110/report/cmd/admin/QueryAdminCountCmd.java index da9faad..468882a 100644 --- a/service-report/src/main/java/com/java110/report/cmd/admin/QueryAdminCountCmd.java +++ b/service-report/src/main/java/com/java110/report/cmd/admin/QueryAdminCountCmd.java @@ -114,10 +114,10 @@ public class QueryAdminCountCmd extends Cmd { StoreDto storeDto = new StoreDto(); storeDto.setStoreId(storeId); storeDto.setStoreTypeCd(StoreDto.STORE_TYPE_ADMIN); - + // 查询管理员账户数量 int count = storeInnerServiceSMOImpl.getStoreCount(storeDto); - + // 如果不是管理员账户,抛出异常 if (count < 1) { throw new CmdException("非法操作,请用系统管理员账户操作"); diff --git a/service-user/src/main/java/com/java110/user/cmd/property/QueryHomeStatsCmd.java b/service-user/src/main/java/com/java110/user/cmd/property/QueryHomeStatsCmd.java new file mode 100644 index 0000000..0914590 --- /dev/null +++ b/service-user/src/main/java/com/java110/user/cmd/property/QueryHomeStatsCmd.java @@ -0,0 +1,70 @@ +package com.java110.user.cmd.property; + +import com.alibaba.fastjson.JSONObject; +import com.java110.core.annotation.Java110Cmd; +import com.java110.core.context.ICmdDataFlowContext; +import com.java110.core.event.cmd.Cmd; +import com.java110.core.event.cmd.CmdEvent; +import com.java110.dto.inspection.InspectionTaskDto; +import com.java110.dto.repair.RepairDto; +import com.java110.intf.community.IRepairInnerServiceSMO; +import com.java110.intf.community.IInspectionTaskInnerServiceSMO; +import com.java110.utils.exception.CmdException; +import com.java110.utils.util.DateUtil; +import com.java110.vo.ResultVo; +import org.springframework.beans.factory.annotation.Autowired; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 首页统计数据查询(不限制管理员权限) + */ +@Java110Cmd(serviceCode = "property.queryHomeStats") +public class QueryHomeStatsCmd extends Cmd { + + @Autowired + private IRepairInnerServiceSMO repairInnerServiceSMOImpl; + + @Autowired + private IInspectionTaskInnerServiceSMO inspectionTaskInnerServiceSMOImpl; + + @Override + public void validate(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException, ParseException { + // 不限制管理员权限 + } + + @Override + public void doCmd(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException, ParseException { + List datas = new ArrayList<>(); + + String startTime = DateUtil.getNow(DateUtil.DATE_FORMATE_STRING_B); + String endTime = startTime + " 23:59:59"; + + // 今日报修数 + RepairDto repairDto = new RepairDto(); + repairDto.setStartTime(startTime); + repairDto.setEndTime(endTime); + int repairCount = repairInnerServiceSMOImpl.queryRepairsCount(repairDto); + Map repairInfo = new HashMap(); + repairInfo.put("name", "今日报修数"); + repairInfo.put("value", repairCount); + datas.add(repairInfo); + + // 今日巡检数 + InspectionTaskDto inspectionTaskDto = new InspectionTaskDto(); + inspectionTaskDto.setStartTime(startTime); + inspectionTaskDto.setEndTime(endTime); + inspectionTaskDto.setStates(new String[]{InspectionTaskDto.STATE_DOING, InspectionTaskDto.STATE_FINISH}); + int inspectionCount = inspectionTaskInnerServiceSMOImpl.queryInspectionTasksCount(inspectionTaskDto); + Map inspectionInfo = new HashMap(); + inspectionInfo.put("name", "今日巡检数"); + inspectionInfo.put("value", inspectionCount); + datas.add(inspectionInfo); + + context.setResponseEntity(ResultVo.createResponseEntity(datas)); + } +} diff --git a/service-user/src/main/java/com/java110/user/cmd/property/QueryTodayAttendanceDetailCmd.java b/service-user/src/main/java/com/java110/user/cmd/property/QueryTodayAttendanceDetailCmd.java new file mode 100644 index 0000000..a005a22 --- /dev/null +++ b/service-user/src/main/java/com/java110/user/cmd/property/QueryTodayAttendanceDetailCmd.java @@ -0,0 +1,120 @@ +package com.java110.user.cmd.property; + +import com.alibaba.fastjson.JSONObject; +import com.java110.core.annotation.Java110Cmd; +import com.java110.core.context.ICmdDataFlowContext; +import com.java110.core.event.cmd.Cmd; +import com.java110.core.event.cmd.CmdEvent; +import com.java110.user.dao.property.IAttendanceRecordV1ServiceDao; +import com.java110.utils.exception.CmdException; +import com.java110.vo.ResultVo; +import org.springframework.beans.factory.annotation.Autowired; + +import java.text.ParseException; +import java.util.*; + +/** + * 查询今日考勤明细,无视权限,查询系统中所有员工(所有有打卡记录的用户) + */ +@Java110Cmd(serviceCode = "property.queryTodayAttendanceDetail") +public class QueryTodayAttendanceDetailCmd extends Cmd { + + @Autowired + private IAttendanceRecordV1ServiceDao attendanceRecordV1ServiceDao; + + @Override + public void validate(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException, ParseException { + } + + @Override + public void doCmd(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException, ParseException { + String today = getToday(reqJson); + + // 1. 查全系统所有员工(有过打卡记录的用户) + List allUsers = attendanceRecordV1ServiceDao.queryAllAttendanceUsers(new HashMap<>()); + + // 2. 查今日打卡记录 + Map recordParams = new HashMap<>(); + recordParams.put("startTime", today + " 00:00:00"); + recordParams.put("endTime", today + " 23:59:59"); + List records = attendanceRecordV1ServiceDao.queryAttendanceRecords(recordParams); + + // 3. 按 userId 分组今日打卡记录 + Map punchMap = new LinkedHashMap<>(); + for (Map r : records) { + String uid = (String) r.get("user_id"); + String type = (String) r.get("punch_type"); + punchMap.putIfAbsent(uid, new HashMap()); + Map pd = punchMap.get(uid); + pd.put("staffId", uid); + pd.put("staffName", r.get("user_name")); + if ("ON".equals(type) && pd.get("onTime") == null) pd.put("onTime", r.get("punch_time")); + if ("OFF".equals(type)) pd.put("offTime", r.get("punch_time")); + } + + // 4. 构建全系统员工→store映射 + Map userStoreMap = new HashMap<>(); + for (Map u : allUsers) { + userStoreMap.put((String) u.get("user_id"), (String) u.get("store_name")); + } + + // 5. 构建结果 + Set seen = new HashSet<>(); + List result = new ArrayList<>(); + + for (Map.Entry e : punchMap.entrySet()) { + Map data = e.getValue(); + data.put("storeName", userStoreMap.getOrDefault(e.getKey(), "")); + result.add(buildTask(data)); + seen.add(e.getKey()); + } + + for (Map u : allUsers) { + String uid = (String) u.get("user_id"); + if (!seen.contains(uid)) { + Map m = new HashMap(); + m.put("staffId", uid); + m.put("staffName", u.get("user_name")); + m.put("storeName", u.get("store_name")); + m.put("onTime", null); + m.put("offTime", null); + result.add(buildTask(m)); + } + } + + context.setResponseEntity(ResultVo.createResponseEntity(result.size(), result.size(), result)); + } + + private Map buildTask(Map data) { + Map task = new HashMap(); + task.put("taskId", UUID.randomUUID().toString()); + task.put("staffId", data.get("staffId")); + task.put("staffName", data.getOrDefault("staffName", "")); + task.put("storeName", data.getOrDefault("storeName", "")); + boolean hasOn = data.get("onTime") != null; + task.put("state", hasOn ? "30000" : "10000"); + + List details = new ArrayList<>(); + if (hasOn) { + Map d = new HashMap(); + d.put("specCd", "1001"); + d.put("checkTime", String.valueOf(data.get("onTime"))); + details.add(d); + } + if (data.get("offTime") != null) { + Map d = new HashMap(); + d.put("specCd", "2002"); + d.put("checkTime", String.valueOf(data.get("offTime"))); + details.add(d); + } + task.put("attendanceClassesTaskDetails", details); + return task; + } + + private String getToday(JSONObject reqJson) { + String date = reqJson.getString("date"); + if (date != null && !date.isEmpty()) return date; + java.time.LocalDate now = java.time.LocalDate.now(); + return now.toString(); + } +} diff --git a/service-user/src/main/java/com/java110/user/dao/impl/AttendanceRecordV1ServiceDaoImpl.java b/service-user/src/main/java/com/java110/user/dao/impl/AttendanceRecordV1ServiceDaoImpl.java index fb3bc6a..2a9b6cd 100644 --- a/service-user/src/main/java/com/java110/user/dao/impl/AttendanceRecordV1ServiceDaoImpl.java +++ b/service-user/src/main/java/com/java110/user/dao/impl/AttendanceRecordV1ServiceDaoImpl.java @@ -48,4 +48,9 @@ public class AttendanceRecordV1ServiceDaoImpl extends BaseServiceDao implements List result = sqlSessionTemplate.selectList("AttendanceRecordV1ServiceDaoImpl.getLastPunch", params); return (result != null && !result.isEmpty()) ? result.get(0) : null; } + + @Override + public List queryAllAttendanceUsers(Map params) { + return sqlSessionTemplate.selectList("AttendanceRecordV1ServiceDaoImpl.queryAllAttendanceUsers", params); + } } diff --git a/service-user/src/main/java/com/java110/user/dao/impl/LocationTrackV1ServiceDaoImpl.java b/service-user/src/main/java/com/java110/user/dao/impl/LocationTrackV1ServiceDaoImpl.java index af6f53b..a78ea15 100644 --- a/service-user/src/main/java/com/java110/user/dao/impl/LocationTrackV1ServiceDaoImpl.java +++ b/service-user/src/main/java/com/java110/user/dao/impl/LocationTrackV1ServiceDaoImpl.java @@ -32,4 +32,9 @@ public class LocationTrackV1ServiceDaoImpl extends BaseServiceDao implements ILo List result = sqlSessionTemplate.selectList("LocationTrackV1ServiceDaoImpl.queryLastLocationByUserId", userId); return (result != null && !result.isEmpty()) ? result.get(0) : null; } + + @Override + public List queryAllLatestLocations(Map params) { + return sqlSessionTemplate.selectList("LocationTrackV1ServiceDaoImpl.queryAllLatestLocations", params); + } } diff --git a/service-user/src/main/java/com/java110/user/dao/property/IAttendanceRecordV1ServiceDao.java b/service-user/src/main/java/com/java110/user/dao/property/IAttendanceRecordV1ServiceDao.java index 1918bb6..204d385 100644 --- a/service-user/src/main/java/com/java110/user/dao/property/IAttendanceRecordV1ServiceDao.java +++ b/service-user/src/main/java/com/java110/user/dao/property/IAttendanceRecordV1ServiceDao.java @@ -14,4 +14,7 @@ public interface IAttendanceRecordV1ServiceDao { int countTodayByType(Map params); /** 获取用户最近一次打卡记录 */ Map getLastPunch(Map params); + + /** 查询所有有打卡记录的用户列表 */ + List queryAllAttendanceUsers(Map params); } diff --git a/service-user/src/main/java/com/java110/user/dao/property/ILocationTrackV1ServiceDao.java b/service-user/src/main/java/com/java110/user/dao/property/ILocationTrackV1ServiceDao.java index 8554ec2..d83bdec 100644 --- a/service-user/src/main/java/com/java110/user/dao/property/ILocationTrackV1ServiceDao.java +++ b/service-user/src/main/java/com/java110/user/dao/property/ILocationTrackV1ServiceDao.java @@ -12,4 +12,7 @@ public interface ILocationTrackV1ServiceDao { * 去重查询:查询同一用户最近一条定位记录,用于判断是否需要插入新记录 */ Map queryLastLocationByUserId(String userId); + + /** 查询所有在职员工的最新位置(今天的数据,每人取最新一条) */ + List queryAllLatestLocations(Map params); } diff --git a/service-user/src/main/resources/mapper/property/AttendanceRecordMapper.xml b/service-user/src/main/resources/mapper/property/AttendanceRecordMapper.xml index d3c084e..a51ad78 100644 --- a/service-user/src/main/resources/mapper/property/AttendanceRecordMapper.xml +++ b/service-user/src/main/resources/mapper/property/AttendanceRecordMapper.xml @@ -51,4 +51,13 @@ LIMIT 1 + + diff --git a/service-user/src/main/resources/mapper/property/LocationTrackMapper.xml b/service-user/src/main/resources/mapper/property/LocationTrackMapper.xml index 05ca52d..4006ea0 100644 --- a/service-user/src/main/resources/mapper/property/LocationTrackMapper.xml +++ b/service-user/src/main/resources/mapper/property/LocationTrackMapper.xml @@ -32,4 +32,21 @@ SELECT * FROM location_track WHERE user_id = #{userId} ORDER BY report_time DESC LIMIT 1 + + diff --git a/springboot/src/main/java/com/java110/boot/BootApplicationStart.java b/springboot/src/main/java/com/java110/boot/BootApplicationStart.java index e0f27e0..b5f90f2 100644 --- a/springboot/src/main/java/com/java110/boot/BootApplicationStart.java +++ b/springboot/src/main/java/com/java110/boot/BootApplicationStart.java @@ -89,7 +89,8 @@ import java.util.concurrent.TimeUnit; exclude = {LiquibaseAutoConfiguration.class, org.activiti.spring.boot.SecurityAutoConfiguration.class, org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class, - com.github.pagehelper.autoconfigure.MapperAutoConfiguration.class + com.github.pagehelper.autoconfigure.MapperAutoConfiguration.class, + org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration.class } ) diff --git a/springboot/src/main/resources/application-prod.yml b/springboot/src/main/resources/application-prod.yml index b634b15..d9b079c 100644 --- a/springboot/src/main/resources/application-prod.yml +++ b/springboot/src/main/resources/application-prod.yml @@ -39,9 +39,9 @@ spring: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver druid: - initial-size: 10 - max-active: 50 - min-idle: 10 + initial-size: 2 + max-active: 30 + min-idle: 2 max-wait: 60000 eureka: