mirror of
https://github.com/hpd840321/starRiverProperty.git
synced 2026-06-10 17:00:30 +08:00
feat(elevator): 租户访客默认楼层策略表与 UC-01 求交
- 新增 tenant_visitor_floor_policy DDL(docs/sql) - MyBatis:TenantVisitorFloorPolicyMapper/Dao 按 businessId 读启用策略 - PersonRuleServiceImpl.addVisitor:未传 floorIds 时组织 floorList 与 allow_zone_ids 求交;无交集 76260532;无楼层 76260531;显式 floorIds 不读表;ServiceException 原样抛出 Made-with: Cursor
This commit is contained in:
+14
@@ -0,0 +1,14 @@
|
||||
package cn.cloudwalk.elevator.person.dao;
|
||||
|
||||
import cn.cloudwalk.elevator.person.dto.TenantVisitorFloorPolicyDto;
|
||||
|
||||
public interface TenantVisitorFloorPolicyDao {
|
||||
|
||||
/**
|
||||
* 查询租户级启用中的 INTERSECT_ALLOWLIST 策略(building_id 为空)。
|
||||
*
|
||||
* @param businessId 机构 ID
|
||||
* @return 无配置时 null
|
||||
*/
|
||||
TenantVisitorFloorPolicyDto selectEnabledTenantDefault(String businessId);
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package cn.cloudwalk.elevator.person.dto;
|
||||
|
||||
/**
|
||||
* 租户访客楼层策略(表 tenant_visitor_floor_policy 行映射)。
|
||||
*/
|
||||
public class TenantVisitorFloorPolicyDto {
|
||||
|
||||
private String id;
|
||||
private String businessId;
|
||||
private String policyType;
|
||||
private String allowZoneIds;
|
||||
private String buildingId;
|
||||
private Integer enabled;
|
||||
private Long policyVersion;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getBusinessId() {
|
||||
return businessId;
|
||||
}
|
||||
|
||||
public void setBusinessId(String businessId) {
|
||||
this.businessId = businessId;
|
||||
}
|
||||
|
||||
public String getPolicyType() {
|
||||
return policyType;
|
||||
}
|
||||
|
||||
public void setPolicyType(String policyType) {
|
||||
this.policyType = policyType;
|
||||
}
|
||||
|
||||
public String getAllowZoneIds() {
|
||||
return allowZoneIds;
|
||||
}
|
||||
|
||||
public void setAllowZoneIds(String allowZoneIds) {
|
||||
this.allowZoneIds = allowZoneIds;
|
||||
}
|
||||
|
||||
public String getBuildingId() {
|
||||
return buildingId;
|
||||
}
|
||||
|
||||
public void setBuildingId(String buildingId) {
|
||||
this.buildingId = buildingId;
|
||||
}
|
||||
|
||||
public Integer getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(Integer enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public Long getPolicyVersion() {
|
||||
return policyVersion;
|
||||
}
|
||||
|
||||
public void setPolicyVersion(Long policyVersion) {
|
||||
this.policyVersion = policyVersion;
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package cn.cloudwalk.elevator.person.impl;
|
||||
|
||||
import cn.cloudwalk.elevator.person.dao.TenantVisitorFloorPolicyDao;
|
||||
import cn.cloudwalk.elevator.person.dto.TenantVisitorFloorPolicyDto;
|
||||
import cn.cloudwalk.elevator.person.mapper.TenantVisitorFloorPolicyMapper;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public class TenantVisitorFloorPolicyDaoImpl implements TenantVisitorFloorPolicyDao {
|
||||
|
||||
@Resource
|
||||
private TenantVisitorFloorPolicyMapper tenantVisitorFloorPolicyMapper;
|
||||
|
||||
@Override
|
||||
public TenantVisitorFloorPolicyDto selectEnabledTenantDefault(String businessId) {
|
||||
return this.tenantVisitorFloorPolicyMapper.selectEnabledTenantDefault(businessId);
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package cn.cloudwalk.elevator.person.mapper;
|
||||
|
||||
import cn.cloudwalk.elevator.person.dto.TenantVisitorFloorPolicyDto;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
public interface TenantVisitorFloorPolicyMapper {
|
||||
|
||||
/**
|
||||
* 租户级默认策略:building_id 为空,启用,INTERSECT_ALLOWLIST。
|
||||
*/
|
||||
TenantVisitorFloorPolicyDto selectEnabledTenantDefault(@Param("businessId") String businessId);
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="cn.cloudwalk.elevator.person.mapper.TenantVisitorFloorPolicyMapper">
|
||||
|
||||
<select id="selectEnabledTenantDefault" resultType="cn.cloudwalk.elevator.person.dto.TenantVisitorFloorPolicyDto">
|
||||
SELECT id,
|
||||
business_id AS businessId,
|
||||
policy_type AS policyType,
|
||||
allow_zone_ids AS allowZoneIds,
|
||||
building_id AS buildingId,
|
||||
enabled AS enabled,
|
||||
policy_version AS policyVersion
|
||||
FROM tenant_visitor_floor_policy
|
||||
WHERE business_id = #{businessId,jdbcType=VARCHAR}
|
||||
AND enabled = 1
|
||||
AND policy_type = 'INTERSECT_ALLOWLIST'
|
||||
AND (building_id IS NULL OR building_id = '')
|
||||
ORDER BY updated_at DESC, policy_version DESC
|
||||
LIMIT 1
|
||||
</select>
|
||||
</mapper>
|
||||
+70
-2
@@ -29,6 +29,8 @@ import cn.cloudwalk.elevator.passrule.dto.ImageRuleRefAddDto;
|
||||
import cn.cloudwalk.elevator.passrule.dto.ImageRuleRefResultDto;
|
||||
import cn.cloudwalk.elevator.passrule.impl.AbstractAcsPassService;
|
||||
import cn.cloudwalk.elevator.passrule.result.AcsPassRuleResult;
|
||||
import cn.cloudwalk.elevator.person.dao.TenantVisitorFloorPolicyDao;
|
||||
import cn.cloudwalk.elevator.person.dto.TenantVisitorFloorPolicyDto;
|
||||
import cn.cloudwalk.elevator.person.param.AcsPersonAddParam;
|
||||
import cn.cloudwalk.elevator.person.param.AcsPersonAddVisitorParam;
|
||||
import cn.cloudwalk.elevator.person.param.AcsPersonDeleteParam;
|
||||
@@ -45,12 +47,16 @@ import cn.cloudwalk.elevator.util.StringUtils;
|
||||
import cn.cloudwalk.elevator.zone.param.ZoneQueryParam;
|
||||
import cn.cloudwalk.elevator.zone.result.ZoneResult;
|
||||
import cn.cloudwalk.elevator.zone.service.ZoneService;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -73,6 +79,8 @@ public class PersonRuleServiceImpl extends AbstractAcsPassService implements Per
|
||||
private AcsElevatorDeviceDao acsElevatorDeviceDao;
|
||||
@Resource
|
||||
private ZoneService zoneService;
|
||||
@Resource
|
||||
private TenantVisitorFloorPolicyDao tenantVisitorFloorPolicyDao;
|
||||
|
||||
@CloudwalkParamsValidate
|
||||
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
|
||||
@@ -167,12 +175,47 @@ public class PersonRuleServiceImpl extends AbstractAcsPassService implements Per
|
||||
this.logger.info("根据被访人添加访客派梯权限开始,AcsPersonAddVisitorParam=[{}], CloudwalkCallContext=[{}]",
|
||||
JSONObject.toJSONString(param), JSONObject.toJSONString(context));
|
||||
try {
|
||||
if (CollectionUtils.isEmpty(param.getFloorIds())) {
|
||||
boolean callerProvidedFloors = !CollectionUtils.isEmpty(param.getFloorIds());
|
||||
if (!callerProvidedFloors) {
|
||||
PersonDetailParam detailParam = new PersonDetailParam();
|
||||
detailParam.setId(param.getPersonId());
|
||||
detailParam.setBusinessId(context.getCompany().getCompanyId());
|
||||
CloudwalkResult<PersonResult> detail = this.personService.detail(detailParam, context);
|
||||
param.setFloorIds(((PersonResult)detail.getData()).getFloorList());
|
||||
if (detail == null || !detail.isSuccess()) {
|
||||
String code = detail != null ? detail.getCode() : "76260531";
|
||||
String msg = detail != null ? detail.getMessage() : getMessage("76260531");
|
||||
return CloudwalkResult.fail(code, msg);
|
||||
}
|
||||
PersonResult personResult = (PersonResult)detail.getData();
|
||||
if (personResult == null) {
|
||||
return CloudwalkResult.fail("76260531", getMessage("76260531"));
|
||||
}
|
||||
List<String> hostFloors = personResult.getFloorList();
|
||||
if (CollectionUtils.isEmpty(hostFloors)) {
|
||||
return CloudwalkResult.fail("76260531", getMessage("76260531"));
|
||||
}
|
||||
List<String> effectiveFloors = hostFloors;
|
||||
TenantVisitorFloorPolicyDto policy =
|
||||
this.tenantVisitorFloorPolicyDao.selectEnabledTenantDefault(context.getCompany().getCompanyId());
|
||||
if (policy != null && policy.getEnabled() != null && policy.getEnabled().intValue() == 1) {
|
||||
List<String> allow = parseAllowZoneIds(policy.getAllowZoneIds());
|
||||
if (!CollectionUtils.isEmpty(allow)) {
|
||||
Set<String> allowSet = new HashSet<>(allow);
|
||||
List<String> intersected = intersectPreserveHostOrder(hostFloors, allowSet);
|
||||
if (intersected.isEmpty()) {
|
||||
return CloudwalkResult.fail("76260532", getMessage("76260532"));
|
||||
}
|
||||
effectiveFloors = intersected;
|
||||
this.logger.info(
|
||||
"租户访客楼层策略求交 businessId={} personId={} visitorId={} policyId={} policyVersion={} effectiveSize={}",
|
||||
context.getCompany().getCompanyId(), param.getPersonId(), param.getVisitorId(),
|
||||
policy.getId(), policy.getPolicyVersion(), Integer.valueOf(intersected.size()));
|
||||
}
|
||||
}
|
||||
param.setFloorIds(effectiveFloors);
|
||||
}
|
||||
if (CollectionUtils.isEmpty(param.getFloorIds())) {
|
||||
return CloudwalkResult.fail("76260531", getMessage("76260531"));
|
||||
}
|
||||
ZoneQueryParam zoneQueryParam = new ZoneQueryParam();
|
||||
zoneQueryParam.setId(param.getFloorIds().get(0));
|
||||
@@ -221,6 +264,8 @@ public class PersonRuleServiceImpl extends AbstractAcsPassService implements Per
|
||||
refParam.setPersonIds(Collections.singletonList(param.getVisitorId()));
|
||||
refParam.setImageStoreId(imageStoreId);
|
||||
this.imageStorePersonService.updateGroupPersonRef(refParam, context);
|
||||
} catch (ServiceException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
this.logger.error("根据被访人添加访客派梯权限失败,原因:[{}]", e);
|
||||
throw new ServiceException("76260530", getMessage("76260530"));
|
||||
@@ -228,6 +273,29 @@ public class PersonRuleServiceImpl extends AbstractAcsPassService implements Per
|
||||
return CloudwalkResult.success(Boolean.valueOf(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析 allow_zone_ids JSON;无效或空则返回空列表(等同未配置有效策略)。
|
||||
*/
|
||||
private List<String> parseAllowZoneIds(String json) {
|
||||
if (StringUtils.isBlank(json)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
try {
|
||||
List<String> list = JSON.parseArray(json, String.class);
|
||||
if (list == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return list.stream().filter(Objects::nonNull).filter(s -> !s.isEmpty()).collect(Collectors.toList());
|
||||
} catch (Exception e) {
|
||||
this.logger.warn("allow_zone_ids JSON 无效,按无策略处理: {}", e.getMessage());
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> intersectPreserveHostOrder(List<String> hostFloors, Set<String> allowSet) {
|
||||
return hostFloors.stream().filter(allowSet::contains).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public CloudwalkResult<Boolean> edit(AcsPersonEditParam param, CloudwalkCallContext context)
|
||||
throws ServiceException {
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user