From ba3233a5b685f0ae6856d8dc5a2bf904296cf8b7 Mon Sep 17 00:00:00 2001
From: “mitao” <“2763622819@qq.com”>
Date: 星期四, 26 三月 2026 15:08:46 +0800
Subject: [PATCH] feat:交易与流水-订单-会员购买订单、交易与流水-订单-养生课程购买订单、交易与流水-财务流水-支付流水、交易与流水-财务流水-退费流水、课程管理-健康科普
---
backend/src/main/java/com/tcm/training/admin/live/service/HealthCourseAppService.java | 381 ++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 337 insertions(+), 44 deletions(-)
diff --git a/backend/src/main/java/com/tcm/training/admin/live/service/HealthCourseAppService.java b/backend/src/main/java/com/tcm/training/admin/live/service/HealthCourseAppService.java
index 209a499..5a9d311 100644
--- a/backend/src/main/java/com/tcm/training/admin/live/service/HealthCourseAppService.java
+++ b/backend/src/main/java/com/tcm/training/admin/live/service/HealthCourseAppService.java
@@ -14,6 +14,7 @@
import com.tcm.training.admin.live.entity.HealthCourseVideo;
import com.tcm.training.admin.live.entity.LiveCourseCategory;
import com.tcm.training.admin.live.excel.HealthCourseExportRow;
+import com.tcm.training.admin.live.excel.HealthCourseVideoImportRow;
import com.tcm.training.admin.live.mapper.ExpertMapper;
import com.tcm.training.admin.live.mapper.HealthCourseMapper;
import com.tcm.training.admin.live.mapper.HealthCourseVideoMapper;
@@ -23,11 +24,13 @@
import com.tcm.training.admin.live.vo.HealthCourseDetailVO;
import com.tcm.training.admin.live.vo.HealthCourseListItemVO;
import com.tcm.training.admin.live.vo.HealthCourseListRow;
+import com.tcm.training.admin.live.vo.HealthCourseOptionVO;
import com.tcm.training.admin.live.vo.HealthCourseStatusVO;
import com.tcm.training.admin.live.vo.HealthCourseVideoDetailVO;
import com.tcm.training.admin.live.vo.HealthCourseVideoItemVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@@ -35,7 +38,13 @@
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
@Service
public class HealthCourseAppService {
@@ -138,7 +147,7 @@
Integer status) throws IOException {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
- String filename = URLEncoder.encode("养身课程", "UTF-8").replace("+", "%20");
+ String filename = URLEncoder.encode("养生课程", "UTF-8").replace("+", "%20");
response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + filename + ".xlsx");
List<HealthCourseListRow> rows = healthCourseMapper.selectCourseList(
@@ -165,15 +174,28 @@
exports.add(export);
}
FastExcel.write(response.getOutputStream(), HealthCourseExportRow.class)
- .sheet("养身课程")
+ .sheet("养生课程")
.doWrite(exports);
+ }
+
+ public List<HealthCourseOptionVO> options(String keyword) {
+ List<HealthCourse> courses = healthCourseMapper.selectList(new LambdaQueryWrapper<HealthCourse>()
+ .eq(HealthCourse::getDeleted, 0)
+ .like(keyword != null && !keyword.trim().isEmpty(), HealthCourse::getTitle, keyword == null ? null : keyword.trim())
+ .orderByAsc(HealthCourse::getSort)
+ .orderByDesc(HealthCourse::getId));
+ List<HealthCourseOptionVO> list = new ArrayList<HealthCourseOptionVO>();
+ for (HealthCourse course : courses) {
+ list.add(new HealthCourseOptionVO(course.getId(), course.getTitle()));
+ }
+ return list;
}
public PageResponse<HealthCourseVideoItemVO> pageVideos(Long courseId,
int page,
int pageSize,
String chapterName,
- Integer saleType) {
+ Integer priceType) {
requireCourse(courseId);
LambdaQueryWrapper<HealthCourseVideo> qw = new LambdaQueryWrapper<HealthCourseVideo>()
.eq(HealthCourseVideo::getCourseId, courseId)
@@ -183,13 +205,55 @@
if (chapterName != null && !chapterName.trim().isEmpty()) {
qw.like(HealthCourseVideo::getChapterName, chapterName.trim());
}
- if (saleType != null) {
- qw.eq(HealthCourseVideo::getSaleType, saleType);
+ if (priceType != null) {
+ if (priceType == 0) {
+ qw.eq(HealthCourseVideo::getSalePrice, BigDecimal.ZERO);
+ } else if (priceType == 1) {
+ qw.gt(HealthCourseVideo::getSalePrice, BigDecimal.ZERO);
+ }
}
IPage<HealthCourseVideo> result = healthCourseVideoMapper.selectPage(new Page<HealthCourseVideo>(page, pageSize), qw);
List<HealthCourseVideoItemVO> list = new ArrayList<HealthCourseVideoItemVO>();
for (HealthCourseVideo item : result.getRecords()) {
list.add(toVideoItem(item));
+ }
+ return PageResponse.of(list, result.getTotal(), result.getCurrent(), result.getSize());
+ }
+
+ public PageResponse<HealthCourseVideoItemVO> pageVideoResources(int page,
+ int pageSize,
+ String courseKeyword,
+ Long courseId,
+ Integer courseType,
+ String chapterName,
+ Integer priceType,
+ Integer status) {
+ List<Long> matchedCourseIds = resolveMatchedCourseIds(courseKeyword, courseId);
+ if (matchedCourseIds.isEmpty()) {
+ return PageResponse.of(Collections.<HealthCourseVideoItemVO>emptyList(), 0, page, pageSize);
+ }
+ LambdaQueryWrapper<HealthCourseVideo> qw = new LambdaQueryWrapper<HealthCourseVideo>()
+ .in(HealthCourseVideo::getCourseId, matchedCourseIds)
+ .eq(HealthCourseVideo::getDeleted, 0)
+ .eq(courseType != null, HealthCourseVideo::getCourseType, courseType)
+ .eq(status != null, HealthCourseVideo::getStatus, status)
+ .orderByAsc(HealthCourseVideo::getSort)
+ .orderByDesc(HealthCourseVideo::getId);
+ if (chapterName != null && !chapterName.trim().isEmpty()) {
+ qw.like(HealthCourseVideo::getChapterName, chapterName.trim());
+ }
+ if (priceType != null) {
+ if (priceType == 0) {
+ qw.eq(HealthCourseVideo::getSalePrice, BigDecimal.ZERO);
+ } else if (priceType == 1) {
+ qw.gt(HealthCourseVideo::getSalePrice, BigDecimal.ZERO);
+ }
+ }
+ IPage<HealthCourseVideo> result = healthCourseVideoMapper.selectPage(new Page<HealthCourseVideo>(page, pageSize), qw);
+ Map<Long, String> courseTitleMap = resolveCourseTitleMap(extractCourseIds(result.getRecords()));
+ List<HealthCourseVideoItemVO> list = new ArrayList<HealthCourseVideoItemVO>();
+ for (HealthCourseVideo item : result.getRecords()) {
+ list.add(toVideoItem(item, courseTitleMap.get(item.getCourseId())));
}
return PageResponse.of(list, result.getTotal(), result.getCurrent(), result.getSize());
}
@@ -200,26 +264,14 @@
@Transactional
public HealthCourseVideoDetailVO createVideo(Long courseId, HealthCourseVideoSaveRequest req) {
- requireCourse(courseId);
- validateVideoSale(req);
- HealthCourseVideo next = new HealthCourseVideo();
- next.setCourseId(courseId);
- fillVideo(next, req);
- next.setSort(resolveNextVideoSort(courseId));
- next.setDeleted(0);
- healthCourseVideoMapper.insert(next);
- refreshCourseStats(courseId);
- return detailVideo(courseId, next.getId());
+ req.setCourseId(courseId);
+ return createVideoResource(req);
}
@Transactional
public HealthCourseVideoDetailVO updateVideo(Long courseId, Long videoId, HealthCourseVideoSaveRequest req) {
- validateVideoSale(req);
- HealthCourseVideo video = requireVideo(courseId, videoId);
- fillVideo(video, req);
- healthCourseVideoMapper.updateById(video);
- refreshCourseStats(courseId);
- return detailVideo(courseId, videoId);
+ req.setCourseId(courseId);
+ return updateVideoResource(videoId, req);
}
@Transactional
@@ -227,6 +279,114 @@
requireVideo(courseId, videoId);
healthCourseVideoMapper.deleteById(videoId);
refreshCourseStats(courseId);
+ }
+
+ public HealthCourseVideoDetailVO detailVideoResource(Long id) {
+ HealthCourseVideo video = requireVideoById(id);
+ return toVideoDetail(video, requireCourse(video.getCourseId()).getTitle());
+ }
+
+ @Transactional
+ public HealthCourseVideoDetailVO createVideoResource(HealthCourseVideoSaveRequest req) {
+ Long courseId = requireVideoCourseId(req.getCourseId());
+ validateVideo(req);
+ HealthCourseVideo next = new HealthCourseVideo();
+ next.setCourseId(courseId);
+ fillVideo(next, req);
+ next.setSort(resolveNextVideoSort(courseId));
+ next.setDeleted(0);
+ healthCourseVideoMapper.insert(next);
+ refreshCourseStats(courseId);
+ return detailVideoResource(next.getId());
+ }
+
+ @Transactional
+ public HealthCourseVideoDetailVO updateVideoResource(Long id, HealthCourseVideoSaveRequest req) {
+ HealthCourseVideo video = requireVideoById(id);
+ Long targetCourseId = req.getCourseId() == null ? video.getCourseId() : requireVideoCourseId(req.getCourseId());
+ req.setCourseId(targetCourseId);
+ validateVideo(req);
+ Long oldCourseId = video.getCourseId();
+ video.setCourseId(targetCourseId);
+ fillVideo(video, req);
+ healthCourseVideoMapper.updateById(video);
+ refreshCourseStats(targetCourseId);
+ if (!oldCourseId.equals(targetCourseId)) {
+ refreshCourseStats(oldCourseId);
+ }
+ return detailVideoResource(id);
+ }
+
+ @Transactional
+ public void deleteVideoResource(Long id) {
+ HealthCourseVideo video = requireVideoById(id);
+ healthCourseVideoMapper.deleteById(id);
+ refreshCourseStats(video.getCourseId());
+ }
+
+ public void downloadVideoResourceTemplate(HttpServletResponse response) throws IOException {
+ response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+ response.setCharacterEncoding("utf-8");
+ String filename = URLEncoder.encode("视频与课程资源导入模板", "UTF-8").replace("+", "%20");
+ response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + filename + ".xlsx");
+ List<HealthCourseVideoImportRow> rows = new ArrayList<HealthCourseVideoImportRow>();
+ HealthCourseVideoImportRow sample = new HealthCourseVideoImportRow();
+ sample.setCourseId(1L);
+ sample.setCourseTitle("中医针灸资格证");
+ sample.setCourseTypeText(courseTypeText(HealthCourseVideo.COURSE_TYPE_HEALTH));
+ sample.setChapterName("方剂学");
+ sample.setSalePrice(BigDecimal.ZERO);
+ sample.setDurationSeconds(238);
+ sample.setVideoUrl("https://example.com/video.mp4");
+ sample.setStatusText(statusText(1));
+ rows.add(sample);
+ FastExcel.write(response.getOutputStream(), HealthCourseVideoImportRow.class)
+ .sheet("视频资源导入模板")
+ .doWrite(rows);
+ }
+
+ @Transactional
+ public void importVideoResources(MultipartFile file) throws IOException {
+ if (file == null || file.isEmpty()) {
+ throw new IllegalArgumentException("请选择导入文件");
+ }
+ List<HealthCourseVideoImportRow> rows = FastExcel.read(file.getInputStream())
+ .head(HealthCourseVideoImportRow.class)
+ .sheet()
+ .doReadSync();
+ if (rows == null || rows.isEmpty()) {
+ throw new IllegalArgumentException("导入文件不能为空");
+ }
+ Set<Long> touchedCourseIds = new LinkedHashSet<Long>();
+ int rowNum = 1;
+ for (HealthCourseVideoImportRow row : rows) {
+ rowNum++;
+ if (row == null || isImportRowEmpty(row)) {
+ continue;
+ }
+ validateImportRow(row, rowNum);
+ HealthCourse course = requireCourse(row.getCourseId());
+ HealthCourseVideo video = new HealthCourseVideo();
+ video.setCourseId(course.getId());
+ video.setCourseType(HealthCourseVideo.COURSE_TYPE_HEALTH);
+ video.setChapterName(row.getChapterName().trim());
+ video.setVideoSourceType(HealthCourseVideo.VIDEO_SOURCE_URL);
+ video.setVideoUrl(row.getVideoUrl().trim());
+ video.setVideoFileName(null);
+ video.setDurationSeconds(row.getDurationSeconds());
+ video.setSalePrice(row.getSalePrice() == null ? BigDecimal.ZERO : row.getSalePrice());
+ video.setSort(resolveNextVideoSort(course.getId()));
+ video.setStatus(parseStatusText(row.getStatusText()));
+ video.setDeleted(0);
+ healthCourseVideoMapper.insert(video);
+ touchedCourseIds.add(course.getId());
+ }
+ if (touchedCourseIds.isEmpty()) {
+ throw new IllegalArgumentException("导入文件没有可用数据");
+ }
+ for (Long courseId : touchedCourseIds) {
+ refreshCourseStats(courseId);
+ }
}
private void fillCourse(HealthCourse course, HealthCourseSaveRequest req) {
@@ -246,18 +406,18 @@
}
private void fillVideo(HealthCourseVideo video, HealthCourseVideoSaveRequest req) {
+ video.setCourseType(resolveCourseType(req.getCourseType()));
video.setChapterName(req.getChapterName().trim());
- video.setChapterRemark(trimToNull(req.getChapterRemark()));
+ video.setVideoSourceType(req.getVideoSourceType());
video.setVideoUrl(req.getVideoUrl().trim());
+ video.setVideoFileName(trimToNull(req.getVideoFileName()));
video.setDurationSeconds(req.getDurationSeconds());
- video.setSaleType(req.getSaleType());
- video.setSalePrice(req.getSaleType() != null && req.getSaleType() == 0 ? BigDecimal.ZERO : req.getSalePrice());
- video.setPlayCount(req.getPlayCount());
- video.setStatus(req.getStatus());
+ video.setSalePrice(req.getSalePrice());
+ video.setStatus(resolveVideoStatus(req.getStatus()));
}
private void validateCategories(Long levelCategoryId, Long difficultyCategoryId) {
- LiveCourseCategory level = requireCategory(levelCategoryId, LiveCourseCategoryAppService.TYPE_LEVEL, "养身等级");
+ LiveCourseCategory level = requireCategory(levelCategoryId, LiveCourseCategoryAppService.TYPE_LEVEL, "养生等级");
LiveCourseCategory difficulty = requireCategory(difficultyCategoryId, LiveCourseCategoryAppService.TYPE_DIFFICULTY, "难度");
if (level == null || difficulty == null) {
throw new IllegalArgumentException("分类不存在");
@@ -289,13 +449,29 @@
}
}
- private void validateVideoSale(HealthCourseVideoSaveRequest req) {
- if (req.getSaleType() == null || (req.getSaleType() != 0 && req.getSaleType() != 1)) {
- throw new IllegalArgumentException("售价类型不合法");
+ private void validateVideo(HealthCourseVideoSaveRequest req) {
+ Integer courseType = resolveCourseType(req.getCourseType());
+ if (courseType != HealthCourseVideo.COURSE_TYPE_HEALTH) {
+ throw new IllegalArgumentException("课程类型不合法");
}
- if (req.getSaleType() == 0 && req.getSalePrice() != null && req.getSalePrice().compareTo(BigDecimal.ZERO) != 0) {
- throw new IllegalArgumentException("免费课程售价必须为0");
+ if (req.getCourseId() == null) {
+ throw new IllegalArgumentException("请选择关联课程");
}
+ if (req.getVideoSourceType() == null
+ || (req.getVideoSourceType() != HealthCourseVideo.VIDEO_SOURCE_URL
+ && req.getVideoSourceType() != HealthCourseVideo.VIDEO_SOURCE_UPLOAD)) {
+ throw new IllegalArgumentException("视频来源不合法");
+ }
+ if (req.getVideoUrl() == null || req.getVideoUrl().trim().isEmpty()) {
+ throw new IllegalArgumentException("请输入视频地址");
+ }
+ if (req.getSalePrice() != null && req.getSalePrice().compareTo(BigDecimal.ZERO) < 0) {
+ throw new IllegalArgumentException("售价不能小于0");
+ }
+ }
+
+ private Integer resolveVideoStatus(Integer status) {
+ return status == null ? 1 : status;
}
private int resolveNextVideoSort(Long courseId) {
@@ -334,10 +510,7 @@
private HealthCourseVideo requireVideo(Long courseId, Long videoId) {
requireCourse(courseId);
- HealthCourseVideo video = healthCourseVideoMapper.selectById(videoId);
- if (video == null) {
- throw new IllegalArgumentException("视频课程不存在");
- }
+ HealthCourseVideo video = requireVideoById(videoId);
if (!courseId.equals(video.getCourseId())) {
throw new IllegalArgumentException("视频课程不属于当前课程");
}
@@ -394,33 +567,49 @@
}
private HealthCourseVideoItemVO toVideoItem(HealthCourseVideo item) {
+ return toVideoItem(item, null);
+ }
+
+ private HealthCourseVideoItemVO toVideoItem(HealthCourseVideo item, String courseTitle) {
HealthCourseVideoItemVO vo = new HealthCourseVideoItemVO();
vo.setId(item.getId());
+ vo.setCourseType(resolveCourseType(item.getCourseType()));
+ vo.setCourseTypeText(courseTypeText(item.getCourseType()));
vo.setCourseId(item.getCourseId());
+ vo.setCourseTitle(defaultText(courseTitle));
vo.setChapterName(item.getChapterName());
- vo.setChapterRemark(item.getChapterRemark());
+ vo.setVideoSourceType(item.getVideoSourceType());
vo.setVideoUrl(item.getVideoUrl());
+ vo.setVideoFileName(item.getVideoFileName());
vo.setDurationSeconds(item.getDurationSeconds());
- vo.setSaleType(item.getSaleType());
- vo.setSalePrice(item.getSalePrice());
- vo.setPlayCount(item.getPlayCount());
+ vo.setDurationText(formatDuration(defaultNumber(item.getDurationSeconds())));
+ vo.setSalePrice(item.getSalePrice() == null ? BigDecimal.ZERO : item.getSalePrice());
+ vo.setWatchCount(0);
vo.setSort(item.getSort());
vo.setStatus(item.getStatus());
+ vo.setStatusText(statusText(item.getStatus()));
vo.setCreatedAt(item.getCreatedAt());
return vo;
}
private HealthCourseVideoDetailVO toVideoDetail(HealthCourseVideo item) {
+ return toVideoDetail(item, null);
+ }
+
+ private HealthCourseVideoDetailVO toVideoDetail(HealthCourseVideo item, String courseTitle) {
HealthCourseVideoDetailVO vo = new HealthCourseVideoDetailVO();
vo.setId(item.getId());
+ vo.setCourseType(resolveCourseType(item.getCourseType()));
+ vo.setCourseTypeText(courseTypeText(item.getCourseType()));
vo.setCourseId(item.getCourseId());
+ vo.setCourseTitle(defaultText(courseTitle));
vo.setChapterName(item.getChapterName());
- vo.setChapterRemark(item.getChapterRemark());
+ vo.setVideoSourceType(item.getVideoSourceType());
vo.setVideoUrl(item.getVideoUrl());
+ vo.setVideoFileName(item.getVideoFileName());
vo.setDurationSeconds(item.getDurationSeconds());
- vo.setSaleType(item.getSaleType());
- vo.setSalePrice(item.getSalePrice());
- vo.setPlayCount(item.getPlayCount());
+ vo.setSalePrice(item.getSalePrice() == null ? BigDecimal.ZERO : item.getSalePrice());
+ vo.setWatchCount(0);
vo.setSort(item.getSort());
vo.setStatus(item.getStatus());
vo.setCreatedAt(item.getCreatedAt());
@@ -447,6 +636,10 @@
return status != null && status == 1 ? "启用" : "禁用";
}
+ private String courseTypeText(Integer courseType) {
+ return resolveCourseType(courseType) == HealthCourseVideo.COURSE_TYPE_HEALTH ? "养生课程" : "-";
+ }
+
private String defaultText(String text) {
return text == null || text.trim().isEmpty() ? "-" : text;
}
@@ -458,4 +651,104 @@
String trimmed = text.trim();
return trimmed.isEmpty() ? null : trimmed;
}
+
+ private Integer resolveCourseType(Integer courseType) {
+ return courseType == null ? HealthCourseVideo.COURSE_TYPE_HEALTH : courseType;
+ }
+
+ private Long requireVideoCourseId(Long courseId) {
+ return requireCourse(courseId).getId();
+ }
+
+ private HealthCourseVideo requireVideoById(Long id) {
+ HealthCourseVideo video = healthCourseVideoMapper.selectById(id);
+ if (video == null) {
+ throw new IllegalArgumentException("视频课程不存在");
+ }
+ return video;
+ }
+
+ private List<Long> resolveMatchedCourseIds(String courseKeyword, Long courseId) {
+ if (courseId != null) {
+ return Collections.singletonList(requireCourse(courseId).getId());
+ }
+ List<HealthCourse> courses = healthCourseMapper.selectList(new LambdaQueryWrapper<HealthCourse>()
+ .eq(HealthCourse::getDeleted, 0)
+ .like(courseKeyword != null && !courseKeyword.trim().isEmpty(), HealthCourse::getTitle, courseKeyword == null ? null : courseKeyword.trim()));
+ if (courses.isEmpty()) {
+ return Collections.emptyList();
+ }
+ List<Long> ids = new ArrayList<Long>();
+ for (HealthCourse course : courses) {
+ ids.add(course.getId());
+ }
+ return ids;
+ }
+
+ private Map<Long, String> resolveCourseTitleMap(Collection<Long> courseIds) {
+ if (courseIds == null || courseIds.isEmpty()) {
+ return Collections.emptyMap();
+ }
+ List<HealthCourse> courses = healthCourseMapper.selectList(new LambdaQueryWrapper<HealthCourse>()
+ .in(HealthCourse::getId, courseIds)
+ .eq(HealthCourse::getDeleted, 0));
+ Map<Long, String> map = new LinkedHashMap<Long, String>();
+ for (HealthCourse course : courses) {
+ map.put(course.getId(), course.getTitle());
+ }
+ return map;
+ }
+
+ private List<Long> extractCourseIds(List<HealthCourseVideo> videos) {
+ Set<Long> ids = new LinkedHashSet<Long>();
+ for (HealthCourseVideo video : videos) {
+ ids.add(video.getCourseId());
+ }
+ return new ArrayList<Long>(ids);
+ }
+
+ private boolean isImportRowEmpty(HealthCourseVideoImportRow row) {
+ return row.getCourseId() == null
+ && (row.getChapterName() == null || row.getChapterName().trim().isEmpty())
+ && row.getSalePrice() == null
+ && row.getDurationSeconds() == null
+ && (row.getVideoUrl() == null || row.getVideoUrl().trim().isEmpty())
+ && (row.getStatusText() == null || row.getStatusText().trim().isEmpty());
+ }
+
+ private void validateImportRow(HealthCourseVideoImportRow row, int rowNum) {
+ if (row.getCourseId() == null) {
+ throw new IllegalArgumentException("第" + rowNum + "行:关联课程ID不能为空");
+ }
+ if (row.getCourseTypeText() != null && !row.getCourseTypeText().trim().isEmpty() && !"养生课程".equals(row.getCourseTypeText().trim())) {
+ throw new IllegalArgumentException("第" + rowNum + "行:课程类型仅支持养生课程");
+ }
+ if (row.getChapterName() == null || row.getChapterName().trim().isEmpty()) {
+ throw new IllegalArgumentException("第" + rowNum + "行:小节名称不能为空");
+ }
+ if (row.getSalePrice() != null && row.getSalePrice().compareTo(BigDecimal.ZERO) < 0) {
+ throw new IllegalArgumentException("第" + rowNum + "行:小节价格不能小于0");
+ }
+ if (row.getDurationSeconds() == null || row.getDurationSeconds() < 0) {
+ throw new IllegalArgumentException("第" + rowNum + "行:时长必须大于等于0");
+ }
+ if (row.getVideoUrl() == null || row.getVideoUrl().trim().isEmpty()) {
+ throw new IllegalArgumentException("第" + rowNum + "行:视频地址不能为空");
+ }
+ try {
+ parseStatusText(row.getStatusText());
+ } catch (IllegalArgumentException ex) {
+ throw new IllegalArgumentException("第" + rowNum + "行:" + ex.getMessage());
+ }
+ }
+
+ private Integer parseStatusText(String statusText) {
+ if (statusText == null || statusText.trim().isEmpty() || "启用".equals(statusText.trim())) {
+ return 1;
+ }
+ if ("禁用".equals(statusText.trim())) {
+ return 0;
+ }
+ throw new IllegalArgumentException("状态仅支持启用或禁用");
+ }
}
--
Gitblit v1.7.1