# NightAuditLogController.java

    package cloud.wconnect.frontoffice.controller.nightauditlog;

    import cloud.wconnect.commonlib.annotation.ApiId;
    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.component.SessionContext;
    import cloud.wconnect.commonlib.cons.BaseConstant;
    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.cons.CommonErrorI18nConstant;
    import cloud.wconnect.commonlib.exception.BadRequestException;
    import cloud.wconnect.commonlib.exception.ForbiddenException;
    import cloud.wconnect.commonlib.pojo.dto.ListPagedDTO;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.frontoffice.cons.nightauditlog.NightAuditLogEnum;
    import cloud.wconnect.frontoffice.entity.nightauditlog.NightAuditLog;
    import cloud.wconnect.frontoffice.pojo.dto.nigntauditlog.NightAuditLogDTO;
    import cloud.wconnect.frontoffice.pojo.query.NightAuditLogQuery;
    import cloud.wconnect.frontoffice.pojo.vo.nightauditlog.NightAuditLogTotalVO;
    import cloud.wconnect.frontoffice.service.nightauditlog.INightAuditLogService;
    import com.google.common.collect.ImmutableMap;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.validation.annotation.Validated;
    import org.springframework.web.bind.annotation.*;

    import jakarta.validation.Valid;

    import java.text.MessageFormat;
    import java.util.Collections;
    import java.util.Map;
    import java.util.Objects;

    /**
     * <p>
     * 前端控制器
     * </p>
     *
     * @author lichen
     * @since 2023-03-16
     */
    @RestController
    @RequestMapping("/night-audit-log")
    public class NightAuditLogController {

        @Autowired
        private INightAuditLogService nightAuditLogService;
        @Autowired
        private BeanMapper beanMapper;
        @Autowired
        private SessionContext sessionContext;

        /**
         * 获取 Night Audit Log 列表
         *
         * @param property 资产标识
         * @param logQuery 检索条件
         * @return cloud.wconnect.commonlib.pojo.dto.ListPagedDTO<cloud.wconnect.frontoffice.pojo.dto.nigntauditlog.NightAuditLogDTO>
         * @author lichen
         * @date 2025/8/22
         */
        @ApiId(109)
        @GetMapping
        public ListPagedDTO<NightAuditLogDTO> page(String property, @Validated(NightAuditLogQuery.Page.class) NightAuditLogQuery logQuery) {
            int propertyId = sessionContext.getPropertyId(property);
            Integer tenantId = sessionContext.getTenantSymbolBO().getId();

            return nightAuditLogService.pageList(tenantId, propertyId, logQuery);
        }

        /**
         * 获取Night Audit Log 不同状态下的数据总数
         *
         * @param property 资产标识
         * @param logQuery 查询条件
         * @return cloud.wconnect.frontoffice.pojo.vo.nightauditlog.NightAuditLogTotalVO
         * @author lichen
         * @date 2025/8/22
         */
        @ApiId(110)
        @GetMapping("/summary")
        public NightAuditLogTotalVO summary(String property, @Validated(NightAuditLogQuery.Summary.class) NightAuditLogQuery logQuery) {
            int propertyId = sessionContext.getPropertyId(property);

            //获取pending 下的Log数量统计
            logQuery.setStatus(NightAuditLogEnum.STATUS_PENDING.getStatus());
            long pendingTotal = nightAuditLogService.count(propertyId, logQuery);

            //获取Resolved 下的Log数量统计
            logQuery.setStatus(NightAuditLogEnum.STATUS_RESOLVED.getStatus());
            long resolvedTotal = nightAuditLogService.count(propertyId, logQuery);

            return NightAuditLogTotalVO.builder()
                    .pendingTotal(pendingTotal)
                    .resolvedTotal(resolvedTotal)
                    .build();
        }

        /**
         * 保存 Night Audit Log 的信息
         *
         * @param logId    主键id
         * @param logDTO   NightAuditLog 信息
         * @param property 资产标识
         * @return java.util.Map
         * @author lichen
         * @date 2025/8/22
         */
        @ApiId(111)
        @PostMapping(value = "/{logId:\\d+}")
        public Map save(@PathVariable long logId, @Valid @RequestBody NightAuditLogDTO logDTO, String property) {
            int propertyId = sessionContext.getPropertyId(property);
            int loginUserId = sessionContext.getLoginUserId();

            NightAuditLog log = beanMapper.map(logDTO, NightAuditLog.class);
            if (logId == 0) {
                //设置创建人+创建时间
                log.setCreatedBy(loginUserId);
                log.setCreatedTime(DateTimeUtils.nowTimestamp());
                //保存新增的Log信息
                nightAuditLogService.save(log.setPropertyId(propertyId));
                return ImmutableMap.of("id", log.getId());
            } else {
                NightAuditLog oriLog = checkExistAndBelongProperty(logId, propertyId);
                nightAuditLogService.update(oriLog, log, loginUserId);
                return ImmutableMap.of("id", logId);
            }
        }

        /**
         * 更新 Night Audit Log 的解决状态
         *
         * @param logId     主键id
         * @param isResolve 是否解决
         * @param property  资产标识
         * @return java.lang.Boolean
         * @author lichen
         * @date 2023/5/12
         */
        @ApiId(112)
        @PutMapping(value = "/{logId:\\d+}/status/{isResolve}")
        public Boolean updateResolvedStatus(@PathVariable long logId, @PathVariable boolean isResolve, String property) {
            int propertyId = sessionContext.getPropertyId(property);
            int loginUserId = sessionContext.getLoginUserId();

            checkExistAndBelongProperty(logId, propertyId);
            NightAuditLog nightAuditLog = new NightAuditLog().setId(logId);
            if (isResolve) {
                nightAuditLog.setResolvedBy(loginUserId).setResolvedTime(DateTimeUtils.nowTimestamp());
            } else {
                nightAuditLog.setResolvedBy(BaseConstant.ZERO)
                        .setResolvedTime(BaseConstant.LONG_ZERO)
                        .setReopenBy(loginUserId)
                        .setReopenTime(DateTimeUtils.nowTimestamp());
            }
            return nightAuditLogService.updateById(nightAuditLog);
        }

        /**
         * 删除 log
         *
         * @param logId    主键id
         * @param property 资产标识
         * @return boolean
         * @author lichen
         * @date 2023/5/12
         */
        @ApiId(113)
        @DeleteMapping("/{logId:\\d+}")
        public Map deleteLog(@PathVariable("logId") long logId, String property) {
            int propertyId = sessionContext.getPropertyId(property);
            NightAuditLog nightAuditLog = checkExistAndBelongProperty(logId, propertyId);
            nightAuditLogService.remove(nightAuditLog);
            return Collections.emptyMap();
        }

        /**
         * 校验存在和是否归属于资产
         *
         * @param logId      主键id
         * @param propertyId 资产id
         * @return cloud.wconnect.frontoffice.entity.nightauditlog.NightAuditLog
         * @author lichen
         * @date 2025/8/22
         */
        private NightAuditLog checkExistAndBelongProperty(Long logId, Integer propertyId) {
            NightAuditLog nightAuditLog = nightAuditLogService.getById(logId);
            if (Objects.isNull(nightAuditLog)) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_NOT_FOUND,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "id=" + logId + " ,NightAuditLog not found");
            }
            if (nightAuditLog.getPropertyId().compareTo(propertyId) != 0) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(),
                        MessageFormat.format("NightAuditLog not belong current property, nightAuditLogId:{0}, belongPropertyId:{1}, currentPropertyId:{2}",
                                logId, nightAuditLog.getPropertyId(), propertyId));
            }
            return nightAuditLog;
        }

    }