diff --git a/src/main/java/com/budwk/app/zhgh/spread/controller/SpreadCreationController.java b/src/main/java/com/budwk/app/zhgh/spread/controller/SpreadCreationController.java index 181ca5e6..c8ed90a2 100644 --- a/src/main/java/com/budwk/app/zhgh/spread/controller/SpreadCreationController.java +++ b/src/main/java/com/budwk/app/zhgh/spread/controller/SpreadCreationController.java @@ -40,6 +40,13 @@ public class SpreadCreationController { return Result.success(categoryService.categoryTree(true)); } + @At + @ApiOperation("当前登录人员可选择的工会") + @SaCheckPermission("spread.creation") + public Result unionOptions() { + return Result.success(contentService.selectableUnions()); + } + @At @ApiOperation("内容详情") @SaCheckPermission("spread.creation") diff --git a/src/main/java/com/budwk/app/zhgh/spread/models/SpreadContent.java b/src/main/java/com/budwk/app/zhgh/spread/models/SpreadContent.java index 2d7eca2a..64385893 100644 --- a/src/main/java/com/budwk/app/zhgh/spread/models/SpreadContent.java +++ b/src/main/java/com/budwk/app/zhgh/spread/models/SpreadContent.java @@ -33,6 +33,16 @@ public class SpreadContent extends BaseModel { @ColDefine(type = ColType.VARCHAR, width = 100) private String categoryName; + @Column + @Comment("所属工会ID") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String unionId; + + @Column + @Comment("所属工会名称") + @ColDefine(type = ColType.VARCHAR, width = 100) + private String unionName; + @Column @Comment("标题") @ColDefine(type = ColType.VARCHAR, width = 300) diff --git a/src/main/java/com/budwk/app/zhgh/spread/service/SpreadContentService.java b/src/main/java/com/budwk/app/zhgh/spread/service/SpreadContentService.java index 07967870..120eb588 100644 --- a/src/main/java/com/budwk/app/zhgh/spread/service/SpreadContentService.java +++ b/src/main/java/com/budwk/app/zhgh/spread/service/SpreadContentService.java @@ -5,6 +5,7 @@ import com.budwk.app.base.param.PageForm; import com.budwk.app.base.service.BaseService; import com.budwk.app.zhgh.spread.models.SpreadContent; import com.budwk.app.zhgh.spread.param.SpreadContentQuery; +import com.budwk.app.sys.models.Sys_union; import org.nutz.lang.util.NutMap; import java.util.List; @@ -28,4 +29,9 @@ public interface SpreadContentService extends BaseService { void addViewCount(String id); List sliderContent(); + + /** + * 查询当前登录人员可选择的工会。 + */ + List selectableUnions(); } diff --git a/src/main/java/com/budwk/app/zhgh/spread/service/impl/SpreadContentServiceImpl.java b/src/main/java/com/budwk/app/zhgh/spread/service/impl/SpreadContentServiceImpl.java index d58ce44a..9871199d 100644 --- a/src/main/java/com/budwk/app/zhgh/spread/service/impl/SpreadContentServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/spread/service/impl/SpreadContentServiceImpl.java @@ -2,9 +2,16 @@ package com.budwk.app.zhgh.spread.service.impl; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.base.page.Pagination; import com.budwk.app.base.param.PageForm; import com.budwk.app.base.service.impl.BaseServiceImpl; +import com.budwk.app.sys.models.Sys_union; +import com.budwk.app.web.commons.auth.utils.AuthUtil; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.zhgh.spread.models.SpreadCategory; import com.budwk.app.zhgh.spread.models.SpreadContent; import com.budwk.app.zhgh.spread.param.SpreadContentQuery; @@ -17,6 +24,7 @@ import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.lang.util.NutMap; import java.util.ArrayList; +import java.util.Collections; import java.util.List; @IocBean(args = {"refer:dao"}) @@ -149,7 +157,7 @@ public class SpreadContentServiceImpl extends BaseServiceImpl imp @Override public List sliderContent() { Sql sql = Sqls.create(""" - SELECT c.id, c.title, c.summary, c.thumbUrl, c.sliderImages, c.categoryId, c.categoryName + SELECT c.id, c.title, c.summary, c.thumbUrl, c.sliderImages, c.categoryId, c.categoryName, c.unionId, c.unionName FROM spread_content c INNER JOIN spread_category child ON child.id = c.categoryId LEFT JOIN spread_category parent ON parent.id = child.parentId @@ -167,6 +175,77 @@ public class SpreadContentServiceImpl extends BaseServiceImpl imp return sql.getList(NutMap.class); } + @Override + public List selectableUnions() { + Cnd cnd = Cnd.NEW(); + if (!canSelectAllUnions()) { + String currentUnionId = SecurityUtil.getUnionId(); + if (StrUtil.isBlank(currentUnionId)) { + return Collections.emptyList(); + } + cnd.and("id", "=", currentUnionId); + } + cnd.asc("unionCode"); + return dao().query(Sys_union.class, cnd); + } + + /** + * 校工会管理员和系统管理员可选择全部工会,其他人员只能选择登录人员自己的分工会。 + */ + private boolean canSelectAllUnions() { + return AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name()); + } + + /** + * 校验工会是否存在且在当前登录人员的可选择范围内。 + */ + private Sys_union requireSelectableUnion(String unionId) { + if (StrUtil.isBlank(unionId)) { + throw new RuntimeException("请选择所属工会"); + } + Sys_union union = dao().fetch(Sys_union.class, unionId); + if (union == null) { + throw new RuntimeException("所属工会不存在"); + } + if (!canSelectAllUnions() && !unionId.equals(SecurityUtil.getUnionId())) { + throw new RuntimeException("无权选择该所属工会"); + } + return union; + } + + /** + * 校验并规范每张轮播图的标题,轮播图统一继承内容所属工会。 + */ + private void validateSliderImages(SpreadContent content) { + if (StrUtil.isBlank(content.getSliderImages())) { + return; + } + JSONArray sliderArray; + try { + sliderArray = JSONUtil.parseArray(content.getSliderImages()); + } catch (RuntimeException e) { + throw new RuntimeException("轮播图片数据格式不正确"); + } + JSONArray normalizedArray = new JSONArray(); + for (int i = 0; i < sliderArray.size(); i++) { + Object rawItem = sliderArray.get(i); + if (!(rawItem instanceof JSONObject)) { + throw new RuntimeException("请完善第" + (i + 1) + "张轮播图标题"); + } + JSONObject item = (JSONObject) rawItem; + if (StrUtil.isBlank(item.getStr("src"))) { + throw new RuntimeException("第" + (i + 1) + "张轮播图地址不能为空"); + } + if (StrUtil.isBlank(item.getStr("title"))) { + throw new RuntimeException("请输入第" + (i + 1) + "张轮播图标题"); + } + JSONObject normalizedItem = new JSONObject(); + normalizedItem.set("src", item.getStr("src")); + normalizedItem.set("title", item.getStr("title").trim()); + normalizedArray.add(normalizedItem); + } + content.setSliderImages(JSONUtil.toJsonStr(normalizedArray)); + } private Cnd buildCondition(SpreadContentQuery query) { Cnd cnd = Cnd.where("c.delFlag", "=", false); if (query == null) { @@ -204,11 +283,16 @@ public class SpreadContentServiceImpl extends BaseServiceImpl imp Cnd.where("parentId", "=", category.getId()).and("delFlag", "=", false)) > 0) { throw new RuntimeException("内容只能发布到末级栏目"); } + + Sys_union union = requireSelectableUnion(content.getUnionId()); if (StrUtil.isBlank(content.getTitle())) { throw new RuntimeException("标题不能为空"); } content.setTitle(content.getTitle().trim()); content.setCategoryName(category.getName()); + content.setUnionName(union.getName()); + validateSliderImages(content); + } private void applyDefaults(SpreadContent content) { diff --git a/src/main/java/com/budwk/app/zhgh/spread/service/impl/SpreadStatisticsServiceImpl.java b/src/main/java/com/budwk/app/zhgh/spread/service/impl/SpreadStatisticsServiceImpl.java index 9e8d2c84..6ed7e0fb 100644 --- a/src/main/java/com/budwk/app/zhgh/spread/service/impl/SpreadStatisticsServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/spread/service/impl/SpreadStatisticsServiceImpl.java @@ -44,9 +44,10 @@ public class SpreadStatisticsServiceImpl implements SpreadStatisticsService { @Override public List top10(SpreadStatisticsQuery query) { Sql sql = Sqls.create(""" - SELECT c.id, c.title, c.categoryName, c.viewCount, c.isPublished, c.publishedAt + SELECT c.id, c.title, c.summary, c.categoryName, c.unionId, c.unionName, c.viewCount, c.isPublished, c.publishedAt FROM spread_content c WHERE c.delFlag = 0 + AND c.isPublished = 1 $condition ORDER BY c.viewCount DESC, c.updatedAt DESC LIMIT 10 @@ -65,6 +66,7 @@ public class SpreadStatisticsServiceImpl implements SpreadStatisticsService { IFNULL(SUM(c.viewCount), 0) AS viewCount FROM spread_content c WHERE c.delFlag = 0 + AND c.isPublished = 1 $condition GROUP BY c.categoryId, c.categoryName ORDER BY viewCount DESC, contentCount DESC diff --git a/src/main/resources/db/spread_create.sql b/src/main/resources/db/spread_create.sql index 4bfda893..91a6b6f5 100644 --- a/src/main/resources/db/spread_create.sql +++ b/src/main/resources/db/spread_create.sql @@ -23,6 +23,8 @@ CREATE TABLE IF NOT EXISTS `spread_content` ( `id` varchar(32) NOT NULL COMMENT 'ID', `categoryId` varchar(32) NOT NULL COMMENT '栏目ID', `categoryName` varchar(100) NOT NULL COMMENT '栏目名称', + `unionId` varchar(32) DEFAULT NULL COMMENT '所属工会ID', + `unionName` varchar(100) DEFAULT NULL COMMENT '所属工会名称', `title` varchar(300) NOT NULL COMMENT '标题', `subTitle` varchar(255) DEFAULT NULL COMMENT '副标题', `summary` varchar(1000) DEFAULT NULL COMMENT '摘要', @@ -43,6 +45,7 @@ CREATE TABLE IF NOT EXISTS `spread_content` ( `delFlag` tinyint NOT NULL DEFAULT 0 COMMENT '删除标记', PRIMARY KEY (`id`), KEY `idx_spread_content_category` (`categoryId`), + KEY `idx_spread_content_union` (`unionId`), KEY `idx_spread_content_publish` (`isPublished`, `publishedAt`), KEY `idx_spread_content_top_sort` (`isTop`, `sortOrder`), KEY `idx_spread_content_created` (`createdAt`) diff --git a/src/main/resources/static/assets/platform/img/spread-bg.png b/src/main/resources/static/assets/platform/img/spread-bg.png new file mode 100644 index 00000000..ac3ce630 Binary files /dev/null and b/src/main/resources/static/assets/platform/img/spread-bg.png differ diff --git a/src/main/resources/views/platform/zhgh/spread/category/index.html b/src/main/resources/views/platform/zhgh/spread/category/index.html index 8582a479..5eec9daf 100644 --- a/src/main/resources/views/platform/zhgh/spread/category/index.html +++ b/src/main/resources/views/platform/zhgh/spread/category/index.html @@ -11,7 +11,7 @@ layout("/layouts/platform.html"){ - +