package com.tcm.training.admin.system.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.tcm.training.admin.common.PageResponse; import com.tcm.training.admin.system.dto.CommonQuestionSaveRequest; import com.tcm.training.admin.system.entity.CommonQuestion; import com.tcm.training.admin.system.mapper.CommonQuestionMapper; import com.tcm.training.admin.system.vo.CommonQuestionDetailVO; import com.tcm.training.admin.system.vo.CommonQuestionListItemVO; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; @Service public class CommonQuestionAppService { private final CommonQuestionMapper commonQuestionMapper; public CommonQuestionAppService(CommonQuestionMapper commonQuestionMapper) { this.commonQuestionMapper = commonQuestionMapper; } public PageResponse page(int page, int pageSize, String title) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() .eq(CommonQuestion::getDeleted, 0) .like(title != null && !title.trim().isEmpty(), CommonQuestion::getTitle, title == null ? null : title.trim()) .orderByDesc(CommonQuestion::getCreatedAt) .orderByDesc(CommonQuestion::getId); IPage result = commonQuestionMapper.selectPage(new Page(page, pageSize), queryWrapper); List list = new ArrayList(); for (CommonQuestion item : result.getRecords()) { list.add(toListItem(item)); } return PageResponse.of(list, result.getTotal(), result.getCurrent(), result.getSize()); } public CommonQuestionDetailVO detail(Long id) { return toDetailVO(requireItem(id)); } @Transactional public CommonQuestionDetailVO create(CommonQuestionSaveRequest request) { CommonQuestion item = new CommonQuestion(); fillEntity(item, request); item.setDeleted(0); commonQuestionMapper.insert(item); return detail(item.getId()); } @Transactional public CommonQuestionDetailVO update(Long id, CommonQuestionSaveRequest request) { CommonQuestion item = requireItem(id); fillEntity(item, request); commonQuestionMapper.updateById(item); return detail(id); } @Transactional public void delete(Long id) { requireItem(id); commonQuestionMapper.deleteById(id); } private void fillEntity(CommonQuestion item, CommonQuestionSaveRequest request) { item.setTitle(normalizeTitle(request.getTitle())); item.setContentHtml(normalizeContent(request.getContentHtml())); } private CommonQuestion requireItem(Long id) { CommonQuestion item = commonQuestionMapper.selectOne(new LambdaQueryWrapper() .eq(CommonQuestion::getId, id) .eq(CommonQuestion::getDeleted, 0) .last("limit 1")); if (item == null) { throw new IllegalArgumentException("常见问题不存在"); } return item; } private CommonQuestionListItemVO toListItem(CommonQuestion item) { CommonQuestionListItemVO vo = new CommonQuestionListItemVO(); vo.setId(item.getId()); vo.setTitle(item.getTitle()); vo.setCreatedAt(item.getCreatedAt()); return vo; } private CommonQuestionDetailVO toDetailVO(CommonQuestion item) { CommonQuestionDetailVO vo = new CommonQuestionDetailVO(); vo.setId(item.getId()); vo.setTitle(item.getTitle()); vo.setContentHtml(item.getContentHtml()); vo.setCreatedAt(item.getCreatedAt()); vo.setUpdatedAt(item.getUpdatedAt()); return vo; } private String normalizeTitle(String title) { String trimmed = trimToNull(title); if (trimmed == null) { throw new IllegalArgumentException("请输入问题"); } if (trimmed.length() > 15) { throw new IllegalArgumentException("请输入15个字以内"); } return trimmed; } private String normalizeContent(String contentHtml) { String trimmed = trimToNull(contentHtml); if (trimmed == null || isBlankRichText(trimmed)) { throw new IllegalArgumentException("请输入内容"); } return trimmed; } private boolean isBlankRichText(String html) { String normalized = html .replaceAll("(?i)", "") .replaceAll("(?i)

", "") .replace(" ", "") .replace(" ", "") .replaceAll("<[^>]+>", "") .trim(); if (!normalized.isEmpty()) { return false; } String lowerCaseHtml = html.toLowerCase(); return !lowerCaseHtml.contains("