Commit 6b0cb223 by zhangxingmin

push

parent 0354d041
......@@ -5,10 +5,7 @@ import com.yd.common.result.Result;
import com.yd.csf.api.service.ApiSalaryService;
import com.yd.csf.feign.client.salary.ApiSalaryFeignClient;
import com.yd.csf.feign.request.salary.*;
import com.yd.csf.feign.response.salary.ApiSalaryBrokerListResponse;
import com.yd.csf.feign.response.salary.ApiSalaryDetailResponse;
import com.yd.csf.feign.response.salary.ApiSalaryPageResponse;
import com.yd.csf.feign.response.salary.ApiSalaryPushPageResponse;
import com.yd.csf.feign.response.salary.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
......@@ -191,4 +188,14 @@ public class ApiSalaryController implements ApiSalaryFeignClient {
return apiSalaryService.brokerList(name);
}
/**
* 电子薪资单-导出
* @param request
* @return
*/
@Override
public Result<ApiSalaryExportResponse> export(ApiSalaryExportRequest request) {
return null;
}
}
......@@ -3,10 +3,7 @@ package com.yd.csf.api.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yd.common.result.Result;
import com.yd.csf.feign.request.salary.*;
import com.yd.csf.feign.response.salary.ApiSalaryBrokerListResponse;
import com.yd.csf.feign.response.salary.ApiSalaryDetailResponse;
import com.yd.csf.feign.response.salary.ApiSalaryPageResponse;
import com.yd.csf.feign.response.salary.ApiSalaryPushPageResponse;
import com.yd.csf.feign.response.salary.*;
import java.math.BigDecimal;
import java.util.List;
......@@ -42,5 +39,7 @@ public interface ApiSalaryService {
Result<BigDecimal> calculateTotalAmount(ApiSalaryCalculateTotalAmountRequest request);
Result<ApiSalaryExportResponse> export(ApiSalaryExportRequest request);
Result<List<ApiSalaryBrokerListResponse>> brokerList(String name);
}
......@@ -18,10 +18,7 @@ import com.yd.csf.feign.dto.salaryremittance.ApiSalaryRemittanceDTO;
import com.yd.csf.feign.dto.salaryremittance.ApiSalaryRemittanceFzDTO;
import com.yd.csf.feign.enums.SalaryStatusEnum;
import com.yd.csf.feign.request.salary.*;
import com.yd.csf.feign.response.salary.ApiSalaryBrokerListResponse;
import com.yd.csf.feign.response.salary.ApiSalaryDetailResponse;
import com.yd.csf.feign.response.salary.ApiSalaryPageResponse;
import com.yd.csf.feign.response.salary.ApiSalaryPushPageResponse;
import com.yd.csf.feign.response.salary.*;
import com.yd.csf.service.enums.FortuneAccountStatusEnum;
import com.yd.csf.service.model.FortuneAccount;
import com.yd.csf.service.model.PolicyFollow;
......@@ -33,6 +30,10 @@ import com.yd.csf.service.service.ISalaryService;
import com.yd.insurance.base.feign.client.usersaleexpand.ApiUserSaleExpandFeignClient;
import com.yd.insurance.base.feign.request.usersaleexpand.ApiUserSaleExpandListRequest;
import com.yd.insurance.base.feign.response.usersaleexpand.ApiUserSaleExpandDetailResponse;
import com.yd.oss.feign.client.ApiExcelFeignClient;
import com.yd.oss.feign.dto.ExportResult;
import com.yd.oss.feign.dto.SheetExportConfig;
import com.yd.oss.feign.request.MultiSheetExportRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
......@@ -44,6 +45,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
......@@ -73,6 +75,9 @@ public class ApiSalaryServiceImpl implements ApiSalaryService {
@Resource
private ApiUserSaleExpandFeignClient apiUserSaleExpandFeignClient;
@Autowired
private ApiExcelFeignClient apiExcelFeignClient;
/**
* 分页查询-制作薪资单列表信息
* @param request
......@@ -451,6 +456,202 @@ public class ApiSalaryServiceImpl implements ApiSalaryService {
}
/**
* 电子薪资单-导出
* @param request
* @return
*/
@Override
public Result<ApiSalaryExportResponse> export(ApiSalaryExportRequest request) {
// 1. 构建查询条件
LambdaQueryWrapper<Salary> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Salary::getIsDeleted, 0);
if (StringUtils.isNotBlank(request.getBrokerName())) {
wrapper.like(Salary::getBrokerName, request.getBrokerName());
}
if (StringUtils.isNotBlank(request.getMonth())) {
wrapper.eq(Salary::getMonth, request.getMonth());
}
if (StringUtils.isNotBlank(request.getStatus())) {
wrapper.eq(Salary::getStatus, request.getStatus());
}
// 按创建时间排序(可选)
wrapper.orderByAsc(Salary::getCreateTime);
// 2. 查询薪资单列表
List<Salary> salaryList = iSalaryService.list(wrapper);
if (CollectionUtils.isEmpty(salaryList)) {
throw new BusinessException("未查询到符合条件的薪资单数据");
}
// 3. 收集所有转介人业务ID,批量查询团队和内部编号(避免循环调用Feign)
List<String> brokerBizIds = salaryList.stream()
.map(Salary::getBrokerBizId)
.filter(StringUtils::isNotBlank)
.distinct()
.collect(Collectors.toList());
Map<String, ApiUserSaleExpandDetailResponse> expandMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(brokerBizIds)) {
ApiUserSaleExpandListRequest expandRequest = new ApiUserSaleExpandListRequest();
expandRequest.setClientUserBizIdList(brokerBizIds);
Result<List<ApiUserSaleExpandDetailResponse>> expandResult =
apiUserSaleExpandFeignClient.list(expandRequest);
if (expandResult != null && CollectionUtils.isNotEmpty(expandResult.getData())) {
expandMap = expandResult.getData().stream()
.collect(Collectors.toMap(
ApiUserSaleExpandDetailResponse::getClientUserBizId,
Function.identity(),
(v1, v2) -> v1
));
}
}
// 4. 批量查询所有汇款明细(按 salaryBizId 分组)
List<String> salaryBizIds = salaryList.stream()
.map(Salary::getSalaryBizId)
.collect(Collectors.toList());
Map<String, List<SalaryRemittance>> remittanceMap =
iSalaryRemittanceService.queryListBySalaryBizIds(salaryBizIds);
// 5. 构建汇总总表数据(每个Salary一行)
List<Map<String, Object>> summaryList = new ArrayList<>();
// 6. 构建打款明细数据(每个Remittance一行)
List<Map<String, Object>> detailList = new ArrayList<>();
for (Salary salary : salaryList) {
// 获取团队和内部编号
String brokerBizId = salary.getBrokerBizId();
String teamName = "";
String internalNumber = salary.getInternalNumber() != null ? salary.getInternalNumber() : "";
if (StringUtils.isNotBlank(brokerBizId) && expandMap.containsKey(brokerBizId)) {
ApiUserSaleExpandDetailResponse detail = expandMap.get(brokerBizId);
teamName = detail.getTeamName() != null ? detail.getTeamName() : "";
if (StringUtils.isBlank(internalNumber)) {
internalNumber = detail.getInternalNumber() != null ? detail.getInternalNumber() : "";
}
}
// --- 汇总行 ---
Map<String, Object> summaryRow = new LinkedHashMap<>();
summaryRow.put("发放编号", salary.getSalaryNo());
summaryRow.put("所属团队", teamName);
summaryRow.put("姓名", salary.getBrokerName());
summaryRow.put("内部编号", internalNumber);
summaryRow.put("薪资月份", formatMonth(salary.getMonth()));
summaryRow.put("应发金额(HKD)", nullToZero(salary.getGrossAmount()));
summaryRow.put("MPF(HK)", nullToZero(salary.getMpfAmount()));
summaryRow.put("其他调整(HKD)", nullToZero(salary.getOtherAmount()));
summaryRow.put("实发金额(HKD)", nullToZero(salary.getPaidAmount()));
summaryRow.put("扣款合计", BigDecimal.ZERO); // 暂无扣款合计字段
summaryRow.put("其他调整(HKD)", nullToZero(salary.getOtherAmount())); // 第二个
summaryRow.put("备注", salary.getRemark() != null ? salary.getRemark() : "");
List<SalaryRemittance> rems = remittanceMap.getOrDefault(salary.getSalaryBizId(), Collections.emptyList());
summaryRow.put("打款账户数", rems.size());
summaryRow.put("发放状态", getStatusDesc(salary.getStatus()));
summaryRow.put("备注", salary.getRemark() != null ? salary.getRemark() : ""); // 第二个备注
summaryRow.put("制作人", salary.getCreatorName() != null ? salary.getCreatorName() : "");
summaryRow.put("制作时间", salary.getCreateTime() != null ?
salary.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : "");
summaryList.add(summaryRow);
// --- 明细行 ---
for (SalaryRemittance rem : rems) {
Map<String, Object> detailRow = new LinkedHashMap<>();
detailRow.put("发放编号", salary.getSalaryNo());
detailRow.put("所属团队", teamName);
detailRow.put("姓名", salary.getBrokerName());
detailRow.put("内部编号", internalNumber);
detailRow.put("薪资月份", formatMonth(salary.getMonth()));
detailRow.put("收款银行", rem.getBank() != null ? rem.getBank() : "");
detailRow.put("账户尾号", rem.getAccountEndNo() != null ? rem.getAccountEndNo() : "");
detailRow.put("币种", rem.getCurrency() != null ? rem.getCurrency() : "");
detailRow.put("发放金额", nullToZero(rem.getAmount()));
detailRow.put("汇率", nullToZero(rem.getExchangeRate()));
detailRow.put("备注", rem.getRemark() != null ? rem.getRemark() : "");
detailList.add(detailRow);
}
}
// 7. 组装多 Sheet 导出请求
MultiSheetExportRequest exportRequest = new MultiSheetExportRequest();
// Sheet1: 汇总总表
SheetExportConfig sheet1 = new SheetExportConfig();
sheet1.setSheetName("汇总总表");
sheet1.setFieldNames(Arrays.asList(
"发放编号", "所属团队", "姓名", "内部编号", "薪资月份",
"应发金额(HKD)", "MPF(HK)", "其他调整(HKD)", "实发金额(HKD)",
"扣款合计", "其他调整(HKD)", "备注", "打款账户数", "发放状态",
"备注", "制作人", "制作时间"
));
sheet1.setDataList(summaryList);
// Sheet2: 打款明细
SheetExportConfig sheet2 = new SheetExportConfig();
sheet2.setSheetName("打款明细");
sheet2.setFieldNames(Arrays.asList(
"发放编号", "所属团队", "姓名", "内部编号", "薪资月份",
"收款银行", "账户尾号", "币种", "发放金额", "汇率", "备注"
));
sheet2.setDataList(detailList);
exportRequest.setSheets(Arrays.asList(sheet1, sheet2));
exportRequest.setFileName("电子薪资单_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
exportRequest.setUploadToOss(true);
// 8. 调用 Feign 导出
Result<ExportResult> feignResult = apiExcelFeignClient.exportMultiSheet(exportRequest);
if (feignResult == null || feignResult.getCode() != 200) {
String errMsg = feignResult != null ? feignResult.getMsg() : "Feign调用失败";
throw new BusinessException("导出失败: " + errMsg);
}
// 9. 返回 URL
ApiSalaryExportResponse response = new ApiSalaryExportResponse();
response.setUrl(feignResult.getData().getOssUrl());
return Result.success(response);
}
/**
* 将 yyyyMM 格式转为 yyyy-MM(便于阅读)
*/
private String formatMonth(String month) {
if (StringUtils.isBlank(month) || month.length() != 6) {
return month;
}
try {
return month.substring(0, 4) + "-" + month.substring(4, 6);
} catch (Exception e) {
return month;
}
}
private BigDecimal nullToZero(BigDecimal value) {
return value != null ? value : BigDecimal.ZERO;
}
/**
* 状态码转中文描述
* @param status 状态值(如 "1")
* @return 中文描述
*/
private String getStatusDesc(String status) {
if (status == null) {
return "";
}
// 根据数据库注释:1-待提交 2-待核对 3-已核对 4-退回 5-已推送 6-已取消
switch (status) {
case "1": return "待提交";
case "2": return "待核对";
case "3": return "已核对";
case "4": return "退回";
case "5": return "已推送";
case "6": return "已取消";
default: return status;
}
}
/**
* 查询薪资单转介人列表信息
* @return
*/
......
......@@ -5,6 +5,7 @@ import com.yd.csf.feign.fallback.salary.ApiSalaryFeignFallbackFactory;
import com.yd.csf.feign.request.salary.*;
import com.yd.csf.feign.response.salary.ApiSalaryBrokerListResponse;
import com.yd.csf.feign.response.salary.ApiSalaryDetailResponse;
import com.yd.csf.feign.response.salary.ApiSalaryExportResponse;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
......@@ -146,4 +147,11 @@ public interface ApiSalaryFeignClient {
@GetMapping("/broker/list")
Result<List<ApiSalaryBrokerListResponse>> brokerList(@RequestParam(value = "name",required = false) String name);
/**
* 电子薪资单-导出
* @param request
* @return
*/
@PostMapping("/salary/export")
Result<ApiSalaryExportResponse> export(@Validated @RequestBody ApiSalaryExportRequest request);
}
......@@ -5,6 +5,7 @@ import com.yd.csf.feign.client.salary.ApiSalaryFeignClient;
import com.yd.csf.feign.request.salary.*;
import com.yd.csf.feign.response.salary.ApiSalaryBrokerListResponse;
import com.yd.csf.feign.response.salary.ApiSalaryDetailResponse;
import com.yd.csf.feign.response.salary.ApiSalaryExportResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
......@@ -101,6 +102,11 @@ public class ApiSalaryFeignFallbackFactory implements FallbackFactory<ApiSalaryF
public Result<List<ApiSalaryBrokerListResponse>> brokerList(String name) {
return null;
}
@Override
public Result<ApiSalaryExportResponse> export(ApiSalaryExportRequest request) {
return null;
}
};
}
}
package com.yd.csf.feign.request.salary;
import lombok.Data;
@Data
public class ApiSalaryExportRequest {
/**
* 转介人名称
*/
private String brokerName;
/**
* 薪资月份(同出账月,如:202605)
*/
private String month;
/**
* 薪资单状态:1-待提交 2-待核对 3-已核对 4-退回 5-已推送 6-已取消
*/
private String status;
}
package com.yd.csf.feign.response.salary;
import lombok.Data;
@Data
public class ApiSalaryExportResponse {
private String url;
}
......@@ -4,6 +4,7 @@ import com.yd.csf.service.model.SalaryRemittance;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import java.util.Map;
/**
* <p>
......@@ -20,4 +21,11 @@ public interface ISalaryRemittanceService extends IService<SalaryRemittance> {
List<SalaryRemittance> queryList(String salaryBizId);
SalaryRemittance queryOne(String salaryRemittanceBizId);
/**
* 批量根据薪资单业务ID列表查询汇款明细,并按 salaryBizId 分组返回 Map
* @param salaryBizIds 薪资单业务ID列表
* @return Map<salaryBizId, List<SalaryRemittance>>
*/
Map<String, List<SalaryRemittance>> queryListBySalaryBizIds(List<String> salaryBizIds);
}
......@@ -5,9 +5,12 @@ import com.yd.csf.service.model.SalaryRemittance;
import com.yd.csf.service.dao.SalaryRemittanceMapper;
import com.yd.csf.service.service.ISalaryRemittanceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* <p>
......@@ -38,4 +41,20 @@ public class SalaryRemittanceServiceImpl extends ServiceImpl<SalaryRemittanceMap
.eq(SalaryRemittance::getSalaryRemittanceBizId,salaryRemittanceBizId)
.last(" limit 1 "));
}
@Override
public Map<String, List<SalaryRemittance>> queryListBySalaryBizIds(List<String> salaryBizIds) {
if (CollectionUtils.isEmpty(salaryBizIds)) {
return java.util.Collections.emptyMap();
}
// 批量查询
List<SalaryRemittance> list = this.baseMapper.selectList(
new LambdaQueryWrapper<SalaryRemittance>()
.in(SalaryRemittance::getSalaryBizId, salaryBizIds)
.orderByAsc(SalaryRemittance::getCreateTime) // 按需排序
);
// 按 salaryBizId 分组
return list.stream()
.collect(Collectors.groupingBy(SalaryRemittance::getSalaryBizId));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment