diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/JDOrderListController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/JDOrderListController.java index a14055a..db2dd1f 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/JDOrderListController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/JDOrderListController.java @@ -163,6 +163,24 @@ public class JDOrderListController extends BaseController } } + /** + * 批量导入后返表:请求内按顺序处理多个文件,前端仅需一次提交;结果概要返回,明细见上传记录。 + */ + @Log(title = "JD订单后返表批量导入", businessType = BusinessType.IMPORT) + @PostMapping("/importGroupRebateExcelBatch") + public AjaxResult importGroupRebateExcelBatch(@RequestParam("files") MultipartFile[] files, + @RequestParam(value = "documentTitle", required = false) String documentTitle) { + try { + Map data = groupRebateExcelImportService.importExcelBatch(files, documentTitle); + if (Boolean.FALSE.equals(data.get("success"))) { + return AjaxResult.error((String) data.get("message")); + } + return AjaxResult.success(data); + } catch (Exception e) { + return AjaxResult.error("批量导入失败: " + e.getMessage()); + } + } + /** * 后返表上传记录(分页) */ @@ -185,6 +203,15 @@ public class JDOrderListController extends BaseController * 重新下载已上传的后返表原件(与通用 download 一致,使用 POST + blob) */ @Log(title = "后返表上传记录下载", businessType = BusinessType.EXPORT) + /** + * 删除一条后返表上传记录,并撤销写入订单的后返备注(依赖 uploadRecordId / affectedOrderIds;历史导入可能仅删记录) + */ + @Log(title = "后返表上传记录", businessType = BusinessType.DELETE) + @DeleteMapping("/groupRebateUpload/{id}") + public AjaxResult deleteGroupRebateUpload(@PathVariable("id") Long id) { + return AjaxResult.success(groupRebateExcelImportService.deleteUploadRecord(id)); + } + @PostMapping("/groupRebateUpload/download/{id}") public void downloadGroupRebateUpload(@PathVariable("id") Long id, HttpServletResponse response) throws Exception { GroupRebateExcelUpload rec = groupRebateExcelUploadService.selectGroupRebateExcelUploadById(id); diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/dto/RebateRemarkItem.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/dto/RebateRemarkItem.java index 1fc0ce3..180eaee 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/dto/RebateRemarkItem.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/dto/RebateRemarkItem.java @@ -20,6 +20,9 @@ public class RebateRemarkItem { /** 写入时间戳(毫秒) */ private Long uploadTime; + /** 对应 jd_group_rebate_excel_upload.id,用于删除上传记录时精确撤销本条备注 */ + private Long uploadRecordId; + /** * 是否判定为异常(空「是否返现」、待补/下次做表等关键词) * 便于列表筛选与着色 diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/mapper/GroupRebateExcelUploadMapper.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/mapper/GroupRebateExcelUploadMapper.java index 34fa2c8..29f53e2 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/mapper/GroupRebateExcelUploadMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/mapper/GroupRebateExcelUploadMapper.java @@ -8,6 +8,10 @@ public interface GroupRebateExcelUploadMapper { int insertGroupRebateExcelUpload(GroupRebateExcelUpload row); + int updateGroupRebateExcelUpload(GroupRebateExcelUpload row); + + int deleteGroupRebateExcelUploadById(Long id); + GroupRebateExcelUpload selectGroupRebateExcelUploadById(Long id); List selectGroupRebateExcelUploadList(GroupRebateExcelUpload query); diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/mapper/JDOrderMapper.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/mapper/JDOrderMapper.java index c295f35..90d3ab0 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/mapper/JDOrderMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/mapper/JDOrderMapper.java @@ -46,6 +46,11 @@ public interface JDOrderMapper { */ JDOrder selectJDOrderByThirdPartyOrderNo(String thirdPartyOrderNo); + /** + * 后返备注 JSON 中含指定 uploadRecordId 的订单主键(撤销导入时用) + */ + List selectOrderIdsByRebateRemarkUploadRecordId(Long uploadRecordId); + /** * 批量删除(根据主键ID) */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/IGroupRebateExcelUploadService.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/IGroupRebateExcelUploadService.java index 06c6c04..7f1626f 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/IGroupRebateExcelUploadService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/IGroupRebateExcelUploadService.java @@ -11,6 +11,8 @@ public interface IGroupRebateExcelUploadService { */ void saveRecordInNewTransaction(GroupRebateExcelUpload row); + void updateRecordInNewTransaction(GroupRebateExcelUpload row); + GroupRebateExcelUpload selectGroupRebateExcelUploadById(Long id); List selectGroupRebateExcelUploadList(GroupRebateExcelUpload query); diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/GroupRebateExcelImportService.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/GroupRebateExcelImportService.java index 36219c6..ae31c1f 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/GroupRebateExcelImportService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/GroupRebateExcelImportService.java @@ -7,9 +7,11 @@ import com.ruoyi.common.constant.Constants; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.file.FileUploadUtils; +import com.ruoyi.common.exception.ServiceException; import com.ruoyi.jarvis.domain.GroupRebateExcelUpload; import com.ruoyi.jarvis.domain.JDOrder; import com.ruoyi.jarvis.domain.dto.RebateRemarkItem; +import com.ruoyi.jarvis.mapper.GroupRebateExcelUploadMapper; import com.ruoyi.jarvis.mapper.JDOrderMapper; import com.ruoyi.jarvis.service.IGroupRebateExcelUploadService; import org.apache.poi.ss.usermodel.Cell; @@ -38,6 +40,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.regex.Pattern; @@ -62,6 +65,9 @@ public class GroupRebateExcelImportService { @Resource private JDOrderMapper jdOrderMapper; + @Resource + private GroupRebateExcelUploadMapper groupRebateExcelUploadMapper; + @Resource private IGroupRebateExcelUploadService groupRebateExcelUploadService; @@ -104,9 +110,10 @@ public class GroupRebateExcelImportService { } File diskFile = resolveDiskFile(webPath); + Long recordId = insertInitialUploadRecord(originalFilename, webPath, fileSize, title); Map result; try { - result = self.processWorkbookTransactional(diskFile, title); + result = self.processWorkbookTransactional(diskFile, title, recordId); } catch (Exception e) { log.error("后返表导入处理异常", e); result = new HashMap<>(); @@ -115,13 +122,136 @@ public class GroupRebateExcelImportService { result.put("documentTitle", title); } result.put("savedFilePath", webPath); - Long recordId = persistUploadRecord(originalFilename, webPath, fileSize, title, result); + finalizeUploadRecord(recordId, originalFilename, webPath, fileSize, title, result); result.put("uploadRecordId", recordId); return result; } + /** + * 批量导入:按顺序逐个调用 {@link #importExcel},在同一请求内由后台依次处理完成。 + * + * @param documentTitle 仅当恰好 1 个有效文件时作为文档标题;多文件时忽略,各文件用各自文件名。 + */ + public Map importExcelBatch(MultipartFile[] files, String documentTitle) { + if (files == null || files.length == 0) { + Map empty = new HashMap<>(); + empty.put("success", false); + empty.put("message", "请选择文件"); + return empty; + } + List list = new ArrayList<>(); + for (MultipartFile f : files) { + if (f != null && !f.isEmpty()) { + list.add(f); + } + } + if (list.isEmpty()) { + Map empty = new HashMap<>(); + empty.put("success", false); + empty.put("message", "没有有效文件"); + return empty; + } + boolean single = list.size() == 1; + String sharedTitle = (single && StringUtils.isNotEmpty(documentTitle)) ? documentTitle.trim() : null; + + int ok = 0; + int fail = 0; + List> failures = new ArrayList<>(); + for (MultipartFile file : list) { + try { + Map r = importExcel(file, sharedTitle); + if (Boolean.TRUE.equals(r.get("success"))) { + ok++; + } else { + fail++; + addBatchFailureBrief(failures, file.getOriginalFilename(), r.get("message")); + } + } catch (Exception e) { + log.warn("批量后返表:单文件导入失败 {}", file.getOriginalFilename(), e); + fail++; + addBatchFailureBrief(failures, file.getOriginalFilename(), e.getMessage()); + } + } + Map out = new HashMap<>(); + out.put("success", true); + out.put("totalFiles", list.size()); + out.put("successCount", ok); + out.put("failCount", fail); + out.put("message", String.format(Locale.ROOT, + "已处理 %d 个文件:成功 %d,失败 %d。明细可在「后返上传记录」查看。", + list.size(), ok, fail)); + if (!failures.isEmpty()) { + out.put("failures", failures); + } + return out; + } + + private static void addBatchFailureBrief(List> failures, String filename, Object message) { + if (failures.size() >= 15) { + return; + } + Map fb = new HashMap<>(2); + fb.put("filename", filename); + fb.put("message", message != null ? message.toString() : ""); + failures.add(fb); + } + + /** + * 删除一条上传记录:从订单 rebate_remark_json 中移除本次导入写入的条目,并删除数据库记录与磁盘文件。 + */ + public Map deleteUploadRecord(Long id) { + if (id == null) { + throw new ServiceException("记录 ID 无效"); + } + GroupRebateExcelUpload rec = groupRebateExcelUploadService.selectGroupRebateExcelUploadById(id); + if (rec == null) { + throw new ServiceException("上传记录不存在"); + } + String filePath = rec.getFilePath(); + Map data = self.deleteUploadRecordTransactional(id, rec); + deleteUploadDiskFileIfPresent(filePath); + return data; + } + @Transactional(rollbackFor = Exception.class) - public Map processWorkbookTransactional(File diskFile, String title) throws Exception { + public Map deleteUploadRecordTransactional(Long id, GroupRebateExcelUpload rec) { + Set orderIds = new LinkedHashSet<>(); + List fromDetail = parseAffectedOrderIds(rec.getResultDetailJson()); + if (fromDetail != null) { + orderIds.addAll(fromDetail); + } + if (orderIds.isEmpty()) { + List fromJson = jdOrderMapper.selectOrderIdsByRebateRemarkUploadRecordId(id); + if (fromJson != null) { + orderIds.addAll(fromJson); + } + } + int ordersUpdated = 0; + for (Long oid : orderIds) { + if (stripRebateRemarkItemsByUploadRecordId(oid, id)) { + ordersUpdated++; + } + } + int deleted = groupRebateExcelUploadMapper.deleteGroupRebateExcelUploadById(id); + if (deleted == 0) { + throw new ServiceException("删除上传记录失败"); + } + Map data = new HashMap<>(); + data.put("ordersScanned", orderIds.size()); + data.put("ordersRemarkUpdated", ordersUpdated); + data.put("revertedByUploadRecordId", id); + if (orderIds.isEmpty()) { + data.put("message", "已删除上传记录;未找到可回滚的订单后返备注(多为本功能上线前的历史导入,请按需手工改订单)"); + } else { + data.put("message", String.format(Locale.ROOT, + "已删除上传记录;已扫描 %d 个订单,从 %d 个订单移除了本次导入对应的后返备注", + orderIds.size(), ordersUpdated)); + } + return data; + } + + @Transactional(rollbackFor = Exception.class) + public Map processWorkbookTransactional(File diskFile, String title, Long uploadRecordId) throws Exception { Map result = new HashMap<>(); try (InputStream is = new FileInputStream(diskFile); Workbook wb = WorkbookFactory.create(is)) { Sheet sheet = wb.getNumberOfSheets() > 0 ? wb.getSheetAt(0) : null; @@ -155,8 +285,40 @@ public class GroupRebateExcelImportService { return result; } + if (hm.whetherRebateCol >= 0) { + int orderDataRows = 0; + boolean anyWhetherFilled = false; + for (int r = headerRowIndex + 1; r <= sheet.getLastRowNum(); r++) { + Row scanRow = sheet.getRow(r); + if (scanRow == null) { + continue; + } + String orderNoScan = normalizeOrderNo(getCellText(scanRow, hm.orderCol)); + if (orderNoScan.isEmpty()) { + continue; + } + orderDataRows++; + String w = trimToNull(getCellText(scanRow, hm.whetherRebateCol)); + if (w != null) { + anyWhetherFilled = true; + break; + } + } + if (orderDataRows > 0 && !anyWhetherFilled) { + result.put("success", false); + result.put("message", "「是否返现」列全部为空,未写入任何订单,请补全该列后重新上传。"); + result.put("documentTitle", title); + result.put("dataRows", orderDataRows); + result.put("updatedOrders", 0); + result.put("notFoundOrderNos", new ArrayList<>()); + result.put("errors", new ArrayList<>()); + return result; + } + } + int dataRows = 0; int updatedOrders = 0; + Set affectedOrderIds = new LinkedHashSet<>(); Set notFound = new LinkedHashSet<>(); List errors = new ArrayList<>(); @@ -194,7 +356,8 @@ public class GroupRebateExcelImportService { } try { - appendRebateRemark(order, title, whether, amountStr); + appendRebateRemark(order, title, whether, amountStr, uploadRecordId); + affectedOrderIds.add(order.getId()); updatedOrders++; } catch (Exception e) { log.warn("写入后返备注失败 orderNo={} id={}", orderNo, order.getId(), e); @@ -208,6 +371,7 @@ public class GroupRebateExcelImportService { result.put("updatedOrders", updatedOrders); result.put("notFoundOrderNos", new ArrayList<>(notFound)); result.put("errors", errors); + result.put("affectedOrderIds", new ArrayList<>(affectedOrderIds)); result.put("message", String.format(Locale.ROOT, "解析完成:有效数据行 %d,匹配并更新订单 %d,未找到订单 %d 条", dataRows, updatedOrders, notFound.size())); @@ -215,18 +379,46 @@ public class GroupRebateExcelImportService { } } - private Long persistUploadRecord(String originalFilename, String webPath, long fileSize, - String title, Map procResult) { + private Long insertInitialUploadRecord(String originalFilename, String webPath, long fileSize, String title) { GroupRebateExcelUpload row = new GroupRebateExcelUpload(); row.setOriginalFilename(originalFilename); - row.setFilePath(StringUtils.isNotEmpty(webPath) ? webPath : ""); + row.setFilePath(webPath); row.setFileSize(fileSize); row.setDocumentTitle(title); + row.setImportStatus(1); + row.setDataRows(0); + row.setUpdatedOrders(0); + row.setNotFoundCount(0); + JSONObject d = new JSONObject(); + d.put("message", "解析中"); + d.put("documentTitle", title); + row.setResultDetailJson(d.toJSONString()); try { row.setCreateBy(SecurityUtils.getUsername()); } catch (Exception e) { row.setCreateBy(""); } + groupRebateExcelUploadService.saveRecordInNewTransaction(row); + return row.getId(); + } + + private void finalizeUploadRecord(Long recordId, String originalFilename, String webPath, long fileSize, + String title, Map procResult) { + GroupRebateExcelUpload row = new GroupRebateExcelUpload(); + row.setId(recordId); + row.setOriginalFilename(originalFilename); + row.setFilePath(StringUtils.isNotEmpty(webPath) ? webPath : ""); + row.setFileSize(fileSize); + row.setDocumentTitle(title); + applyProcResultToRow(row, procResult); + try { + groupRebateExcelUploadService.updateRecordInNewTransaction(row); + } catch (Exception e) { + log.error("更新后返上传记录失败 id={}", recordId, e); + } + } + + private void applyProcResultToRow(GroupRebateExcelUpload row, Map procResult) { boolean ok = Boolean.TRUE.equals(procResult.get("success")); row.setImportStatus(ok ? 2 : 1); row.setDataRows(asInt(procResult.get("dataRows"))); @@ -247,7 +439,25 @@ public class GroupRebateExcelImportService { if (procResult.containsKey("savedFilePath")) { detail.put("savedFilePath", procResult.get("savedFilePath")); } + if (procResult.containsKey("affectedOrderIds")) { + detail.put("affectedOrderIds", procResult.get("affectedOrderIds")); + } row.setResultDetailJson(detail.toJSONString()); + } + + private Long persistUploadRecord(String originalFilename, String webPath, long fileSize, + String title, Map procResult) { + GroupRebateExcelUpload row = new GroupRebateExcelUpload(); + row.setOriginalFilename(originalFilename); + row.setFilePath(StringUtils.isNotEmpty(webPath) ? webPath : ""); + row.setFileSize(fileSize); + row.setDocumentTitle(title); + try { + row.setCreateBy(SecurityUtils.getUsername()); + } catch (Exception e) { + row.setCreateBy(""); + } + applyProcResultToRow(row, procResult); try { groupRebateExcelUploadService.saveRecordInNewTransaction(row); @@ -258,6 +468,69 @@ public class GroupRebateExcelImportService { } } + private static List parseAffectedOrderIds(String resultDetailJson) { + if (StringUtils.isEmpty(resultDetailJson)) { + return null; + } + try { + JSONObject o = JSON.parseObject(resultDetailJson); + if (o == null || !o.containsKey("affectedOrderIds")) { + return null; + } + return o.getList("affectedOrderIds", Long.class); + } catch (Exception e) { + return null; + } + } + + private boolean stripRebateRemarkItemsByUploadRecordId(Long orderId, Long uploadRecordId) { + JDOrder order = jdOrderMapper.selectJDOrderById(orderId); + if (order == null) { + return false; + } + List list = new ArrayList<>(); + String existing = order.getRebateRemarkJson(); + if (existing != null && !existing.trim().isEmpty()) { + try { + list.addAll(JSON.parseArray(existing, RebateRemarkItem.class)); + } catch (Exception e) { + return false; + } + } + int before = list.size(); + list.removeIf(it -> Objects.equals(uploadRecordId, it.getUploadRecordId())); + if (list.size() == before) { + return false; + } + boolean hasAbnormal = false; + for (RebateRemarkItem it : list) { + if (Boolean.TRUE.equals(it.getAbnormal())) { + hasAbnormal = true; + break; + } + } + JDOrder upd = new JDOrder(); + upd.setId(order.getId()); + upd.setRebateRemarkJson(list.isEmpty() ? "[]" : JSON.toJSONString(list)); + upd.setRebateRemarkHasAbnormal(hasAbnormal ? 1 : 0); + jdOrderMapper.updateJDOrder(upd); + return true; + } + + private void deleteUploadDiskFileIfPresent(String webPath) { + if (StringUtils.isEmpty(webPath)) { + return; + } + try { + File f = resolveDiskFile(webPath); + if (f.isFile() && !f.delete()) { + log.warn("删除后返上传文件失败: {}", f.getAbsolutePath()); + } + } catch (Exception e) { + log.warn("删除后返上传文件异常 path={}", webPath, e); + } + } + private static Integer asInt(Object o) { if (o == null) { return null; @@ -299,7 +572,8 @@ public class GroupRebateExcelImportService { return new File(RuoYiConfig.getProfile(), sub); } - private void appendRebateRemark(JDOrder order, String documentTitle, String whetherRebate, String rebateAmount) { + private void appendRebateRemark(JDOrder order, String documentTitle, String whetherRebate, String rebateAmount, + Long uploadRecordId) { List list = new ArrayList<>(); String existing = order.getRebateRemarkJson(); if (existing != null && !existing.trim().isEmpty()) { @@ -317,6 +591,7 @@ public class GroupRebateExcelImportService { item.setRebateAmount(rebateAmount); item.setUploadTime(System.currentTimeMillis()); item.setAbnormal(isAbnormalWhetherRebate(whetherRebate)); + item.setUploadRecordId(uploadRecordId); list.add(item); boolean hasAbnormal = false; diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/GroupRebateExcelUploadServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/GroupRebateExcelUploadServiceImpl.java index cd6a0d6..1612943 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/GroupRebateExcelUploadServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/GroupRebateExcelUploadServiceImpl.java @@ -22,6 +22,12 @@ public class GroupRebateExcelUploadServiceImpl implements IGroupRebateExcelUploa groupRebateExcelUploadMapper.insertGroupRebateExcelUpload(row); } + @Override + @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class) + public void updateRecordInNewTransaction(GroupRebateExcelUpload row) { + groupRebateExcelUploadMapper.updateGroupRebateExcelUpload(row); + } + @Override public GroupRebateExcelUpload selectGroupRebateExcelUploadById(Long id) { return groupRebateExcelUploadMapper.selectGroupRebateExcelUploadById(id); diff --git a/ruoyi-system/src/main/resources/mapper/jarvis/GroupRebateExcelUploadMapper.xml b/ruoyi-system/src/main/resources/mapper/jarvis/GroupRebateExcelUploadMapper.xml index 4bed946..3c161d3 100644 --- a/ruoyi-system/src/main/resources/mapper/jarvis/GroupRebateExcelUploadMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/jarvis/GroupRebateExcelUploadMapper.xml @@ -33,6 +33,24 @@ ) + + update jd_group_rebate_excel_upload + set document_title = #{documentTitle}, + original_filename = #{originalFilename}, + file_path = #{filePath}, + file_size = #{fileSize}, + import_status = #{importStatus}, + data_rows = #{dataRows}, + updated_orders = #{updatedOrders}, + not_found_count = #{notFoundCount}, + result_detail_json = #{resultDetailJson} + where id = #{id} + + + + delete from jd_group_rebate_excel_upload where id = #{id} + + + + delete from jd_order where id in diff --git a/sql/clear_rebate_remark_without_upload_record_id.sql b/sql/clear_rebate_remark_without_upload_record_id.sql new file mode 100644 index 0000000..b46bb54 --- /dev/null +++ b/sql/clear_rebate_remark_without_upload_record_id.sql @@ -0,0 +1,71 @@ +-- ============================================================================= +-- 清理「无 uploadRecordId」的后返备注,便于重新上传后带上批次 ID +-- 执行前请先备份 jd_order 或整库;建议先跑预览 SELECT +-- 库名请按实际执行 USE(示例库名 jd) +-- ============================================================================= + +-- USE jd; + +-- --------------------------------------------------------------------------- +-- 方案 A(推荐):整条 JSON 里从未出现 "uploadRecordId" 的订单 → 整段清空为 [] +-- 适用:历史导入都没有批次 ID,准备整批重传 +-- --------------------------------------------------------------------------- + +SELECT COUNT(*) AS cnt_will_clear +FROM jd_order +WHERE rebate_remark_json IS NOT NULL + AND CHAR_LENGTH(TRIM(rebate_remark_json)) > 2 + AND rebate_remark_json NOT LIKE '%"uploadRecordId"%'; + +/* +START TRANSACTION; + +UPDATE jd_order +SET rebate_remark_json = '[]', + rebate_remark_has_abnormal = 0 +WHERE rebate_remark_json IS NOT NULL + AND CHAR_LENGTH(TRIM(rebate_remark_json)) > 2 + AND rebate_remark_json NOT LIKE '%"uploadRecordId"%'; + +COMMIT; +-- 若需回滚:ROLLBACK; +*/ + + +-- --------------------------------------------------------------------------- +-- 方案 B(可选,MySQL 8.0+):从 JSON 数组里只保留带 uploadRecordId 的元素 +-- 适用:同一订单里混有新旧备注,只想删掉无批次 ID 的旧条 +-- 要求:rebate_remark_json 为合法 JSON;无效行会报错,请先修正或跳过 +-- --------------------------------------------------------------------------- + +/* +START TRANSACTION; + +UPDATE jd_order o +INNER JOIN ( + SELECT o2.id AS oid, + COALESCE( + ( + SELECT JSON_ARRAYAGG(j.elem) + FROM JSON_TABLE(o2.rebate_remark_json, '$[*]' + COLUMNS (elem JSON PATH '$') + ) AS j + WHERE JSON_EXTRACT(j.elem, '$.uploadRecordId') IS NOT NULL + ), + JSON_ARRAY() + ) AS new_j + FROM jd_order o2 + WHERE o2.rebate_remark_json IS NOT NULL + AND CHAR_LENGTH(TRIM(o2.rebate_remark_json)) > 2 + AND JSON_VALID(o2.rebate_remark_json) +) t ON o.id = t.oid +SET o.rebate_remark_json = CAST(t.new_j AS CHAR), + o.rebate_remark_has_abnormal = CASE + WHEN JSON_LENGTH(t.new_j) = 0 THEN 0 + WHEN CAST(t.new_j AS CHAR) LIKE '%"abnormal":true%' THEN 1 + ELSE 0 + END +WHERE CAST(t.new_j AS CHAR) <> o.rebate_remark_json; + +COMMIT; +*/