<%#
 Copyright 2013-2024 the original author or authors from the JHipster project.

 This file is part of the JHipster project, see https://www.jhipster.tech/
 for more information.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      https://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-%>
package <%= packageName %>.web.rest;


<%_
const pageName = ormTool !== 'mybatis' ? 'Page': 'IPage';
const pageGetContent = ormTool !== 'mybatis' ? 'getContent': 'getRecords';
const pageGetTotal = ormTool !== 'mybatis' ? 'getTotalElements': 'getTotal';
const pageGetCurrent = ormTool === 'mybatis' ? 'getCurrent': 'getNumber';
const pageUtil = ormTool !== 'mybatis' ? 'PaginationUtil': 'IPageUtil';
const pageInstance = ormTool !== 'mybatis' ? 'pageable' : 'PageableUtils.toPage(pageable)'
_%>
import <%= packageName %>.config.Constants;
import <%= entityAbsoluteClass %>;
import <%= packageName %>.repository.UserRepository;
import <%= packageName %>.security.AuthoritiesConstants;
import <%= packageName %>.service.MailService;
import org.springframework.data.domain.Sort;
import java.util.Collections;
import io.swagger.v3.oas.annotations.Operation;
import <%= packageName %>.service.UserService;
import <%= packageName %>.service.dto.<%= adminUserDto %>;
import <%= packageName %>.service.dto.<%= dtoClass %>;
import <%= packageName %>.web.rest.errors.BadRequestAlertException;
import <%= packageName %>.web.rest.errors.EmailAlreadyUsedException;
import <%= packageName %>.web.rest.errors.LoginAlreadyUsedException;

import tech.jhipster.web.util.HeaderUtil;
import tech.jhipster.web.util.PageRecord;
import <%= packageName %>.aop.logging.AutoLog;
import <%= packageName %>.domain.enumeration.LogType;
import <%= packageName %>.domain.enumeration.OperateType;
import <%= packageName %>.service.UserQueryService;
import <%= packageName %>.service.criteria.UserCriteria;
<%_ if (databaseTypeSql || databaseTypeMongodb || databaseTypeNeo4j || databaseTypeCouchbase) { _%>
  <%_ if (ormTool === 'hibernate') { _%>
import tech.jhipster.web.util.PaginationUtil;
  <%_ } else { _%>
import <%= packageName %>.util.web.IPageUtil;
import <%= packageName %>.util.web.PageableUtils;
  <%_ } _%>
<%_ } _%>
<%_ if (!reactive) { _%>
import tech.jhipster.web.util.ResponseUtil;
<%_ } _%>

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
<%_ if (databaseTypeSql || databaseTypeMongodb || databaseTypeNeo4j || databaseTypeCouchbase) { _%>
  <%_ if (reactive) { _%>
import org.springframework.data.domain.PageImpl;
  <%_ } else { _%>
    <%_ if (ormTool === 'hibernate') { _%>
import org.springframework.data.domain.Page;
    <%_ } else { _%>
import org.apache.commons.collections4.CollectionUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
    <%_ } _%>
  <%_ } _%>
import org.springframework.data.domain.Pageable;
  <%_ if (!reactive) { _%>
import org.springframework.http.HttpHeaders;
  <%_ } _%>
<%_ } _%>
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
<%_ if (reactive) { _%>
import org.springframework.http.server.reactive.ServerHttpRequest;
<%_ } _%>
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
<%_ if (reactive) { _%>
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.util.ForwardedHeaderUtils;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
<%_ } else { _%>
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
<%_ } _%>

import <%= javaVersion === '17' ? 'jakarta' : 'javax'%>.validation.constraints.Pattern;
import <%= javaVersion === '17' ? 'jakarta' : 'javax'%>.validation.Valid;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
<%_ if (searchEngineElasticsearch && !reactive) { _%>
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
<%_ } _%>

