/* * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the dreamlu.net developer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * Author: Chill 庄骞 (smallchill@163.com) */ package org.sxkj.gd.workorder.wrapper; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.springblade.core.mp.support.BaseEntityWrapper; import org.springblade.core.tool.utils.BeanUtil; import org.springblade.core.tool.utils.StringUtil; import org.sxkj.gd.workorder.dto.GdTaskResultDTO; import org.sxkj.gd.workorder.entity.GdTaskResultEntity; import org.sxkj.gd.workorder.vo.GdTaskResultVO; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; /** * 成果表 包装类,返回视图层所需的字段 * * @author lw * @since 2026-01-14 */ @Slf4j public class GdTaskResultWrapper extends BaseEntityWrapper { public static GdTaskResultWrapper build() { return new GdTaskResultWrapper(); } @Override public GdTaskResultVO entityVO(GdTaskResultEntity gdTaskResult) { return Objects.requireNonNull(BeanUtil.copy(gdTaskResult, GdTaskResultVO.class)); } /** * 将DTO列表转换为Entity列表 * * @param gdTaskResultDTOList DTO列表 * @return Entity列表 */ public List listEntity(List gdTaskResultDTOList) { return gdTaskResultDTOList.stream() .map(this::convertDtoToEntity) .collect(Collectors.toList()); } /** * 将单个DTO转换为Entity * 处理geojson字段:将字符串数组格式转换为正确的JSON对象数组格式 * * @param dto DTO对象 * @return Entity对象 */ private GdTaskResultEntity convertDtoToEntity(GdTaskResultDTO dto) { GdTaskResultEntity entity = BeanUtil.copy(dto, GdTaskResultEntity.class); // 步骤1:设置附件类型 if (dto.getDateType() != null) { if (dto.getDateType().equals(1) && dto.getFileType().equals("视频")) { // 录像的视频 entity.setAttachmentType(3); } else if (dto.getDateType().equals(3) && dto.getFileType().equals("视频")) { // 机巢+无人机录像视频 entity.setAttachmentType(4); } else { entity.setAttachmentType(dto.getDateType()); } } // 步骤2:处理geojson字段,将字符串数组转换为正确的JSON格式 String processedGeojson = processGeojson(dto.getGeojson()); entity.setGeojson(processedGeojson); return entity; } /** * 处理geojson字段,将字符串数组格式转换为正确的JSON对象数组格式 * 解决问题:["{\"score\":0.88}"] -> [{"score":0.88}] * * @param geojson 原始geojson字符串 * @return 处理后的geojson字符串,如果处理失败则返回原值 */ private String processGeojson(String geojson) { // 步骤1:空值检查 if (StringUtil.isEmpty(geojson)) { return geojson; } try { // 步骤2:尝试解析为JSONArray com.alibaba.fastjson.JSONArray jsonArray = JSON.parseArray(geojson); if (jsonArray == null || jsonArray.isEmpty()) { return geojson; } // 步骤3:检查第一个元素是否为字符串(说明是字符串数组格式) Object firstElement = jsonArray.get(0); if (firstElement instanceof String) { // 步骤4:这是一个字符串数组,需要解析每个字符串元素 com.alibaba.fastjson.JSONArray resultArray = new com.alibaba.fastjson.JSONArray(); for (int i = 0; i < jsonArray.size(); i++) { String elementStr = jsonArray.getString(i); if (StringUtil.hasText(elementStr)) { try { // 步骤5:解析字符串为JSON对象 com.alibaba.fastjson.JSONObject jsonObj = JSON.parseObject(elementStr); if (jsonObj != null) { resultArray.add(jsonObj); } } catch (Exception e) { // 单个元素解析失败,记录日志但继续处理其他元素 log.warn("解析geojson数组元素失败: {}", elementStr); } } } // 步骤6:返回正确的JSON数组格式 return resultArray.toJSONString(); } // 如果不是字符串数组,直接返回原值 return geojson; } catch (Exception e) { // 解析失败,返回原值 log.warn("处理geojson失败,返回原值: {}", geojson, e); return geojson; } } /** * 将文件类型字符串转换为附件类型编码 * * @param fileType 文件类型字符串(图片/视频/照片) * @return 附件类型编码:0-图片,1-视频,2-其他 */ private Integer convertFileTypeToAttachmentType(String fileType) { if (fileType == null) { return 2; } switch (fileType.trim()) { case "图片": case "照片": return 0; case "视频": return 1; default: return 2; } } }