@@ -59,7 +59,6 @@ import com.hz.pm.api.user.security.model.UserFullInfoDTO; | |||
import com.hz.pm.api.user.security.model.UserInfoDetails; | |||
import com.hz.pm.api.user.util.LoginUserUtil; | |||
import com.ningdatech.basic.exception.BizException; | |||
import com.ningdatech.basic.function.VUtils; | |||
import com.ningdatech.basic.model.PageVo; | |||
import com.ningdatech.basic.util.CollUtils; | |||
import com.ningdatech.file.entity.File; | |||
@@ -74,7 +73,6 @@ import com.wflow.workflow.bean.process.ProcessComment; | |||
import com.wflow.workflow.bean.vo.ProcessDetailVO; | |||
import com.wflow.workflow.bean.vo.ProcessStartParamsVo; | |||
import com.wflow.workflow.service.ProcessInstanceService; | |||
import com.wflow.workflow.service.ProcessModelService; | |||
import lombok.AllArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.apache.commons.lang3.StringUtils; | |||
@@ -213,9 +211,7 @@ public class ProjectFileManage { | |||
} | |||
private List<Long> getSubOrgList(Long mhUnitId) { | |||
List<Long> childIds = mhUnitCache.getChildrenIdsRecursion(mhUnitId); | |||
childIds.add(mhUnitId); | |||
return childIds; | |||
return mhUnitCache.getViewChildIdsRecursion(mhUnitId); | |||
} | |||
public ProjectFileVO file(Long projectId) { | |||
@@ -24,7 +24,7 @@ import java.util.List; | |||
@Slf4j | |||
@Validated | |||
@RestController | |||
@Api("实施管理") | |||
@Api(tags = "实施管理") | |||
@RequestMapping("/api/v1/declared/operation") | |||
@RequiredArgsConstructor | |||
public class OperationController { | |||
@@ -10,7 +10,6 @@ import cn.hutool.json.JSONUtil; | |||
import com.alibaba.excel.EasyExcel; | |||
import com.baomidou.mybatisplus.core.conditions.Wrapper; | |||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction; | |||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | |||
@@ -133,8 +132,7 @@ public class PurchaseManage { | |||
query.exists(String.format("%s = '%s'", existsSql, user.getMhUnitIdStr())); | |||
break; | |||
case COMPANY_MANAGER: | |||
List<Long> childUnitIds = mhUnitCache.getChildrenIdsRecursion(user.getMhUnitId()); | |||
childUnitIds.add(user.getMhUnitId()); | |||
List<Long> childUnitIds = mhUnitCache.getViewChildIdsRecursion(user.getMhUnitId()); | |||
List<String> viewUnitIdList = CollUtils.convert(childUnitIds, String::valueOf); | |||
query.exists(String.format("%s in %s", existsSql, BizUtils.inSqlJoin(viewUnitIdList))); | |||
break; | |||
@@ -260,8 +260,7 @@ public class AnnualPlanLibManage { | |||
break; | |||
case COMPANY_MANAGER: | |||
// 单位管理员 看到自己单位去申报的 + 待预审的主管单位是自己单位的项目 | |||
List<Long> childUnitIds = mhUnitCache.getChildrenIdsRecursion(user.getMhUnitId()); | |||
childUnitIds.add(user.getMhUnitId()); | |||
List<Long> childUnitIds = mhUnitCache.getViewChildIdsRecursion(user.getMhUnitId()); | |||
List<String> viewUnitIdList = CollUtils.convert(childUnitIds, String::valueOf); | |||
query.in(Project::getBuildOrgCode, viewUnitIdList); | |||
break; | |||
@@ -121,25 +121,32 @@ public class DeclaredRecordManage { | |||
return query; | |||
} | |||
private boolean buildMhProjectLibPermission(LambdaQueryWrapper<MhProject> query, UserFullInfoDTO user) { | |||
private boolean buildMhProjectLibPermission(LambdaQueryWrapper<MhProject> query, UserFullInfoDTO user, Long declaredUnitId) { | |||
boolean queryState = true; | |||
Optional<DataScopeDTO> currentUserDataScope = DataScopeUtil.getCurrentUserDataScopeHasUserId(user); | |||
if (!currentUserDataScope.isPresent()) { | |||
log.warn("没有取到权限信息 当前查询 没有权限条件"); | |||
queryState = false; | |||
} else { | |||
List<Long> viewUnitIds = new ArrayList<>(); | |||
switch (currentUserDataScope.get().getRole()) { | |||
case NORMAL_MEMBER: | |||
//普通用户 只能看到自己单位去申报的 | |||
query.eq(MhProject::getUnitId, user.getMhUnitId()); | |||
viewUnitIds.add(user.getMhUnitId()); | |||
break; | |||
case COMPANY_MANAGER: | |||
List<Long> childUnitIds = mhUnitCache.getChildrenIdsRecursion(user.getMhUnitId()); | |||
childUnitIds.add(user.getMhUnitId()); | |||
List<Long> childUnitIds = mhUnitCache.getViewChildIdsRecursion(user.getMhUnitId()); | |||
if (declaredUnitId != null && childUnitIds.contains(declaredUnitId) | |||
&& !declaredUnitId.equals(user.getMhUnitId())) { | |||
childUnitIds = mhUnitCache.getViewChildIdsRecursion(declaredUnitId); | |||
} | |||
viewUnitIds.addAll(childUnitIds); | |||
//单位管理员 看到自己单位去申报的 + 待预审的主管单位是自己单位的项目 | |||
query.in(MhProject::getUnitId, childUnitIds); | |||
break; | |||
case SUPER_ADMIN: | |||
if (declaredUnitId != null) { | |||
viewUnitIds.addAll(mhUnitCache.getViewChildIdsRecursion(declaredUnitId)); | |||
} | |||
//超级管理员 看到丽水全市的 并且也要判断他 同时是不是单位管理员 | |||
break; | |||
case VISITOR: | |||
@@ -152,6 +159,9 @@ public class DeclaredRecordManage { | |||
queryState = false; | |||
break; | |||
} | |||
if (queryState) { | |||
query.in(MhProject::getUnitId, viewUnitIds); | |||
} | |||
} | |||
return queryState; | |||
} | |||
@@ -169,8 +179,7 @@ public class DeclaredRecordManage { | |||
query.eq(Project::getBuildOrgCode, user.getMhUnitIdStr()); | |||
break; | |||
case COMPANY_MANAGER: | |||
List<Long> childUnitIds = mhUnitCache.getChildrenIdsRecursion(user.getMhUnitId()); | |||
childUnitIds.add(user.getMhUnitId()); | |||
List<Long> childUnitIds = mhUnitCache.getViewChildIdsRecursion(user.getMhUnitId()); | |||
List<String> viewUnitIdList = CollUtils.convert(childUnitIds, String::valueOf); | |||
//单位管理员 看到自己单位去申报的 + 待预审的主管单位是自己单位的项目 | |||
query.in(Project::getBuildOrgCode, viewUnitIdList); | |||
@@ -204,7 +213,7 @@ public class DeclaredRecordManage { | |||
if (!buildProjectLibPermission(pQuery, user)) { | |||
return PageVo.empty(); | |||
} | |||
if (!buildMhProjectLibPermission(query, user)) { | |||
if (!buildMhProjectLibPermission(query, user, req.getDeclaredUnitId())) { | |||
return PageVo.empty(); | |||
} | |||
List<Project> projects = projectService.list(pQuery); | |||
@@ -11,6 +11,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | |||
import com.github.xiaoymin.knife4j.core.util.StrUtil; | |||
import com.google.common.collect.Lists; | |||
import com.google.common.collect.Maps; | |||
import com.hz.pm.api.common.compare.CompareUtils; | |||
@@ -1326,8 +1327,7 @@ public class ProjectLibManage { | |||
query.eq(Project::getBuildOrgCode, user.getMhUnitIdStr()); | |||
break; | |||
case COMPANY_MANAGER: | |||
List<Long> childUnitIds = mhUnitCache.getChildrenIdsRecursion(user.getMhUnitId()); | |||
childUnitIds.add(user.getMhUnitId()); | |||
List<Long> childUnitIds = mhUnitCache.getViewChildIdsRecursion(user.getMhUnitId()); | |||
List<String> viewUnitIdList = CollUtils.convert(childUnitIds, String::valueOf); | |||
//单位管理员 看到自己单位去申报的 + 待预审的主管单位是自己单位的项目 | |||
query.and(q1 -> q1.in(Project::getBuildOrgCode, viewUnitIdList) | |||
@@ -1366,9 +1366,16 @@ public class ProjectLibManage { | |||
req.setUserValue(user.getMhUnitIdStr()); | |||
break; | |||
case COMPANY_MANAGER: | |||
Long buildOrgCode = null; | |||
if (StrUtil.isNotBlank(req.getBuildOrgCode())) { | |||
buildOrgCode = Long.parseLong(req.getBuildOrgCode()); | |||
} | |||
//单位管理员 看到自己单位去申报的 + 待预审的主管单位是自己单位的项目 | |||
List<Long> childUnitIds = mhUnitCache.getChildrenIdsRecursion(user.getMhUnitId()); | |||
childUnitIds.add(user.getMhUnitId()); | |||
List<Long> childUnitIds = mhUnitCache.getViewChildIdsRecursion(user.getMhUnitId()); | |||
if (buildOrgCode != null && childUnitIds.contains(buildOrgCode) | |||
&& !buildOrgCode.equals(user.getMhUnitId())) { | |||
childUnitIds = mhUnitCache.getViewChildIdsRecursion(buildOrgCode); | |||
} | |||
String viewUnitIdStr = CollUtils.joinByComma(childUnitIds, w -> "'" + w + "'"); | |||
req.setUserType("org"); | |||
req.setUserValue(viewUnitIdStr); | |||
@@ -631,8 +631,7 @@ public class ProjectRenewalFundManage { | |||
case COMPANY_MANAGER: | |||
case SUPER_ADMIN: | |||
case REGION_MANAGER: | |||
List<Long> childUnitIds = mhUnitCache.getChildrenIdsRecursion(user.getMhUnitId()); | |||
childUnitIds.add(user.getMhUnitId()); | |||
List<Long> childUnitIds = mhUnitCache.getViewChildIdsRecursion(user.getMhUnitId()); | |||
String viewUnitIdStr = CollUtils.joinByComma(childUnitIds, w -> "'" + w + "'"); | |||
//单位管理员 看到自己单位去申报的 + 待预审的主管单位是自己单位的项目 | |||
//超级管理员 也只能看本单位的 | |||
@@ -18,10 +18,10 @@ import java.util.Optional; | |||
@AllArgsConstructor | |||
public enum TenderAdaptStatusEnum { | |||
WITHOUT_ADAPT_INFO(100, "待填写适配改造信息"), | |||
ADAPT_INFO_AUDIT(101, "适配改造信息审核中"), | |||
ADAPT_INFO_FAILED(102, "适配改造信息审核失败"), | |||
ADAPT_INFO_PASSED(103, "适配改造信息审核通过"); | |||
WITHOUT_ADAPT_INFO(2100, "待填写适配改造信息"), | |||
ADAPT_INFO_AUDIT(2101, "适配改造信息审核中"), | |||
ADAPT_INFO_FAILED(2102, "适配改造信息审核失败"), | |||
ADAPT_INFO_PASSED(2103, "适配改造信息审核通过"); | |||
private final Integer code; | |||
private final String val; | |||
@@ -18,10 +18,10 @@ import java.util.Optional; | |||
@AllArgsConstructor | |||
public enum TenderSelfTestStatusEnum { | |||
WITHOUT_SELF_TEST_INFO(100, "待填写系统自测信息"), | |||
SELF_TEST_INFO_AUDIT(101, "系统自测信息审核中"), | |||
SELF_TEST_INFO_FAILED(102, "系统自测信息审核失败"), | |||
SELF_TEST_INFO_PASSED(103, "系统自测信息审核通过"); | |||
WITHOUT_SELF_TEST_INFO(1100, "待填写系统自测信息"), | |||
SELF_TEST_INFO_AUDIT(1101, "系统自测信息审核中"), | |||
SELF_TEST_INFO_FAILED(1102, "系统自测信息审核失败"), | |||
SELF_TEST_INFO_PASSED(1103, "系统自测信息审核通过"); | |||
private final Integer code; | |||
private final String val; | |||
@@ -18,10 +18,10 @@ import java.util.Optional; | |||
@AllArgsConstructor | |||
public enum TenderTestValidStatusEnum { | |||
WITHOUT_TEST_VALID_INFO(100, "待填写测试验证信息"), | |||
TEST_VALID_INFO_AUDIT(101, "测试验证信息审核中"), | |||
TEST_VALID_INFO_FAILED(102, "测试验证信息审核失败"), | |||
TEST_VALID_INFO_PASSED(103, "测试验证信息审核通过"); | |||
WITHOUT_TEST_VALID_INFO(3100, "待填写测试验证信息"), | |||
TEST_VALID_INFO_AUDIT(3101, "测试验证信息审核中"), | |||
TEST_VALID_INFO_FAILED(3102, "测试验证信息审核失败"), | |||
TEST_VALID_INFO_PASSED(3103, "测试验证信息审核通过"); | |||
private final Integer code; | |||
private final String val; | |||
@@ -25,10 +25,12 @@ public interface MhUnitCache { | |||
List<UnitDTO> getChildren(Long id); | |||
List<Long> getChildrenIds(Long id); | |||
List<Long> getChildIds(Long id); | |||
List<UnitDTO> getChildrenRecursion(Long id); | |||
List<Long> getChildrenIdsRecursion(Long id); | |||
List<Long> getChildIdsRecursion(Long id); | |||
List<Long> getViewChildIdsRecursion(Long id); | |||
} |
@@ -120,23 +120,30 @@ public class MhUnitCacheImpl implements MhUnitCache, InitializingBean { | |||
} | |||
@Override | |||
public List<Long> getChildrenIds(Long id) { | |||
public List<Long> getChildIds(Long id) { | |||
return childIdMap.get(id); | |||
} | |||
@Override | |||
public List<UnitDTO> getChildrenRecursion(Long id) { | |||
return CollUtils.convert(getChildrenIdsRecursion(id), cache::get); | |||
return CollUtils.convert(getChildIdsRecursion(id), cache::get); | |||
} | |||
@Override | |||
public List<Long> getChildrenIdsRecursion(Long id) { | |||
public List<Long> getChildIdsRecursion(Long id) { | |||
List<Long> childIds = new ArrayList<>(); | |||
collectChildId(childIds, id); | |||
return childIds; | |||
} | |||
@Override | |||
public List<Long> getViewChildIdsRecursion(Long id) { | |||
List<Long> childIds = getChildIdsRecursion(id); | |||
childIds.add(id); | |||
return childIds; | |||
} | |||
@Override | |||
public List<Long> getUnitIdPaths(Long unitId) { | |||
Assert.notNull(unitId, "单位ID不能为空"); | |||
List<Long> nodeIdPaths = new ArrayList<>(); | |||
@@ -132,9 +132,8 @@ public class MhUnitManage { | |||
Set<Long> viewUnitIds = new HashSet<>(); | |||
boolean hasId = req.getId() != null; | |||
if (hasId) { | |||
List<Long> childIds = mhUnitCache.getChildrenIdsRecursion(req.getId()); | |||
List<Long> childIds = mhUnitCache.getViewChildIdsRecursion(req.getId()); | |||
viewUnitIds.addAll(childIds); | |||
viewUnitIds.add(req.getId()); | |||
} | |||
boolean hasName = CharSequenceUtil.isNotBlank(req.getName()); | |||
LambdaQueryWrapper<UserInfo> userQuery = Wrappers.lambdaQuery(UserInfo.class) | |||
@@ -157,7 +157,7 @@ public class WorkbenchManage { | |||
.select(Project::getReviewAmount, Project::getApprovalGovOwnFinanceAmount, Project::getId) | |||
.eq(Project::getProjectYear, projectYear) | |||
.eq(Project::getNewest, Boolean.TRUE); | |||
List<Long> viewUnitIds = mhUnitCache.getChildrenIdsRecursion(unitId); | |||
List<Long> viewUnitIds = mhUnitCache.getChildIdsRecursion(unitId); | |||
viewUnitIds.add(unitId); | |||
query.in(Project::getBuildOrgCode, CollUtils.convert(viewUnitIds, String::valueOf)); | |||
List<Project> projects = projectService.list(query); | |||
@@ -8,7 +8,6 @@ import com.hz.pm.api.common.util.CryptUtils; | |||
import com.hz.pm.api.common.util.HmacAuthUtil; | |||
import com.hz.pm.api.common.util.RefreshKeyUtil; | |||
import com.ningdatech.zwdd.ZwddIntegrationProperties; | |||
import com.ningdatech.zwdd.client.ZwddAuthClient; | |||
import com.ningdatech.zwdd.client.ZwddClient; | |||
import com.ningdatech.zwdd.client.provider.ZwddAuthClientProvider; | |||
import org.apache.http.client.methods.CloseableHttpResponse; | |||
@@ -38,12 +37,7 @@ import java.util.Objects; | |||
public class IrsTest extends AppTests { | |||
@Autowired | |||
private ZwddAuthClient zwddAuthClient; | |||
@Autowired | |||
private ZwddClient zwddClient; | |||
@Autowired | |||
private AppIrsManage appIrsManage; | |||
@Test | |||
public void test1() { | |||
@@ -77,7 +71,7 @@ public class IrsTest extends AppTests { | |||
String appKey = "A331101453557202109017383"; | |||
String appCode = "A331123467587202307014177";//A331123467587202307014171 | |||
String requestSecret = RefreshKeyUtil.getRequestSecret(appKey, appScret,timestamp); | |||
String requestSecret = RefreshKeyUtil.getRequestSecret(appKey, appScret, timestamp); | |||
String sign = CryptUtils.MD5Encode(appKey + requestSecret + timestamp); | |||
String url = "https://interface.zjzwfw.gov.cn/gateway/api/001003001029/dataSharing/XS8daav3bcemZ3Ra.htm?" + | |||
"requestTime=" + timestamp + "&sign=" + sign + "&appKey=" + appKey + "&name=&" + | |||
@@ -98,7 +92,7 @@ public class IrsTest extends AppTests { | |||
String baseProjSysCode = "A331123467587202307014177"; | |||
String baseProjName = "遂昌县-nsl-项目测试004"; | |||
String baseProjId = "331123230130123412186"; | |||
String requestSecret = RefreshKeyUtil.getRequestSecret(appKey, appScret,timestamp); | |||
String requestSecret = RefreshKeyUtil.getRequestSecret(appKey, appScret, timestamp); | |||
String capCode = CryptUtils.MD5Encode(timestamp + areaCode); | |||
String capTime = String.valueOf(timestamp); | |||
@@ -5,12 +5,12 @@ import com.alibaba.fastjson.JSON; | |||
import com.alibaba.fastjson.JSONObject; | |||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; | |||
import com.google.common.collect.Lists; | |||
import com.ningdatech.basic.model.GenericResult; | |||
import com.hz.pm.api.AppTests; | |||
import com.hz.pm.api.ding.model.DingOrgInfoTreeDTO; | |||
import com.hz.pm.api.ding.task.GovBusinessStripsTask; | |||
import com.hz.pm.api.organization.model.entity.DingOrganization; | |||
import com.hz.pm.api.organization.service.IDingOrganizationService; | |||
import com.ningdatech.basic.model.GenericResult; | |||
import com.ningdatech.zwdd.client.ZwddClient; | |||
import com.ningdatech.zwdd.model.dto.*; | |||
import lombok.extern.slf4j.Slf4j; | |||
@@ -28,12 +28,6 @@ import java.util.stream.Collectors; | |||
class OrganizationTest extends AppTests { | |||
@Autowired | |||
private OrganizationBatchGetTask organizationBatchGetTask; | |||
@Autowired | |||
private EmployeeBatchGetTask employeeBatchGetTask; | |||
@Autowired | |||
private GovBusinessStripsTask govBusinessStripsTask; | |||
@Autowired | |||
@@ -45,16 +39,6 @@ class OrganizationTest extends AppTests { | |||
private static final Integer GROUP_SIZE = 100; | |||
@Test | |||
public void testBatchGetOrganization() { | |||
organizationBatchGetTask.batchGetOrganizationTask(); | |||
} | |||
@Test | |||
public void testEmployeeBatchGetTask() { | |||
employeeBatchGetTask.batchGetEmployeeTask(); | |||
} | |||
@Test | |||
public void testGovBusinessStripsTask() { | |||
govBusinessStripsTask.batchGetGovBusinessStripsTask(); | |||
} | |||
@@ -102,7 +86,7 @@ class OrganizationTest extends AppTests { | |||
treeDTOList.add(childDingOrgInfoTreeDTO); | |||
if (CollectionUtils.isNotEmpty(treeDTOList)) { | |||
List<DingOrganization> saveRecordList = new ArrayList<>(); | |||
buildSaveRecordList(treeDTOList, saveRecordList,currentAllOrganizationList); | |||
buildSaveRecordList(treeDTOList, saveRecordList, currentAllOrganizationList); | |||
// 批量保存 | |||
if (saveRecordList.size() <= GROUP_SIZE) { | |||
organizationService.saveOrUpdateBatch(saveRecordList); | |||
@@ -162,9 +146,9 @@ class OrganizationTest extends AppTests { | |||
private void buildSaveRecordList(List<DingOrgInfoTreeDTO> treeDTOList, List<DingOrganization> saveRecordList, | |||
List<DingOrganization> oldList) { | |||
Set<String> set = new HashSet(); | |||
Map<String,DingOrganization> map = oldList.stream() | |||
Map<String, DingOrganization> map = oldList.stream() | |||
.filter(o -> set.add(o.getOrganizationCode())) | |||
.collect(Collectors.toMap(DingOrganization::getOrganizationCode,o -> o)); | |||
.collect(Collectors.toMap(DingOrganization::getOrganizationCode, o -> o)); | |||
if (CollectionUtils.isEmpty(treeDTOList)) { | |||
return; | |||
} | |||
@@ -172,27 +156,25 @@ class OrganizationTest extends AppTests { | |||
DingOrganization saveRecord = new DingOrganization(); | |||
DingOrgInfoDTO dingOrgInfoDTO = dingOrgInfoTreeDTO.getDingOrgInfoDTO(); | |||
List<DingOrgInfoTreeDTO> childCodes = dingOrgInfoTreeDTO.getChildCodes(); | |||
if(map.containsKey(dingOrgInfoDTO.getOrganizationCode())) { | |||
if (map.containsKey(dingOrgInfoDTO.getOrganizationCode())) { | |||
DingOrganization organization = map.get(dingOrgInfoDTO.getOrganizationCode()); | |||
saveRecord.setId(organization.getId()); | |||
if (CollectionUtils.isNotEmpty(childCodes)) { | |||
buildSaveRecordList(childCodes, saveRecordList,oldList); | |||
buildSaveRecordList(childCodes, saveRecordList, oldList); | |||
} | |||
continue; | |||
} | |||
saveRecord.setDisplayOrder(dingOrgInfoDTO.getDisplayOrder()); | |||
// saveRecord.setEnabled("1"); | |||
saveRecord.setParentCode(dingOrgInfoDTO.getParentCode()); | |||
saveRecord.setTypeCode(dingOrgInfoDTO.getTypeCode()); | |||
saveRecord.setTypeName(dingOrgInfoDTO.getTypeName()); | |||
saveRecord.setOrganizationCode(dingOrgInfoDTO.getOrganizationCode()); | |||
// saveRecord.setSubCount((long) dingOrgInfoTreeDTO.getChildCodes().size()); | |||
saveRecord.setOrganizationName(dingOrgInfoDTO.getOrganizationName()); | |||
saveRecord.setDivisionCode(dingOrgInfoDTO.getDivisionCode()); | |||
saveRecordList.add(saveRecord); | |||
if (CollectionUtils.isNotEmpty(childCodes)) { | |||
buildSaveRecordList(childCodes, saveRecordList,oldList); | |||
buildSaveRecordList(childCodes, saveRecordList, oldList); | |||
} | |||
} | |||
} | |||