/**
 * REST controller for managing users.
 * <p>
 * This class accesses the {@link <%= entityAbsoluteClass %>} entity, and needs to fetch its collection of authorities.
 * <p>
 * For a normal use-case, it would be better to have an eager relationship between User and Authority,
 * and send everything to the client side: there would be no View Model and DTO, a lot less code, and an outer-join
 * which would be good for performance.
 * <p>
 * We use a View Model and a DTO for 3 reasons:
 * <ul>
 * <li>We want to keep a lazy association between the user and the authorities, because people will
 * quite often do relationships with the user, and we don't want them to get the authorities all
 * the time for nothing (for performance reasons). This is the #1 goal: we should not impact our users'
 * application because of this use-case.</li>
 * <li> Not having an outer join causes n+1 requests to the database. This is not a real issue as
 * we have by default a second-level cache. This means on the first HTTP call we do the n+1 requests,
 * but then all authorities come from the cache, so in fact it's much better than doing an outer join
 * (which will get lots of data from the database, for each HTTP call).</li>
 * <li> As this manages users, for security reasons, we'd rather have a DTO layer.</li>
 * </ul>
 * <p>
 * Another option would be to have a specific JPA entity graph to handle this case.
 */
@RestController
@RequestMapping("/api/admin")
public class UserResource {
    private static final List<String> ALLOWED_ORDERED_PROPERTIES = Collections.unmodifiableList(Arrays.asList(
    "id", "login", "firstName", "lastName", "email", "activated", "langKey", "createdBy", "createdDate", "lastModifiedBy", "lastModifiedDate"));

    private static final Logger log = LoggerFactory.getLogger(UserResource.class);
    private static final String ENTITY_NAME = "systemUser";

    @Value("${jhipster.clientApp.name}")
    private String applicationName;

    private final UserService userService;

    private final UserRepository userRepository;

    private final MailService mailService;

    private final UserQueryService userQueryService;

    public UserResource(UserService userService, UserRepository userRepository, MailService mailService, UserQueryService userQueryService) {
        this.userService = userService;
        this.userRepository = userRepository;
        this.mailService = mailService;
        this.userQueryService = userQueryService;
    }
<%_ if (applicationTypeMonolith || applicationTypeMicroservice && !authenticationTypeOauth2) { _%>

    /**
     * {@code POST  /admin/users}  : Creates a new user.
     * <p>
     * Creates a new user if the login and email are not already used, and sends an
     * mail with an activation link.
     * The user needs to be activated on creation.
     *
     * @param userDTO the user to create.
     * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new user, or with status {@code 400 (Bad Request)} if the login or email is already in use.
<%_ if (!reactive) { _%>
     * @throws URISyntaxException if the Location URI syntax is incorrect.
<%_ } _%>
     * @throws BadRequestAlertException {@code 400 (Bad Request)} if the login or email is already in use.
     */
    @PostMapping("/users")
    @PreAuthorize("hasAuthority(\"" + AuthoritiesConstants.ADMIN + "\")")
    public <% if (reactive) { %>Mono<ResponseEntity<<%= persistClass %>>><% } else { %>ResponseEntity<<%= persistClass %>><% } %> createUser(@Valid @RequestBody <%= adminUserDto %> userDTO)<% if (!reactive) { %> throws URISyntaxException<% } %> {
        log.debug("REST request to save User : {}", userDTO);

        if (userDTO.getId() != null) {
            throw new BadRequestAlertException("A new user cannot already have an ID", "userManagement", "idexists");
            // Lowercase the user login before comparing with database
<%_ if (reactive) { _%>
        }
        return userRepository.findOneByLogin(userDTO.getLogin().toLowerCase())
            .hasElement()
            .flatMap(loginExists -> {
                if (Boolean.TRUE.equals(loginExists)) {
                    return Mono.error(new LoginAlreadyUsedException());
                }
                return userRepository.findOneByEmailIgnoreCase(userDTO.getEmail());
            })
            .hasElement()
            .flatMap(emailExists -> {
                if (Boolean.TRUE.equals(emailExists)) {
                    return Mono.error(new EmailAlreadyUsedException());
                }
                return userService.createUser(userDTO);
            })
            .doOnSuccess(mailService::sendCreationEmail)
            .map(user -> {
                try {
                    return ResponseEntity.created(new URI("/api/admin/users/" + user.getLogin()))
                        .headers(HeaderUtil.createAlert(applicationName, <% if (enableTranslation) { %> "userManagement.created"<% } else { %> "A user is created with identifier " + user.getLogin()<% } %>, user.getLogin()))
                        .body(user);
                } catch (URISyntaxException e) {
                    throw new RuntimeException(e);
                }
            });
<%_ } else { _%>
        } else if (userRepository.findOneByLogin(userDTO.getLogin().toLowerCase()).isPresent()) {
            throw new LoginAlreadyUsedException();
        } else if (userRepository.findOneByEmailIgnoreCase(userDTO.getEmail()).isPresent()) {
            throw new EmailAlreadyUsedException();
        } else {
            <%= persistClass %> newUser = userService.createUser(userDTO);
            mailService.sendCreationEmail(newUser);
            return ResponseEntity.created(new URI("/api/admin/users/" + newUser.getLogin()))
                .headers(HeaderUtil.createAlert(applicationName, <% if (enableTranslation) { %> "userManagement.created"<% } else { %> "A user is created with identifier " + newUser.getLogin()<% } %>, newUser.getLogin()))
                .body(newUser);
        }
<%_ } _%>
    }

