更新数字基座
build / build-push (push) Successful in 1m3s

This commit is contained in:
chenxing
2026-08-24 09:29:31 +08:00
parent 4ed43dbc05
commit a7539a4cf0
48 changed files with 2983 additions and 3 deletions
@@ -0,0 +1,92 @@
package com.yunhai.userhome.controller.api;
import com.yunhai.platform.utils.model.BoaUser;
import com.yunhai.userhome.config.Config;
import com.yunhai.userhome.entity.MenuBar;
import com.yunhai.userhome.entity.UserCurrentRole;
import com.yunhai.userhome.service.IMenuBarService;
import com.yunhai.userhome.service.IUserCurrentRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/**
* 菜单栏控制器(对齐旧 UserHome contorller.api.MenuBarController)。
*/
@RestController
@RequestMapping(Config.API_PATH)
public class MenuBarController {
@Autowired
private IMenuBarService menuBarService;
@Autowired
private IUserCurrentRoleService userCurrentRoleService;
@GetMapping("getMenuBarSchList")
public List<MenuBar> getMenuBarSchList(BoaUser authUserWithDept) {
UserCurrentRole userCurrentRole = userCurrentRoleService.findById(authUserWithDept.getId())
.orElseThrow(() -> new com.yunhai.platform.apistd.BizException(com.yunhai.platform.utils.exception.ErrorCode.INTERNAL_SERVER_ERROR));
return menuBarService.getMenuBarList(userCurrentRole.getSchId());
}
@GetMapping("getMenuBarList")
public List<Map> getMenuBarList(BoaUser authUserWithDept) {
List<Map> result = new ArrayList<>();
UserCurrentRole userCurrentRole = userCurrentRoleService.findById(authUserWithDept.getId())
.orElseThrow(() -> new com.yunhai.platform.apistd.BizException(com.yunhai.platform.utils.exception.ErrorCode.INTERNAL_SERVER_ERROR));
Integer roleId = userCurrentRole.getRoleId();
if (roleId == 7 || roleId == 2) roleId = 2;
Boolean isSuperAdmin = authUserWithDept.getType() == 1;
List<MenuBar> list = menuBarService.findMenuBarById(authUserWithDept.getId());
for (MenuBar model : list) {
Map map = new HashMap();
if (!isSuperAdmin && !model.getRoleIds().contains(roleId)) continue;
map.put("id", model.getId());
map.put("name", model.getName());
map.put("url", model.getUrl());
map.put("icon", model.getIcon());
map.put("isNative", model.getIsNative());
map.put("isHeader", model.getIsHeader());
map.put("isBottom", model.getIsBottom());
map.put("orderNum", model.getOrderNum());
map.put("openType", model.getLinkOpenType());
result.add(map);
}
return result;
}
@PostMapping(value = "saveMenuBar", produces = "application/json")
public void saveMenuBar(BoaUser authUserWithDept, @RequestBody MenuBar menuBar) {
UserCurrentRole userCurrentRole = userCurrentRoleService.findById(authUserWithDept.getId())
.orElseThrow(() -> new com.yunhai.platform.apistd.BizException(com.yunhai.platform.utils.exception.ErrorCode.INTERNAL_SERVER_ERROR));
menuBar.setCId(authUserWithDept.getId());
menuBar.setSchId(userCurrentRole.getSchId());
if (menuBar.getId() == null) menuBar.setCDate(new Date());
menuBarService.saveMenuBar(menuBar);
}
@PostMapping(value = "toggleMenuBarShow", produces = "application/json")
public void toggleMenuBarShow(BoaUser authUserWithDept, Integer id) {
UserCurrentRole userCurrentRole = userCurrentRoleService.findById(authUserWithDept.getId())
.orElseThrow(() -> new com.yunhai.platform.apistd.BizException(com.yunhai.platform.utils.exception.ErrorCode.INTERNAL_SERVER_ERROR));
menuBarService.toggleMenuBarShow(id, userCurrentRole.getSchId());
}
@PostMapping(value = "saveMenuBarOrderNum", produces = "application/json")
public void saveMenuBarOrderNum(BoaUser authUserWithDept, @RequestBody Map<String, Integer> params) {
Integer id = params.get("id"),
orderNum = params.get("orderNum");
menuBarService.saveMenuBarOrderNum(id, orderNum);
}
@PostMapping(value = "deleteMenuBar", produces = "application/json")
public void deleteMenuBar(BoaUser authUserWithDept, Integer id) {
menuBarService.deleteMenuBar(id);
}
}
@@ -0,0 +1,111 @@
package com.yunhai.userhome.controller.api;
import com.yunhai.platform.utils.model.BoaApp;
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.UserMessage;
import com.yunhai.userhome.service.AppRemoteService;
import com.yunhai.userhome.service.IUserMessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* 消息中心接口(CAS 登录态,路径 {@code /{platform}/}),对齐旧 UserHome MessageController 契约。
* <p>响应字段与旧版 {@code getMessageByUserId} 完全一致:{id,msg,date,name,avatar,appPath,msgType}。</p>
*/
@RestController
@RequestMapping(value = Config.API_PATH)
public class MessageController {
@Autowired
private IUserMessageService userMessageService;
@Autowired
private AppRemoteService appRemoteService;
/** schId=0 时推断:主学校 → 主归属组(bureau)→ 0(对齐旧版 school.id→bureau.id→0)。 */
private Integer resolveSchId(BoaUser user) {
if (user.getSchool() != null) {
return user.getSchool().getId();
}
if (user.getBureau() != null) {
return user.getBureau().getId();
}
return 0;
}
private List<BoaApp> flattenApps(BoaUser user) {
List<BoaAppType> types = appRemoteService.getUserApps(user);
if (types == null) {
return new ArrayList<>();
}
List<BoaApp> apps = new ArrayList<>();
for (BoaAppType t : types) {
if (t.getApps() != null) {
apps.addAll(t.getApps());
}
}
return apps;
}
// 获取个人最近消息(对齐旧 getMessageByUserId,响应 List<Map>,字段逐字核对)
@GetMapping("getMessageByUserId")
public List<Map<String, Object>> getMessageByUserId(BoaUser authUserWithDept, Integer page, Integer count) {
Integer userId = authUserWithDept.getId();
Integer schId = resolveSchId(authUserWithDept);
List<UserMessage> msgList = userMessageService.findUserMessageByUserId(userId);
Collections.reverse(msgList);
List<BoaApp> appList = flattenApps(authUserWithDept);
List<Map<String, Object>> list = new ArrayList<>();
for (UserMessage msg : msgList) {
Optional<BoaApp> boaApp = appList.stream().filter(x -> x.getId() != null && x.getId().equals(msg.getAppId())).findFirst();
if (!boaApp.isPresent()) {
continue;
}
BoaApp model = boaApp.get();
Map<String, Object> map = new HashMap<>();
map.put("id", msg.getId());
map.put("msg", msg.getContent());
map.put("date", msg.getCDate());
map.put("name", model.getName());
map.put("avatar", model.getIcon());
map.put("appPath", model.getWebAddr());
map.put("msgType", model.getType());
list.add(map);
}
return list;
}
// 已读消息(对齐旧 readMessage,POST,参数 id,返回 void)
@PostMapping("readMessage")
public void readMessage(BoaUser authUserWithDept, Integer id) {
userMessageService.updateUserRead(id, authUserWithDept.getId());
}
// 全部已读消息(对齐旧 readMessageAll,POST 无参,返回 void)
@PostMapping("readMessageAll")
public void readMessageAll(BoaUser authUserWithDept) {
userMessageService.updateReadAll(authUserWithDept.getId());
}
// 是否有新消息(对齐旧 findUserMessageUnRead,GET,返回 Boolean)
@GetMapping("findUserMessageUnRead")
public Boolean findUserMessageUnRead(BoaUser authUserWithDept) {
return userMessageService.findUserMessageUnRead(authUserWithDept.getId());
}
}
@@ -0,0 +1,58 @@
package com.yunhai.userhome.controller.api;
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.BoaUser;
import com.yunhai.userhome.config.Config;
import com.yunhai.userhome.utils.OtherUtil;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.view.RedirectView;
import java.util.Map;
/**
* 承载旧后端 UserController 中挂在扁平路径 {@code /{platform}/} 下的端点。
*
* <p>新后端 UserController 已改为 {@code /{platform}/user/} 前缀,
* 但以下两个端点的前端调用路径是扁平的(不含 /user/ 段),故单独抽出:
* <ul>
* <li>{@code POST /api/updateUserPassword} — 前端 BaseApi.updatePassword</li>
* <li>{@code GET /api/RedirectTo/{hexUrl}} — 前端 bschSsoRedirect.replaceOriginUrl</li>
* </ul>
*/
@RestController
@RequestMapping(value = Config.API_PATH)
public class MiscController {
/**
* 修改用户密码(对齐旧 UserController.updateUserPassword)。
* 前端调用:BaseApi.updatePassword → POST /api/updateUserPassword
*/
@PostMapping("updateUserPassword")
public void updateUserPassword(BoaUser authUserWithDept, @RequestBody Map<String, String> params) {
String password = params.get("password");
String oldPassword = params.get("oldPassword");
if (password == null || password.trim().isEmpty() || oldPassword == null || oldPassword.trim().isEmpty()) {
throw new BizException(ErrorCode.PARAM_ERROR, "密码参数不能为空");
}
if (password.equals(oldPassword)) {
throw new BizException(ErrorCode.CUSTOM, "新密码不得与旧密码相同!");
}
try {
YschBaseOpenApi.updateUserPassword(authUserWithDept.getId(), oldPassword, password);
} catch (Exception e) {
throw new BizException(ErrorCode.CUSTOM, e.getMessage());
}
}
/**
* 十六进制 URL 重定向(对齐旧 UserController.RedirectTo)。
* 前端调用:bschSsoRedirect.replaceOriginUrl → GET /api/RedirectTo/{hexUrl}
*/
@GetMapping("RedirectTo/{id}")
public RedirectView redirectTo(@PathVariable(name = "id") String id) {
String url = OtherUtil.hexToString(id);
return new RedirectView(url, true);
}
}
@@ -0,0 +1,84 @@
package com.yunhai.userhome.controller.api;
import com.yunhai.platform.utils.model.BoaUser;
import com.yunhai.userhome.config.Config;
import com.yunhai.userhome.entity.SchSettings;
import com.yunhai.userhome.service.ISchSettingsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.Optional;
/**
* 学校设置接口(CAS 登录态,路径 {@code /{platform}/}),对齐旧 UserHome SchSettingsController。
* <p>getSchSettings 实际跨仓调用 schConfig(见 SchSettingsServiceImpl);
* saveSchTheme/saveSchLogo(P1)本期写入本地 sch_settings 表(跨仓回写可后续对接)。</p>
*/
@RestController
@RequestMapping(value = Config.API_PATH)
public class SchSettingsController {
@Autowired
private ISchSettingsService schSettingsService;
private Integer resolveSchId(BoaUser user) {
if (user.getSchool() != null) {
return user.getSchool().getId();
}
if (user.getBureau() != null) {
return user.getBureau().getId();
}
return 0;
}
@PostMapping("saveSchTheme")
public void saveSchTheme(BoaUser authUserWithDept, String themeName, @RequestParam(name = "schId", defaultValue = "0") Integer schId) {
if (schId == null || schId == 0) {
schId = resolveSchId(authUserWithDept);
}
SchSettings schSettings = new SchSettings();
Optional<SchSettings> model = schSettingsService.findBySchId(schId);
if (model.isPresent()) {
schSettings = model.get();
}
schSettings.setCDate(new Date());
schSettings.setSchId(schId);
schSettings.setCId(authUserWithDept.getId());
schSettings.setThemeName(themeName);
schSettingsService.save(schSettings);
}
@PostMapping("saveSchLogo")
public void saveSchLogo(BoaUser authUserWithDept, String logoUrl, @RequestParam(name = "schId", defaultValue = "0") Integer schId) {
if (schId == null || schId == 0) {
schId = resolveSchId(authUserWithDept);
}
SchSettings schSettings = newSchSettingsOrLoad(schId, authUserWithDept);
schSettings.setLogoUrl(logoUrl);
schSettingsService.save(schSettings);
}
/** getSchSettings:schId=0 时按 主学校→主归属组→0 推断(对齐旧 SchSettingsController)。 */
@GetMapping("getSchSettings")
public Optional<SchSettings> getSchSettings(BoaUser authUserWithDept,
@RequestParam(name = "schId", defaultValue = "0") Integer schId) {
if (schId == null || schId == 0) {
schId = resolveSchId(authUserWithDept);
}
return schSettingsService.findBySchId(schId);
}
private SchSettings newSchSettingsOrLoad(Integer schId, BoaUser user) {
Optional<SchSettings> model = schSettingsService.findBySchId(schId);
SchSettings schSettings = model.orElseGet(SchSettings::new);
schSettings.setCDate(new Date());
schSettings.setSchId(schId);
schSettings.setCId(user.getId());
return schSettings;
}
}
@@ -0,0 +1,33 @@
package com.yunhai.userhome.controller.api;
import com.yunhai.platform.utils.model.BoaUser;
import com.yunhai.userhome.config.Config;
import com.yunhai.userhome.utils.MapCacheUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
/**
* WebSocket 鉴权地址端点(CAS 登录态,路径 {@code /{platform}/})。
* <p>对齐旧 UserHome SocketController.getMsgAddress:生成 uuid → 缓存(uuid→userId, 20s) →
* 返回 {@code {WEBSOCKET_URL}/{uuid}},供前端握手阶段鉴权。WS 推送服务端本期可后置,
* 前端改轮询 {@code getMessageByUserId} 兜底刷新。</p>
*/
@RestController
@RequestMapping(value = Config.API_PATH)
public class SocketController {
@Value("${WEBSOCKET_URL:ws://localhost:8091/ws}")
private String websocketUrl;
@GetMapping("getMsgAddress")
public String getMsgAddress(BoaUser authUserWithDept) {
Integer uid = authUserWithDept.getId();
UUID uuid = UUID.randomUUID();
MapCacheUtil.getInstance().add(uuid.toString(), uid.toString(), 20 * 1000L);
return this.websocketUrl + "/" + uuid.toString();
}
}
@@ -0,0 +1,88 @@
package com.yunhai.userhome.controller.api;
import com.yunhai.platform.utils.model.BoaUser;
import com.yunhai.userhome.config.Config;
import com.yunhai.userhome.entity.StatsBar;
import com.yunhai.userhome.entity.UserCurrentRole;
import com.yunhai.userhome.service.IStatsBarService;
import com.yunhai.userhome.service.IUserCurrentRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/**
* 统计栏目控制器(对齐旧 UserHome contorller.api.StatsBarController)。
*/
@RestController
@RequestMapping(Config.API_PATH)
public class StatsBarController {
@Autowired
private IStatsBarService statsBarService;
@Autowired
private IUserCurrentRoleService userCurrentRoleService;
@GetMapping("getStatsBarSchList")
public List<StatsBar> getStatsBarSchList(BoaUser authUserWithDept) {
UserCurrentRole userCurrentRole = userCurrentRoleService.findById(authUserWithDept.getId())
.orElseThrow(() -> new com.yunhai.platform.apistd.BizException(com.yunhai.platform.utils.exception.ErrorCode.INTERNAL_SERVER_ERROR));
return statsBarService.getStatsBarList(userCurrentRole.getSchId());
}
@GetMapping("getStatsBarList")
public List<Map> getStatsBarList(BoaUser authUserWithDept) {
List<Map> result = new ArrayList<>();
UserCurrentRole userCurrentRole = userCurrentRoleService.findById(authUserWithDept.getId())
.orElseThrow(() -> new com.yunhai.platform.apistd.BizException(com.yunhai.platform.utils.exception.ErrorCode.INTERNAL_SERVER_ERROR));
Integer roleId = userCurrentRole.getRoleId();
if (roleId == 7 || roleId == 2) roleId = 2;
Boolean isSuperAdmin = authUserWithDept.getType() == 1;
List<StatsBar> list = statsBarService.findStatsBarById(authUserWithDept.getId());
for (StatsBar model : list) {
Map map = new HashMap();
if (!isSuperAdmin && !model.getRoleIds().contains(roleId)) continue;
map.put("id", model.getId());
map.put("name", model.getName());
map.put("url", model.getUrl());
map.put("icon", model.getIcon());
map.put("openType", model.getLinkOpenType());
result.add(map);
}
return result;
}
@PostMapping(value = "saveStatsBar", produces = "application/json")
public void saveStatsBar(BoaUser authUserWithDept, @RequestBody StatsBar statsBar) {
UserCurrentRole userCurrentRole = userCurrentRoleService.findById(authUserWithDept.getId())
.orElseThrow(() -> new com.yunhai.platform.apistd.BizException(com.yunhai.platform.utils.exception.ErrorCode.INTERNAL_SERVER_ERROR));
statsBar.setCId(authUserWithDept.getId());
statsBar.setSchId(userCurrentRole.getSchId());
if (statsBar.getId() == null) statsBar.setCDate(new Date());
statsBarService.saveStatsBar(statsBar);
}
@PostMapping(value = "toggleStatsBarShow", produces = "application/json")
public void toggleStatsBarShow(BoaUser authUserWithDept, Integer id) {
UserCurrentRole userCurrentRole = userCurrentRoleService.findById(authUserWithDept.getId())
.orElseThrow(() -> new com.yunhai.platform.apistd.BizException(com.yunhai.platform.utils.exception.ErrorCode.INTERNAL_SERVER_ERROR));
statsBarService.toggleStatsBarShow(id, userCurrentRole.getSchId());
}
@PostMapping(value = "saveStatsBarOrderNum", produces = "application/json")
public void saveStatsBarOrderNum(BoaUser authUserWithDept, @RequestBody Map<String, Integer> params) {
Integer id = params.get("id"),
orderNum = params.get("orderNum");
statsBarService.saveStatsBarOrderNum(id, orderNum);
}
@PostMapping(value = "deleteStatsBar", produces = "application/json")
public void deleteStatsBar(BoaUser authUserWithDept, Integer id) {
statsBarService.deleteStatsBar(id);
}
}
@@ -0,0 +1,89 @@
package com.yunhai.userhome.controller.api;
import com.yunhai.platform.utils.model.BoaUser;
import com.yunhai.userhome.config.Config;
import com.yunhai.userhome.entity.TeacherCopilot;
import com.yunhai.userhome.entity.UserCurrentRole;
import com.yunhai.userhome.service.ITeacherCopilotService;
import com.yunhai.userhome.service.IUserCurrentRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/**
* 教师助手控制器(对齐旧 UserHome contorller.api.TeacherCopilotController)。
*/
@RestController
@RequestMapping(Config.API_PATH)
public class TeacherCopilotController {
@Autowired
private ITeacherCopilotService teacherCopilotService;
@Autowired
private IUserCurrentRoleService userCurrentRoleService;
@GetMapping("TeacherCopilot/getSchList")
public List<TeacherCopilot> getList(BoaUser authUserWithDept) {
UserCurrentRole userCurrentRole = userCurrentRoleService.findById(authUserWithDept.getId())
.orElseThrow(() -> new com.yunhai.platform.apistd.BizException(com.yunhai.platform.utils.exception.ErrorCode.INTERNAL_SERVER_ERROR));
return teacherCopilotService.getList(userCurrentRole.getSchId());
}
@GetMapping("TeacherCopilot/getUserList")
public List<TeacherCopilot.Dto> getUserList(BoaUser authUserWithDept) {
List<TeacherCopilot.Dto> result = new ArrayList<>();
UserCurrentRole userCurrentRole = userCurrentRoleService.findById(authUserWithDept.getId())
.orElseThrow(() -> new com.yunhai.platform.apistd.BizException(com.yunhai.platform.utils.exception.ErrorCode.INTERNAL_SERVER_ERROR));
Integer roleId = userCurrentRole.getRoleId();
if (roleId == 7 || roleId == 2) roleId = 2;
Boolean isSuperAdmin = authUserWithDept.getType() == 1;
List<TeacherCopilot> list = teacherCopilotService.findById(authUserWithDept.getId());
for (TeacherCopilot model : list) {
TeacherCopilot.Dto dto = new TeacherCopilot.Dto();
if (!isSuperAdmin && !model.getRoleIds().contains(roleId)) continue;
dto.setId(model.getId());
dto.setName(model.getName());
dto.setUrl(model.getUrl());
dto.setIcon(model.getIcon());
dto.setOpenType(model.getLinkOpenType());
dto.setType(model.getType());
result.add(dto);
}
return result;
}
@PostMapping(value = "TeacherCopilot/save", produces = "application/json")
public void save(BoaUser authUserWithDept, @RequestBody TeacherCopilot teacherCopilot) {
UserCurrentRole userCurrentRole = userCurrentRoleService.findById(authUserWithDept.getId())
.orElseThrow(() -> new com.yunhai.platform.apistd.BizException(com.yunhai.platform.utils.exception.ErrorCode.INTERNAL_SERVER_ERROR));
teacherCopilot.setCId(authUserWithDept.getId());
teacherCopilot.setSchId(userCurrentRole.getSchId());
if (teacherCopilot.getId() == null) teacherCopilot.setCDate(new Date());
teacherCopilotService.save(teacherCopilot);
}
@PostMapping(value = "TeacherCopilot/toggleShow", produces = "application/json")
public void toggleShow(BoaUser authUserWithDept, Integer id) {
UserCurrentRole userCurrentRole = userCurrentRoleService.findById(authUserWithDept.getId())
.orElseThrow(() -> new com.yunhai.platform.apistd.BizException(com.yunhai.platform.utils.exception.ErrorCode.INTERNAL_SERVER_ERROR));
teacherCopilotService.toggleShow(id, userCurrentRole.getSchId());
}
@PostMapping(value = "TeacherCopilot/saveOrderNum", produces = "application/json")
public void saveOrderNum(BoaUser authUserWithDept, @RequestBody Map<String, Integer> params) {
Integer id = params.get("id"),
orderNum = params.get("orderNum");
teacherCopilotService.saveOrderNum(id, orderNum);
}
@PostMapping(value = "TeacherCopilot/delete", produces = "application/json")
public void delete(BoaUser authUserWithDept, Integer id) {
teacherCopilotService.delete(id);
}
}
@@ -0,0 +1,428 @@
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.client.YschBaseOpenApi;
import com.yunhai.platform.utils.enums.ClientEnum;
import com.yunhai.platform.utils.exception.ErrorCode;
import com.yunhai.platform.utils.model.BoaApp;
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.*;
import com.yunhai.userhome.enums.DesktopAppType;
import com.yunhai.userhome.enums.LightAppGroup;
import com.yunhai.userhome.enums.LinkOpenType;
import com.yunhai.userhome.service.IUserCurrentRoleService;
import com.yunhai.userhome.service.IUserSettingsService;
import com.yunhai.userhome.service.UsedAppService;
import com.yunhai.userhome.utils.EnumUtil;
import com.yunhai.userhome.utils.FileUtil;
import com.yunhai.userhome.utils.OtherUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
/**
* 用户设置控制器(对齐旧 UserHome contorller.api.UserSettingsController)。
*
* <p>待确认接口(已写入待确认清单):
* <ul>
* <li>getUserSettings 中 bschBaseOpenApi.getPcGrzxPage —— 新框架 YschBaseOpenApi 是否有此方法待确认</li>
* <li>GetSchSettingsWallpaper 依赖 SCH_CONF_URL —— 需确认环境地址</li>
* </ul>
*/
@RestController
@RequestMapping(Config.API_PATH)
public class UserSettingsController {
@Value("${FILE_PATH:./upload/}")
private String FILE_PATH;
@Value("${FILE_WEB_PATH:}")
private String FILE_WEB_PATH;
@Value("${SCH_CONF_URL:}")
private String SCH_CONF_URL;
@Autowired
private IUserSettingsService userSettingsService;
@Autowired
private IUserCurrentRoleService userCurrentRoleService;
@Autowired
private UsedAppService usedAppService;
private final RestTemplate restTemplate = new RestTemplate();
private final ObjectMapper objectMapper = new ObjectMapper();
// ==================== 壁纸 ====================
@PostMapping(value = "wallpaperUpload", produces = "application/json")
public void wallpaperUpload(BoaUser authUserWithDept, @RequestParam("file") MultipartFile file) {
String uploadUrl = this.upload(file, "wallpaper");
UserCurrentRole currentRole = userCurrentRoleService.findById(authUserWithDept.getId())
.orElseThrow(() -> new BizException(ErrorCode.INTERNAL_SERVER_ERROR));
Integer type = authUserWithDept.getType() == 1 ? 0 : OtherUtil.isAdminById(currentRole.getRoleId()) ? 1 : 2;
Wallpaper wallpaper = new Wallpaper();
wallpaper.setSchId(currentRole.getSchId());
wallpaper.setWallpaperUrl(uploadUrl);
wallpaper.setUserId(authUserWithDept.getId());
wallpaper.setType(type);
userSettingsService.saveWallpaper(wallpaper);
}
@PostMapping(value = "iconUpload", produces = "application/json")
public String iconUpload(BoaUser authUserWithDept, @RequestParam("file") MultipartFile file) {
return this.upload(file, "icon");
}
@PostMapping(value = "deleteWallById", produces = "application/json")
public void deleteWallById(BoaUser authUserWithDept, Integer id) {
userSettingsService.deleteWallById(id);
}
@PostMapping(value = "checkWallpaper", produces = "application/json")
public void checkWallpaper(BoaUser authUserWithDept, @RequestBody Map res) {
String wallpaperUrl = res.get("wallpaperUrl").toString();
userSettingsService.checkWallpaper(authUserWithDept.getId(), wallpaperUrl);
}
@GetMapping(value = "getUserWallpaperList")
public List<Map> getUserWallpaperList(BoaUser authUserWithDept, Integer schId) {
List<Map> result = new ArrayList<>();
List<Wallpaper> list = userSettingsService.findWallList(authUserWithDept.getId());
list = list.stream().sorted(Comparator.comparing(Wallpaper::getId).reversed()).collect(Collectors.toList());
list.forEach(model -> {
Map map = new HashMap();
map.put("id", model.getId());
map.put("url", FILE_WEB_PATH + model.getWallpaperUrl().replace("/upload", ""));
map.put("type", model.getType());
map.put("isEdit", model.getIsEdit());
result.add(map);
});
if (authUserWithDept.getType() != 1 && !list.stream().anyMatch(x -> x.getType() == 1)) {
List<String> schList = getSchSettingsWallpaper(schId);
for (String schWall : schList) {
Map map = new HashMap();
map.put("id", null);
map.put("type", 1);
map.put("url", schWall);
map.put("isEdit", false);
result.add(map);
}
}
return result;
}
// ==================== 用户设置 ====================
@GetMapping(value = "getUserSettings")
public UserSettings getUserSettings(BoaUser authUserWithDept) {
UserCurrentRole currentRole = userCurrentRoleService.findById(authUserWithDept.getId())
.orElseThrow(() -> new BizException(ErrorCode.INTERNAL_SERVER_ERROR));
Integer schId = currentRole.getSchId();
UserSettings model = new UserSettings();
Optional<UserSettings> optional = userSettingsService.findUserSettings(authUserWithDept.getId());
// TODO 待确认:bschBaseOpenApi.getPcGrzxPage —— 新框架 YschBaseOpenApi 是否有此方法待确认
// List<BoaApp> appPageList = bschBaseOpenApi.getPcGrzxPage(authUserWithDept.getId(), schId);
List<BoaApp> appPageList = Collections.emptyList();
if (optional.isPresent()) model = optional.get();
if (model.getWallpaperUrl() == null || model.getWallpaperUrl().isEmpty()) {
List<String> schList = getSchSettingsWallpaper(schId);
if (schList.size() > 0) model.setWallpaperUrl(schList.get(0));
}
List<Map> mapList = appPageList.stream().map(boaApp -> {
Map map = new HashMap<>();
map.put("id", boaApp.getId());
map.put("appId", boaApp.getId());
map.put("name", boaApp.getName());
map.put("url", boaApp.getWebAddr());
return map;
}).collect(Collectors.toList());
model.setWidgetAppList(mapList);
return model;
}
@GetMapping(value = "getUserDesktopAppList")
public List<Map> getUserDesktopAppList(BoaUser authUserWithDept) {
UserCurrentRole currentRole = userCurrentRoleService.findById(authUserWithDept.getId())
.orElseThrow(() -> new BizException(ErrorCode.INTERNAL_SERVER_ERROR));
Optional<UserSettings> optional = userSettingsService.findUserSettings(authUserWithDept.getId());
Integer schId = currentRole.getSchId(), userId = currentRole.getUserId();
UserSettings model = new UserSettings();
List<UserSettingsDesktopApp> desktopAppList = new ArrayList<>();
List<Map> result = new ArrayList<>();
if (optional.isPresent()) model = optional.get();
// 初始化设置为常用应用
if (model.getDesktopApps().isEmpty()) desktopAppList = getUserUsedByUserId(authUserWithDept.getId());
else desktopAppList = model.getDesktopApps();
List<BoaApp> bschAllList = new ArrayList<>();
List<LightApp> lightAllList = new ArrayList<>();
List<Integer> bschAppIds = desktopAppList.stream()
.filter(x -> x.getAppType() == DesktopAppType.Bsch)
.map(UserSettingsDesktopApp::getAppId)
.collect(Collectors.toList());
List<Integer> lightAppIds = desktopAppList.stream()
.filter(x -> x.getAppType() == DesktopAppType.Light)
.map(UserSettingsDesktopApp::getAppId)
.collect(Collectors.toList());
if (bschAppIds.size() > 0) {
List<BoaAppType> appTypeList = YschBaseOpenApi.getUserApp(authUserWithDept.getId(), ClientEnum.PC_BROWSER);
for (BoaAppType mode : appTypeList) bschAllList.addAll(mode.getApps());
}
if (lightAppIds.size() > 0) {
lightAllList = userSettingsService.findLightAppList(schId, userId);
}
desktopAppList = desktopAppList.stream()
.sorted(Comparator.comparing(UserSettingsDesktopApp::getOrderNum, Comparator.nullsLast(Integer::compareTo)))
.collect(Collectors.toList());
for (UserSettingsDesktopApp desktopApp : desktopAppList) {
Map map = new HashMap();
map.put("id", desktopApp.getId());
map.put("appId", desktopApp.getAppId());
if (desktopApp.getAppType() == DesktopAppType.Bsch) {
Optional<BoaApp> optionalBoaApp = bschAllList.stream()
.filter(boa -> desktopApp.getAppId().equals(boa.getId())).findFirst();
if (!optionalBoaApp.isPresent()) continue;
map.put("name", optionalBoaApp.get().getName());
map.put("icon", optionalBoaApp.get().getIcon());
map.put("url", optionalBoaApp.get().getWebAddr());
map.put("type", DesktopAppType.Bsch.getKey());
map.put("linkType", LinkOpenType.Open.getKey());
map.put("layout", null);
} else if (desktopApp.getAppType() == DesktopAppType.Light) {
Optional<LightApp> optionalLightApp = lightAllList.stream()
.filter(app -> desktopApp.getAppId().equals(app.getId())).findFirst();
if (!optionalLightApp.isPresent()) continue;
map.put("name", optionalLightApp.get().getName());
map.put("icon", optionalLightApp.get().getIcon());
map.put("url", optionalLightApp.get().getUrl());
map.put("type", DesktopAppType.Light.getKey());
map.put("linkType", optionalLightApp.get().getLinkOpenType());
map.put("layout", optionalLightApp.get().getLayout());
}
result.add(map);
}
return result;
}
@PostMapping(value = "saveUserWidget", produces = "application/json")
public void saveUserWidget(BoaUser authUserWithDept, @RequestBody UserSettings userSettings) {
userSettings.setUserId(authUserWithDept.getId());
userSettingsService.saveUserWidget(userSettings);
}
@PostMapping(value = "toggleWidgetShow", produces = "application/json")
public void toggleWidgetShow(BoaUser authUserWithDept, @RequestBody Map<String, Integer> params) {
Integer id = params.get("id");
userSettingsService.toggleWidgetShow(id, authUserWithDept.getId());
}
@PostMapping(value = "saveUserAppIds", produces = "application/json")
public void saveUserAppIds(BoaUser authUserWithDept, @RequestBody Map<String, String> params) {
Integer id = null;
if (params.get("id") != null) id = Integer.parseInt(params.get("id"));
String appIds = params.get("appIds");
userSettingsService.saveUserAppIds(id, authUserWithDept.getId(), appIds);
}
// ==================== 轻应用 ====================
@GetMapping(value = "getLightAppGroup")
public Object getLightAppGroup(BoaUser authUserWithDept) {
return EnumUtil.toMapList(LightAppGroup.class);
}
@GetMapping(value = "getLightAppList", produces = "application/json")
public List<LightApp> getLightAppList(BoaUser authUserWithDept) {
UserCurrentRole currentRole = userCurrentRoleService.findById(authUserWithDept.getId())
.orElseThrow(() -> new BizException(ErrorCode.INTERNAL_SERVER_ERROR));
Integer schId, userId = null;
if (authUserWithDept.getType() == 1) {
schId = 0;
} else if (currentRole.getRoleId() == 7 || currentRole.getRoleId() == 2) {
schId = currentRole.getSchId();
} else {
schId = currentRole.getSchId();
userId = currentRole.getUserId();
}
return userSettingsService.findLightAppList(schId, userId);
}
@PostMapping(value = "saveLightApp", produces = "application/json")
public void saveLightApp(BoaUser authUserWithDept, @RequestBody LightApp lightApp) {
UserCurrentRole currentRole = userCurrentRoleService.findById(authUserWithDept.getId())
.orElseThrow(() -> new BizException(ErrorCode.INTERNAL_SERVER_ERROR));
Integer schId, userId = null;
if (authUserWithDept.getType() == 1) {
schId = 0;
} else if (currentRole.getRoleId() == 7 || currentRole.getRoleId() == 2) {
schId = currentRole.getSchId();
} else {
schId = currentRole.getSchId();
userId = currentRole.getUserId();
}
lightApp.setUserId(userId);
lightApp.setSchId(schId);
lightApp.setCId(authUserWithDept.getId());
lightApp.setCDate(new Date());
userSettingsService.saveLightApp(lightApp);
}
@PostMapping(value = "deleteLightAppById", produces = "application/json")
public void deleteLightAppById(BoaUser authUserWithDept, Integer id) {
userSettingsService.deleteLightAppById(id);
}
// ==================== 桌面应用 ====================
@PostMapping(value = "saveUserDesktopAppById", produces = "application/json")
public void saveUserDesktopAppById(BoaUser authUserWithDept, @RequestBody Map<String, Integer> params) {
Integer id = params.get("id");
Integer type = params.get("type");
DesktopAppType desktopAppType = DesktopAppType.valueOf(type);
Optional<UserSettings> optional = userSettingsService.findUserSettings(authUserWithDept.getId());
if (!optional.isPresent() || optional.get().getDesktopApps().isEmpty()) {
initUserSettingsDesktopApp(authUserWithDept.getId());
optional = userSettingsService.findUserSettings(authUserWithDept.getId());
}
UserSettings userSettings = optional.get();
if (userSettings.getDesktopApps().stream().anyMatch(x -> x.getAppId().equals(id)))
throw new BizException(ErrorCode.CUSTOM, "该应用已存在于桌面,请勿重复添加!");
UserSettingsDesktopApp desktopApp = new UserSettingsDesktopApp();
desktopApp.setAppType(desktopAppType);
desktopApp.setAppId(id);
desktopApp.setUserSettingsId(userSettings.getId());
userSettingsService.saveDesktopApp(desktopApp);
}
@PostMapping(value = "deleteDesktopAppById", produces = "application/json")
public void deleteDesktopAppById(BoaUser authUserWithDept, @RequestBody Map<String, Integer> params) {
Integer id = params.get("id");
Integer appId = params.get("appId");
if (id != null) {
userSettingsService.deleteDesktopAppById(id);
} else {
Integer userId = authUserWithDept.getId();
Optional<UserSettings> optional = userSettingsService.findUserSettings(userId);
List<UserSettingsDesktopApp> desktopList = getUserUsedByUserId(userId);
desktopList = desktopList.stream().filter(x -> !x.getAppId().equals(appId)).collect(Collectors.toList());
UserSettings model;
if (!optional.isPresent()) model = userSettingsService.initUserSettings(userId);
else model = optional.get();
desktopList.forEach(x -> x.setUserSettingsId(model.getId()));
userSettingsService.saveDesktopAppList(desktopList);
}
}
@PostMapping(value = "sortUserDesktopApp", produces = "application/json")
public void sortUserDesktopApp(BoaUser authUserWithDept, @RequestBody Map<String, String> params) {
String idsStr = params.get("ids");
List<Integer> ids = Arrays.stream(idsStr.split(",")).map(s -> Integer.parseInt(s.trim())).collect(Collectors.toList());
Optional<UserSettings> optional = userSettingsService.findUserSettings(authUserWithDept.getId());
List<UserSettingsDesktopApp> desktopApps = new ArrayList<>();
if (!optional.isPresent() || optional.get().getDesktopApps().isEmpty()) {
desktopApps = initUserSettingsDesktopApp(authUserWithDept.getId());
desktopApps.forEach(x -> {
Integer i = ids.indexOf(x.getAppId());
x.setOrderNum(i);
});
} else {
desktopApps = optional.get().getDesktopApps();
desktopApps.forEach(x -> {
Integer i = ids.indexOf(x.getId());
x.setOrderNum(i);
});
}
userSettingsService.saveDesktopAppList(desktopApps);
}
// ==================== 私有方法 ====================
private String upload(@RequestParam("file") MultipartFile file, String pathName) {
File fl = new File(FILE_PATH + "/" + pathName + "/");
if (!fl.exists()) fl.mkdirs();
String fileName = FileUtil.uploadImg(file, FILE_PATH + "/" + pathName + "/");
return "/upload/" + pathName + "/" + fileName;
}
/**
* 获取学校设置的壁纸集合(对齐旧 UserHome GetSchSettingsWallpaper,fastjson → Jackson)。
*/
private List<String> getSchSettingsWallpaper(Integer schId) {
if (SCH_CONF_URL == null || SCH_CONF_URL.isEmpty()) return Collections.emptyList();
String apiPath = SCH_CONF_URL + "/oapi/getSchSetting?schId=" + schId;
List<String> result = new ArrayList<>();
try {
String resultStr = restTemplate.getForObject(apiPath, String.class);
if (resultStr == null || resultStr.isEmpty()) return result;
JsonNode root = objectMapper.readTree(resultStr);
JsonNode dataNode = root.get("data");
if (root.has("code") && "0".equals(root.get("code").asText()) && dataNode != null && !dataNode.isNull()) {
JsonNode appBgUrlNode = dataNode.get("appBackgroundUrl");
if (appBgUrlNode == null) appBgUrlNode = dataNode.get("appBgUrl");
String appBgUrlStr = appBgUrlNode != null ? appBgUrlNode.asText("") : "";
if (appBgUrlStr.isEmpty()) return result;
String[] imgUrls = appBgUrlStr.split(",");
for (String imgUrl : imgUrls) {
if (!imgUrl.contains(SCH_CONF_URL))
result.add(SCH_CONF_URL + imgUrl);
else
result.add(imgUrl);
}
}
} catch (Exception e) {
// 跨仓调用失败时返回空列表
}
return result;
}
/**
* 将某个人常用应用转化为桌面应用
*/
private List<UserSettingsDesktopApp> initUserSettingsDesktopApp(Integer userId) {
Optional<UserSettings> optional = userSettingsService.findUserSettings(userId);
List<UserSettingsDesktopApp> desktopList = getUserUsedByUserId(userId);
UserSettings model;
if (!optional.isPresent()) model = userSettingsService.initUserSettings(userId);
else model = optional.get();
desktopList.forEach(x -> x.setUserSettingsId(model.getId()));
return userSettingsService.saveDesktopAppList(desktopList);
}
/**
* 获取常用应用转化为桌面应用类型
*/
private List<UserSettingsDesktopApp> getUserUsedByUserId(Integer userId) {
UserCurrentRole currentRole = userCurrentRoleService.findById(userId)
.orElseThrow(() -> new BizException(ErrorCode.INTERNAL_SERVER_ERROR));
Optional<UsedApp> optionalUsedApp = usedAppService.findById(currentRole.getSchId(), currentRole.getUserId(), currentRole.getRoleId());
List<UserSettingsDesktopApp> desktopAppList = new ArrayList<>();
if (optionalUsedApp.isPresent() && optionalUsedApp.get().getAppIds() != null && !optionalUsedApp.get().getAppIds().isEmpty()) {
List<String> appIds = Arrays.asList(optionalUsedApp.get().getAppIds().split(","));
List<Integer> bschAppIds = appIds.stream().mapToInt(Integer::parseInt).boxed().collect(Collectors.toList());
Integer i = 0;
for (Integer appId : bschAppIds) {
UserSettingsDesktopApp desktopApp = new UserSettingsDesktopApp();
desktopApp.setAppId(appId);
desktopApp.setAppType(DesktopAppType.Bsch);
desktopApp.setOrderNum(i);
desktopAppList.add(desktopApp);
i++;
}
}
return desktopAppList;
}
}