| | |
| | | ensureMerchantExists(request.merchantId()); |
| | | validateProductConfiguration(request.merchantId(), request.salePrice(), request.productImages()); |
| | | validateProductRights(request.merchantId(), request.rightsConfig()); |
| | | Long productId = resolveProductId(id); |
| | | BigDecimal subsidyAmount = valueOrZero(request.subsidyAmount()); |
| | | int updated = jdbcTemplate.update(""" |
| | | update merchant_product |
| | | set merchant_id = ?, product_type = ?, product_name = ?, subtitle = ?, cover_url = ?, |
| | | original_price = ?, sale_price = ?, subsidy_amount = ?, is_government_subsidy = ?, |
| | | stock = ?, detail_text = ?, benefit_desc = ?, purchase_notice = ?, valid_start_time = ?, |
| | | valid_end_time = ?, product_images = ?, rights_config = ?, status = 0, sort_no = ?, |
| | | audit_status = 1, audit_remark = null, audit_time = null, submit_time = now() |
| | | where deleted = 0 and id = ? |
| | | """, |
| | | int updated = jdbcTemplate.update(""" |
| | | update merchant_product |
| | | set merchant_id = ?, product_type = ?, product_name = ?, subtitle = ?, cover_url = ?, |
| | | original_price = ?, sale_price = ?, subsidy_amount = ?, is_government_subsidy = ?, |
| | | stock = ?, detail_text = ?, benefit_desc = ?, purchase_notice = ?, valid_start_time = ?, |
| | | valid_end_time = ?, product_images = ?, rights_config = ?, status = 0, sort_no = ?, |
| | | audit_status = 1, audit_remark = null, audit_time = null, submit_time = now() |
| | | where deleted = 0 and id = ? |
| | | """, |
| | | request.merchantId(), |
| | | request.productType(), |
| | | request.productName(), |
| | |
| | | toJson(request.productImages()), |
| | | toJson(request.rightsConfig()), |
| | | request.sortNo() == null ? 0 : request.sortNo(), |
| | | id); |
| | | productId); |
| | | ensureUpdated(updated); |
| | | appendProductAuditRecord(id); |
| | | return product(id); |
| | | appendProductAuditRecord(productId); |
| | | return product(productId); |
| | | } |
| | | |
| | | @Transactional |
| | | public Map<String, Object> updateProductStatus(Long id, Byte status) { |
| | | Number auditStatus = (Number) product(id).get("auditStatus"); |
| | | Long productId = resolveProductId(id); |
| | | Number auditStatus = (Number) product(productId).get("auditStatus"); |
| | | if (auditStatus == null || auditStatus.intValue() != 2) { |
| | | throw new BusinessException(ErrorCode.BAD_REQUEST, "Only approved products can be listed or unlisted"); |
| | | throw new BusinessException(ErrorCode.BAD_REQUEST, "只有审核通过的团单才能上架或下架"); |
| | | } |
| | | int updated = jdbcTemplate.update("update merchant_product set status = ? where deleted = 0 and id = ?", status, id); |
| | | int updated = jdbcTemplate.update("update merchant_product set status = ? where deleted = 0 and id = ?", status, productId); |
| | | ensureUpdated(updated); |
| | | return product(id); |
| | | return product(productId); |
| | | } |
| | | |
| | | @Transactional |
| | | public Map<String, Object> deleteProduct(Long id) { |
| | | Map<String, Object> existing = product(id); |
| | | int updated = jdbcTemplate.update("update merchant_product set deleted = 1 where deleted = 0 and id = ?", id); |
| | | Long productId = resolveProductId(id); |
| | | Map<String, Object> existing = product(productId); |
| | | int updated = jdbcTemplate.update("update merchant_product set deleted = 1 where deleted = 0 and id = ?", productId); |
| | | ensureUpdated(updated); |
| | | return existing; |
| | | } |
| | | |
| | | @Transactional |
| | | public Map<String, Object> auditProduct(Long id, ProductAuditRequest request) { |
| | | Long productId = resolveProductId(id); |
| | | List<Map<String, Object>> pendingRecords = DatabaseRows.normalize(jdbcTemplate.queryForList(""" |
| | | select id from merchant_product_audit_record |
| | | where product_id = ? and deleted = 0 and audit_status = 1 |
| | | order by id desc limit 1 |
| | | """, id)); |
| | | """, productId)); |
| | | if (!pendingRecords.isEmpty()) { |
| | | return auditProductAuditRecord(Long.valueOf(String.valueOf(pendingRecords.get(0).get("id"))), request); |
| | | } |
| | | if (request.auditStatus() != 2 && request.auditStatus() != 3) { |
| | | throw new BusinessException(ErrorCode.BAD_REQUEST, "Invalid audit status"); |
| | | } |
| | | Number currentAuditStatus = (Number) product(id).get("auditStatus"); |
| | | Number currentAuditStatus = (Number) product(productId).get("auditStatus"); |
| | | if (currentAuditStatus == null || currentAuditStatus.intValue() != 1) { |
| | | throw new BusinessException(ErrorCode.BAD_REQUEST, "Product is not pending audit"); |
| | | } |
| | |
| | | update merchant_product |
| | | set audit_status = ?, audit_remark = ?, audit_time = now(), status = ? |
| | | where deleted = 0 and id = ? |
| | | """, request.auditStatus(), request.auditRemark(), request.auditStatus() == 2 ? 1 : 0, id); |
| | | """, request.auditStatus(), request.auditRemark(), request.auditStatus() == 2 ? 1 : 0, productId); |
| | | ensureUpdated(updated); |
| | | return product(id); |
| | | return product(productId); |
| | | } |
| | | |
| | | @Transactional |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 团单在后台有两个 id 口径:商家编辑页的团单列表给的是商品 id,团单审核列表给的是审核记录 id。 |
| | | * 两个都认——否则拿另一口径的 id 去改团单,就只会在 update 影响 0 行之后抛出英文的 |
| | | * {@code Data not found},现场完全看不出是"id 口径不一致"。 |
| | | */ |
| | | private Long resolveProductId(Long id) { |
| | | if (id == null) { |
| | | throw new BusinessException(ErrorCode.BAD_REQUEST, "团单参数不能为空"); |
| | | } |
| | | List<Long> direct = jdbcTemplate.queryForList( |
| | | "select id from merchant_product where deleted = 0 and id = ?", |
| | | Long.class, |
| | | id); |
| | | if (!direct.isEmpty()) { |
| | | return direct.get(0); |
| | | } |
| | | List<Long> byAuditRecord = jdbcTemplate.queryForList(""" |
| | | select p.id |
| | | from merchant_product_audit_record r |
| | | join merchant_product p on p.id = r.product_id and p.deleted = 0 |
| | | where r.deleted = 0 and r.id = ? |
| | | limit 1 |
| | | """, Long.class, id); |
| | | if (!byAuditRecord.isEmpty()) { |
| | | return byAuditRecord.get(0); |
| | | } |
| | | throw new BusinessException(ErrorCode.NOT_FOUND, "团单不存在或已被删除,请刷新列表后重试"); |
| | | } |
| | | |
| | | private void ensureMerchantExists(Long merchantId) { |
| | | Long count = jdbcTemplate.queryForObject( |
| | | "select count(*) from merchant where deleted = 0 and id = ?", |