merge ervu-backend/release/ervu/1.9.11

This commit is contained in:
Халтобин Евгений 2025-04-09 09:40:41 +03:00
parent 1ce2361347
commit 4f6c16b5c7
50 changed files with 12221 additions and 934 deletions

8
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,8 @@
---
variables:
DEPLOY_TEMPLATES_VERSION: v1
include:
- project: ervu/devops/ci-cd-templates
ref: v1
file: pipelines/container-helm-kubernetes-dev.yml

57
Dockerfile Normal file
View file

@ -0,0 +1,57 @@
ARG BUILDER_IMAGE=registry.gosuslugi.local/ervu-uat/micord-deps:1.9.11
ARG RUNTIME_IMAGE=registry.gosuslugi.local/os/altlinux@sha256:fd478a99adab9e195d652f78d0c90638de83f6f605fd7254f6241e594054f0f2
FROM $BUILDER_IMAGE AS builder
ARG MVN_FLAGS="-T4C -Pprod -DexecuteNpmInstall=false --batch-mode --no-transfer-progress"
RUN apt-get update \
&& apt-get -y install git glibc-locales java-17-openjdk-devel maven node \
&& apt-get clean
ENV JAVA_HOME=/usr/lib/jvm/java
ENV LANG ru_RU.UTF-8
ENV LANGUAGE ru_RU.UTF-8
ENV LC_ALL ru_RU.UTF-8
WORKDIR /app
COPY . .
RUN mkdir -p /root/.m2 \
&& cp config/uat/settings.xml /root/.m2/settings.xml
RUN mvn clean ${MVN_FLAGS} \
&& mvn package ${MVN_FLAGS}
FROM $RUNTIME_IMAGE
COPY --from=builder /usr/lib/locale/ru_RU /usr/lib/locale/ru_RU
COPY --from=builder /usr/lib/locale/ru_RU.utf8 /usr/lib/locale/ru_RU.utf8
COPY --from=builder /usr/share/locale/ru_RU /usr/share/locale/ru_RU
COPY config/entrypoint.sh /entrypoint.sh
RUN apt-get update \
&& apt-get -y install fonts-ttf-ms java-17-openjdk-headless tomcat tomcat-webapps tomcat-admin-webapps \
&& apt-get clean \
&& rm -f /var/cache/apt/*.bin \
&& rm -f /var/lib/apt/lists/update* \
&& chmod +x /entrypoint.sh
ENV JAVA_HOME=/usr/lib/jvm/java
ENV LANG=ru_RU.UTF-8
ENV LANGUAGE=ru_RU.UTF-8
ENV LC_ALL=ru_RU.UTF-8
COPY config/tomcat /
RUN cat /etc/tomcat/webbpm.properties >> /etc/tomcat/catalina.properties \
&& chown -R tomcat:tomcat /var/lib/tomcat/webapps
COPY --from=builder /app/backend/target/account-applications.war /var/lib/tomcat/webapps/account-applications.war
USER tomcat
EXPOSE 8080
ENTRYPOINT ["/entrypoint.sh"]

63
Dockerfile.pgs2 Normal file
View file

@ -0,0 +1,63 @@
ARG BUILDER_IMAGE=registry-dev.pgs.rtlabs.ru/ervu/micord-deps:0.0.1-shaeb3853d5
ARG RUNTIME_IMAGE=registry-dev.pgs.rtlabs.ru/basealt/altsp:c10f1
FROM $BUILDER_IMAGE AS builder
ARG MVN_FLAGS="-T4C -Pprod -DexecuteNpmInstall=false --batch-mode --no-transfer-progress"
RUN rm -f /etc/apt/sources.list.d/* \
&& echo "rpm http://nexus-dev.pgs.rtlabs.ru repository/alt-c10f1-classic/x86_64 classic" > /etc/apt/sources.list \
&& echo "rpm http://nexus-dev.pgs.rtlabs.ru repository/alt-c10f1-classic/noarch classic" >> /etc/apt/sources.list \
&& apt-get update \
&& apt-get -y install git glibc-locales java-17-openjdk-devel maven node \
&& apt-get clean
ENV JAVA_HOME=/usr/lib/jvm/java
ENV LANG ru_RU.UTF-8
ENV LANGUAGE ru_RU.UTF-8
ENV LC_ALL ru_RU.UTF-8
WORKDIR /app
COPY . .
RUN mkdir -p /root/.m2 \
&& cp config/settings.xml /root/.m2/settings.xml
RUN mvn clean ${MVN_FLAGS} \
&& mvn package ${MVN_FLAGS}
FROM $RUNTIME_IMAGE
COPY --from=builder /usr/lib/locale/ru_RU /usr/lib/locale/ru_RU
COPY --from=builder /usr/lib/locale/ru_RU.utf8 /usr/lib/locale/ru_RU.utf8
COPY --from=builder /usr/share/locale/ru_RU /usr/share/locale/ru_RU
COPY config/entrypoint.sh /entrypoint.sh
RUN rm -f /etc/apt/sources.list.d/* \
&& echo "rpm http://nexus-dev.pgs.rtlabs.ru repository/alt-c10f1-classic/x86_64 classic" > /etc/apt/sources.list \
&& echo "rpm http://nexus-dev.pgs.rtlabs.ru repository/alt-c10f1-classic/noarch classic" >> /etc/apt/sources.list \
&& apt-get update \
&& apt-get -y install fonts-ttf-ms java-17-openjdk-headless tomcat tomcat-webapps \
&& apt-get clean \
&& rm -f /var/cache/apt/*.bin \
&& rm -f /var/lib/apt/lists/update* \
&& chmod +x /entrypoint.sh
ENV JAVA_HOME=/usr/lib/jvm/java
ENV LANG=ru_RU.UTF-8
ENV LANGUAGE=ru_RU.UTF-8
ENV LC_ALL=ru_RU.UTF-8
COPY config/tomcat /
RUN cat /etc/tomcat/webbpm.properties >> /etc/tomcat/catalina.properties \
&& chown -R tomcat:tomcat /var/lib/tomcat/webapps
COPY --from=builder /app/backend/target/account-applications.war /var/lib/tomcat/webapps/account-applications.war
USER tomcat
EXPOSE 8080
ENTRYPOINT ["/entrypoint.sh"]

View file

@ -188,6 +188,14 @@
<groupId>net.javacrumbs.shedlock</groupId> <groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-jdbc-template</artifactId> <artifactId>shedlock-provider-jdbc-template</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId> <artifactId>log4j-slf4j2-impl</artifactId>

View file

@ -1,4 +1,11 @@
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.time.Duration; import java.time.Duration;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.sql.DataSource; import javax.sql.DataSource;
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature;
@ -9,6 +16,10 @@ import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
import net.javacrumbs.shedlock.spring.ScheduledLockConfiguration; import net.javacrumbs.shedlock.spring.ScheduledLockConfiguration;
import net.javacrumbs.shedlock.spring.ScheduledLockConfigurationBuilder; import net.javacrumbs.shedlock.spring.ScheduledLockConfigurationBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
@ -16,6 +27,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.FilterType;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.retry.annotation.EnableRetry; import org.springframework.retry.annotation.EnableRetry;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@ -50,6 +62,7 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@EnableScheduling @EnableScheduling
@EnableRetry @EnableRetry
public class AppConfig { public class AppConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(AppConfig.class);
@Bean @Bean
public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){ public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){
@ -83,7 +96,37 @@ public class AppConfig {
@Bean @Bean
public RestTemplate restTemplate() { public RestTemplate restTemplate() {
return new RestTemplate(); CloseableHttpClient httpClient = HttpClients.custom()
.setSSLContext(sslContext())
.build();
RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
return restTemplate;
}
@Bean
public SSLContext sslContext() {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
}
};
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new SecureRandom());
}
catch (NoSuchAlgorithmException | KeyManagementException e) {
LOGGER.error("Failed to init SSL context", e);
}
return sslContext;
} }
@Bean @Bean

View file

@ -27,6 +27,7 @@ public class EnumColumnFormatter implements Formatter {
strObjectToStringMapping.put("EDIT_USER_ACCOUNT", "Изменение учетной записи пользователя"); strObjectToStringMapping.put("EDIT_USER_ACCOUNT", "Изменение учетной записи пользователя");
strObjectToStringMapping.put("EDIT_USER_ROLES", "Изменение ролей пользователя"); strObjectToStringMapping.put("EDIT_USER_ROLES", "Изменение ролей пользователя");
strObjectToStringMapping.put("BLOCK_USER", "Деактивация пользователя"); strObjectToStringMapping.put("BLOCK_USER", "Деактивация пользователя");
strObjectToStringMapping.put("UNBLOCK_USER", "Активация пользователя");
strObjectToStringMapping.put("RESET_PASSWORD", "Сброс пароля пользователя"); strObjectToStringMapping.put("RESET_PASSWORD", "Сброс пароля пользователя");
strObjectToStringMapping.put("MALE", "Мужской"); strObjectToStringMapping.put("MALE", "Мужской");
strObjectToStringMapping.put("FEMALE", "Женский"); strObjectToStringMapping.put("FEMALE", "Женский");

View file

@ -57,6 +57,12 @@ public class RecruitmentDao {
.orderBy(DSL.field(DSL.name("recruitment_hierarchy", "depth")).asc()) .orderBy(DSL.field(DSL.name("recruitment_hierarchy", "depth")).asc())
.fetchInto(String.class); .fetchInto(String.class);
} }
public List<String> getAllRecruitmentIds() {
return dslContext.select(Recruitment.RECRUITMENT.IDM_ID)
.from(Recruitment.RECRUITMENT)
.fetch(Recruitment.RECRUITMENT.IDM_ID);
}
} }

View file

@ -26,6 +26,8 @@ import ru.micord.ervu.account_applications.component.model.dto.GridServiceReques
import ru.micord.ervu.account_applications.component.model.dto.GridServiceResponse; import ru.micord.ervu.account_applications.component.model.dto.GridServiceResponse;
import ru.micord.ervu.account_applications.component.model.User; import ru.micord.ervu.account_applications.component.model.User;
import ru.micord.ervu.account_applications.security.context.SecurityContext; import ru.micord.ervu.account_applications.security.context.SecurityContext;
import ru.micord.ervu.account_applications.security.model.jwt.UserSession;
import ru.micord.ervu.account_applications.security.model.role.ErvuRoleAuthority;
import ru.micord.ervu.account_applications.service.constant.PathConstant; import ru.micord.ervu.account_applications.service.constant.PathConstant;
import ru.micord.ervu.account_applications.util.StringUtils; import ru.micord.ervu.account_applications.util.StringUtils;
import service.GridService; import service.GridService;
@ -44,6 +46,8 @@ public class ErvuUserGridLoadService extends Behavior implements GridService {
private int httpTimeout; private int httpTimeout;
@Value("${idm.url}") @Value("${idm.url}")
private String idmUrl; private String idmUrl;
@Value("${ervu.role.admin:#{null}}")
private String ervuAdminRole;
public ErvuUserGridLoadService(ObjectMapper objectMapper, public ErvuUserGridLoadService(ObjectMapper objectMapper,
SecurityContext securityContext) { SecurityContext securityContext) {
@ -124,8 +128,12 @@ public class ErvuUserGridLoadService extends Behavior implements GridService {
private GridServiceRequest createLoadServiceRequest(Integer offset, Integer limit, Filter[] filters) { private GridServiceRequest createLoadServiceRequest(Integer offset, Integer limit, Filter[] filters) {
int page = (offset / limit) + 1; int page = (offset / limit) + 1;
Map<String, Object> filterMap = new HashMap<>(); Map<String, Object> filterMap = new HashMap<>();
UserSession userSession = securityContext.getUserSession();
Set<ErvuRoleAuthority> roles = userSession.roles();
if (ervuAdminRole == null || roles.stream().noneMatch(role -> role.getAuthority().equals(
ervuAdminRole))) {
filterMap.put("domainId", securityContext.getDomainId()); filterMap.put("domainId", securityContext.getDomainId());
}
if (filters != null && filters.length > 0) { if (filters != null && filters.length > 0) {
filterMap.putAll(Arrays.stream(filters) filterMap.putAll(Arrays.stream(filters)
.filter(filter -> filter.getFilterModels() != null && filter.getFilterModels().length > 0) .filter(filter -> filter.getFilterModels() != null && filter.getFilterModels().length > 0)
@ -136,7 +144,6 @@ public class ErvuUserGridLoadService extends Behavior implements GridService {
)) ))
); );
} }
return new GridServiceRequest(filterMap, page, limit); return new GridServiceRequest(filterMap, page, limit);
} }

View file

@ -4,13 +4,17 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import component.field.persist.filter.FilterControl; import component.field.persist.filter.FilterControl;
import model.Filter; import model.Filter;
import model.grid.GridRows; import model.grid.GridRows;
import model.grid.SortInfo; import model.grid.SortInfo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.micord.ervu.account_applications.component.dao.RecruitmentDao; import ru.micord.ervu.account_applications.component.dao.RecruitmentDao;
import ru.micord.ervu.account_applications.security.model.jwt.UserSession;
import ru.micord.ervu.account_applications.security.model.role.ErvuRoleAuthority;
import service.GridV2ServiceImpl; import service.GridV2ServiceImpl;
import ru.cg.webbpm.modules.database.api.dao.option.LoadOptions; import ru.cg.webbpm.modules.database.api.dao.option.LoadOptions;
@ -35,6 +39,8 @@ public class RecruitmentGridService extends GridV2ServiceImpl {
@LocalGraphSource(sourceFieldName = "loadDao") @LocalGraphSource(sourceFieldName = "loadDao")
@NotNull @NotNull
public EntityColumn recruitmentColumn; public EntityColumn recruitmentColumn;
@Value("${ervu.role.admin:security_administrator}")
private String ervuAdminRole;
public RecruitmentGridService(RecruitmentDao recruitmentDao, SecurityContext securityContext) { public RecruitmentGridService(RecruitmentDao recruitmentDao, SecurityContext securityContext) {
this.recruitmentDao = recruitmentDao; this.recruitmentDao = recruitmentDao;
@ -43,13 +49,22 @@ public class RecruitmentGridService extends GridV2ServiceImpl {
@Override @Override
public GridRows loadData(Integer offset, Integer limit, Filter[] filters, SortInfo[] sortInfos) { public GridRows loadData(Integer offset, Integer limit, Filter[] filters, SortInfo[] sortInfos) {
UserSession userSession = securityContext.getUserSession();
Set<ErvuRoleAuthority> roles = userSession.roles();
List<String> recruitmentIds;
List<Filter> updatedFilters = new ArrayList<>(Arrays.asList(filters)); List<Filter> updatedFilters = new ArrayList<>(Arrays.asList(filters));
Optional<Filter> recruitmentFilterOpt = findRecruitmentFilter(updatedFilters); Optional<Filter> recruitmentFilterOpt = findRecruitmentFilter(updatedFilters);
if (ervuAdminRole != null && roles.stream().anyMatch(role -> role.getAuthority().equals(
List<String> recruitmentIds = recruitmentFilterOpt.map( ervuAdminRole))) {
recruitmentIds = recruitmentFilterOpt.map(
filter -> getChildRecruitmentIds(updatedFilters, filter))
.orElseGet(this::getAllRecruitmentIds);
}
else {
recruitmentIds = recruitmentFilterOpt.map(
filter -> getChildRecruitmentIds(updatedFilters, filter)) filter -> getChildRecruitmentIds(updatedFilters, filter))
.orElseGet(this::getRecruitmentIdsForCurrentUser); .orElseGet(this::getRecruitmentIdsForCurrentUser);
}
LoadOptions options = getOptions(offset, limit, updatedFilters.toArray(new Filter[0]), LoadOptions options = getOptions(offset, limit, updatedFilters.toArray(new Filter[0]),
sortInfos sortInfos
); );
@ -78,5 +93,8 @@ public class RecruitmentGridService extends GridV2ServiceImpl {
private EntityFilter getEntityFilterForRecruitmentIds(List<String> recruitmentIds) { private EntityFilter getEntityFilterForRecruitmentIds(List<String> recruitmentIds) {
return new EntityFilter(recruitmentIds, FilterOperation.IN, this.recruitmentColumn); return new EntityFilter(recruitmentIds, FilterOperation.IN, this.recruitmentColumn);
} }
}
private List<String> getAllRecruitmentIds() {
return recruitmentDao.getAllRecruitmentIds();
}
}

View file

@ -4,10 +4,13 @@ import java.util.*;
import database.dao.DefaultLoadDao; import database.dao.DefaultLoadDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.micord.ervu.account_applications.component.model.TreeItemDto; import ru.micord.ervu.account_applications.component.model.TreeItemDto;
import ru.micord.ervu.account_applications.component.rpc.TreeItemRpcService; import ru.micord.ervu.account_applications.component.rpc.TreeItemRpcService;
import ru.micord.ervu.account_applications.security.context.SecurityContext; import ru.micord.ervu.account_applications.security.context.SecurityContext;
import ru.micord.ervu.account_applications.security.model.jwt.UserSession;
import ru.micord.ervu.account_applications.security.model.role.ErvuRoleAuthority;
import ru.cg.webbpm.modules.database.api.bean.TableRow; import ru.cg.webbpm.modules.database.api.bean.TableRow;
import ru.cg.webbpm.modules.database.api.dao.option.LoadOptions; import ru.cg.webbpm.modules.database.api.dao.option.LoadOptions;
@ -39,6 +42,8 @@ public class TreeItemService {
public EntityColumn businessIdColumn; public EntityColumn businessIdColumn;
@GraphSource(value = TreeItemRpcService.class, scanMode = GraphSource.ScanMode.SELF) @GraphSource(value = TreeItemRpcService.class, scanMode = GraphSource.ScanMode.SELF)
public EntityColumn domainIdColumn; public EntityColumn domainIdColumn;
@Value("${ervu.role.admin:security_administrator}")
private String ervuAdminRole;
public TreeItemService(SecurityContext securityContext) { public TreeItemService(SecurityContext securityContext) {
this.securityContext = securityContext; this.securityContext = securityContext;
@ -46,9 +51,15 @@ public class TreeItemService {
public List<TreeItemDto> loadTreeData() { public List<TreeItemDto> loadTreeData() {
String domainId = securityContext.getDomainId(); String domainId = securityContext.getDomainId();
List<TreeItemDto> filteredTreeItems = loadTreeItems().stream() UserSession userSession = securityContext.getUserSession();
Set<ErvuRoleAuthority> roles = userSession.roles();
List<TreeItemDto> filteredTreeItems = loadTreeItems();
if (ervuAdminRole == null || roles.stream().noneMatch(role -> role.getAuthority().equals(
ervuAdminRole))) {
filteredTreeItems = filteredTreeItems.stream()
.filter(item -> item.domainId.equalsIgnoreCase(domainId)) .filter(item -> item.domainId.equalsIgnoreCase(domainId))
.toList(); .toList();
}
filteredTreeItems.forEach(this::setDomainIdToNull); filteredTreeItems.forEach(this::setDomainIdToNull);
return filteredTreeItems; return filteredTreeItems;
} }

View file

@ -32,9 +32,9 @@ import ru.micord.ervu.account_applications.dto.Person;
import ru.micord.ervu.account_applications.dto.ProcessResponse; import ru.micord.ervu.account_applications.dto.ProcessResponse;
import ru.micord.ervu.account_applications.dto.Role; import ru.micord.ervu.account_applications.dto.Role;
import ru.micord.ervu.account_applications.dto.Roles; import ru.micord.ervu.account_applications.dto.Roles;
import ru.micord.ervu.account_applications.dto.deactivate.DeactivateData; import ru.micord.ervu.account_applications.dto.activation.ChangeActivationData;
import ru.micord.ervu.account_applications.dto.deactivate.DeactivateDto; import ru.micord.ervu.account_applications.dto.activation.ChangeActivationDto;
import ru.micord.ervu.account_applications.dto.deactivate.DeactivateProcessRequest; import ru.micord.ervu.account_applications.dto.activation.ChangeActivationProcessRequest;
import ru.micord.ervu.account_applications.dto.edit.EditAccountDto; import ru.micord.ervu.account_applications.dto.edit.EditAccountDto;
import ru.micord.ervu.account_applications.dto.edit.EditData; import ru.micord.ervu.account_applications.dto.edit.EditData;
import ru.micord.ervu.account_applications.dto.edit.EditRolesDto; import ru.micord.ervu.account_applications.dto.edit.EditRolesDto;
@ -44,11 +44,12 @@ import ru.micord.ervu.account_applications.dto.password.ResetPasswordData;
import ru.micord.ervu.account_applications.dto.password.ResetPasswordDto; import ru.micord.ervu.account_applications.dto.password.ResetPasswordDto;
import ru.micord.ervu.account_applications.dto.password.ResetPasswordProcessRequest; import ru.micord.ervu.account_applications.dto.password.ResetPasswordProcessRequest;
import ru.micord.ervu.account_applications.dto.password.UserIdInfo; import ru.micord.ervu.account_applications.dto.password.UserIdInfo;
import ru.micord.ervu.account_applications.enums.ProcessKey;
import ru.micord.ervu.account_applications.security.context.SecurityContext; import ru.micord.ervu.account_applications.security.context.SecurityContext;
import ru.micord.ervu.account_applications.service.RoleServiceImpl; import ru.micord.ervu.account_applications.service.RoleServiceImpl;
import ru.micord.ervu.account_applications.service.UserApplicationListService; import ru.micord.ervu.account_applications.service.UserApplicationListService;
import static ru.micord.ervu.account_applications.enums.ProcessKey.*;
/** /**
* @author gulnaz * @author gulnaz
*/ */
@ -86,7 +87,7 @@ public class AdminController {
.collect(Collectors.toList()); .collect(Collectors.toList());
Roles roles = new Roles(rolesList); Roles roles = new Roles(rolesList);
CreateProcessRequest request = new CreateProcessRequest( CreateProcessRequest request = new CreateProcessRequest(
ProcessKey.CREATE.getValue(), getUserId(), new CreateData(credential, account, person, roles)); CREATE.getValue(), getUserId(), new CreateData(credential, account, person, roles));
return doRequestAndSaveTraceId(request, dto.appNumber()); return doRequestAndSaveTraceId(request, dto.appNumber());
} }
@ -94,7 +95,7 @@ public class AdminController {
public ResponseEntity<?> editPerson(@RequestBody @Valid EditPersonDto dto) { public ResponseEntity<?> editPerson(@RequestBody @Valid EditPersonDto dto) {
Person person = new Person(dto.id(), dto.surname(), dto.firstname(), dto.middlename(), dto.sex(), Person person = new Person(dto.id(), dto.surname(), dto.firstname(), dto.middlename(), dto.sex(),
dto.email(), dto.birthdate(), dto.snils(), dto.ipAddresses()); dto.email(), dto.birthdate(), dto.snils(), dto.ipAddresses());
EditPersonProcessRequest request = new EditPersonProcessRequest(ProcessKey.EDIT_PERSON.getValue(), EditPersonProcessRequest request = new EditPersonProcessRequest(EDIT_PERSON.getValue(),
getUserId(), new EditData(dto.accountId(), person)); getUserId(), new EditData(dto.accountId(), person));
return doRequestAndSaveTraceId(request, dto.appNumber()); return doRequestAndSaveTraceId(request, dto.appNumber());
} }
@ -102,7 +103,7 @@ public class AdminController {
@PostMapping(value = "/account", consumes = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = "/account", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> editAccount(@RequestBody @Valid EditAccountDto dto) { public ResponseEntity<?> editAccount(@RequestBody @Valid EditAccountDto dto) {
Account account = new Account(dto.accountId(), dto.userDomain(), dto.position()); Account account = new Account(dto.accountId(), dto.userDomain(), dto.position());
EditPersonProcessRequest request = new EditPersonProcessRequest(ProcessKey.EDIT_ACCOUNT.getValue(), EditPersonProcessRequest request = new EditPersonProcessRequest(EDIT_ACCOUNT.getValue(),
getUserId(), new EditData(account)); getUserId(), new EditData(account));
return doRequestAndSaveTraceId(request, dto.appNumber()); return doRequestAndSaveTraceId(request, dto.appNumber());
} }
@ -116,15 +117,22 @@ public class AdminController {
List<String> removedRoleIds = roleService.fetchRemovedRoleIds(dto.accountId(), dto.roles()); List<String> removedRoleIds = roleService.fetchRemovedRoleIds(dto.accountId(), dto.roles());
Account account = new Account(dto.accountId(), removedRoleIds, rolesList); Account account = new Account(dto.accountId(), removedRoleIds, rolesList);
EditPersonProcessRequest request = new EditPersonProcessRequest(ProcessKey.EDIT_ROLES.getValue(), EditPersonProcessRequest request = new EditPersonProcessRequest(EDIT_ROLES.getValue(),
getUserId(), new EditData(account)); getUserId(), new EditData(account));
return doRequestAndSaveTraceId(request, dto.appNumber()); return doRequestAndSaveTraceId(request, dto.appNumber());
} }
@PostMapping(value = "/deactivation", consumes = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = "/deactivation", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> deactivate(@RequestBody @Valid DeactivateDto dto) { public ResponseEntity<?> deactivate(@RequestBody @Valid ChangeActivationDto dto) {
DeactivateProcessRequest request = new DeactivateProcessRequest(ProcessKey.DEACTIVATE.getValue(), ChangeActivationProcessRequest request = new ChangeActivationProcessRequest(DEACTIVATE.getValue(),
getUserId(), new DeactivateData(Collections.singletonList(dto.accountId()))); getUserId(), new ChangeActivationData(Collections.singletonList(dto.accountId())));
return doRequestAndSaveTraceId(request, dto.appNumber());
}
@PostMapping(value = "/activation", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> activate(@RequestBody @Valid ChangeActivationDto dto) {
ChangeActivationProcessRequest request = new ChangeActivationProcessRequest(ACTIVATE.getValue(),
getUserId(), new ChangeActivationData(Collections.singletonList(dto.accountId())));
return doRequestAndSaveTraceId(request, dto.appNumber()); return doRequestAndSaveTraceId(request, dto.appNumber());
} }
@ -139,7 +147,7 @@ public class AdminController {
UserIdInfo userIdInfo = new UserIdInfo(dto.accountId()); UserIdInfo userIdInfo = new UserIdInfo(dto.accountId());
ResetPasswordData resetPasswordData = new ResetPasswordData(userIdInfo); ResetPasswordData resetPasswordData = new ResetPasswordData(userIdInfo);
ResetPasswordProcessRequest request = new ResetPasswordProcessRequest( ResetPasswordProcessRequest request = new ResetPasswordProcessRequest(
ProcessKey.RESET_PASSWORD.getValue(), RESET_PASSWORD.getValue(),
getUserId(), resetPasswordData getUserId(), resetPasswordData
); );
return doRequestAndSaveTraceId(request, dto.appNumber()); return doRequestAndSaveTraceId(request, dto.appNumber());

View file

@ -89,6 +89,11 @@ public class UserApplicationRole extends TableImpl<UserApplicationRoleRecord> {
*/ */
public final TableField<UserApplicationRoleRecord, Timestamp> FINISHED = createField(DSL.name("finished"), SQLDataType.TIMESTAMP(0), this, "Дата и время окончания действия роли"); public final TableField<UserApplicationRoleRecord, Timestamp> FINISHED = createField(DSL.name("finished"), SQLDataType.TIMESTAMP(0), this, "Дата и время окончания действия роли");
/**
* The column <code>public.user_application_role.role_code</code>. Код роли
*/
public final TableField<UserApplicationRoleRecord, String> ROLE_CODE = createField(DSL.name("role_code"), SQLDataType.VARCHAR, this, "Код роли");
private UserApplicationRole(Name alias, Table<UserApplicationRoleRecord> aliased) { private UserApplicationRole(Name alias, Table<UserApplicationRoleRecord> aliased) {
this(alias, aliased, (Field<?>[]) null, null); this(alias, aliased, (Field<?>[]) null, null);
} }

View file

@ -100,6 +100,20 @@ public class UserApplicationRoleRecord extends UpdatableRecordImpl<UserApplicati
return (Timestamp) get(4); return (Timestamp) get(4);
} }
/**
* Setter for <code>public.user_application_role.role_code</code>. Код роли
*/
public void setRoleCode(String value) {
set(5, value);
}
/**
* Getter for <code>public.user_application_role.role_code</code>. Код роли
*/
public String getRoleCode() {
return (String) get(5);
}
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Primary key information // Primary key information
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@ -123,7 +137,7 @@ public class UserApplicationRoleRecord extends UpdatableRecordImpl<UserApplicati
/** /**
* Create a detached, initialised UserApplicationRoleRecord * Create a detached, initialised UserApplicationRoleRecord
*/ */
public UserApplicationRoleRecord(String userRoleId, String roleName, Timestamp created, Timestamp updated, Timestamp finished) { public UserApplicationRoleRecord(String userRoleId, String roleName, Timestamp created, Timestamp updated, Timestamp finished, String roleCode) {
super(UserApplicationRole.USER_APPLICATION_ROLE); super(UserApplicationRole.USER_APPLICATION_ROLE);
setUserRoleId(userRoleId); setUserRoleId(userRoleId);
@ -131,6 +145,7 @@ public class UserApplicationRoleRecord extends UpdatableRecordImpl<UserApplicati
setCreated(created); setCreated(created);
setUpdated(updated); setUpdated(updated);
setFinished(finished); setFinished(finished);
setRoleCode(roleCode);
resetChangedOnNotNull(); resetChangedOnNotNull();
} }
} }

View file

@ -0,0 +1,9 @@
package ru.micord.ervu.account_applications.dto.activation;
import java.util.List;
/**
* @author gulnaz
*/
public record ChangeActivationData(List<String> accountIdList) {
}

View file

@ -0,0 +1,12 @@
package ru.micord.ervu.account_applications.dto.activation;
import javax.validation.constraints.NotNull;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* @author gulnaz
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public record ChangeActivationDto(@NotNull long appNumber, @NotNull String accountId) {
}

View file

@ -0,0 +1,13 @@
package ru.micord.ervu.account_applications.dto.activation;
import ru.micord.ervu.account_applications.dto.ProcessRequest;
/**
* @author gulnaz
*/
public class ChangeActivationProcessRequest extends ProcessRequest<ChangeActivationData> {
public ChangeActivationProcessRequest(String processKey, String userId, ChangeActivationData data) {
super(processKey, userId, data);
}
}

View file

@ -5,9 +5,9 @@ import ru.micord.ervu.account_applications.dto.ProcessRequest;
/** /**
* @author Adel Kalimullin * @author Adel Kalimullin
*/ */
public class ResetPasswordProcessRequest extends ProcessRequest { public class ResetPasswordProcessRequest extends ProcessRequest<ResetPasswordData> {
public ResetPasswordProcessRequest(String processKey, String userId, Object data) { public ResetPasswordProcessRequest(String processKey, String userId, ResetPasswordData data) {
super(processKey, userId, data); super(processKey, userId, data);
} }
} }

View file

@ -9,6 +9,7 @@ public enum ProcessKey {
EDIT_ACCOUNT("milBaseEditAccountIDMProcess"), EDIT_ACCOUNT("milBaseEditAccountIDMProcess"),
EDIT_ROLES("milBaseEditAccountRolesIDMSubProcess"), EDIT_ROLES("milBaseEditAccountRolesIDMSubProcess"),
DEACTIVATE("milBaseMassDeActivateAccountIDMProcess"), DEACTIVATE("milBaseMassDeActivateAccountIDMProcess"),
ACTIVATE("milBaseMassActivateAccountIDMProcess"),
RESET_PASSWORD("milBaseResetPasswordProcess"); RESET_PASSWORD("milBaseResetPasswordProcess");
private final String value; private final String value;

View file

@ -26,6 +26,8 @@ public class RoleResponse {
private Long createDate; private Long createDate;
private Long modified; private Long modified;
private Long finish; private Long finish;
private String name;
private Boolean ervuRole;
public String getId() { public String getId() {
return id; return id;
@ -66,5 +68,22 @@ public class RoleResponse {
public void setFinish(Long finish) { public void setFinish(Long finish) {
this.finish = finish; this.finish = finish;
} }
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getErvuRole() {
return ervuRole;
}
public void setErvuRole(Boolean ervuRole) {
this.ervuRole = ervuRole;
}
} }
} }

View file

@ -13,7 +13,6 @@ import com.google.common.net.HttpHeaders;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
/** /**
* @author Adel Kalimullin * @author Adel Kalimullin
*/ */

View file

@ -27,6 +27,9 @@ import ru.cg.webbpm.modules.standard_annotations.editor.ObjectRef;
@Service @Service
public class AccountServiceImpl extends AbstractUserDataService { public class AccountServiceImpl extends AbstractUserDataService {
private static final String FIELD_SEX = "sex";
private static final String FIELD_IP_ADDRESSES = "ipAddresses";
private static final String FIELD_SNILS = "snils";
@ObjectRef @ObjectRef
public EditableGridColumn editableGridColumnRef; public EditableGridColumn editableGridColumnRef;
@ -67,12 +70,23 @@ public class AccountServiceImpl extends AbstractUserDataService {
if (value == null || (value instanceof String string && string.isEmpty())) { if (value == null || (value instanceof String string && string.isEmpty())) {
continue; continue;
} }
if ("ipAddresses".equals(field.getName())) {
List<?> ipList = (List<?>) value; if (FIELD_SEX.equals(field.getName()) && value instanceof String sex) {
if (ipList != null && !ipList.isEmpty()) { map.put(field.getName(), sex.toLowerCase());
continue;
}
if (FIELD_SNILS.equals(field.getName()) && value instanceof String snils) {
map.put(field.getName(), formatSnils(snils));
continue;
}
if (FIELD_IP_ADDRESSES.equals(field.getName()) && value instanceof List<?> ipList
&& !ipList.isEmpty()) {
map.put(field.getName(), convertIpAddressesToGridRows(ipList)); map.put(field.getName(), convertIpAddressesToGridRows(ipList));
continue;
} }
}
if (isSimple(value.getClass())) { if (isSimple(value.getClass())) {
map.put(field.getName(), value); map.put(field.getName(), value);
} }
@ -104,4 +118,20 @@ public class AccountServiceImpl extends AbstractUserDataService {
private boolean isSimple(Class<?> type) { private boolean isSimple(Class<?> type) {
return ClassUtils.isPrimitiveOrWrapper(type) || type == String.class; return ClassUtils.isPrimitiveOrWrapper(type) || type == String.class;
} }
private String formatSnils(String snils) {
if (snils == null) {
return null;
}
String number = snils.replaceAll("\\D", "");
if (number.length() != 11) {
throw new IllegalArgumentException("Некорректный формат СНИЛС: " + number);
}
return number.substring(0, 3) + "-" +
number.substring(3, 6) + "-" +
number.substring(6, 9) + " " +
number.substring(9);
}
} }

View file

@ -25,12 +25,12 @@ public class ErvuDirectoriesDaoService {
return ervuDirectoriesDao.getRoleIds(); return ervuDirectoriesDao.getRoleIds();
} }
@Cacheable(value = "domain-ids", unless = "#result == null") // @Cacheable(value = "domain-ids", unless = "#result == null")
public Result<Record2<UUID, String>> getDomainIds() { public Result<Record2<UUID, String>> getDomainIds() {
return ervuDirectoriesDao.getDomainIds(); return ervuDirectoriesDao.getDomainIds();
} }
@Cacheable(value = "role-ids", unless = "#result == null") // @Cacheable(value = "role-ids", unless = "#result == null")
public UserApplicationRoleRecord getRoleRecord() { public UserApplicationRoleRecord getRoleRecord() {
return ervuDirectoriesDao.getRoleRecord(); return ervuDirectoriesDao.getRoleRecord();
} }

View file

@ -10,6 +10,7 @@ import java.util.UUID;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.jooq.DSLContext;
import org.jooq.Record2; import org.jooq.Record2;
import org.jooq.Result; import org.jooq.Result;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -32,6 +33,7 @@ import ru.micord.ervu.account_applications.model.RecruitmentResponse;
import ru.micord.ervu.account_applications.model.RoleResponse; import ru.micord.ervu.account_applications.model.RoleResponse;
import static ru.micord.ervu.account_applications.db_beans.public_.tables.Recruitment.RECRUITMENT; import static ru.micord.ervu.account_applications.db_beans.public_.tables.Recruitment.RECRUITMENT;
import static ru.micord.ervu.account_applications.db_beans.public_.tables.UserApplicationRole.USER_APPLICATION_ROLE;
/** /**
* @author Eduard Tihomirov * @author Eduard Tihomirov
@ -41,8 +43,8 @@ import static ru.micord.ervu.account_applications.db_beans.public_.tables.Recrui
public class ErvuDirectoriesService { public class ErvuDirectoriesService {
private static final Logger LOGGER = LoggerFactory.getLogger( private static final Logger LOGGER = LoggerFactory.getLogger(
MethodHandles.lookup().lookupClass()); MethodHandles.lookup().lookupClass());
@Value("${ervu.url}") @Value("${idm.url}")
private String ervuUrl; private String idmUrl;
@Value("${ervu.collection:domain, role}") @Value("${ervu.collection:domain, role}")
private String ervuCollection; private String ervuCollection;
@Autowired @Autowired
@ -51,17 +53,20 @@ public class ErvuDirectoriesService {
private ObjectMapper objectMapper; private ObjectMapper objectMapper;
@Autowired @Autowired
private ErvuDirectoriesDaoService ervuDirectoriesDaoService; private ErvuDirectoriesDaoService ervuDirectoriesDaoService;
@Autowired
private DSLContext dsl;
Result<Record2<UUID, String>> domainIds = null;
List<String> roleIds = null;
@Caching(evict = {
@CacheEvict(value = "domain-ids", allEntries = true),
@CacheEvict(value = "role-ids", allEntries = true)
})
public void updateDirectories() { public void updateDirectories() {
try { try {
initIds();
String[] ervuCollectionArray = ervuCollection.split(","); String[] ervuCollectionArray = ervuCollection.split(",");
Arrays.stream(ervuCollectionArray).forEach(ervuCollection -> { Arrays.stream(ervuCollectionArray).forEach(ervuCollection -> {
String targetUrl = ervuUrl + "/service/idm/reconcile/"+ ervuCollection + "/to/kafka/v1"; String targetUrl = idmUrl + "/reconcile/"+ ervuCollection + "/to/kafka/v1";
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON); headers.setContentType(MediaType.APPLICATION_JSON);
String emptyJson = "{}"; String emptyJson = "{}";
@ -92,6 +97,9 @@ public class ErvuDirectoriesService {
throw new RuntimeException("Error with parsing domain kafka message", e); throw new RuntimeException("Error with parsing domain kafka message", e);
} }
if (response.length > 0 && response[0].getData() != null && !response[0].getData().isEmpty()) { if (response.length > 0 && response[0].getData() != null && !response[0].getData().isEmpty()) {
if (domainIds == null) {
initIds();
}
upsertRecruitmentData(response[0].getData()); upsertRecruitmentData(response[0].getData());
} }
} }
@ -106,6 +114,9 @@ public class ErvuDirectoriesService {
throw new RuntimeException("Error with parsing role kafka message", e); throw new RuntimeException("Error with parsing role kafka message", e);
} }
if (response.length > 0 && response[0].getData() != null && !response[0].getData().isEmpty()) { if (response.length > 0 && response[0].getData() != null && !response[0].getData().isEmpty()) {
if (roleIds == null) {
initIds();
}
upsertRoleData(response[0].getData()); upsertRoleData(response[0].getData());
} }
} }
@ -113,7 +124,7 @@ public class ErvuDirectoriesService {
private void upsertRecruitmentData(List<RecruitmentResponse.Data> dataList) { private void upsertRecruitmentData(List<RecruitmentResponse.Data> dataList) {
List<RecruitmentRecord> newRecruitmentRecords = new ArrayList<>(); List<RecruitmentRecord> newRecruitmentRecords = new ArrayList<>();
List<RecruitmentRecord> recruitmentRecords = new ArrayList<>(); List<RecruitmentRecord> recruitmentRecords = new ArrayList<>();
Result<Record2<UUID, String>> ids = ervuDirectoriesDaoService.getDomainIds(); Result<Record2<UUID, String>> ids = domainIds;
dataList.forEach(data -> { dataList.forEach(data -> {
Timestamp updatedAt = Timestamp.from(Instant.ofEpochSecond(data.getModified())); Timestamp updatedAt = Timestamp.from(Instant.ofEpochSecond(data.getModified()));
Timestamp createdAt = Timestamp.from(Instant.ofEpochSecond(data.getCreateDate())); Timestamp createdAt = Timestamp.from(Instant.ofEpochSecond(data.getCreateDate()));
@ -172,8 +183,11 @@ public class ErvuDirectoriesService {
private void upsertRoleData(List<RoleResponse.Data> dataList) { private void upsertRoleData(List<RoleResponse.Data> dataList) {
List<UserApplicationRoleRecord> newRoleRecords = new ArrayList<>(); List<UserApplicationRoleRecord> newRoleRecords = new ArrayList<>();
List<UserApplicationRoleRecord> roleRecords = new ArrayList<>(); List<UserApplicationRoleRecord> roleRecords = new ArrayList<>();
List<String> ids = ervuDirectoriesDaoService.getRoleIds(); List<String> ids = roleIds;
dataList.forEach(data -> { dataList.forEach(data -> {
if (data.getErvuRole() == null || !data.getErvuRole()) {
return;
}
Timestamp updatedAt = Timestamp.from(Instant.ofEpochSecond(data.getModified())); Timestamp updatedAt = Timestamp.from(Instant.ofEpochSecond(data.getModified()));
Timestamp createdAt = Timestamp.from(Instant.ofEpochSecond(data.getCreateDate())); Timestamp createdAt = Timestamp.from(Instant.ofEpochSecond(data.getCreateDate()));
Timestamp finishAt = null; Timestamp finishAt = null;
@ -182,6 +196,7 @@ public class ErvuDirectoriesService {
} }
UserApplicationRoleRecord roleRecord = ervuDirectoriesDaoService.getRoleRecord(); UserApplicationRoleRecord roleRecord = ervuDirectoriesDaoService.getRoleRecord();
roleRecord.setUserRoleId(data.getId()); roleRecord.setUserRoleId(data.getId());
roleRecord.setRoleCode(data.getName());
roleRecord.setRoleName(data.getDisplayName()); roleRecord.setRoleName(data.getDisplayName());
roleRecord.setCreated(createdAt); roleRecord.setCreated(createdAt);
roleRecord.setUpdated(updatedAt); roleRecord.setUpdated(updatedAt);
@ -196,4 +211,14 @@ public class ErvuDirectoriesService {
ervuDirectoriesDaoService.insertRoleRecords(newRoleRecords); ervuDirectoriesDaoService.insertRoleRecords(newRoleRecords);
ervuDirectoriesDaoService.updateRoleRecords(roleRecords); ervuDirectoriesDaoService.updateRoleRecords(roleRecords);
} }
private void initIds() {
domainIds = dsl.select(RECRUITMENT.ID, RECRUITMENT.IDM_ID)
.from(RECRUITMENT)
.fetch();
roleIds = dsl.select(USER_APPLICATION_ROLE.USER_ROLE_ID)
.from(USER_APPLICATION_ROLE)
.fetch(USER_APPLICATION_ROLE.USER_ROLE_ID);
}
} }

View file

@ -25,10 +25,20 @@ public class ErvuDirectoriesUpdateShedulerService {
@PostConstruct @PostConstruct
public void init() { public void init() {
if (!cronLoad.equals(CRON_DISABLED)) { if (!cronLoad.equals(CRON_DISABLED)) {
new Thread(this::run).start(); new Thread(this::runWithSleep).start();
} }
} }
private void runWithSleep() {
try {
Thread.sleep(100000);
}
catch (InterruptedException e) {
throw new RuntimeException(e);
}
run();
}
@Scheduled(cron = "${directory.update.cron:0 0 */1 * * *}") @Scheduled(cron = "${directory.update.cron:0 0 */1 * * *}")
@SchedulerLock(name = "updateDirectories") @SchedulerLock(name = "updateDirectories")
public void run() { public void run() {

View file

@ -16,6 +16,7 @@ import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import ru.micord.ervu.account_applications.component.exception.UserDataLoadException; import ru.micord.ervu.account_applications.component.exception.UserDataLoadException;
import ru.micord.ervu.account_applications.component.model.Role; import ru.micord.ervu.account_applications.component.model.Role;
import ru.micord.ervu.account_applications.security.context.SecurityContext;
import ru.micord.ervu.account_applications.service.constant.PathConstant; import ru.micord.ervu.account_applications.service.constant.PathConstant;
/** /**

View file

@ -1,5 +1,9 @@
package ru.micord.ervu.account_applications.websocket; package ru.micord.ervu.account_applications.websocket;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.SSLContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.client.WebSocketClient; import org.springframework.web.socket.client.WebSocketClient;
@ -11,8 +15,15 @@ import org.springframework.web.socket.client.standard.StandardWebSocketClient;
@Configuration @Configuration
public class WebSocketConfig { public class WebSocketConfig {
@Autowired
private SSLContext sslContext;
@Bean @Bean
public WebSocketClient webSocketClient() { public WebSocketClient webSocketClient() {
return new StandardWebSocketClient(); Map<String, Object> userProperties = new HashMap<>();
userProperties.put("org.apache.tomcat.websocket.SSL_CONTEXT", sslContext);
StandardWebSocketClient webSocketClient = new StandardWebSocketClient();
webSocketClient.setUserProperties(userProperties);
return webSocketClient;
} }
} }

View file

@ -63,6 +63,7 @@ public class WebSocketService {
socketHandler.putUserData(session.getId(), userId, token); socketHandler.putUserData(session.getId(), userId, token);
} }
catch (InterruptedException | ExecutionException | TimeoutException e) { catch (InterruptedException | ExecutionException | TimeoutException e) {
LOGGER.error("Failed to connect socket", e);
LOGGER.error("Failed to connect socket on retry {}", LOGGER.error("Failed to connect socket on retry {}",
RetrySynchronizationManager.getContext().getRetryCount()); RetrySynchronizationManager.getContext().getRetryCount());
throw new WebSocketConnectionException(e.getMessage()); throw new WebSocketConnectionException(e.getMessage());

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd">
<changeSet id="0001" author="tihomirov">
<comment>truncate user_application_role table</comment>
<sql>
TRUNCATE public.user_application_role CASCADE;
</sql>
</changeSet>
<changeSet id="0002" author="tihomirov">
<comment>add role_code column to user_application_role table</comment>
<sql>
ALTER TABLE IF EXISTS public.user_application_role ADD COLUMN IF NOT EXISTS role_code character varying;
COMMENT ON COLUMN public.user_application_role.role_code IS 'Код роли';
</sql>
</changeSet>
</databaseChangeLog>

View file

@ -18,4 +18,5 @@
<include file="20250313-SUPPORT-8957_add_trace_id.xml" relativeToChangelogFile="true"/> <include file="20250313-SUPPORT-8957_add_trace_id.xml" relativeToChangelogFile="true"/>
<include file="20250317-SUPPORT-8696_add_shedlock.xml" relativeToChangelogFile="true"/> <include file="20250317-SUPPORT-8696_add_shedlock.xml" relativeToChangelogFile="true"/>
<include file="20250324-SUPPORT-9023_add_sent_date.xml" relativeToChangelogFile="true"/> <include file="20250324-SUPPORT-9023_add_sent_date.xml" relativeToChangelogFile="true"/>
<include file="20250404-SUPPORT-9080_add_role_code.xml" relativeToChangelogFile="true"/>
</databaseChangeLog> </databaseChangeLog>

1
config/.gitignore vendored
View file

@ -1,2 +1,3 @@
/*.ear /*.ear
/*.jar /*.jar
/*.war

74
config/config.yaml Normal file
View file

@ -0,0 +1,74 @@
name: ervu-account-applications-backend
replicaCount: 1
resources:
requests:
memory: '256Mi'
cpu: '50m'
limits:
memory: '2Gi'
cpu: '1'
env:
- name: ERVU_URL
value: 'https://{{ $.Values.ingress_base_host }}'
- name: ERVU_PWD_SIGN_SECRET_KEY
value: 'DtCAQdeKnrAMLfdJkFVdfQnyT/Z5OINK4jqX0LbavfM='
ports:
- name: http
containerPort: 8080
services:
- name: '{{ $.Values.name }}'
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 8080
postgres:
database: 'ervu_account_applications'
livenessProbe:
failureThreshold: 3
httpGet:
path: /
port: 8080
initialDelaySeconds: 30
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 5
readinessProbe:
failureThreshold: 3
httpGet:
path: /account-applications/version
port: 8080
initialDelaySeconds: 30
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 5
ingress:
- name: '{{ $.Values.name }}'
annotations:
nginx.ingress.kubernetes.io/affinity: 'cookie'
nginx.ingress.kubernetes.io/session-cookie-name: 'stickysession'
nginx.ingress.kubernetes.io/session-cookie-max-age: '7200'
nginx.ingress.kubernetes.io/proxy-body-size: "75m"
nginx.ingress.kubernetes.io/rewrite-target: /account-applications/$2
labels:
app/name: ervu-account-applications
rules:
- host: '{{ $.Values.ingress_base_host }}'
http:
paths:
- path: /mfe/account-applications/account-applications(/|$)(.*)
pathType: Prefix
backend:
service:
name: '{{ $.Values.name }}'
port:
name: http

6
config/entrypoint.sh Normal file
View file

@ -0,0 +1,6 @@
#! /bin/bash
. /etc/tomcat/tomcat.conf
. /etc/sysconfig/tomcat
/usr/libexec/tomcat/server start

13
config/settings.xml Normal file
View file

@ -0,0 +1,13 @@
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<mirrors>
<mirror>
<id>central-mirror</id>
<name>rtlabs-public</name>
<url>https://nexus-dev.pgs.rtlabs.ru/repository/maven-public</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
</settings>

View file

@ -1,8 +1,8 @@
JDK_JAVA_OPTIONS="$JDK_JAVA_OPTIONS \ JDK_JAVA_OPTIONS="$JDK_JAVA_OPTIONS \
-Ddb.host=${DB_APP_HOST:-db} \ -Ddb.host=\"${PG_HOST:-db}\" \
-Ddb.port=${DB_APP_PORT:-5432} \ -Ddb.port=\"${PG_PORT:-5432}\" \
-Ddb.name=${DB_APP_NAME:-app} \ -Ddb.name=\"${PG_DATABASE:-app}\" \
-Ddb.username=${DB_APP_USERNAME:-app_user} \ -Ddb.username=\"${PG_USER:-app_user}\" \
-Ddb.password=${DB_APP_PASSWORD:-apppassword} \ -Ddb.password=\"${PG_PASSWORD:-apppassword}\" \
" "
export JDK_JAVA_OPTIONS export JDK_JAVA_OPTIONS

View file

@ -6,6 +6,7 @@ authentication.method=form
bpmn.enable=false bpmn.enable=false
fias.enable=false fias.enable=false
gar.enable=false gar.enable=false
registration.enabled=false
mail.jndi.resource.name= mail.jndi.resource.name=
@ -16,4 +17,4 @@ webbpm.mode=production
webbpm.jbpm.hibernate_statistics.enabled=false webbpm.jbpm.hibernate_statistics.enabled=false
webbpm.cache.hazelcast.hosts=127.0.0.1 webbpm.cache.hazelcast.hosts=127.0.0.1
webbpm.cache.hazelcast.outbound_port_definitions=5801-5820 webbpm.cache.hazelcast.outbound_port_definitions=5801-5820
registration.enabled=false com.amazonaws.sdk.disableCertChecking

13
config/uat/settings.xml Normal file
View file

@ -0,0 +1,13 @@
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<mirrors>
<mirror>
<id>central-mirror</id>
<name>rtlabs-public</name>
<url>http://nexus.gosuslugi.local/content/repositories/central</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
</settings>

View file

@ -51,6 +51,9 @@ export class UserManagementService extends Behavior {
case ApplicationKind.BLOCK_USER: case ApplicationKind.BLOCK_USER:
this.doRequest("user/deactivation", jsonObj); this.doRequest("user/deactivation", jsonObj);
break; break;
case ApplicationKind.UNBLOCK_USER:
this.doRequest("user/activation", jsonObj);
break;
case ApplicationKind.RESET_PASSWORD: case ApplicationKind.RESET_PASSWORD:
this.doRequest("user/password/reset", jsonObj); this.doRequest("user/password/reset", jsonObj);
break; break;

View file

@ -4,5 +4,6 @@ export enum ApplicationKind {
EDIT_USER_ACCOUNT = "EDIT_USER_ACCOUNT", EDIT_USER_ACCOUNT = "EDIT_USER_ACCOUNT",
EDIT_USER_ROLES = "EDIT_USER_ROLES", EDIT_USER_ROLES = "EDIT_USER_ROLES",
BLOCK_USER = "BLOCK_USER", BLOCK_USER = "BLOCK_USER",
UNBLOCK_USER = "UNBLOCK_USER",
RESET_PASSWORD = "RESET_PASSWORD" RESET_PASSWORD = "RESET_PASSWORD"
} }

View file

@ -15,6 +15,6 @@ export class DropdownTreeviewSelectI18n extends DefaultTreeviewI18n {
} }
getText(selection: TreeviewSelection): string { getText(selection: TreeviewSelection): string {
return this.internalSelectedItem ? this.internalSelectedItem.text : 'Элемент не выбран'; return this.internalSelectedItem ? this.internalSelectedItem.text : '';
} }
} }

View file

@ -28,6 +28,7 @@ import {
import { import {
TreeItemRpcService TreeItemRpcService
} from "../../../generated/ru/micord/ervu/account_applications/component/rpc/TreeItemRpcService"; } from "../../../generated/ru/micord/ervu/account_applications/component/rpc/TreeItemRpcService";
import {AuthorizationService} from "../../../modules/app/service/authorization.service";
@Component({ @Component({
@ -54,15 +55,20 @@ export class DropdownTreeViewComponent extends InputControl {
@Visible("false") @Visible("false")
public items: TreeviewItem[]; public items: TreeviewItem[];
@Visible("false") @Visible("false")
public value: any; public value: TreeItemDto;
@Visible("false") @Visible("false")
public valueChangeEvent: Event<TreeItemDto> = new Event<TreeItemDto>(); public valueChangeEvent: Event<TreeItemDto> = new Event<TreeItemDto>();
@AdvancedProperty()
public skipInitialSelection: boolean;
@NotNull()
public preferBusinessId: boolean = false;
private rpcService: TreeItemRpcService; private rpcService: TreeItemRpcService;
private localStorageService: LocalStorageService; private localStorageService: LocalStorageService;
private taskParamsProvider: TaskParamsProvider; private taskParamsProvider: TaskParamsProvider;
private pageContextHolder: PageContextHolder; private pageContextHolder: PageContextHolder;
private webbpmStorage: WebbpmStorage; private webbpmStorage: WebbpmStorage;
private storageKey: string; private storageKey: string;
private rootValues: TreeItemDto[];
constructor(el: ElementRef, cd: ChangeDetectorRef, constructor(el: ElementRef, cd: ChangeDetectorRef,
private i18n: DropdownTreeviewSelectI18n) { private i18n: DropdownTreeviewSelectI18n) {
@ -75,13 +81,18 @@ export class DropdownTreeViewComponent extends InputControl {
this.taskParamsProvider = this.injector.get(TaskParamsProvider); this.taskParamsProvider = this.injector.get(TaskParamsProvider);
this.localStorageService = this.injector.get(LocalStorageService); this.localStorageService = this.injector.get(LocalStorageService);
this.pageContextHolder = this.injector.get(PageContextHolder); this.pageContextHolder = this.injector.get(PageContextHolder);
let authService = this.injector.get(AuthorizationService);
if (authService.hasRole('security_administrator')) {
this.skipInitialSelection = true;
}
this.webbpmStorage = this.webbpmStorage =
this.getTreeValuesStorage(this.treeValuesCacheStrategy, this.treeValuesCustomName); this.getTreeValuesStorage(this.treeValuesCacheStrategy, this.treeValuesCustomName);
this.cachedValue = this.getCachedValue(); this.cachedValue = this.getCachedValue();
this.loadTreeItems(); this.loadTreeItems();
} }
private getTreeValuesStorage(treeValuesCacheStrategy: TreeValuesCacheStrategy, customKeyName: string) { private getTreeValuesStorage(treeValuesCacheStrategy: TreeValuesCacheStrategy,
customKeyName: string) {
if (!treeValuesCacheStrategy) { if (!treeValuesCacheStrategy) {
return null; return null;
} }
@ -116,6 +127,7 @@ export class DropdownTreeViewComponent extends InputControl {
private populateTree(res: TreeItemDto[]) { private populateTree(res: TreeItemDto[]) {
this.items = res.map(value => new TreeviewItem(this.createTreeItem(value))); this.items = res.map(value => new TreeviewItem(this.createTreeItem(value)));
this.rootValues = res;
const rootItem = this.items[0]; const rootItem = this.items[0];
if (this.cachedValue) { if (this.cachedValue) {
const matchedItem = this.findTreeItemByValue(this.items, this.cachedValue); const matchedItem = this.findTreeItemByValue(this.items, this.cachedValue);
@ -124,13 +136,12 @@ export class DropdownTreeViewComponent extends InputControl {
this.value = matchedItem.value; this.value = matchedItem.value;
} }
} }
else { else if (!this.skipInitialSelection) {
this.i18n.selectedItem = rootItem; this.i18n.selectedItem = rootItem;
this.value = rootItem.value; this.value = rootItem.value;
} }
this.doCollapseLevel(); this.doCollapseLevel();
this.valueChangeEvent.trigger(this.value); this.onValueChange(this.value);
this.cd.markForCheck();
} }
private findTreeItemByValue(rootItems: TreeviewItem[], valueToFind: any): TreeviewItem | null { private findTreeItemByValue(rootItems: TreeviewItem[], valueToFind: any): TreeviewItem | null {
@ -171,6 +182,7 @@ export class DropdownTreeViewComponent extends InputControl {
this.setCachedValue(this.value); this.setCachedValue(this.value);
this.valueChangeEvent.trigger($event); this.valueChangeEvent.trigger($event);
this.applyListener(this.changeListeners); this.applyListener(this.changeListeners);
this.cd.markForCheck();
} }
@Visible() @Visible()
@ -198,13 +210,13 @@ export class DropdownTreeViewComponent extends InputControl {
} }
} }
protected setCachedValue(newValue: any): void { protected setCachedValue(newValue: TreeItemDto): void {
if (this.webbpmStorage) { if (this.webbpmStorage) {
this.webbpmStorage.put(this.storageKey, newValue); this.webbpmStorage.put(this.storageKey, newValue);
} }
} }
protected getCachedValue(): any { protected getCachedValue(): TreeItemDto {
if (this.webbpmStorage) { if (this.webbpmStorage) {
return this.webbpmStorage.get(this.storageKey); return this.webbpmStorage.get(this.storageKey);
} }
@ -220,23 +232,41 @@ export class DropdownTreeViewComponent extends InputControl {
} }
getPresentationValue(): string | number | boolean { getPresentationValue(): string | number | boolean {
return this.value; return this.value ? this.value.label : '';
} }
@Visible()
getValue(): any { getValue(): any {
return this.value; return this.value ? this.value.id : this.value;
} }
getValueAsModel(): any { getValueAsModel(): TreeItemDto {
return this.value ? this.value : null; return this.value ? this.value : null;
} }
getValueForForm(): any { getValueForForm(): any {
return this.getBusinessId(); return this.preferBusinessId ? this.getBusinessId() : this.getValue();
} }
setValue(value: any): any { @Visible()
this.value = value; setValue(value: any): void {
this.items = [...this.items];
this.value = this.findValueInRootsById(value);
this.onValueChange(this.value);
}
private findValueInRootsById(id: any): TreeItemDto {
let searchArray: TreeItemDto[] = this.rootValues.slice();
while (searchArray.length > 0) {
const current = searchArray.shift();
if (current.id == id) {
return current;
}
if (current.children && current.children.length > 0) {
searchArray.push(...current.children);
}
}
return null;
} }
onChange() { onChange() {
@ -251,5 +281,4 @@ export class DropdownTreeViewComponent extends InputControl {
unsubscribeToModelChange() { unsubscribeToModelChange() {
//empty because there is no ngModel here //empty because there is no ngModel here
} }
} }

View file

@ -44,6 +44,11 @@ const appRoutes: Routes = [
path: 'process_application_edit_user/:id', path: 'process_application_edit_user/:id',
loadChildren: 'generated-sources/page-process_application_edit_user.module#Pageprocess_application_edit_userModule', loadChildren: 'generated-sources/page-process_application_edit_user.module#Pageprocess_application_edit_userModule',
canActivate: [ConfirmExitGuard, RolesGuard] canActivate: [ConfirmExitGuard, RolesGuard]
},
{
path: 'unblock_user_application',
loadChildren: 'generated-sources/page-unblock_user_application.module#Pageunblock_user_applicationModule',
canActivate: [ConfirmExitGuard, RolesGuard]
} }
]; ];

10
pom.xml
View file

@ -228,6 +228,16 @@
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
<version>2.0.13</version> <version>2.0.13</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.12</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId> <artifactId>log4j-slf4j2-impl</artifactId>

View file

@ -853,6 +853,169 @@
</item> </item>
<item id="dc389089-75a9-4406-82bc-8fb9a4488631" removed="true"/> <item id="dc389089-75a9-4406-82bc-8fb9a4488631" removed="true"/>
<item id="b4e369c2-515c-494b-930e-5097408cb0ff" removed="true"/> <item id="b4e369c2-515c-494b-930e-5097408cb0ff" removed="true"/>
<item id="09d5c116-dbac-4817-a43d-a1273df74f31" removed="true"/>
</value>
</entry>
</properties>
</scripts>
</children>
<children id="4629960e-1ab0-4d44-a1a4-65ad26a38180">
<prototypeId>98594cec-0a9b-4cef-af09-e1b71cb2ad9e</prototypeId>
<componentRootId>4629960e-1ab0-4d44-a1a4-65ad26a38180</componentRootId>
<name>AC_UNBLOCK_USER</name>
<container>false</container>
<childrenReordered>false</childrenReordered>
<scripts id="37dff5c8-1599-4984-b107-c44a87b6da2e">
<properties>
<entry>
<key>eventRefs</key>
<value>
<item id="1a590440-bd87-4a5d-aab3-8f718a179ec5" removed="false">
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"80f94647-9cb4-4aaf-8c6b-a842e486e98c","packageName":"component.container","className":"Form","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>propertyName</key>
<value>
<simple>"formLoaded"</simple>
</value>
</entry>
</complex>
</value>
</item>
</value>
</entry>
<entry>
<key>ifCondition</key>
<value>
<complex>
<entry>
<key>conditions</key>
<value>
<item id="c7e8f8f5-8e89-4248-b68b-e1d1afec4cdd" removed="false">
<value>
<complex>
<entry>
<key>_isGroupSelected</key>
<value>
<simple>false</simple>
</value>
</entry>
<entry>
<key>one</key>
<value>
<complex>
<entry>
<key>conditionFirstPart</key>
<value>
<complex>
<entry>
<key>objectValue</key>
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"9e772048-b43f-42f1-a370-2519dd4f6ad7","packageName":"component.field","className":"TextField","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>method</key>
<value>
<simple>"getValue"</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>conditionSecondPart</key>
<value>
<complex>
<entry>
<key>staticValue</key>
<value>
<implRef type="TS">
<className>string</className>
<packageName></packageName>
</implRef>
<simple>"UNBLOCK_USER"</simple>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>operation</key>
<value>
<simple>"EQUALS"</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
</value>
</entry>
<entry>
<key>logicalOperation</key>
<value>
<simple>null</simple>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>thenActions</key>
<value>
<item id="6a6f7cf8-b71e-4c7c-a2b7-4ed8d3a7c83f" removed="false">
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"522f1f66-b490-45d4-ab45-0e4cacfe63a2","packageName":"component","className":"Text","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>method</key>
<value>
<simple>"setValue"</simple>
</value>
</entry>
<entry>
<key>value</key>
<value>
<complex>
<entry>
<key>staticValue</key>
<value>
<implRef type="TS">
<className>string</className>
<packageName></packageName>
</implRef>
<simple>"активацию"</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
<item id="dc389089-75a9-4406-82bc-8fb9a4488631" removed="true"/>
<item id="b4e369c2-515c-494b-930e-5097408cb0ff" removed="true"/>
<item id="09d5c116-dbac-4817-a43d-a1273df74f31" removed="true"/> <item id="09d5c116-dbac-4817-a43d-a1273df74f31" removed="true"/>
</value> </value>
</entry> </entry>

View file

@ -151,346 +151,7 @@
<componentRootId>cb4f0a77-8312-43f3-a03d-441936d1e08b</componentRootId> <componentRootId>cb4f0a77-8312-43f3-a03d-441936d1e08b</componentRootId>
<name>AC_EDIT_USER</name> <name>AC_EDIT_USER</name>
<container>false</container> <container>false</container>
<childrenReordered>false</childrenReordered> <removed>true</removed>
<scripts id="37dff5c8-1599-4984-b107-c44a87b6da2e">
<properties>
<entry>
<key>elseActions</key>
<value>
<item id="46cd4a5a-ee4e-4399-9426-5aacbb856be2" removed="true"/>
<item id="ac08d39f-2342-4471-b763-2a798f7f344a" removed="false">
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"aea4f26b-3d2b-42bd-bad8-49fc634769b2","packageName":"component.field","className":"TextField","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>method</key>
<value>
<simple>"setVisible"</simple>
</value>
</entry>
<entry>
<key>value</key>
<value>
<complex>
<entry>
<key>staticValue</key>
<value>
<implRef type="TS">
<className>boolean</className>
<packageName></packageName>
</implRef>
<simple>true</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
<item id="9af67c9c-650e-4530-8c05-4a28bfe5401c" removed="false">
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"adb4c166-21ae-45e0-ba9b-12ca7aeabdfe","packageName":"component.field","className":"TextField","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>method</key>
<value>
<simple>"setVisible"</simple>
</value>
</entry>
<entry>
<key>value</key>
<value>
<complex>
<entry>
<key>staticValue</key>
<value>
<implRef type="TS">
<className>boolean</className>
<packageName></packageName>
</implRef>
<simple>true</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
<item id="cd224f4c-643c-4fce-82b4-f74844371ebc" removed="false">
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"27764b05-3a3e-4bed-b1dd-d032f990240d","packageName":"component.field","className":"Autocomplete","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>method</key>
<value>
<simple>"setVisible"</simple>
</value>
</entry>
<entry>
<key>value</key>
<value>
<complex>
<entry>
<key>staticValue</key>
<value>
<implRef type="TS">
<className>boolean</className>
<packageName></packageName>
</implRef>
<simple>true</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
<item id="ff3d6ba3-e6ab-4cb3-bb4a-bbe68428e1c4" removed="true"/>
</value>
</entry>
<entry>
<key>eventRefs</key>
<value>
<item id="1a590440-bd87-4a5d-aab3-8f718a179ec5" removed="false">
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"80f94647-9cb4-4aaf-8c6b-a842e486e98c","packageName":"component.container","className":"Form","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>propertyName</key>
<value>
<simple>"formLoaded"</simple>
</value>
</entry>
</complex>
</value>
</item>
</value>
</entry>
<entry>
<key>ifCondition</key>
<value>
<complex>
<entry>
<key>conditions</key>
<value>
<item id="c7e8f8f5-8e89-4248-b68b-e1d1afec4cdd" removed="false">
<value>
<complex>
<entry>
<key>_isGroupSelected</key>
<value>
<simple>false</simple>
</value>
</entry>
<entry>
<key>one</key>
<value>
<complex>
<entry>
<key>conditionFirstPart</key>
<value>
<complex>
<entry>
<key>objectValue</key>
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"9e772048-b43f-42f1-a370-2519dd4f6ad7","packageName":"component.field","className":"TextField","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>method</key>
<value>
<simple>"getValue"</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>conditionSecondPart</key>
<value>
<complex>
<entry>
<key>staticValue</key>
<value>
<implRef type="TS">
<className>string</className>
<packageName></packageName>
</implRef>
<simple>"EDIT_USER_MAIN"</simple>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>operation</key>
<value>
<simple>"EQUALS"</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
</value>
</entry>
<entry>
<key>logicalOperation</key>
<value>
<simple>null</simple>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>thenActions</key>
<value>
<item id="6a6f7cf8-b71e-4c7c-a2b7-4ed8d3a7c83f" removed="true"/>
<item id="234072de-7635-4db5-8f45-b73e59d5b948" removed="true"/>
<item id="896fc5ac-ee75-4637-89c0-834a30fd6958" removed="false">
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"aea4f26b-3d2b-42bd-bad8-49fc634769b2","packageName":"component.field","className":"TextField","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>method</key>
<value>
<simple>"setVisible"</simple>
</value>
</entry>
<entry>
<key>value</key>
<value>
<complex>
<entry>
<key>staticValue</key>
<value>
<implRef type="TS">
<className>boolean</className>
<packageName></packageName>
</implRef>
<simple>false</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
<item id="365e8bd2-055e-46f8-b7d4-de2e72642cad" removed="false">
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"adb4c166-21ae-45e0-ba9b-12ca7aeabdfe","packageName":"component.field","className":"TextField","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>method</key>
<value>
<simple>"setVisible"</simple>
</value>
</entry>
<entry>
<key>value</key>
<value>
<complex>
<entry>
<key>staticValue</key>
<value>
<implRef type="TS">
<className>boolean</className>
<packageName></packageName>
</implRef>
<simple>false</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
<item id="b9c8a946-29b1-44a7-82fa-4f9fd73797fe" removed="false">
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"27764b05-3a3e-4bed-b1dd-d032f990240d","packageName":"component.field","className":"Autocomplete","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>method</key>
<value>
<simple>"setVisible"</simple>
</value>
</entry>
<entry>
<key>value</key>
<value>
<complex>
<entry>
<key>staticValue</key>
<value>
<implRef type="TS">
<className>boolean</className>
<packageName></packageName>
</implRef>
<simple>false</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
<item id="43b072fa-d2d9-479d-b38f-a4cdc4a3e798" removed="true"/>
<item id="09d5c116-dbac-4817-a43d-a1273df74f31" removed="true"/>
</value>
</entry>
</properties>
</scripts>
</children> </children>
</children> </children>
<children id="a68c745b-dad9-4eb3-99fb-34c1554f21c3"> <children id="a68c745b-dad9-4eb3-99fb-34c1554f21c3">
@ -1179,7 +840,6 @@
<componentRootId>80f94647-9cb4-4aaf-8c6b-a842e486e98c</componentRootId> <componentRootId>80f94647-9cb4-4aaf-8c6b-a842e486e98c</componentRootId>
<name>Form</name> <name>Form</name>
<container>true</container> <container>true</container>
<expanded>false</expanded>
<childrenReordered>false</childrenReordered> <childrenReordered>false</childrenReordered>
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f"/> <scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f"/>
<scripts id="c0bf7050-bd39-426a-8f1e-1600bbd4b9bb"> <scripts id="c0bf7050-bd39-426a-8f1e-1600bbd4b9bb">
@ -1962,119 +1622,7 @@
<componentRootId>27764b05-3a3e-4bed-b1dd-d032f990240d</componentRootId> <componentRootId>27764b05-3a3e-4bed-b1dd-d032f990240d</componentRootId>
<name>Организация</name> <name>Организация</name>
<container>false</container> <container>false</container>
<childrenReordered>false</childrenReordered> <removed>true</removed>
<scripts id="859913ec-9a30-439c-afc2-3c83cddcfe03">
<properties>
<entry>
<key>cssClasses</key>
<value>
<item id="a9ed2b2d-4668-4417-967b-8ebfafc21110" removed="false">
<value>
<simple>"width-full"</simple>
</value>
</item>
</value>
</entry>
<entry>
<key>disabled</key>
<value>
<simple>true</simple>
</value>
</entry>
<entry>
<key>label</key>
<value>
<simple>"Организация"</simple>
</value>
</entry>
<entry>
<key>required</key>
<value>
<simple>true</simple>
</value>
</entry>
</properties>
</scripts>
<scripts id="d9ac3145-9d66-42bd-9f24-1c3d0d2e31d0">
<properties>
<entry>
<key>autocompleteService</key>
<value>
<complex>
<entry>
<key>businessIdColumn</key>
<value>
<simple>{"schema":"public","table":"recruitment","entity":"recruitment","name":"idm_id"}</simple>
</value>
</entry>
<entry>
<key>displayColumn</key>
<value>
<simple>{"schema":"public","table":"recruitment","entity":"recruitment","name":"fullname"}</simple>
</value>
</entry>
<entry>
<key>loadDao</key>
<value>
<complex>
<entry>
<key>graph</key>
<value>
<simple>{"conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"nodeByIndex":{"0":{"tableName":"recruitment","schemaName":"public","x":334.0,"y":161.0,"alias":"recruitment","conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}},"nodes":[{"tableName":"recruitment","schemaName":"public","x":334.0,"y":161.0,"alias":"recruitment","conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}],"nodeByEntityName":{"recruitment":{"tableName":"recruitment","schemaName":"public","x":334.0,"y":161.0,"alias":"recruitment","conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}},"matrix":[[null]],"mainNodeIndex":0}</simple>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>parentControlReference</key>
<value>
<simple>null</simple>
</value>
</entry>
</complex>
</value>
</entry>
</properties>
</scripts>
<scripts id="0b478949-71f8-4a8c-bcfc-8407265d231c">
<properties>
<entry>
<key>variable</key>
<value>
<simple>"org_unit_id"</simple>
</value>
</entry>
</properties>
</scripts>
<scripts id="2d8e021b-77e9-4d5c-a3e7-36fa9f8f1c42"/>
<scripts id="5c1508fe-b7fe-44cb-bec9-11eb7b09570f"/>
<scripts id="b26e8065-5cb8-40d4-b160-61e2ccc0cb14">
<properties>
<entry>
<key>columnForSave</key>
<value>
<simple>{"schema":"public","table":"user_application_list","entity":"user_application_list","name":"recruitment_id"}</simple>
</value>
</entry>
</properties>
</scripts>
<scripts id="93cced4c-2537-4583-95cf-db5937d58efd">
<classRef type="TS">
<className>FormField</className>
<packageName>account_applications.component.field</packageName>
</classRef>
<enabled>true</enabled>
<expanded>true</expanded>
<properties>
<entry>
<key>name</key>
<value>
<simple>"userDomain"</simple>
</value>
</entry>
</properties>
</scripts>
</children> </children>
<children id="90961d84-b7e6-4b18-b51f-1cc07d2acf09"> <children id="90961d84-b7e6-4b18-b51f-1cc07d2acf09">
<prototypeId>69af9ec9-d640-499a-bf05-cda6ce64a81f</prototypeId> <prototypeId>69af9ec9-d640-499a-bf05-cda6ce64a81f</prototypeId>
@ -3237,6 +2785,125 @@
<key>name</key> <key>name</key>
<value> <value>
<simple>"position"</simple> <simple>"position"</simple>
</value>
</entry>
</properties>
</scripts>
</children>
<children id="27764b05-3a3e-4bed-b1dd-d032f990240d">
<prototypeId>f9a38417-9ad0-412a-9b5f-bbeb450dddd6</prototypeId>
<componentRootId>27764b05-3a3e-4bed-b1dd-d032f990240d</componentRootId>
<name>Организация</name>
<container>false</container>
<childrenReordered>false</childrenReordered>
<scripts id="859913ec-9a30-439c-afc2-3c83cddcfe03">
<properties>
<entry>
<key>cssClasses</key>
<value>
<item id="a9ed2b2d-4668-4417-967b-8ebfafc21110" removed="false">
<value>
<simple>"width-full"</simple>
</value>
</item>
</value>
</entry>
<entry>
<key>disabled</key>
<value>
<simple>true</simple>
</value>
</entry>
<entry>
<key>label</key>
<value>
<simple>"Организация"</simple>
</value>
</entry>
<entry>
<key>required</key>
<value>
<simple>true</simple>
</value>
</entry>
</properties>
</scripts>
<scripts id="d9ac3145-9d66-42bd-9f24-1c3d0d2e31d0">
<properties>
<entry>
<key>autocompleteService</key>
<value>
<complex>
<entry>
<key>businessIdColumn</key>
<value>
<simple>{"schema":"public","table":"recruitment","entity":"recruitment","name":"idm_id"}</simple>
</value>
</entry>
<entry>
<key>displayColumn</key>
<value>
<simple>{"schema":"public","table":"recruitment","entity":"recruitment","name":"fullname"}</simple>
</value>
</entry>
<entry>
<key>loadDao</key>
<value>
<complex>
<entry>
<key>graph</key>
<value>
<simple>{"conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"nodeByIndex":{"0":{"tableName":"recruitment","schemaName":"public","x":334.0,"y":161.0,"alias":"recruitment","conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}},"nodes":[{"tableName":"recruitment","schemaName":"public","x":334.0,"y":161.0,"alias":"recruitment","conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}],"nodeByEntityName":{"recruitment":{"tableName":"recruitment","schemaName":"public","x":334.0,"y":161.0,"alias":"recruitment","conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}},"matrix":[[null]],"mainNodeIndex":0}</simple>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>parentControlReference</key>
<value>
<simple>null</simple>
</value>
</entry>
</complex>
</value>
</entry>
</properties>
</scripts>
<scripts id="0b478949-71f8-4a8c-bcfc-8407265d231c">
<properties>
<entry>
<key>variable</key>
<value>
<simple>"org_unit_id"</simple>
</value>
</entry>
</properties>
</scripts>
<scripts id="2d8e021b-77e9-4d5c-a3e7-36fa9f8f1c42"/>
<scripts id="5c1508fe-b7fe-44cb-bec9-11eb7b09570f"/>
<scripts id="b26e8065-5cb8-40d4-b160-61e2ccc0cb14">
<properties>
<entry>
<key>columnForSave</key>
<value>
<simple>{"schema":"public","table":"user_application_list","entity":"user_application_list","name":"recruitment_id"}</simple>
</value>
</entry>
</properties>
</scripts>
<scripts id="93cced4c-2537-4583-95cf-db5937d58efd">
<classRef type="TS">
<className>FormField</className>
<packageName>account_applications.component.field</packageName>
</classRef>
<enabled>true</enabled>
<expanded>true</expanded>
<properties>
<entry>
<key>name</key>
<value>
<simple>"userDomain"</simple>
</value> </value>
</entry> </entry>
</properties> </properties>

View file

@ -1713,13 +1713,13 @@
<entry> <entry>
<key>pattern</key> <key>pattern</key>
<value> <value>
<simple>"^[a-zA-Z][a-zA-Z0-9]{0,49}$"</simple> <simple>"^[a-zA-Z][a-zA-Z0-9_]{0,49}$"</simple>
</value> </value>
</entry> </entry>
<entry> <entry>
<key>patternErrorMessage</key> <key>patternErrorMessage</key>
<value> <value>
<simple>"Логин не должен начинаться с цифры, содержать спецсимволы, буквы кирилицы и быть не более 50 символов"</simple> <simple>"Логин не должен начинаться с цифры, содержать спецсимволы (кроме знака подчёркивания), буквы кириллицы и быть длиннее 50 символов."</simple>
</value> </value>
</entry> </entry>
<entry> <entry>
@ -2009,6 +2009,12 @@
</value> </value>
</entry> </entry>
<entry> <entry>
<key>preferBusinessId</key>
<value>
<simple>true</simple>
</value>
</entry>
<entry>
<key>required</key> <key>required</key>
<value> <value>
<simple>true</simple> <simple>true</simple>
@ -2294,7 +2300,6 @@
<componentRootId>9bfac70b-fd5e-4cdc-84fa-50190bde76d1</componentRootId> <componentRootId>9bfac70b-fd5e-4cdc-84fa-50190bde76d1</componentRootId>
<name>Many to many</name> <name>Many to many</name>
<container>true</container> <container>true</container>
<expanded>false</expanded>
<childrenReordered>false</childrenReordered> <childrenReordered>false</childrenReordered>
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f"> <scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
<properties> <properties>
@ -2365,6 +2370,16 @@
<childrenReordered>false</childrenReordered> <childrenReordered>false</childrenReordered>
<scripts id="e6553d24-6c92-461b-b0ab-f7a400836302"> <scripts id="e6553d24-6c92-461b-b0ab-f7a400836302">
<properties> <properties>
<entry>
<key>cssClasses</key>
<value>
<item id="338d589f-48ae-4b4e-adff-aa65775c8fd7" removed="false">
<value>
<simple>"show-alarm"</simple>
</value>
</item>
</value>
</entry>
<entry> <entry>
<key>label</key> <key>label</key>
<value> <value>
@ -2927,7 +2942,6 @@
<componentRootId>a44f98ec-c47e-40b3-983f-73b5a72bb31d</componentRootId> <componentRootId>a44f98ec-c47e-40b3-983f-73b5a72bb31d</componentRootId>
<name>IP-адреса</name> <name>IP-адреса</name>
<container>true</container> <container>true</container>
<expanded>false</expanded>
<childrenReordered>false</childrenReordered> <childrenReordered>false</childrenReordered>
<scripts id="e39e7bd9-3f44-4cb6-ab26-7aa5f7e7e1cc"> <scripts id="e39e7bd9-3f44-4cb6-ab26-7aa5f7e7e1cc">
<properties> <properties>
@ -2950,6 +2964,16 @@
</value> </value>
</entry> </entry>
<entry> <entry>
<key>cssClasses</key>
<value>
<item id="9085966e-de55-4aa6-930e-b1f4c43b6c3d" removed="false">
<value>
<simple>"show-alarm"</simple>
</value>
</item>
</value>
</entry>
<entry>
<key>label</key> <key>label</key>
<value> <value>
<simple>null</simple> <simple>null</simple>
@ -3655,13 +3679,6 @@
<container>false</container> <container>false</container>
<removed>true</removed> <removed>true</removed>
</children> </children>
<children id="0c7d30a2-2d41-4e88-a14a-bd3cc91705ee">
<prototypeId>05ed2031-091f-4fe0-8844-067ac42155aa</prototypeId>
<componentRootId>0c7d30a2-2d41-4e88-a14a-bd3cc91705ee</componentRootId>
<name>Validation controller_нет роли</name>
<container>false</container>
<removed>true</removed>
</children>
<children id="7b65eda9-a92d-49fe-8355-547f7941ba7f"> <children id="7b65eda9-a92d-49fe-8355-547f7941ba7f">
<prototypeId>57c7cd21-1556-4dbd-b9da-33520486a1db</prototypeId> <prototypeId>57c7cd21-1556-4dbd-b9da-33520486a1db</prototypeId>
<componentRootId>7b65eda9-a92d-49fe-8355-547f7941ba7f</componentRootId> <componentRootId>7b65eda9-a92d-49fe-8355-547f7941ba7f</componentRootId>

View file

@ -788,7 +788,6 @@
<componentRootId>b02f97ad-e367-4b34-9b0c-cd1d20c108bf</componentRootId> <componentRootId>b02f97ad-e367-4b34-9b0c-cd1d20c108bf</componentRootId>
<name>Vbox_LOAD</name> <name>Vbox_LOAD</name>
<container>true</container> <container>true</container>
<expanded>false</expanded>
<childrenReordered>false</childrenReordered> <childrenReordered>false</childrenReordered>
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f"> <scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
<properties> <properties>
@ -994,7 +993,6 @@
<componentRootId>3c5bd179-ffd8-4d0a-8742-e604d25ccfeb</componentRootId> <componentRootId>3c5bd179-ffd8-4d0a-8742-e604d25ccfeb</componentRootId>
<name>Vbox_1</name> <name>Vbox_1</name>
<container>true</container> <container>true</container>
<expanded>false</expanded>
<childrenReordered>false</childrenReordered> <childrenReordered>false</childrenReordered>
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f"> <scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
<properties> <properties>
@ -1298,6 +1296,7 @@
<componentRootId>981f9ebc-cf0e-4f28-916e-d78b6309dcb6</componentRootId> <componentRootId>981f9ebc-cf0e-4f28-916e-d78b6309dcb6</componentRootId>
<name>Пол load_1</name> <name>Пол load_1</name>
<container>false</container> <container>false</container>
<expanded>false</expanded>
<childrenReordered>false</childrenReordered> <childrenReordered>false</childrenReordered>
<scripts id="b7c451ce-53e4-45be-8fec-2bcd67fac11c"> <scripts id="b7c451ce-53e4-45be-8fec-2bcd67fac11c">
<properties> <properties>
@ -1332,7 +1331,7 @@
<entry> <entry>
<key>value</key> <key>value</key>
<value> <value>
<simple>"FEMALE"</simple> <simple>"female"</simple>
</value> </value>
</entry> </entry>
</complex> </complex>
@ -1350,7 +1349,7 @@
<entry> <entry>
<key>value</key> <key>value</key>
<value> <value>
<simple>"MALE"</simple> <simple>"male"</simple>
</value> </value>
</entry> </entry>
</complex> </complex>
@ -1368,7 +1367,7 @@
<entry> <entry>
<key>value</key> <key>value</key>
<value> <value>
<simple>"Мужской"</simple> <simple>"мужской"</simple>
</value> </value>
</entry> </entry>
</complex> </complex>
@ -1386,7 +1385,7 @@
<entry> <entry>
<key>value</key> <key>value</key>
<value> <value>
<simple>"Женский"</simple> <simple>"женский"</simple>
</value> </value>
</entry> </entry>
</complex> </complex>
@ -2743,7 +2742,7 @@
<className>string</className> <className>string</className>
<packageName></packageName> <packageName></packageName>
</implRef> </implRef>
<simple>"Мужской"</simple> <simple>"мужской"</simple>
</value> </value>
</entry> </entry>
</complex> </complex>
@ -2811,7 +2810,7 @@
<className>string</className> <className>string</className>
<packageName></packageName> <packageName></packageName>
</implRef> </implRef>
<simple>"MALE"</simple> <simple>"male"</simple>
</value> </value>
</entry> </entry>
</complex> </complex>
@ -3011,7 +3010,7 @@
<className>string</className> <className>string</className>
<packageName></packageName> <packageName></packageName>
</implRef> </implRef>
<simple>"Женский"</simple> <simple>"женский"</simple>
</value> </value>
</entry> </entry>
</complex> </complex>
@ -3079,7 +3078,7 @@
<className>string</className> <className>string</className>
<packageName></packageName> <packageName></packageName>
</implRef> </implRef>
<simple>"FEMALE"</simple> <simple>"female"</simple>
</value> </value>
</entry> </entry>
</complex> </complex>
@ -5330,6 +5329,7 @@
<componentRootId>5cce7e30-858d-489f-8b46-6e0f8dfc9a22</componentRootId> <componentRootId>5cce7e30-858d-489f-8b46-6e0f8dfc9a22</componentRootId>
<name>Пол</name> <name>Пол</name>
<container>false</container> <container>false</container>
<expanded>false</expanded>
<childrenReordered>false</childrenReordered> <childrenReordered>false</childrenReordered>
<scripts id="b7c451ce-53e4-45be-8fec-2bcd67fac11c"> <scripts id="b7c451ce-53e4-45be-8fec-2bcd67fac11c">
<properties> <properties>
@ -7585,7 +7585,6 @@
<componentRootId>ec35c0af-f0ca-486b-953a-ed607a05ac70</componentRootId> <componentRootId>ec35c0af-f0ca-486b-953a-ed607a05ac70</componentRootId>
<name>Dialog</name> <name>Dialog</name>
<container>true</container> <container>true</container>
<expanded>false</expanded>
<childrenReordered>false</childrenReordered> <childrenReordered>false</childrenReordered>
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c"> <scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
<properties> <properties>
@ -8639,6 +8638,102 @@
</children> </children>
</children> </children>
</children> </children>
<children id="1cb0019c-1019-463e-aff0-9b7ed97bdceb">
<prototypeId>887d2044-9e34-46a5-852c-e9ce07b42f30</prototypeId>
<componentRootId>1cb0019c-1019-463e-aff0-9b7ed97bdceb</componentRootId>
<name>Static combobox (filter)</name>
<container>false</container>
<childrenReordered>false</childrenReordered>
<scripts id="b7c451ce-53e4-45be-8fec-2bcd67fac11c">
<properties>
<entry>
<key>initialValue</key>
<value>
<simple>"true"</simple>
</value>
</entry>
<entry>
<key>values</key>
<value>
<item id="f8fd67f5-f715-43e6-a534-705d7155d749" removed="false">
<value>
<complex>
<entry>
<key>label</key>
<value>
<simple>"true"</simple>
</value>
</entry>
<entry>
<key>value</key>
<value>
<simple>"true"</simple>
</value>
</entry>
</complex>
</value>
</item>
<item id="44472950-bf27-4e7b-a76e-bf970bf0a74a" removed="false">
<value>
<complex>
<entry>
<key>label</key>
<value>
<simple>"false"</simple>
</value>
</entry>
<entry>
<key>value</key>
<value>
<simple>"false"</simple>
</value>
</entry>
</complex>
</value>
</item>
</value>
</entry>
<entry>
<key>visible</key>
<value>
<simple>false</simple>
</value>
</entry>
</properties>
</scripts>
<scripts id="609d3d73-3afc-43ab-ac23-182b192c3173">
<properties>
<entry>
<key>operation</key>
<value>
<simple>"EQUAL"</simple>
</value>
</entry>
</properties>
</scripts>
<scripts id="88e054a1-803b-4b55-bf21-c0843f1ed028">
<enabled>false</enabled>
</scripts>
<scripts id="4273d23d-add7-483f-95a5-0849005c975b"/>
<scripts id="d4e0342b-e32a-415c-8d45-83b71f074db2"/>
<scripts id="cf967f04-f483-4815-b84e-8d502546c07e"/>
<scripts id="0e80d3fa-8fb8-453b-8538-2310ec4f7889">
<classRef type="JAVA">
<className>StaticFilterComponent</className>
<packageName>ru.micord.ervu.account_applications.component.field.persist.filter</packageName>
</classRef>
<enabled>true</enabled>
<expanded>true</expanded>
<properties>
<entry>
<key>name</key>
<value>
<simple>"enabled"</simple>
</value>
</entry>
</properties>
</scripts>
</children>
<children id="bb27636e-7c7b-4489-a07c-9d2b214bf7a9"> <children id="bb27636e-7c7b-4489-a07c-9d2b214bf7a9">
<prototypeId>4d981f15-5535-45f7-882b-3647b251ad05</prototypeId> <prototypeId>4d981f15-5535-45f7-882b-3647b251ad05</prototypeId>
<componentRootId>bb27636e-7c7b-4489-a07c-9d2b214bf7a9</componentRootId> <componentRootId>bb27636e-7c7b-4489-a07c-9d2b214bf7a9</componentRootId>
@ -8660,13 +8755,6 @@
<container>false</container> <container>false</container>
<removed>true</removed> <removed>true</removed>
</children> </children>
<children id="5b8c5ac4-549d-411f-80ff-d29293638e5f">
<prototypeId>887d2044-9e34-46a5-852c-e9ce07b42f30</prototypeId>
<componentRootId>5b8c5ac4-549d-411f-80ff-d29293638e5f</componentRootId>
<name>Пол</name>
<container>false</container>
<removed>true</removed>
</children>
<children id="39040b94-4780-4067-864e-64ad3d22a2a3"> <children id="39040b94-4780-4067-864e-64ad3d22a2a3">
<prototypeId>4d981f15-5535-45f7-882b-3647b251ad05</prototypeId> <prototypeId>4d981f15-5535-45f7-882b-3647b251ad05</prototypeId>
<componentRootId>39040b94-4780-4067-864e-64ad3d22a2a3</componentRootId> <componentRootId>39040b94-4780-4067-864e-64ad3d22a2a3</componentRootId>
@ -8838,7 +8926,7 @@
<entry> <entry>
<key>height</key> <key>height</key>
<value> <value>
<simple>null</simple> <simple>"300px"</simple>
</value> </value>
</entry> </entry>
</complex> </complex>
@ -8947,6 +9035,30 @@
<simple>null</simple> <simple>null</simple>
</value> </value>
</entry> </entry>
<entry>
<key>headerHeight</key>
<value>
<simple>40.0</simple>
</value>
</entry>
<entry>
<key>loadingOverlayMessage</key>
<value>
<simple>"Загрузка данных, пожалуйста, подождите."</simple>
</value>
</entry>
<entry>
<key>loadingOverlayType</key>
<value>
<simple>"TEXT_OVERLAY"</simple>
</value>
</entry>
<entry>
<key>noRowsOverlayMessage</key>
<value>
<simple>"Данные отсутствуют"</simple>
</value>
</entry>
<entry> <entry>
<key>pagination</key> <key>pagination</key>
<value> <value>
@ -8959,6 +9071,31 @@
<simple>"SINGLE_SELECT_CLICK"</simple> <simple>"SINGLE_SELECT_CLICK"</simple>
</value> </value>
</entry> </entry>
<entry>
<key>rowHeight</key>
<value>
<simple>40.0</simple>
</value>
</entry>
<entry>
<key>style</key>
<value>
<complex>
<entry>
<key>height</key>
<value>
<simple>"300px"</simple>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>theme</key>
<value>
<simple>"BALHAM"</simple>
</value>
</entry>
<entry> <entry>
<key>visible</key> <key>visible</key>
<value> <value>
@ -9205,6 +9342,73 @@
<entry> <entry>
<key>sortable</key> <key>sortable</key>
<value> <value>
<simple>false</simple>
</value>
</entry>
</properties>
</scripts>
</children>
<children id="0f9753a4-bad5-4842-9ee5-f8565c53c0e0">
<prototypeId>d4f69cb0-864e-4895-b6fd-152072774909</prototypeId>
<componentRootId>0f9753a4-bad5-4842-9ee5-f8565c53c0e0</componentRootId>
<name>StaticColumn</name>
<container>false</container>
<childrenReordered>false</childrenReordered>
<scripts id="bc6afb28-7884-477d-b425-2c2001be8379">
<properties>
<entry>
<key>valueFormatter</key>
<value>
<implRef type="TS">
<className>DefaultValueFormatter</className>
<packageName>component.grid.formatters</packageName>
</implRef>
</value>
</entry>
</properties>
</scripts>
<scripts id="a930059f-1e14-40ed-a4de-3dec3d03f9a7">
<properties>
<entry>
<key>displayName</key>
<value>
<simple>"Активен"</simple>
</value>
</entry>
<entry>
<key>field</key>
<value>
<complex>
<entry>
<key>column</key>
<value>
<simple>"enabled"</simple>
</value>
</entry>
<entry>
<key>filterType</key>
<value>
<simple>"TEXT"</simple>
</value>
</entry>
<entry>
<key>type</key>
<value>
<simple>"java.lang.String"</simple>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>hidden</key>
<value>
<simple>true</simple>
</value>
</entry>
<entry>
<key>sortable</key>
<value>
<simple>false</simple> <simple>false</simple>
</value> </value>
</entry> </entry>

View file

@ -788,7 +788,6 @@
<componentRootId>c656213a-75da-4dd2-ac85-b44c05c18665</componentRootId> <componentRootId>c656213a-75da-4dd2-ac85-b44c05c18665</componentRootId>
<name>Vbox_LOAD</name> <name>Vbox_LOAD</name>
<container>true</container> <container>true</container>
<expanded>false</expanded>
<childrenReordered>false</childrenReordered> <childrenReordered>false</childrenReordered>
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f"> <scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
<properties> <properties>
@ -944,7 +943,6 @@
<componentRootId>16989f4f-4bbf-4fad-9d75-1cc0dbd5b6c9</componentRootId> <componentRootId>16989f4f-4bbf-4fad-9d75-1cc0dbd5b6c9</componentRootId>
<name>Vbox_1-2</name> <name>Vbox_1-2</name>
<container>true</container> <container>true</container>
<expanded>false</expanded>
<childrenReordered>false</childrenReordered> <childrenReordered>false</childrenReordered>
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f"> <scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
<properties> <properties>
@ -1335,6 +1333,7 @@
<componentRootId>7772ae11-fa24-4a7c-8ce8-8746db142da2</componentRootId> <componentRootId>7772ae11-fa24-4a7c-8ce8-8746db142da2</componentRootId>
<name>Пол load_1</name> <name>Пол load_1</name>
<container>false</container> <container>false</container>
<expanded>false</expanded>
<childrenReordered>false</childrenReordered> <childrenReordered>false</childrenReordered>
<scripts id="b7c451ce-53e4-45be-8fec-2bcd67fac11c"> <scripts id="b7c451ce-53e4-45be-8fec-2bcd67fac11c">
<properties> <properties>
@ -1369,7 +1368,7 @@
<entry> <entry>
<key>value</key> <key>value</key>
<value> <value>
<simple>"FEMALE"</simple> <simple>"female"</simple>
</value> </value>
</entry> </entry>
</complex> </complex>
@ -1387,7 +1386,7 @@
<entry> <entry>
<key>value</key> <key>value</key>
<value> <value>
<simple>"MALE"</simple> <simple>"male"</simple>
</value> </value>
</entry> </entry>
</complex> </complex>
@ -1405,7 +1404,7 @@
<entry> <entry>
<key>value</key> <key>value</key>
<value> <value>
<simple>"Мужской"</simple> <simple>"мужской"</simple>
</value> </value>
</entry> </entry>
</complex> </complex>
@ -1423,7 +1422,7 @@
<entry> <entry>
<key>value</key> <key>value</key>
<value> <value>
<simple>"Женский"</simple> <simple>"женский"</simple>
</value> </value>
</entry> </entry>
</complex> </complex>
@ -2736,7 +2735,7 @@
<className>string</className> <className>string</className>
<packageName></packageName> <packageName></packageName>
</implRef> </implRef>
<simple>"Мужской"</simple> <simple>"мужской"</simple>
</value> </value>
</entry> </entry>
</complex> </complex>
@ -2804,7 +2803,7 @@
<className>string</className> <className>string</className>
<packageName></packageName> <packageName></packageName>
</implRef> </implRef>
<simple>"MALE"</simple> <simple>"male"</simple>
</value> </value>
</entry> </entry>
</complex> </complex>
@ -3004,7 +3003,7 @@
<className>string</className> <className>string</className>
<packageName></packageName> <packageName></packageName>
</implRef> </implRef>
<simple>"Женский"</simple> <simple>"женский"</simple>
</value> </value>
</entry> </entry>
</complex> </complex>
@ -3072,7 +3071,7 @@
<className>string</className> <className>string</className>
<packageName></packageName> <packageName></packageName>
</implRef> </implRef>
<simple>"FEMALE"</simple> <simple>"female"</simple>
</value> </value>
</entry> </entry>
</complex> </complex>
@ -8963,6 +8962,30 @@
<simple>null</simple> <simple>null</simple>
</value> </value>
</entry> </entry>
<entry>
<key>headerHeight</key>
<value>
<simple>40.0</simple>
</value>
</entry>
<entry>
<key>loadingOverlayMessage</key>
<value>
<simple>"Загрузка данных, пожалуйста, подождите."</simple>
</value>
</entry>
<entry>
<key>loadingOverlayType</key>
<value>
<simple>"TEXT_OVERLAY"</simple>
</value>
</entry>
<entry>
<key>noRowsOverlayMessage</key>
<value>
<simple>"Данные отсутствуют"</simple>
</value>
</entry>
<entry> <entry>
<key>pagination</key> <key>pagination</key>
<value> <value>
@ -8975,6 +8998,31 @@
<simple>"SINGLE_SELECT_CLICK"</simple> <simple>"SINGLE_SELECT_CLICK"</simple>
</value> </value>
</entry> </entry>
<entry>
<key>rowHeight</key>
<value>
<simple>40.0</simple>
</value>
</entry>
<entry>
<key>style</key>
<value>
<complex>
<entry>
<key>height</key>
<value>
<simple>"300px"</simple>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>theme</key>
<value>
<simple>"BALHAM"</simple>
</value>
</entry>
<entry> <entry>
<key>visible</key> <key>visible</key>
<value> <value>

View file

@ -1297,6 +1297,24 @@
</complex> </complex>
</value> </value>
</item> </item>
<item id="d67c7c75-7860-463e-8cfb-759f4ae74e57" removed="false">
<value>
<complex>
<entry>
<key>label</key>
<value>
<simple>"Активация пользователя"</simple>
</value>
</entry>
<entry>
<key>value</key>
<value>
<simple>"UNBLOCK_USER"</simple>
</value>
</entry>
</complex>
</value>
</item>
<item id="3a8f7695-26c6-4761-9997-a5c09b344960" removed="false"> <item id="3a8f7695-26c6-4761-9997-a5c09b344960" removed="false">
<value> <value>
<complex> <complex>
@ -2915,6 +2933,44 @@
</properties> </properties>
</scripts> </scripts>
</children> </children>
<children id="a9fe3332-1c67-43e6-8427-093584409caa">
<prototypeId>c8dfe691-a84a-48da-b79e-6298d90db71d</prototypeId>
<componentRootId>a9fe3332-1c67-43e6-8427-093584409caa</componentRootId>
<name>Создать заявку на активацию пользователя</name>
<container>false</container>
<childrenReordered>false</childrenReordered>
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
<removed>true</removed>
</scripts>
<scripts id="42e7c690-5629-47fd-96b7-3b39ee2949e0">
<classRef type="TS">
<className>StaticRouteNavigationButton</className>
<packageName>modules.user-management.component</packageName>
</classRef>
<enabled>true</enabled>
<expanded>true</expanded>
<properties>
<entry>
<key>caption</key>
<value>
<simple>"Создать заявку на активацию"</simple>
</value>
</entry>
<entry>
<key>route</key>
<value>
<simple>"/unblock_user_application"</simple>
</value>
</entry>
<entry>
<key>visible</key>
<value>
<simple>true</simple>
</value>
</entry>
</properties>
</scripts>
</children>
<children id="ff5d942c-950d-4b8c-9c41-b403a74e3831"> <children id="ff5d942c-950d-4b8c-9c41-b403a74e3831">
<prototypeId>c8dfe691-a84a-48da-b79e-6298d90db71d</prototypeId> <prototypeId>c8dfe691-a84a-48da-b79e-6298d90db71d</prototypeId>
<componentRootId>ff5d942c-950d-4b8c-9c41-b403a74e3831</componentRootId> <componentRootId>ff5d942c-950d-4b8c-9c41-b403a74e3831</componentRootId>