✨ 新增应收账单按角色和客户归属的行级数据权限
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package com.bms.ar.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.bms.ar.security.ArBillRowScope;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.bms.ar.domain.ArBalanceWriteoff;
|
||||
|
||||
@@ -33,5 +35,5 @@ public interface ArBalanceWriteoffMapper
|
||||
@Param("effectiveStatus") String effectiveStatus);
|
||||
|
||||
/** 查询核销记录列表(关联账单名称/客户名称) */
|
||||
List<ArBalanceWriteoff> selectWriteoffList(ArBalanceWriteoff query);
|
||||
List<ArBalanceWriteoff> selectWriteoffList(@Param("query") ArBalanceWriteoff query, @Param("scope") ArBillRowScope scope);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package com.bms.ar.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.bms.ar.security.ArBillRowScope;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.bms.ar.domain.ArBillDetailFee;
|
||||
|
||||
public interface ArBillDetailFeeMapper {
|
||||
List<ArBillDetailFee> selectByBillIdAndDetailIdScoped(@Param("arBillId") Long arBillId, @Param("detailId") Long detailId, @Param("scope") ArBillRowScope scope);
|
||||
|
||||
List<ArBillDetailFee> selectByDetailId(Long detailId);
|
||||
|
||||
List<ArBillDetailFee> selectByBillIdAndDetailId(@Param("arBillId") Long arBillId,
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
package com.bms.ar.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.bms.ar.security.ArBillRowScope;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.bms.ar.domain.ArBillDetail;
|
||||
|
||||
public interface ArBillDetailMapper {
|
||||
List<ArBillDetail> selectByBillIdScoped(@Param("arBillId") Long arBillId, @Param("scope") ArBillRowScope scope);
|
||||
|
||||
List<ArBillDetail> selectByBillId(Long arBillId);
|
||||
|
||||
List<ArBillDetail> selectByBillIdAndSourceIds(@Param("arBillId") Long arBillId,
|
||||
|
||||
@@ -10,6 +10,9 @@ import com.bms.ar.domain.ArBillGenerateTask;
|
||||
* 应收账单异步生成任务 Mapper。
|
||||
*/
|
||||
public interface ArBillGenerateTaskMapper {
|
||||
List<ArBillGenerateTask> selectActiveByCreateByScoped(@Param("createBy") String createBy,
|
||||
@Param("scope") com.bms.ar.security.ArBillRowScope scope);
|
||||
|
||||
ArBillGenerateTask selectById(Long taskId);
|
||||
|
||||
ArBillGenerateTask selectByRequestToken(String requestToken);
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package com.bms.ar.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.bms.ar.security.ArBillRowScope;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.bms.ar.domain.ArBillLog;
|
||||
|
||||
public interface ArBillLogMapper
|
||||
{
|
||||
List<ArBillLog> selectList(ArBillLog query);
|
||||
List<ArBillLog> selectList(@Param("query") ArBillLog query, @Param("scope") ArBillRowScope scope);
|
||||
|
||||
ArBillLog selectSuccessByRequestId(@Param("requestId") String requestId,
|
||||
@Param("objectType") String objectType,
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.bms.ar.mapper;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import com.bms.ar.security.ArBillRowScope;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.bms.ar.domain.ArBill;
|
||||
@@ -10,12 +11,14 @@ import com.bms.ar.domain.vo.ArBillQuery;
|
||||
import com.bms.ar.domain.vo.ArBillSummary;
|
||||
|
||||
public interface ArBillMapper {
|
||||
List<ArBill> selectArBillList(ArBillQuery query);
|
||||
List<ArBill> selectArBillList(@Param("query") ArBillQuery query, @Param("scope") ArBillRowScope scope);
|
||||
|
||||
ArBillSummary selectArBillSummary(ArBillQuery query);
|
||||
ArBillSummary selectArBillSummary(@Param("query") ArBillQuery query, @Param("scope") ArBillRowScope scope);
|
||||
|
||||
ArBill selectArBillById(Long arBillId);
|
||||
|
||||
ArBill selectArBillByIdScoped(@Param("arBillId") Long arBillId, @Param("scope") ArBillRowScope scope);
|
||||
|
||||
ArBill selectArBillByBillNo(String billNo);
|
||||
|
||||
ArBill selectGeneratingByCustomerPeriod(@Param("customerId") Long customerId,
|
||||
@@ -29,7 +32,7 @@ public interface ArBillMapper {
|
||||
/**
|
||||
* 查询客户可核销账单(已确认/部分核销),按账单日期升序,供余额核销选择
|
||||
*/
|
||||
List<ArBill> selectUnsettledByCustomer(@Param("customerId") Long customerId);
|
||||
List<ArBill> selectUnsettledByCustomer(@Param("customerId") Long customerId, @Param("scope") ArBillRowScope scope);
|
||||
|
||||
int insertArBill(ArBill bill);
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.bms.ar.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.bms.ar.security.ArBillRowScope;
|
||||
import com.bms.customer.customerinfo.domain.BmsCustomerOption;
|
||||
|
||||
public interface ArBillScopeMapper {
|
||||
int countCustomerSourceBills(@Param("customerId") Long customerId, @Param("sourceIds") List<String> sourceIds);
|
||||
|
||||
int countAccessibleBill(@Param("arBillId") Long arBillId, @Param("scope") ArBillRowScope scope);
|
||||
|
||||
BmsCustomerOption selectAccessibleCustomer(@Param("customerId") Long customerId, @Param("scope") ArBillRowScope scope);
|
||||
|
||||
List<BmsCustomerOption> selectCustomerOptions(@Param("keywords") List<String> keywords,
|
||||
@Param("scope") ArBillRowScope scope);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.bms.ar.security;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/** 应收业务范围,与角色管理的 dataScope 配置无关。 */
|
||||
public final class ArBillRoleKeys {
|
||||
public static final String SALES = "ORA_6041";
|
||||
public static final String BUSINESS_SPECIALIST = "ORA_6163";
|
||||
public static final String SALES_MANAGER = "ORA_6040";
|
||||
/** 销售员、商务专员:本人负责客户的账单。 */
|
||||
public static final Set<String> SELF_DATA_ROLES = Set.of(SALES, BUSINESS_SPECIALIST);
|
||||
/** 财务经理、应收财务;仍须具备对应接口的功能权限。 */
|
||||
public static final Set<String> ALL_DATA_ROLES = Set.of("ORA_6042", "ORA_6043");
|
||||
|
||||
static {
|
||||
if (SELF_DATA_ROLES.contains(SALES_MANAGER) || ALL_DATA_ROLES.contains(SALES_MANAGER)
|
||||
|| SELF_DATA_ROLES.stream().anyMatch(ALL_DATA_ROLES::contains)) {
|
||||
throw new IllegalStateException("应收数据权限角色映射冲突");
|
||||
}
|
||||
}
|
||||
|
||||
private ArBillRoleKeys() {}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.bms.ar.security;
|
||||
|
||||
/** 仅由后端构造,不能绑定到 HTTP 查询对象。 */
|
||||
public final class ArBillRowScope {
|
||||
private final boolean all;
|
||||
private final boolean self;
|
||||
private final boolean department;
|
||||
private final Long userId;
|
||||
private final Long deptId;
|
||||
|
||||
ArBillRowScope(boolean all, boolean self, boolean department, Long userId, Long deptId) {
|
||||
this.all = all;
|
||||
this.self = self && userId != null && userId > 0;
|
||||
this.department = department && deptId != null && deptId > 0;
|
||||
this.userId = userId;
|
||||
this.deptId = deptId;
|
||||
}
|
||||
|
||||
public boolean isAll() { return all; }
|
||||
public boolean isSelf() { return self; }
|
||||
public boolean isDepartment() { return department; }
|
||||
public Long getUserId() { return userId; }
|
||||
public Long getDeptId() { return deptId; }
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.bms.ar.security;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import org.springframework.stereotype.Component;
|
||||
import com.bms.ar.mapper.ArBillScopeMapper;
|
||||
import com.bms.common.constant.Constants;
|
||||
import com.bms.common.core.domain.entity.SysRole;
|
||||
import com.bms.common.core.domain.entity.SysUser;
|
||||
import com.bms.common.core.domain.model.LoginUser;
|
||||
import com.bms.common.exception.ServiceException;
|
||||
import com.bms.common.utils.PermissionContext;
|
||||
import com.bms.common.utils.SecurityUtils;
|
||||
import com.bms.customer.customerinfo.domain.BmsCustomerOption;
|
||||
|
||||
@Component
|
||||
public class ArBillScopeResolver {
|
||||
private final ArBillScopeMapper mapper;
|
||||
|
||||
public ArBillScopeResolver(ArBillScopeMapper mapper) {
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
/** 只读取登录态;功能上下文由 @ss.hasPermi 写入,缺失时不授权。 */
|
||||
public ArBillRowScope resolve() {
|
||||
return resolve(SecurityUtils.getLoginUser(), PermissionContext.get());
|
||||
}
|
||||
|
||||
public ArBillRowScope resolve(LoginUser actor, String permission) {
|
||||
if (actor == null || actor.getUser() == null || actor.getUserId() == null) {
|
||||
throw new ServiceException("登录状态无效,请重新登录", 401);
|
||||
}
|
||||
SysUser user = actor.getUser();
|
||||
if (!"0".equals(user.getStatus()) || !"0".equals(user.getDelFlag())) {
|
||||
return new ArBillRowScope(false, false, false, actor.getUserId(), actor.getDeptId());
|
||||
}
|
||||
if (user.isAdmin()) {
|
||||
return new ArBillRowScope(true, false, false, actor.getUserId(), actor.getDeptId());
|
||||
}
|
||||
boolean all = false;
|
||||
boolean self = false;
|
||||
boolean department = false;
|
||||
if (permission != null && !permission.isBlank() && user.getRoles() != null) {
|
||||
for (SysRole role : user.getRoles()) {
|
||||
if (role == null || !"0".equals(role.getStatus()) || !permits(role.getPermissions(), permission)) continue;
|
||||
String key = role.getRoleKey();
|
||||
all |= ArBillRoleKeys.ALL_DATA_ROLES.contains(key == null ? "" : key);
|
||||
self |= ArBillRoleKeys.SELF_DATA_ROLES.contains(key == null ? "" : key);
|
||||
department |= ArBillRoleKeys.SALES_MANAGER.equals(key);
|
||||
}
|
||||
}
|
||||
return new ArBillRowScope(all, self, department, actor.getUserId(), actor.getDeptId());
|
||||
}
|
||||
|
||||
private boolean permits(Set<String> permissions, String required) {
|
||||
return permissions != null && (permissions.contains(Constants.ALL_PERMISSION)
|
||||
|| Arrays.stream(required.split(Constants.PERMISSION_DELIMITER)).map(String::trim).anyMatch(permissions::contains));
|
||||
}
|
||||
|
||||
public void requireBillAccessible(Long arBillId) {
|
||||
ArBillRowScope scope = resolve();
|
||||
if (arBillId == null || withoutPagination(() -> mapper.countAccessibleBill(arBillId, scope)) == 0) {
|
||||
throw new ServiceException("账单不存在或无权访问");
|
||||
}
|
||||
}
|
||||
|
||||
public BmsCustomerOption requireCustomerAccessible(Long customerId) {
|
||||
ArBillRowScope scope = resolve();
|
||||
BmsCustomerOption customer = customerId == null ? null
|
||||
: withoutPagination(() -> mapper.selectAccessibleCustomer(customerId, scope));
|
||||
if (customer == null) throw new ServiceException("客户不存在或无权访问");
|
||||
return customer;
|
||||
}
|
||||
|
||||
public List<BmsCustomerOption> selectCustomerOptions(String keywords) {
|
||||
List<String> values = keywords == null ? List.of()
|
||||
: Arrays.stream(keywords.split("\\R")).map(String::trim).filter(s -> !s.isEmpty()).distinct().toList();
|
||||
return mapper.selectCustomerOptions(values, resolve());
|
||||
}
|
||||
|
||||
public void requireCustomerSourceBills(Long customerId, List<String> sourceIds) {
|
||||
if (!sourceIds.isEmpty() && withoutPagination(() -> mapper.countCustomerSourceBills(customerId, sourceIds)) != sourceIds.size()) {
|
||||
throw new ServiceException("所选订单不存在或不属于当前客户");
|
||||
}
|
||||
}
|
||||
|
||||
/** 资源预校验不能消耗 Controller 已设置的分页,最终业务查询仍使用原分页对象。 */
|
||||
private <T> T withoutPagination(Supplier<T> query) {
|
||||
Page<?> page = PageHelper.getLocalPage();
|
||||
PageHelper.clearPage();
|
||||
try {
|
||||
return query.get();
|
||||
} finally {
|
||||
if (page != null) PageHelper.setLocalPage(page);
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-2
@@ -23,6 +23,7 @@ import com.bms.ar.enums.ArLogOperationType;
|
||||
import com.bms.ar.enums.ArLogResult;
|
||||
import com.bms.ar.mapper.ArBalanceWriteoffMapper;
|
||||
import com.bms.ar.mapper.ArBillMapper;
|
||||
import com.bms.ar.security.ArBillScopeResolver;
|
||||
import com.bms.ar.service.IArBalanceWriteoffService;
|
||||
import com.bms.ar.service.IArBillLogService;
|
||||
import com.bms.common.exception.ServiceException;
|
||||
@@ -46,6 +47,8 @@ public class ArBalanceWriteoffServiceImpl implements IArBalanceWriteoffService {
|
||||
|
||||
@Autowired
|
||||
private ArBillMapper billMapper;
|
||||
@Autowired
|
||||
private ArBillScopeResolver billScope;
|
||||
|
||||
@Autowired
|
||||
private ArBalanceWriteoffMapper writeoffMapper;
|
||||
@@ -67,7 +70,7 @@ public class ArBalanceWriteoffServiceImpl implements IArBalanceWriteoffService {
|
||||
if (customerId == null) {
|
||||
return List.of();
|
||||
}
|
||||
return billMapper.selectUnsettledByCustomer(customerId);
|
||||
return billMapper.selectUnsettledByCustomer(customerId, billScope.resolve());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,7 +78,7 @@ public class ArBalanceWriteoffServiceImpl implements IArBalanceWriteoffService {
|
||||
*/
|
||||
@Override
|
||||
public List<ArBalanceWriteoff> selectWriteoffList(ArBalanceWriteoff query) {
|
||||
return writeoffMapper.selectWriteoffList(query);
|
||||
return writeoffMapper.selectWriteoffList(query, billScope.resolve());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,6 +106,7 @@ public class ArBalanceWriteoffServiceImpl implements IArBalanceWriteoffService {
|
||||
if (bill == null) {
|
||||
throw new ServiceException("应收账单不存在");
|
||||
}
|
||||
billScope.requireBillAccessible(bill.getArBillId());
|
||||
ArBillStatus status = ArBillStatus.of(bill.getStatus());
|
||||
if (status == null || !status.canWriteOff()) {
|
||||
throw new ServiceException("当前账单状态不允许核销:" + (status == null ? bill.getStatus() : status.getLabel()));
|
||||
@@ -170,6 +174,7 @@ public class ArBalanceWriteoffServiceImpl implements IArBalanceWriteoffService {
|
||||
if (writeoff == null) {
|
||||
throw new ServiceException("核销记录不存在");
|
||||
}
|
||||
billScope.requireBillAccessible(writeoff.getArBillId());
|
||||
if (!ArBalanceWriteoffStatus.EFFECTIVE.getCode().equals(writeoff.getStatus())) {
|
||||
throw new ServiceException("只有有效状态的核销记录可以反核销");
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.bms.ar.enums.ArLogOperationSource;
|
||||
import com.bms.ar.enums.ArLogOperationType;
|
||||
import com.bms.ar.enums.ArLogResult;
|
||||
import com.bms.ar.mapper.ArBillLogMapper;
|
||||
import com.bms.ar.security.ArBillScopeResolver;
|
||||
import com.bms.ar.service.IArBillLogService;
|
||||
import com.bms.common.utils.uuid.IdUtils;
|
||||
|
||||
@@ -19,10 +20,12 @@ import com.bms.common.utils.uuid.IdUtils;
|
||||
public class ArBillLogServiceImpl implements IArBillLogService {
|
||||
@Autowired
|
||||
private ArBillLogMapper logMapper;
|
||||
@Autowired
|
||||
private ArBillScopeResolver billScope;
|
||||
|
||||
@Override
|
||||
public List<ArBillLog> selectLogList(ArBillLog query) {
|
||||
return logMapper.selectList(query);
|
||||
return logMapper.selectList(query, billScope.resolve());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -70,6 +70,8 @@ import com.bms.ar.mapper.ArBillDetailMapper;
|
||||
import com.bms.ar.mapper.ArBillExportMapper;
|
||||
import com.bms.ar.mapper.ArBillLogMapper;
|
||||
import com.bms.ar.mapper.ArBillMapper;
|
||||
import com.bms.ar.security.ArBillScopeResolver;
|
||||
import com.bms.customer.customerinfo.domain.BmsCustomerOption;
|
||||
import com.bms.ar.mapper.ArBillGenerateTaskMapper;
|
||||
import com.bms.ar.mapper.ArBankAccountMapper;
|
||||
import com.bms.ar.mapper.ArExportTemplateMapper;
|
||||
@@ -182,6 +184,8 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
@Autowired
|
||||
private ArBillMapper billMapper;
|
||||
@Autowired
|
||||
private ArBillScopeResolver billScope;
|
||||
@Autowired
|
||||
private ArBillGenerateTaskMapper generateTaskMapper;
|
||||
@Autowired
|
||||
private ArBankAccountMapper bankAccountMapper;
|
||||
@@ -214,7 +218,8 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
@Override
|
||||
public List<ArBill> selectArBillList(ArBillQuery query) {
|
||||
long startedAt = System.nanoTime();
|
||||
List<ArBill> bills = billMapper.selectArBillList(query);
|
||||
query = query == null ? new ArBillQuery() : query;
|
||||
List<ArBill> bills = billMapper.selectArBillList(query, billScope.resolve());
|
||||
for (ArBill bill : bills) {
|
||||
bill.setBankAccountNo(maskAccount(bill.getBankAccountNo()));
|
||||
}
|
||||
@@ -229,7 +234,7 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
*/
|
||||
@Override
|
||||
public ArBillSummary selectArBillSummary(ArBillQuery query) {
|
||||
return billMapper.selectArBillSummary(query);
|
||||
return billMapper.selectArBillSummary(query == null ? new ArBillQuery() : query, billScope.resolve());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,9 +243,9 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
@Override
|
||||
public ArBill selectArBillById(Long arBillId) {
|
||||
long startedAt = System.nanoTime();
|
||||
ArBill bill = billMapper.selectArBillById(arBillId);
|
||||
ArBill bill = billMapper.selectArBillByIdScoped(arBillId, billScope.resolve());
|
||||
if (bill == null) {
|
||||
throw new ServiceException("应收账单不存在");
|
||||
throw new ServiceException("账单不存在或无权访问");
|
||||
}
|
||||
bill.setBankAccountNo(maskAccount(bill.getBankAccountNo()));
|
||||
bill.setExports(exportMapper.selectByBillId(arBillId));
|
||||
@@ -256,7 +261,7 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
@Override
|
||||
public List<ArBillDetail> selectArBillDetails(Long arBillId) {
|
||||
long startedAt = System.nanoTime();
|
||||
List<ArBillDetail> details = detailMapper.selectByBillId(arBillId);
|
||||
List<ArBillDetail> details = detailMapper.selectByBillIdScoped(arBillId, billScope.resolve());
|
||||
log.debug("应收账单明细查询完成,arBillId={}, resultCount={}, costMs={}",
|
||||
arBillId, details.size(), elapsedMillis(startedAt));
|
||||
return details;
|
||||
@@ -268,7 +273,7 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
@Override
|
||||
public List<ArBillDetailFee> selectArBillDetailFees(Long arBillId, Long detailId) {
|
||||
long startedAt = System.nanoTime();
|
||||
List<ArBillDetailFee> fees = detailFeeMapper.selectByBillIdAndDetailId(arBillId, detailId);
|
||||
List<ArBillDetailFee> fees = detailFeeMapper.selectByBillIdAndDetailIdScoped(arBillId, detailId, billScope.resolve());
|
||||
log.debug("应收账单费用明细查询完成,arBillId={}, detailId={}, resultCount={}, costMs={}",
|
||||
arBillId, detailId, fees.size(), elapsedMillis(startedAt));
|
||||
return fees;
|
||||
@@ -308,6 +313,8 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
public List<PrcOrderBill> previewBill(ArBillGenerateQuery query) {
|
||||
long startedAt = System.nanoTime();
|
||||
validatePreviewQuery(query);
|
||||
BmsCustomerOption customer = billScope.requireCustomerAccessible(query.getCustomerId());
|
||||
query.setCustomerCode(customer.getCustomerCode());
|
||||
List<String> orderIdentifiers = normalizeOrderIdentifiers(query.getOrderOrTrackingNo());
|
||||
List<String> excludeOrderIdentifiers = normalizeOrderIdentifiers(query.getExcludeOrderOrTrackingNo());
|
||||
List<PrcOrderBill> result = sourceBillMapper.selectPrcOrderBillByCustomerPeriod(query.getCustomerId(),
|
||||
@@ -336,6 +343,8 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
public BigDecimal sumPreviewBill(ArBillGenerateQuery query) {
|
||||
long startedAt = System.nanoTime();
|
||||
validatePreviewQuery(query);
|
||||
BmsCustomerOption customer = billScope.requireCustomerAccessible(query.getCustomerId());
|
||||
query.setCustomerCode(customer.getCustomerCode());
|
||||
List<String> orderIdentifiers = normalizeOrderIdentifiers(query.getOrderOrTrackingNo());
|
||||
List<String> excludeOrderIdentifiers = normalizeOrderIdentifiers(query.getExcludeOrderOrTrackingNo());
|
||||
BigDecimal total = nvl(sourceBillMapper.sumPrcOrderBillIncomeByCustomerPeriod(query.getCustomerId(),
|
||||
@@ -359,8 +368,12 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
long startedAt = System.nanoTime();
|
||||
Long createUserId = SecurityUtils.getUserId();
|
||||
validatePeriod(request);
|
||||
BmsCustomerOption customer = billScope.requireCustomerAccessible(request.getCustomerId());
|
||||
request.setCustomerCode(customer.getCustomerCode());
|
||||
request.setCustomerName(customer.getCustomerName());
|
||||
ArBillGenerateTask existed = generateTaskMapper.selectByRequestToken(requestId);
|
||||
if (existed != null) {
|
||||
billScope.requireBillAccessible(existed.getArBillId());
|
||||
log.info("应收账单生成请求命中幂等记录,operator={}, requestId={}, taskId={}, status={}, costMs={}",
|
||||
safeLogValue(operator), safeLogValue(requestId), existed.getTaskId(), existed.getStatus(),
|
||||
elapsedMillis(startedAt));
|
||||
@@ -401,6 +414,7 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
validateOrderIdentifierParameterCount(
|
||||
orderIdentifierCount,
|
||||
allMatched ? excludedSourceBillIds.size() : sourceBillIds.size());
|
||||
billScope.requireCustomerSourceBills(request.getCustomerId(), allMatched ? excludedSourceBillIds : sourceBillIds);
|
||||
request.setSelectionMode(selectionMode);
|
||||
|
||||
String currency = StringUtils.isEmpty(request.getCurrency()) ? "CNY" : request.getCurrency().trim();
|
||||
@@ -478,8 +492,9 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
long startedAt = System.nanoTime();
|
||||
ArBillGenerateTask task = generateTaskMapper.selectById(taskId);
|
||||
if (task == null) {
|
||||
throw new ServiceException("账单生成任务不存在");
|
||||
throw new ServiceException("账单不存在或无权访问");
|
||||
}
|
||||
billScope.requireBillAccessible(task.getArBillId());
|
||||
log.debug("应收账单生成任务状态查询,taskId={}, status={}, processedCount={}, totalCount={}, costMs={}",
|
||||
taskId, task.getStatus(), task.getProcessedCount(), task.getTotalCount(), elapsedMillis(startedAt));
|
||||
return task;
|
||||
@@ -491,7 +506,7 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
@Override
|
||||
public List<ArBillGenerateTask> selectActiveGenerateTasks(String operator) {
|
||||
long startedAt = System.nanoTime();
|
||||
List<ArBillGenerateTask> tasks = generateTaskMapper.selectActiveByCreateBy(operator);
|
||||
List<ArBillGenerateTask> tasks = generateTaskMapper.selectActiveByCreateByScoped(operator, billScope.resolve());
|
||||
log.debug("当前用户应收账单生成任务查询,operator={}, taskCount={}, costMs={}",
|
||||
safeLogValue(operator), tasks.size(), elapsedMillis(startedAt));
|
||||
return tasks;
|
||||
@@ -504,7 +519,9 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ArBillGenerateTask cancelGenerateTask(Long taskId, String operator, String requestId) {
|
||||
long startedAt = System.nanoTime();
|
||||
ArBillGenerateTask task = selectGenerateTask(taskId);
|
||||
ArBillGenerateTask task = generateTaskMapper.selectById(taskId);
|
||||
if (task == null) throw new ServiceException("账单不存在或无权访问");
|
||||
billScope.requireBillAccessible(task.getArBillId());
|
||||
if (!operator.equals(task.getCreateBy())) {
|
||||
throw new ServiceException("只能取消自己创建的账单生成任务");
|
||||
}
|
||||
@@ -533,7 +550,9 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ArBillGenerateTask retryGenerateTask(Long taskId, String operator, String requestId) {
|
||||
long startedAt = System.nanoTime();
|
||||
ArBillGenerateTask task = selectGenerateTask(taskId);
|
||||
ArBillGenerateTask task = generateTaskMapper.selectById(taskId);
|
||||
if (task == null) throw new ServiceException("账单不存在或无权访问");
|
||||
billScope.requireBillAccessible(task.getArBillId());
|
||||
if (!operator.equals(task.getCreateBy())) {
|
||||
throw new ServiceException("只能重新生成自己创建的账单任务");
|
||||
}
|
||||
@@ -923,6 +942,7 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
public ArBill confirmBill(Long arBillId, ArBillActionRequest request, String operator, String requestId) {
|
||||
long startedAt = System.nanoTime();
|
||||
ArBill bill = billMapper.selectArBillByIdForUpdate(arBillId);
|
||||
billScope.requireBillAccessible(arBillId);
|
||||
if (bill == null) {
|
||||
throw failure(arBillId, ArLogObjectType.BILL, String.valueOf(arBillId), ArLogOperationType.CONFIRM,
|
||||
null, "应收账单不存在", operator, requestId);
|
||||
@@ -972,6 +992,7 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
null, "作废必须填写原因", operator, requestId);
|
||||
}
|
||||
ArBill bill = billMapper.selectArBillByIdForUpdate(arBillId);
|
||||
billScope.requireBillAccessible(arBillId);
|
||||
if (bill == null) {
|
||||
throw failure(arBillId, ArLogObjectType.BILL, String.valueOf(arBillId), ArLogOperationType.VOID,
|
||||
null, "应收账单不存在", operator, requestId);
|
||||
@@ -1011,11 +1032,13 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
public ArBillExport exportBill(Long arBillId, String operator, String requestId) {
|
||||
long startedAt = System.nanoTime();
|
||||
Long exportUserId = SecurityUtils.getUserId();
|
||||
billScope.requireBillAccessible(arBillId);
|
||||
ArBillLog previous = logMapper.selectSuccessByRequestId(requestId, ArLogObjectType.EXPORT.getCode(),
|
||||
ArLogResult.SUCCESS.getCode());
|
||||
if (previous != null && isNumber(previous.getObjectId())) {
|
||||
ArBillExport previousExport = exportMapper.selectById(Long.valueOf(previous.getObjectId()));
|
||||
if (previousExport != null) {
|
||||
billScope.requireBillAccessible(previousExport.getArBillId());
|
||||
log.info("应收账单导出请求命中幂等记录,operator={}, requestId={}, arBillId={}, exportId={}, status={}, costMs={}",
|
||||
safeLogValue(operator), safeLogValue(requestId), arBillId, previousExport.getExportId(),
|
||||
previousExport.getExportStatus(), elapsedMillis(startedAt));
|
||||
@@ -1084,9 +1107,8 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
public ArBillExport selectExport(Long exportId) {
|
||||
long startedAt = System.nanoTime();
|
||||
ArBillExport export = exportMapper.selectById(exportId);
|
||||
if (export == null) {
|
||||
throw new ServiceException("导出任务不存在");
|
||||
}
|
||||
if (export == null) throw new ServiceException("账单不存在或无权访问");
|
||||
billScope.requireBillAccessible(export.getArBillId());
|
||||
log.debug("应收账单导出任务状态查询,exportId={}, status={}, costMs={}",
|
||||
exportId, export.getExportStatus(), elapsedMillis(startedAt));
|
||||
return export;
|
||||
@@ -1167,6 +1189,7 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
@Override
|
||||
public List<ArBillExport> selectExports(Long arBillId) {
|
||||
long startedAt = System.nanoTime();
|
||||
billScope.requireBillAccessible(arBillId);
|
||||
List<ArBillExport> exports = exportMapper.selectByBillId(arBillId);
|
||||
log.debug("应收账单导出记录查询,arBillId={}, exportCount={}, costMs={}",
|
||||
arBillId, exports.size(), elapsedMillis(startedAt));
|
||||
@@ -1177,7 +1200,11 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
public void downloadExport(Long exportId, HttpServletResponse response) throws Exception {
|
||||
long startedAt = System.nanoTime();
|
||||
ArBillExport export = exportMapper.selectById(exportId);
|
||||
if (export == null || !ArExportStatus.SUCCESS.getCode().equals(export.getExportStatus()) || StringUtils.isEmpty(export.getStorageKey())) {
|
||||
if (export == null) {
|
||||
throw new ServiceException("账单不存在或无权访问");
|
||||
}
|
||||
billScope.requireBillAccessible(export.getArBillId());
|
||||
if (!ArExportStatus.SUCCESS.getCode().equals(export.getExportStatus()) || StringUtils.isEmpty(export.getStorageKey())) {
|
||||
throw new ServiceException("导出文件不存在或尚未生成成功");
|
||||
}
|
||||
String resource = export.getStorageKey();
|
||||
|
||||
Reference in New Issue
Block a user