From 6a972c54fe99a186b5885db1b1319643ce9679dd Mon Sep 17 00:00:00 2001
From: shinnosuke <tantao@1hoper.com>
Date: 星期三, 26 八月 2026 18:43:38 +0800
Subject: [PATCH] 又又更新

---
 talent-card-server/src/main/java/com/talentcard/server/business/admin/AdminBusinessService.java |  137 ++++++++++++++++++++++++++++++++++++---------
 1 files changed, 108 insertions(+), 29 deletions(-)

diff --git a/talent-card-server/src/main/java/com/talentcard/server/business/admin/AdminBusinessService.java b/talent-card-server/src/main/java/com/talentcard/server/business/admin/AdminBusinessService.java
index d199cb3..067351d 100644
--- a/talent-card-server/src/main/java/com/talentcard/server/business/admin/AdminBusinessService.java
+++ b/talent-card-server/src/main/java/com/talentcard/server/business/admin/AdminBusinessService.java
@@ -44,7 +44,7 @@
 		result.put("cardCount", count("select count(*) from talent_card where deleted = 0"));
 		result.put("merchantCount", count("select count(*) from merchant where deleted = 0"));
 		result.put("orderCount", count("select count(*) from benefit_order where deleted = 0"));
-		result.put("pendingProductCount", count("select count(*) from merchant_product where deleted = 0 and audit_status = 1"));
+		result.put("pendingProductCount", count("select count(*) from merchant_product_audit_record where deleted = 0 and audit_status = 1"));
 		result.put("todayVerifyCount", count("select count(*) from verify_record where date(verify_time) = current_date"));
 		return result;
 	}
@@ -273,7 +273,7 @@
 			countSql.append(" and date(m.created_at) <= ?");
 			args.add(createdEnd);
 		}
-		sql.append(" order by m.is_recommend desc, m.sort_no desc, m.id desc");
+		sql.append(" order by m.sort_no desc, m.created_at desc, m.id desc");
 		PageResult<Map<String, Object>> result = page(sql.toString(), countSql.toString(), page, size, args.toArray());
 		applyBusinessStatus(result.records());
 		return result;