    /**
     * {@code PUT /admin/users} : Updates an existing User.
     *
     * @param userDTO the user to update.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated user.
     * @throws EmailAlreadyUsedException {@code 400 (Bad Request)} if the email is already in use.
     * @throws LoginAlreadyUsedException {@code 400 (Bad Request)} if the login is already in use.
     */
    @PutMapping("/users")
    @PreAuthorize("hasAuthority(\"" + AuthoritiesConstants.ADMIN + "\")")
<%_ if (reactive) { _%>
    public Mono<ResponseEntity<<%= adminUserDto %>>> updateUser(@Valid @RequestBody <%= adminUserDto %> userDTO) {
        log.debug("REST request to update User : {}", userDTO);
        return userRepository.findOneByEmailIgnoreCase(userDTO.getEmail())
            .filter(user -> !user.getId().equals(userDTO.getId()))
            .hasElement()
            .flatMap(emailExists -> {
                if (Boolean.TRUE.equals(emailExists)) {
                    return Mono.error(new EmailAlreadyUsedException());
                }
                return userRepository.findOneByLogin(userDTO.getLogin().toLowerCase());
            })
            .filter(user -> !user.getId().equals(userDTO.getId()))
            .hasElement()
            .flatMap(loginExists -> {
                if (Boolean.TRUE.equals(loginExists)) {
                    return Mono.error(new LoginAlreadyUsedException());
                }
                return userService.updateUser(userDTO);
            })
            .switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.NOT_FOUND)))
            .map(user -> ResponseEntity.ok()
                .headers(HeaderUtil.createAlert(applicationName, <% if (enableTranslation) { %>"userManagement.updated"<% } else { %>"A user is updated with identifier " + userDTO.getLogin()<% } %>, userDTO.getLogin()))
                .body(user)
            );
