# BudgetDatabaseConfigOtherTabController.java

    package cloud.wconnect.rateshop.controller.budgetdatabase;

    import cloud.wconnect.commonlib.annotation.ApiId;
    import cloud.wconnect.commonlib.component.SessionContext;
    import cloud.wconnect.commonlib.cons.BaseConstant;
    import cloud.wconnect.commonlib.pojo.dto.ListPagedDTO;
    import cloud.wconnect.commonlib.pojo.dto.jsonview.Views;
    import cloud.wconnect.rateshop.cons.budgetdatabase.ClassificationCons;
    import cloud.wconnect.rateshop.cons.budgetdatabase.VariableTypeEnum;
    import cloud.wconnect.rateshop.entity.budgetdatabase.BudgetDatabaseConfigOtherTab;
    import cloud.wconnect.rateshop.entity.budgetdatabase.BudgetDatabaseConfigOtherTabItem;
    import cloud.wconnect.rateshop.pojo.dto.budgetdatabase.*;
    import cloud.wconnect.rateshop.pojo.query.budgetdatabase.ConfigItemQuery;
    import cloud.wconnect.rateshop.service.budgetdatabase.*;
    import com.fasterxml.jackson.annotation.JsonView;
    import com.google.common.collect.ImmutableMap;
    import jakarta.validation.Valid;
    import org.apache.commons.lang3.StringUtils;
    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>
     *  前端控制器
     * </p>
     *
     * @author yyt
     * @since 2025-11-10
     */
    @RestController
    @RequestMapping("/budget-database")
    public class BudgetDatabaseConfigOtherTabController {

        @Autowired
        private IBudgetDatabaseService budgetDatabaseService;
        @Autowired
        private IBudgetDatabaseConfigOtherTabService budgetDatabaseConfigOtherTabService;
        @Autowired
        private IBudgetDatabaseConfigOtherTabItemService budgetDatabaseConfigOtherTabItemService;
        @Autowired
        private IBudgetDatabaseConfigVariableService budgetDatabaseConfigVariableService;
        @Autowired
        private IBudgetDatabaseConfigVariableOtherService budgetDatabaseConfigVariableOtherService;
        @Autowired
        private IBudgetDatabaseCheckCircularDependencyService budgetDatabaseCheckCircularDependencyService;
        @Autowired
        private SessionContext sessionContext;

        /**
         * 1632 - 获取所有 tab
         *
         * @param year     年
         * @param property 资产标识
         * @return tab
         * @author yyt
         * @date 2025/11/10
         **/
        @ApiId(1632)
        @GetMapping("/{year:\\d+}/other-tab")
        public List<TabDTO> list(@PathVariable int year, String property) {
            return budgetDatabaseConfigOtherTabService.listDTOs(sessionContext.getPropertyId(property), year);
        }

        /**
         * 1633 - 新增/编辑 tab
         *
         * @param year       年
         * @param id         tab id
         * @param property   资产标识
         * @param saveTabDTO tab 信息
         * @return tab id
         * @author yyt
         * @date 2025/11/10
         **/
        @ApiId(1633)
        @PostMapping("/{year:\\d+}/other-tab/{id:\\d+}")
        public Map<String, Integer> saveTab(@PathVariable int year, @PathVariable int id, String property, @Valid @RequestBody SaveTabDTO saveTabDTO) {
            int propertyId = sessionContext.getPropertyId(property);

            // budget database 完成后，则不支持任何操作
            budgetDatabaseService.checkComplete(propertyId, year);

            if (id == BaseConstant.ZERO) {
                // 验重
                budgetDatabaseConfigOtherTabService.checkRepeat(propertyId, year, saveTabDTO.getName(), null);

                // 验证 tab 数量最多不可超过5个
                budgetDatabaseConfigOtherTabService.checkTabCount(propertyId, year);

                // 保存
                return ImmutableMap.of("id", budgetDatabaseConfigOtherTabService.save(propertyId, year, saveTabDTO, sessionContext.getLoginUserId()));
            } else {
                // 验证 tab 存在
                BudgetDatabaseConfigOtherTab tab = budgetDatabaseConfigOtherTabService.checkExist(id);

                // 验证资产所属
                budgetDatabaseConfigOtherTabService.checkBelong(tab, propertyId);

                // 验重
                budgetDatabaseConfigOtherTabService.checkRepeat(propertyId, year, saveTabDTO.getName(), id);

                // 更新
                budgetDatabaseConfigOtherTabService.update(id, saveTabDTO, sessionContext.getLoginUserId());

                return ImmutableMap.of("id", id);
            }
        }

        /**
         * 1560 - 查询配置
         *
         * @param tabId    tab id
         * @param property 资产标识
         * @param query    查询条件
         * @return 配置列表
         * @author yyt
         * @date 2025/11/10
         */
        @JsonView(Views.GeneralView.class)
        @ApiId(1560)
        @GetMapping("/{tabId:\\d+}/other-config")
        public ListPagedDTO<ConfigItemDTO> list(@PathVariable int tabId, String property, ConfigItemQuery query) {
            Integer propertyId = sessionContext.getPropertyId(property);
            return budgetDatabaseConfigOtherTabItemService.list(propertyId, tabId, query);
        }

        /**
         * 1561 - 保存配置
         *
         * @param tabId               tab id
         * @param id                  数据 id
         * @param property            资产标识
         * @param updateConfigItemDTO 配置
         * @return {}
         * @author yyt
         * @date 2025/11/10
         */
        @ApiId(1561)
        @PostMapping("/{tabId:\\d+}/other-config/{id:\\d+}")
        public ConfigBoundToDTO save(@PathVariable int tabId, @PathVariable int id, String property, @Valid @RequestBody UpdateOtherConfigItemDTO updateConfigItemDTO) {
            Integer propertyId = sessionContext.getPropertyId(property);

            // budget database 完成后，则不支持任何操作
            budgetDatabaseService.checkComplete(propertyId, budgetDatabaseConfigOtherTabService.getById(tabId).getBudgetYear());

            // 验证变量配置
            if (updateConfigItemDTO.getEnableBudgetRevenue()) {
                // 验证存在
                budgetDatabaseConfigVariableService.checkExist(propertyId, VariableTypeEnum.REVENUE.getCode(), updateConfigItemDTO.getBudgetRevenueVariableId());
            }

            BudgetDatabaseConfigOtherTab tab = budgetDatabaseConfigOtherTabService.checkTab(tabId, propertyId);
            Integer budgetYear = tab.getBudgetYear();

            if (id == BaseConstant.ZERO) {
                budgetDatabaseConfigOtherTabItemService.checkRepeat(propertyId, tabId, updateConfigItemDTO.getClassification(), updateConfigItemDTO.getName(), null);

                budgetDatabaseConfigOtherTabItemService.save(tab, updateConfigItemDTO, sessionContext.getLoginUserId());

                return new ConfigBoundToDTO();
            } else {
                ConfigBoundToDTO configBoundToDTO = new ConfigBoundToDTO();

                budgetDatabaseConfigOtherTabItemService.checkRepeat(propertyId, tabId, updateConfigItemDTO.getClassification(), updateConfigItemDTO.getName(), id);

                BudgetDatabaseConfigOtherTabItem config = budgetDatabaseConfigOtherTabItemService.checkExist(id);

                budgetDatabaseConfigOtherTabItemService.checkBelong(config, propertyId);

                // 验证当前变量配置是否绑定过当前配置
                if (updateConfigItemDTO.getEnableBudgetRevenue()) {
                    boolean boundToRevenue = budgetDatabaseConfigVariableOtherService.checkBoundToTheConfig(propertyId, updateConfigItemDTO.getBudgetRevenueVariableId(), config.getId());
                    if (boundToRevenue) {
                        configBoundToDTO.setBoundToRevenue(true);
                        return configBoundToDTO;
                    }

                    boolean circularDependency = budgetDatabaseCheckCircularDependencyService.checkCircularDependency(propertyId, budgetYear, updateConfigItemDTO.getBudgetRevenueVariableId(),
                            StringUtils.joinWith(":", ClassificationCons.OTHER, config.getId()), VariableTypeEnum.REVENUE.getCode());
                    if (circularDependency) {
                        configBoundToDTO.setCircularDependency(true);
                        return configBoundToDTO;
                    }
                }

                budgetDatabaseConfigOtherTabItemService.update(tab, config, updateConfigItemDTO, sessionContext.getLoginUserId());

                return configBoundToDTO;
            }
        }

        /**
         * 1562 - 删除配置
         *
         * @param id       数据 id
         * @param property 资产标识
         * @return 可以删除标志
         * @author yyt
         * @date 2025/11/11
         */
        @ApiId(1562)
        @DeleteMapping("/other-config/{id:\\d+}")
        public ConfigDeleteFlagDTO delete(@PathVariable int id, String property) {
            Integer propertyId = sessionContext.getPropertyId(property);
            BudgetDatabaseConfigOtherTabItem config = budgetDatabaseConfigOtherTabItemService.checkExist(id);

            budgetDatabaseConfigOtherTabItemService.checkBelong(config, propertyId);

            // budget database 完成后，则不支持任何操作
            BudgetDatabaseConfigOtherTab tab = budgetDatabaseConfigOtherTabService.getById(config.getOtherTabId());
            budgetDatabaseService.checkComplete(propertyId, tab.getBudgetYear());

            // 若被变量配置引用到，则不可删除
            if (budgetDatabaseConfigVariableOtherService.checkConfigBoundToTheVariable(propertyId, config.getId())) {
                return new ConfigDeleteFlagDTO(false, true);
            }

            return new ConfigDeleteFlagDTO(budgetDatabaseConfigOtherTabItemService.handleDeleteRevenueConfig(config), false);
        }

        /**
         * 1634 - 参与计算 Total Revenue
         *
         * @param id                   tab id
         * @param participateCalculate 参与计算标志
         * @param property             资产标识
         * @return {}
         * @author yyt
         * @date 2025/11/11
         **/
        @ApiId(1634)
        @PutMapping("/other-tab/{id:\\d+}/participate-calculate/{participateCalculate}")
        public Map participateCalculateTotalRevenue(@PathVariable int id, @PathVariable boolean participateCalculate, String property) {
            BudgetDatabaseConfigOtherTab tab = budgetDatabaseConfigOtherTabService.checkExist(id);
            budgetDatabaseConfigOtherTabService.checkBelong(tab, sessionContext.getPropertyId(property));

            budgetDatabaseConfigOtherTabService.participateCalculate(id, participateCalculate, sessionContext.getLoginUserId());

            return Collections.emptyMap();
        }

        /**
         * 1635 - 删除 tab
         *
         * @param  id tab id
         * @param property 资产标识
         * @return 配置删除标志
         * @author yyt
         * @date 2025/11/11
         **/
        @ApiId(1635)
        @DeleteMapping("/other-tab/{id:\\d+}")
        public ConfigDeleteFlagDTO deleteRoomTab(@PathVariable int id, String property) {
            BudgetDatabaseConfigOtherTab tab = budgetDatabaseConfigOtherTabService.checkExist(id);
            budgetDatabaseConfigOtherTabService.checkBelong(tab, sessionContext.getPropertyId(property));
            return budgetDatabaseConfigOtherTabService.handleDelete(tab);
        }

    }