init local code

This commit is contained in:
chenxing
2026-09-07 09:09:39 +08:00
commit 99cd26b3d2
259 changed files with 20554 additions and 0 deletions
@@ -0,0 +1,118 @@
package com.yunhai.cms.service.impl;
import com.yunhai.cms.model.vo.SchoolVo;
import com.yunhai.cms.model.vo.SiteVo;
import com.yunhai.cms.repository.CmsArticleRepository;
import com.yunhai.platform.apistd.BizException;
import com.yunhai.platform.openapi.client.YschBaseOpenApi;
import com.yunhai.platform.utils.exception.ErrorCode;
import com.yunhai.platform.utils.model.BoaGroup;
import com.yunhai.platform.utils.model.BoaUser;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* 学校工作台(docs/09 §3.3,方案A 双层壳):
* ① listFor —— 学校卡片 = 顶层站点(主站),院系子站经 parentSiteId 归属;
* 权限语义与 {@link SiteService#listFor} 完全一致(超管全部 / 校级本校 / 无角色空)。
* ② schoolOptions —— 「添加学校」选择器:代理 UserBase oapi getGroupTree 过滤 type=2(学校组),
* 只绑定不跨系统写(D6-4);平台不可达降级空数组(CmsUserCenterService 同款)。
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class SchoolService {
/** UserBase GroupTypeEnum.SCHOOL_GROUP:学校组节点类型 */
private static final int GROUP_TYPE_SCHOOL = 2;
private final SiteService siteService;
private final CmsArticleRepository articleRepository;
/** 学校工作台列表:当前用户可见的顶层站点逐站聚合成学校卡片 */
public List<SchoolVo> listFor(BoaUser user) {
List<SiteVo> sites = siteService.listFor(user);
List<SchoolVo> result = new ArrayList<>();
for (SiteVo top : sites) {
if (top.getParentSiteId() != null && top.getParentSiteId() > 0) {
continue;
}
SchoolVo vo = new SchoolVo();
vo.setSchId(top.getSchId());
vo.setSchName(top.getSchName());
vo.setMainSiteId(top.getId());
vo.setMainSiteCode(top.getCode());
vo.setMainSiteName(top.getName());
vo.setTheme(top.getTheme());
vo.setStatus(top.getStatus());
// 院系子站按 parentSiteId 归属(同权限范围内统计)
long articleCount = 0;
int siteCount = 1;
for (SiteVo s : sites) {
if (s.getParentSiteId() != null && top.getId().equals(s.getParentSiteId())) {
siteCount++;
}
}
for (SiteVo s : sites) {
boolean own = s.getId().equals(top.getId());
boolean child = s.getParentSiteId() != null && top.getId().equals(s.getParentSiteId());
if (own || child) {
articleCount += articleRepository.countBySiteId(s.getId());
}
}
vo.setSiteCount(siteCount);
vo.setArticleCount(articleCount);
result.add(vo);
}
result.sort((a, b) -> Integer.compare(a.getMainSiteId(), b.getMainSiteId()));
return result;
}
/** UserBase 学校选项(仅超管;添加学校=绑定已有学校,不新建) */
public List<SchoolVo.Option> schoolOptions(BoaUser user) {
siteService.requireSuperAdmin(user);
BoaGroup root;
try {
root = YschBaseOpenApi.getGroupTree();
} catch (Exception e) {
log.warn("[cms] 获取 UserBase 学校组树失败,学校选项降级为空: {}", e.getMessage());
return Collections.emptyList();
}
List<SchoolVo.Option> options = new ArrayList<>();
collectSchools(root, options);
return options;
}
private void collectSchools(BoaGroup node, List<SchoolVo.Option> out) {
if (node == null) {
return;
}
if (node.getType() != null && node.getType() == GROUP_TYPE_SCHOOL) {
out.add(new SchoolVo.Option(node.getId(), node.getName()));
}
if (node.getChildren() != null) {
for (BoaGroup child : node.getChildren()) {
collectSchools(child, out);
}
}
}
/** 工作台卡片挂载的站点摘要(供校名下拉/快速切换;权限复用 listFor) */
public Map<Integer, List<SiteVo>> sitesGroupedByMain(BoaUser user) {
List<SiteVo> sites = siteService.listFor(user);
Map<Integer, List<SiteVo>> grouped = new LinkedHashMap<>();
for (SiteVo s : sites) {
Integer mainId = (s.getParentSiteId() == null || s.getParentSiteId() <= 0)
? s.getId() : s.getParentSiteId();
grouped.computeIfAbsent(mainId, k -> new ArrayList<>()).add(s);
}
return grouped;
}
}