<%_ } else { _%>
    public ResponseEntity<<%= adminUserDto %>> updateUser(@Valid @RequestBody <%= adminUserDto %> userDTO) {
        log.debug("REST request to update User : {}", userDTO);
        Optional<<%= persistClass %>> existingUser = userRepository.findOneByEmailIgnoreCase(userDTO.getEmail());
        if (existingUser.isPresent() && (!existingUser.orElseThrow(<% if (javaVersion === '8') { %>() -> new NoSuchElementException("No value present")<% } %>).getId().equals(userDTO.getId()))) {
            throw new EmailAlreadyUsedException();
        }
        existingUser = userRepository.findOneByLogin(userDTO.getLogin().toLowerCase());
        if (existingUser.isPresent() && (!existingUser.orElseThrow(<% if (javaVersion === '8') { %>() -> new NoSuchElementException("No value present")<% } %>).getId().equals(userDTO.getId()))) {
            throw new LoginAlreadyUsedException();
        }
        Optional<<%= adminUserDto %>> updatedUser = userService.updateUser(userDTO);

        return ResponseUtil.wrapOrNotFound(updatedUser,
            HeaderUtil.createAlert(applicationName, <% if (enableTranslation) { %>"userManagement.updated"<% } else { %>"A user is updated with identifier " + userDTO.getLogin()<% } %>, userDTO.getLogin()));
<%_ } _%>
    }

    /**
     * {@code PUT /admin/users/{id}} : Updates an existing User.
     *
     * @param userDTO the user to update.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated user.
     * @throws EmailAlreadyUsedException {@code 400 (Bad Request)} if the email is already in use.
     * @throws LoginAlreadyUsedException {@code 400 (Bad Request)} if the login is already in use.
     */
    @PutMapping("/users/{id}")
    @PreAuthorize("hasAuthority(\"" + AuthoritiesConstants.ADMIN + "\")")
<%_ if (reactive) { _%>
    public Mono<ResponseEntity<<%= adminUserDto %>>> updateUserById(@PathVariable <%= user.primaryKey.type %> id,@Valid @RequestBody <%= adminUserDto %> userDTO) {
        log.debug("REST request to update User : {}", userDTO);
        return userRepository.findOneByEmailIgnoreCase(userDTO.getEmail())
            .filter(user -> !user.getId().equals(userDTO.getId()))
            .hasElement()
            .flatMap(emailExists -> {
                if (Boolean.TRUE.equals(emailExists)) {
                    return Mono.error(new EmailAlreadyUsedException());
                }
                return userRepository.findOneByLogin(userDTO.getLogin().toLowerCase());
            })
            .filter(user -> !user.getId().equals(userDTO.getId()))
            .hasElement()
            .flatMap(loginExists -> {
                if (Boolean.TRUE.equals(loginExists)) {
                    return Mono.error(new LoginAlreadyUsedException());
                }
                return userService.updateUser(userDTO);
            })
            .switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.NOT_FOUND)))
            .map(user -> ResponseEntity.ok()
                .headers(HeaderUtil.createAlert(applicationName, <% if (enableTranslation) { %>"userManagement.updated"<% } else { %>"A user is updated with identifier " + userDTO.getLogin()<% } %>, userDTO.getLogin()))
                .body(user)
            );
<%_ } else { _%>
    public ResponseEntity<<%= adminUserDto %>> updateUserById(@PathVariable(name = "login", required = false) @Pattern(regexp = Constants.LOGIN_REGEX) String login, @Valid @RequestBody <%= adminUserDto %> userDTO) {
        log.debug("REST request to update User : {}", userDTO);
        Optional<<%= persistClass %>> existingUser = userRepository.findOneByEmailIgnoreCase(userDTO.getEmail());
        if (existingUser.isPresent() && (!existingUser.orElseThrow(<% if (javaVersion === '8') { %>() -> new NoSuchElementException("No value present")<% } %>).getId().equals(userDTO.getId()))) {
            throw new EmailAlreadyUsedException();
        }
        existingUser = userRepository.findOneByLogin(userDTO.getLogin().toLowerCase());
        if (existingUser.isPresent() && (!existingUser.orElseThrow(<% if (javaVersion === '8') { %>() -> new NoSuchElementException("No value present")<% } %>).getId().equals(userDTO.getId()))) {
            throw new LoginAlreadyUsedException();
        }
        Optional<<%= adminUserDto %>> updatedUser = userService.updateUser(userDTO);

        return ResponseUtil.wrapOrNotFound(updatedUser,
            HeaderUtil.createAlert(applicationName, <% if (enableTranslation) { %>"userManagement.updated"<% } else { %>"A user is updated with identifier " + userDTO.getLogin()<% } %>, userDTO.getLogin()));
<%_ } _%>
    }
