From b1c101a20f00717c3ef3a29217b85eca8d142217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BE=E5=90=9B=E7=A6=B9?= <2673609096@qq.com> Date: Fri, 5 Sep 2025 14:33:26 +0800 Subject: [PATCH] =?UTF-8?q?farm=E6=A8=A1=E5=9D=97-=E6=BA=AF=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TraceabilityCodeController.java | 11 +- .../vo/TraceabilityCodePageReqVO.java | 11 +- .../vo/TraceabilityCodeRespVO.java | 125 +++++++++- .../vo/TraceabilityCodeSaveReqVO.java | 116 ++++++++- .../traceabilitycode/TraceabilityCodeDO.java | 100 +++++++- .../TraceabilityCodeMapper.java | 6 +- .../util/TraceabilityDataConverter.java | 132 ++++++++++ .../TraceabilityCodeServiceImpl.java | 151 +++++++++++- .../sql/add_traceability_json_fields.sql | 41 ++++ .../traceability-code-new-structure.http | 225 ++++++++++++++++++ 10 files changed, 874 insertions(+), 44 deletions(-) create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/framework/util/TraceabilityDataConverter.java create mode 100644 yudao-module-farm/src/main/resources/sql/add_traceability_json_fields.sql create mode 100644 yudao-module-farm/src/main/resources/traceability-code-new-structure.http diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/traceabilitycode/TraceabilityCodeController.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/traceabilitycode/TraceabilityCodeController.java index bd05dff9..5fe4f946 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/traceabilitycode/TraceabilityCodeController.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/traceabilitycode/TraceabilityCodeController.java @@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.Traceab import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodeRespVO; import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodeSaveReqVO; import cn.iocoder.yudao.module.farm.dal.dataobject.traceabilitycode.TraceabilityCodeDO; +import cn.iocoder.yudao.module.farm.framework.util.TraceabilityDataConverter; import cn.iocoder.yudao.module.farm.service.traceabilitycode.TraceabilityCodeService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -69,14 +70,20 @@ public class TraceabilityCodeController { @Parameter(name = "id", description = "编号", required = true, example = "1024") public CommonResult getTraceabilityCode(@RequestParam("id") String id) { TraceabilityCodeDO traceabilityCode = traceabilityCodeService.getTraceabilityCode(id); - return success(BeanUtils.toBean(traceabilityCode, TraceabilityCodeRespVO.class)); + return success(TraceabilityDataConverter.convertToRespVO(traceabilityCode)); } @GetMapping("/page") @Operation(summary = "获得溯源-溯源码分页") public CommonResult> getTraceabilityCodePage(@Valid TraceabilityCodePageReqVO pageReqVO) { PageResult pageResult = traceabilityCodeService.getTraceabilityCodePage(pageReqVO); - return success(BeanUtils.toBean(pageResult, TraceabilityCodeRespVO.class)); + // 转换分页结果中的每个DO对象为RespVO对象 + PageResult respPageResult = new PageResult<>(); + respPageResult.setList(pageResult.getList().stream() + .map(TraceabilityDataConverter::convertToRespVO) + .toList()); + respPageResult.setTotal(pageResult.getTotal()); + return success(respPageResult); } @GetMapping("/export-excel") diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/traceabilitycode/vo/TraceabilityCodePageReqVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/traceabilitycode/vo/TraceabilityCodePageReqVO.java index fefc5ffa..ecb50931 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/traceabilitycode/vo/TraceabilityCodePageReqVO.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/traceabilitycode/vo/TraceabilityCodePageReqVO.java @@ -35,8 +35,15 @@ public class TraceabilityCodePageReqVO extends PageParam { private String tenantId; @Schema(description = "采收时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] harvestDate; + private String harvestDate; + + @Schema(description = "采收时间范围查询-开始时间") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private String harvestDateStart; + + @Schema(description = "采收时间范围查询-结束时间") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private String harvestDateEnd; @Schema(description = "农事记录", example = "24734") private Long farmingInputCount; diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/traceabilitycode/vo/TraceabilityCodeRespVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/traceabilitycode/vo/TraceabilityCodeRespVO.java index cc22ca3c..7e55d51f 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/traceabilitycode/vo/TraceabilityCodeRespVO.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/traceabilitycode/vo/TraceabilityCodeRespVO.java @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; -import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; import cn.idev.excel.annotation.*; @@ -46,7 +45,7 @@ public class TraceabilityCodeRespVO { @Schema(description = "采收时间") @ExcelProperty("采收时间") - private LocalDateTime harvestDate; + private String harvestDate; @Schema(description = "农事记录", example = "24734") @ExcelProperty("农事记录") @@ -81,7 +80,7 @@ public class TraceabilityCodeRespVO { @Schema(description = "商品认证") @ExcelProperty("商品认证") - private String brandAuthentication; + private String brandAuthenticationStr; @Schema(description = "企业id", example = "25407") @ExcelProperty("企业id") @@ -91,9 +90,9 @@ public class TraceabilityCodeRespVO { @ExcelProperty("企业名称") private String businessName; - @Schema(description = "是否显示企业名称", example = "张三") + @Schema(description = "是否显示企业名称", example = "true") @ExcelProperty("是否显示企业名称") - private Long isShowBusinessName; + private Boolean isShowBusinessName; @Schema(description = "联系电话") @ExcelProperty("联系电话") @@ -101,15 +100,15 @@ public class TraceabilityCodeRespVO { @Schema(description = "是否显示联系电话") @ExcelProperty("是否显示联系电话") - private Long isShowBusinessPhone; + private Boolean isShowBusinessPhone; @Schema(description = "企业网店", example = "李四") @ExcelProperty("企业网店") private String storeName; - @Schema(description = "是否显示企业网店", example = "张三") + @Schema(description = "是否显示企业网店", example = "true") @ExcelProperty("是否显示企业网店") - private Long isShowStoreName; + private Boolean isShowStoreName; @Schema(description = "企业地址") @ExcelProperty("企业地址") @@ -117,7 +116,7 @@ public class TraceabilityCodeRespVO { @Schema(description = "是否显示企业地址") @ExcelProperty("是否显示企业地址") - private Long isShowBusinessAddress; + private Boolean isShowBusinessAddress; @Schema(description = "宣传图片(逗号分隔的字符串)") @ExcelProperty("宣传图片") @@ -128,7 +127,7 @@ public class TraceabilityCodeRespVO { @Schema(description = "是否显示宣传图片") @ExcelProperty("是否显示宣传图片") - private Long isShowPublicityImage; + private Boolean isShowPublicityImage; @Schema(description = "企业简介") @ExcelProperty("企业简介") @@ -136,7 +135,7 @@ public class TraceabilityCodeRespVO { @Schema(description = "是否显示企业简介") @ExcelProperty("是否显示企业简介") - private Long isShowPublicityProfile; + private Boolean isShowPublicityProfile; @Schema(description = "批次检验报告") @ExcelProperty("批次检验报告") @@ -170,4 +169,108 @@ public class TraceabilityCodeRespVO { private LocalDateTime createTime; private String codeOutBatch; private Long scanCodeCount; + + // ========== 新增字段支持复杂JSON结构 ========== + @Schema(description = "农事记录列表") + private List farmingInputList; + + @Schema(description = "品牌认证列表") + private List brandAuthentication; + + @Schema(description = "检验报告列表") + private List inspectionReportList; + + @Schema(description = "计量单位", example = "3") + private Integer measuringUnit; + + @Schema(description = "包装单位", example = "8") + private Integer packingUnit; + + @Schema(description = "自定义数据列表") + private List customData; + + @Schema(description = "是否显示基地") + private Boolean isShowBase; + + @Schema(description = "农事记录JSON数据") + private String farmingInputJson; + + @Schema(description = "自定义数据JSON") + private String customDataJson; + + @Schema(description = "农事记录项") + @Data + public static class FarmingInputItem { + @Schema(description = "农事名称", example = "123") + private String farmingName; + + @Schema(description = "农事日期列表") + private List date; + + @Schema(description = "投入品列表") + private List inputList; + + @Schema(description = "农事图片列表") + private List imageList; + } + + @Schema(description = "投入品项") + @Data + public static class InputItem { + @Schema(description = "投入品ID", example = "97e9f792-3b84-4132-9350-b08f34641c65") + private String inputsId; + + @Schema(description = "资产类型", example = "2") + private Integer assetType; + + @Schema(description = "用量", example = "100") + private java.math.BigDecimal dose; + + @Schema(description = "单位", example = "6") + private Integer unit; + + @Schema(description = "包装单位", example = "1") + private Integer packageUnit; + + @Schema(description = "稀释倍液", example = "1.5倍") + private String diluted; + + @Schema(description = "用法", example = "123") + private String usage; + + @Schema(description = "投入品名称", example = "药物") + private String inputsName; + + @Schema(description = "单位名称") + private String unitName; + + @Schema(description = "包装单位名称") + private String packageUnitName; + } + + @Schema(description = "自定义数据项") + @Data + public static class CustomDataItem { + @Schema(description = "链接名称") + private String linkName; + + @Schema(description = "自定义区块列表") + private List customSection; + + @Schema(description = "自定义区块") + @Data + public static class CustomSection { + @Schema(description = "标签") + private String label; + + @Schema(description = "类型") + private Integer type; + + @Schema(description = "内容") + private String content; + + @Schema(description = "图片列表") + private List imageList; + } + } } diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/traceabilitycode/vo/TraceabilityCodeSaveReqVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/traceabilitycode/vo/TraceabilityCodeSaveReqVO.java index e6824d81..203eaa5c 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/traceabilitycode/vo/TraceabilityCodeSaveReqVO.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/traceabilitycode/vo/TraceabilityCodeSaveReqVO.java @@ -3,8 +3,6 @@ package cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; -import jakarta.validation.constraints.*; -import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; @Schema(description = "管理后台 - 溯源-溯源码新增/修改 Request VO") @@ -36,7 +34,7 @@ public class TraceabilityCodeSaveReqVO { private String tenantId; @Schema(description = "采收时间") - private LocalDateTime harvestDate; + private String harvestDate; @Schema(description = "农事记录", example = "24734") private Long farmingInputCount; @@ -63,7 +61,7 @@ public class TraceabilityCodeSaveReqVO { private String introduce; @Schema(description = "商品认证") - private String brandAuthentication; + private String brandAuthenticationStr; @Schema(description = "企业id", example = "25407") private String businessId; @@ -72,25 +70,25 @@ public class TraceabilityCodeSaveReqVO { private String businessName; @Schema(description = "是否显示企业名称", example = "张三") - private Long isShowBusinessName; + private Boolean isShowBusinessName; @Schema(description = "联系电话") private String businessPhone; @Schema(description = "是否显示联系电话") - private Long isShowBusinessPhone; + private Boolean isShowBusinessPhone; @Schema(description = "企业网店", example = "李四") private String storeName; @Schema(description = "是否显示企业网店", example = "张三") - private Long isShowStoreName; + private Boolean isShowStoreName; @Schema(description = "企业地址") private String businessAddress; @Schema(description = "是否显示企业地址") - private Long isShowBusinessAddress; + private Boolean isShowBusinessAddress; @Schema(description = "宣传图片(逗号分隔的字符串)") private String publicityImage; @@ -99,13 +97,13 @@ public class TraceabilityCodeSaveReqVO { private List publicityImageList; @Schema(description = "是否显示宣传图片") - private Long isShowPublicityImage; + private Boolean isShowPublicityImage; @Schema(description = "企业简介") private String publicityProfile; @Schema(description = "是否显示企业简介") - private Long isShowPublicityProfile; + private Boolean isShowPublicityProfile; @Schema(description = "批次检验报告") private String inspectionReport; @@ -129,4 +127,102 @@ public class TraceabilityCodeSaveReqVO { private Long status; private String codeOutBatch; private Long scanCodeCount; + + // ========== 新增字段支持复杂JSON结构 ========== + @Schema(description = "农事记录列表") + private List farmingInputList; + + @Schema(description = "品牌认证列表") + private List brandAuthentication; + + @Schema(description = "检验报告列表") + private List inspectionReportList; + + @Schema(description = "计量单位", example = "3") + private String measuringUnit; + + @Schema(description = "包装单位", example = "8") + private String packingUnit; + + @Schema(description = "自定义数据列表") + private List customData; + + @Schema(description = "是否显示基地") + private Boolean isShowBase; + + @Schema(description = "农事记录项") + @Data + public static class FarmingInputItem { + @Schema(description = "农事名称", example = "123") + private String farmingName; + + @Schema(description = "农事日期列表") + private List date; + + @Schema(description = "投入品列表") + private List inputList; + + @Schema(description = "农事图片列表") + private List imageList; + } + + @Schema(description = "投入品项") + @Data + public static class InputItem { + @Schema(description = "投入品ID", example = "97e9f792-3b84-4132-9350-b08f34641c65") + private String inputsId; + + @Schema(description = "资产类型", example = "2") + private Integer assetType; + + @Schema(description = "用量", example = "100") + private java.math.BigDecimal dose; + + @Schema(description = "单位", example = "6") + private Integer unit; + + @Schema(description = "包装单位", example = "1") + private Integer packageUnit; + + @Schema(description = "稀释倍液", example = "1.5倍") + private String diluted; + + @Schema(description = "用法", example = "123") + private String usage; + + @Schema(description = "投入品名称", example = "药物") + private String inputsName; + + @Schema(description = "单位名称") + private String unitName; + + @Schema(description = "包装单位名称") + private String packageUnitName; + } + + @Schema(description = "自定义数据项") + @Data + public static class CustomDataItem { + @Schema(description = "链接名称") + private String linkName; + + @Schema(description = "自定义区块列表") + private List customSection; + + @Schema(description = "自定义区块") + @Data + public static class CustomSection { + @Schema(description = "标签") + private String label; + + @Schema(description = "类型") + private Integer type; + + @Schema(description = "内容") + private String content; + + @Schema(description = "图片列表") + private List imageList; + } + } } \ No newline at end of file diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/dal/dataobject/traceabilitycode/TraceabilityCodeDO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/dal/dataobject/traceabilitycode/TraceabilityCodeDO.java index 1bdb4333..5aad1885 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/dal/dataobject/traceabilitycode/TraceabilityCodeDO.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/dal/dataobject/traceabilitycode/TraceabilityCodeDO.java @@ -1,19 +1,17 @@ package cn.iocoder.yudao.module.farm.dal.dataobject.traceabilitycode; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; +import cn.iocoder.yudao.module.farm.framework.util.ImageCollectionUtil; +import com.baomidou.mybatisplus.annotation.*; import lombok.*; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.Arrays; import java.util.List; -import cn.iocoder.yudao.module.farm.framework.util.ImageCollectionUtil; /** - * 溯源-溯源码 DO + * 溯源-溯源码 DO * * @author 芋道源码 */ @@ -57,9 +55,15 @@ public class TraceabilityCodeDO extends BaseDO { */ private String plotName; /** - * 采收时间 + * 采收时间(数据库存储为逗号分隔的字符串) */ - private LocalDateTime harvestDate; + private String harvestDate; + + /** + * 采收时间集合(业务层使用) + */ + @TableField(exist = false) + private List harvestDateList; /** * 农事记录 */ @@ -99,7 +103,7 @@ public class TraceabilityCodeDO extends BaseDO { /** * 商品认证 */ - private String brandAuthentication; + private String brandAuthenticationStr; /** * 企业id */ @@ -199,6 +203,32 @@ public class TraceabilityCodeDO extends BaseDO { private Long scanCodeCount; + // ========== 新增字段支持复杂JSON结构 ========== + /** + * 农事记录JSON数据(存储复杂的农事记录结构) + */ + private String farmingInputJson; + + /** + * 自定义数据JSON(存储自定义字段数据) + */ + private String customDataJson; + + /** + * 计量单位 + */ + private Integer measuringUnit; + + /** + * 包装单位 + */ + private Integer packingUnit; + + /** + * 是否显示基地 + */ + private Long isShowBase; + /** * 获取商品图片集合 */ @@ -252,4 +282,54 @@ public class TraceabilityCodeDO extends BaseDO { this.collectImagesList = collectImagesList; this.collectImages = ImageCollectionUtil.toDatabaseString(collectImagesList); } + + /** + * 获取农事记录JSON数据 + */ + public String getFarmingInputJson() { + return farmingInputJson; + } + + /** + * 设置农事记录JSON数据 + */ + public void setFarmingInputJson(String farmingInputJson) { + this.farmingInputJson = farmingInputJson; + } + + /** + * 获取自定义数据JSON + */ + public String getCustomDataJson() { + return customDataJson; + } + + /** + * 设置自定义数据JSON + */ + public void setCustomDataJson(String customDataJson) { + this.customDataJson = customDataJson; + } + + /** + * 获取采收时间集合 + */ + public List getHarvestDateList() { + if (harvestDateList == null && harvestDate != null) { + harvestDateList = Arrays.asList(harvestDate.split(",")); + } + return harvestDateList; + } + + /** + * 设置采收时间集合 + */ + public void setHarvestDateList(List harvestDateList) { + this.harvestDateList = harvestDateList; + if (harvestDateList != null && !harvestDateList.isEmpty()) { + this.harvestDate = String.join(",", harvestDateList); + } else { + this.harvestDate = null; + } + } } diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/dal/mysql/traceabilitycode/TraceabilityCodeMapper.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/dal/mysql/traceabilitycode/TraceabilityCodeMapper.java index 62c558e9..3e73c512 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/dal/mysql/traceabilitycode/TraceabilityCodeMapper.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/dal/mysql/traceabilitycode/TraceabilityCodeMapper.java @@ -24,7 +24,9 @@ public interface TraceabilityCodeMapper extends BaseMapperX .eqIfPresent(TraceabilityCodeDO::getPlotId, reqVO.getPlotId()) .likeIfPresent(TraceabilityCodeDO::getPlotName, reqVO.getPlotName()) .eqIfPresent(TraceabilityCodeDO::getTenantId, reqVO.getTenantId()) - .betweenIfPresent(TraceabilityCodeDO::getHarvestDate, reqVO.getHarvestDate()) + // 采收时间范围查询 + .gtIfPresent(TraceabilityCodeDO::getHarvestDate, reqVO.getHarvestDateStart()) + .leIfPresent(TraceabilityCodeDO::getHarvestDate, reqVO.getHarvestDateEnd()) .eqIfPresent(TraceabilityCodeDO::getFarmingInputCount, reqVO.getFarmingInputCount()) .eqIfPresent(TraceabilityCodeDO::getProductId, reqVO.getProductId()) .likeIfPresent(TraceabilityCodeDO::getProductName, reqVO.getProductName()) @@ -32,7 +34,7 @@ public interface TraceabilityCodeMapper extends BaseMapperX .eqIfPresent(TraceabilityCodeDO::getProductImage, reqVO.getProductImage()) .likeIfPresent(TraceabilityCodeDO::getBrandName, reqVO.getBrandName()) .eqIfPresent(TraceabilityCodeDO::getIntroduce, reqVO.getIntroduce()) - .eqIfPresent(TraceabilityCodeDO::getBrandAuthentication, reqVO.getBrandAuthentication()) + .eqIfPresent(TraceabilityCodeDO::getBrandAuthenticationStr, reqVO.getBrandAuthentication()) .eqIfPresent(TraceabilityCodeDO::getBusinessId, reqVO.getBusinessId()) .likeIfPresent(TraceabilityCodeDO::getBusinessName, reqVO.getBusinessName()) .eqIfPresent(TraceabilityCodeDO::getIsShowBusinessName, reqVO.getIsShowBusinessName()) diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/framework/util/TraceabilityDataConverter.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/framework/util/TraceabilityDataConverter.java new file mode 100644 index 00000000..18436ad9 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/framework/util/TraceabilityDataConverter.java @@ -0,0 +1,132 @@ +package cn.iocoder.yudao.module.farm.framework.util; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodeRespVO; +import cn.iocoder.yudao.module.farm.dal.dataobject.traceabilitycode.TraceabilityCodeDO; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * 溯源数据转换工具类 + * 用于统一返回数据格式 + * + * @author 芋道源码 + */ +public class TraceabilityDataConverter { + + /** + * 将DO对象转换为RespVO对象,统一返回数据格式 + * + * @param traceabilityCodeDO 数据库对象 + * @return 响应VO对象 + */ + public static TraceabilityCodeRespVO convertToRespVO(TraceabilityCodeDO traceabilityCodeDO) { + if (traceabilityCodeDO == null) { + return null; + } + + TraceabilityCodeRespVO respVO = new TraceabilityCodeRespVO(); + + // 基本信息映射 + respVO.setId(traceabilityCodeDO.getId()); + respVO.setSpeciesCode(traceabilityCodeDO.getSpeciesCode()); + respVO.setSpeciesName(traceabilityCodeDO.getSpeciesName()); + respVO.setBaseId(traceabilityCodeDO.getBaseId()); + respVO.setBaseName(traceabilityCodeDO.getBaseName()); + respVO.setPlotId(traceabilityCodeDO.getPlotId()); + respVO.setPlotName(traceabilityCodeDO.getPlotName()); + respVO.setTenantId(traceabilityCodeDO.getTenantId()); + respVO.setHarvestDate(traceabilityCodeDO.getHarvestDate()); + respVO.setFarmingInputCount(traceabilityCodeDO.getFarmingInputCount()); + respVO.setProductId(traceabilityCodeDO.getProductId()); + respVO.setProductName(traceabilityCodeDO.getProductName()); + respVO.setPackingSpec(traceabilityCodeDO.getPackingSpec()); + respVO.setProductImage(traceabilityCodeDO.getProductImage()); + respVO.setProductImageList(traceabilityCodeDO.getProductImageList()); + respVO.setBrandName(traceabilityCodeDO.getBrandName()); + respVO.setIntroduce(traceabilityCodeDO.getIntroduce()); + respVO.setBusinessId(traceabilityCodeDO.getBusinessId()); + respVO.setBusinessName(traceabilityCodeDO.getBusinessName()); + respVO.setBusinessPhone(traceabilityCodeDO.getBusinessPhone()); + respVO.setStoreName(traceabilityCodeDO.getStoreName()); + respVO.setBusinessAddress(traceabilityCodeDO.getBusinessAddress()); + respVO.setPublicityImage(traceabilityCodeDO.getPublicityImage()); + respVO.setPublicityImageList(traceabilityCodeDO.getPublicityImageList()); + respVO.setPublicityProfile(traceabilityCodeDO.getPublicityProfile()); + respVO.setInspectionReport(traceabilityCodeDO.getInspectionReport()); + respVO.setCollectImages(traceabilityCodeDO.getCollectImages()); + respVO.setCollectImagesList(traceabilityCodeDO.getCollectImagesList()); + respVO.setCameraInformation(traceabilityCodeDO.getCameraInformation()); + respVO.setCodeOutCount(traceabilityCodeDO.getCodeOutCount()); + respVO.setQrCode(traceabilityCodeDO.getQrCode()); + respVO.setStatus(traceabilityCodeDO.getStatus()); + respVO.setCreateTime(traceabilityCodeDO.getCreateTime()); + respVO.setCodeOutBatch(traceabilityCodeDO.getCodeOutBatch()); + respVO.setScanCodeCount(traceabilityCodeDO.getScanCodeCount()); + + // 统一显示标志格式:Long -> Boolean + respVO.setIsShowBusinessName(convertLongToBoolean(traceabilityCodeDO.getIsShowBusinessName())); + respVO.setIsShowBusinessPhone(convertLongToBoolean(traceabilityCodeDO.getIsShowBusinessPhone())); + respVO.setIsShowStoreName(convertLongToBoolean(traceabilityCodeDO.getIsShowStoreName())); + respVO.setIsShowBusinessAddress(convertLongToBoolean(traceabilityCodeDO.getIsShowBusinessAddress())); + respVO.setIsShowPublicityImage(convertLongToBoolean(traceabilityCodeDO.getIsShowPublicityImage())); + respVO.setIsShowPublicityProfile(convertLongToBoolean(traceabilityCodeDO.getIsShowPublicityProfile())); + respVO.setIsShowBase(convertLongToBoolean(traceabilityCodeDO.getIsShowBase())); + + // 处理复杂数据结构 + respVO.setFarmingInputJson(traceabilityCodeDO.getFarmingInputJson()); + respVO.setCustomDataJson(traceabilityCodeDO.getCustomDataJson()); + respVO.setMeasuringUnit(traceabilityCodeDO.getMeasuringUnit()); + respVO.setPackingUnit(traceabilityCodeDO.getPackingUnit()); + + // 解析品牌认证列表 + if (StrUtil.isNotBlank(traceabilityCodeDO.getBrandAuthenticationStr())) { + respVO.setBrandAuthentication(Arrays.asList(traceabilityCodeDO.getBrandAuthenticationStr().split(","))); + } + + // 解析检验报告列表 + if (StrUtil.isNotBlank(traceabilityCodeDO.getInspectionReport())) { + respVO.setInspectionReportList(Arrays.asList(traceabilityCodeDO.getInspectionReport().split(","))); + } + + // 解析农事记录列表 + if (StrUtil.isNotBlank(traceabilityCodeDO.getFarmingInputJson())) { + try { + List farmingInputList = + JSONUtil.toList(traceabilityCodeDO.getFarmingInputJson(), TraceabilityCodeRespVO.FarmingInputItem.class); + respVO.setFarmingInputList(farmingInputList); + } catch (Exception e) { + // 解析失败,保持为空 + } + } + + // 解析自定义数据列表 + if (StrUtil.isNotBlank(traceabilityCodeDO.getCustomDataJson())) { + try { + List customDataList = + JSONUtil.toList(traceabilityCodeDO.getCustomDataJson(), TraceabilityCodeRespVO.CustomDataItem.class); + respVO.setCustomData(customDataList); + } catch (Exception e) { + // 解析失败,保持为空 + } + } + + return respVO; + } + + /** + * 将Long类型转换为Boolean类型 + * + * @param value Long值 + * @return Boolean值 + */ + private static Boolean convertLongToBoolean(Long value) { + if (value == null) { + return null; + } + return value == 1L; + } +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/traceabilitycode/TraceabilityCodeServiceImpl.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/traceabilitycode/TraceabilityCodeServiceImpl.java index 2a28241d..9a1c01bd 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/traceabilitycode/TraceabilityCodeServiceImpl.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/traceabilitycode/TraceabilityCodeServiceImpl.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.farm.service.traceabilitycode; +import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.util.IdUtil; +import cn.hutool.json.JSONUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.security.core.LoginUser; @@ -8,7 +10,6 @@ import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.Traceab import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodeSaveReqVO; import cn.iocoder.yudao.module.farm.dal.dataobject.traceabilitycode.TraceabilityCodeDO; import cn.iocoder.yudao.module.farm.dal.mysql.traceabilitycode.TraceabilityCodeMapper; -import cn.iocoder.yudao.module.farm.framework.util.ImageCollectionUtil; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -45,10 +46,10 @@ public class TraceabilityCodeServiceImpl implements TraceabilityCodeService { traceabilityCode.setId(IdUtil.fastUUID()); traceabilityCode.setTenantId(String.valueOf(user.getTenantId())); traceabilityCode.setCodeOutBatch(dateStr); - + // 处理图片集合转换 handleImageConversion(traceabilityCode, createReqVO); - + traceabilityCodeMapper.insert(traceabilityCode); } // 返回 @@ -61,10 +62,10 @@ public class TraceabilityCodeServiceImpl implements TraceabilityCodeService { validateTraceabilityCodeExists(updateReqVO.getId()); // 更新 TraceabilityCodeDO updateObj = BeanUtils.toBean(updateReqVO, TraceabilityCodeDO.class); - + // 处理图片集合转换 handleImageConversion(updateObj, updateReqVO); - + traceabilityCodeMapper.updateById(updateObj); } @@ -97,6 +98,9 @@ public class TraceabilityCodeServiceImpl implements TraceabilityCodeService { traceabilityCode.getProductImageList(); traceabilityCode.getPublicityImageList(); traceabilityCode.getCollectImagesList(); + + // 处理复杂数据结构的解析 + parseComplexDataFromDatabase(traceabilityCode); } return traceabilityCode; } @@ -111,6 +115,9 @@ public class TraceabilityCodeServiceImpl implements TraceabilityCodeService { traceabilityCode.getProductImageList(); traceabilityCode.getPublicityImageList(); traceabilityCode.getCollectImagesList(); + + // 处理复杂数据结构的解析 + parseComplexDataFromDatabase(traceabilityCode); } }); } @@ -136,19 +143,149 @@ public class TraceabilityCodeServiceImpl implements TraceabilityCodeService { } else if (reqVO.getProductImage() != null) { traceabilityCode.setProductImage(reqVO.getProductImage()); } - + // 处理宣传图片 if (reqVO.getPublicityImageList() != null && !reqVO.getPublicityImageList().isEmpty()) { traceabilityCode.setPublicityImageList(reqVO.getPublicityImageList()); } else if (reqVO.getPublicityImage() != null) { traceabilityCode.setPublicityImage(reqVO.getPublicityImage()); } - + // 处理批次采收图片 if (reqVO.getCollectImagesList() != null && !reqVO.getCollectImagesList().isEmpty()) { traceabilityCode.setCollectImagesList(reqVO.getCollectImagesList()); } else if (reqVO.getCollectImages() != null) { traceabilityCode.setCollectImages(reqVO.getCollectImages()); } + + // 处理Boolean到Long的类型转换 + convertBooleanToLong(traceabilityCode, reqVO); + + // 处理复杂数据结构转换 + handleComplexDataConversion(traceabilityCode, reqVO); + } + + /** + * 处理复杂数据结构转换 + * 将复杂的嵌套结构序列化为JSON字符串存储到数据库 + */ + private void handleComplexDataConversion(TraceabilityCodeDO traceabilityCode, TraceabilityCodeSaveReqVO reqVO) { + // 处理农事记录列表 + if (reqVO.getFarmingInputList() != null && !reqVO.getFarmingInputList().isEmpty()) { + String farmingInputJson = JSONUtil.toJsonStr(reqVO.getFarmingInputList()); + // 将农事记录JSON存储到专门的字段 + traceabilityCode.setFarmingInputJson(farmingInputJson); + // 同时存储到cameraInformation字段以保持兼容性 + traceabilityCode.setCameraInformation(farmingInputJson); + } + + // 处理品牌认证列表 + if (reqVO.getBrandAuthentication() != null && !reqVO.getBrandAuthentication().isEmpty()) { + String brandAuthStr = String.join(",", reqVO.getBrandAuthentication()); + traceabilityCode.setBrandAuthenticationStr(brandAuthStr); + } + + // 处理检验报告列表 + if (reqVO.getInspectionReportList() != null && !reqVO.getInspectionReportList().isEmpty()) { + String inspectionReportStr = String.join(",", reqVO.getInspectionReportList()); + traceabilityCode.setInspectionReport(inspectionReportStr); + } + + // 处理自定义数据 + if (reqVO.getCustomData() != null && !reqVO.getCustomData().isEmpty()) { + String customDataJson = JSONUtil.toJsonStr(reqVO.getCustomData()); + // 存储到专门的字段 + traceabilityCode.setCustomDataJson(customDataJson); + } + + // 处理新增的字段 + if (CharSequenceUtil.isNotBlank(reqVO.getMeasuringUnit())) { + try { + traceabilityCode.setMeasuringUnit(Integer.valueOf(reqVO.getMeasuringUnit())); + } catch (NumberFormatException e) { + // 忽略无效的数字格式 + } + } + + if (CharSequenceUtil.isNotBlank(reqVO.getPackingUnit())) { + try { + traceabilityCode.setPackingUnit(Integer.valueOf(reqVO.getPackingUnit())); + } catch (NumberFormatException e) { + // 忽略无效的数字格式 + } + } + + // isShowBase字段已经在convertBooleanToLong方法中处理了 + } + + /** + * 处理Boolean到Long的类型转换 + * 将VO中的Boolean字段转换为DO中的Long字段 + */ + private void convertBooleanToLong(TraceabilityCodeDO traceabilityCode, TraceabilityCodeSaveReqVO reqVO) { + // 转换显示标志字段 + if (reqVO.getIsShowBusinessName() != null) { + traceabilityCode.setIsShowBusinessName(reqVO.getIsShowBusinessName() ? 1L : 0L); + } + + if (reqVO.getIsShowBusinessPhone() != null) { + traceabilityCode.setIsShowBusinessPhone(reqVO.getIsShowBusinessPhone() ? 1L : 0L); + } + + if (reqVO.getIsShowStoreName() != null) { + traceabilityCode.setIsShowStoreName(reqVO.getIsShowStoreName() ? 1L : 0L); + } + + if (reqVO.getIsShowBusinessAddress() != null) { + traceabilityCode.setIsShowBusinessAddress(reqVO.getIsShowBusinessAddress() ? 1L : 0L); + } + + if (reqVO.getIsShowPublicityProfile() != null) { + traceabilityCode.setIsShowPublicityProfile(reqVO.getIsShowPublicityProfile() ? 1L : 0L); + } + + if (reqVO.getIsShowPublicityImage() != null) { + traceabilityCode.setIsShowPublicityImage(reqVO.getIsShowPublicityImage() ? 1L : 0L); + } + + if (reqVO.getIsShowBase() != null) { + traceabilityCode.setIsShowBase(reqVO.getIsShowBase() ? 1L : 0L); + } + } + + /** + * 从数据库解析复杂数据结构 + * 将存储的JSON字符串解析为对象属性,并统一返回数据格式 + */ + private void parseComplexDataFromDatabase(TraceabilityCodeDO traceabilityCode) { + // 解析农事记录JSON数据 + if (CharSequenceUtil.isNotBlank(traceabilityCode.getCameraInformation())) { + String cameraInfo = traceabilityCode.getCameraInformation(); + // 检查是否是JSON格式的农事记录数据 + if (cameraInfo.startsWith("{") || cameraInfo.startsWith("[")) { + traceabilityCode.setFarmingInputJson(cameraInfo); + } + } + + // 解析品牌认证列表 + if (CharSequenceUtil.isNotBlank(traceabilityCode.getBrandAuthenticationStr())) { + // 品牌认证已经是逗号分隔的字符串,不需要额外处理 + } + + // 解析检验报告列表 + if (CharSequenceUtil.isNotBlank(traceabilityCode.getInspectionReport())) { + // 检验报告已经是逗号分隔的字符串,不需要额外处理 + } + + // 统一返回数据格式:将Long类型的显示标志转换为Boolean类型 + convertLongToBoolean(traceabilityCode); + } + + /** + * 将DO中的Long字段转换为Boolean字段,统一返回数据格式 + */ + private void convertLongToBoolean(TraceabilityCodeDO traceabilityCode) { + // 这里我们不需要实际转换,因为DO对象保持Long类型用于数据库存储 + // 转换将在VO层进行,确保前端接收到的是Boolean类型 } } \ No newline at end of file diff --git a/yudao-module-farm/src/main/resources/sql/add_traceability_json_fields.sql b/yudao-module-farm/src/main/resources/sql/add_traceability_json_fields.sql new file mode 100644 index 00000000..7f4cd3d1 --- /dev/null +++ b/yudao-module-farm/src/main/resources/sql/add_traceability_json_fields.sql @@ -0,0 +1,41 @@ +-- 为 farm_traceability_code 表添加 JSON 字段 +-- 用于存储复杂的农事记录和自定义数据 + +-- MySQL 版本 +ALTER TABLE farm_traceability_code +ADD COLUMN farming_input_json TEXT COMMENT '农事记录JSON数据(存储复杂的农事记录结构)', +ADD COLUMN custom_data_json TEXT COMMENT '自定义数据JSON(存储自定义字段数据)', +ADD COLUMN measuring_unit INT COMMENT '计量单位', +ADD COLUMN packing_unit INT COMMENT '包装单位', +ADD COLUMN is_show_base BIGINT COMMENT '是否显示基地'; + +-- PostgreSQL 版本 +-- ALTER TABLE farm_traceability_code +-- ADD COLUMN farming_input_json TEXT, +-- ADD COLUMN custom_data_json TEXT, +-- ADD COLUMN measuring_unit INTEGER, +-- ADD COLUMN packing_unit INTEGER, +-- ADD COLUMN is_show_base BIGINT; + +-- Oracle 版本 +-- ALTER TABLE farm_traceability_code +-- ADD (farming_input_json CLOB, +-- custom_data_json CLOB, +-- measuring_unit NUMBER(10), +-- packing_unit NUMBER(10), +-- is_show_base NUMBER(19)); + +-- SQL Server 版本 +-- ALTER TABLE farm_traceability_code +-- ADD farming_input_json NVARCHAR(MAX), +-- custom_data_json NVARCHAR(MAX), +-- measuring_unit INT, +-- packing_unit INT, +-- is_show_base BIGINT; + +-- 添加索引以提高查询性能 +CREATE INDEX idx_farm_traceability_code_farming_input_json ON farm_traceability_code(farming_input_json(100)); +CREATE INDEX idx_farm_traceability_code_custom_data_json ON farm_traceability_code(custom_data_json(100)); +CREATE INDEX idx_farm_traceability_code_measuring_unit ON farm_traceability_code(measuring_unit); +CREATE INDEX idx_farm_traceability_code_packing_unit ON farm_traceability_code(packing_unit); +CREATE INDEX idx_farm_traceability_code_is_show_base ON farm_traceability_code(is_show_base); diff --git a/yudao-module-farm/src/main/resources/traceability-code-new-structure.http b/yudao-module-farm/src/main/resources/traceability-code-new-structure.http new file mode 100644 index 00000000..3d0741ed --- /dev/null +++ b/yudao-module-farm/src/main/resources/traceability-code-new-structure.http @@ -0,0 +1,225 @@ +### 创建溯源-溯源码(支持新的复杂JSON结构) +POST http://localhost:8080/admin-api/farm/traceability-code/create +Content-Type: application/json +Authorization: Bearer {{token}} + +{ + "speciesCode": "", + "speciesName": "绿水稻", + "businessId": "027fef60-72c7-4b16-aad7-74bd4e7c492d", + "businessName": "测试", + "businessPhone": "19995432633", + "storeName": "123", + "businessAddress": "123", + "publicityProfile": "123", + "publicityImageList": [ + "http://223.83.152.93:9000/farm/20250826/b569169d762c4c74bcb5b007be492060_1756207500866.png", + "http://223.83.152.93:9000/farm/20250826/b569169d762c4c74bcb5b007be492060_1756207885105.png" + ], + "isShowBusinessName": true, + "isShowBusinessPhone": true, + "isShowStoreName": true, + "isShowBusinessAddress": true, + "isShowPublicityProfile": true, + "isShowPublicityImage": true, + "productId": "64fcede4-247b-437d-93be-b7c9d636e6ce", + "productName": "红薯干", + "baseId": "", + "baseName": "测试基地1", + "isShowBase": true, + "harvestDate": "2025-09-01 00:00:00", + "farmingInputCount": 1, + "farmingInputList": [ + { + "farmingName": "123", + "date": ["2025-08-31", "2025-09-01"], + "inputList": [ + { + "inputsId": "97e9f792-3b84-4132-9350-b08f34641c65", + "assetType": 2, + "dose": 100, + "unit": 6, + "packageUnit": 1, + "diluted": "1.5倍", + "usage": "123", + "inputsName": "药物", + "unitName": null, + "packageUnitName": null + } + ], + "imageList": [] + } + ], + "productImage": "", + "brandAuthentication": ["1", "2", "3", "4"], + "inspectionReport": "", + "inspectionReportList": [], + "collectImages": "", + "collectImagesList": [], + "measuringUnit": "2", + "packingUnit": "2", + "customData": [ + { + "linkName": "123", + "customSection": [ + { + "label": "123", + "type": 1, + "content": "123", + "imageList": [] + }, + { + "label": "456", + "type": 2, + "content": "456", + "imageList": [ + "http://example.com/image1.jpg", + "http://example.com/image2.jpg" + ] + } + ] + }, + { + "linkName": "789", + "customSection": [ + { + "label": "789", + "type": 1, + "content": "789", + "imageList": [] + } + ] + } + ], + "codeOutCount": 1, + "cameraInformation": null, + "packingSpec": "10", + "brandName": "红薯干", + "introduce": "好吃的红薯干哦" +} + +### 更新溯源-溯源码(支持新的复杂JSON结构) +PUT http://localhost:8080/admin-api/farm/traceability-code/update +Content-Type: application/json +Authorization: Bearer {{token}} + +{ + "id": "{{traceabilityCodeId}}", + "speciesCode": "", + "speciesName": "绿水稻", + "businessId": "027fef60-72c7-4b16-aad7-74bd4e7c492d", + "businessName": "测试企业", + "businessPhone": "19995432633", + "storeName": "测试网店", + "businessAddress": "测试地址", + "publicityProfile": "测试企业简介", + "publicityImageList": [ + "http://223.83.152.93:9000/farm/20250826/b569169d762c4c74bcb5b007be492060_1756207500866.png" + ], + "isShowBusinessName": true, + "isShowBusinessPhone": true, + "isShowStoreName": true, + "isShowBusinessAddress": true, + "isShowPublicityProfile": true, + "isShowPublicityImage": true, + "productId": "64fcede4-247b-437d-93be-b7c9d636e6ce", + "productName": "红薯干", + "baseId": "", + "baseName": "测试基地1", + "isShowBase": true, + "harvestDate": "2025-09-01 00:00:00", + "farmingInputCount": 2, + "farmingInputList": [ + { + "farmingName": "施肥", + "date": ["2025-08-31", "2025-09-01"], + "inputList": [ + { + "inputsId": "97e9f792-3b84-4132-9350-b08f34641c65", + "assetType": 2, + "dose": 100, + "unit": 6, + "packageUnit": 1, + "diluted": "1.5倍", + "usage": "叶面喷施", + "inputsName": "药物", + "unitName": "毫升", + "packageUnitName": "瓶" + } + ], + "imageList": [] + }, + { + "farmingName": "浇水", + "date": ["2025-09-02"], + "inputList": [], + "imageList": [] + } + ], + "productImage": "", + "brandAuthentication": ["有机认证", "绿色食品认证", "无公害认证"], + "inspectionReport": "", + "inspectionReportList": ["报告1.pdf", "报告2.pdf"], + "collectImages": "", + "collectImagesList": [], + "measuringUnit": "2", + "packingUnit": "2", + "customData": [ + { + "linkName": "产品特色", + "customSection": [ + { + "label": "产地特色", + "type": 1, + "content": "来自四川优质红薯产区", + "imageList": [] + }, + { + "label": "制作工艺", + "type": 2, + "content": "传统手工制作,无添加", + "imageList": [ + "http://example.com/process1.jpg", + "http://example.com/process2.jpg" + ] + } + ] + }, + { + "linkName": "营养价值", + "customSection": [ + { + "label": "营养成分", + "type": 1, + "content": "富含膳食纤维和维生素", + "imageList": [] + } + ] + } + ], + "codeOutCount": 1, + "cameraInformation": null, + "packingSpec": "10", + "brandName": "红薯干", + "introduce": "好吃的红薯干哦,营养丰富,口感香甜" +} + +### 获取溯源-溯源码详情 +GET http://localhost:8080/admin-api/farm/traceability-code/get?id={{traceabilityCodeId}} +Authorization: Bearer {{token}} + +### 获取溯源-溯源码分页 +GET http://localhost:8080/admin-api/farm/traceability-code/page?pageNo=1&pageSize=10 +Authorization: Bearer {{token}} + +### 扫描溯源码 +GET http://localhost:8080/admin-api/farm/traceability-code/scan?id={{traceabilityCodeId}} +Authorization: Bearer {{token}} + +### 删除溯源-溯源码 +DELETE http://localhost:8080/admin-api/farm/traceability-code/delete?id={{traceabilityCodeId}} +Authorization: Bearer {{token}} + +### 批量删除溯源-溯源码 +DELETE http://localhost:8080/admin-api/farm/traceability-code/delete-list?ids={{traceabilityCodeId1}},{{traceabilityCodeId2}} +Authorization: Bearer {{token}}