package com.ruoyi.basic.service;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.ruoyi.basic.dto.StorageBlobVO;
|
import com.ruoyi.basic.mapper.CustomerFinancialReportMapper;
|
import com.ruoyi.basic.mapper.CustomerMapper;
|
import com.ruoyi.basic.mapper.CustomerUserMapper;
|
import com.ruoyi.basic.mapper.StorageBlobMapper;
|
import com.ruoyi.basic.pojo.Customer;
|
import com.ruoyi.basic.pojo.CustomerFinancialReport;
|
import com.ruoyi.basic.pojo.CustomerUser;
|
import com.ruoyi.basic.pojo.StorageBlob;
|
import com.ruoyi.basic.utils.FileUtil;
|
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.utils.SecurityUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.framework.security.LoginUser;
|
import lombok.RequiredArgsConstructor;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.time.LocalDateTime;
|
import java.time.Year;
|
import java.util.List;
|
import java.util.Objects;
|
import java.util.Set;
|
import java.util.stream.Collectors;
|
|
/**
|
* 客户近3年财务报表Service
|
*/
|
@Service
|
@RequiredArgsConstructor
|
public class CustomerFinancialReportService extends ServiceImpl<CustomerFinancialReportMapper, CustomerFinancialReport> {
|
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
|
private final CustomerMapper customerMapper;
|
private final CustomerUserMapper customerUserMapper;
|
private final StorageBlobMapper storageBlobMapper;
|
private final FileUtil fileUtil;
|
|
/**
|
* 后台按客户查询近3年财务报表
|
*/
|
public List<CustomerFinancialReport> listByCustomer(Long customerId) {
|
if (customerId == null) {
|
throw new ServiceException("请选择客户");
|
}
|
List<CustomerFinancialReport> reports = list(new LambdaQueryWrapper<CustomerFinancialReport>()
|
.eq(CustomerFinancialReport::getCustomerId, customerId)
|
.orderByDesc(CustomerFinancialReport::getReportYear));
|
refreshFileUrls(reports);
|
fillCustomerName(reports);
|
return reports;
|
}
|
|
/**
|
* 客户账号查询自己的近3年财务报表
|
*/
|
public List<CustomerFinancialReport> listMine() {
|
Long customerId = currentCustomerId();
|
List<CustomerFinancialReport> reports = list(new LambdaQueryWrapper<CustomerFinancialReport>()
|
.eq(CustomerFinancialReport::getCustomerId, customerId)
|
.orderByDesc(CustomerFinancialReport::getReportYear));
|
refreshFileUrls(reports);
|
fillCustomerName(reports);
|
return reports;
|
}
|
|
/**
|
* 保存财务报表:同一客户同一年度仅保留一条,可反复覆盖修改
|
*/
|
@Transactional(rollbackFor = Exception.class)
|
public CustomerFinancialReport saveReport(CustomerFinancialReport input) {
|
if (input.getReportYear() == null) {
|
throw new ServiceException("请选择报表年度");
|
}
|
int currentYear = Year.now().getValue();
|
if (input.getReportYear() < currentYear - 2 || input.getReportYear() > currentYear) {
|
throw new ServiceException("只能上传最近三个年度的财务报表");
|
}
|
if (StringUtils.isBlank(input.getReportFiles())) {
|
throw new ServiceException("请上传财务报表附件");
|
}
|
|
Long customerId;
|
if (isCustomerAccount()) {
|
customerId = currentCustomerId();
|
} else {
|
customerId = input.getCustomerId();
|
if (customerId == null || customerMapper.selectById(customerId) == null) {
|
throw new ServiceException("客户不存在");
|
}
|
}
|
|
CustomerFinancialReport entity = getOne(new LambdaQueryWrapper<CustomerFinancialReport>()
|
.eq(CustomerFinancialReport::getCustomerId, customerId)
|
.eq(CustomerFinancialReport::getReportYear, input.getReportYear()), false);
|
LoginUser loginUser = SecurityUtils.getLoginUser();
|
if (entity == null) {
|
entity = new CustomerFinancialReport();
|
entity.setCustomerId(customerId);
|
entity.setReportYear(input.getReportYear());
|
}
|
entity.setReportName(input.getReportName());
|
entity.setReportFiles(input.getReportFiles());
|
// 重新提交后回到待审批状态,等待内部人员重新审批
|
entity.setAuditStatus(0);
|
entity.setAuditUserId(null);
|
entity.setAuditUserName(null);
|
entity.setAuditTime(null);
|
entity.setAuditRemark(null);
|
entity.setUploadUserId(loginUser.getUserId());
|
entity.setUploadUserName(loginUser.getNickName());
|
saveOrUpdate(entity);
|
return entity;
|
}
|
|
/**
|
* 申报审批列表:内部人员查看所有客户的提交情况
|
*/
|
public List<CustomerFinancialReport> auditList(String customerName, Integer reportYear, Integer auditStatus) {
|
LambdaQueryWrapper<CustomerFinancialReport> wrapper = new LambdaQueryWrapper<CustomerFinancialReport>()
|
.eq(reportYear != null, CustomerFinancialReport::getReportYear, reportYear)
|
.eq(auditStatus != null, CustomerFinancialReport::getAuditStatus, auditStatus)
|
.orderByDesc(CustomerFinancialReport::getUpdateTime);
|
if (StringUtils.isNotBlank(customerName)) {
|
List<Long> customerIds = customerMapper.selectList(new LambdaQueryWrapper<Customer>()
|
.like(Customer::getCustomerName, customerName))
|
.stream().map(Customer::getId).filter(Objects::nonNull).collect(Collectors.toList());
|
if (customerIds.isEmpty()) {
|
return new java.util.ArrayList<>();
|
}
|
wrapper.in(CustomerFinancialReport::getCustomerId, customerIds);
|
}
|
List<CustomerFinancialReport> reports = list(wrapper);
|
refreshFileUrls(reports);
|
fillCustomerName(reports);
|
return reports;
|
}
|
|
/**
|
* 审批财务报表:1通过 2退回
|
*/
|
@Transactional(rollbackFor = Exception.class)
|
public CustomerFinancialReport auditReport(Long id, Integer auditStatus, String auditRemark) {
|
if (isCustomerAccount()) {
|
throw new ServiceException("客户账号无权审批财务报表");
|
}
|
if (id == null) {
|
throw new ServiceException("请选择申报记录");
|
}
|
if (auditStatus == null || auditStatus != 1 && auditStatus != 2) {
|
throw new ServiceException("审批结果不正确");
|
}
|
CustomerFinancialReport entity = getById(id);
|
if (entity == null) {
|
throw new ServiceException("申报记录不存在");
|
}
|
LoginUser loginUser = SecurityUtils.getLoginUser();
|
entity.setAuditStatus(auditStatus);
|
entity.setAuditUserId(loginUser.getUserId());
|
entity.setAuditUserName(loginUser.getNickName());
|
entity.setAuditTime(LocalDateTime.now());
|
entity.setAuditRemark(auditRemark);
|
updateById(entity);
|
return entity;
|
}
|
|
/**
|
* 删除财务报表:仅后台人员可删除,客户账号不允许删除
|
*/
|
@Transactional(rollbackFor = Exception.class)
|
public void deleteReport(Long id) {
|
if (isCustomerAccount()) {
|
throw new ServiceException("客户账号无权删除财务报表");
|
}
|
CustomerFinancialReport entity = getById(id);
|
if (entity == null) {
|
throw new ServiceException("财务报表不存在");
|
}
|
removeById(id);
|
}
|
|
/**
|
* 重新生成附件预览/下载地址:数据库中保存的是上传时的带签名地址,会过期,读取时按文件id刷新
|
*/
|
private void refreshFileUrls(List<CustomerFinancialReport> reports) {
|
if (reports == null || reports.isEmpty()) {
|
return;
|
}
|
for (CustomerFinancialReport report : reports) {
|
String files = report.getReportFiles();
|
if (StringUtils.isBlank(files)) {
|
continue;
|
}
|
try {
|
JsonNode root = OBJECT_MAPPER.readTree(files);
|
if (root == null || !root.isArray()) {
|
continue;
|
}
|
for (JsonNode node : root) {
|
Long blobId = node.hasNonNull("id") ? node.get("id").asLong() : null;
|
if (blobId == null) {
|
continue;
|
}
|
StorageBlob blob = storageBlobMapper.selectById(blobId);
|
if (blob == null) {
|
continue;
|
}
|
StorageBlobVO vo = new StorageBlobVO();
|
vo.setUidFilename(blob.getUidFilename());
|
vo.setPath(blob.getPath());
|
vo.setResourceKey(blob.getResourceKey());
|
ObjectNode objectNode = (ObjectNode) node;
|
objectNode.put("url", fileUtil.buildSignedPreviewUrl(vo));
|
objectNode.put("downloadURL", fileUtil.buildSignedDownloadUrl(vo));
|
if (!node.hasNonNull("name")) {
|
objectNode.put("name", blob.getOriginalFilename());
|
}
|
}
|
report.setReportFiles(OBJECT_MAPPER.writeValueAsString(root));
|
} catch (Exception e) {
|
// 旧数据或非 JSON 格式,保持原值
|
}
|
}
|
}
|
|
private boolean isCustomerAccount() {
|
Long userId = SecurityUtils.getUserId();
|
return !SecurityUtils.isAdmin(userId) && SecurityUtils.hasRole("customer");
|
}
|
|
/**
|
* 获取当前登录账号绑定的客户id
|
*/
|
private Long currentCustomerId() {
|
CustomerUser binding = customerUserMapper.selectOne(new LambdaQueryWrapper<CustomerUser>()
|
.eq(CustomerUser::getUserId, SecurityUtils.getUserId()).last("limit 1"));
|
if (binding == null || binding.getCustomerId() == null) {
|
throw new ServiceException("当前账号尚未绑定客户,请联系管理员");
|
}
|
return binding.getCustomerId();
|
}
|
|
private void fillCustomerName(List<CustomerFinancialReport> reports) {
|
if (reports == null || reports.isEmpty()) {
|
return;
|
}
|
Set<Long> ids = reports.stream().map(CustomerFinancialReport::getCustomerId)
|
.filter(Objects::nonNull).collect(Collectors.toSet());
|
if (ids.isEmpty()) {
|
return;
|
}
|
List<Customer> customers = customerMapper.selectBatchIds(ids);
|
java.util.Map<Long, String> nameMap = customers.stream()
|
.collect(Collectors.toMap(Customer::getId, Customer::getCustomerName, (a, b) -> a));
|
reports.forEach(item -> item.setCustomerName(nameMap.getOrDefault(item.getCustomerId(), "")));
|
}
|
}
|