<%_ } _%>

    /**
     * {@code GET /admin/users} : get all users with all the details - calling this are only allowed for the administrators.
     *<% if (databaseTypeSql || databaseTypeMongodb || databaseTypeNeo4j || databaseTypeCouchbase) { %>
<%_ if (reactive) { _%>
     * @param request a {@link ServerHttpRequest} request.
<%_ } _%>
     * @param pageable the pagination information.<% } %>
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body all users.
     */
    @GetMapping("/users")
    @PreAuthorize("hasAuthority(\"" + AuthoritiesConstants.ADMIN + "\")")
<%_ if (databaseTypeSql || databaseTypeMongodb || databaseTypeNeo4j || databaseTypeCouchbase) { _%>
  <%_ if (reactive) { _%>
    public Mono<ResponseEntity<Flux<<%= adminUserDto %>>>> getAllUsers(@org.springdoc.core.annotations.ParameterObject ServerHttpRequest request, @org.springdoc.core.annotations.ParameterObject Pageable pageable) {
        log.debug("REST request to get all User for an admin");
        if (!onlyContainsAllowedProperties(pageable)) {
            return Mono.just(ResponseEntity.badRequest().build());
        }

        return userService.countManagedUsers()
            .map(total -> new PageImpl<>(new ArrayList<>(), pageable, total))
            .map(page -> PaginationUtil.generatePaginationHttpHeaders(ForwardedHeaderUtils.adaptFromForwardedHeaders(request.getURI(), request.getHeaders()), page))
            .map(headers -> ResponseEntity.ok().headers(headers).body(userService.getAllManagedUsers(pageable)));
  <%_ } else { _%>
    public ResponseEntity<PageRecord<<%= dtoClass %>>> getAllUsers(UserCriteria criteria, @org.springdoc.<%= javaVersion === '8' ? 'api' : 'core'%>.annotations.ParameterObject Pageable pageable) {
        log.debug("REST request to get all User for an admin");
        if (!onlyContainsAllowedProperties(pageable)) {
            return ResponseEntity.badRequest().build();
        }

        final <%= pageName %><<%= dtoClass %>> page = userQueryService.findByCriteria(criteria, <%- pageInstance%>);
        PageRecord<<%= dtoClass %>> result = new PageRecord<>();
        result.records(page.<%= pageGetContent%>()).size(page.getSize()).total(page.<%= pageGetTotal %>()).page(page.<%= pageGetCurrent %>());
        HttpHeaders headers = <%= pageUtil%>.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page);
        return ResponseEntity.ok().headers(headers).body(result);
  <%_ } _%>
    }

    @GetMapping("/users/stats")
    @Operation(tags = "根据条件对用户进行统计", description = "条件和统计的配置通过用户的Criteria类来实现")
    @AutoLog(value = "根据条件对用户进行统计", logType = LogType.OPERATE, operateType = OperateType.STATS)
    public ResponseEntity<List<Map<String, Object>>> stats(UserCriteria criteria) {
        log.debug("REST request to get stats by criteria: {}", criteria);
        List<Map<String, Object>> statsMapList = userQueryService.statsByAggregateCriteria(criteria);
        return ResponseEntity.ok().body(statsMapList);
    }

    private boolean onlyContainsAllowedProperties(Pageable pageable) {
        return pageable.getSort().stream().map(Sort.Order::getProperty).allMatch(ALLOWED_ORDERED_PROPERTIES::contains);
    }

<%_ } else { /* Cassandra */ _%>
    public <% if (reactive) { %>Flux<% } else { %>List<% } %><<%= adminUserDto %>> getAllUsers() {
        log.debug("REST request to get all User for an admin");
        return userService.getAllManagedUsers();
    }

    <%_ } _%>
    /**
     * {@code GET /admin/users/:id} : get the "id" user.
     *
     * @param id the id of the user to find.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the "id" user, or with status {@code 404 (Not Found)}.
     */
    @GetMapping("/users/id/{id}")
    @PreAuthorize("hasAuthority(\"" + AuthoritiesConstants.ADMIN + "\")")
    <%_ if (!reactive) { _%>
    public ResponseEntity<<%= user.adminUserDto %>> getUserById(@PathVariable <%= databaseTypeSql ? userIdTypeName : 'String'%> id) {
        log.debug("REST request to get User : {}", id);
        return ResponseUtil.wrapOrNotFound(
            userService.getUserWithAuthorities(id));
    <%_ } else { _%>
    public Mono<<%= user.adminUserDto %>> getUserById(@PathVariable <%= databaseTypeSql ? userIdTypeName : 'String'%> id) {
        log.debug("REST request to get User : {}", id);
        return userService.getUserWithAuthorities(id)
            .switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.NOT_FOUND)));
    <%_ } _%>
    }

    /**
     * {@code GET /admin/users/login/:login} : get the "login" user.
     *
     * @param login the login of the user to find.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the "login" user, or with status {@code 404 (Not Found)}.
     */
    @GetMapping("/users/login/{login}")
    @PreAuthorize("hasAuthority(\"" + AuthoritiesConstants.ADMIN + "\")")
