hejianhao
2026-08-20 bfd6c3fd2bf6e6a2c1b2c0c9d9e85a7b88103dcb
feat0806: 新流程下创建门店绑定普通代理
1个文件已修改
167 ■■■■■ 已修改文件
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/service/ClinicAppService.java 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/service/ClinicAppService.java
@@ -4,6 +4,7 @@
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.fasterxml.jackson.databind.JsonNode;
import com.tcm.training.admin.agent.entity.AgentRegion;
import com.tcm.training.admin.agent.entity.ProvincialAgent;
import com.tcm.training.admin.agent.excel.ClinicAgentImportRow;
@@ -28,8 +29,14 @@
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 com.tcm.training.admin.utils.VzanHttpUtil;
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;
@@ -39,6 +46,7 @@
import java.util.*;
@Service
@Slf4j
public class ClinicAppService {
    private final ClinicQueryMapper clinicQueryMapper;
@@ -46,13 +54,23 @@
    private final ProvincialAgentMapper provincialAgentMapper;
    private final UserMapper userMapper;
    private final SysRegionMapper sysRegionMapper;
    private final VzanHttpUtil vzanHttpUtil;
    private final DataSourceTransactionManager transactionManager;
    public ClinicAppService(ClinicQueryMapper clinicQueryMapper, ClinicMapper clinicMapper, ProvincialAgentMapper provincialAgentMapper, UserMapper userMapper, SysRegionMapper sysRegionMapper) {
    public ClinicAppService(ClinicQueryMapper clinicQueryMapper,
                           ClinicMapper clinicMapper,
                           ProvincialAgentMapper provincialAgentMapper,
                           UserMapper userMapper,
                           SysRegionMapper sysRegionMapper,
                           VzanHttpUtil vzanHttpUtil,
                           DataSourceTransactionManager transactionManager) {
        this.clinicQueryMapper = clinicQueryMapper;
        this.clinicMapper = clinicMapper;
        this.provincialAgentMapper = provincialAgentMapper;
        this.userMapper = userMapper;
        this.sysRegionMapper = sysRegionMapper;
        this.vzanHttpUtil = vzanHttpUtil;
        this.transactionManager = transactionManager;
    }
    public PageResponse<ClinicListItemVO> page(int page,
@@ -229,52 +247,121 @@
        return vo;
    }
    @Transactional
    public ClinicDetailVO updateBankAccount(Long id, ClinicBankAccountUpdateRequest request) {
        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);
        // 手动开启事务
        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;
        }
        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);
        // 事务提交后,调用微赞接口(不回滚本地事务)
        try {
            Clinic clinic = clinicMapper.selectById(id);
            // 调用微赞创建门店
            Integer provinceCode = parseRegionCode(clinic.getProvinceCode(), "省编码");
            Integer cityCode = parseRegionCode(clinic.getCityCode(), "市编码");
            Integer areaCode = parseRegionCode(clinic.getDistrictCode(), "区县编码");
            log.info("调用微赞创建门店,入参 title={}, provinceCode={}, cityCode={}, areaCode={}, address={}, telephone={}",
                    clinic.getName(), provinceCode, cityCode, areaCode, clinic.getAddress(), clinic.getContactPhone());
            JsonNode vzanStoreResponse = vzanHttpUtil.createStore(clinic.getName(), provinceCode, cityCode, areaCode, clinic.getAddress(), clinic.getContactPhone());
            log.info("微赞创建门店成功,出参={}", vzanStoreResponse);
            // 查询代理信息获取parentMobile
            ProvincialAgent agent = provincialAgentMapper.selectById(request.getAgentId());
            if (agent == null) {
                throw new IllegalArgumentException("代理不存在,agentId=" + request.getAgentId());
            }
            String parentMobile = agent.getContactInfo();
            if (parentMobile == null || parentMobile.trim().isEmpty()) {
                throw new IllegalArgumentException("代理联系方式为空,agentId=" + request.getAgentId());
            }
            // 调用微赞创建代理
            log.info("调用微赞创建代理,入参 agentMobile={}, agentName={}, levelCode=1, storeName={}, parentMobile={}",
                    clinic.getContactPhone(), clinic.getName(), clinic.getName(), parentMobile);
            JsonNode vzanAgentResponse = vzanHttpUtil.createAgent(
                    clinic.getContactPhone(),  // agentMobile传门店的手机号
                    clinic.getName(),          // agentName传门店的名称
                    1,                        // levelCode传1
                    parentMobile,              // parentMobile传代理的contact_info
                    clinic.getName()          // storeName传门店的name
            );
            log.info("微赞创建代理成功,出参={}", vzanAgentResponse);
        } catch (Exception e) {
            // 捕获微赞接口异常,不回滚本地事务
            log.error("调用微赞接口失败,但本地数据已保存成功,clinicId={}", id, e);
            throw new IllegalStateException("调用微赞失败", e);
        }
        return detail(id);
    }
    private Integer parseRegionCode(String code, String fieldName) {
        if (code == null || code.trim().isEmpty()) {
            throw new IllegalArgumentException(fieldName + "不能为空");
        }
        try {
            return Integer.parseInt(code);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException(fieldName + "格式错误: " + code);
        }
    }
    private void addCode(Set<String> codes, String code) {
        String value = trimToNull(code);
        if (value != null) {