# LogbookController.java

    package cloud.wconnect.frontoffice.controller.logbook;

    import cloud.wconnect.commonlib.annotation.ApiId;
    import cloud.wconnect.commonlib.component.SessionContext;
    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.exception.ForbiddenException;
    import cloud.wconnect.commonlib.pojo.dto.ListPagedDTO;
    import cloud.wconnect.frontoffice.entity.logbook.Logbook;
    import cloud.wconnect.frontoffice.entity.logbook.LogbookCategory;
    import cloud.wconnect.frontoffice.entity.logbook.LogbookComment;
    import cloud.wconnect.frontoffice.entity.logbook.LogbookNotification;
    import cloud.wconnect.frontoffice.pojo.dto.logbook.*;
    import cloud.wconnect.frontoffice.pojo.query.logbook.LogbookQuery;
    import cloud.wconnect.frontoffice.pojo.query.logbook.PrintQuery;
    import cloud.wconnect.frontoffice.service.logbook.ILogbookCategoryService;
    import cloud.wconnect.frontoffice.service.logbook.ILogbookCommentService;
    import cloud.wconnect.frontoffice.service.logbook.ILogbookNotificationService;
    import cloud.wconnect.frontoffice.service.logbook.ILogbookService;
    import jakarta.validation.Valid;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;

    import java.util.Collections;
    import java.util.List;
    import java.util.Map;

    /**
     * <p>
     *  logbook
     * </p>
     *
     * @author yyt
     * @since 2023-03-18
     */
    @RestController
    @RequestMapping("/logbook")
    public class LogbookController {

        @Autowired
        private ILogbookService logbookService;
        @Autowired
        private ILogbookCategoryService logbookCategoryService;
        @Autowired
        private ILogbookNotificationService logbookNotificationService;
        @Autowired
        private ILogbookCommentService logbookCommentService;
        @Autowired
        private SessionContext sessionContext;

        /**
         * 检索 logbook 列表
         *
         * @param logbookQuery 搜索条件
         * @return logbook 列表
         * @author yyt
         * @date 2023/3/18
         */
        @ApiId(136)
        @GetMapping
        public ListPagedDTO<LogbookDTO> listPage(@Valid LogbookQuery logbookQuery, @RequestParam String property) {
            return logbookService.listPage(sessionContext.getPropertyId(property), logbookQuery);
        }

        /**
         * 新增、编辑 logbook
         *
         * @param id         logbook id
         * @param property   资产标识
         * @param logbookDTO logbook 内容
         * @return {}
         * @author yyt
         * @date 2023/3/18
         */
        @ApiId(137)
        @PostMapping("/{id:\\d+}")
        public Map saveLogbook(@PathVariable("id") int id, @RequestParam String property,
                                       @Valid @RequestBody UpdateLogbookDTO logbookDTO) {
            int propertyId = sessionContext.getPropertyId(property);
            // 校验 category 必须存在
            LogbookCategory category = logbookCategoryService.checkExist(logbookDTO.getCategory());
            if (category.getPropertyId() != propertyId) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "the property id parameter is different from " +
                        "the property id of the logbookCategory;propertyId:" + propertyId + ",logbookCategoryPropertyId:" +
                        category.getPropertyId() + ",logbookCategoryId:" + category.getId());
            }

            if (id == 0) {
                Logbook logbook = logbookService.saveLogbook(propertyId, logbookDTO, sessionContext.getLoginUserId());

                logbookNotificationService.handleSendMailAsync(LogbookNotification.OPERATION_CREATED, logbook);
            } else {
                Logbook logbook = logbookService.checkLogbookExist(id);

                checkPropertySame(logbook, propertyId);

                logbookService.updateLogbook(logbook, logbookDTO, sessionContext.getLoginUserId());
            }

            return Collections.emptyMap();
        }

        /**
         * 校验 logbook property 与 参数 property 一致
         *
         * @param logbook         logbook
         * @param paramPropertyId 参数 property
         * @author yyt
         * @date 2023/3/20
         */
        public void checkPropertySame(Logbook logbook, int paramPropertyId) {
            if (logbook.getPropertyId() != paramPropertyId) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "the property id parameter is different from " +
                        "the property id of the logbook;propertyId:" + paramPropertyId + ",logbookPropertyId:" +
                        logbook.getPropertyId() + ",logbookId:" + logbook.getId());
            }
        }

        /**
         * logbook 详情
         *
         * @param id       主键 id
         * @param property 资产标识
         * @return logbook 详情
         * @author yyt
         * @date 2023/3/20
         */
        @ApiId(138)
        @GetMapping("/{id:\\d+}")
        public LogbookDTO getDetail(@PathVariable("id") int id, @RequestParam String property) {
            Logbook logbook = logbookService.checkLogbookExist(id);

            int propertyId = sessionContext.getPropertyId(property);
            checkPropertySame(logbook, propertyId);

            return logbookService.getDetail(logbook);
        }

        /**
         * 统计 logbook 数量
         *
         * @param property 资产标识
         * @param status   状态（false:未解决，true:已解决）
         * @return category 数量
         * @author yyt
         * @date 2023/3/20
         */
        @ApiId(139)
        @GetMapping("/count")
        public List<LogbookCountDTO> count(@RequestParam String property, @RequestParam boolean status){
           return logbookService.count(sessionContext.getPropertyId(property), status);
        }

        /**
         * 修改状态
         *
         * @param id                     logbook id
         * @param property               资产标识
         * @param updateLogbookStatusDTO 修改状态信息
         * @return {}
         * @author yyt
         * @date 2023/3/21
         */
        @ApiId(140)
        @PutMapping("/{id:\\d+}/status")
        public Map updateStatus(@PathVariable("id") int id, @RequestParam String property,
                                @Valid @RequestBody UpdateLogbookStatusDTO updateLogbookStatusDTO) {
            Logbook logbook = logbookService.checkLogbookExist(id);

            checkPropertySame(logbook, sessionContext.getPropertyId(property));

            logbook = logbookService.updateStatus(id, updateLogbookStatusDTO, sessionContext.getLoginUserId());

            if (updateLogbookStatusDTO.getStatus()) {
                logbookNotificationService.handleSendMailAsync(LogbookNotification.OPERATION_RESOLVED, logbook);
            } else {
                logbookNotificationService.handleSendMailAsync(LogbookNotification.OPERATION_CREATED, logbook);
            }

            return Collections.emptyMap();
        }

        /**
         * 获取打印数据
         *
         * @param printQuery 查询条件
         * @return logbook 数据
         * @author yyt
         * @date 2023/3/21
         */
        @ApiId(141)
        @GetMapping("/print")
        public List<LogbookDTO> getPrintData(PrintQuery printQuery) {
            return logbookService.getPrintData(printQuery, sessionContext.getPropertyId(printQuery.getProperty()));
        }

        /**
         * 备注列表
         *
         * @param id       logbook id
         * @param property 资产标识
         * @return 备注列表
         * @author yyt
         * @date 2023/3/21
         */
        @ApiId(142)
        @GetMapping("/{id:\\d+}/comment")
        public List<LogbookCommentDTO> listComment(@PathVariable("id") int id, @RequestParam String property){
            Logbook logbook = logbookService.checkLogbookExist(id);

            checkPropertySame(logbook, sessionContext.getPropertyId(property));

            return logbookCommentService.listComment(sessionContext.getTenantSymbolBO().getId(), id);
        }

        /**
         * 新增备注
         *
         * @param id         logbook id
         * @param property   资产标识
         * @param commentDTO 备注内容
         * @return {}
         * @author yyt
         * @date 2023/3/21
         */
        @ApiId(143)
        @PostMapping("/{id:\\d+}/comment")
        public Map saveComment(@PathVariable("id") int id, @RequestParam String property,
                               @Valid @RequestBody LogbookCommentDTO commentDTO) {
            Logbook logbook = logbookService.checkLogbookExist(id);

            int propertyId = sessionContext.getPropertyId(property);
            checkPropertySame(logbook, propertyId);

            LogbookComment comment = logbookCommentService.saveComment(id, propertyId, commentDTO, sessionContext.getLoginUserId());
            logbook.setComment(comment);
            logbookNotificationService.handleSendMailAsync(LogbookNotification.OPERATION_COMMENT, logbook);

            return Collections.emptyMap();
        }

        /**
         * 删除备注
         *
         * @param id       logbook id
         * @param property 资产标识
         * @param cid      备注 id
         * @return {}
         * @author yyt
         * @date 2023/3/21
         */
        @ApiId(144)
        @DeleteMapping("/{id:\\d+}/comment/{cid:\\d+}")
        public Map deleteComment(@PathVariable("id") int id, @RequestParam String property, @PathVariable("cid") int cid) {
            Logbook logbook = logbookService.checkLogbookExist(id);

            int propertyId = sessionContext.getPropertyId(property);
            checkPropertySame(logbook, propertyId);

            LogbookComment comment = logbookCommentService.checkCommentExist(id, cid);
            if (comment.getCreateId() != sessionContext.getLoginUserId()) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "The comment is not created by the current login user;"
                        + "commentId:" + comment.getId() + ",commentCreateUserId:" + comment.getCreateId()
                        + ",loginUserId:" + sessionContext.getLoginUserId());
            }
            if (!comment.getPropertyId().equals(propertyId)) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(),
                        "the property id parameter is different from the property id of the logbookComment;" +
                                "propertyId:" + propertyId + ",logbookCommentPropertyId:" + comment.getPropertyId() +
                                ",logbookId:" + logbook.getId() + ",logbookCommentId:" + comment.getId());
            }

            logbookCommentService.remove(id, comment);

            return Collections.emptyMap();
        }

    }