@@ -283,7 +283,7 @@
 	public List<Map<String, Object>> pendingNotices() {
 		List<Map<String, Object>> notices = new ArrayList<>();
 		addPendingNotice(notices, "product-audit", "团单审核", "您有 %d 条团单待审核", "/products",
-				"select count(*) as pending_count, max(coalesce(submit_time, created_at)) as latest_time from merchant_product where deleted = 0 and audit_status = 1");
+				"select count(*) as pending_count, max(coalesce(submit_time, created_at)) as latest_time from merchant_product_audit_record where deleted = 0 and audit_status = 1");
 		addPendingNotice(notices, "family-card", "家属卡申请", "您有 %d 条家属卡申请待审核", "/family-card-applications",
 				"select count(*) as pending_count, max(apply_time) as latest_time from family_card_application where deleted = 0 and status = '待审核'");
 		addPendingNotice(notices, "upgrade", "升级申请", "您有 %d 条升级申请待审核", "/upgrade-applications",
@@ -719,26 +719,28 @@
 			int size
 	) {
 		StringBuilder sql = new StringBuilder("""
-				select p.id, p.merchant_id, m.merchant_name, m.merchant_type, m.contact_mobile,
-				       p.product_no, p.product_type, p.product_name,
-				       p.subtitle, p.cover_url, p.original_price, p.sale_price, p.subsidy_amount,
-				       p.is_government_subsidy, p.stock, p.sales_count, p.detail_text, p.benefit_desc,
-				       p.purchase_notice, p.valid_start_time, p.valid_end_time, p.product_images, p.rights_config,
-				       p.audit_status, p.audit_remark, p.status, p.sort_no, p.submit_time, p.created_at
-				from merchant_product p
-				left join merchant m on m.id = p.merchant_id
-				where p.deleted = 0
+				select r.id, r.product_id, r.merchant_id, m.merchant_name, m.merchant_type, m.merchant_type_code, m.contact_mobile,
+				       r.product_no, r.product_type, r.product_name,
+				       r.subtitle, r.cover_url, r.original_price, r.sale_price, r.subsidy_amount,
+				       r.is_government_subsidy, r.stock, r.sales_count, r.detail_text, r.benefit_desc,
+				       r.purchase_notice, r.valid_start_time, r.valid_end_time, r.product_images, r.rights_config,
+				       r.audit_status, r.audit_remark, r.audit_by, r.audit_time, r.submit_time,
+				       r.source_created_at as created_at, p.status
+				from merchant_product_audit_record r
+				left join merchant_product p on p.id = r.product_id
+				left join merchant m on m.id = r.merchant_id
+				where r.deleted = 0
 				""");
 		StringBuilder countSql = new StringBuilder("""
 				select count(*)
-				from merchant_product p
-				left join merchant m on m.id = p.merchant_id
-				where p.deleted = 0
+				from merchant_product_audit_record r
+				left join merchant m on m.id = r.merchant_id
+				where r.deleted = 0
 				""");
 		List<Object> args = new ArrayList<>();
 		if (merchantId != null) {
-			sql.append(" and p.merchant_id = ?");
-			countSql.append(" and p.merchant_id = ?");
+			sql.append(" and r.merchant_id = ?");
+			countSql.append(" and r.merchant_id = ?");
 			args.add(merchantId);
 		}
 		if (merchantName != null && !merchantName.isBlank()) {
@@ -752,8 +754,8 @@
 			args.add("%" + contactMobile.trim() + "%");
 		}
 		if (keyword != null && !keyword.isBlank()) {
-			sql.append(" and p.product_name like ?");
-			countSql.append(" and p.product_name like ?");
+			sql.append(" and r.product_name like ?");
+			countSql.append(" and r.product_name like ?");
 			String like = "%" + keyword.trim() + "%";
 			args.add(like);
 		}
@@ -763,28 +765,28 @@
 			args.add(MerchantTypeCatalog.canonicalCode(type));
 		}
 		if (status != null) {
-			sql.append(" and p.audit_status = ?");
-			countSql.append(" and p.audit_status = ?");
+			sql.append(" and r.audit_status = ?");
+			countSql.append(" and r.audit_status = ?");
 			args.add(status);
 		}
 		if (createdStart != null && !createdStart.isBlank()) {
-			sql.append(" and date(p.created_at) >= ?");
-			countSql.append(" and date(p.created_at) >= ?");
+			sql.append(" and date(coalesce(r.submit_time, r.created_at)) >= ?");
+			countSql.append(" and date(coalesce(r.submit_time, r.created_at)) >= ?");
 			args.add(createdStart);
 		}
 		if (createdEnd != null && !createdEnd.isBlank()) {
-			sql.append(" and date(p.created_at) <= ?");
-			countSql.append(" and date(p.created_at) <= ?");
+			sql.append(" and date(coalesce(r.submit_time, r.created_at)) <= ?");
+			countSql.append(" and date(coalesce(r.submit_time, r.created_at)) <= ?");
 			args.add(createdEnd);
 		}
-		sql.append(" order by p.submit_time desc, p.id desc");
+		sql.append(" order by coalesce(r.submit_time, r.created_at) desc, r.id desc");
 		return page(sql.toString(), countSql.toString(), page, size, args.toArray());
 	}
 
 	@Transactional(readOnly = true)
 	public Map<String, Object> product(Long id) {
 		return one("""
-				select p.id, p.merchant_id, m.merchant_name, m.merchant_type, m.contact_mobile,
+				select p.id, p.merchant_id, m.merchant_name, m.merchant_type, m.merchant_type_code, m.contact_mobile,
 				       p.product_no, p.product_type, p.product_name,
 				       p.subtitle, p.cover_url, p.original_price, p.sale_price, p.subsidy_amount,
 				       p.is_government_subsidy, p.stock, p.sales_count, p.detail_text, p.benefit_desc,
@@ -794,6 +796,23 @@
 				left join merchant m on m.id = p.merchant_id
 				where p.deleted = 0 and p.id = ?
 				""", id);
+	}
+
+	@Transactional(readOnly = true)
+	public Map<String, Object> productAuditRecord(Long auditRecordId) {
+		return one("""
+				select r.id, r.product_id, r.merchant_id, m.merchant_name, m.merchant_type, m.merchant_type_code, m.contact_mobile,
+				       r.product_no, r.product_type, r.product_name, r.subtitle, r.cover_url,
+				       r.original_price, r.sale_price, r.subsidy_amount, r.is_government_subsidy,
+				       r.stock, r.sales_count, r.detail_text, r.benefit_desc, r.purchase_notice,
+				       r.valid_start_time, r.valid_end_time, r.product_images, r.rights_config,
+				       r.audit_status, r.audit_remark, r.audit_by, r.audit_time, r.submit_time,
+				       r.source_created_at as created_at, p.status
+				from merchant_product_audit_record r
+				left join merchant_product p on p.id = r.product_id
+				left join merchant m on m.id = r.merchant_id
+				where r.deleted = 0 and r.id = ?
+				""", auditRecordId);
 	}
 
 	@Transactional
