qxy пре 1 недеља
родитељ
комит
615e9e0202

+ 14 - 28
alien-store/src/main/java/shop/alien/store/controller/StoreLawFirmController.java

@@ -4,13 +4,11 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import io.swagger.annotations.*;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 import shop.alien.entity.result.R;
 import shop.alien.entity.store.LawFirm;
 import shop.alien.entity.store.vo.LawFirmPaymentVO;
-import shop.alien.store.feign.LawyerServiceFeign;
 import shop.alien.store.service.StoreLawFirmService;
 import shop.alien.util.myBaticsPlus.QueryBuilder;
 
@@ -34,8 +32,6 @@ import java.util.List;
 @RequiredArgsConstructor
 public class StoreLawFirmController {
 
-    private final LawyerServiceFeign lawyerServiceFeign;
-
     private final StoreLawFirmService storeLawFirmService;
 
     @ApiOperation(value = "新增律所", notes = "新增律所信息,支持同时添加收款账号列表。如果统一社会信用代码(creditCode)已存在,将自动执行更新操作。收款账号(payment_account)必须唯一,不能重复添加。")
@@ -46,7 +42,7 @@ public class StoreLawFirmController {
     @PostMapping("/addLawFirm")
     public R<LawFirm> addLawFirm(@RequestBody LawFirm lawFirm) {
         log.info("StoreLawFirmController.addLawFirm?lawFirm={}", lawFirm);
-        return lawyerServiceFeign.addLawFirm(lawFirm);
+        return storeLawFirmService.addLawFirm(lawFirm);
     }
 
     @ApiOperation(value = "编辑律所", notes = "编辑律所信息,支持同时新增、修改、删除收款账号。收款账号(payment_account)必须唯一,不能重复添加。")
@@ -57,7 +53,7 @@ public class StoreLawFirmController {
     @PostMapping("/editLawFirm")
     public R<LawFirm> editLawFirm(@RequestBody LawFirm lawFirm) {
         log.info("StoreLawFirmController.editLawFirm?lawFirm={}", lawFirm);
-        return lawyerServiceFeign.editLawFirm(lawFirm);
+        return storeLawFirmService.editLawFirm(lawFirm);
     }
 
     @ApiOperation(value = "删除律所", notes = "根据律所子表id删除收款账号。删除后如果该律所没有其他收款账号,将自动删除律所主表")
@@ -68,7 +64,7 @@ public class StoreLawFirmController {
     @DeleteMapping("/deleteLawFirm")
     public R<Boolean> deleteLawFirm(@RequestParam(value = "id") Integer id) {
         log.info("StoreLawFirmController.deleteLawFirm?paymentId={}", id);
-        return lawyerServiceFeign.deleteLawFirm(id);
+        return storeLawFirmService.deleteLawFirm(id);
     }
 
 //    @ApiOperation(value = "保存或更新律所", notes = "根据是否有id判断新增或更新。注意:此接口不支持收款账号的关联操作,建议使用addLawFirm或editLawFirm接口")
@@ -99,7 +95,13 @@ public class StoreLawFirmController {
     @GetMapping("/getList")
     public R<List<LawFirm>> getList(@ModelAttribute LawFirm lawFirm) {
         log.info("StoreLawFirmController.getList?lawFirm={}", lawFirm);
-        return null;
+        List<LawFirm> list = QueryBuilder.of(lawFirm)
+                .likeFields("firmName", "creditCode")  // 律所名称和统一社会信用代码支持模糊查询
+                .build()
+                .list(storeLawFirmService);
+        // 批量填充收款账号列表
+        storeLawFirmService.fillPaymentList(list);
+        return R.data(list);
     }
 
     @ApiOperation(value = "通用分页查询", notes = "分页查询律所列表,包含收款账号列表(paymentList)")
@@ -141,7 +143,7 @@ public class StoreLawFirmController {
     @GetMapping("/getDetail")
     public R<LawFirm> getLawFirmDetail(@RequestParam(value = "id") Integer id) {
         log.info("StoreLawFirmController.getLawFirmDetail?id={}", id);
-        return lawyerServiceFeign.getLawFirmDetail(id);
+        return storeLawFirmService.getLawFirmDetail(id);
     }
 
     @ApiOperation(value = "导出律所数据到Excel", notes = "导出律所数据到Excel文件,包含收款账号信息")
@@ -149,15 +151,7 @@ public class StoreLawFirmController {
     @GetMapping("/export")
     public void exportLawFirm(HttpServletResponse response) throws IOException {
         log.info("StoreLawFirmController.exportLawFirm");
-        ResponseEntity<byte[]> responseEntity = lawyerServiceFeign.exportLawFirm();
-        if (responseEntity != null && responseEntity.getBody() != null) {
-            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
-            response.setCharacterEncoding("utf-8");
-            String fileName = java.net.URLEncoder.encode("律所数据导出", "UTF-8").replaceAll("\\+", "%20");
-            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
-            response.getOutputStream().write(responseEntity.getBody());
-            response.getOutputStream().flush();
-        }
+        storeLawFirmService.exportLawFirm(response);
     }
 
     @ApiOperation(value = "从Excel导入律所数据", notes = "从Excel文件导入律所数据,支持批量导入。导入规则:1. 按统一社会信用代码(creditCode)分组,相同信用代码的数据会自动合并;2. 相同信用代码的多行数据会合并收款账号;3. 如果统一社会信用代码已存在,将更新现有记录并合并收款账号;4. 收款账号必须全局唯一,已存在的收款账号将跳过添加")
@@ -165,7 +159,7 @@ public class StoreLawFirmController {
     @PostMapping("/import")
     public R<String> importLawFirm(MultipartFile file) {
         log.info("StoreLawFirmController.importLawFirm fileName={}", file != null ? file.getOriginalFilename() : "null");
-        return lawyerServiceFeign.importLawFirm(file);
+        return storeLawFirmService.importLawFirm(file);
     }
 
     @ApiOperation(value = "下载律所Excel导入模板", notes = "下载律所数据导入的Excel模板文件")
@@ -173,15 +167,7 @@ public class StoreLawFirmController {
     @GetMapping("/downloadTemplate")
     public void downloadTemplate(HttpServletResponse response) throws IOException {
         log.info("StoreLawFirmController.downloadTemplate");
-        ResponseEntity<byte[]> responseEntity = lawyerServiceFeign.downloadTemplate();
-        if (responseEntity != null && responseEntity.getBody() != null) {
-            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
-            response.setCharacterEncoding("utf-8");
-            String fileName = java.net.URLEncoder.encode("律所导入模板", "UTF-8").replaceAll("\\+", "%20");
-            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
-            response.getOutputStream().write(responseEntity.getBody());
-            response.getOutputStream().flush();
-        }
+        storeLawFirmService.downloadTemplate(response);
     }
 
     @ApiOperation(value = "分页查询律所子表关联律所表", notes = "以律所子表(law_firm_payment)为主表,关联律所表(law_firm)进行分页查询")

+ 59 - 0
alien-store/src/main/java/shop/alien/store/service/StoreLawFirmService.java

@@ -2,10 +2,13 @@ package shop.alien.store.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
+import org.springframework.web.multipart.MultipartFile;
 import shop.alien.entity.result.R;
 import shop.alien.entity.store.LawFirm;
 import shop.alien.entity.store.vo.LawFirmPaymentVO;
 
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
 import java.util.List;
 
 /**
@@ -36,6 +39,62 @@ public interface StoreLawFirmService extends IService<LawFirm> {
     void fillPaymentList(List<LawFirm> lawFirmList);
 
     /**
+     * 新增律所
+     *
+     * @param lawFirm 律所
+     * @return R<LawFirm>
+     */
+    R<LawFirm> addLawFirm(LawFirm lawFirm);
+
+    /**
+     * 编辑律所
+     *
+     * @param lawFirm 律所
+     * @return R<LawFirm>
+     */
+    R<LawFirm> editLawFirm(LawFirm lawFirm);
+
+    /**
+     * 删除律所
+     *
+     * @param id 主键
+     * @return R<Boolean>
+     */
+    R<Boolean> deleteLawFirm(Integer id);
+
+    /**
+     * 导出律所数据到Excel
+     *
+     * @param response HTTP响应
+     * @throws IOException IO异常
+     */
+    void exportLawFirm(HttpServletResponse response) throws IOException;
+
+    /**
+     * 导入律所数据从Excel
+     *
+     * @param file Excel文件
+     * @return R<String> 返回导入结果信息
+     */
+    R<String> importLawFirm(MultipartFile file);
+
+    /**
+     * 获取律所详情
+     *
+     * @param id 律所ID
+     * @return R<LawFirm>
+     */
+    R<LawFirm> getLawFirmDetail(Integer id);
+
+    /**
+     * 下载律所Excel导入模板
+     *
+     * @param response HTTP响应
+     * @throws IOException IO异常
+     */
+    void downloadTemplate(HttpServletResponse response) throws IOException;
+
+    /**
      * 分页查询律所子表关联律所表
      *
      * @param pageNum 页码

+ 956 - 5
alien-store/src/main/java/shop/alien/store/service/impl/StoreLawFirmServiceImpl.java

@@ -6,22 +6,35 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
+import org.springframework.web.multipart.MultipartFile;
 import shop.alien.entity.result.R;
 import shop.alien.entity.store.LawFirm;
 import shop.alien.entity.store.LawFirmPayment;
+import shop.alien.entity.store.excelVo.LawFirmExcelVo;
+import shop.alien.entity.store.excelVo.util.ExcelHeader;
 import shop.alien.entity.store.vo.LawFirmPaymentVO;
 import shop.alien.mapper.LawFirmMapper;
 import shop.alien.mapper.LawFirmPaymentMapper;
 import shop.alien.store.service.StoreLawFirmPaymentService;
 import shop.alien.store.service.StoreLawFirmService;
+import shop.alien.util.excel.EasyExcelUtil;
 
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import org.apache.poi.ss.usermodel.DateUtil;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -96,8 +109,813 @@ public class StoreLawFirmServiceImpl extends ServiceImpl<LawFirmMapper, LawFirm>
     }
 
     @Override
+    public R<LawFirm> addLawFirm(LawFirm lawFirm) {
+        log.info("StoreLawFirmServiceImpl.addLawFirm?lawFirm={}, platformCommissionRatio={}", lawFirm, lawFirm.getPlatformCommissionRatio());
+        
+        // 第一步:先校验收款账号,如果 paymentAccount 在数据库中存在,不让新增
+        if (lawFirm.getPaymentList() != null && !lawFirm.getPaymentList().isEmpty()) {
+            for (LawFirmPayment payment : lawFirm.getPaymentList()) {
+                if (StringUtils.hasText(payment.getPaymentAccount())) {
+                    String paymentAccount = payment.getPaymentAccount().trim();
+                    
+                    // 检查收款账号是否在数据库中存在
+                    LambdaQueryWrapper<LawFirmPayment> queryWrapper = new LambdaQueryWrapper<>();
+                    queryWrapper.eq(LawFirmPayment::getPaymentAccount, paymentAccount);
+                    queryWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
+                    long count = storeLawFirmPaymentService.count(queryWrapper);
+                    if (count > 0) {
+                        return R.fail("收款账号[" + paymentAccount + "]在数据库中已存在,不能添加");
+                    }
+                }
+            }
+        }
+        
+        // 第二步:paymentAccount 校验通过后,检查统一社会信用代码是否已存在
+        LawFirm existingLawFirm = null;
+        if (StringUtils.hasText(lawFirm.getCreditCode())) {
+            LambdaQueryWrapper<LawFirm> creditCodeWrapper = new LambdaQueryWrapper<>();
+            creditCodeWrapper.eq(LawFirm::getCreditCode, lawFirm.getCreditCode());
+            creditCodeWrapper.eq(LawFirm::getDeleteFlag, 0);
+            existingLawFirm = this.getOne(creditCodeWrapper);
+        }
+        
+        // existingLawFirm 不为空执行更新子表,否则执行新增主子表操作
+        if (existingLawFirm != null) {
+            // 更新子表操作:只更新子表数据,不更新主表
+            Integer firmId = existingLawFirm.getId();
+            log.info("统一社会信用代码[{}]已存在,只更新子表数据,律所ID={}", lawFirm.getCreditCode(), firmId);
+            
+            // 保存子表数据
+            if (lawFirm.getPaymentList() != null && !lawFirm.getPaymentList().isEmpty()) {
+                for (LawFirmPayment payment : lawFirm.getPaymentList()) {
+                    if (!StringUtils.hasText(payment.getPaymentAccount())) {
+                        continue;
+                    }
+                    
+                    String paymentAccount = payment.getPaymentAccount().trim();
+                    
+                    // 再次检查账号是否已存在(防止并发问题)
+                    LambdaQueryWrapper<LawFirmPayment> checkWrapper = new LambdaQueryWrapper<>();
+                    checkWrapper.eq(LawFirmPayment::getPaymentAccount, paymentAccount);
+                    checkWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
+                    long checkCount = storeLawFirmPaymentService.count(checkWrapper);
+                    if (checkCount > 0) {
+                        return R.fail("收款账号[" + paymentAccount + "]在数据库中已存在,不能添加");
+                    }
+                    
+                    // 新增收款账号
+                    LawFirmPayment newPayment = new LawFirmPayment();
+                    newPayment.setFirmId(firmId);
+                    newPayment.setPaymentAccount(paymentAccount);
+                    if (StringUtils.hasText(payment.getAddress())) {
+                        newPayment.setAddress(payment.getAddress().trim());
+                    }
+                    newPayment.setDeleteFlag(0);
+                    
+                    boolean saveResult = storeLawFirmPaymentService.save(newPayment);
+                    if (!saveResult) {
+                        log.error("保存收款账号失败,firmId={}, paymentAccount={}", firmId, paymentAccount);
+                        return R.fail("保存收款账号失败:" + paymentAccount);
+                    }
+                    log.info("保存收款账号成功,firmId={}, paymentAccount={}, id={}", 
+                            firmId, paymentAccount, newPayment.getId());
+                }
+            }
+            
+            return R.data(existingLawFirm, "统一社会信用代码已存在,已更新收款账号列表");
+        } else {
+            // 新增主子表操作
+            // 保存主表
+            log.info("新增律所,platformCommissionRatio={}", lawFirm.getPlatformCommissionRatio());
+            boolean result = this.save(lawFirm);
+            if (!result) {
+                return R.fail("新增失败");
+            }
+            Integer firmId = lawFirm.getId();
+            
+            // 验证 platformCommissionRatio 是否保存成功
+            LawFirm savedLawFirm = this.getById(firmId);
+            if (savedLawFirm != null) {
+                log.info("保存后的律所,platformCommissionRatio={}", savedLawFirm.getPlatformCommissionRatio());
+            }
+            
+            // 保存子表数据
+            if (lawFirm.getPaymentList() != null && !lawFirm.getPaymentList().isEmpty()) {
+                for (LawFirmPayment payment : lawFirm.getPaymentList()) {
+                    if (!StringUtils.hasText(payment.getPaymentAccount())) {
+                        continue;
+                    }
+                    
+                    String paymentAccount = payment.getPaymentAccount().trim();
+                    
+                    // 再次检查账号是否已存在(防止并发问题)
+                    LambdaQueryWrapper<LawFirmPayment> checkWrapper = new LambdaQueryWrapper<>();
+                    checkWrapper.eq(LawFirmPayment::getPaymentAccount, paymentAccount);
+                    checkWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
+                    long checkCount = storeLawFirmPaymentService.count(checkWrapper);
+                    if (checkCount > 0) {
+                        return R.fail("收款账号[" + paymentAccount + "]在数据库中已存在,不能添加");
+                    }
+                    
+                    // 创建新的对象,避免污染原对象
+                    LawFirmPayment newPayment = new LawFirmPayment();
+                    newPayment.setFirmId(firmId);
+                    newPayment.setPaymentAccount(paymentAccount);
+                    if (StringUtils.hasText(payment.getAddress())) {
+                        newPayment.setAddress(payment.getAddress().trim());
+                    }
+                    newPayment.setDeleteFlag(0);
+
+                    boolean saveResult = storeLawFirmPaymentService.save(newPayment);
+                    if (!saveResult) {
+                        log.error("保存收款账号失败,firmId={}, paymentAccount={}", firmId, paymentAccount);
+                        return R.fail("保存收款账号失败:" + paymentAccount);
+                    }
+                    log.info("保存收款账号成功,firmId={}, paymentAccount={}, id={}", 
+                            firmId, paymentAccount, newPayment.getId());
+                }
+            }
+            
+            return R.data(lawFirm);
+        }
+    }
+
+    @Override
+    public R<LawFirm> editLawFirm(LawFirm lawFirm) {
+        log.info("StoreLawFirmServiceImpl.editLawFirm?lawFirm={}", lawFirm);
+        
+        // 校验律所ID
+        if (lawFirm.getId() == null) {
+            return R.fail("律所ID不能为空");
+        }
+        
+        // 检查律所是否存在
+        LawFirm existingLawFirm = this.getById(lawFirm.getId());
+        if (existingLawFirm == null || existingLawFirm.getDeleteFlag() == 1) {
+            return R.fail("律所不存在");
+        }
+        
+        // 第一步:先校验收款账号,如果 paymentAccount 在数据库中存在,不让新增或修改
+        if (lawFirm.getPaymentList() != null && !lawFirm.getPaymentList().isEmpty()) {
+            // 查询当前律所下现有的收款账号记录(用于判断是新增还是更新)
+            LambdaQueryWrapper<LawFirmPayment> existingWrapper = new LambdaQueryWrapper<>();
+            existingWrapper.eq(LawFirmPayment::getFirmId, lawFirm.getId());
+            existingWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
+            List<LawFirmPayment> existingPayments = storeLawFirmPaymentService.list(existingWrapper);
+            Map<Integer, String> existingPaymentMap = existingPayments.stream()
+                    .collect(Collectors.toMap(LawFirmPayment::getId, LawFirmPayment::getPaymentAccount));
+            
+            for (LawFirmPayment payment : lawFirm.getPaymentList()) {
+                if (StringUtils.hasText(payment.getPaymentAccount())) {
+                    String paymentAccount = payment.getPaymentAccount().trim();
+                    
+                    // 如果是更新操作,检查账号是否被修改
+                    if (payment.getId() != null) {
+                        String originalAccount = existingPaymentMap.get(payment.getId());
+                        // 如果账号被修改了,需要检查新账号是否已存在
+                        if (originalAccount != null && !originalAccount.equals(paymentAccount)) {
+                            // 检查新账号是否在数据库中存在(排除当前记录)
+                            LambdaQueryWrapper<LawFirmPayment> queryWrapper = new LambdaQueryWrapper<>();
+                            queryWrapper.eq(LawFirmPayment::getPaymentAccount, paymentAccount);
+                            queryWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
+                            queryWrapper.ne(LawFirmPayment::getId, payment.getId());
+                            long count = storeLawFirmPaymentService.count(queryWrapper);
+                            if (count > 0) {
+                                return R.fail("新收款账号数据库已存在");
+                            }
+                        }
+                    } else {
+                        // 新增操作:检查账号是否在数据库中存在
+                        LambdaQueryWrapper<LawFirmPayment> queryWrapper = new LambdaQueryWrapper<>();
+                        queryWrapper.eq(LawFirmPayment::getPaymentAccount, paymentAccount);
+                        queryWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
+                        long count = storeLawFirmPaymentService.count(queryWrapper);
+                        if (count > 0) {
+                            return R.fail("收款账号[" + paymentAccount + "]在数据库中已存在,不能添加");
+                        }
+                    }
+                }
+            }
+        }
+        
+        // 第二步:更新主表
+        boolean result = this.updateById(lawFirm);
+        if (!result) {
+        return R.fail("修改失败");
+        }
+        
+        // 第三步:处理子表数据
+        if (lawFirm.getPaymentList() != null) {
+            // 查询现有的收款账号记录
+            LambdaQueryWrapper<LawFirmPayment> existingWrapper = new LambdaQueryWrapper<>();
+            existingWrapper.eq(LawFirmPayment::getFirmId, lawFirm.getId());
+            existingWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
+            List<LawFirmPayment> existingPayments = storeLawFirmPaymentService.list(existingWrapper);
+            
+            // 收集前端传来的收款账号ID
+            Set<Integer> incomingIds = lawFirm.getPaymentList().stream()
+                    .filter(p -> p.getId() != null)
+                    .map(LawFirmPayment::getId)
+                    .collect(Collectors.toSet());
+            
+            // 删除不在前端列表中的记录(逻辑删除)
+            for (LawFirmPayment existing : existingPayments) {
+                if (!incomingIds.contains(existing.getId())) {
+                    existing.setDeleteFlag(1);
+                    storeLawFirmPaymentService.updateById(existing);
+                }
+            }
+            
+            // 新增或更新收款账号记录
+            for (LawFirmPayment payment : lawFirm.getPaymentList()) {
+                if (!StringUtils.hasText(payment.getPaymentAccount())) {
+                    continue;
+                }
+                
+                String paymentAccount = payment.getPaymentAccount().trim();
+                
+                try {
+                    if (payment.getId() != null) {
+                        // 更新:获取原始记录
+                        LawFirmPayment existingPayment = existingPayments.stream()
+                                .filter(p -> p.getId().equals(payment.getId()))
+                                .findFirst()
+                                .orElse(null);
+                        
+                        if (existingPayment != null) {
+                            String originalAccount = existingPayment.getPaymentAccount();
+                            
+                            // 如果 paymentAccount 被修改了,不更新 paymentAccount 字段,保持原值
+                            LawFirmPayment updatePayment = new LawFirmPayment();
+                            updatePayment.setId(payment.getId());
+                            updatePayment.setFirmId(lawFirm.getId());
+                            
+                            // 如果账号被修改了,保持原值;否则使用新值
+                            if (!originalAccount.equals(paymentAccount)) {
+                                updatePayment.setPaymentAccount(originalAccount); // 保持原值
+                            } else {
+                                updatePayment.setPaymentAccount(paymentAccount);
+                            }
+                            
+                            // 更新其他字段
+                            if (StringUtils.hasText(payment.getAddress())) {
+                                updatePayment.setAddress(payment.getAddress().trim());
+                            } else {
+                                updatePayment.setAddress(existingPayment.getAddress());
+                            }
+                            
+                            boolean updateResult = storeLawFirmPaymentService.updateById(updatePayment);
+                            if (!updateResult) {
+                                log.error("更新收款账号失败,firmId={}, paymentAccount={}, id={}", 
+                                        lawFirm.getId(), paymentAccount, payment.getId());
+                                return R.fail("更新收款账号失败:" + paymentAccount);
+                            }
+                            log.info("更新收款账号成功,firmId={}, paymentAccount={}, id={}", 
+                                    lawFirm.getId(), existingPayment.getPaymentAccount(), updatePayment.getId());
+                        }
+                    } else {
+                        // 新增:再次检查账号是否已存在(防止并发问题)
+                        LambdaQueryWrapper<LawFirmPayment> checkWrapper = new LambdaQueryWrapper<>();
+                        checkWrapper.eq(LawFirmPayment::getPaymentAccount, paymentAccount);
+                        checkWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
+                        long checkCount = storeLawFirmPaymentService.count(checkWrapper);
+                        if (checkCount > 0) {
+                            return R.fail("收款账号[" + paymentAccount + "]在数据库中已存在,不能添加");
+                        }
+                        
+                        // 新增收款账号
+                        LawFirmPayment newPayment = new LawFirmPayment();
+                        newPayment.setFirmId(lawFirm.getId());
+                        newPayment.setPaymentAccount(paymentAccount);
+                        if (StringUtils.hasText(payment.getAddress())) {
+                            newPayment.setAddress(payment.getAddress().trim());
+                        }
+                        newPayment.setDeleteFlag(0);
+                        
+                        boolean saveResult = storeLawFirmPaymentService.save(newPayment);
+                        if (!saveResult) {
+                            log.error("保存收款账号失败,firmId={}, paymentAccount={}", lawFirm.getId(), paymentAccount);
+                            return R.fail("保存收款账号失败:" + paymentAccount);
+                        }
+                        log.info("保存收款账号成功,firmId={}, paymentAccount={}, id={}", 
+                                lawFirm.getId(), paymentAccount, newPayment.getId());
+                    }
+                } catch (Exception e) {
+                    log.error("处理收款账号异常,firmId={}, paymentAccount={}", lawFirm.getId(), paymentAccount, e);
+                    return R.fail("处理收款账号异常:" + e.getMessage());
+                }
+            }
+        }
+        
+        return R.data(lawFirm);
+    }
+
+    @Override
+    public R<Boolean> deleteLawFirm(Integer id) {
+        log.info("StoreLawFirmServiceImpl.deleteLawFirm?paymentId={}", id);
+        
+        // 1. 根据律所子表id查询子表记录
+        LawFirmPayment payment = storeLawFirmPaymentService.getById(id);
+        if (payment == null || payment.getDeleteFlag() == 1) {
+            return R.fail("收款账号记录不存在或已被删除");
+        }
+        
+        Integer firmId = payment.getFirmId();
+        if (firmId == null) {
+            return R.fail("律所ID为空,无法删除");
+        }
+        
+        // 2. 删除子表记录(逻辑删除)
+        boolean deletePaymentResult = storeLawFirmPaymentService.removeById(id);
+        if (!deletePaymentResult) {
+            return R.fail("删除收款账号失败");
+        }
+        log.info("删除收款账号成功,paymentId={}, firmId={}", id, firmId);
+        
+        // 3. 查询该律所是否还有关联的子表(未删除的)
+        LambdaQueryWrapper<LawFirmPayment> paymentWrapper = new LambdaQueryWrapper<>();
+        paymentWrapper.eq(LawFirmPayment::getFirmId, firmId);
+        paymentWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
+        long remainingPaymentCount = storeLawFirmPaymentService.count(paymentWrapper);
+        
+        // 4. 如果没有子表了,继续删除主表(逻辑删除)
+        if (remainingPaymentCount == 0) {
+            log.info("律所[{}]没有关联的收款账号了,删除主表", firmId);
+            boolean deleteFirmResult = this.removeById(firmId);
+            if (!deleteFirmResult) {
+                log.warn("删除律所主表失败,firmId={}", firmId);
+                return R.success("收款账号删除成功,但删除律所主表失败");
+            }
+            log.info("删除律所主表成功,firmId={}", firmId);
+            return R.success("删除成功,已同时删除律所主表");
+        } else {
+            log.info("律所[{}]还有{}个收款账号,保留主表", firmId, remainingPaymentCount);
+            return R.success("删除成功");
+        }
+    }
+
+    @Override
+    public void exportLawFirm(HttpServletResponse response) throws IOException {
+        log.info("StoreLawFirmServiceImpl.exportLawFirm");
+        try {
+            // 使用 getPaymentPageWithFirm 的方式查询所有数据(不分页)
+            // 设置一个很大的页面大小来获取所有数据
+            Page<LawFirmPaymentVO> page = new Page<>(1, Integer.MAX_VALUE);
+            IPage<LawFirmPaymentVO> pageResult = lawFirmPaymentMapper.selectPaymentPageWithFirm(
+                    page, null, null, null, null, null, null, null, null, null
+            );
+
+            List<LawFirmPaymentVO> paymentList = pageResult.getRecords();
+
+            if (paymentList == null || paymentList.isEmpty()) {
+                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+                response.getWriter().write("暂无数据可导出");
+                return;
+            }
+
+            // 使用 EasyExcelUtil 导出
+            EasyExcelUtil.exportExcel(response, paymentList, LawFirmPaymentVO.class, "律所列表", "律所列表");
+        } catch (Exception e) {
+            log.error("导出律所数据失败", e);
+            if (!response.isCommitted()) {
+                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+                response.getWriter().write("导出失败:" + e.getMessage());
+            }
+            throw new IOException("导出失败:" + e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public R<String> importLawFirm(MultipartFile file) {
+        log.info("StoreLawFirmServiceImpl.importLawFirm fileName={}", file.getOriginalFilename());
+        try {
+            if (file == null || file.isEmpty()) {
+                return R.fail("文件不能为空");
+            }
+
+            String fileName = file.getOriginalFilename();
+            if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) {
+                return R.fail("文件格式不正确,请上传Excel文件");
+            }
+
+            List<LawFirmExcelVo> excelVoList = new ArrayList<>();
+            List<String> errorMessages = new ArrayList<>();
+
+            // 使用POI读取Excel
+            try (InputStream inputStream = file.getInputStream();
+                 Workbook workbook = new XSSFWorkbook(inputStream)) {
+                Sheet sheet = workbook.getSheetAt(0);
+
+                // 获取表头
+                Row headerRow = sheet.getRow(0);
+                if (headerRow == null) {
+                    return R.fail("Excel文件格式不正确,缺少表头");
+                }
+
+                // 构建字段映射(表头名称 -> 列索引)
+                Map<String, Integer> headerMap = new HashMap<>();
+                Field[] fields = LawFirmExcelVo.class.getDeclaredFields();
+                for (int i = 0; i < headerRow.getLastCellNum(); i++) {
+                    Cell cell = headerRow.getCell(i);
+                    if (cell != null) {
+                        String headerName = cell.getStringCellValue().trim();
+                        headerMap.put(headerName, i);
+                    }
+                }
+
+                // 读取数据行
+                for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
+                    Row row = sheet.getRow(rowIndex);
+                    if (row == null) {
+                        continue;
+                    }
+
+                    // 检查是否为空行
+                    boolean isEmptyRow = true;
+                    for (int i = 0; i < row.getLastCellNum(); i++) {
+                        Cell cell = row.getCell(i);
+                        if (cell != null && cell.getCellType() != CellType.BLANK) {
+                            isEmptyRow = false;
+                            break;
+                        }
+                    }
+                    if (isEmptyRow) {
+                        continue;
+                    }
+
+                    LawFirmExcelVo excelVo = new LawFirmExcelVo();
+
+                    // 读取每个字段
+                    for (Field field : fields) {
+                        if (!field.isAnnotationPresent(ExcelHeader.class)) {
+                            continue;
+                        }
+                        ExcelHeader excelHeader = field.getAnnotation(ExcelHeader.class);
+                        String headerName = excelHeader.value();
+                        Integer colIndex = headerMap.get(headerName);
+                        if (colIndex == null) {
+                            continue;
+                        }
+
+                        Cell cell = row.getCell(colIndex);
+                        if (cell == null) {
+                            continue;
+                        }
+
+                        field.setAccessible(true);
+                        try {
+                            String cellValue = getCellValueAsString(cell);
+                            if (cellValue != null && !cellValue.trim().isEmpty()) {
+                                // 根据字段类型设置值
+                                Class<?> fieldType = field.getType();
+                                if (fieldType == String.class) {
+                                    field.set(excelVo, cellValue.trim());
+                                } else if (fieldType == Integer.class) {
+                                    try {
+                                        field.set(excelVo, Integer.parseInt(cellValue.trim()));
+                                    } catch (NumberFormatException e) {
+                                        // 忽略
+                                    }
+                                }
+                            }
+                        } catch (Exception e) {
+                            log.warn("读取字段{}失败:{}", headerName, e.getMessage());
+                        }
+                    }
+
+                    // 校验数据
+                    String errorMsg = validateExcelData(excelVo, rowIndex + 1);
+                    if (errorMsg != null) {
+                        errorMessages.add(errorMsg);
+                    } else {
+                        excelVoList.add(excelVo);
+                    }
+                }
+            }
+
+            if (!errorMessages.isEmpty()) {
+                return R.fail("数据校验失败:\n" + String.join("\n", errorMessages));
+            }
+
+            if (excelVoList.isEmpty()) {
+                return R.fail("Excel文件中没有有效数据");
+            }
+
+            // 收集所有导入数据中的收款账号(用于检查重复)
+            Set<String> allImportAccounts = new HashSet<>();
+            Map<String, String> accountToFirmNameMap = new HashMap<>(); // 账号 -> 律所名称,用于错误提示
+
+            // 先收集所有账号,检查导入数据中的重复(不允许逗号分隔)
+            for (LawFirmExcelVo excelVo : excelVoList) {
+                String paymentAccount = excelVo.getPaymentAccount();
+                if (StringUtils.hasText(paymentAccount)) {
+                    String trimmedAccount = paymentAccount.trim();
+                    if (!trimmedAccount.isEmpty()) {
+                        if (allImportAccounts.contains(trimmedAccount)) {
+                            // 发现重复账号
+                            String existingFirmName = accountToFirmNameMap.get(trimmedAccount);
+                            return R.fail(String.format("导入数据中存在重复的收款账号[%s],律所[%s]和律所[%s]使用了相同的账号,无法导入",
+                                    trimmedAccount, existingFirmName, excelVo.getFirmName()));
+                        }
+                        allImportAccounts.add(trimmedAccount);
+                        accountToFirmNameMap.put(trimmedAccount, excelVo.getFirmName());
+                    }
+                }
+            }
+
+            // 检查数据库中是否已存在这些账号
+            if (!allImportAccounts.isEmpty()) {
+                // 查询数据库中所有已存在的收款账号(从子表查询)
+                LambdaQueryWrapper<LawFirmPayment> paymentWrapper = new LambdaQueryWrapper<>();
+                paymentWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
+                paymentWrapper.isNotNull(LawFirmPayment::getPaymentAccount);
+                paymentWrapper.ne(LawFirmPayment::getPaymentAccount, "");
+                List<LawFirmPayment> existingPayments = storeLawFirmPaymentService.list(paymentWrapper);
+
+                // 收集数据库中所有已存在的账号
+                Set<String> existingAccounts = new HashSet<>();
+                for (LawFirmPayment payment : existingPayments) {
+                    String paymentAccount = payment.getPaymentAccount();
+                    if (StringUtils.hasText(paymentAccount)) {
+                        existingAccounts.add(paymentAccount.trim());
+                    }
+                }
+
+                // 检查导入的账号是否已存在
+                Set<String> duplicateAccounts = new HashSet<>();
+                for (String importAccount : allImportAccounts) {
+                    if (existingAccounts.contains(importAccount)) {
+                        duplicateAccounts.add(importAccount);
+                    }
+                }
+
+                if (!duplicateAccounts.isEmpty()) {
+                    String duplicateAccountList = String.join("、", duplicateAccounts);
+                    return R.fail(String.format("收款账号[%s]在数据库中已存在,无法导入。请检查并修改账号后重新导入", duplicateAccountList));
+                }
+            }
+
+            // 按统一社会信用代码分组,合并数据
+            // 先检查是否有空的信用代码
+            for (LawFirmExcelVo excelVo : excelVoList) {
+                if (!StringUtils.hasText(excelVo.getCreditCode())) {
+                    return R.fail("导入数据中存在空的统一社会信用代码,请检查第" + (excelVoList.indexOf(excelVo) + 2) + "行数据");
+                }
+            }
+
+            // 按统一社会信用代码分组
+            Map<String, List<LawFirmExcelVo>> creditCodeMap = excelVoList.stream()
+                    .filter(vo -> StringUtils.hasText(vo.getCreditCode()))
+                    .collect(Collectors.groupingBy(LawFirmExcelVo::getCreditCode));
+
+            int successCount = 0;
+            int failCount = 0;
+            int updateCount = 0;
+            List<String> importErrors = new ArrayList<>();
+
+            for (Map.Entry<String, List<LawFirmExcelVo>> entry : creditCodeMap.entrySet()) {
+                String creditCode = entry.getKey();
+                List<LawFirmExcelVo> voList = entry.getValue();
+
+                // 合并收款账号,并维护账号和地址的对应关系(不允许逗号分隔)
+                // 使用LinkedHashMap保持顺序,后出现的账号地址会覆盖先出现的(如果地址不为空)
+                Map<String, String> accountAddressMap = new LinkedHashMap<>();
+                for (LawFirmExcelVo vo : voList) {
+                    String paymentAccount = vo.getPaymentAccount();
+                    String address = vo.getAddress();
+                    if (StringUtils.hasText(paymentAccount)) {
+                        String trimmedAccount = paymentAccount.trim();
+                        if (!trimmedAccount.isEmpty()) {
+                            // 如果账号已存在但地址为空,且当前地址不为空,则更新地址
+                            // 如果账号不存在,直接添加
+                            if (!accountAddressMap.containsKey(trimmedAccount) || 
+                                (StringUtils.hasText(address) && !StringUtils.hasText(accountAddressMap.get(trimmedAccount)))) {
+                                accountAddressMap.put(trimmedAccount, address != null ? address.trim() : "");
+                            }
+                        }
+                    }
+                }
+
+                // 使用第一个数据作为主数据,其他数据补充缺失字段
+                LawFirmExcelVo firstVo = voList.get(0);
+                LawFirm lawFirm = convertToLawFirm(firstVo);
+                
+                // 如果第一个数据缺少某些字段,尝试从其他数据中获取
+                for (int i = 1; i < voList.size(); i++) {
+                    LawFirmExcelVo otherVo = voList.get(i);
+                    // 补充缺失的字段(这里可以根据需要补充其他字段)
+                    if (!StringUtils.hasText(lawFirm.getFirmName()) && StringUtils.hasText(otherVo.getFirmName())) {
+                        lawFirm.setFirmName(otherVo.getFirmName());
+                    }
+                    if (!StringUtils.hasText(lawFirm.getPhone()) && StringUtils.hasText(otherVo.getPhone())) {
+                        lawFirm.setPhone(otherVo.getPhone());
+                    }
+                    if (!StringUtils.hasText(lawFirm.getDirectorName()) && StringUtils.hasText(otherVo.getDirectorName())) {
+                        lawFirm.setDirectorName(otherVo.getDirectorName());
+                    }
+                    if (!StringUtils.hasText(lawFirm.getDirectorPhone()) && StringUtils.hasText(otherVo.getDirectorPhone())) {
+                        lawFirm.setDirectorPhone(otherVo.getDirectorPhone());
+                    }
+                }
+
+                // 检查统一社会信用代码是否已存在
+                LambdaQueryWrapper<LawFirm> creditCodeWrapper = new LambdaQueryWrapper<>();
+                creditCodeWrapper.eq(LawFirm::getCreditCode, creditCode);
+                creditCodeWrapper.eq(LawFirm::getDeleteFlag, 0);
+                LawFirm existingLawFirm = this.getOne(creditCodeWrapper);
+                
+                boolean isUpdate = false;
+                if (existingLawFirm != null) {
+                    // 如果已存在,更新现有记录
+                    isUpdate = true;
+                    lawFirm.setId(existingLawFirm.getId());
+                    // 保留原有的一些字段(如果新数据没有提供)
+                    if (!StringUtils.hasText(lawFirm.getFirmName())) {
+                        lawFirm.setFirmName(existingLawFirm.getFirmName());
+                    }
+                    if (!StringUtils.hasText(lawFirm.getPhone())) {
+                        lawFirm.setPhone(existingLawFirm.getPhone());
+                    }
+                    if (lawFirm.getStatus() == null) {
+                        lawFirm.setStatus(existingLawFirm.getStatus());
+                    }
+                } else {
+                    // 设置默认值(新增时)
+                if (lawFirm.getStatus() == null) {
+                    lawFirm.setStatus(1);
+                }
+                }
+                
+                if (lawFirm.getDeleteFlag() == null) {
+                    lawFirm.setDeleteFlag(0);
+                }
+                
+                // 保存或更新主表
+                boolean saveResult;
+                if (isUpdate) {
+                    saveResult = this.updateById(lawFirm);
+                } else {
+                    saveResult = this.save(lawFirm);
+                }
+                
+                if (!saveResult) {
+                    importErrors.add("统一社会信用代码[" + creditCode + "]" + (isUpdate ? "更新" : "保存") + "失败");
+                    failCount++;
+                    continue;
+                }
+                
+                // 处理子表收款账号
+                if (!accountAddressMap.isEmpty()) {
+                    // 查询现有的收款账号
+                    LambdaQueryWrapper<LawFirmPayment> existingPaymentWrapper = new LambdaQueryWrapper<>();
+                    existingPaymentWrapper.eq(LawFirmPayment::getFirmId, lawFirm.getId());
+                    existingPaymentWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
+                    List<LawFirmPayment> existingPayments = storeLawFirmPaymentService.list(existingPaymentWrapper);
+                    
+                    // 收集现有的收款账号
+                    Set<String> existingAccountSet = existingPayments.stream()
+                            .map(LawFirmPayment::getPaymentAccount)
+                            .filter(Objects::nonNull)
+                            .filter(acc -> !acc.trim().isEmpty())
+                            .collect(Collectors.toSet());
+                    
+                    // 添加新的收款账号(排除已存在的),每个账号使用其对应的地址
+                    for (Map.Entry<String, String> accountEntry : accountAddressMap.entrySet()) {
+                        String trimmedAccount = accountEntry.getKey();
+                        String address = accountEntry.getValue();
+                        
+                        if (!trimmedAccount.isEmpty() && !existingAccountSet.contains(trimmedAccount)) {
+                            // 检查账号是否已存在(全局唯一性校验)
+                            LambdaQueryWrapper<LawFirmPayment> accountWrapper = new LambdaQueryWrapper<>();
+                            accountWrapper.eq(LawFirmPayment::getPaymentAccount, trimmedAccount);
+                            accountWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
+                            long accountCount = storeLawFirmPaymentService.count(accountWrapper);
+                            if (accountCount == 0) {
+                                // 账号不存在,可以添加
+                                LawFirmPayment payment = new LawFirmPayment();
+                                payment.setFirmId(lawFirm.getId());
+                                payment.setPaymentAccount(trimmedAccount);
+                                // 设置详细地址(使用该账号对应的地址)
+                                if (StringUtils.hasText(address)) {
+                                    payment.setAddress(address.trim());
+                                }
+                                payment.setDeleteFlag(0);
+                                storeLawFirmPaymentService.save(payment);
+                            } else {
+                                // 账号已存在,记录警告但不阻止导入
+                                log.warn("收款账号[{}]已存在,跳过添加", trimmedAccount);
+                            }
+                        }
+                    }
+                }
+
+                if (isUpdate) {
+                    updateCount++;
+                } else {
+                    successCount++;
+                }
+            }
+
+            String resultMsg = String.format("导入完成:新增%d条,更新%d条,失败%d条", successCount, updateCount, failCount);
+            if (!importErrors.isEmpty()) {
+                resultMsg += "\n失败详情:\n" + String.join("\n", importErrors);
+            }
+
+            return R.success(resultMsg);
+        } catch (Exception e) {
+            log.error("导入律所数据失败", e);
+            return R.fail("导入失败:" + e.getMessage());
+        }
+    }
+
+    @Override
+    public R<LawFirm> getLawFirmDetail(Integer id) {
+        log.info("StoreLawFirmServiceImpl.getLawFirmDetail?id={}", id);
+
+        if (id == null) {
+            return R.fail("律所ID不能为空");
+        }
+
+        // 使用 MyBatis-Plus 的 getById 方法获取律所详情
+        LawFirm lawFirm = this.getById(id);
+
+        if (lawFirm == null) {
+            return R.fail("律所不存在");
+        }
+
+        // 检查是否已删除
+        if (lawFirm.getDeleteFlag() != null && lawFirm.getDeleteFlag() == 1) {
+            return R.fail("律所已被删除");
+        }
+
+        // 查询收款账号列表
+        LambdaQueryWrapper<LawFirmPayment> paymentWrapper = new LambdaQueryWrapper<>();
+        paymentWrapper.eq(LawFirmPayment::getFirmId, id);
+        paymentWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
+        List<LawFirmPayment> paymentList = storeLawFirmPaymentService.list(paymentWrapper);
+        lawFirm.setPaymentList(paymentList);
+
+        return R.data(lawFirm, "查询成功");
+    }
+
+    @Override
+    public void downloadTemplate(HttpServletResponse response) throws IOException {
+        log.info("StoreLawFirmServiceImpl.downloadTemplate");
+        
+        XSSFWorkbook workbook = new XSSFWorkbook();
+        try {
+            Sheet sheet = workbook.createSheet("律所导入模板");
+
+            // 获取带有 @ExcelHeader 注解的字段
+            Field[] fields = LawFirmExcelVo.class.getDeclaredFields();
+            List<Field> excelFields = Arrays.stream(fields)
+                    .filter(f -> f.isAnnotationPresent(ExcelHeader.class))
+                    .collect(Collectors.toList());
+
+            // 创建表头样式
+            Font headerFont = workbook.createFont();
+            headerFont.setBold(true);
+            CellStyle headerCellStyle = workbook.createCellStyle();
+            headerCellStyle.setFont(headerFont);
+            headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
+            headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+
+            // 创建表头
+            Row headerRow = sheet.createRow(0);
+            for (int i = 0; i < excelFields.size(); i++) {
+                Field field = excelFields.get(i);
+                ExcelHeader excelHeader = field.getAnnotation(ExcelHeader.class);
+                Cell cell = headerRow.createCell(i);
+                cell.setCellValue(excelHeader.value());
+                cell.setCellStyle(headerCellStyle);
+            }
+
+            // 设置列宽
+            for (int i = 0; i < excelFields.size(); i++) {
+                sheet.setColumnWidth(i, 20 * 256);
+            }
+
+            // 设置响应头(必须在获取输出流之前设置)
+            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+            response.setCharacterEncoding("utf-8");
+            String fileName = URLEncoder.encode("律所导入模板", "UTF-8").replaceAll("\\+", "%20");
+            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
+
+            // 输出到响应流
+            OutputStream outputStream = response.getOutputStream();
+            workbook.write(outputStream);
+            outputStream.flush();
+        } finally {
+            // 确保 workbook 被正确关闭
+            if (workbook != null) {
+                workbook.close();
+            }
+        }
+    }
+
+    @Override
     public R<IPage<LawFirmPaymentVO>> getPaymentPageWithFirm(int pageNum, int pageSize, Integer firmId, String paymentAccount, String firmName, String creditCode, Integer status, Integer certificationStatus, String directorName, String createdTimeStart, String createdTimeEnd) {
-        log.info("LawFirmServiceImpl.getPaymentPageWithFirm?pageNum={},pageSize={},firmId={},paymentAccount={},firmName={},creditCode={},status={},certificationStatus={},directorName={},createdTimeStart={},createdTimeEnd={}",
+        log.info("StoreLawFirmServiceImpl.getPaymentPageWithFirm?pageNum={},pageSize={},firmId={},paymentAccount={},firmName={},creditCode={},status={},certificationStatus={},directorName={},createdTimeStart={},createdTimeEnd={}",
                 pageNum, pageSize, firmId, paymentAccount, firmName, creditCode, status, certificationStatus, directorName, createdTimeStart, createdTimeEnd);
 
         Page<LawFirmPaymentVO> page = new Page<>(pageNum, pageSize);
@@ -107,4 +925,137 @@ public class StoreLawFirmServiceImpl extends ServiceImpl<LawFirmMapper, LawFirm>
         return R.data(pageResult);
     }
 
+    /**
+     * 校验Excel数据
+     */
+    private String validateExcelData(LawFirmExcelVo excelVo, int rowIndex) {
+        if (!StringUtils.hasText(excelVo.getFirmName())) {
+            return "第" + rowIndex + "行:律所名称不能为空";
+        }
+        if (!StringUtils.hasText(excelVo.getCreditCode())) {
+            return "第" + rowIndex + "行:统一社会信用代码不能为空";
+        }
+        if (!StringUtils.hasText(excelVo.getDirectorName())) {
+            return "第" + rowIndex + "行:负责人姓名不能为空";
+        }
+
+        // 校验收款账号(不允许逗号分隔,必须是单个16位或19位账号)
+        if (StringUtils.hasText(excelVo.getPaymentAccount())) {
+            String paymentAccount = excelVo.getPaymentAccount().trim();
+            // 不允许包含逗号
+            if (paymentAccount.contains(",")) {
+                return "第" + rowIndex + "行:收款账号不允许包含逗号,每行只能填写一个账号";
+            }
+            // 校验长度(必须是16位或19位)
+            int length = paymentAccount.length();
+            if (length != 16 && length != 19) {
+                return "第" + rowIndex + "行:收款账号[" + paymentAccount + "]长度不正确,必须是16位或19位,当前为" + length + "位";
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * 转换为LawFirm实体
+     */
+    private LawFirm convertToLawFirm(LawFirmExcelVo excelVo) {
+        LawFirm lawFirm = new LawFirm();
+        BeanUtils.copyProperties(excelVo, lawFirm);
+
+        // 解析类型
+        if (StringUtils.hasText(excelVo.getFirmType())) {
+            switch (excelVo.getFirmType()) {
+                case "合伙制":
+                    lawFirm.setFirmType(1);
+                    break;
+                case "个人制":
+                    lawFirm.setFirmType(2);
+                    break;
+                case "国资制":
+                    lawFirm.setFirmType(3);
+                    break;
+            }
+        }
+
+        // 解析规模
+        if (StringUtils.hasText(excelVo.getFirmScale())) {
+            if (excelVo.getFirmScale().contains("小型")) {
+                lawFirm.setFirmScale(1);
+            } else if (excelVo.getFirmScale().contains("中型")) {
+                lawFirm.setFirmScale(2);
+            } else if (excelVo.getFirmScale().contains("大型") && !excelVo.getFirmScale().contains("超大型")) {
+                lawFirm.setFirmScale(3);
+            } else if (excelVo.getFirmScale().contains("超大型")) {
+                lawFirm.setFirmScale(4);
+            }
+        }
+
+        // 解析状态
+        if (StringUtils.hasText(excelVo.getStatus())) {
+            lawFirm.setStatus("启用".equals(excelVo.getStatus()) ? 1 : 0);
+        }
+
+        // 解析认证状态
+        if (StringUtils.hasText(excelVo.getCertificationStatus())) {
+            switch (excelVo.getCertificationStatus()) {
+                case "未认证":
+                    lawFirm.setCertificationStatus(0);
+                    break;
+                case "认证中":
+                    lawFirm.setCertificationStatus(1);
+                    break;
+                case "已认证":
+                    lawFirm.setCertificationStatus(2);
+                    break;
+                case "认证失败":
+                    lawFirm.setCertificationStatus(3);
+                    break;
+            }
+        }
+
+        // 解析日期
+        if (StringUtils.hasText(excelVo.getEstablishmentDate())) {
+            try {
+                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+                lawFirm.setEstablishmentDate(dateFormat.parse(excelVo.getEstablishmentDate()));
+            } catch (Exception e) {
+                log.warn("解析成立日期失败:{}", excelVo.getEstablishmentDate());
+            }
+        }
+
+        return lawFirm;
+    }
+
+    /**
+     * 获取单元格值作为字符串
+     */
+    private String getCellValueAsString(Cell cell) {
+        if (cell == null) {
+            return null;
+        }
+        switch (cell.getCellType()) {
+            case STRING:
+                return cell.getStringCellValue();
+            case NUMERIC:
+                if (DateUtil.isCellDateFormatted(cell)) {
+                    return new SimpleDateFormat("yyyy-MM-dd").format(cell.getDateCellValue());
+                } else {
+                    double numericValue = cell.getNumericCellValue();
+                    // 如果是整数,返回整数格式
+                    if (numericValue == (long) numericValue) {
+                        return String.valueOf((long) numericValue);
+                    } else {
+                        return String.valueOf(numericValue);
+                    }
+                }
+            case BOOLEAN:
+                return String.valueOf(cell.getBooleanCellValue());
+            case FORMULA:
+                return cell.getCellFormula();
+            default:
+                return null;
+        }
+    }
+
 }