This commit is contained in:
2025-06-27 10:23:57 +08:00
parent 15d7ef8771
commit b94549185c
774 changed files with 3543 additions and 3558 deletions

View File

@ -0,0 +1,54 @@
package com.fuyuanshen.system.controller.monitor;
import cn.dev33.satoken.annotation.SaCheckPermission;
import lombok.RequiredArgsConstructor;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.core.utils.StringUtils;
import org.redisson.spring.data.connection.RedissonConnectionFactory;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/**
* 缓存监控
*
* @author Lion Li
*/
@RequiredArgsConstructor
@RestController
@RequestMapping("/monitor/cache")
public class CacheController {
private final RedissonConnectionFactory connectionFactory;
/**
* 获取缓存监控列表
*/
@SaCheckPermission("monitor:cache:list")
@GetMapping()
public R<CacheListInfoVo> getInfo() throws Exception {
RedisConnection connection = connectionFactory.getConnection();
Properties commandStats = connection.commands().info("commandstats");
List<Map<String, String>> pieList = new ArrayList<>();
if (commandStats != null) {
commandStats.stringPropertyNames().forEach(key -> {
Map<String, String> data = new HashMap<>(2);
String property = commandStats.getProperty(key);
data.put("name", StringUtils.removeStart(key, "cmdstat_"));
data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
pieList.add(data);
});
}
return R.ok(new CacheListInfoVo(
connection.commands().info(),
connection.commands().dbSize(), pieList));
}
public record CacheListInfoVo(Properties info, Long dbSize, List<Map<String, String>> commandStats) {}
}

View File

@ -0,0 +1,89 @@
package com.fuyuanshen.system.controller.monitor;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import com.fuyuanshen.common.core.constant.CacheConstants;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.excel.utils.ExcelUtil;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.common.redis.utils.RedisUtils;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.system.domain.bo.SysLogininforBo;
import com.fuyuanshen.system.domain.vo.SysLogininforVo;
import com.fuyuanshen.system.service.ISysLogininforService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 系统访问记录
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/monitor/logininfor")
public class SysLogininforController extends BaseController {
private final ISysLogininforService logininforService;
/**
* 获取系统访问记录列表
*/
@SaCheckPermission("monitor:logininfor:list")
@GetMapping("/list")
public TableDataInfo<SysLogininforVo> list(SysLogininforBo logininfor, PageQuery pageQuery) {
return logininforService.selectPageLogininforList(logininfor, pageQuery);
}
/**
* 导出系统访问记录列表
*/
@Log(title = "登录日志", businessType = BusinessType.EXPORT)
@SaCheckPermission("monitor:logininfor:export")
@PostMapping("/export")
public void export(SysLogininforBo logininfor, HttpServletResponse response) {
List<SysLogininforVo> list = logininforService.selectLogininforList(logininfor);
ExcelUtil.exportExcel(list, "登录日志", SysLogininforVo.class, response);
}
/**
* 批量删除登录日志
* @param infoIds 日志ids
*/
@SaCheckPermission("monitor:logininfor:remove")
@Log(title = "登录日志", businessType = BusinessType.DELETE)
@DeleteMapping("/{infoIds}")
public R<Void> remove(@PathVariable Long[] infoIds) {
return toAjax(logininforService.deleteLogininforByIds(infoIds));
}
/**
* 清理系统访问记录
*/
@SaCheckPermission("monitor:logininfor:remove")
@Log(title = "登录日志", businessType = BusinessType.CLEAN)
@DeleteMapping("/clean")
public R<Void> clean() {
logininforService.cleanLogininfor();
return R.ok();
}
@SaCheckPermission("monitor:logininfor:unlock")
@Log(title = "账户解锁", businessType = BusinessType.OTHER)
@GetMapping("/unlock/{userName}")
public R<Void> unlock(@PathVariable("userName") String userName) {
String loginName = CacheConstants.PWD_ERR_CNT_KEY + userName;
if (RedisUtils.hasKey(loginName)) {
RedisUtils.deleteObject(loginName);
}
return R.ok();
}
}

View File

@ -0,0 +1,75 @@
package com.fuyuanshen.system.controller.monitor;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.excel.utils.ExcelUtil;
import com.fuyuanshen.system.domain.bo.SysOperLogBo;
import com.fuyuanshen.system.domain.vo.SysOperLogVo;
import com.fuyuanshen.system.service.ISysOperLogService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 操作日志记录
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/monitor/operlog")
public class SysOperlogController extends BaseController {
private final ISysOperLogService operLogService;
/**
* 获取操作日志记录列表
*/
@SaCheckPermission("monitor:operlog:list")
@GetMapping("/list")
public TableDataInfo<SysOperLogVo> list(SysOperLogBo operLog, PageQuery pageQuery) {
return operLogService.selectPageOperLogList(operLog, pageQuery);
}
/**
* 导出操作日志记录列表
*/
@Log(title = "操作日志", businessType = BusinessType.EXPORT)
@SaCheckPermission("monitor:operlog:export")
@PostMapping("/export")
public void export(SysOperLogBo operLog, HttpServletResponse response) {
List<SysOperLogVo> list = operLogService.selectOperLogList(operLog);
ExcelUtil.exportExcel(list, "操作日志", SysOperLogVo.class, response);
}
/**
* 批量删除操作日志记录
* @param operIds 日志ids
*/
@Log(title = "操作日志", businessType = BusinessType.DELETE)
@SaCheckPermission("monitor:operlog:remove")
@DeleteMapping("/{operIds}")
public R<Void> remove(@PathVariable Long[] operIds) {
return toAjax(operLogService.deleteOperLogByIds(operIds));
}
/**
* 清理操作日志记录
*/
@Log(title = "操作日志", businessType = BusinessType.CLEAN)
@SaCheckPermission("monitor:operlog:remove")
@DeleteMapping("/clean")
public R<Void> clean() {
operLogService.cleanOperLog();
return R.ok();
}
}

View File

@ -0,0 +1,131 @@
package com.fuyuanshen.system.controller.monitor;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import lombok.RequiredArgsConstructor;
import com.fuyuanshen.common.core.constant.CacheConstants;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.core.domain.dto.UserOnlineDTO;
import com.fuyuanshen.common.core.utils.StreamUtils;
import com.fuyuanshen.common.core.utils.StringUtils;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.common.redis.utils.RedisUtils;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.system.domain.SysUserOnline;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* 在线用户监控
*
* @author Lion Li
*/
@RequiredArgsConstructor
@RestController
@RequestMapping("/monitor/online")
public class SysUserOnlineController extends BaseController {
/**
* 获取在线用户监控列表
*
* @param ipaddr IP地址
* @param userName 用户名
*/
@SaCheckPermission("monitor:online:list")
@GetMapping("/list")
public TableDataInfo<SysUserOnline> list(String ipaddr, String userName) {
// 获取所有未过期的 token
Collection<String> keys = RedisUtils.keys(CacheConstants.ONLINE_TOKEN_KEY + "*");
List<UserOnlineDTO> userOnlineDTOList = new ArrayList<>();
for (String key : keys) {
String token = StringUtils.substringAfterLast(key, ":");
// 如果已经过期则跳过
if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < -1) {
continue;
}
userOnlineDTOList.add(RedisUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + token));
}
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) {
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
StringUtils.equals(ipaddr, userOnline.getIpaddr()) &&
StringUtils.equals(userName, userOnline.getUserName())
);
} else if (StringUtils.isNotEmpty(ipaddr)) {
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
StringUtils.equals(ipaddr, userOnline.getIpaddr())
);
} else if (StringUtils.isNotEmpty(userName)) {
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
StringUtils.equals(userName, userOnline.getUserName())
);
}
Collections.reverse(userOnlineDTOList);
userOnlineDTOList.removeAll(Collections.singleton(null));
List<SysUserOnline> userOnlineList = BeanUtil.copyToList(userOnlineDTOList, SysUserOnline.class);
return TableDataInfo.build(userOnlineList);
}
/**
* 强退用户
*
* @param tokenId token值
*/
@SaCheckPermission("monitor:online:forceLogout")
@Log(title = "在线用户", businessType = BusinessType.FORCE)
@DeleteMapping("/{tokenId}")
public R<Void> forceLogout(@PathVariable String tokenId) {
try {
StpUtil.kickoutByTokenValue(tokenId);
} catch (NotLoginException ignored) {
}
return R.ok();
}
/**
* 获取当前用户登录在线设备
*/
@GetMapping()
public TableDataInfo<SysUserOnline> getInfo() {
// 获取指定账号 id 的 token 集合
List<String> tokenIds = StpUtil.getTokenValueListByLoginId(StpUtil.getLoginIdAsString());
List<UserOnlineDTO> userOnlineDTOList = tokenIds.stream()
.filter(token -> StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) >= -1)
.map(token -> (UserOnlineDTO) RedisUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + token))
.collect(Collectors.toList());
//复制和处理 SysUserOnline 对象列表
Collections.reverse(userOnlineDTOList);
userOnlineDTOList.removeAll(Collections.singleton(null));
List<SysUserOnline> userOnlineList = BeanUtil.copyToList(userOnlineDTOList, SysUserOnline.class);
return TableDataInfo.build(userOnlineList);
}
/**
* 强退当前在线设备
*
* @param tokenId token值
*/
@Log(title = "在线设备", businessType = BusinessType.FORCE)
@DeleteMapping("/myself/{tokenId}")
public R<Void> remove(@PathVariable("tokenId") String tokenId) {
try {
// 获取指定账号 id 的 token 集合
List<String> keys = StpUtil.getTokenValueListByLoginId(StpUtil.getLoginIdAsString());
keys.stream()
.filter(key -> key.equals(tokenId))
.findFirst()
.ifPresent(key -> StpUtil.kickoutByTokenValue(tokenId));
} catch (NotLoginException ignored) {
}
return R.ok();
}
}