@@ -828,7 +847,9 @@
 				blankToNull(request.validEndTime()),
 				toJson(request.productImages()),
 				toJson(request.rightsConfig()));
-		return one("select * from merchant_product where product_no = ?", productNo);
+		Long productId = jdbcTemplate.queryForObject("select id from merchant_product where product_no = ?", Long.class, productNo);
+		appendProductAuditRecord(productId);
+		return product(productId);
 	}
 
 	@Transactional
@@ -866,6 +887,7 @@
 				request.sortNo() == null ? 0 : request.sortNo(),
 				id);
 		ensureUpdated(updated);
+		appendProductAuditRecord(id);
 		return product(id);
 	}
 
@@ -890,6 +912,14 @@
 
 	@Transactional
 	public Map<String, Object> auditProduct(Long id, ProductAuditRequest request) {
+		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));
+		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");
 		}
@@ -904,6 +934,55 @@
 				""", request.auditStatus(), request.auditRemark(), request.auditStatus() == 2 ? 1 : 0, id);
 		ensureUpdated(updated);
 		return product(id);
+	}
+
+	@Transactional
+	public Map<String, Object> auditProductAuditRecord(Long auditRecordId, ProductAuditRequest request) {
+		if (request.auditStatus() != 2 && request.auditStatus() != 3) {
+			throw new BusinessException(ErrorCode.BAD_REQUEST, "Invalid audit status");
+		}
+		Map<String, Object> record = productAuditRecord(auditRecordId);
+		Number currentAuditStatus = (Number) record.get("auditStatus");
+		if (currentAuditStatus == null || currentAuditStatus.intValue() != 1) {
+			throw new BusinessException(ErrorCode.BAD_REQUEST, "Product audit record is not pending");
+		}
+		int updated = jdbcTemplate.update("""
+				update merchant_product_audit_record
+				set audit_status = ?, audit_remark = ?, audit_time = now()
+				where deleted = 0 and id = ? and audit_status = 1
+				""", request.auditStatus(), request.auditRemark(), auditRecordId);
+		ensureUpdated(updated);
+		Long productId = Long.valueOf(String.valueOf(record.get("productId")));
+		jdbcTemplate.update("""
+				update merchant_product
+				set audit_status = ?, audit_remark = ?, audit_time = now(), status = ?
+				where deleted = 0 and id = ? and audit_status = 1
+				""", request.auditStatus(), request.auditRemark(), request.auditStatus() == 2 ? 1 : 0, productId);
+		return productAuditRecord(auditRecordId);
+	}
+
+	private void appendProductAuditRecord(Long productId) {
+		jdbcTemplate.update("""
+				update merchant_product_audit_record
+				set audit_status = 4, audit_remark = coalesce(audit_remark, 'superseded by a new submission')
+				where product_id = ? and deleted = 0 and audit_status = 1
+				""", productId);
+		jdbcTemplate.update("""
+				insert into merchant_product_audit_record(
+				    product_id, merchant_id, product_no, product_type, product_name, subtitle, cover_url,
+				    original_price, sale_price, subsidy_amount, is_government_subsidy, stock, sales_count,
+				    detail_text, benefit_desc, purchase_notice, valid_start_time, valid_end_time,
+				    product_images, rights_config, audit_status, audit_remark, audit_by, submit_time,
+				    audit_time, source_created_at
+				)
+				select id, merchant_id, product_no, product_type, product_name, subtitle, cover_url,
+				       original_price, sale_price, subsidy_amount, is_government_subsidy, stock, sales_count,
+				       detail_text, benefit_desc, purchase_notice, valid_start_time, valid_end_time,
+				       product_images, rights_config, audit_status, audit_remark, audit_by, submit_time,
+				       audit_time, created_at
+				from merchant_product
+				where id = ? and deleted = 0
+				""", productId);
 	}
 
 	@Transactional(readOnly = true)
@@ -962,7 +1041,7 @@
 			countSql.append(" and date(c.created_at) <= ?");
 			args.add(createdEnd);
 		}
-		sql.append(" order by c.id desc");
+		sql.append(" order by c.created_at desc, c.id desc");
 		return page(sql.toString(), countSql.toString(), page, size, args.toArray());
 	}
 

--
Gitblit v1.7.1