package com.tourguide.modules.user.service;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.tourguide.common.api.PageResponse;
|
import com.tourguide.common.exception.BusinessException;
|
import com.tourguide.modules.user.dto.GuideTeamResponse;
|
import com.tourguide.modules.user.dto.GuideTeamScenicRequest;
|
import com.tourguide.modules.user.dto.GuideTeamSaveRequest;
|
import com.tourguide.modules.user.entity.GuideTeam;
|
import com.tourguide.modules.user.entity.GuideTeamScenicConfig;
|
import com.tourguide.modules.user.mapper.GuideTeamMapper;
|
import com.tourguide.modules.user.mapper.GuideTeamScenicConfigMapper;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.util.StringUtils;
|
import java.time.LocalDate;
|
import java.util.Collections;
|
import java.util.HashSet;
|
import java.util.List;
|
import java.util.Set;
|
import java.util.stream.Collectors;
|
|
@Service
|
public class GuideTeamService {
|
private final GuideTeamMapper teamMapper;
|
private final GuideTeamScenicConfigMapper scenicConfigMapper;
|
|
public GuideTeamService(GuideTeamMapper teamMapper, GuideTeamScenicConfigMapper scenicConfigMapper) {
|
this.teamMapper = teamMapper;
|
this.scenicConfigMapper = scenicConfigMapper;
|
}
|
|
public GuideTeamResponse detail(Long id) {
|
GuideTeam team = requireTeam(id);
|
List<GuideTeamScenicConfig> scenicConfigs = scenicConfigMapper.selectList(
|
new LambdaQueryWrapper<GuideTeamScenicConfig>()
|
.eq(GuideTeamScenicConfig::getTeamId, id)
|
.orderByAsc(GuideTeamScenicConfig::getId));
|
return GuideTeamResponse.from(team, scenicConfigs);
|
}
|
|
public PageResponse<GuideTeamResponse> page(long page, long size, String keyword, Integer status,
|
LocalDate startDate, LocalDate endDate) {
|
LambdaQueryWrapper<GuideTeam> query = new LambdaQueryWrapper<GuideTeam>();
|
if (StringUtils.hasText(keyword)) {
|
String searchKeyword = keyword.trim();
|
query.and(wrapper -> wrapper.like(GuideTeam::getTeamName, searchKeyword)
|
.or().like(GuideTeam::getContactPhone, searchKeyword));
|
}
|
query.eq(status != null, GuideTeam::getStatus, status)
|
.ge(startDate != null, GuideTeam::getCreatedAt, startDate == null ? null : startDate.atStartOfDay())
|
.lt(endDate != null, GuideTeam::getCreatedAt, endDate == null ? null : endDate.plusDays(1).atStartOfDay())
|
.orderByDesc(GuideTeam::getId);
|
Page<GuideTeam> result = teamMapper.selectPage(new Page<GuideTeam>(page, size), query);
|
return new PageResponse<GuideTeamResponse>(
|
result.getRecords().stream().map(GuideTeamResponse::from).collect(Collectors.toList()),
|
result.getTotal(), result.getCurrent(), result.getSize());
|
}
|
|
@Transactional
|
public GuideTeamResponse create(GuideTeamSaveRequest request) {
|
ensureNameAvailable(request.getTeamName(), null);
|
GuideTeam team = new GuideTeam();
|
apply(team, request);
|
team.setStatus(1);
|
teamMapper.insert(team);
|
replaceScenicConfigs(team.getId(), request.getScenicConfigs());
|
return detail(team.getId());
|
}
|
|
@Transactional
|
public GuideTeamResponse update(Long id, GuideTeamSaveRequest request) {
|
GuideTeam team = requireTeam(id);
|
ensureNameAvailable(request.getTeamName(), id);
|
apply(team, request);
|
teamMapper.updateById(team);
|
replaceScenicConfigs(id, request.getScenicConfigs());
|
return detail(id);
|
}
|
|
@Transactional
|
public void updateStatus(Long id, Integer status) {
|
GuideTeam team = requireTeam(id);
|
team.setStatus(status);
|
teamMapper.updateById(team);
|
}
|
|
private GuideTeam requireTeam(Long id) {
|
GuideTeam team = teamMapper.selectById(id);
|
if (team == null) {
|
throw new BusinessException(404, "讲解队不存在");
|
}
|
return team;
|
}
|
|
private void ensureNameAvailable(String teamName, Long excludedId) {
|
LambdaQueryWrapper<GuideTeam> query = new LambdaQueryWrapper<GuideTeam>()
|
.eq(GuideTeam::getTeamName, teamName.trim())
|
.ne(excludedId != null, GuideTeam::getId, excludedId);
|
if (teamMapper.selectCount(query) > 0) {
|
throw new BusinessException(409, "讲解队名称已存在");
|
}
|
}
|
|
private void apply(GuideTeam team, GuideTeamSaveRequest request) {
|
List<GuideTeamScenicRequest> scenicConfigs = request.getScenicConfigs() == null
|
? Collections.<GuideTeamScenicRequest>emptyList()
|
: request.getScenicConfigs();
|
team.setTeamName(request.getTeamName().trim());
|
team.setContactPhone(request.getContactPhone().trim());
|
team.setOperatingArea(scenicConfigs.stream()
|
.map(GuideTeamScenicRequest::getScenicName)
|
.filter(StringUtils::hasText)
|
.map(String::trim)
|
.distinct()
|
.collect(Collectors.joining(",")));
|
team.setCompanyName(trimToNull(request.getCompanyName()));
|
team.setUnifiedSocialCreditCode(trimToNull(request.getUnifiedSocialCreditCode()));
|
team.setCommissionRatio(request.getCommissionRatio());
|
team.setWechatOpenId(trimToNull(request.getWechatOpenId()));
|
team.setMerchantId(trimToNull(request.getMerchantId()));
|
}
|
|
private void replaceScenicConfigs(Long teamId, List<GuideTeamScenicRequest> requests) {
|
scenicConfigMapper.markDeletedByTeamId(teamId);
|
if (requests == null) {
|
return;
|
}
|
Set<String> scenicNames = new HashSet<String>();
|
for (GuideTeamScenicRequest request : requests) {
|
String scenicName = request.getScenicName().trim();
|
if (!scenicNames.add(scenicName)) {
|
throw new BusinessException(409, "同一讲解队不能重复配置相同景区");
|
}
|
GuideTeamScenicConfig config = new GuideTeamScenicConfig();
|
config.setTeamId(teamId);
|
config.setScenicName(scenicName);
|
config.setCityName(request.getCityName().trim());
|
config.setMeetingPoints(request.getMeetingPoints().trim());
|
scenicConfigMapper.upsert(config);
|
}
|
}
|
|
private String trimToNull(String value) {
|
return StringUtils.hasText(value) ? value.trim() : null;
|
}
|
}
|