| | |
| | | package com.tcm.training.admin.member.service; |
| | | |
| | | import cn.idev.excel.FastExcel; |
| | | 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.agent.entity.AgentRegion; |
| | | import com.tcm.training.admin.agent.entity.ProvincialAgent; |
| | | import com.tcm.training.admin.agent.excel.ClinicAgentImportRow; |
| | | import com.tcm.training.admin.agent.mapper.ProvincialAgentMapper; |
| | | import com.tcm.training.admin.app.register.entity.SysRegion; |
| | | import com.tcm.training.admin.app.register.mapper.SysRegionMapper; |
| | | import com.tcm.training.admin.common.DateTimes; |
| | | import com.tcm.training.admin.common.PageResponse; |
| | | import com.tcm.training.admin.common.PhoneMasker; |
| | | import com.tcm.training.admin.live.entity.Clinic; |
| | | import com.tcm.training.admin.live.mapper.ClinicMapper; |
| | | import com.tcm.training.admin.member.dto.ClinicBankAccountUpdateRequest; |
| | | import com.tcm.training.admin.member.entity.AppUser; |
| | | import com.tcm.training.admin.member.excel.ClinicExcelRow; |
| | | import com.tcm.training.admin.member.mapper.ClinicQueryMapper; |
| | | import com.tcm.training.admin.member.mapper.UserMapper; |
| | | import com.tcm.training.admin.member.row.ClinicBoundUserRow; |
| | | import com.tcm.training.admin.member.row.ClinicDetailRow; |
| | | import com.tcm.training.admin.member.mapper.ClinicQueryMapper; |
| | | import com.tcm.training.admin.member.row.ClinicListRow; |
| | | import com.tcm.training.admin.member.row.ClinicRegionOptionRow; |
| | | import com.tcm.training.admin.member.vo.ClinicBoundUserItemVO; |
| | | import com.tcm.training.admin.member.vo.ClinicDetailVO; |
| | | import com.tcm.training.admin.member.vo.ClinicListItemVO; |
| | | import com.tcm.training.admin.member.vo.ClinicRegionOptionVO; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.jdbc.datasource.DataSourceTransactionManager; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.TransactionDefinition; |
| | | import org.springframework.transaction.TransactionStatus; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.transaction.support.DefaultTransactionDefinition; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.net.URLEncoder; |
| | | import java.time.LocalDateTime; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.*; |
| | | |
| | | @Service |
| | | @Slf4j |
| | | public class ClinicAppService { |
| | | |
| | | private final ClinicQueryMapper clinicQueryMapper; |
| | | private final ClinicMapper clinicMapper; |
| | | private final ProvincialAgentMapper provincialAgentMapper; |
| | | private final UserMapper userMapper; |
| | | private final SysRegionMapper sysRegionMapper; |
| | | private final DataSourceTransactionManager transactionManager; |
| | | |
| | | public ClinicAppService(ClinicQueryMapper clinicQueryMapper) { |
| | | public ClinicAppService(ClinicQueryMapper clinicQueryMapper, |
| | | ClinicMapper clinicMapper, |
| | | ProvincialAgentMapper provincialAgentMapper, |
| | | UserMapper userMapper, |
| | | SysRegionMapper sysRegionMapper, |
| | | DataSourceTransactionManager transactionManager) { |
| | | this.clinicQueryMapper = clinicQueryMapper; |
| | | this.clinicMapper = clinicMapper; |
| | | this.provincialAgentMapper = provincialAgentMapper; |
| | | this.userMapper = userMapper; |
| | | this.sysRegionMapper = sysRegionMapper; |
| | | this.transactionManager = transactionManager; |
| | | } |
| | | |
| | | public PageResponse<ClinicListItemVO> page(int page, |
| | |
| | | String regionCode, |
| | | String name, |
| | | String phone, |
| | | String agentName, |
| | | LocalDateTime createdFrom, |
| | | LocalDateTime createdTo, |
| | | Integer status) { |
| | |
| | | trimToNull(regionCode), |
| | | trimToNull(name), |
| | | trimToNull(phone), |
| | | trimToNull(agentName), |
| | | createdFrom, |
| | | createdTo, |
| | | status |
| | |
| | | return PageResponse.of(list, result.getTotal(), result.getCurrent(), result.getSize()); |
| | | } |
| | | |
| | | public void downloadClinicImportTemplate(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"); |
| | | FastExcel.write(response.getOutputStream(), ClinicAgentImportRow.class) |
| | | .sheet("诊所省区代理导入模板") |
| | | .doWrite(Collections.emptyList()); |
| | | } |
| | | |
| | | @Transactional |
| | | public void importAgentBindings(MultipartFile file) throws IOException { |
| | | if (file == null || file.isEmpty()) { |
| | | throw new IllegalArgumentException("请选择导入文件"); |
| | | } |
| | | List<ClinicAgentImportRow> rows = FastExcel.read(file.getInputStream()) |
| | | .head(ClinicAgentImportRow.class).sheet().doReadSync(); |
| | | if (rows == null || rows.isEmpty()) { |
| | | throw new IllegalArgumentException("导入文件不能为空"); |
| | | } |
| | | |
| | | Set<String> clinicNames = new LinkedHashSet<String>(); |
| | | Set<String> agentNames = new LinkedHashSet<String>(); |
| | | Map<String, String> bindingByClinicName = new HashMap<String, String>(); |
| | | int rowNumber = 1; |
| | | for (ClinicAgentImportRow row : rows) { |
| | | rowNumber++; |
| | | if (row == null || (trimToNull(row.getClinicName()) == null && trimToNull(row.getAgentName()) == null)) |
| | | continue; |
| | | String clinicName = trimToNull(row.getClinicName()); |
| | | String agentName = trimToNull(row.getAgentName()); |
| | | if (clinicName == null) { |
| | | throw new IllegalArgumentException("第" + rowNumber + "行诊所不能为空"); |
| | | } |
| | | if (agentName == null) { |
| | | throw new IllegalArgumentException("第" + rowNumber + "行省区代理名称不能为空"); |
| | | } |
| | | String previous = bindingByClinicName.put(clinicName, agentName); |
| | | if (previous != null && !previous.equals(agentName)) { |
| | | throw new IllegalArgumentException("诊所“" + clinicName + "”存在多个代理绑定"); |
| | | } |
| | | |
| | | clinicNames.add(clinicName); |
| | | agentNames.add(agentName); |
| | | } |
| | | if (bindingByClinicName.isEmpty()) { |
| | | throw new IllegalArgumentException("导入文件没有可用数据"); |
| | | } |
| | | |
| | | List<Clinic> clinics = clinicMapper.selectList(new LambdaQueryWrapper<Clinic>().in(Clinic::getName, clinicNames)); |
| | | List<ProvincialAgent> agents = provincialAgentMapper.selectList(new LambdaQueryWrapper<ProvincialAgent>() |
| | | .eq(ProvincialAgent::getDeleted, 0).in(ProvincialAgent::getAgentName, agentNames)); |
| | | Map<String, ProvincialAgent> agentByName = new LinkedHashMap<String, ProvincialAgent>(); |
| | | for (ProvincialAgent agent : agents) { |
| | | agentByName.put(agent.getAgentName(), agent); |
| | | } |
| | | for (String agentName : agentNames) { |
| | | if (!agentByName.containsKey(agentName)) { |
| | | throw new IllegalArgumentException("省区代理不存在:" + agentName); |
| | | } |
| | | } |
| | | |
| | | |
| | | Set<String> foundClinicNames = new LinkedHashSet<String>(); |
| | | for (Clinic clinic : clinics) { |
| | | foundClinicNames.add(clinic.getName()); |
| | | ProvincialAgent agent = agentByName.get(bindingByClinicName.get(clinic.getName())); |
| | | clinic.setAgentId(agent.getId()); |
| | | clinicMapper.updateById(clinic); |
| | | } |
| | | for (String clinicName : clinicNames) { |
| | | if (!foundClinicNames.contains(clinicName)) { |
| | | throw new IllegalArgumentException("诊所不存在:" + clinicName); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public void export(String regionCode, |
| | | String name, |
| | | String phone, |
| | | String agentName, |
| | | LocalDateTime createdFrom, |
| | | LocalDateTime createdTo, |
| | | Integer status, |
| | |
| | | trimToNull(regionCode), |
| | | trimToNull(name), |
| | | trimToNull(phone), |
| | | trimToNull(agentName), |
| | | createdFrom, |
| | | createdTo, |
| | | status |
| | |
| | | } |
| | | ClinicDetailVO vo = new ClinicDetailVO(); |
| | | vo.setId(row.getId()); |
| | | vo.setAgentId(row.getAgentId()); |
| | | vo.setName(row.getName()); |
| | | vo.setStatus(row.getStatus()); |
| | | vo.setPhone(defaultText(row.getContactPhone())); |
| | | vo.setAddress(defaultText(row.getAddress())); |
| | | vo.setProvinceCode(row.getProvinceCode()); |
| | | vo.setCityCode(row.getCityCode()); |
| | | vo.setDistrictCode(row.getDistrictCode()); |
| | | vo.setBusinessLicenseUrl(trimToNull(row.getBusinessLicenseUrl())); |
| | | vo.setUserCount(row.getUserCount() == null ? 0 : row.getUserCount()); |
| | | vo.setBankName(defaultText(row.getBankName())); |
| | | vo.setAccountHolder(defaultText(row.getAccountHolder())); |
| | | vo.setAccountNumber(defaultText(row.getAccountNumber())); |
| | | vo.setBranchName(defaultText(row.getBranchName())); |
| | | vo.setAvatar(row.getAvatar()); |
| | | vo.setLoginAccount(row.getLoginAccount()); |
| | | return vo; |
| | | } |
| | | |
| | | public ClinicDetailVO updateBankAccount(Long id, ClinicBankAccountUpdateRequest request) { |
| | | // 手动开启事务 |
| | | DefaultTransactionDefinition def = new DefaultTransactionDefinition(); |
| | | def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); |
| | | TransactionStatus status = transactionManager.getTransaction(def); |
| | | |
| | | try { |
| | | Clinic clinic = clinicMapper.selectById(id); |
| | | if (clinic == null || (clinic.getDeleted() != null && clinic.getDeleted() == 1)) { |
| | | throw new IllegalArgumentException("诊所不存在"); |
| | | } |
| | | String loginAccount = trimToNull(request.getLoginAccount()); |
| | | AppUser user = userMapper.selectOne(new LambdaQueryWrapper<AppUser>().eq(AppUser::getPhone, loginAccount).eq(AppUser::getDeleted, 0).last("limit 1")); |
| | | if (user == null) { |
| | | throw new IllegalArgumentException("登录账号不存在"); |
| | | } |
| | | user.setAvatar(trimToNull(request.getAvatar())); |
| | | user.setPhone(loginAccount); |
| | | userMapper.updateById(user); |
| | | Set<String> codes = new LinkedHashSet<String>(); |
| | | addCode(codes, request.getProvinceCode()); |
| | | addCode(codes, request.getCityCode()); |
| | | addCode(codes, request.getDistrictCode()); |
| | | Map<String, SysRegion> regions = new HashMap<String, SysRegion>(); |
| | | List<SysRegion> regionList = sysRegionMapper.selectList(new LambdaQueryWrapper<SysRegion>().in(SysRegion::getCode, codes)); |
| | | if (!regionList.isEmpty()) { |
| | | for (SysRegion region : regionList) { |
| | | regions.put(region.getCode(), region); |
| | | } |
| | | } |
| | | |
| | | clinic.setName(trimToNull(request.getName())); |
| | | clinic.setContactPhone(loginAccount); |
| | | clinic.setProvinceCode(trimToNull(request.getProvinceCode())); |
| | | clinic.setProvinceName(regionName(request.getProvinceCode(), request.getProvinceName(), regions)); |
| | | clinic.setCityCode(trimToNull(request.getCityCode())); |
| | | clinic.setCityName(regionName(request.getCityCode(), request.getCityName(), regions)); |
| | | clinic.setDistrictCode(trimToNull(request.getDistrictCode())); |
| | | clinic.setDistrictName(regionName(request.getDistrictCode(), request.getDistrictName(), regions)); |
| | | clinic.setAddress(trimToNull(request.getAddress())); |
| | | clinic.setBusinessLicenseUrl(trimToNull(request.getBusinessLicenseUrl())); |
| | | clinic.setStatus(request.getStatus()); |
| | | clinic.setAgentId(request.getAgentId()); |
| | | clinic.setBankName(trimToNull(request.getBankName())); |
| | | clinic.setAccountHolder(trimToNull(request.getAccountHolder())); |
| | | clinic.setAccountNumber(trimToNull(request.getAccountNumber())); |
| | | clinic.setBranchName(trimToNull(request.getBranchName())); |
| | | clinicMapper.updateById(clinic); |
| | | |
| | | // 提交事务 |
| | | transactionManager.commit(status); |
| | | log.info("诊所本地数据更新成功,clinicId={}", id); |
| | | |
| | | } catch (Exception e) { |
| | | // 发生异常,回滚事务 |
| | | transactionManager.rollback(status); |
| | | log.error("诊所本地数据更新失败,clinicId={}", id, e); |
| | | throw e; |
| | | } |
| | | |
| | | return detail(id); |
| | | } |
| | | |
| | | private void addCode(Set<String> codes, String code) { |
| | | String value = trimToNull(code); |
| | | if (value != null) { |
| | | codes.add(value); |
| | | } |
| | | } |
| | | |
| | | private String regionName(String code, String fallback, Map<String, SysRegion> regions) { |
| | | String value = trimToNull(code); |
| | | SysRegion region = value == null ? null : regions.get(value); |
| | | return region == null ? trimToNull(fallback) : region.getName(); |
| | | } |
| | | |
| | | public PageResponse<ClinicBoundUserItemVO> clinicUsers(Long clinicId, |
| | |
| | | item.setPhone(row.getPhone() == null ? "-" : PhoneMasker.mask(row.getPhone())); |
| | | item.setRegionName(defaultText(row.getRegionName())); |
| | | item.setStatus(row.getStatus()); |
| | | item.setAgentName(defaultText(row.getAgentName())); |
| | | item.setUserCount(row.getUserCount() == null ? 0 : row.getUserCount()); |
| | | item.setCreatedAt(row.getCreatedAt()); |
| | | item.setBusinessLicenseUrl(trimToNull(row.getBusinessLicenseUrl())); |