View File

@ -0,0 +1,115 @@
package com.fuyuanshen.system.controller.system;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.fuyuanshen.common.idempotent.annotation.RepeatSubmit;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.core.validate.AddGroup;
import com.fuyuanshen.common.core.validate.EditGroup;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.excel.utils.ExcelUtil;
import com.fuyuanshen.system.domain.vo.SysClientVo;
import com.fuyuanshen.system.domain.bo.SysClientBo;
import com.fuyuanshen.system.service.ISysClientService;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
/**
* 客户端管理
*
* @author Michelle.Chung
* @date 2023-06-18
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/client")
public class SysClientController extends BaseController {
private final ISysClientService sysClientService;
/**
* 查询客户端管理列表
*/
@SaCheckPermission("system:client:list")
@GetMapping("/list")
public TableDataInfo<SysClientVo> list(SysClientBo bo, PageQuery pageQuery) {
return sysClientService.queryPageList(bo, pageQuery);
}
/**
* 导出客户端管理列表
*/
@SaCheckPermission("system:client:export")
@Log(title = "客户端管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(SysClientBo bo, HttpServletResponse response) {
List<SysClientVo> list = sysClientService.queryList(bo);
ExcelUtil.exportExcel(list, "客户端管理", SysClientVo.class, response);
}
/**
* 获取客户端管理详细信息
*
* @param id 主键
*/
@SaCheckPermission("system:client:query")
@GetMapping("/{id}")
public R<SysClientVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(sysClientService.queryById(id));
}
/**
* 新增客户端管理
*/
@SaCheckPermission("system:client:add")
@Log(title = "客户端管理", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody SysClientBo bo) {
return toAjax(sysClientService.insertByBo(bo));
}
/**
* 修改客户端管理
*/
@SaCheckPermission("system:client:edit")
@Log(title = "客户端管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysClientBo bo) {
return toAjax(sysClientService.updateByBo(bo));
}
/**
* 状态修改
*/
@SaCheckPermission("system:client:edit")
@Log(title = "客户端管理", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public R<Void> changeStatus(@RequestBody SysClientBo bo) {
return toAjax(sysClientService.updateClientStatus(bo.getClientId(), bo.getStatus()));
}
/**
* 删除客户端管理
*
* @param ids 主键串
*/
@SaCheckPermission("system:client:remove")
@Log(title = "客户端管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(sysClientService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@ -0,0 +1,137 @@
package com.fuyuanshen.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.excel.utils.ExcelUtil;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.system.domain.bo.SysConfigBo;
import com.fuyuanshen.system.domain.vo.SysConfigVo;
import com.fuyuanshen.system.service.ISysConfigService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 参数配置 信息操作处理
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/config")
public class SysConfigController extends BaseController {
private final ISysConfigService configService;
/**
* 获取参数配置列表
*/
@SaCheckPermission("system:config:list")
@GetMapping("/list")
public TableDataInfo<SysConfigVo> list(SysConfigBo config, PageQuery pageQuery) {
return configService.selectPageConfigList(config, pageQuery);
}
/**
* 导出参数配置列表
*/
@Log(title = "参数管理", businessType = BusinessType.EXPORT)
@SaCheckPermission("system:config:export")
@PostMapping("/export")
public void export(SysConfigBo config, HttpServletResponse response) {
List<SysConfigVo> list = configService.selectConfigList(config);
ExcelUtil.exportExcel(list, "参数数据", SysConfigVo.class, response);
}
/**
* 根据参数编号获取详细信息
*
* @param configId 参数ID
*/
@SaCheckPermission("system:config:query")
@GetMapping(value = "/{configId}")
public R<SysConfigVo> getInfo(@PathVariable Long configId) {
return R.ok(configService.selectConfigById(configId));
}
/**
* 根据参数键名查询参数值
*
* @param configKey 参数Key
*/
@GetMapping(value = "/configKey/{configKey}")
public R<String> getConfigKey(@PathVariable String configKey) {
return R.ok("操作成功", configService.selectConfigByKey(configKey));
}
/**
* 新增参数配置
*/
@SaCheckPermission("system:config:add")
@Log(title = "参数管理", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysConfigBo config) {
if (!configService.checkConfigKeyUnique(config)) {
return R.fail("新增参数'" + config.getConfigName() + "'失败,参数键名已存在");
}
configService.insertConfig(config);
return R.ok();
}
/**
* 修改参数配置
*/
@SaCheckPermission("system:config:edit")
@Log(title = "参数管理", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysConfigBo config) {
if (!configService.checkConfigKeyUnique(config)) {
return R.fail("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
}
configService.updateConfig(config);
return R.ok();
}
/**
* 根据参数键名修改参数配置
*/
@SaCheckPermission("system:config:edit")
@Log(title = "参数管理", businessType = BusinessType.UPDATE)
@PutMapping("/updateByKey")
public R<Void> updateByKey(@RequestBody SysConfigBo config) {
configService.updateConfig(config);
return R.ok();
}
/**
* 删除参数配置
*
* @param configIds 参数ID串
*/
@SaCheckPermission("system:config:remove")
@Log(title = "参数管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{configIds}")
public R<Void> remove(@PathVariable Long[] configIds) {
configService.deleteConfigByIds(configIds);
return R.ok();
}
/**
* 刷新参数缓存
*/
@SaCheckPermission("system:config:remove")
@Log(title = "参数管理", businessType = BusinessType.CLEAN)
@DeleteMapping("/refreshCache")
public R<Void> refreshCache() {
configService.resetConfigCache();
return R.ok();
}
}

View File

@ -0,0 +1,140 @@
package com.fuyuanshen.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.convert.Convert;
import lombok.RequiredArgsConstructor;
import com.fuyuanshen.common.core.constant.SystemConstants;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.core.utils.StringUtils;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.system.domain.bo.SysDeptBo;
import com.fuyuanshen.system.domain.vo.SysDeptVo;
import com.fuyuanshen.system.service.ISysDeptService;
import com.fuyuanshen.system.service.ISysPostService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 部门信息
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/dept")
public class SysDeptController extends BaseController {
private final ISysDeptService deptService;
private final ISysPostService postService;
/**
* 获取部门列表
*/
@SaCheckPermission("system:dept:list")
@GetMapping("/list")
public R<List<SysDeptVo>> list(SysDeptBo dept) {
List<SysDeptVo> depts = deptService.selectDeptList(dept);
return R.ok(depts);
}
/**
* 查询部门列表(排除节点)
*
* @param deptId 部门ID
*/
@SaCheckPermission("system:dept:list")
@GetMapping("/list/exclude/{deptId}")
public R<List<SysDeptVo>> excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) {
List<SysDeptVo> depts = deptService.selectDeptList(new SysDeptBo());
depts.removeIf(d -> d.getDeptId().equals(deptId)
|| StringUtils.splitList(d.getAncestors()).contains(Convert.toStr(deptId)));
return R.ok(depts);
}
/**
* 根据部门编号获取详细信息
*
* @param deptId 部门ID
*/
@SaCheckPermission("system:dept:query")
@GetMapping(value = "/{deptId}")
public R<SysDeptVo> getInfo(@PathVariable Long deptId) {
deptService.checkDeptDataScope(deptId);
return R.ok(deptService.selectDeptById(deptId));
}
/**
* 新增部门
*/
@SaCheckPermission("system:dept:add")
@Log(title = "部门管理", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysDeptBo dept) {
if (!deptService.checkDeptNameUnique(dept)) {
return R.fail("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
}
return toAjax(deptService.insertDept(dept));
}
/**
* 修改部门
*/
@SaCheckPermission("system:dept:edit")
@Log(title = "部门管理", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysDeptBo dept) {
Long deptId = dept.getDeptId();
deptService.checkDeptDataScope(deptId);
if (!deptService.checkDeptNameUnique(dept)) {
return R.fail("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
} else if (dept.getParentId().equals(deptId)) {
return R.fail("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
} else if (StringUtils.equals(SystemConstants.DISABLE, dept.getStatus())) {
if (deptService.selectNormalChildrenDeptById(deptId) > 0) {
return R.fail("该部门包含未停用的子部门!");
} else if (deptService.checkDeptExistUser(deptId)) {
return R.fail("该部门下存在已分配用户,不能禁用!");
}
}
return toAjax(deptService.updateDept(dept));
}
/**
* 删除部门
*
* @param deptId 部门ID
*/
@SaCheckPermission("system:dept:remove")
@Log(title = "部门管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{deptId}")
public R<Void> remove(@PathVariable Long deptId) {
if (deptService.hasChildByDeptId(deptId)) {
return R.warn("存在下级部门,不允许删除");
}
if (deptService.checkDeptExistUser(deptId)) {
return R.warn("部门存在用户,不允许删除");
}
if (postService.countPostByDeptId(deptId) > 0) {
return R.warn("部门存在岗位,不允许删除");
}
deptService.checkDeptDataScope(deptId);
return toAjax(deptService.deleteDeptById(deptId));
}
/**
* 获取部门选择框列表
*
* @param deptIds 部门ID串
*/
@SaCheckPermission("system:dept:query")
@GetMapping("/optionselect")
public R<List<SysDeptVo>> optionselect(@RequestParam(required = false) Long[] deptIds) {
return R.ok(deptService.selectDeptByIds(deptIds == null ? null : List.of(deptIds)));
}
}

View File

@ -0,0 +1,123 @@
package com.fuyuanshen.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.ObjectUtil;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.excel.utils.ExcelUtil;
import com.fuyuanshen.system.domain.bo.SysDictDataBo;
import com.fuyuanshen.system.domain.vo.SysDictDataVo;
import com.fuyuanshen.system.service.ISysDictDataService;
import com.fuyuanshen.system.service.ISysDictTypeService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import jakarta.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
* 数据字典信息
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/dict/data")
public class SysDictDataController extends BaseController {
private final ISysDictDataService dictDataService;
private final ISysDictTypeService dictTypeService;
/**
* 查询字典数据列表
*/
@SaCheckPermission("system:dict:list")
@GetMapping("/list")
public TableDataInfo<SysDictDataVo> list(SysDictDataBo dictData, PageQuery pageQuery) {
return dictDataService.selectPageDictDataList(dictData, pageQuery);
}
/**
* 导出字典数据列表
*/
@Log(title = "字典数据", businessType = BusinessType.EXPORT)
@SaCheckPermission("system:dict:export")
@PostMapping("/export")
public void export(SysDictDataBo dictData, HttpServletResponse response) {
List<SysDictDataVo> list = dictDataService.selectDictDataList(dictData);
ExcelUtil.exportExcel(list, "字典数据", SysDictDataVo.class, response);
}
/**
* 查询字典数据详细
*
* @param dictCode 字典code
*/
@SaCheckPermission("system:dict:query")
@GetMapping(value = "/{dictCode}")
public R<SysDictDataVo> getInfo(@PathVariable Long dictCode) {
return R.ok(dictDataService.selectDictDataById(dictCode));
}
/**
* 根据字典类型查询字典数据信息
*
* @param dictType 字典类型
*/
@GetMapping(value = "/type/{dictType}")
public R<List<SysDictDataVo>> dictType(@PathVariable String dictType) {
List<SysDictDataVo> data = dictTypeService.selectDictDataByType(dictType);
if (ObjectUtil.isNull(data)) {
data = new ArrayList<>();
}
return R.ok(data);
}
/**
* 新增字典类型
*/
@SaCheckPermission("system:dict:add")
@Log(title = "字典数据", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysDictDataBo dict) {
if (!dictDataService.checkDictDataUnique(dict)) {
return R.fail("新增字典数据'" + dict.getDictValue() + "'失败,字典键值已存在");
}
dictDataService.insertDictData(dict);
return R.ok();
}
/**
* 修改保存字典类型
*/
@SaCheckPermission("system:dict:edit")
@Log(title = "字典数据", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysDictDataBo dict) {
if (!dictDataService.checkDictDataUnique(dict)) {
return R.fail("修改字典数据'" + dict.getDictValue() + "'失败,字典键值已存在");
}
dictDataService.updateDictData(dict);
return R.ok();
}
/**
* 删除字典类型
*
* @param dictCodes 字典code串
*/
@SaCheckPermission("system:dict:remove")
@Log(title = "字典类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{dictCodes}")
public R<Void> remove(@PathVariable Long[] dictCodes) {
dictDataService.deleteDictDataByIds(dictCodes);
return R.ok();
}
}

View File

@ -0,0 +1,125 @@
package com.fuyuanshen.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.excel.utils.ExcelUtil;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.system.domain.bo.SysDictTypeBo;
import com.fuyuanshen.system.domain.vo.SysDictTypeVo;
import com.fuyuanshen.system.service.ISysDictTypeService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 数据字典信息
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/dict/type")
public class SysDictTypeController extends BaseController {
private final ISysDictTypeService dictTypeService;
/**
* 查询字典类型列表
*/
@SaCheckPermission("system:dict:list")
@GetMapping("/list")
public TableDataInfo<SysDictTypeVo> list(SysDictTypeBo dictType, PageQuery pageQuery) {
return dictTypeService.selectPageDictTypeList(dictType, pageQuery);
}
/**
* 导出字典类型列表
*/
@Log(title = "字典类型", businessType = BusinessType.EXPORT)
@SaCheckPermission("system:dict:export")
@PostMapping("/export")
public void export(SysDictTypeBo dictType, HttpServletResponse response) {
List<SysDictTypeVo> list = dictTypeService.selectDictTypeList(dictType);
ExcelUtil.exportExcel(list, "字典类型", SysDictTypeVo.class, response);
}
/**
* 查询字典类型详细
*
* @param dictId 字典ID
*/
@SaCheckPermission("system:dict:query")
@GetMapping(value = "/{dictId}")
public R<SysDictTypeVo> getInfo(@PathVariable Long dictId) {
return R.ok(dictTypeService.selectDictTypeById(dictId));
}
/**
* 新增字典类型
*/
@SaCheckPermission("system:dict:add")
@Log(title = "字典类型", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysDictTypeBo dict) {
if (!dictTypeService.checkDictTypeUnique(dict)) {
return R.fail("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dictTypeService.insertDictType(dict);
return R.ok();
}
/**
* 修改字典类型
*/
@SaCheckPermission("system:dict:edit")
@Log(title = "字典类型", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysDictTypeBo dict) {
if (!dictTypeService.checkDictTypeUnique(dict)) {
return R.fail("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dictTypeService.updateDictType(dict);
return R.ok();
}
/**
* 删除字典类型
*
* @param dictIds 字典ID串
*/
@SaCheckPermission("system:dict:remove")
@Log(title = "字典类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{dictIds}")
public R<Void> remove(@PathVariable Long[] dictIds) {
dictTypeService.deleteDictTypeByIds(dictIds);
return R.ok();
}
/**
* 刷新字典缓存
*/
@SaCheckPermission("system:dict:remove")
@Log(title = "字典类型", businessType = BusinessType.CLEAN)
@DeleteMapping("/refreshCache")
public R<Void> refreshCache() {
dictTypeService.resetDictCache();
return R.ok();
}
/**
* 获取字典选择框列表
*/
@GetMapping("/optionselect")
public R<List<SysDictTypeVo>> optionselect() {
List<SysDictTypeVo> dictTypes = dictTypeService.selectDictTypeAll();
return R.ok(dictTypes);
}
}

View File

@ -0,0 +1,194 @@
package com.fuyuanshen.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.lang.tree.Tree;
import lombok.RequiredArgsConstructor;
import com.fuyuanshen.common.core.constant.SystemConstants;
import com.fuyuanshen.common.core.constant.TenantConstants;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.core.utils.StringUtils;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.satoken.utils.LoginHelper;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.system.domain.SysMenu;
import com.fuyuanshen.system.domain.bo.SysMenuBo;
import com.fuyuanshen.system.domain.vo.RouterVo;
import com.fuyuanshen.system.domain.vo.SysMenuVo;
import com.fuyuanshen.system.service.ISysMenuService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 菜单信息
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/menu")
public class SysMenuController extends BaseController {
private final ISysMenuService menuService;
/**
* 获取路由信息
*
* @return 路由信息
*/
@GetMapping("/getRouters")
public R<List<RouterVo>> getRouters() {
List<SysMenu> menus = menuService.selectMenuTreeByUserId(LoginHelper.getUserId());
return R.ok(menuService.buildMenus(menus));
}
/**
* 获取菜单列表
*/
@SaCheckRole(value = {
TenantConstants.SUPER_ADMIN_ROLE_KEY,
TenantConstants.TENANT_ADMIN_ROLE_KEY
}, mode = SaMode.OR)
@SaCheckPermission("system:menu:list")
@GetMapping("/list")
public R<List<SysMenuVo>> list(SysMenuBo menu) {
List<SysMenuVo> menus = menuService.selectMenuList(menu, LoginHelper.getUserId());
return R.ok(menus);
}
/**
* 根据菜单编号获取详细信息
*
* @param menuId 菜单ID
*/
@SaCheckRole(value = {
TenantConstants.SUPER_ADMIN_ROLE_KEY,
TenantConstants.TENANT_ADMIN_ROLE_KEY
}, mode = SaMode.OR)
@SaCheckPermission("system:menu:query")
@GetMapping(value = "/{menuId}")
public R<SysMenuVo> getInfo(@PathVariable Long menuId) {
return R.ok(menuService.selectMenuById(menuId));
}
/**
* 获取菜单下拉树列表
*/
@SaCheckPermission("system:menu:query")
@GetMapping("/treeselect")
public R<List<Tree<Long>>> treeselect(SysMenuBo menu) {
List<SysMenuVo> menus = menuService.selectMenuList(menu, LoginHelper.getUserId());
return R.ok(menuService.buildMenuTreeSelect(menus));
}
/**
* 加载对应角色菜单列表树
*
* @param roleId 角色ID
*/
@SaCheckPermission("system:menu:query")
@GetMapping(value = "/roleMenuTreeselect/{roleId}")
public R<MenuTreeSelectVo> roleMenuTreeselect(@PathVariable("roleId") Long roleId) {
List<SysMenuVo> menus = menuService.selectMenuList(LoginHelper.getUserId());
MenuTreeSelectVo selectVo = new MenuTreeSelectVo(
menuService.selectMenuListByRoleId(roleId),
menuService.buildMenuTreeSelect(menus));
return R.ok(selectVo);
}
/**
* 加载对应租户套餐菜单列表树
*
* @param packageId 租户套餐ID
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:menu:query")
@GetMapping(value = "/tenantPackageMenuTreeselect/{packageId}")
public R<MenuTreeSelectVo> tenantPackageMenuTreeselect(@PathVariable("packageId") Long packageId) {
List<SysMenuVo> menus = menuService.selectMenuList(LoginHelper.getUserId());
MenuTreeSelectVo selectVo = new MenuTreeSelectVo(
menuService.selectMenuListByPackageId(packageId),
menuService.buildMenuTreeSelect(menus));
return R.ok(selectVo);
}
/**
* 新增菜单
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:menu:add")
@Log(title = "菜单管理", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysMenuBo menu) {
if (!menuService.checkMenuNameUnique(menu)) {
return R.fail("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
} else if (SystemConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
return R.fail("新增菜单'" + menu.getMenuName() + "'失败地址必须以http(s)://开头");
}
return toAjax(menuService.insertMenu(menu));
}
/**
* 修改菜单
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:menu:edit")
@Log(title = "菜单管理", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysMenuBo menu) {
if (!menuService.checkMenuNameUnique(menu)) {
return R.fail("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
} else if (SystemConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
return R.fail("修改菜单'" + menu.getMenuName() + "'失败地址必须以http(s)://开头");
} else if (menu.getMenuId().equals(menu.getParentId())) {
return R.fail("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
}
return toAjax(menuService.updateMenu(menu));
}
/**
* 删除菜单
*
* @param menuId 菜单ID
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:menu:remove")
@Log(title = "菜单管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{menuId}")
public R<Void> remove(@PathVariable("menuId") Long menuId) {
if (menuService.hasChildByMenuId(menuId)) {
return R.warn("存在子菜单,不允许删除");
}
if (menuService.checkMenuExistRole(menuId)) {
return R.warn("菜单已分配,不允许删除");
}
return toAjax(menuService.deleteMenuById(menuId));
}
public record MenuTreeSelectVo(List<Long> checkedKeys, List<Tree<Long>> menus) {
}
/**
* 批量级联删除菜单
*
* @param menuIds 菜单ID串
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:menu:remove")
@Log(title = "菜单管理", businessType = BusinessType.DELETE)
@DeleteMapping("/cascade/{menuIds}")
public R<Void> remove(@PathVariable("menuIds") Long[] menuIds) {
List<Long> menuIdList = List.of(menuIds);
if (menuService.hasChildByMenuId(menuIdList)) {
return R.warn("存在子菜单,不允许删除");
}
menuService.deleteMenuById(menuIdList);
return R.ok();
}
}

View File

@ -0,0 +1,90 @@
package com.fuyuanshen.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import lombok.RequiredArgsConstructor;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.core.service.DictService;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.common.sse.utils.SseMessageUtils;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.system.domain.bo.SysNoticeBo;
import com.fuyuanshen.system.domain.vo.SysNoticeVo;
import com.fuyuanshen.system.service.ISysNoticeService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* 公告 信息操作处理
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/notice")
public class SysNoticeController extends BaseController {
private final ISysNoticeService noticeService;
private final DictService dictService;
/**
* 获取通知公告列表
*/
@SaCheckPermission("system:notice:list")
@GetMapping("/list")
public TableDataInfo<SysNoticeVo> list(SysNoticeBo notice, PageQuery pageQuery) {
return noticeService.selectPageNoticeList(notice, pageQuery);
}
/**
* 根据通知公告编号获取详细信息
*
* @param noticeId 公告ID
*/
@SaCheckPermission("system:notice:query")
@GetMapping(value = "/{noticeId}")
public R<SysNoticeVo> getInfo(@PathVariable Long noticeId) {
return R.ok(noticeService.selectNoticeById(noticeId));
}
/**
* 新增通知公告
*/
@SaCheckPermission("system:notice:add")
@Log(title = "通知公告", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysNoticeBo notice) {
int rows = noticeService.insertNotice(notice);
if (rows <= 0) {
return R.fail();
}
String type = dictService.getDictLabel("sys_notice_type", notice.getNoticeType());
SseMessageUtils.publishAll("[" + type + "] " + notice.getNoticeTitle());
return R.ok();
}
/**
* 修改通知公告
*/
@SaCheckPermission("system:notice:edit")
@Log(title = "通知公告", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysNoticeBo notice) {
return toAjax(noticeService.updateNotice(notice));
}
/**
* 删除通知公告
*
* @param noticeIds 公告ID串
*/
@SaCheckPermission("system:notice:remove")
@Log(title = "通知公告", businessType = BusinessType.DELETE)
@DeleteMapping("/{noticeIds}")
public R<Void> remove(@PathVariable Long[] noticeIds) {
return toAjax(noticeService.deleteNoticeByIds(noticeIds));
}
}

View File

@ -0,0 +1,105 @@
package com.fuyuanshen.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.core.validate.AddGroup;
import com.fuyuanshen.common.core.validate.EditGroup;
import com.fuyuanshen.common.core.validate.QueryGroup;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.common.idempotent.annotation.RepeatSubmit;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.system.domain.bo.SysOssConfigBo;
import com.fuyuanshen.system.domain.vo.SysOssConfigVo;
import com.fuyuanshen.system.service.ISysOssConfigService;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 对象存储配置
*
* @author Lion Li
* @author 孤舟烟雨
* @date 2021-08-13
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/resource/oss/config")
public class SysOssConfigController extends BaseController {
private final ISysOssConfigService ossConfigService;
/**
* 查询对象存储配置列表
*/
@SaCheckPermission("system:ossConfig:list")
@GetMapping("/list")
public TableDataInfo<SysOssConfigVo> list(@Validated(QueryGroup.class) SysOssConfigBo bo, PageQuery pageQuery) {
return ossConfigService.queryPageList(bo, pageQuery);
}
/**
* 获取对象存储配置详细信息
*
* @param ossConfigId OSS配置ID
*/
@SaCheckPermission("system:ossConfig:list")
@GetMapping("/{ossConfigId}")
public R<SysOssConfigVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long ossConfigId) {
return R.ok(ossConfigService.queryById(ossConfigId));
}
/**
* 新增对象存储配置
*/
@SaCheckPermission("system:ossConfig:add")
@Log(title = "对象存储配置", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody SysOssConfigBo bo) {
return toAjax(ossConfigService.insertByBo(bo));
}
/**
* 修改对象存储配置
*/
@SaCheckPermission("system:ossConfig:edit")
@Log(title = "对象存储配置", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysOssConfigBo bo) {
return toAjax(ossConfigService.updateByBo(bo));
}
/**
* 删除对象存储配置
*
* @param ossConfigIds OSS配置ID串
*/
@SaCheckPermission("system:ossConfig:remove")
@Log(title = "对象存储配置", businessType = BusinessType.DELETE)
@DeleteMapping("/{ossConfigIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ossConfigIds) {
return toAjax(ossConfigService.deleteWithValidByIds(List.of(ossConfigIds), true));
}
/**
* 状态修改
*/
@SaCheckPermission("system:ossConfig:edit")
@Log(title = "对象存储状态修改", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public R<Void> changeStatus(@RequestBody SysOssConfigBo bo) {
return toAjax(ossConfigService.updateOssConfigStatus(bo));
}
}

View File

@ -0,0 +1,108 @@
package com.fuyuanshen.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.ObjectUtil;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.core.validate.QueryGroup;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.system.domain.bo.SysOssBo;
import com.fuyuanshen.system.domain.vo.SysOssUploadVo;
import com.fuyuanshen.system.domain.vo.SysOssVo;
import com.fuyuanshen.system.service.ISysOssService;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
/**
* 文件上传 控制层
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/resource/oss")
public class SysOssController extends BaseController {
private final ISysOssService ossService;
/**
* 查询OSS对象存储列表
*/
@SaCheckPermission("system:oss:list")
@GetMapping("/list")
public TableDataInfo<SysOssVo> list(@Validated(QueryGroup.class) SysOssBo bo, PageQuery pageQuery) {
return ossService.queryPageList(bo, pageQuery);
}
/**
* 查询OSS对象基于id串
*
* @param ossIds OSS对象ID串
*/
@SaCheckPermission("system:oss:query")
@GetMapping("/listByIds/{ossIds}")
public R<List<SysOssVo>> listByIds(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ossIds) {
List<SysOssVo> list = ossService.listByIds(Arrays.asList(ossIds));
return R.ok(list);
}
/**
* 上传OSS对象存储
*
* @param file 文件
*/
@SaCheckPermission("system:oss:upload")
@Log(title = "OSS对象存储", businessType = BusinessType.INSERT)
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<SysOssUploadVo> upload(@RequestPart("file") MultipartFile file) {
if (ObjectUtil.isNull(file)) {
return R.fail("上传文件不能为空");
}
SysOssVo oss = ossService.upload(file);
SysOssUploadVo uploadVo = new SysOssUploadVo();
uploadVo.setUrl(oss.getUrl());
uploadVo.setFileName(oss.getOriginalName());
uploadVo.setOssId(oss.getOssId().toString());
return R.ok(uploadVo);
}
/**
* 下载OSS对象
*
* @param ossId OSS对象ID
*/
@SaCheckPermission("system:oss:download")
@GetMapping("/download/{ossId}")
public void download(@PathVariable Long ossId, HttpServletResponse response) throws IOException {
ossService.download(ossId, response);
}
/**
* 删除OSS对象存储
*
* @param ossIds OSS对象ID串
*/
@SaCheckPermission("system:oss:remove")
@Log(title = "OSS对象存储", businessType = BusinessType.DELETE)
@DeleteMapping("/{ossIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ossIds) {
return toAjax(ossService.deleteWithValidByIds(List.of(ossIds), true));
}
}

View File

@ -0,0 +1,133 @@
package com.fuyuanshen.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.ObjectUtil;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import com.fuyuanshen.common.core.constant.SystemConstants;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.excel.utils.ExcelUtil;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.system.domain.bo.SysPostBo;
import com.fuyuanshen.system.domain.vo.SysPostVo;
import com.fuyuanshen.system.service.ISysPostService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
* 岗位信息操作处理
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/post")
public class SysPostController extends BaseController {
private final ISysPostService postService;
/**
* 获取岗位列表
*/
@SaCheckPermission("system:post:list")
@GetMapping("/list")
public TableDataInfo<SysPostVo> list(SysPostBo post, PageQuery pageQuery) {
return postService.selectPagePostList(post, pageQuery);
}
/**
* 导出岗位列表
*/
@Log(title = "岗位管理", businessType = BusinessType.EXPORT)
@SaCheckPermission("system:post:export")
@PostMapping("/export")
public void export(SysPostBo post, HttpServletResponse response) {
List<SysPostVo> list = postService.selectPostList(post);
ExcelUtil.exportExcel(list, "岗位数据", SysPostVo.class, response);
}
/**
* 根据岗位编号获取详细信息
*
* @param postId 岗位ID
*/
@SaCheckPermission("system:post:query")
@GetMapping(value = "/{postId}")
public R<SysPostVo> getInfo(@PathVariable Long postId) {
return R.ok(postService.selectPostById(postId));
}
/**
* 新增岗位
*/
@SaCheckPermission("system:post:add")
@Log(title = "岗位管理", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysPostBo post) {
if (!postService.checkPostNameUnique(post)) {
return R.fail("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在");
} else if (!postService.checkPostCodeUnique(post)) {
return R.fail("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在");
}
return toAjax(postService.insertPost(post));
}
/**
* 修改岗位
*/
@SaCheckPermission("system:post:edit")
@Log(title = "岗位管理", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysPostBo post) {
if (!postService.checkPostNameUnique(post)) {
return R.fail("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
} else if (!postService.checkPostCodeUnique(post)) {
return R.fail("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
} else if (SystemConstants.DISABLE.equals(post.getStatus())
&& postService.countUserPostById(post.getPostId()) > 0) {
return R.fail("该岗位下存在已分配用户,不能禁用!");
}
return toAjax(postService.updatePost(post));
}
/**
* 删除岗位
*
* @param postIds 岗位ID串
*/
@SaCheckPermission("system:post:remove")
@Log(title = "岗位管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{postIds}")
public R<Void> remove(@PathVariable Long[] postIds) {
return toAjax(postService.deletePostByIds(postIds));
}
/**
* 获取岗位选择框列表
*
* @param postIds 岗位ID串
* @param deptId 部门id
*/
@SaCheckPermission("system:post:query")
@GetMapping("/optionselect")
public R<List<SysPostVo>> optionselect(@RequestParam(required = false) Long[] postIds, @RequestParam(required = false) Long deptId) {
List<SysPostVo> list = new ArrayList<>();
if (ObjectUtil.isNotNull(deptId)) {
SysPostBo post = new SysPostBo();
post.setDeptId(deptId);
list = postService.selectPostList(post);
} else if (postIds != null) {
list = postService.selectPostByIds(List.of(postIds));
}
return R.ok(list);
}
}

View File

@ -0,0 +1,133 @@
package com.fuyuanshen.system.controller.system;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.crypto.digest.BCrypt;
import lombok.RequiredArgsConstructor;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.core.utils.StringUtils;
import com.fuyuanshen.common.core.utils.file.MimeTypeUtils;
import com.fuyuanshen.common.encrypt.annotation.ApiEncrypt;
import com.fuyuanshen.common.idempotent.annotation.RepeatSubmit;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.mybatis.helper.DataPermissionHelper;
import com.fuyuanshen.common.satoken.utils.LoginHelper;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.system.domain.bo.SysUserBo;
import com.fuyuanshen.system.domain.bo.SysUserPasswordBo;
import com.fuyuanshen.system.domain.bo.SysUserProfileBo;
import com.fuyuanshen.system.domain.vo.SysOssVo;
import com.fuyuanshen.system.domain.vo.SysUserVo;
import com.fuyuanshen.system.service.ISysOssService;
import com.fuyuanshen.system.service.ISysUserService;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.Arrays;
/**
* 个人信息 业务处理
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/user/profile")
public class SysProfileController extends BaseController {
private final ISysUserService userService;
private final ISysOssService ossService;
/**
* 个人信息
*/
@GetMapping
public R<ProfileVo> profile() {
SysUserVo user = userService.selectUserById(LoginHelper.getUserId());
String roleGroup = userService.selectUserRoleGroup(user.getUserId());
String postGroup = userService.selectUserPostGroup(user.getUserId());
ProfileVo profileVo = new ProfileVo(user, roleGroup, postGroup);
return R.ok(profileVo);
}
/**
* 修改用户信息
*/
@RepeatSubmit
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> updateProfile(@Validated @RequestBody SysUserProfileBo profile) {
SysUserBo user = BeanUtil.toBean(profile, SysUserBo.class);
user.setUserId(LoginHelper.getUserId());
String username = LoginHelper.getUsername();
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
return R.fail("修改用户'" + username + "'失败,手机号码已存在");
}
if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
return R.fail("修改用户'" + username + "'失败,邮箱账号已存在");
}
int rows = DataPermissionHelper.ignore(() -> userService.updateUserProfile(user));
if (rows > 0) {
return R.ok();
}
return R.fail("修改个人信息异常,请联系管理员");
}
/**
* 重置密码
*
* @param bo 新旧密码
*/
@RepeatSubmit
@ApiEncrypt
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping("/updatePwd")
public R<Void> updatePwd(@Validated @RequestBody SysUserPasswordBo bo) {
SysUserVo user = userService.selectUserById(LoginHelper.getUserId());
String password = user.getPassword();
if (!BCrypt.checkpw(bo.getOldPassword(), password)) {
return R.fail("修改密码失败,旧密码错误");
}
if (BCrypt.checkpw(bo.getNewPassword(), password)) {
return R.fail("新密码不能与旧密码相同");
}
int rows = DataPermissionHelper.ignore(() -> userService.resetUserPwd(user.getUserId(), BCrypt.hashpw(bo.getNewPassword())));
if (rows > 0) {
return R.ok();
}
return R.fail("修改密码异常,请联系管理员");
}
/**
* 头像上传
*
* @param avatarfile 用户头像
*/
@RepeatSubmit
@Log(title = "用户头像", businessType = BusinessType.UPDATE)
@PostMapping(value = "/avatar", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<AvatarVo> avatar(@RequestPart("avatarfile") MultipartFile avatarfile) {
if (!avatarfile.isEmpty()) {
String extension = FileUtil.extName(avatarfile.getOriginalFilename());
if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) {
return R.fail("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "格式");
}
SysOssVo oss = ossService.upload(avatarfile);
String avatar = oss.getUrl();
boolean updateSuccess = DataPermissionHelper.ignore(() -> userService.updateUserAvatar(LoginHelper.getUserId(), oss.getOssId()));
if (updateSuccess) {
return R.ok(new AvatarVo(avatar));
}
}
return R.fail("上传图片异常,请联系管理员");
}
public record AvatarVo(String imgUrl) {}
public record ProfileVo(SysUserVo user, String roleGroup, String postGroup) {}
}

View File

@ -0,0 +1,232 @@
package com.fuyuanshen.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.lang.tree.Tree;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.excel.utils.ExcelUtil;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.system.domain.SysUserRole;
import com.fuyuanshen.system.domain.bo.SysDeptBo;
import com.fuyuanshen.system.domain.bo.SysRoleBo;
import com.fuyuanshen.system.domain.bo.SysUserBo;
import com.fuyuanshen.system.domain.vo.SysRoleVo;
import com.fuyuanshen.system.domain.vo.SysUserVo;
import com.fuyuanshen.system.service.ISysDeptService;
import com.fuyuanshen.system.service.ISysRoleService;
import com.fuyuanshen.system.service.ISysUserService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 角色信息
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/role")
public class SysRoleController extends BaseController {
private final ISysRoleService roleService;
private final ISysUserService userService;
private final ISysDeptService deptService;
/**
* 获取角色信息列表
*/
@SaCheckPermission("system:role:list")
@GetMapping("/list")
public TableDataInfo<SysRoleVo> list(SysRoleBo role, PageQuery pageQuery) {
return roleService.selectPageRoleList(role, pageQuery);
}
/**
* 导出角色信息列表
*/
@Log(title = "角色管理", businessType = BusinessType.EXPORT)
@SaCheckPermission("system:role:export")
@PostMapping("/export")
public void export(SysRoleBo role, HttpServletResponse response) {
List<SysRoleVo> list = roleService.selectRoleList(role);
ExcelUtil.exportExcel(list, "角色数据", SysRoleVo.class, response);
}
/**
* 根据角色编号获取详细信息
*
* @param roleId 角色ID
*/
@SaCheckPermission("system:role:query")
@GetMapping(value = "/{roleId}")
public R<SysRoleVo> getInfo(@PathVariable Long roleId) {
roleService.checkRoleDataScope(roleId);
return R.ok(roleService.selectRoleById(roleId));
}
/**
* 新增角色
*/
@SaCheckPermission("system:role:add")
@Log(title = "角色管理", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysRoleBo role) {
roleService.checkRoleAllowed(role);
if (!roleService.checkRoleNameUnique(role)) {
return R.fail("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
} else if (!roleService.checkRoleKeyUnique(role)) {
return R.fail("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
return toAjax(roleService.insertRole(role));
}
/**
* 修改保存角色
*/
@SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysRoleBo role) {
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
if (!roleService.checkRoleNameUnique(role)) {
return R.fail("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
} else if (!roleService.checkRoleKeyUnique(role)) {
return R.fail("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
if (roleService.updateRole(role) > 0) {
roleService.cleanOnlineUserByRole(role.getRoleId());
return R.ok();
}
return R.fail("修改角色'" + role.getRoleName() + "'失败,请联系管理员");
}
/**
* 修改保存数据权限
*/
@SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PutMapping("/dataScope")
public R<Void> dataScope(@RequestBody SysRoleBo role) {
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
return toAjax(roleService.authDataScope(role));
}
/**
* 状态修改
*/
@SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public R<Void> changeStatus(@RequestBody SysRoleBo role) {
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
return toAjax(roleService.updateRoleStatus(role.getRoleId(), role.getStatus()));
}
/**
* 删除角色
*
* @param roleIds 角色ID串
*/
@SaCheckPermission("system:role:remove")
@Log(title = "角色管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{roleIds}")
public R<Void> remove(@PathVariable Long[] roleIds) {
return toAjax(roleService.deleteRoleByIds(roleIds));
}
/**
* 获取角色选择框列表
*
* @param roleIds 角色ID串
*/
@SaCheckPermission("system:role:query")
@GetMapping("/optionselect")
public R<List<SysRoleVo>> optionselect(@RequestParam(required = false) Long[] roleIds) {
return R.ok(roleService.selectRoleByIds(roleIds == null ? null : List.of(roleIds)));
}
/**
* 查询已分配用户角色列表
*/
@SaCheckPermission("system:role:list")
@GetMapping("/authUser/allocatedList")
public TableDataInfo<SysUserVo> allocatedList(SysUserBo user, PageQuery pageQuery) {
return userService.selectAllocatedList(user, pageQuery);
}
/**
* 查询未分配用户角色列表
*/
@SaCheckPermission("system:role:list")
@GetMapping("/authUser/unallocatedList")
public TableDataInfo<SysUserVo> unallocatedList(SysUserBo user, PageQuery pageQuery) {
return userService.selectUnallocatedList(user, pageQuery);
}
/**
* 取消授权用户
*/
@SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PutMapping("/authUser/cancel")
public R<Void> cancelAuthUser(@RequestBody SysUserRole userRole) {
return toAjax(roleService.deleteAuthUser(userRole));
}
/**
* 批量取消授权用户
*
* @param roleId 角色ID
* @param userIds 用户ID串
*/
@SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PutMapping("/authUser/cancelAll")
public R<Void> cancelAuthUserAll(Long roleId, Long[] userIds) {
return toAjax(roleService.deleteAuthUsers(roleId, userIds));
}
/**
* 批量选择用户授权
*
* @param roleId 角色ID
* @param userIds 用户ID串
*/
@SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PutMapping("/authUser/selectAll")
public R<Void> selectAuthUserAll(Long roleId, Long[] userIds) {
roleService.checkRoleDataScope(roleId);
return toAjax(roleService.insertAuthUsers(roleId, userIds));
}
/**
* 获取对应角色部门树列表
*
* @param roleId 角色ID
*/
@SaCheckPermission("system:role:list")
@GetMapping(value = "/deptTree/{roleId}")
public R<DeptTreeSelectVo> roleDeptTreeselect(@PathVariable("roleId") Long roleId) {
DeptTreeSelectVo selectVo = new DeptTreeSelectVo(
deptService.selectDeptListByRoleId(roleId),
deptService.selectDeptTreeList(new SysDeptBo()));
return R.ok(selectVo);
}
public record DeptTreeSelectVo(List<Long> checkedKeys, List<Tree<Long>> depts) {}
}

View File

@ -0,0 +1,38 @@
package com.fuyuanshen.system.controller.system;
import lombok.RequiredArgsConstructor;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.satoken.utils.LoginHelper;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.system.domain.vo.SysSocialVo;
import com.fuyuanshen.system.service.ISysSocialService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 社会化关系
*
* @author thiszhc
* @date 2023-06-16
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/social")
public class SysSocialController extends BaseController {
private final ISysSocialService socialUserService;
/**
* 查询社会化关系列表
*/
@GetMapping("/list")
public R<List<SysSocialVo>> list() {
return R.ok(socialUserService.queryListByUserId(LoginHelper.getUserId()));
}
}

View File

@ -0,0 +1,193 @@
package com.fuyuanshen.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import com.baomidou.lock.annotation.Lock4j;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import com.fuyuanshen.common.core.constant.TenantConstants;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.core.validate.AddGroup;
import com.fuyuanshen.common.core.validate.EditGroup;
import com.fuyuanshen.common.encrypt.annotation.ApiEncrypt;
import com.fuyuanshen.common.excel.utils.ExcelUtil;
import com.fuyuanshen.common.idempotent.annotation.RepeatSubmit;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.common.tenant.helper.TenantHelper;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.system.domain.bo.SysTenantBo;
import com.fuyuanshen.system.domain.vo.SysTenantVo;
import com.fuyuanshen.system.service.ISysTenantService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 租户管理
*
* @author Michelle.Chung
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/tenant")
@ConditionalOnProperty(value = "tenant.enable", havingValue = "true")
public class SysTenantController extends BaseController {
private final ISysTenantService tenantService;
/**
* 查询租户列表
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenant:list")
@GetMapping("/list")
public TableDataInfo<SysTenantVo> list(SysTenantBo bo, PageQuery pageQuery) {
return tenantService.queryPageList(bo, pageQuery);
}
/**
* 导出租户列表
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenant:export")
@Log(title = "租户管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(SysTenantBo bo, HttpServletResponse response) {
List<SysTenantVo> list = tenantService.queryList(bo);
ExcelUtil.exportExcel(list, "租户", SysTenantVo.class, response);
}
/**
* 获取租户详细信息
*
* @param id 主键
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenant:query")
@GetMapping("/{id}")
public R<SysTenantVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(tenantService.queryById(id));
}
/**
* 新增租户
*/
@ApiEncrypt
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenant:add")
@Log(title = "租户管理", businessType = BusinessType.INSERT)
@Lock4j
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody SysTenantBo bo) {
if (!tenantService.checkCompanyNameUnique(bo)) {
return R.fail("新增租户'" + bo.getCompanyName() + "'失败,企业名称已存在");
}
return toAjax(TenantHelper.ignore(() -> tenantService.insertByBo(bo)));
}
/**
* 修改租户
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenant:edit")
@Log(title = "租户管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysTenantBo bo) {
tenantService.checkTenantAllowed(bo.getTenantId());
if (!tenantService.checkCompanyNameUnique(bo)) {
return R.fail("修改租户'" + bo.getCompanyName() + "'失败,公司名称已存在");
}
return toAjax(tenantService.updateByBo(bo));
}
/**
* 状态修改
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenant:edit")
@Log(title = "租户管理", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public R<Void> changeStatus(@RequestBody SysTenantBo bo) {
tenantService.checkTenantAllowed(bo.getTenantId());
return toAjax(tenantService.updateTenantStatus(bo));
}
/**
* 删除租户
*
* @param ids 主键串
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenant:remove")
@Log(title = "租户管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(tenantService.deleteWithValidByIds(List.of(ids), true));
}
/**
* 动态切换租户
*
* @param tenantId 租户ID
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@GetMapping("/dynamic/{tenantId}")
public R<Void> dynamicTenant(@NotBlank(message = "租户ID不能为空") @PathVariable String tenantId) {
TenantHelper.setDynamic(tenantId, true);
return R.ok();
}
/**
* 清除动态租户
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@GetMapping("/dynamic/clear")
public R<Void> dynamicClear() {
TenantHelper.clearDynamic();
return R.ok();
}
/**
* 同步租户套餐
*
* @param tenantId 租户id
* @param packageId 套餐id
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenant:edit")
@Log(title = "租户管理", businessType = BusinessType.UPDATE)
@GetMapping("/syncTenantPackage")
public R<Void> syncTenantPackage(@NotBlank(message = "租户ID不能为空") String tenantId,
@NotNull(message = "套餐ID不能为空") Long packageId) {
return toAjax(TenantHelper.ignore(() -> tenantService.syncTenantPackage(tenantId, packageId)));
}
/**
* 同步租户字典
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@Log(title = "租户管理", businessType = BusinessType.INSERT)
@GetMapping("/syncTenantDict")
public R<Void> syncTenantDict() {
if (!TenantHelper.isEnable()) {
return R.fail("当前未开启租户模式");
}
tenantService.syncTenantDict();
return R.ok("同步租户字典成功");
}
}

View File

@ -0,0 +1,142 @@
package com.fuyuanshen.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import com.fuyuanshen.common.core.constant.TenantConstants;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.core.validate.AddGroup;
import com.fuyuanshen.common.core.validate.EditGroup;
import com.fuyuanshen.common.excel.utils.ExcelUtil;
import com.fuyuanshen.common.idempotent.annotation.RepeatSubmit;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.system.domain.bo.SysTenantPackageBo;
import com.fuyuanshen.system.domain.vo.SysTenantPackageVo;
import com.fuyuanshen.system.service.ISysTenantPackageService;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 租户套餐管理
*
* @author Michelle.Chung
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/tenant/package")
@ConditionalOnProperty(value = "tenant.enable", havingValue = "true")
public class SysTenantPackageController extends BaseController {
private final ISysTenantPackageService tenantPackageService;
/**
* 查询租户套餐列表
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenantPackage:list")
@GetMapping("/list")
public TableDataInfo<SysTenantPackageVo> list(SysTenantPackageBo bo, PageQuery pageQuery) {
return tenantPackageService.queryPageList(bo, pageQuery);
}
/**
* 查询租户套餐下拉选列表
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenantPackage:list")
@GetMapping("/selectList")
public R<List<SysTenantPackageVo>> selectList() {
return R.ok(tenantPackageService.selectList());
}
/**
* 导出租户套餐列表
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenantPackage:export")
@Log(title = "租户套餐", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(SysTenantPackageBo bo, HttpServletResponse response) {
List<SysTenantPackageVo> list = tenantPackageService.queryList(bo);
ExcelUtil.exportExcel(list, "租户套餐", SysTenantPackageVo.class, response);
}
/**
* 获取租户套餐详细信息
*
* @param packageId 主键
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenantPackage:query")
@GetMapping("/{packageId}")
public R<SysTenantPackageVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long packageId) {
return R.ok(tenantPackageService.queryById(packageId));
}
/**
* 新增租户套餐
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenantPackage:add")
@Log(title = "租户套餐", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody SysTenantPackageBo bo) {
if (!tenantPackageService.checkPackageNameUnique(bo)) {
return R.fail("新增套餐'" + bo.getPackageName() + "'失败,套餐名称已存在");
}
return toAjax(tenantPackageService.insertByBo(bo));
}
/**
* 修改租户套餐
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenantPackage:edit")
@Log(title = "租户套餐", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysTenantPackageBo bo) {
if (!tenantPackageService.checkPackageNameUnique(bo)) {
return R.fail("修改套餐'" + bo.getPackageName() + "'失败,套餐名称已存在");
}
return toAjax(tenantPackageService.updateByBo(bo));
}
/**
* 状态修改
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenantPackage:edit")
@Log(title = "租户套餐", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public R<Void> changeStatus(@RequestBody SysTenantPackageBo bo) {
return toAjax(tenantPackageService.updatePackageStatus(bo));
}
/**
* 删除租户套餐
*
* @param packageIds 主键串
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenantPackage:remove")
@Log(title = "租户套餐", businessType = BusinessType.DELETE)
@DeleteMapping("/{packageIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] packageIds) {
return toAjax(tenantPackageService.deleteWithValidByIds(List.of(packageIds), true));
}
}

View File

@ -0,0 +1,300 @@
package com.fuyuanshen.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.BCrypt;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import com.fuyuanshen.common.core.constant.SystemConstants;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.core.domain.model.LoginUser;
import com.fuyuanshen.common.core.utils.StreamUtils;
import com.fuyuanshen.common.core.utils.StringUtils;
import com.fuyuanshen.common.encrypt.annotation.ApiEncrypt;
import com.fuyuanshen.common.excel.core.ExcelResult;
import com.fuyuanshen.common.excel.utils.ExcelUtil;
import com.fuyuanshen.common.log.annotation.Log;
import com.fuyuanshen.common.log.enums.BusinessType;
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.common.satoken.utils.LoginHelper;
import com.fuyuanshen.common.tenant.helper.TenantHelper;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.system.domain.bo.SysDeptBo;
import com.fuyuanshen.system.domain.bo.SysPostBo;
import com.fuyuanshen.system.domain.bo.SysRoleBo;
import com.fuyuanshen.system.domain.bo.SysUserBo;
import com.fuyuanshen.system.domain.vo.*;
import com.fuyuanshen.system.listener.SysUserImportListener;
import com.fuyuanshen.system.service.*;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.List;
/**
* 用户信息
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/user")
public class SysUserController extends BaseController {
private final ISysUserService userService;
private final ISysRoleService roleService;
private final ISysPostService postService;
private final ISysDeptService deptService;
private final ISysTenantService tenantService;
/**
* 获取用户列表
*/
@SaCheckPermission("system:user:list")
@GetMapping("/list")
public TableDataInfo<SysUserVo> list(SysUserBo user, PageQuery pageQuery) {
return userService.selectPageUserList(user, pageQuery);
}
/**
* 导出用户列表
*/
@Log(title = "用户管理", businessType = BusinessType.EXPORT)
@SaCheckPermission("system:user:export")
@PostMapping("/export")
public void export(SysUserBo user, HttpServletResponse response) {
List<SysUserExportVo> list = userService.selectUserExportList(user);
ExcelUtil.exportExcel(list, "用户数据", SysUserExportVo.class, response);
}
/**
* 导入数据
*
* @param file 导入文件
* @param updateSupport 是否更新已存在数据
*/
@Log(title = "用户管理", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:user:import")
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception {
ExcelResult<SysUserImportVo> result = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class, new SysUserImportListener(updateSupport));
return R.ok(result.getAnalysis());
}
/**
* 获取导入模板
*/
@PostMapping("/importTemplate")
public void importTemplate(HttpServletResponse response) {
ExcelUtil.exportExcel(new ArrayList<>(), "用户数据", SysUserImportVo.class, response);
}
/**
* 获取用户信息
*
* @return 用户信息
*/
@GetMapping("/getInfo")
public R<UserInfoVo> getInfo() {
UserInfoVo userInfoVo = new UserInfoVo();
LoginUser loginUser = LoginHelper.getLoginUser();
if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) {
// 超级管理员 如果重新加载用户信息需清除动态租户
TenantHelper.clearDynamic();
}
SysUserVo user = userService.selectUserById(loginUser.getUserId());
if (ObjectUtil.isNull(user)) {
return R.fail("没有权限访问用户数据!");
}
userInfoVo.setUser(user);
userInfoVo.setPermissions(loginUser.getMenuPermission());
userInfoVo.setRoles(loginUser.getRolePermission());
return R.ok(userInfoVo);
}
/**
* 根据用户编号获取详细信息
*
* @param userId 用户ID
*/
@SaCheckPermission("system:user:query")
@GetMapping(value = {"/", "/{userId}"})
public R<SysUserInfoVo> getInfo(@PathVariable(value = "userId", required = false) Long userId) {
SysUserInfoVo userInfoVo = new SysUserInfoVo();
if (ObjectUtil.isNotNull(userId)) {
userService.checkUserDataScope(userId);
SysUserVo sysUser = userService.selectUserById(userId);
userInfoVo.setUser(sysUser);
userInfoVo.setRoleIds(roleService.selectRoleListByUserId(userId));
Long deptId = sysUser.getDeptId();
if (ObjectUtil.isNotNull(deptId)) {
SysPostBo postBo = new SysPostBo();
postBo.setDeptId(deptId);
userInfoVo.setPosts(postService.selectPostList(postBo));
userInfoVo.setPostIds(postService.selectPostListByUserId(userId));
}
}
SysRoleBo roleBo = new SysRoleBo();
roleBo.setStatus(SystemConstants.NORMAL);
List<SysRoleVo> roles = roleService.selectRoleList(roleBo);
userInfoVo.setRoles(LoginHelper.isSuperAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isSuperAdmin()));
return R.ok(userInfoVo);
}
/**
* 新增用户
*/
@SaCheckPermission("system:user:add")
@Log(title = "用户管理", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysUserBo user) {
deptService.checkDeptDataScope(user.getDeptId());
if (!userService.checkUserNameUnique(user)) {
return R.fail("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
} else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
return R.fail("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
} else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
return R.fail("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
if (TenantHelper.isEnable()) {
if (!tenantService.checkAccountBalance(TenantHelper.getTenantId())) {
return R.fail("当前租户下用户名额不足,请联系管理员");
}
}
user.setPassword(BCrypt.hashpw(user.getPassword()));
return toAjax(userService.insertUser(user));
}
/**
* 修改用户
*/
@SaCheckPermission("system:user:edit")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysUserBo user) {
userService.checkUserAllowed(user.getUserId());
userService.checkUserDataScope(user.getUserId());
deptService.checkDeptDataScope(user.getDeptId());
if (!userService.checkUserNameUnique(user)) {
return R.fail("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
} else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
return R.fail("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
} else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
return R.fail("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
return toAjax(userService.updateUser(user));
}
/**
* 删除用户
*
* @param userIds 角色ID串
*/
@SaCheckPermission("system:user:remove")
@Log(title = "用户管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{userIds}")
public R<Void> remove(@PathVariable Long[] userIds) {
if (ArrayUtil.contains(userIds, LoginHelper.getUserId())) {
return R.fail("当前用户不能删除");
}
return toAjax(userService.deleteUserByIds(userIds));
}
/**
* 根据用户ID串批量获取用户基础信息
*
* @param userIds 用户ID串
* @param deptId 部门ID
*/
@SaCheckPermission("system:user:query")
@GetMapping("/optionselect")
public R<List<SysUserVo>> optionselect(@RequestParam(required = false) Long[] userIds,
@RequestParam(required = false) Long deptId) {
return R.ok(userService.selectUserByIds(ArrayUtil.isEmpty(userIds) ? null : List.of(userIds), deptId));
}
/**
* 重置密码
*/
@ApiEncrypt
@SaCheckPermission("system:user:resetPwd")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping("/resetPwd")
public R<Void> resetPwd(@RequestBody SysUserBo user) {
userService.checkUserAllowed(user.getUserId());
userService.checkUserDataScope(user.getUserId());
user.setPassword(BCrypt.hashpw(user.getPassword()));
return toAjax(userService.resetUserPwd(user.getUserId(), user.getPassword()));
}
/**
* 状态修改
*/
@SaCheckPermission("system:user:edit")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public R<Void> changeStatus(@RequestBody SysUserBo user) {
userService.checkUserAllowed(user.getUserId());
userService.checkUserDataScope(user.getUserId());
return toAjax(userService.updateUserStatus(user.getUserId(), user.getStatus()));
}
/**
* 根据用户编号获取授权角色
*
* @param userId 用户ID
*/
@SaCheckPermission("system:user:query")
@GetMapping("/authRole/{userId}")
public R<SysUserInfoVo> authRole(@PathVariable Long userId) {
userService.checkUserDataScope(userId);
SysUserVo user = userService.selectUserById(userId);
List<SysRoleVo> roles = roleService.selectRolesAuthByUserId(userId);
SysUserInfoVo userInfoVo = new SysUserInfoVo();
userInfoVo.setUser(user);
userInfoVo.setRoles(LoginHelper.isSuperAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isSuperAdmin()));
return R.ok(userInfoVo);
}
/**
* 用户授权角色
*
* @param userId 用户Id
* @param roleIds 角色ID串
*/
@SaCheckPermission("system:user:edit")
@Log(title = "用户管理", businessType = BusinessType.GRANT)
@PutMapping("/authRole")
public R<Void> insertAuthRole(Long userId, Long[] roleIds) {
userService.checkUserDataScope(userId);
userService.insertUserAuth(userId, roleIds);
return R.ok();
}
/**
* 获取部门树列表
*/
@SaCheckPermission("system:user:list")
@GetMapping("/deptTree")
public R<List<Tree<Long>>> deptTree(SysDeptBo dept) {
return R.ok(deptService.selectDeptTreeList(dept));
}
/**
* 获取部门下的所有用户信息
*/
@SaCheckPermission("system:user:list")
@GetMapping("/list/dept/{deptId}")
public R<List<SysUserVo>> listByDept(@PathVariable @NotNull Long deptId) {
return R.ok(userService.selectUserListByDept(deptId));
}
}