feat(appicon): 应用图标键下发出栏(YschAppIcons 10-04 轮 P2 后端)
build / build-push (push) Successful in 13m48s

- AppIconKeyService/AppIconEntryVo(新):icon_key/icon_color 资产库键值读取
- UserController:getUserApp 返回体加图标键注入(withIconKeys)
- UserSettingsController:用户设置应用列表注入 iconKey/iconColor(未配置 null 走原 img 回退)
- UsedAppController/UsedAppServiceImpl:常用应用列表同口径注入
依据:根目录《AppIcon资产库落地-执行报告-20261004.md》P2 数据侧/管理端
This commit is contained in:
chenxing
2026-10-06 20:21:04 +08:00
parent 564403b5ca
commit b621c959cf
6 changed files with 197 additions and 3 deletions
@@ -5,7 +5,9 @@ import com.yunhai.platform.utils.model.BoaAppType;
import com.yunhai.platform.utils.model.BoaUser;
import com.yunhai.userhome.config.Config;
import com.yunhai.userhome.entity.UsedApp;
import com.yunhai.userhome.model.AppIconEntryVo;
import com.yunhai.userhome.model.SetType;
import com.yunhai.userhome.service.AppIconKeyService;
import com.yunhai.userhome.service.AppRemoteService;
import com.yunhai.userhome.service.UsedAppService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -36,6 +38,9 @@ public class UsedAppController {
@Autowired
private AppRemoteService appRemoteService;
@Autowired
private AppIconKeyService appIconKeyService;
/**
* 取当前角色生效的常用应用(BoaApp 详情,按 appIds 顺序)。
*
@@ -112,7 +117,7 @@ public class UsedAppController {
usedAppService.saveUserId(usedApp);
}
/** 按 appIds(逗号分隔)取应用精简映射(id/name/icon/url),在全集中查找。 */
/** 按 appIds(逗号分隔)取应用精简映射(id/name/icon/url/iconKey/iconColor),在全集中查找。 */
@GetMapping("getAppByIds")
public List<Map<String, Object>> getAppByIds(BoaUser authUserWithDept, String appIds) {
List<Map<String, Object>> list = new ArrayList<>();
@@ -132,6 +137,10 @@ public class UsedAppController {
m.put("name", app.getName());
m.put("icon", app.getIcon());
m.put("url", app.getWebAddr());
// 矢量图标键(AppIcon 通道;未配置为 null,前端按空走原 img 回退)
AppIconEntryVo iconEntry = appIconKeyService.byId(app.getId());
m.put("iconKey", iconEntry == null ? null : iconEntry.getIconKey());
m.put("iconColor", iconEntry == null ? null : iconEntry.getIconColor());
list.add(m);
});
} catch (NumberFormatException ignore) {
@@ -1,5 +1,7 @@
package com.yunhai.userhome.controller.api;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yunhai.platform.apistd.BizException;
import com.yunhai.platform.openapi.base.OpenApiUserClient;
import com.yunhai.platform.openapi.base.YschBaseOpenApi;
@@ -11,6 +13,8 @@ import com.yunhai.platform.utils.model.BoaAppType;
import com.yunhai.platform.utils.model.BoaRoleInfo;
import com.yunhai.platform.utils.model.BoaUser;
import com.yunhai.userhome.config.Config;
import com.yunhai.userhome.model.AppIconEntryVo;
import com.yunhai.userhome.service.AppIconKeyService;
import com.yunhai.userhome.service.AppRemoteService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -48,6 +52,12 @@ public class UserController {
@Autowired
private YschOpenCall openCall;
@Autowired
private AppIconKeyService appIconKeyService;
@Autowired
private ObjectMapper objectMapper;
/** 当前登录用户信息(CAS 注入)。 */
@GetMapping("GetUserInfo")
@@ -72,9 +82,41 @@ public class UserController {
* @param userId 指定用户(缺省用登录用户)
*/
@GetMapping("GetUserApp")
public List<BoaAppType> getUserApp(BoaUser authUserWithDept, Integer schId,
public JsonNode getUserApp(BoaUser authUserWithDept, Integer schId,
@RequestParam(name = "userId", required = false) Integer userId) {
return appRemoteService.getUserApps(authUserWithDept);
return withIconKeys(appRemoteService.getUserApps(authUserWithDept));
}
/**
* 应用分组结果上合并注入矢量图标字段(iconKey/iconColor,AppIcon 资产库通道)。<br>
* BoaApp 属 BasePlatform SDK 本期不动:SDK 反序列化会丢弃 icon-map 的扩展字段,
* 故序列化前经 JsonNode 平铺注入;icon-map 不可达时按空映射跳过,出参结构与原值完全一致(零回归)。
*/
private JsonNode withIconKeys(List<BoaAppType> types) {
JsonNode root = objectMapper.valueToTree(types);
Map<Integer, AppIconEntryVo> iconMap = appIconKeyService.iconMap();
if (iconMap.isEmpty() || root == null || !root.isArray()) {
return root;
}
for (JsonNode type : root) {
JsonNode apps = type.get("apps");
if (apps == null || !apps.isArray()) {
continue;
}
for (JsonNode app : apps) {
JsonNode idNode = app.get("id");
if (idNode == null || !idNode.isNumber()) {
continue;
}
AppIconEntryVo entry = iconMap.get(idNode.asInt());
if (entry != null) {
((com.fasterxml.jackson.databind.node.ObjectNode) app)
.put("iconKey", entry.getIconKey())
.put("iconColor", entry.getIconColor());
}
}
}
return root;
}
/** 按应用ID取单个应用(在已拉取全集中查找,免额外跨仓请求)。 */
@@ -14,6 +14,8 @@ import com.yunhai.userhome.entity.*;
import com.yunhai.userhome.enums.DesktopAppType;
import com.yunhai.userhome.enums.LightAppGroup;
import com.yunhai.userhome.enums.LinkOpenType;
import com.yunhai.userhome.model.AppIconEntryVo;
import com.yunhai.userhome.service.AppIconKeyService;
import com.yunhai.userhome.service.IUserCurrentRoleService;
import com.yunhai.userhome.service.IUserSettingsService;
import com.yunhai.userhome.service.UsedAppService;
@@ -59,6 +61,9 @@ public class UserSettingsController {
@Autowired
private OpenApiUserClient openApiUserClient;
@Autowired
private AppIconKeyService appIconKeyService;
// ==================== 壁纸 ====================
/**
@@ -376,6 +381,10 @@ public class UserSettingsController {
map.put("type", DesktopAppType.Bsch.getKey());
map.put("linkType", LinkOpenType.Open.getKey());
map.put("layout", null);
// 矢量图标键(AppIcon 通道;未配置为 null,前端按空走原 img 回退)
AppIconEntryVo iconEntry = appIconKeyService.byId(optionalBoaApp.get().getId());
map.put("iconKey", iconEntry == null ? null : iconEntry.getIconKey());
map.put("iconColor", iconEntry == null ? null : iconEntry.getIconColor());
} else if (desktopApp.getAppType() == DesktopAppType.Light) {
Optional<LightApp> optionalLightApp = lightAllList.stream()
.filter(app -> desktopApp.getAppId().equals(app.getId())).findFirst();