<%_ if (reactive) { _%>
    public Mono<<%= adminUserDto %>> getUser(@PathVariable("login") String login) {
        log.debug("REST request to get User : {}", login);
        return userService.getUserWithAuthoritiesByLogin(login)
            .map(<%= adminUserDto %>::new)
            .switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.NOT_FOUND)));
<%_ } else { _%>
    public ResponseEntity<<%= adminUserDto %>> getUser(@PathVariable("login") @Pattern(regexp = Constants.LOGIN_REGEX) String login) {
        log.debug("REST request to get User : {}", login);
        return ResponseUtil.wrapOrNotFound(
            userService.getUserWithAuthoritiesByLogin(login));
<%_ } _%>
    }

    /**
     * {@code DELETE /admin/users/:login} : delete the "login" User.
     *
     * @param login the login of the user to delete.
     * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}.
     */
    @DeleteMapping("/users/{login}")
    @PreAuthorize("hasAuthority(\"" + AuthoritiesConstants.ADMIN + "\")")
<%_ if (reactive) { _%>
    public Mono<ResponseEntity<Void>> deleteUser(@PathVariable("login") @Pattern(regexp = Constants.LOGIN_REGEX) String login) {
        log.debug("REST request to delete User: {}", login);
        return userService.deleteUser(login)
        .then(Mono.just(ResponseEntity.noContent().headers(HeaderUtil.createAlert( applicationName, <% if (enableTranslation) { %> "userManagement.deleted"<% } else { %> "A user is deleted with identifier " + login<% } %>, login)).build()));
<%_ } else { _%>
    public ResponseEntity<Void> deleteUser(@PathVariable("login") @Pattern(regexp = Constants.LOGIN_REGEX) String login) {
        log.debug("REST request to delete User: {}", login);
        <%= authenticationTypeOauth2 ? '// todo ': ''%>userService.deleteUser(login);
        return ResponseEntity.noContent().headers(HeaderUtil.createAlert(applicationName, <% if (enableTranslation) { %> "userManagement.deleted"<% } else { %> "A user is deleted with identifier " + login<% } %>, login)).build();
<%_ } _%>
    }

    <%_
    const instanceType = restClass;
    const instanceName = restInstance;
    const mapper = entityInstance  + 'Mapper';
    const entityToDtoReference = mapper + '::' + 'toDto';
    _%>
    /**
     * {@code PUT  /<%= entityApiUrl %>/id/:<%= primaryKey.name %>} : Updates an existing <%= entityInstance %>.
     *
     * @param <%= primaryKey.name %> the id of the <%= instanceName %> to save.
     * @param <%= instanceName %> the <%= instanceName %> to update.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated <%= instanceName %>,
     * or with status {@code 400 (Bad Request)} if the <%= instanceName %> is not valid,
     * or with status {@code 500 (Internal Server Error)} if the <%= instanceName %> couldn't be updated.
     * @throws URISyntaxException if the Location URI syntax is incorrect.
     */
    @PutMapping("/users/id/{<%= primaryKey.name %>}")
    @Operation(tags = "更新<%= bcTitle%>", description = "根据主键更新并返回一个更新后的<%= bcTitle%>")
    @AutoLog(value = "更新<%= bcTitle%>", logType = LogType.OPERATE, operateType = OperateType.EDIT)
  <%_ if (entitySpringPreAuthorize) { _%>
    @PreAuthorize("<%- entitySpringPreAuthorize %>")
  <%_ } _%>
    public <% if (reactive) { %>Mono<<% } %>ResponseEntity<<%= instanceType %>><% if (reactive) { %>><% } %> update<%= entityClass %>(
        @PathVariable(value = "<%= primaryKey.name %>", required = false) final <%= primaryKey.type %> <%= primaryKey.name %>,
        <% if (anyPropertyHasValidation) { %>@Valid <% } %>@RequestBody <%= restClass %> <%= restInstance %>,
        @RequestParam(value = "batchIds", required = false) ArrayList<<%= primaryKey.type %>> batchIds,
        @RequestParam(value = "batchFields", required = false) ArrayList<String> batchFields
    ) {
        log.debug("REST request to update <%= entityClass %> : {}, {}", <%= primaryKey.name %>, <%= instanceName %>);
        if (<%= instanceName %>.get<%= primaryKey.nameCapitalized %>() == null) {
            throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
        }
        if (!Objects.equals(<%= primaryKey.name %>, <%= instanceName %>.get<%= primaryKey.nameCapitalized %>())) {
            throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid");
        }

  <%_ if (reactive) { _%>
        return <%= entityInstance %>Repository
            .existsById(<%= primaryKey.name %>)
            .flatMap(exists -> {
                if (!exists) {
                    return Mono.error(new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"));
                }
  <%_ } else { _%>
      <%_ if (ormTool === 'hibernate') { _%>
        if (!<%= entityInstance %>Repository.existsById(<%= primaryKey.name %>)) {
      <%_ } else { _%>
        if (<%= entityInstance %>Repository.findById(<%= primaryKey.name %>).<%= javaVersion === '17' ? 'isEmpty()' : 'isPresent()'%>) {
      <%_ } _%>
            throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound");
        }
  <%_ } _%>

  <%_ if (saveUserSnapshot) { _%>
    <% for (const userRelationship of relationships.filter(rel => rel.otherEntity.builtInUser)) { %>
      <%_ if (userRelationship.collection) { _%>
        if (<%= instanceName %>.get<%= userRelationship.relationshipNameCapitalizedPlural %>() != null) {
            // Save users in case they are new and only exist in gateway
            userRepository.saveAll(<%= instanceName %>.get<%= userRelationship.relationshipNameCapitalizedPlural %>());
        }
      <%_ } else { _%>
        if (<%= instanceName %>.get<%= userRelationship.relationshipNameCapitalized %>() != null) {
            // Save user in case it's new and only exists in gateway
            userRepository.save(<%= instanceName %>.get<%= userRelationship.relationshipNameCapitalized %>());
        }
      <%_ } _%>
    <% } %>
  <%_ } _%>
  <%_ if (serviceNo) { _%>
    <%_ if (ormTool === 'mybatis') { _%>
    <%- include('../../_partials_entity_/mybatis_save_get_template', {saveNewEntityOperation: false, returnDirectly: false}); -%>
    <%_ } else { _%>
    <%- include('/_global_partials_entity_/save_template', {saveNewEntityOperation: false, returnDirectly: false}); -%>
    <%_ } _%>
  <%_ } _%>
  <%_ if (reactive) { _%>
    <%_ if (!serviceNo) { _%>
            return <%= entityInstance %>Service
                .update(<%= restInstance %>)
    <%_ } _%>
                .switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.NOT_FOUND)))
                .map(result -> ResponseEntity.ok()
                    .headers(HeaderUtil.createEntityUpdateAlert(applicationName, <%= enableTranslation %>, ENTITY_NAME, result.get<%= primaryKey.nameCapitalized %>()<% if (!primaryKey.typeString) { %>.toString()<% } %>))
                    .body(result)
                );
        });
  <%_ } else { _%>
    <%_ if (!serviceNo) { _%>
        if (CollectionUtils.isNotEmpty(batchFields) && CollectionUtils.isNotEmpty(batchIds)) {
            batchIds = new ArrayList<>(batchIds);
            if (!batchIds.contains(<%= primaryKey.name %>)) {
                batchIds.add(<%= primaryKey.name %>);
            }
            <%= entityInstance %>Service.updateBatch(<%= restInstance %>, batchFields, batchIds);
            <%- restInstance %> = <%= entityInstance %>Service.findOne(<%= primaryKey.name %>).orElseThrow(<% if (javaVersion === '8') { %>() -> new NoSuchElementException("No value present")<% } %>);
        } else {
            <%- restInstance %> = <%= entityInstance %>Service.update(<%= restInstance %>);
        }
    <%_ } _%>
        return ResponseEntity.ok()
            .headers(HeaderUtil.createEntityUpdateAlert(applicationName, <%= enableTranslation %>, ENTITY_NAME, <%- restInstance %>.get<%= primaryKey.nameCapitalized %>()<% if (!primaryKey.typeString) { %>.toString()<% } %>))
            .body(<%- restInstance %>);
  <%_ } _%>
    }
