diff --git a/src/main/java/com/huoran/iasf/common/exception/code/BaseResponseCode.java b/src/main/java/com/huoran/iasf/common/exception/code/BaseResponseCode.java index b41faea..d2b5c07 100644 --- a/src/main/java/com/huoran/iasf/common/exception/code/BaseResponseCode.java +++ b/src/main/java/com/huoran/iasf/common/exception/code/BaseResponseCode.java @@ -54,6 +54,8 @@ public enum BaseResponseCode implements ResponseCodeInterface { ROLE_ERROR(401017, "账号角色被删,请联系管理员添加角色后再试"), EXCEL_FILE_NULL(40006, "导入失败,导入数据为空!"), + DATA_DUPLICATION(40007, "方案存在重复"), + DATA_DOES_NOT_EXIST(500, "当前数据不存在"), ; diff --git a/src/main/java/com/huoran/iasf/common/utils/R.java b/src/main/java/com/huoran/iasf/common/utils/R.java index 8336db6..b23c654 100644 --- a/src/main/java/com/huoran/iasf/common/utils/R.java +++ b/src/main/java/com/huoran/iasf/common/utils/R.java @@ -113,4 +113,20 @@ public class R { } + /** + * 返回警告信息的R对象,通常用于前端展示警告但不完全阻止操作的场景。 + * + * @param warnMsg 警告信息 + * @return 包含警告信息的R对象实例 + */ + public static R warn(String warnMsg) { + // 这里直接使用字符串信息作为警告,如果您有专门的警告响应码,可以使用如下形式: + // return new R(BaseResponseCode.WARNING_CODE, warnMsg); + + // 或者,如果只想传递消息而不改变响应码(保持成功响应码,但附带警告信息): + return new R(300, warnMsg); + } + + + } diff --git a/src/main/java/com/huoran/iasf/controller/SeoController.java b/src/main/java/com/huoran/iasf/controller/SeoController.java new file mode 100644 index 0000000..182377f --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SeoController.java @@ -0,0 +1,68 @@ +package com.huoran.iasf.controller; + + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.Seo; +import com.huoran.iasf.service.SeoService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + *

+ * 前端控制器 + *

+ * + * @author cheney + * @since 2023-08-24 + */ +@Api(tags = "seo管理") +@RestController +@RequestMapping("/seo") +public class SeoController { + + @Autowired + private SeoService seoService; + + @PostMapping("/add") + @ApiOperation(value = "新增seo") + public R addUserGroup(@RequestBody Seo seo) { + Seo one = seoService.getOne(new QueryWrapper().eq("title", seo.getTitle())); + if (ObjectUtil.isNotNull(one)) { + R.fail("seo已存在"); + } + boolean save = seoService.save(seo); + return save ? R.success() : R.fail("添加失败"); + } + + @PostMapping("/delete") + @ApiOperation(value = "删除seo") + public R deleted(@RequestParam Integer id) { + boolean remove = seoService.removeById(id); + return remove ? R.success() : R.fail("删除失败"); + } + + @PostMapping("/update") + @ApiOperation(value = "更新seo") + public R update(@RequestBody Seo seo) { + boolean update = seoService.updateById(seo); + return update ? R.success() : R.fail("更新失败"); + } + + + @GetMapping("/list") + @ApiOperation(value = "站点seo列表") + public R list(@RequestParam Integer siteId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("site_id", siteId); + List list = seoService.list(queryWrapper); + return R.success(list); + } + +} + diff --git a/src/main/java/com/huoran/iasf/controller/SysColumnController.java b/src/main/java/com/huoran/iasf/controller/SysColumnController.java index 1adaa55..95e7f31 100644 --- a/src/main/java/com/huoran/iasf/controller/SysColumnController.java +++ b/src/main/java/com/huoran/iasf/controller/SysColumnController.java @@ -112,6 +112,18 @@ public class SysColumnController { return updateState ? R.success() : R.fail("编辑失败"); } + @PostMapping("/controlDisplayNavigationMenu") + @ApiOperation(value = "控制显示导航菜单", response = SysColumn.class) + public R controlDisplayNavigationMenu(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id, + @ApiParam(name = "menuVisible", value = "菜单是否可见(默认0可见 1不可见)", required = true) @RequestParam Integer menuVisible) { + SysColumn column = new SysColumn(); + column.setId(id); + column.setMenuVisible(menuVisible);//菜单是否可见(默认0可见 1不可见) + + boolean updateState = service.updateById(column); + return updateState ? R.success() : R.fail("编辑失败"); + } + /*@NoRepeatSubmit @PostMapping("/delete") @ApiOperation(value = "删除", response = SysContent.class) diff --git a/src/main/java/com/huoran/iasf/controller/SysFloatingColumnSchemeController.java b/src/main/java/com/huoran/iasf/controller/SysFloatingColumnSchemeController.java new file mode 100644 index 0000000..228a255 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SysFloatingColumnSchemeController.java @@ -0,0 +1,309 @@ +package com.huoran.iasf.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysFloatingColumnScheme; +import com.huoran.iasf.entity.SysFloatingColumnSchemeModule; +import com.huoran.iasf.entity.SysFloatingColumnSchemeScopeOfApplication; +import com.huoran.iasf.service.SysFloatingColumnSchemeModuleService; +import com.huoran.iasf.service.SysFloatingColumnSchemeScopeOfApplicationService; +import com.huoran.iasf.service.SysFloatingColumnSchemeService; +import com.huoran.iasf.vo.SysFloatingColumnSchemeVO; +import com.huoran.iasf.vo.req.SuspensionBarListPagingReq; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +/** + * @描述:悬浮栏方案控制类 + * @作者: Rong + * @日期: 2024-06-04 + */ +@RestController +@RequestMapping("/SysFloatingColumnSchemeService/SysFloatingColumnScheme") +@Api(value = "悬浮栏相关接口:SysFloatingColumnSchemeController", tags = "悬浮栏方案:悬浮栏相关接口") +public class SysFloatingColumnSchemeController { + + @Autowired + public SysFloatingColumnSchemeService service; + + @Autowired + public SysFloatingColumnSchemeScopeOfApplicationService floatingColumnSchemeScopeOfApplicationService; + + @Autowired + public SysFloatingColumnSchemeModuleService floatingColumnSchemeModuleService; + + + /** + * 保存或更新悬浮栏方案记录 + * 如果ID为空,则执行保存操作;如果ID有值,则视为更新操作。 + * + * @param sysFloatingColumnScheme 要保存或更新的悬浮栏方案对象 + * @return R 结果对象,包含操作状态信息 + */ + @PostMapping("/saveOrUpdate") + @ApiOperation(value = "保存或更新悬浮栏方案记录", response = SysFloatingColumnScheme.class) + public R saveOrUpdate(@RequestBody @ApiParam(name = "悬浮栏方案对象", value = "包含悬浮栏方案详细信息,若id不存在则新建,否则视为更新", required = true) SysFloatingColumnScheme sysFloatingColumnScheme) { + + // 校验集合内是否有重复的schemeTitle + Set schemeTitles = new HashSet<>(); + for (SysFloatingColumnSchemeModule module : sysFloatingColumnScheme.getFloatingColumnSchemeModules()) { + if (!schemeTitles.add(module.getSchemeTitle())) { +// throw new IllegalArgumentException(module.getSchemeTitle() + " 标题已存在"); + + String msg = module.getSchemeTitle() + " 标题已存在"; + + /*throw new RuntimeException(msg);*/ + return R.fail(msg); + } + } + + // 新增场景下直接进行校验 + if (sysFloatingColumnScheme.getId() == null) { + if (checkSchemeName(sysFloatingColumnScheme.getSchemeName(), sysFloatingColumnScheme.getSiteId())) { + return R.fail("该站点下已存在相同的悬浮栏方案名称"); + } + } + // 编辑场景下,只有当名称发生改变时才进行校验,并排除当前记录自身 + else if (!sysFloatingColumnScheme.getSchemeName().equals(service.getById(sysFloatingColumnScheme.getId()).getSchemeName())) { + if (checkSchemeNameExceptSelf(sysFloatingColumnScheme.getSchemeName(), sysFloatingColumnScheme.getSiteId(), sysFloatingColumnScheme.getId())) { + return R.fail("该站点下已存在相同的悬浮栏方案名称"); + } + } + + + //获取floatingColumnSchemeScopeOfApplications中的范围判断是不是0,如果包含为0 + List floatingColumnSchemeScopeOfApplications = sysFloatingColumnScheme.getFloatingColumnSchemeScopeOfApplications(); + for (SysFloatingColumnSchemeScopeOfApplication floatingColumnSchemeScopeOfApplication : floatingColumnSchemeScopeOfApplications) { + if (floatingColumnSchemeScopeOfApplication.getApplicationScopeId().equals("0")) { + sysFloatingColumnScheme.setIsGlobal(1); + + } else { + sysFloatingColumnScheme.setIsGlobal(0); + } + } + + + // 处理全局悬浮栏逻辑 + if (sysFloatingColumnScheme.getIsGlobal() == 1) { + // 确保没有其他全局悬浮栏同时启用 + long globalCount = service.count(new QueryWrapper().eq("is_global", true).eq("is_disable", 0).ne("id", sysFloatingColumnScheme.getId())); + if (globalCount > 0) { + return R.fail("已经有全局悬浮栏启用,请先禁用后再尝试设置"); + } + } + + boolean result = false; + + try { + if (sysFloatingColumnScheme.getId() == null) { + // 保存操作 + result = service.save(sysFloatingColumnScheme); + } else { + // 更新操作 + result = service.updateById(sysFloatingColumnScheme); + } + } catch (Exception e) { + return R.fail("操作失败"); + } + + if (!result) { + return R.fail("操作失败"); + } + + //删除原有的方案和范围关系 + + floatingColumnSchemeModuleService.deleteByFloatingBarSchemeId(sysFloatingColumnScheme.getId()); + floatingColumnSchemeScopeOfApplicationService.deleteByFloatingBarSchemeId(sysFloatingColumnScheme.getId()); + + + // 保持原有的模块和范围处理逻辑 + handleFloatingColumnSchemeModules(sysFloatingColumnScheme); + handleFloatingColumnSchemeScopeOfApplications(sysFloatingColumnScheme); + + return R.success(); + } + + + @PostMapping("/columnDisplayFloatingBar") + @ApiOperation(value = "根据栏目展示悬浮栏", response = SysFloatingColumnSchemeVO.class) + public R columnDisplayFloatingBar(@ApiParam(name = "columnId", value = "栏目id", required = true) @RequestParam String columnId) { + return service.columnDisplayFloatingBar(columnId); + } + + + + @PostMapping("/floatingBarList") + @ApiOperation(value = "悬浮栏列表", response = SysFloatingColumnSchemeVO.class) + public R floatingBarList(@RequestBody SuspensionBarListPagingReq sysFloatingColumnScheme) { + return service.floatingBarList(sysFloatingColumnScheme); + } + + + /** + * * 1.应用全部权限最高,只要是启用应用全部的,除了一开始没有启用悬浮栏的都弹窗提示,当前已启用了的悬浮栏方案将会被取消。 + * 2.启用了应用全部的,后面要启用部分的,提示先禁用应用全部的。 + * 3.部分启用vs部分启用,且有重合的,提示移除重合的。 + */ + @PostMapping("/enableOrDisableScheme") + @ApiOperation(value = "启用或禁用", response = SysFloatingColumnSchemeVO.class) + public R enableOrDisableScheme(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id, @ApiParam(name = "isDisable", value = "是否禁用(0启用 1禁用)", required = true) @RequestParam Integer isDisable) { + /* return service.enableOrDisableScheme(id, isDisable);*/ + + //禁启用操作 + SysFloatingColumnScheme sysFloatingColumnScheme = service.getById(id); + sysFloatingColumnScheme.setIsDisable(isDisable); + boolean operation = service.updateById(sysFloatingColumnScheme); + //增加判断如果当前的应用权限如果为全部,需要将当前站点下其余已经启用的给禁用了 + if (sysFloatingColumnScheme.getIsDisable() == 0 && sysFloatingColumnScheme.getIsGlobal() == 1) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.set("is_disable", 1); + updateWrapper.eq("is_disable", 0); + updateWrapper.eq("site_id", sysFloatingColumnScheme.getSiteId()); + updateWrapper.ne("id", id); + service.update(updateWrapper); + + } + + + return operation ? R.success() : R.fail("操作失败"); + } + + + @PostMapping("/checkEnableOrDisable") + @ApiOperation(value = "检查“启用”或“禁用”()", response = SysFloatingColumnSchemeVO.class) + public R checkEnableOrDisable(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id, @ApiParam(name = "isDisable", value = "是否禁用(0启用 1禁用)", required = true) @RequestParam Integer isDisable) { + + return service.checkEnableOrDisable(id, isDisable); + } + + + @PostMapping("/findById") + @ApiOperation(value = "查询详情", response = SysFloatingColumnScheme.class) + public R findById(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { + SysFloatingColumnScheme sysFloatingColumnScheme = service.getById(id); + List sysFloatingColumnSchemeScopeOfApplications = floatingColumnSchemeScopeOfApplicationService.getScopeOfApplicationByFloatingBarSchemeId(id); + List getModuleByFloatingBarSchemeId = floatingColumnSchemeModuleService.getModuleByFloatingBarSchemeId(id); + sysFloatingColumnScheme.setFloatingColumnSchemeScopeOfApplications(sysFloatingColumnSchemeScopeOfApplications); + sysFloatingColumnScheme.setFloatingColumnSchemeModules(getModuleByFloatingBarSchemeId); + return R.success(sysFloatingColumnScheme); + } + + + @PostMapping("/batchDeletion") + @ApiOperation(value = "批量删除悬浮栏数据", response = SysFloatingColumnScheme.class) + public R batchDeletion(@ApiParam(name = "id", value = "主键", required = true) @RequestParam List id) { + boolean delState = service.removeByIds(id); + + //删除的同时将悬浮栏方案以及悬浮栏应用范围 + if (delState) { + for (Integer removeId : id) { + + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysFloatingColumnSchemeModule::getFloatingBarSchemeId, removeId); + floatingColumnSchemeModuleService.remove(queryWrapper); + + LambdaQueryWrapper queryWrapper1 = new LambdaQueryWrapper<>(); + queryWrapper1.eq(SysFloatingColumnSchemeScopeOfApplication::getFloatingBarSchemeId, removeId); + floatingColumnSchemeScopeOfApplicationService.remove(queryWrapper1); + } + + + } + + return R.success(); + } + + + @PostMapping("/batchDeletionScheme") + @ApiOperation(value = "批量删除方案", response = SysFloatingColumnSchemeModule.class) + public R batchDeletionScheme(@ApiParam(name = "id", value = "主键", required = true) @RequestParam List id) { + boolean delState = floatingColumnSchemeModuleService.removeByIds(id); + return delState ? R.success() : R.fail("删除失败"); + } + + + @PostMapping("/batchDeleteRange") + @ApiOperation(value = "批量删除应用范围", response = SysFloatingColumnSchemeScopeOfApplication.class) + public R batchDeleteRange(@ApiParam(name = "id", value = "主键", required = true) @RequestParam List id) { + boolean delState = floatingColumnSchemeScopeOfApplicationService.removeByIds(id); + return delState ? R.success() : R.fail("删除失败"); + } + + + private void handleFloatingColumnSchemeModules(SysFloatingColumnScheme sysFloatingColumnScheme) { + /*// 校验集合内是否有重复的schemeTitle + Set schemeTitles = new HashSet<>(); + for (SysFloatingColumnSchemeModule module : sysFloatingColumnScheme.getFloatingColumnSchemeModules()) { + if (!schemeTitles.add(module.getSchemeTitle())) { +// throw new IllegalArgumentException(module.getSchemeTitle() + " 标题已存在"); + + String msg = module.getSchemeTitle() + " 标题已存在"; + + throw new RuntimeException(msg); + } + }*/ + if (sysFloatingColumnScheme.getFloatingColumnSchemeModules() != null && !sysFloatingColumnScheme.getFloatingColumnSchemeModules().isEmpty()) { + for (SysFloatingColumnSchemeModule module : sysFloatingColumnScheme.getFloatingColumnSchemeModules()) { + module.setFloatingBarSchemeId(sysFloatingColumnScheme.getId()); // 确保模块关联到当前方案 + if (sysFloatingColumnScheme.getId() == null) { + // 如果悬浮栏方案是新建的,直接保存模块(假设模块没有独立的ID生成策略) + floatingColumnSchemeModuleService.save(module); + } else { + // 如果悬浮栏方案是更新的,根据情况更新或保存模块 + floatingColumnSchemeModuleService.saveOrUpdate(module); + } + } + } + } + + private void handleFloatingColumnSchemeScopeOfApplications(SysFloatingColumnScheme sysFloatingColumnScheme) { + if (sysFloatingColumnScheme.getFloatingColumnSchemeScopeOfApplications() != null && !sysFloatingColumnScheme.getFloatingColumnSchemeScopeOfApplications().isEmpty()) { + for (SysFloatingColumnSchemeScopeOfApplication scope : sysFloatingColumnScheme.getFloatingColumnSchemeScopeOfApplications()) { + scope.setFloatingBarSchemeId(sysFloatingColumnScheme.getId()); + if (sysFloatingColumnScheme.getId() == null) { + // 如果悬浮栏方案是新建的,直接保存范围 + floatingColumnSchemeScopeOfApplicationService.save(scope); + } else { + // 如果悬浮栏方案是更新的,根据情况更新或保存范围 + floatingColumnSchemeScopeOfApplicationService.saveOrUpdate(scope); + } + } + } + } + + + // 根据站点校验方案名称,排除当前ID记录 + private boolean checkSchemeNameExceptSelf(String schemeName, Integer siteId, Integer id) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("scheme_name", schemeName); + queryWrapper.eq("site_id", siteId); + // 添加条件,排除当前ID的记录 + if (id != null) { + queryWrapper.ne("id", id); + } + return service.count(queryWrapper) > 0; + } + + + // 现在仅用于新增场景或编辑时名称变更的校验,不需排除自身ID + private boolean checkSchemeName(String schemeName, Integer siteId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("scheme_name", schemeName); + queryWrapper.eq("site_id", siteId); + return service.count(queryWrapper) > 0; + } +} + diff --git a/src/main/java/com/huoran/iasf/entity/Seo.java b/src/main/java/com/huoran/iasf/entity/Seo.java new file mode 100644 index 0000000..e8358bb --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/Seo.java @@ -0,0 +1,45 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; + +/** + *

+ * + *

+ * + * @author cheney + * @since 2023-08-24 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("sys_seo") +@ApiModel(value = "Seo对象", description = "") +public class Seo implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "标题") + private String title; + + @ApiModelProperty(value = "关键词") + private String keyword; + + @ApiModelProperty(value = "描述") + private String description; + + @ApiModelProperty(value = "站点") + private Integer siteId; + +} diff --git a/src/main/java/com/huoran/iasf/entity/SysFloatingColumnScheme.java b/src/main/java/com/huoran/iasf/entity/SysFloatingColumnScheme.java new file mode 100644 index 0000000..8692045 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysFloatingColumnScheme.java @@ -0,0 +1,76 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + *

+ * 悬浮栏方案 + *

+ * + * @author cheney + * @since 2024-06-04 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "SysFloatingColumnScheme对象", description = "悬浮栏方案") +public class SysFloatingColumnScheme implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "悬浮栏方案名称") + private String schemeName; + + @ApiModelProperty(value = "状态(0默认草稿箱 1为已发布)") + private Integer status; + + @ApiModelProperty(value = "悬浮栏样式id(关联样式表id)") + private Integer floatingBarStyle; + + @ApiModelProperty(value = "是否禁用(默认1不启用,0启用 1禁用)") + private Integer isDisable; + + @ApiModelProperty(value = "站点id") + private Integer siteId; + + @ApiModelProperty(value = "创建人id") + private Integer founderId; + + @ApiModelProperty(value = "编辑人id") + private Integer editorId; + + @ApiModelProperty(value = "创建时间") + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + @ApiModelProperty(value = "更新时间") + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateTime; + + @ApiModelProperty(value = "表示是否为全局应用,便于快速判断是否存在全局悬浮栏,0表示不是全局悬浮栏,1表示是全局悬浮栏") + private Integer isGlobal; + + + @ApiModelProperty(value = "悬浮栏方案模块") + @TableField(exist = false) + private List floatingColumnSchemeModules; + + @ApiModelProperty(value = "悬浮栏方案范围") + @TableField(exist = false) + private List floatingColumnSchemeScopeOfApplications; + +} diff --git a/src/main/java/com/huoran/iasf/entity/SysFloatingColumnSchemeModule.java b/src/main/java/com/huoran/iasf/entity/SysFloatingColumnSchemeModule.java new file mode 100644 index 0000000..506bb45 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysFloatingColumnSchemeModule.java @@ -0,0 +1,48 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; + +import java.io.Serializable; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 悬浮栏方案设置 + *