<%_ if (ormTool === 'mybatis') { _%>

    /**
     * {@code PUT  /admin/users/relations/:operateType} : Updates relationships an existing user.
     *
     * @param operateType the operateType of the User to update.
     * @param otherEntityIds the otherEntityIds to update.
     * @param relationshipName the relationshipName to update.
     * @param relatedIds the relation relatedIds.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated success or not,
     * or with status {@code 400 (Bad Request)},
     * or with status {@code 500 (Internal Server Error)}.
     */
    @PutMapping("/users/relations/{operateType}")
    @PreAuthorize("hasAuthority(\"" + AuthoritiesConstants.ADMIN + "\")")
    @Operation(tags = "更新用户关联关系", description = "根据主键更新用户关联关系")
    @AutoLog(value = "更新用户关联关系", logType = LogType.OPERATE, operateType = OperateType.EDIT)
    public ResponseEntity<Boolean> updateRelationships(
        @PathVariable(value = "operateType") final String operateType,
        @RequestParam(value = "otherEntityIds") ArrayList<String> otherEntityIds,
        @RequestParam(value = "relationshipName") String relationshipName,
        @RequestParam(value = "relatedIds") ArrayList<Long> relatedIds
    ) {
        log.debug("REST request to update Authority : {}, {}", otherEntityIds, operateType);
        if (CollectionUtils.isEmpty(relatedIds)) {
            return ResponseEntity.ok(true);
        }
        userService.updateRelationships(otherEntityIds, relationshipName, relatedIds, operateType);
        return ResponseEntity.ok(true);
    }
<%_ } _%>
}