+ * + * @author cheney + * @since 2024-06-04 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "SysFloatingColumnSchemeModule对象", description = "悬浮栏方案设置") +public class SysFloatingColumnSchemeModule implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "悬浮栏方案id") + private Integer floatingBarSchemeId; + + @ApiModelProperty(value = "图片地址") + private String pictureAddress; + + @ApiModelProperty(value = "方案标题") + private String schemeTitle; + + @ApiModelProperty(value = "方案内容(json)") + private String schemeContentJson; + + @ApiModelProperty(value = "是否禁用(0默认,0启用 1禁用)") + private Integer isDisable; + + +} diff --git a/src/main/java/com/huoran/iasf/entity/SysFloatingColumnSchemeScopeOfApplication.java b/src/main/java/com/huoran/iasf/entity/SysFloatingColumnSchemeScopeOfApplication.java new file mode 100644 index 0000000..e1de98a --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysFloatingColumnSchemeScopeOfApplication.java @@ -0,0 +1,38 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; + +/** + *

+ * 悬浮栏应用范围 + *

+ * + * @author cheney + * @since 2024-06-04 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "SysFloatingColumnSchemeScopeOfApplication对象", description = "悬浮栏应用范围") +public class SysFloatingColumnSchemeScopeOfApplication implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "悬浮栏方案id") + private Integer floatingBarSchemeId; + + @ApiModelProperty(value = "应用范围id(为0表示网站全局,其余为栏目表主键),如果为父级子级栏目一起选中,则显示为多个,以逗号隔开:1,3,45,49") + private String applicationScopeId; + + +} diff --git a/src/main/java/com/huoran/iasf/mapper/SeoMapper.java b/src/main/java/com/huoran/iasf/mapper/SeoMapper.java new file mode 100644 index 0000000..a39ae7a --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SeoMapper.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.huoran.iasf.entity.Seo; + +/** + *

+ * Mapper 接口 + *

+ * + * @author cheney + * @since 2023-08-24 + */ +public interface SeoMapper extends BaseMapper { + +} diff --git a/src/main/java/com/huoran/iasf/mapper/SysFloatingColumnSchemeMapper.java b/src/main/java/com/huoran/iasf/mapper/SysFloatingColumnSchemeMapper.java new file mode 100644 index 0000000..80dc4c3 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysFloatingColumnSchemeMapper.java @@ -0,0 +1,24 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.huoran.iasf.entity.SysFloatingColumnScheme; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.huoran.iasf.vo.SysFloatingColumnSchemeVO; +import com.huoran.iasf.vo.req.PageContentReqVO; +import com.huoran.iasf.vo.req.SuspensionBarListPagingReq; +import com.huoran.iasf.vo.resp.PageContentRespVO; +import org.apache.ibatis.annotations.Param; + +/** + *

+ * 悬浮栏方案 Mapper 接口 + *

+ * + * @author cheney + * @since 2024-06-04 + */ +public interface SysFloatingColumnSchemeMapper extends BaseMapper { + IPage floatingBarList(Page page, @Param("req") SuspensionBarListPagingReq req); + +} diff --git a/src/main/java/com/huoran/iasf/mapper/SysFloatingColumnSchemeModuleMapper.java b/src/main/java/com/huoran/iasf/mapper/SysFloatingColumnSchemeModuleMapper.java new file mode 100644 index 0000000..dd54e3a --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysFloatingColumnSchemeModuleMapper.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.mapper; + +import com.huoran.iasf.entity.SysFloatingColumnSchemeModule; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 悬浮栏方案设置 Mapper 接口 + *

+ * + * @author cheney + * @since 2024-06-04 + */ +public interface SysFloatingColumnSchemeModuleMapper extends BaseMapper { + +} diff --git a/src/main/java/com/huoran/iasf/mapper/SysFloatingColumnSchemeScopeOfApplicationMapper.java b/src/main/java/com/huoran/iasf/mapper/SysFloatingColumnSchemeScopeOfApplicationMapper.java new file mode 100644 index 0000000..179a0f9 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysFloatingColumnSchemeScopeOfApplicationMapper.java @@ -0,0 +1,19 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.huoran.iasf.entity.SysFloatingColumnSchemeScopeOfApplication; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 悬浮栏应用范围 Mapper 接口 + *

+ * + * @author cheney + * @since 2024-06-04 + */ +public interface SysFloatingColumnSchemeScopeOfApplicationMapper extends BaseMapper { + List checkBoundByColumnId(@Param("columnId") String columnId); +} diff --git a/src/main/java/com/huoran/iasf/mapper/xml/SysFloatingColumnSchemeMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/SysFloatingColumnSchemeMapper.xml new file mode 100644 index 0000000..3bc88ad --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/SysFloatingColumnSchemeMapper.xml @@ -0,0 +1,51 @@ + + + + + + diff --git a/src/main/java/com/huoran/iasf/mapper/xml/SysFloatingColumnSchemeModuleMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/SysFloatingColumnSchemeModuleMapper.xml new file mode 100644 index 0000000..cf17443 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/SysFloatingColumnSchemeModuleMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/java/com/huoran/iasf/mapper/xml/SysFloatingColumnSchemeScopeOfApplicationMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/SysFloatingColumnSchemeScopeOfApplicationMapper.xml new file mode 100644 index 0000000..17e2716 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/SysFloatingColumnSchemeScopeOfApplicationMapper.xml @@ -0,0 +1,16 @@ + + + + + + + diff --git a/src/main/java/com/huoran/iasf/service/SeoService.java b/src/main/java/com/huoran/iasf/service/SeoService.java new file mode 100644 index 0000000..4fbee02 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SeoService.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.huoran.iasf.entity.Seo; + +/** + *

+ * 服务类 + *

+ * + * @author cheney + * @since 2023-08-24 + */ +public interface SeoService extends IService { + +} diff --git a/src/main/java/com/huoran/iasf/service/SysFloatingColumnSchemeModuleService.java b/src/main/java/com/huoran/iasf/service/SysFloatingColumnSchemeModuleService.java new file mode 100644 index 0000000..f7d5cf6 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysFloatingColumnSchemeModuleService.java @@ -0,0 +1,22 @@ +package com.huoran.iasf.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.huoran.iasf.entity.SysFloatingColumnSchemeModule; + +import java.util.List; + +/** + *

+ * 悬浮栏方案设置 服务类 + *

+ * + * @author cheney + * @since 2024-06-04 + */ +public interface SysFloatingColumnSchemeModuleService extends IService { + //根据floatingBarSchemeId查询方案列表 + List getModuleByFloatingBarSchemeId(Integer floatingBarSchemeId); + + //删除 + void deleteByFloatingBarSchemeId(Integer floatingBarSchemeId); +} diff --git a/src/main/java/com/huoran/iasf/service/SysFloatingColumnSchemeScopeOfApplicationService.java b/src/main/java/com/huoran/iasf/service/SysFloatingColumnSchemeScopeOfApplicationService.java new file mode 100644 index 0000000..61514da --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysFloatingColumnSchemeScopeOfApplicationService.java @@ -0,0 +1,23 @@ +package com.huoran.iasf.service; + +import com.huoran.iasf.entity.SysFloatingColumnSchemeScopeOfApplication; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + *

+ * 悬浮栏应用范围 服务类 + *

+ * + * @author cheney + * @since 2024-06-04 + */ +public interface SysFloatingColumnSchemeScopeOfApplicationService extends IService { + + //根据floatingBarSchemeId获取应用范围列表 + List getScopeOfApplicationByFloatingBarSchemeId(Integer floatingBarSchemeId); + + //删除 + void deleteByFloatingBarSchemeId(Integer floatingBarSchemeId); +} diff --git a/src/main/java/com/huoran/iasf/service/SysFloatingColumnSchemeService.java b/src/main/java/com/huoran/iasf/service/SysFloatingColumnSchemeService.java new file mode 100644 index 0000000..761351c --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysFloatingColumnSchemeService.java @@ -0,0 +1,25 @@ +package com.huoran.iasf.service; + +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysFloatingColumnScheme; +import com.baomidou.mybatisplus.extension.service.IService; +import com.huoran.iasf.vo.req.SuspensionBarListPagingReq; + +/** + *

+ * 悬浮栏方案 服务类 + *

+ * + * @author cheney + * @since 2024-06-04 + */ +public interface SysFloatingColumnSchemeService extends IService { + + R floatingBarList(SuspensionBarListPagingReq req); + + R enableOrDisableScheme(Integer schemeId, Integer enable); + + R checkEnableOrDisable(Integer schemeId, Integer enable); + + R columnDisplayFloatingBar(String columnId); +} diff --git a/src/main/java/com/huoran/iasf/service/impl/SeoServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SeoServiceImpl.java new file mode 100644 index 0000000..fbdb3ff --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SeoServiceImpl.java @@ -0,0 +1,20 @@ +package com.huoran.iasf.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.entity.Seo; +import com.huoran.iasf.mapper.SeoMapper; +import com.huoran.iasf.service.SeoService; +import org.springframework.stereotype.Service; + +/** + *

+ * 服务实现类 + *

+ * + * @author cheney + * @since 2023-08-24 + */ +@Service +public class SeoServiceImpl extends ServiceImpl implements SeoService { + +} diff --git a/src/main/java/com/huoran/iasf/service/impl/SysFloatingColumnSchemeModuleServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysFloatingColumnSchemeModuleServiceImpl.java new file mode 100644 index 0000000..37aaaaf --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysFloatingColumnSchemeModuleServiceImpl.java @@ -0,0 +1,36 @@ +package com.huoran.iasf.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.huoran.iasf.entity.SysFloatingColumnSchemeModule; +import com.huoran.iasf.mapper.SysFloatingColumnSchemeModuleMapper; +import com.huoran.iasf.service.SysFloatingColumnSchemeModuleService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + *

+ * 悬浮栏方案设置 服务实现类 + *

+ * + * @author cheney + * @since 2024-06-04 + */ +@Service +public class SysFloatingColumnSchemeModuleServiceImpl extends ServiceImpl implements SysFloatingColumnSchemeModuleService { + + @Override + public List getModuleByFloatingBarSchemeId(Integer floatingBarSchemeId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(SysFloatingColumnSchemeModule::getFloatingBarSchemeId, floatingBarSchemeId); + return list(queryWrapper); + } + + @Override + public void deleteByFloatingBarSchemeId(Integer floatingBarSchemeId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(SysFloatingColumnSchemeModule::getFloatingBarSchemeId, floatingBarSchemeId); + remove(queryWrapper); + } +} diff --git a/src/main/java/com/huoran/iasf/service/impl/SysFloatingColumnSchemeScopeOfApplicationServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysFloatingColumnSchemeScopeOfApplicationServiceImpl.java new file mode 100644 index 0000000..a4dc3bf --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysFloatingColumnSchemeScopeOfApplicationServiceImpl.java @@ -0,0 +1,36 @@ +package com.huoran.iasf.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.huoran.iasf.entity.SysFloatingColumnSchemeScopeOfApplication; +import com.huoran.iasf.mapper.SysFloatingColumnSchemeScopeOfApplicationMapper; +import com.huoran.iasf.service.SysFloatingColumnSchemeScopeOfApplicationService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + *

+ * 悬浮栏应用范围 服务实现类 + *

+ * + * @author cheney + * @since 2024-06-04 + */ +@Service +public class SysFloatingColumnSchemeScopeOfApplicationServiceImpl extends ServiceImpl implements SysFloatingColumnSchemeScopeOfApplicationService { + + @Override + public List getScopeOfApplicationByFloatingBarSchemeId(Integer floatingBarSchemeId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("floating_bar_scheme_id", floatingBarSchemeId); + return this.list(queryWrapper); + } + + @Override + public void deleteByFloatingBarSchemeId(Integer floatingBarSchemeId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("floating_bar_scheme_id", floatingBarSchemeId); + this.remove(queryWrapper); + } +} diff --git a/src/main/java/com/huoran/iasf/service/impl/SysFloatingColumnSchemeServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysFloatingColumnSchemeServiceImpl.java new file mode 100644 index 0000000..ab26610 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysFloatingColumnSchemeServiceImpl.java @@ -0,0 +1,322 @@ +package com.huoran.iasf.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysColumn; +import com.huoran.iasf.entity.SysFloatingColumnScheme; +import com.huoran.iasf.entity.SysFloatingColumnSchemeModule; +import com.huoran.iasf.entity.SysFloatingColumnSchemeScopeOfApplication; +import com.huoran.iasf.mapper.SysColumnMapper; +import com.huoran.iasf.mapper.SysFloatingColumnSchemeMapper; +import com.huoran.iasf.mapper.SysFloatingColumnSchemeModuleMapper; +import com.huoran.iasf.mapper.SysFloatingColumnSchemeScopeOfApplicationMapper; +import com.huoran.iasf.service.SysFloatingColumnSchemeService; +import com.huoran.iasf.vo.SysFloatingColumnSchemeVO; +import com.huoran.iasf.vo.req.SuspensionBarListPagingReq; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; + +/** + *

+ * 悬浮栏方案 服务实现类 + *

+ * + * @author cheney + * @since 2024-06-04 + */ +@Service +public class SysFloatingColumnSchemeServiceImpl extends ServiceImpl implements SysFloatingColumnSchemeService { + + @Resource + private SysFloatingColumnSchemeMapper floatingColumnSchemeMapper; + + @Autowired + public SysFloatingColumnSchemeScopeOfApplicationMapper scopeOfApplicationMapper; + + @Autowired + public SysFloatingColumnSchemeModuleMapper floatingColumnSchemeModuleMapper; + + @Autowired + public SysColumnMapper columnMapper; + + private Log logger = LogFactory.getLog(getClass()); + + @Override + public R floatingBarList(SuspensionBarListPagingReq reqVO) { + Page page = new Page(reqVO.getPageNum(), reqVO.getPageSize()); + IPage pageList = baseMapper.floatingBarList(page, reqVO); + return R.success(pageList); + } + + + /** + * isGlobal为1表示应用全部的意思,为1表示部分应用。(表示是否为全局应用,便于快速判断是否存在全局悬浮栏,0表示不是全局悬浮栏,1表示是全局悬浮栏) + *

+ *

+ *

+ * 应用全部权限最高。 + * 1.只要是启用应用全部的,除了没有启用的悬浮栏,包含全部,不论是应用全部还是部分应用的情况下,都会弹窗提示:"当前已启用了的悬浮栏方案将会被取消!" + * 2.如果当前操作的悬浮栏是要为启用状态,且当前的悬浮栏应用类型为为部分应用的情况下下,需要判断当前站点下是否存在已经启用了应用全部的,如果存在,则弹窗提示:"当前已启用全局悬浮栏,无法启用部分应用的悬浮栏,请先禁用全局悬浮栏!" + * 3.部分启用vs部分启用,且有重合的,提示"当前选择的栏目范围与已启用的悬浮栏方案有冲突,请移除冲突的栏目后再试:{后边展示的是冲突的栏目名称}" + * + * @param schemeId 悬浮栏目id + * @param enable 是否禁用(0默认,0启用 1禁用) + * @return + */ + @Transactional + @Override + public R enableOrDisableScheme(Integer schemeId, Integer enable) { + /* SysFloatingColumnScheme scheme = floatingColumnSchemeMapper.selectById(schemeId); + scheme.setFloatingColumnSchemeScopeOfApplications(scopeOfApplicationMapper.selectList(new QueryWrapper().lambda().eq(SysFloatingColumnSchemeScopeOfApplication::getFloatingBarSchemeId, schemeId))); + + if (ObjectUtil.isEmpty(scheme)) { + return R.fail("悬浮窗方案不存在"); + } + + // 获取当前悬浮栏是否为全局应用(1表示全局,0表示非全局) + Integer isGlobal = scheme.getIsGlobal(); + + // 首先处理启用全局悬浮栏逻辑 + if (enable == 0 && isGlobal.equals(1)) { + // 确保没有其他全局悬浮栏已启用 + SysFloatingColumnScheme existingGlobal = floatingColumnSchemeMapper.selectOne(new LambdaQueryWrapper().eq(SysFloatingColumnScheme::getIsGlobal, 1).eq(SysFloatingColumnScheme::getIsDisable, 0)); + if (existingGlobal != null && !Objects.equals(existingGlobal.getId(), schemeId)) { + System.err.println("已有其他全局悬浮栏方案启用,请先禁用它!"); + } + } + + // 2. 当尝试启用非全局悬浮栏,检查是否与已启用的全局悬浮栏冲突 + if (enable == 0) { + SysFloatingColumnScheme globalEnabled = floatingColumnSchemeMapper.selectOne(new LambdaQueryWrapper().eq(SysFloatingColumnScheme::getIsGlobal, 1).eq(SysFloatingColumnScheme::getIsDisable, 0)); + if (globalEnabled != null) { + System.err.println("当前已启用全局悬浮栏,无法启用部分应用的悬浮栏,请先禁用全局悬浮栏"); + } + } + + // 3. 部分启用vs部分启用的冲突检查 + if (enable == 0) { + List activeSchemes = floatingColumnSchemeMapper.selectList(new LambdaQueryWrapper().ne(SysFloatingColumnScheme::getId, schemeId).eq(SysFloatingColumnScheme::getIsDisable, 0)); + + if (!activeSchemes.isEmpty()) { + Set currentScopeIdsSet = new HashSet<>(); + for (SysFloatingColumnSchemeScopeOfApplication scope : scheme.getFloatingColumnSchemeScopeOfApplications()) { + currentScopeIdsSet.addAll(Arrays.asList(scope.getApplicationScopeId().split(","))); + } + + List activeScopes = scopeOfApplicationMapper.selectList(new LambdaQueryWrapper().in(SysFloatingColumnSchemeScopeOfApplication::getFloatingBarSchemeId, activeSchemes.stream().map(SysFloatingColumnScheme::getId).collect(Collectors.toList()))); + + List conflictingScopeIds = activeScopes.stream().flatMap(scope -> Arrays.stream(scope.getApplicationScopeId().split(","))).distinct().filter(currentScopeIdsSet::contains).collect(Collectors.toList()); + + if (!conflictingScopeIds.isEmpty()) { + //根据获取到的栏目id 通过in查询栏目的名称 + List conflictingScopeNames = columnMapper.selectList(new LambdaQueryWrapper().in(SysColumn::getId, conflictingScopeIds)).stream().map(SysColumn::getColumnName).collect(Collectors.toList()); + String columnName = String.join(",", conflictingScopeNames); + System.err.println("当前选择的栏目范围与已启用的悬浮栏方案有冲突,请移除冲突的栏目后再试:" + columnName); + } + } + } + + // 更新悬浮栏方案的状态 + scheme.setIsDisable(enable); + floatingColumnSchemeMapper.updateById(scheme); + + // 如果启用的是全局悬浮栏,需要禁用其他已启用的非全局悬浮栏 + if (isGlobal.equals(1) && enable == 0) { + getNonGlobal(schemeId); + }*/ + + return R.success("操作成功"); + } + + + /** + * 这个方法用来检查是否可以启用或禁用指定悬浮栏方案 + * isGlobal为1表示应用全部的意思,为1表示部分应用。(表示是否为全局应用,便于快速判断是否存在全局悬浮栏,0表示不是全局悬浮栏,1表示是全局悬浮栏) + *

+ * --所有操作里面应用全部权限最高。 + * 1.只要是启用应用全部的,除了没有启用的悬浮栏,包含全部,不论是应用全部还是部分应用的情况下,都会弹窗提示:"当前已启用了的悬浮栏方案将会被取消!" + * 2.如果当前操作的悬浮栏是要为启用状态,且当前的悬浮栏应用类型为为部分应用的情况下下,需要判断当前站点下是否存在已经启用了应用全部的,如果存在,则弹窗提示:"当前已启用全局悬浮栏,无法启用部分应用的悬浮栏,请先禁用全局悬浮栏!" + * 3.部分启用vs部分启用,且有重合的,提示"当前选择的栏目范围与已启用的悬浮栏方案有冲突,请移除冲突的栏目后再试:{后边展示的是冲突的栏目名称}" + * + * @param schemeId 悬浮栏目id + * @param enable 是否禁用(0启用 1禁用) + * @return 包含操作结果或警告信息的对象 + */ + + public R checkEnableOrDisable(Integer schemeId, Integer enable) { + SysFloatingColumnScheme scheme = floatingColumnSchemeMapper.selectById(schemeId); + if (scheme == null) { + return R.fail("悬浮窗方案不存在"); + } + + Integer siteId = scheme.getSiteId(); + + // 1. 当前操作为启用时,检查逻辑 + if (enable == 0) { + // 全局悬浮栏启用逻辑 + // 对于启用操作,先检查是否是全局应用 + if (scheme.getIsGlobal() == 1) { + // 检查站点下是否存在任何已启用的悬浮栏方案,不论全局还是部分应用 + long enabledCount = floatingColumnSchemeMapper.selectCount(new LambdaQueryWrapper().eq(SysFloatingColumnScheme::getSiteId, siteId).eq(SysFloatingColumnScheme::getIsDisable, 0)); + if (enabledCount > 0) { + // 弹窗提示,表明启用新的全局悬浮栏会覆盖当前已启用的悬浮栏 + return R.warn("当前站点已存在启用的悬浮栏方案,启用新方案将会覆盖原有设置,请确认是否继续?"); + } + } else { // 非全局悬浮栏启用逻辑 + // 检查是否存在启用的全局悬浮栏 + if (existsEnabledGlobal(siteId)) { + return R.fail("当前已启用全局悬浮栏,无法直接启用部分应用的悬浮栏,请先禁用全局悬浮栏!"); + } + // 检查与其它部分应用悬浮栏的冲突 + if (hasOverlapWithOtherEnabled(schemeId, siteId)) { + return R.fail(generateConflictMessage(schemeId, siteId, enable)); + } + } + } else if (enable == 1) { // 禁用操作逻辑 + // 禁用操作直接允许,无需特殊检查 + } else { + return R.fail("无效的操作类型"); + } + + // 如果没有冲突,直接返回成功提示 + return R.success("操作可执行"); + } + + @Override + public R columnDisplayFloatingBar(String columnId) { + //获取站点 + SysColumn column = columnMapper.selectById(columnId); + if (ObjectUtil.isEmpty(column)) { + return R.fail("未找到该栏目"); + } + + //查询范围应用为栏目的 + /* List sysFloatingColumnSchemeScopeOfApplications = scopeOfApplicationMapper.selectList(new LambdaQueryWrapper() + .eq(SysFloatingColumnSchemeScopeOfApplication::getFloatingBarSchemeId, columnId) + ); +*/ + + //查询栏目绑定过的悬浮栏 + List sysFloatingColumnSchemeScopeOfApplications = scopeOfApplicationMapper.checkBoundByColumnId(columnId); + + List columnSchemeModuleList = new ArrayList<>(); + + + for (Integer floatingBarId : sysFloatingColumnSchemeScopeOfApplications) { + //查询启用的悬浮栏 + SysFloatingColumnScheme scheme = floatingColumnSchemeMapper.selectById(floatingBarId); + + if (!ObjectUtil.isEmpty(scheme)) { + //且为启用状态下才查询绑定的方案 + if (scheme.getIsDisable() == 0) { + //查询悬浮栏当前绑定的方案 + List columnSchemeModule = floatingColumnSchemeModuleMapper.selectList(new LambdaQueryWrapper() + .eq(SysFloatingColumnSchemeModule::getFloatingBarSchemeId, scheme.getId()).eq(SysFloatingColumnSchemeModule::getIsDisable, 0));; + if (!ObjectUtil.isEmpty(columnSchemeModule)) { + columnSchemeModuleList.addAll(columnSchemeModule); + } + } + + + } + } + + + return R.success(columnSchemeModuleList); + } + + // 辅助方法检查站点下是否存在启用的全局悬浮栏 + private boolean existsEnabledGlobal(Integer siteId) { + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("is_global", 1); + queryWrapper.eq("is_disable", 0); + queryWrapper.eq("site_id", siteId); + return !floatingColumnSchemeMapper.selectList(queryWrapper).isEmpty(); + + } + + + /** + * 检查当前悬浮栏方案与已启用方案是否有重叠。 + * + * @param schemeId 悬浮栏方案ID + * @return 是否有重叠 + */ + private boolean hasOverlapWithOtherEnabled(Integer schemeId, Integer siteId) { + // 获取当前要检查的方案的应用范围 + List currentScopes = scopeOfApplicationMapper.selectList(new LambdaQueryWrapper().eq(SysFloatingColumnSchemeScopeOfApplication::getFloatingBarSchemeId, schemeId)); + + if (currentScopes.isEmpty()) { + return false; // 当前方案无应用范围,自然无重叠 + } + + Set currentScopeIds = currentScopes.stream().flatMap(scope -> Arrays.stream(scope.getApplicationScopeId().split(","))).map(Integer::parseInt).collect(Collectors.toSet()); + + // 构造查询条件,确保比较的方案属于同一个站点 + String sqlInCondition = "SELECT id FROM sys_floating_column_scheme WHERE is_disable = 0 AND site_id = " + siteId; + + // 查询所有启用且ID不等于当前schemeId且属于相同站点的悬浮栏方案的应用范围 + List enabledScopes = scopeOfApplicationMapper.selectList(new LambdaQueryWrapper().ne(SysFloatingColumnSchemeScopeOfApplication::getFloatingBarSchemeId, schemeId).inSql(SysFloatingColumnSchemeScopeOfApplication::getFloatingBarSchemeId, sqlInCondition)); + + // 检查是否有重叠 + for (SysFloatingColumnSchemeScopeOfApplication enabledScope : enabledScopes) { + Set enabledScopeIds = Arrays.stream(enabledScope.getApplicationScopeId().split(",")).map(Integer::parseInt).collect(Collectors.toSet()); + + if (!Collections.disjoint(currentScopeIds, enabledScopeIds)) { + return true; // 存在重叠 + } + } + + return false; // 无重叠 + } + + /** + * 生成冲突提示信息,展示冲突的栏目名称。 + * + * @param schemeId 悬浮栏方案ID + * @return 冲突提示信息 + */ + private String generateConflictMessage(Integer schemeId, Integer siteId, Integer enableAction) { + // 调用 hasOverlapWithOtherEnabled 确认是否有重叠 + if (!hasOverlapWithOtherEnabled(schemeId, siteId)) { + return ""; // 无冲突则返回空字符串 + } + + // 获取当前方案冲突的范围ID + List conflictingScopes = scopeOfApplicationMapper.selectList(new LambdaQueryWrapper().eq(SysFloatingColumnSchemeScopeOfApplication::getFloatingBarSchemeId, schemeId)); + + Set conflictScopeIds = conflictingScopes.stream().flatMap(scope -> Arrays.stream(scope.getApplicationScopeId().split(","))).map(Integer::parseInt).collect(Collectors.toSet()); + + // 查询冲突范围对应的栏目名称 + List conflictingScopeNames = columnMapper.selectList(new LambdaQueryWrapper().in(SysColumn::getId, conflictScopeIds)).stream().map(SysColumn::getColumnName).collect(Collectors.toList()); + + // 根据操作类型调整提示信息() + if (enableAction == 0) { // 启用操作 + return "“" + String.join("”, “", conflictingScopeNames) + "”栏目已设置有悬浮栏,请移除后再试。。"; + } else if (enableAction == 1) { // 禁用操作 + return "“" + String.join("”, “", conflictingScopeNames) + "”存在悬浮栏配置冲突,请注意操作可能影响这些栏目的现有悬浮栏设置。"; + } else { + return "未知的操作类型"; + } + } + + + // 新增方法:统计当前站点下已启用的全局悬浮栏数量 + public Integer countGlobalEnabled(Integer siteId) { + return baseMapper.selectCount(new LambdaQueryWrapper().eq(SysFloatingColumnScheme::getSiteId, siteId).eq(SysFloatingColumnScheme::getIsGlobal, 1).eq(SysFloatingColumnScheme::getIsDisable, false)); + } + +} diff --git a/src/main/java/com/huoran/iasf/util/ConflictException.java b/src/main/java/com/huoran/iasf/util/ConflictException.java new file mode 100644 index 0000000..43fc79c --- /dev/null +++ b/src/main/java/com/huoran/iasf/util/ConflictException.java @@ -0,0 +1,7 @@ +package com.huoran.iasf.util; + +public class ConflictException extends RuntimeException { + public ConflictException(String message) { + super(message); + } +} diff --git a/src/main/java/com/huoran/iasf/vo/SysFloatingColumnSchemeVO.java b/src/main/java/com/huoran/iasf/vo/SysFloatingColumnSchemeVO.java new file mode 100644 index 0000000..9aa9ce6 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/SysFloatingColumnSchemeVO.java @@ -0,0 +1,59 @@ +package com.huoran.iasf.vo; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + *

+ * 悬浮栏方案 + *

+ * + * @author cheney + * @since 2024-06-04 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "SysFloatingColumnScheme对象", description = "悬浮栏方案") +public class SysFloatingColumnSchemeVO { + + + @ApiModelProperty(value = "悬浮栏方案id") + private Integer floatingBarSchemeId; + + @ApiModelProperty(value = "悬浮栏方案名称") + private String schemeName; + + + @ApiModelProperty(value = "应用范围") + private String scopeOfApplication; + + @ApiModelProperty(value = "内容模块数量") + private String numberOfContentModules; + + @ApiModelProperty(value = "是否禁用(0默认,0启用 1禁用)") + private Integer isDisable; + + + @ApiModelProperty(value = "编辑人id", hidden = true) + private Integer editorId; + + @ApiModelProperty(value = "编辑人名称") + private String editorSName; + + + @ApiModelProperty(value = "创建时间") + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + @ApiModelProperty(value = "更新时间") + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateTime; + + +} diff --git a/src/main/java/com/huoran/iasf/vo/req/SuspensionBarListPagingReq.java b/src/main/java/com/huoran/iasf/vo/req/SuspensionBarListPagingReq.java new file mode 100644 index 0000000..dc7818a --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/req/SuspensionBarListPagingReq.java @@ -0,0 +1,31 @@ +package com.huoran.iasf.vo.req; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 悬浮栏方案 + *

+ * + * @author cheney + * @since 2024-06-04 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "SuspensionBarListPagingReq对象", description = "悬浮栏列表请求参数") +public class SuspensionBarListPagingReq extends PageReqVO { + + + @ApiModelProperty(value = "搜索参数") + private String search; + + @ApiModelProperty(value = "站点id") + private Integer siteId; + + /* @ApiModelProperty(value = "是否为前台(用于区分前台和后台,1为前台,0为后台)") + private Integer isForeground;*/ + +} diff --git a/src/test/java/com/company/project/CodeGenerator.java b/src/test/java/com/company/project/CodeGenerator.java index 4fd3a7f..fa06bd7 100644 --- a/src/test/java/com/company/project/CodeGenerator.java +++ b/src/test/java/com/company/project/CodeGenerator.java @@ -61,7 +61,7 @@ public class CodeGenerator { // 5、策略配置 StrategyConfig strategy = new StrategyConfig(); - strategy.setInclude("sys_floating_column_scheme_scope_of_application"); + strategy.setInclude("sys_floating_column_scheme","sys_floating_column_scheme_module","sys_floating_column_scheme_scope_of_application"); strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略 // strategy.setTablePrefix("sys_"); //生成实体时去掉表前缀