feat: initial iShare project code

This commit is contained in:
purovps
2026-02-16 23:20:59 +08:00
parent 8c83a6fd46
commit 6f270a972e
1910 changed files with 218015 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
FROM pig4cloud/java:8-jre
MAINTAINER wangiegie@gmail.com
ENV TZ=Asia/Shanghai
ENV JAVA_OPTS="-Xms512m -Xmx1024m -Djava.security.egd=file:/dev/./urandom"
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN mkdir -p /pigx-upms
WORKDIR /as-upms
EXPOSE 4000
ADD ./target/as-upms-biz.jar ./
CMD sleep 60;java $JAVA_OPTS -jar as-upms-biz.jar

186
as-upms/as-upms-biz/pom.xml Normal file
View File

@@ -0,0 +1,186 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>as-upms</artifactId>
<version>5.2.0</version>
</parent>
<artifactId>as-upms-biz</artifactId>
<packaging>jar</packaging>
<description>pigx 通用用户权限管理系统业务处理模块</description>
<dependencies>
<!-- mysql -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- ojdbc8 -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
</dependency>
<!--PG-->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<!--mssql-->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
</dependency>
<!--DM8-->
<dependency>
<groupId>com.dameng</groupId>
<artifactId>DmJdbcDriver18</artifactId>
</dependency>
<!--upms api、model 模块-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>as-upms-api</artifactId>
</dependency>
<!--日志处理-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-log</artifactId>
</dependency>
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-data</artifactId>
</dependency>
<!--swagger-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-swagger</artifactId>
</dependency>
<!--文件系统-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-oss</artifactId>
</dependency>
<!--注册中心客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--配置中心客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--spring security 、oauth、jwt依赖-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-security</artifactId>
</dependency>
<!--XSS 安全过滤-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-xss</artifactId>
</dependency>
<!-- 字段审计 -->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-audit</artifactId>
</dependency>
<!--支持动态路由配置 -->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-gateway</artifactId>
</dependency>
<!--sentinel 依赖-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-sentinel</artifactId>
</dependency>
<!--路由控制-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-gray</artifactId>
</dependency>
<!--mybatis-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- druid 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<!-- cas sdk -->
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>${cas.sdk.version}</version>
</dependency>
<!--旧版api,新版api未包含全部的服务端API的产品能力-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>alibaba-dingtalk-service-sdk</artifactId>
<version>${dingtalk.old.version}</version>
</dependency>
<!--企业微信-->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-cp</artifactId>
</dependency>
<!--web 模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>**/*.xlsx</exclude>
<exclude>**/*.xls</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/*.xlsx</include>
<include>**/*.xls</include>
</includes>
</resource>
</resources>
</build>
</project>

View File

@@ -0,0 +1,46 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin;
import com.pig4cloud.pigx.common.feign.annotation.EnablePigxFeignClients;
import com.pig4cloud.pigx.common.security.annotation.EnablePigxResourceServer;
import com.pig4cloud.pigx.common.swagger.annotation.EnableOpenApi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @author lengleng
* @date 2018年06月21日
* <p>
* 用户统一管理系统
*/
@EnableOpenApi("admin")
@EnablePigxFeignClients
@EnablePigxResourceServer
@EnableDiscoveryClient
@SpringBootApplication
public class AsAdminApplication {
public static void main(String[] args) {
SpringApplication.run(AsAdminApplication.class, args);
}
}

View File

@@ -0,0 +1,98 @@
package com.pig4cloud.pigx.admin.config;
import cn.hutool.core.util.StrUtil;
import com.pig4cloud.pigx.admin.service.SysOauthClientDetailsService;
import com.pig4cloud.pigx.admin.service.SysTenantService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.data.tenant.TenantBroker;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.event.TransactionalEventListener;
/**
* @author lengleng
* @date 2020/11/18
* <p>
* oauth 客户端认证参数初始化
*/
@Slf4j
@Service
@RequiredArgsConstructor
@SuppressWarnings("all")
public class ClientDetailsInitRunner implements InitializingBean {
private final SysOauthClientDetailsService clientDetailsService;
private final RedisMessageListenerContainer listenerContainer;
private final SysTenantService tenantService;
private final RedisTemplate redisTemplate;
/**
* WebServerInitializedEvent 使用 TransactionalEventListener 时启动时无法获取到事件
*/
@Async
@Order
@EventListener({ WebServerInitializedEvent.class })
public void webServerInit() {
this.initClientDetails();
}
@Async
@Order
@TransactionalEventListener({ ClientDetailsInitEvent.class })
public void initClientDetails() {
log.debug("初始化客户端信息开始 ");
// 1. 查询全部租户循环遍历
tenantService.list().forEach(tenant -> {
TenantBroker.runAs(tenant.getId(), tenantId -> {
// 2. 查询当前租户的所有客户端信息 (排除客户端扩展信息为空)
clientDetailsService.list().stream().filter(client -> {
return StrUtil.isNotBlank(client.getAdditionalInformation());
}).forEach(client -> {
// 3. 拼接key 1:client_config_flag:clinetId
String key = String.format("%s:%s:%s", tenantId, CacheConstants.CLIENT_FLAG, client.getClientId());
// 4. hashkey clientId 保存客户端信息
redisTemplate.opsForValue().set(key, client.getAdditionalInformation());
});
});
});
log.debug("初始化客户端信息结束 ");
}
/**
* 客户端刷新事件
*/
public static class ClientDetailsInitEvent extends ApplicationEvent {
public ClientDetailsInitEvent(Object source) {
super(source);
}
}
/**
* redis 监听配置,监听 upms_redis_client_reload_topic,重新加载Redis
*/
@Override
public void afterPropertiesSet() throws Exception {
listenerContainer.addMessageListener((message, bytes) -> {
log.warn("接收到重新Redis 重新加载客户端配置事件");
initClientDetails();
}, new ChannelTopic(CacheConstants.CLIENT_REDIS_RELOAD_TOPIC));
}
}

View File

@@ -0,0 +1,112 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.config;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.pig4cloud.pigx.admin.service.SysRouteConfService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.gateway.support.DynamicRouteInitEvent;
import com.pig4cloud.pigx.common.gateway.vo.RouteDefinitionVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.event.TransactionalEventListener;
import java.net.URI;
import java.util.Map;
/**
* @author lengleng
* @date 2018/10/31
* <p>
* 容器启动后保存配置文件里面的路由信息到Redis
*/
@Slf4j
@Configuration
@RequiredArgsConstructor
public class DynamicRouteInitRunner implements InitializingBean {
private final RedisTemplate redisTemplate;
private final SysRouteConfService routeConfService;
private final RedisMessageListenerContainer listenerContainer;
/**
* WebServerInitializedEvent 使用 TransactionalEventListener 时启动时无法获取到事件
*/
@Async
@Order
@EventListener({ WebServerInitializedEvent.class })
public void WebServerInit() {
this.initRoute();
}
@Async
@Order
@TransactionalEventListener({ DynamicRouteInitEvent.class })
public void initRoute() {
redisTemplate.delete(CacheConstants.ROUTE_KEY);
log.info("开始初始化网关路由");
routeConfService.list().forEach(route -> {
RouteDefinitionVo vo = new RouteDefinitionVo();
vo.setRouteName(route.getRouteName());
vo.setId(route.getRouteId());
vo.setUri(URI.create(route.getUri()));
vo.setOrder(route.getSortOrder());
JSONArray filterObj = JSONUtil.parseArray(route.getFilters());
vo.setFilters(filterObj.toList(FilterDefinition.class));
JSONArray predicateObj = JSONUtil.parseArray(route.getPredicates());
vo.setPredicates(predicateObj.toList(PredicateDefinition.class));
vo.setMetadata(JSONUtil.toBean(route.getMetadata(), Map.class));
log.info("加载路由ID{},{}", route.getRouteId(), vo);
redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(RouteDefinitionVo.class));
redisTemplate.opsForHash().put(CacheConstants.ROUTE_KEY, route.getRouteId(), vo);
});
// 通知网关重置路由
redisTemplate.convertAndSend(CacheConstants.ROUTE_JVM_RELOAD_TOPIC, "路由信息,网关缓存更新");
log.debug("初始化网关路由结束 ");
}
/**
* redis 监听配置,监听 upms_redis_route_reload_topic,重新加载Redis
*/
@Override
public void afterPropertiesSet() {
listenerContainer.addMessageListener((message, bytes) -> {
log.warn("接收到重新Redis 重新加载路由事件");
initRoute();
}, new ChannelTopic(CacheConstants.ROUTE_REDIS_RELOAD_TOPIC));
}
}

View File

@@ -0,0 +1,76 @@
package com.pig4cloud.pigx.admin.controller;
import com.pig4cloud.pigx.admin.api.entity.SysDept;
import com.pig4cloud.pigx.admin.service.ConnectService;
import com.pig4cloud.pigx.admin.service.SysDeptService;
import com.pig4cloud.pigx.common.core.util.R;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 钉钉、微信 互联
*
* @author lengleng
* @date 2022/4/22
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/connect")
@Tag(description = "connect", name = "开放互联")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class ConnectController {
private final ConnectService connectService;
private final SysDeptService deptService;
/**
* 同步钉钉用户
* @return
*/
@PostMapping("/sync/ding/user")
@PreAuthorize("@pms.hasPermission('sys_connect_sync')")
public R syncUser() {
for (SysDept sysDept : deptService.list()) {
connectService.syncDingUser(sysDept.getDeptId());
}
return R.ok();
}
/**
* 同步钉钉部门
* @return
*/
@PostMapping("/sync/ding/dept")
@PreAuthorize("@pms.hasPermission('sys_connect_sync')")
public R syncDept() {
return R.ok(connectService.syncDingDept());
}
/**
* 同步企微用户
* @return
*/
@PostMapping("/sync/cp/user")
@PreAuthorize("@pms.hasPermission('sys_connect_sync')")
public R syncCpUser() {
return connectService.syncCpUser();
}
/**
* 同步企微部门
* @return
*/
@PostMapping("/sync/cp/dept")
@PreAuthorize("@pms.hasPermission('sys_connect_sync')")
public R syncCpDept() {
return connectService.syncCpDept();
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.controller;
import com.pig4cloud.pigx.admin.service.MobileService;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.security.annotation.Inner;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author lengleng
* @date 2018/11/14
* <p>
* 手机验证码
*/
@RestController
@AllArgsConstructor
@RequestMapping("/mobile")
@Tag(description = "mobile", name = "手机管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class MobileController {
private final MobileService mobileService;
@Inner(value = false)
@GetMapping("/{mobile}")
public R sendSmsCode(@PathVariable String mobile) {
return mobileService.sendSmsCode(mobile);
}
}

View File

@@ -0,0 +1,41 @@
package com.pig4cloud.pigx.admin.controller;
import com.pig4cloud.pigx.admin.api.dto.UserDTO;
import com.pig4cloud.pigx.admin.service.SysUserService;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import com.pig4cloud.pigx.common.security.annotation.Inner;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
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;
/**
* @author lengleng
* @date 2022/3/30
* <p>
* 客户端注册功能 register.user = false
*/
@RestController
@RequestMapping("/register")
@RequiredArgsConstructor
@ConditionalOnProperty(name = "register.user", matchIfMissing = true)
public class RegisterController {
private final SysUserService userService;
/**
* 注册用户
* @param userDto 用户信息
* @return success/false
*/
@Inner(value = false)
@SysLog("注册用户")
@PostMapping("/user")
public R<Boolean> registerUser(@RequestBody UserDTO userDto) {
return userService.registerUser(userDto);
}
}

View File

@@ -0,0 +1,117 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.admin.api.entity.SysAuditLog;
import com.pig4cloud.pigx.admin.service.SysAuditLogService;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import com.pig4cloud.pigx.common.security.annotation.Inner;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 审计记录表
*
* @author PIG
* @date 2023-02-28 20:12:23
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/audit")
@Tag(description = "audit", name = "审计记录表管理")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysAuditLogController {
private final SysAuditLogService sysAuditLogService;
/**
* 分页查询
* @param page 分页对象
* @param sysAuditLog 审计记录表
* @return
*/
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
public R getsysAuditLogPage(@ParameterObject Page page, @ParameterObject SysAuditLog sysAuditLog) {
return R.ok(sysAuditLogService.getAuditsByScope(page, sysAuditLog));
}
/**
* 通过id查询审计记录表
* @param id id
* @return R
*/
@Operation(summary = "通过id查询", description = "通过id查询")
@GetMapping("/{id}")
public R getById(@PathVariable("id") Long id) {
return R.ok(sysAuditLogService.getById(id));
}
/**
* 新增审计记录表 (异步插入)
* @param auditLogList 审计记录
* @return R
*/
@Inner
@PostMapping
@Operation(summary = "新增审计记录表", description = "新增审计记录表")
public R save(@RequestBody List<SysAuditLog> auditLogList) {
return R.ok(sysAuditLogService.saveBatch(auditLogList));
}
/**
* 通过id删除审计记录表
* @param ids id列表
* @return R
*/
@Operation(summary = "通过id删除审计记录表", description = "通过id删除审计记录表")
@SysLog("通过id删除审计记录表")
@DeleteMapping("/delete")
@PreAuthorize("@pms.hasPermission('sys_audit_del')")
public R removeById(@RequestBody Long[] ids) {
return R.ok(sysAuditLogService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 导出excel 表格
* @param sysAuditLog 查询条件
* @return excel 文件流
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('sys_audit_export')")
public List<SysAuditLog> export(SysAuditLog sysAuditLog, Long[] ids) {
return sysAuditLogService
.list(Wrappers.lambdaQuery(sysAuditLog).in(ArrayUtil.isNotEmpty(ids), SysAuditLog::getId, ids));
}
}

View File

@@ -0,0 +1,181 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.admin.api.dto.SysOauthClientDetailsDTO;
import com.pig4cloud.pigx.admin.api.entity.SysOauthClientDetails;
import com.pig4cloud.pigx.admin.config.ClientDetailsInitRunner;
import com.pig4cloud.pigx.admin.service.SysOauthClientDetailsService;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import com.pig4cloud.pigx.common.security.annotation.Inner;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author lengleng
* @since 2018-05-15
*/
@RestController
@AllArgsConstructor
@RequestMapping("/client")
@Tag(description = "client", name = "客户端管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysClientController {
private final SysOauthClientDetailsService clientDetailsService;
/**
* 通过ID查询
* @param clientId clientId
* @return SysOauthClientDetails
*/
@GetMapping("/{clientId}")
public R getByClientId(@PathVariable String clientId) {
SysOauthClientDetails details = clientDetailsService
.getOne(Wrappers.<SysOauthClientDetails>lambdaQuery().eq(SysOauthClientDetails::getClientId, clientId));
String information = details.getAdditionalInformation();
String captchaFlag = JSONUtil.parseObj(information).getStr(CommonConstants.CAPTCHA_FLAG);
String encFlag = JSONUtil.parseObj(information).getStr(CommonConstants.ENC_FLAG);
String onlineQuantity = JSONUtil.parseObj(information).getStr(CommonConstants.ONLINE_QUANTITY);
SysOauthClientDetailsDTO dto = new SysOauthClientDetailsDTO();
BeanUtils.copyProperties(details, dto);
dto.setCaptchaFlag(captchaFlag);
dto.setEncFlag(encFlag);
dto.setOnlineQuantity(onlineQuantity);
return R.ok(dto);
}
/**
* 简单分页查询
* @param page 分页对象
* @param sysOauthClientDetails 系统终端
* @return
*/
@GetMapping("/page")
public R getOauthClientDetailsPage(@ParameterObject Page page,
@ParameterObject SysOauthClientDetails sysOauthClientDetails) {
LambdaQueryWrapper<SysOauthClientDetails> wrapper = Wrappers.<SysOauthClientDetails>lambdaQuery()
.like(StrUtil.isNotBlank(sysOauthClientDetails.getClientId()), SysOauthClientDetails::getClientId,
sysOauthClientDetails.getClientId())
.like(StrUtil.isNotBlank(sysOauthClientDetails.getClientSecret()),
SysOauthClientDetails::getClientSecret, sysOauthClientDetails.getClientSecret());
return R.ok(clientDetailsService.page(page, wrapper));
}
/**
* 添加
* @param clientDetailsDTO 实体
* @return success/false
*/
@SysLog("添加终端")
@PostMapping
@PreAuthorize("@pms.hasPermission('sys_client_add')")
public R add(@Valid @RequestBody SysOauthClientDetailsDTO clientDetailsDTO) {
return R.ok(clientDetailsService.saveClient(clientDetailsDTO));
}
/**
* 删除
* @param ids ID 列表
* @return success/false
*/
@SysLog("删除终端")
@DeleteMapping
@PreAuthorize("@pms.hasPermission('sys_client_del')")
public R removeById(@RequestBody Long[] ids) {
clientDetailsService.removeBatchByIds(CollUtil.toList(ids));
SpringContextHolder.publishEvent(new ClientDetailsInitRunner.ClientDetailsInitEvent(ids));
return R.ok();
}
/**
* 编辑
* @param clientDetailsDTO 实体
* @return success/false
*/
@SysLog("编辑终端")
@PutMapping
@PreAuthorize("@pms.hasPermission('sys_client_edit')")
public R update(@Valid @RequestBody SysOauthClientDetailsDTO clientDetailsDTO) {
return R.ok(clientDetailsService.updateClientById(clientDetailsDTO));
}
@Inner(false)
@GetMapping("/getClientDetailsById/{clientId}")
public R getClientDetailsById(@PathVariable String clientId) {
return R.ok(clientDetailsService.getOne(
Wrappers.<SysOauthClientDetails>lambdaQuery().eq(SysOauthClientDetails::getClientId, clientId), false));
}
/**
* 查询全部客户端
* @return
*/
@Inner(false)
@GetMapping("/list")
public R listClients() {
return R.ok(clientDetailsService.list());
}
/**
* 同步缓存字典
* @return R
*/
@SysLog("同步终端")
@PutMapping("/sync")
public R sync() {
return clientDetailsService.syncClientCache();
}
/**
* 导出所有客户端
* @return excel
*/
@ResponseExcel
@SysLog("导出excel")
@GetMapping("/export")
public List<SysOauthClientDetails> export(SysOauthClientDetails sysOauthClientDetails) {
return clientDetailsService.list(Wrappers.query(sysOauthClientDetails));
}
}

View File

@@ -0,0 +1,158 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.controller;
import com.pig4cloud.pigx.admin.api.entity.SysDept;
import com.pig4cloud.pigx.admin.api.vo.DeptExcelVo;
import com.pig4cloud.pigx.admin.service.SysDeptService;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.excel.annotation.RequestExcel;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.List;
/**
* <p>
* 部门管理 前端控制器
* </p>
*
* @author lengleng
* @since 2018-01-20
*/
@RestController
@AllArgsConstructor
@RequestMapping("/dept")
@Tag(description = "dept", name = "部门管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysDeptController {
private final SysDeptService sysDeptService;
/**
* 通过ID查询
* @param id ID
* @return SysDept
*/
@GetMapping("/{id}")
public R getById(@PathVariable Long id) {
return R.ok(sysDeptService.getById(id));
}
/**
* 查询全部部门
*/
@GetMapping("/list")
public R list() {
return R.ok(sysDeptService.list());
}
/**
* 返回树形菜单集合
* @param deptName 部门名称
* @return 树形菜单
*/
@GetMapping(value = "/tree")
public R getTree(String deptName, Long parentId) {
return R.ok(sysDeptService.selectTree(deptName, parentId));
}
/**
* 添加
* @param sysDept 实体
* @return success/false
*/
@SysLog("添加部门")
@PostMapping
@PreAuthorize("@pms.hasPermission('sys_dept_add')")
public R save(@Valid @RequestBody SysDept sysDept) {
return R.ok(sysDeptService.save(sysDept));
}
/**
* 删除
* @param id ID
* @return success/false
*/
@SysLog("删除部门")
@DeleteMapping("/{id}")
@PreAuthorize("@pms.hasPermission('sys_dept_del')")
public R removeById(@PathVariable Long id) {
return R.ok(sysDeptService.removeDeptById(id));
}
/**
* 编辑
* @param sysDept 实体
* @return success/false
*/
@SysLog("编辑部门")
@PutMapping
@PreAuthorize("@pms.hasPermission('sys_dept_edit')")
public R update(@Valid @RequestBody SysDept sysDept) {
sysDept.setUpdateTime(LocalDateTime.now());
return R.ok(sysDeptService.updateById(sysDept));
}
/**
* 查收子级列表
* @return 返回子级
*/
@GetMapping(value = "/getDescendantList/{deptId}")
public R getDescendantList(@PathVariable Long deptId) {
return R.ok(sysDeptService.listDescendant(deptId));
}
@GetMapping(value = "/leader/{deptId}")
public R getAllDeptLeader(@PathVariable Long deptId) {
return R.ok(sysDeptService.listDeptLeader(deptId));
}
/**
* 导出部门
* @return
*/
@ResponseExcel
@GetMapping("/export")
public List<DeptExcelVo> export() {
return sysDeptService.listExcelVo();
}
/**
* 导入部门
* @param excelVOList
* @param bindingResult
* @return
*/
@PostMapping("import")
public R importDept(@RequestExcel List<DeptExcelVo> excelVOList, BindingResult bindingResult) {
return sysDeptService.importDept(excelVOList, bindingResult);
}
}

View File

@@ -0,0 +1,242 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.admin.api.entity.SysDict;
import com.pig4cloud.pigx.admin.api.entity.SysDictItem;
import com.pig4cloud.pigx.admin.service.SysDictItemService;
import com.pig4cloud.pigx.admin.service.SysDictService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* <p>
* 字典表 前端控制器
* </p>
*
* @author lengleng
* @since 2019-03-19
*/
@RestController
@AllArgsConstructor
@RequestMapping("/dict")
@Tag(description = "dict", name = "字典管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysDictController {
private final SysDictService sysDictService;
private final SysDictItemService sysDictItemService;
/**
* 通过ID查询字典信息
* @param id ID
* @return 字典信息
*/
@GetMapping("/details/{id}")
public R getById(@PathVariable Long id) {
return R.ok(sysDictService.getById(id));
}
/**
* 查询字典信息
* @param query 查询信息
* @return 字典信息
*/
@GetMapping("/details")
public R getDetails(@ParameterObject SysDict query) {
return R.ok(sysDictService.getOne(Wrappers.query(query), false));
}
/**
* 分页查询字典信息
* @param page 分页对象
* @return 分页对象
*/
@GetMapping("/page")
public R<IPage> getDictPage(@ParameterObject Page page, @ParameterObject SysDict sysDict) {
return R.ok(sysDictService.page(page,
Wrappers.<SysDict>lambdaQuery()
.eq(StrUtil.isNotBlank(sysDict.getSystemFlag()), SysDict::getSystemFlag,
sysDict.getSystemFlag())
.like(StrUtil.isNotBlank(sysDict.getDictType()), SysDict::getDictType, sysDict.getDictType())));
}
/**
* 通过字典类型查找字典
* @param type 类型
* @return 同类型字典
*/
@GetMapping("/type/{type}")
@Cacheable(value = CacheConstants.DICT_DETAILS, key = "#type", unless = "#result.data.isEmpty()")
public R<List<SysDictItem>> getDictByType(@PathVariable String type) {
return R.ok(sysDictItemService.list(Wrappers.<SysDictItem>query().lambda().eq(SysDictItem::getDictType, type)));
}
/**
* 添加字典
* @param sysDict 字典信息
* @return success、false
*/
@SysLog("添加字典")
@PostMapping
@PreAuthorize("@pms.hasPermission('sys_dict_add')")
public R save(@Valid @RequestBody SysDict sysDict) {
sysDictService.save(sysDict);
return R.ok(sysDict);
}
/**
* 删除字典,并且清除字典缓存
* @param ids ID
* @return R
*/
@SysLog("删除字典")
@DeleteMapping
@PreAuthorize("@pms.hasPermission('sys_dict_del')")
@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
public R removeById(@RequestBody Long[] ids) {
return R.ok(sysDictService.removeDictByIds(ids));
}
/**
* 修改字典
* @param sysDict 字典信息
* @return success/false
*/
@PutMapping
@SysLog("修改字典")
@PreAuthorize("@pms.hasPermission('sys_dict_edit')")
public R updateById(@Valid @RequestBody SysDict sysDict) {
return sysDictService.updateDict(sysDict);
}
/**
* 分页查询
* @param name 名称或者字典项
* @return
*/
@GetMapping("/list")
public R getDictList(String name) {
return R.ok(sysDictService
.list(Wrappers.<SysDict>lambdaQuery().like(StrUtil.isNotBlank(name), SysDict::getDictType, name).or()
.like(StrUtil.isNotBlank(name), SysDict::getDescription, name)));
}
/**
* 分页查询
* @param page 分页对象
* @param sysDictItem 字典项
* @return
*/
@GetMapping("/item/page")
public R getSysDictItemPage(Page page, SysDictItem sysDictItem) {
return R.ok(sysDictItemService.page(page, Wrappers.query(sysDictItem)));
}
/**
* 通过id查询字典项
* @param id id
* @return R
*/
@GetMapping("/item/details/{id}")
public R getDictItemById(@PathVariable("id") Long id) {
return R.ok(sysDictItemService.getById(id));
}
/**
* 查询字典项详情
* @param query 查询条件
* @return R
*/
@GetMapping("/item/details")
public R getDictItemDetails(SysDictItem query) {
return R.ok(sysDictItemService.getOne(Wrappers.query(query), false));
}
/**
* 新增字典项
* @param sysDictItem 字典项
* @return R
*/
@SysLog("新增字典项")
@PostMapping("/item")
@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
public R save(@RequestBody SysDictItem sysDictItem) {
return R.ok(sysDictItemService.save(sysDictItem));
}
/**
* 修改字典项
* @param sysDictItem 字典项
* @return R
*/
@SysLog("修改字典项")
@PutMapping("/item")
public R updateById(@RequestBody SysDictItem sysDictItem) {
return sysDictItemService.updateDictItem(sysDictItem);
}
/**
* 通过id删除字典项
* @param id id
* @return R
*/
@SysLog("删除字典项")
@DeleteMapping("/item/{id}")
public R removeDictItemById(@PathVariable Long id) {
return sysDictItemService.removeDictItem(id);
}
/**
* 同步缓存字典
* @return R
*/
@SysLog("同步字典")
@PutMapping("/sync")
public R sync() {
return sysDictService.syncDictCache();
}
@ResponseExcel
@GetMapping("/export")
public List<SysDictItem> export(SysDictItem sysDictItem) {
return sysDictItemService.list(Wrappers.query(sysDictItem));
}
}

View File

@@ -0,0 +1,187 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.controller;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.admin.api.dto.SysFileGroupDTO;
import com.pig4cloud.pigx.admin.api.entity.SysFile;
import com.pig4cloud.pigx.admin.api.entity.SysFileGroup;
import com.pig4cloud.pigx.admin.service.SysFileService;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import com.pig4cloud.pigx.common.security.annotation.Inner;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
/**
* 文件管理
*
* @author Luckly
* @date 2019-06-18 17:18:42
*/
@RestController
@AllArgsConstructor
@RequestMapping("/sys-file")
@Tag(description = "sys-file", name = "文件管理")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysFileController {
private final SysFileService sysFileService;
/**
* 分页查询
* @param page 分页对象
* @param sysFile 文件管理
* @return
*/
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
public R getSysFilePage(@ParameterObject Page page, @ParameterObject SysFile sysFile) {
LambdaQueryWrapper<SysFile> wrapper = Wrappers.<SysFile>lambdaQuery()
.eq(StrUtil.isNotBlank(sysFile.getType()), SysFile::getType, sysFile.getType())
.eq(Objects.nonNull(sysFile.getGroupId()), SysFile::getGroupId, sysFile.getGroupId())
.like(StrUtil.isNotBlank(sysFile.getOriginal()), SysFile::getOriginal, sysFile.getOriginal());
return R.ok(sysFileService.page(page, wrapper));
}
/**
* 通过id删除文件管理
* @param ids id 列表
* @return R
*/
@Operation(summary = "通过id删除文件管理", description = "通过id删除文件管理")
@SysLog("删除文件管理")
@DeleteMapping
@PreAuthorize("@pms.hasPermission('sys_file_del')")
public R removeById(@RequestBody Long[] ids) {
for (Long id : ids) {
sysFileService.deleteFile(id);
}
return R.ok();
}
@PutMapping("/rename")
public R rename(@RequestBody SysFile sysFile) {
return R.ok(sysFileService.updateById(sysFile));
}
/**
* 上传文件 文件名采用uuid,避免原始文件名中带"-"符号导致下载的时候解析出现异常
* @param file 资源
* @return R(/ admin / bucketName / filename)
*/
@PostMapping(value = "/upload")
public R upload(@RequestPart("file") MultipartFile file,
@RequestParam(value = "groupId", required = false) Long groupId,
@RequestParam(value = "type", required = false) String type) {
return sysFileService.uploadFile(file, groupId, type);
}
/**
* 获取文件
* @param bucket 桶名称
* @param fileName 文件空间/名称
* @param response
* @return
*/
@Inner(false)
@GetMapping("/{bucket}/{fileName}")
public void file(@PathVariable String bucket, @PathVariable String fileName, HttpServletResponse response) {
sysFileService.getFile(bucket, fileName, response);
}
/**
* 获取本地resources文件
* @param fileName 文件名称
* @param response 本地文件
*/
@SneakyThrows
@GetMapping("/local/file/{fileName}")
public void localFile(@PathVariable String fileName, HttpServletResponse response) {
ClassPathResource resource = new ClassPathResource("file/" + fileName);
response.setContentType("application/octet-stream; charset=UTF-8");
IoUtil.copy(resource.getInputStream(), response.getOutputStream());
}
/**
* 查询文件组列表
* @param fileGroup SysFileGroup对象用于筛选条件
* @return 包含文件组列表的R对象
*/
@GetMapping("/group/list")
public R listGroup(SysFileGroup fileGroup) {
return R.ok(sysFileService.listFileGroup(fileGroup));
}
/**
* 添加文件组
* @param fileGroup SysFileGroup对象要添加的文件组信息
* @return 包含添加结果的R对象
*/
@PostMapping("/group/add")
public R addGroup(@RequestBody SysFileGroup fileGroup) {
return R.ok(sysFileService.saveOrUpdateGroup(fileGroup));
}
/**
* 更新文件组
* @param fileGroup SysFileGroup对象要更新的文件组信息
* @return 包含更新结果的R对象
*/
@PutMapping("/group/update")
public R updateGroup(@RequestBody SysFileGroup fileGroup) {
return R.ok(sysFileService.saveOrUpdateGroup(fileGroup));
}
/**
* 删除文件组
* @param id 待删除文件组的ID
* @return 包含删除结果的R对象
*/
@DeleteMapping("/group/delete/{id}")
public R updateGroup(@PathVariable Long id) {
return R.ok(sysFileService.deleteGroup(id));
}
/**
* 移动文件组
* @param fileGroupDTO SysFileGroupDTO对象要移动的文件组信息
* @return 包含移动结果的R对象
*/
@PutMapping("/group/move")
public R moveFileGroup(@RequestBody SysFileGroupDTO fileGroupDTO) {
return R.ok(sysFileService.moveFileGroup(fileGroupDTO));
}
}

View File

@@ -0,0 +1,169 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.admin.api.entity.SysI18nEntity;
import com.pig4cloud.pigx.admin.service.SysI18nService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import com.pig4cloud.pigx.common.security.annotation.Inner;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 系统表-国际化
*
* @author PIG
* @date 2023-02-14 09:07:01
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/i18n")
@Tag(description = "i18n", name = "系统表-国际化管理")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysI18nController {
private final SysI18nService sysI18nService;
/**
* 分页查询
* @param page 分页对象
* @param sysI18n 系统表-国际化
* @return
*/
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('sys_i18n_view')")
public R getsysI18nPage(@ParameterObject Page page, @ParameterObject SysI18nEntity sysI18n) {
LambdaQueryWrapper<SysI18nEntity> wrapper = Wrappers.lambdaQuery();
wrapper.like(StrUtil.isNotBlank(sysI18n.getName()), SysI18nEntity::getName, sysI18n.getName());
wrapper.like(StrUtil.isNotBlank(sysI18n.getZhCn()), SysI18nEntity::getZhCn, sysI18n.getZhCn());
wrapper.like(StrUtil.isNotBlank(sysI18n.getEn()), SysI18nEntity::getEn, sysI18n.getEn());
return R.ok(sysI18nService.page(page, wrapper));
}
/**
* 通过id查询系统表-国际化
* @param id id
* @return R
*/
@Operation(summary = "通过id查询", description = "通过id查询")
@GetMapping("/details/{id}")
public R getById(@PathVariable("id") Long id) {
return R.ok(sysI18nService.getById(id));
}
@GetMapping("/details")
public R getDetails(@ParameterObject SysI18nEntity entity) {
return R.ok(sysI18nService.getOne(Wrappers.query(entity)));
}
/**
* 新增系统表-国际化
* @param sysI18n 系统表-国际化
* @return R
*/
@Operation(summary = "新增系统表-国际化", description = "新增系统表-国际化")
@SysLog("新增系统表-国际化")
@PostMapping
@CacheEvict(value = CacheConstants.I18N_DETAILS, allEntries = true)
@PreAuthorize("@pms.hasPermission('sys_i18n_add')")
public R save(@RequestBody SysI18nEntity sysI18n) {
return R.ok(sysI18nService.save(sysI18n));
}
/**
* 修改系统表-国际化
* @param sysI18n 系统表-国际化
* @return R
*/
@Operation(summary = "修改系统表-国际化", description = "修改系统表-国际化")
@SysLog("修改系统表-国际化")
@PutMapping
@CacheEvict(value = CacheConstants.I18N_DETAILS, allEntries = true)
@PreAuthorize("@pms.hasPermission('sys_i18n_edit')")
public R updateById(@RequestBody SysI18nEntity sysI18n) {
return R.ok(sysI18nService.updateById(sysI18n));
}
/**
* 通过id删除系统表-国际化
* @param ids id 列表
* @return R
*/
@Operation(summary = "通过id删除系统表-国际化", description = "通过id删除系统表-国际化")
@SysLog("通过id删除系统表-国际化")
@DeleteMapping
@CacheEvict(value = CacheConstants.I18N_DETAILS, allEntries = true)
@PreAuthorize("@pms.hasPermission('sys_i18n_del')")
public R removeById(@RequestBody Long[] ids) {
return R.ok(sysI18nService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 导出excel 表格
* @param sysI18n 查询条件
* @return excel 文件流
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('sys_i18n_export')")
public List<SysI18nEntity> export(SysI18nEntity sysI18n, Long[] ids) {
return sysI18nService
.list(Wrappers.lambdaQuery(sysI18n).in(ArrayUtil.isNotEmpty(ids), SysI18nEntity::getId, ids));
}
/**
* 获取系统I18N配置
* @return I18N 配置
*/
@Operation(summary = "获取系统配置-国际化", description = "获取系统配置-国际化")
@Inner(false)
@GetMapping("/info")
public R list() {
return R.ok(sysI18nService.listMap());
}
/**
* 同步数据
* @return R
*/
@SysLog("同步数据")
@PutMapping("/sync")
public R sync() {
return sysI18nService.syncI18nCache();
}
}

View File

@@ -0,0 +1,116 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.controller;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.admin.api.dto.SysLogDTO;
import com.pig4cloud.pigx.admin.api.entity.SysLog;
import com.pig4cloud.pigx.admin.api.vo.PreLogVO;
import com.pig4cloud.pigx.admin.service.SysLogService;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.security.annotation.Inner;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import java.util.Objects;
/**
* <p>
* 日志表 前端控制器
* </p>
*
* @author lengleng
* @since 2017-11-20
*/
@RestController
@AllArgsConstructor
@RequestMapping("/log")
@Tag(description = "log", name = "日志管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysLogController {
private final SysLogService sysLogService;
/**
* 简单分页查询
* @param page 分页对象
* @param sysLog 系统日志
* @return
*/
@GetMapping("/page")
public R getLogPage(@ParameterObject Page page, @ParameterObject SysLogDTO sysLog) {
return R.ok(sysLogService.getLogByPage(page, sysLog));
}
/**
* 批量删除日志
* @param ids ID
* @return success/false
*/
@DeleteMapping
@PreAuthorize("@pms.hasPermission('sys_log_del')")
public R removeByIds(@RequestBody Long[] ids) {
return R.ok(sysLogService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 插入日志
* @param sysLog 日志实体
* @return success/false
*/
@Inner
@PostMapping("/save")
public R save(@Valid @RequestBody SysLogDTO sysLog) {
return R.ok(sysLogService.saveLog(sysLog));
}
/**
* 批量插入前端异常日志
* @param preLogVoList 日志实体
* @return success/false
*/
@PostMapping("/logs")
public R saveBatchLogs(@RequestBody List<PreLogVO> preLogVoList) {
return R.ok(sysLogService.saveBatchLogs(preLogVoList));
}
/**
* 导出excel 表格
* @param sysLog 查询条件
* @return
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('sys_log_export')")
public List<SysLog> export(SysLog sysLog, Long[] ids) {
return sysLogService.list(Wrappers.lambdaQuery(sysLog).in(Objects.nonNull(ids), SysLog::getId, ids));
}
}

View File

@@ -0,0 +1,135 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.controller;
import com.pig4cloud.pigx.admin.api.entity.SysMenu;
import com.pig4cloud.pigx.admin.service.SysMenuService;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @author lengleng
* @date 2017/10/31
*/
@RestController
@AllArgsConstructor
@RequestMapping("/menu")
@Tag(description = "menu", name = "菜单管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysMenuController {
private final SysMenuService sysMenuService;
/**
* 返回当前用户的树形菜单集合
* @param type 类型
* @param parentId 父节点ID
* @return 当前用户的树形菜单
*/
@GetMapping
public R getUserMenu(String type, Long parentId) {
// 获取符合条件的菜单
Set<SysMenu> all = new HashSet<>();
SecurityUtils.getRoles().forEach(roleId -> all.addAll(sysMenuService.findMenuByRoleId(roleId)));
return R.ok(sysMenuService.filterMenu(all, type, parentId));
}
/**
* 返回树形菜单集合
* @param parentId 父节点ID
* @param menuName 菜单名称
* @return 树形菜单
*/
@GetMapping(value = "/tree")
public R getTree(Long parentId, String menuName, String type) {
return R.ok(sysMenuService.treeMenu(parentId, menuName, type));
}
/**
* 返回角色的菜单集合
* @param roleId 角色ID
* @return 属性集合
*/
@GetMapping("/tree/{roleId}")
public R getRoleTree(@PathVariable Long roleId) {
return R.ok(
sysMenuService.findMenuByRoleId(roleId).stream().map(SysMenu::getMenuId).collect(Collectors.toList()));
}
/**
* 通过ID查询菜单的详细信息
* @param id 菜单ID
* @return 菜单详细信息
*/
@GetMapping("/{id}")
public R getById(@PathVariable Long id) {
return R.ok(sysMenuService.getById(id));
}
/**
* 新增菜单
* @param sysMenu 菜单信息
* @return success/false
*/
@SysLog("新增菜单")
@PostMapping
@PreAuthorize("@pms.hasPermission('sys_menu_add')")
public R save(@Valid @RequestBody SysMenu sysMenu) {
sysMenuService.save(sysMenu);
return R.ok(sysMenu);
}
/**
* 删除菜单
* @param id 菜单ID
* @return success/false
*/
@SysLog("删除菜单")
@DeleteMapping("/{id}")
@PreAuthorize("@pms.hasPermission('sys_menu_del')")
public R removeById(@PathVariable Long id) {
return sysMenuService.removeMenuById(id);
}
/**
* 更新菜单
* @param sysMenu
* @return
*/
@SysLog("更新菜单")
@PutMapping
@PreAuthorize("@pms.hasPermission('sys_menu_edit')")
public R update(@Valid @RequestBody SysMenu sysMenu) {
return R.ok(sysMenuService.updateMenuById(sysMenu));
}
}

View File

@@ -0,0 +1,167 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.admin.api.entity.SysPost;
import com.pig4cloud.pigx.admin.api.vo.PostExcelVO;
import com.pig4cloud.pigx.admin.service.SysPostService;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.excel.annotation.RequestExcel;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 岗位信息表
*
* @author fxz
* @date 2022-03-26 12:50:43
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/post")
@Tag(description = "post", name = "岗位信息表管理")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysPostController {
private final SysPostService sysPostService;
/**
* 获取岗位列表
* @return 岗位列表
*/
@GetMapping("/list")
public R<List<SysPost>> listPosts() {
return R.ok(sysPostService.list(Wrappers.emptyWrapper()));
}
/**
* 分页查询
* @param page 分页对象
* @param sysPost 岗位信息表
* @return
*/
@Operation(description = "分页查询", summary = "分页查询")
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('sys_post_view')")
public R getSysPostPage(@ParameterObject Page page, @ParameterObject SysPost sysPost) {
return R.ok(sysPostService.page(page, Wrappers.<SysPost>lambdaQuery()
.like(StrUtil.isNotBlank(sysPost.getPostName()), SysPost::getPostName, sysPost.getPostName())));
}
/**
* 通过id查询岗位信息表
* @param postId id
* @return R
*/
@Operation(description = "通过id查询", summary = "通过id查询")
@GetMapping("/details/{postId}")
@PreAuthorize("@pms.hasPermission('sys_post_view')")
public R getById(@PathVariable("postId") Long postId) {
return R.ok(sysPostService.getById(postId));
}
/**
* 查询岗位信息信息
* @param query 查询条件
* @return R
*/
@Operation(description = "查询角色信息", summary = "查询角色信息")
@GetMapping("/details")
@PreAuthorize("@pms.hasPermission('sys_post_view')")
public R getDetails(@ParameterObject SysPost query) {
return R.ok(sysPostService.getOne(Wrappers.query(query), false));
}
/**
* 新增岗位信息表
* @param sysPost 岗位信息表
* @return R
*/
@Operation(description = "新增岗位信息表", summary = "新增岗位信息表")
@SysLog("新增岗位信息表")
@PostMapping
@PreAuthorize("@pms.hasPermission('sys_post_add')")
public R save(@RequestBody SysPost sysPost) {
return R.ok(sysPostService.save(sysPost));
}
/**
* 修改岗位信息表
* @param sysPost 岗位信息表
* @return R
*/
@Operation(description = "修改岗位信息表", summary = "修改岗位信息表")
@SysLog("修改岗位信息表")
@PutMapping
@PreAuthorize("@pms.hasPermission('sys_post_edit')")
public R updateById(@RequestBody SysPost sysPost) {
return R.ok(sysPostService.updateById(sysPost));
}
/**
* 通过id删除岗位信息表
* @param ids id 列表
* @return R
*/
@Operation(description = "通过id删除岗位信息表", summary = "通过id删除岗位信息表")
@SysLog("通过id删除岗位信息表")
@DeleteMapping
@PreAuthorize("@pms.hasPermission('sys_post_del')")
public R removeById(@RequestBody Long[] ids) {
return R.ok(sysPostService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 导出excel 表格
* @return excel 文件流
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('sys_post_export')")
public List<PostExcelVO> export(SysPost post, Long[] ids) {
return sysPostService.listPost(post, ids);
}
/**
* 导入岗位
* @param excelVOList 岗位列表
* @param bindingResult 错误信息列表
* @return ok fail
*/
@PostMapping("/import")
@PreAuthorize("@pms.hasPermission('sys_post_export')")
public R importRole(@RequestExcel List<PostExcelVO> excelVOList, BindingResult bindingResult) {
return sysPostService.importPost(excelVOList, bindingResult);
}
}

View File

@@ -0,0 +1,179 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.controller;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.admin.api.entity.SysPublicParam;
import com.pig4cloud.pigx.admin.service.SysPublicParamService;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import com.pig4cloud.pigx.common.security.annotation.Inner;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 公共参数
*
* @author Lucky
* @date 2019-04-29
*/
@RestController
@AllArgsConstructor
@RequestMapping("/param")
@Tag(description = "param", name = "公共参数配置")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysPublicParamController {
private final SysPublicParamService sysPublicParamService;
/**
* 通过key查询公共参数值
* @param publicKey
* @return
*/
@Inner(value = false)
@Operation(description = "查询公共参数值", summary = "根据key查询公共参数值")
@GetMapping("/publicValue/{publicKey}")
public R publicKey(@PathVariable("publicKey") String publicKey) {
return R.ok(sysPublicParamService.getSysPublicParamKeyToValue(publicKey));
}
/**
* 通过key查询公共参数值
* @param keys
* @return
*/
@Inner(value = false)
@Operation(description = "查询公共参数值", summary = "根据key查询公共参数值")
@GetMapping("/publicValues")
public R publicKeys(String[] keys) {
return R.ok(sysPublicParamService.getSysPublicParamsKeyToValue(keys));
}
/**
* 分页查询
* @param page 分页对象
* @param sysPublicParam 公共参数
* @return
*/
@Operation(description = "分页查询", summary = "分页查询")
@GetMapping("/page")
public R getSysPublicParamPage(@ParameterObject Page page, @ParameterObject SysPublicParam sysPublicParam) {
LambdaUpdateWrapper<SysPublicParam> wrapper = Wrappers.<SysPublicParam>lambdaUpdate()
.like(StrUtil.isNotBlank(sysPublicParam.getPublicName()), SysPublicParam::getPublicName,
sysPublicParam.getPublicName())
.like(StrUtil.isNotBlank(sysPublicParam.getPublicKey()), SysPublicParam::getPublicKey,
sysPublicParam.getPublicKey())
.eq(StrUtil.isNotBlank(sysPublicParam.getSystemFlag()), SysPublicParam::getSystemFlag,
sysPublicParam.getSystemFlag());
return R.ok(sysPublicParamService.page(page, wrapper));
}
/**
* 通过id查询公共参数
* @param publicId id
* @return R
*/
@Operation(description = "通过id查询公共参数", summary = "通过id查询公共参数")
@GetMapping("/details/{publicId}")
public R getById(@PathVariable("publicId") Long publicId) {
return R.ok(sysPublicParamService.getById(publicId));
}
@GetMapping("/details")
public R getDetail(@ParameterObject SysPublicParam param) {
return R.ok(sysPublicParamService.getOne(Wrappers.query(param), false));
}
/**
* 新增公共参数
* @param sysPublicParam 公共参数
* @return R
*/
@Operation(description = "新增公共参数", summary = "新增公共参数")
@SysLog("新增公共参数")
@PostMapping
@PreAuthorize("@pms.hasPermission('sys_syspublicparam_add')")
public R save(@RequestBody SysPublicParam sysPublicParam) {
return R.ok(sysPublicParamService.save(sysPublicParam));
}
/**
* 修改公共参数
* @param sysPublicParam 公共参数
* @return R
*/
@Operation(description = "修改公共参数", summary = "修改公共参数")
@SysLog("修改公共参数")
@PutMapping
@PreAuthorize("@pms.hasPermission('sys_syspublicparam_edit')")
public R updateById(@RequestBody SysPublicParam sysPublicParam) {
return sysPublicParamService.updateParam(sysPublicParam);
}
/**
* 通过id删除公共参数
* @param publicId id
* @return R
*/
@Operation(description = "删除公共参数", summary = "删除公共参数")
@SysLog("删除公共参数")
@DeleteMapping
@PreAuthorize("@pms.hasPermission('sys_syspublicparam_del')")
public R removeById(@RequestBody Long[] ids) {
return R.ok(sysPublicParamService.removeParamByIds(ids));
}
/**
* 导出excel 表格
* @return
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('sys_syspublicparam_edit')")
public List<SysPublicParam> export(SysPublicParam param, Long[] ids) {
return sysPublicParamService
.list(Wrappers.lambdaQuery(param).in(ArrayUtil.isNotEmpty(ids), SysPublicParam::getPublicId, ids));
}
/**
* 同步参数
* @return R
*/
@SysLog("同步参数")
@PutMapping("/sync")
@PreAuthorize("@pms.hasPermission('sys_syspublicparam_edit')")
public R sync() {
return sysPublicParamService.syncParamCache();
}
}

View File

@@ -0,0 +1,188 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.admin.api.entity.SysRole;
import com.pig4cloud.pigx.admin.api.vo.RoleExcelVO;
import com.pig4cloud.pigx.admin.api.vo.RoleVO;
import com.pig4cloud.pigx.admin.service.SysRoleService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.excel.annotation.RequestExcel;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* @author lengleng
* @date 2020-02-10
*/
@RestController
@AllArgsConstructor
@RequestMapping("/role")
@Tag(description = "role", name = "角色管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysRoleController {
private final SysRoleService sysRoleService;
/**
* 通过ID查询角色信息
* @param id ID
* @return 角色信息
*/
@GetMapping("/details/{id}")
public R getById(@PathVariable Long id) {
return R.ok(sysRoleService.getById(id));
}
/**
* 查询角色信息
* @param query 查询条件
* @return 角色信息
*/
@GetMapping("/details")
public R getDetails(@ParameterObject SysRole query) {
return R.ok(sysRoleService.getOne(Wrappers.query(query), false));
}
/**
* 添加角色
* @param sysRole 角色信息
* @return success、false
*/
@SysLog("添加角色")
@PostMapping
@PreAuthorize("@pms.hasPermission('sys_role_add')")
@CacheEvict(value = CacheConstants.ROLE_DETAILS, allEntries = true)
public R save(@Valid @RequestBody SysRole sysRole) {
return R.ok(sysRoleService.save(sysRole));
}
/**
* 修改角色
* @param sysRole 角色信息
* @return success/false
*/
@SysLog("修改角色")
@PutMapping
@PreAuthorize("@pms.hasPermission('sys_role_edit')")
@CacheEvict(value = CacheConstants.ROLE_DETAILS, allEntries = true)
public R update(@Valid @RequestBody SysRole sysRole) {
return R.ok(sysRoleService.updateById(sysRole));
}
/**
* 删除角色
* @param ids
* @return
*/
@SysLog("删除角色")
@DeleteMapping
@PreAuthorize("@pms.hasPermission('sys_role_del')")
@CacheEvict(value = CacheConstants.ROLE_DETAILS, allEntries = true)
public R removeById(@RequestBody Long[] ids) {
return R.ok(sysRoleService.removeRoleByIds(ids));
}
/**
* 获取角色列表
* @return 角色列表
*/
@GetMapping("/list")
public R listRoles() {
return R.ok(sysRoleService.list(Wrappers.emptyWrapper()));
}
/**
* 分页查询角色信息
* @param page 分页对象
* @param role 查询条件
* @return 分页对象
*/
@GetMapping("/page")
public R getRolePage(Page page, SysRole role) {
return R.ok(sysRoleService.page(page, Wrappers.<SysRole>lambdaQuery()
.like(StrUtil.isNotBlank(role.getRoleName()), SysRole::getRoleName, role.getRoleName())));
}
/**
* 更新角色菜单
* @param roleVo 角色对象
* @return success、false
*/
@SysLog("更新角色菜单")
@PutMapping("/menu")
@PreAuthorize("@pms.hasPermission('sys_role_perm')")
public R saveRoleMenus(@RequestBody RoleVO roleVo) {
return R.ok(sysRoleService.updateRoleMenus(roleVo));
}
/**
* 通过角色ID 查询角色列表
* @param roleIdList 角色ID
* @return
*/
@PostMapping("/getRoleList")
public R getRoleList(@RequestBody List<Long> roleIdList) {
return R.ok(sysRoleService.findRolesByRoleIds(roleIdList, CollUtil.join(roleIdList, StrUtil.UNDERLINE)));
}
/**
* 导出excel 表格
* @param sysRole 查询条件
* @param ids 导出ids
* @return
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('sys_role_export')")
public List<RoleExcelVO> export(SysRole sysRole, Long[] ids) {
return sysRoleService.listRole(sysRole, ids);
}
/**
* 导入角色
* @param excelVOList 角色列表
* @param bindingResult 错误信息列表
* @return ok fail
*/
@PostMapping("/import")
@PreAuthorize("@pms.hasPermission('sys_role_export')")
public R importRole(@RequestExcel List<RoleExcelVO> excelVOList, BindingResult bindingResult) {
return sysRoleService.importRole(excelVOList, bindingResult);
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.controller;
import cn.hutool.json.JSONArray;
import com.pig4cloud.pigx.admin.service.SysRouteConfService;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
/**
* 路由
*
* @author lengleng
* @date 2018-11-06 10:17:18
*/
@RestController
@AllArgsConstructor
@RequestMapping("/route")
@Tag(description = "route", name = "动态路由管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysRouteConfController {
private final SysRouteConfService sysRouteConfService;
/**
* 获取当前定义的路由信息
* @return
*/
@GetMapping
public R listRoutes() {
return R.ok(sysRouteConfService.list());
}
/**
* 修改路由
* @param routes 路由定义
* @return
*/
@SysLog("修改路由")
@PutMapping
public R updateRoutes(@RequestBody JSONArray routes) {
return R.ok(sysRouteConfService.updateRoutes(routes));
}
}

View File

@@ -0,0 +1,130 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.controller;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.admin.api.entity.SysScheduleEntity;
import com.pig4cloud.pigx.admin.service.SysScheduleService;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 日程
*
* @author aeizzz
* @date 2023-03-06 14:26:23
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/schedule")
@Tag(description = "schedule", name = "日程管理")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysScheduleController {
private final SysScheduleService sysScheduleService;
/**
* 分页查询
* @param page 分页对象
* @param sysSchedule 日程
* @return
*/
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
public R getSchedulePage(@ParameterObject Page page, @ParameterObject SysScheduleEntity sysSchedule) {
return R.ok(sysScheduleService.getScheduleByScope(page, sysSchedule));
}
/**
* 通过id查询日程
* @param id id
* @return R
*/
@Operation(summary = "通过id查询", description = "通过id查询")
@GetMapping("/{id}")
public R getById(@PathVariable("id") Long id) {
return R.ok(sysScheduleService.getById(id));
}
/**
* 新增日程
* @param sysSchedule 日程
* @return R
*/
@Operation(summary = "新增日程", description = "新增日程")
@SysLog("新增日程")
@PostMapping
public R save(@RequestBody SysScheduleEntity sysSchedule) {
return R.ok(sysScheduleService.save(sysSchedule));
}
/**
* 修改日程
* @param sysSchedule 日程
* @return R
*/
@Operation(summary = "修改日程", description = "修改日程")
@SysLog("修改日程")
@PutMapping
public R updateById(@RequestBody SysScheduleEntity sysSchedule) {
return R.ok(sysScheduleService.updateById(sysSchedule));
}
/**
* 通过id删除日程
* @param ids id列表
* @return R
*/
@Operation(summary = "通过id删除日程", description = "通过id删除日程")
@SysLog("通过id删除日程")
@DeleteMapping
public R removeById(@RequestBody Long[] ids) {
return R.ok(sysScheduleService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 导出excel 表格
* @param sysSchedule 查询条件
* @return excel 文件流
*/
@ResponseExcel
@GetMapping("/export")
public List<SysScheduleEntity> export(SysScheduleEntity sysSchedule) {
return sysScheduleService.list(Wrappers.query(sysSchedule));
}
@Operation(summary = "列表查询", description = "列表查询")
@GetMapping("/list")
public R list(String month) {
List<SysScheduleEntity> list = sysScheduleService.selectListByScope(month);
return R.ok(list);
}
}

View File

@@ -0,0 +1,152 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
import com.pig4cloud.pigx.admin.service.SysSocialDetailsService;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.core.util.ValidGroup;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import com.pig4cloud.pigx.common.security.annotation.Inner;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* 系统社交登录账号表
*
* @author lengleng
* @date 2018-08-16 21:30:41
*/
@RestController
@RequestMapping("/social")
@AllArgsConstructor
@Tag(description = "social", name = "三方账号管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysSocialDetailsController {
private final SysSocialDetailsService sysSocialDetailsService;
/**
* 社交登录账户简单分页查询
* @param page 分页对象
* @param sysSocialDetails 社交登录
* @return
*/
@GetMapping("/page")
public R getSocialDetailsPage(@ParameterObject Page page, @ParameterObject SysSocialDetails sysSocialDetails) {
return R.ok(sysSocialDetailsService.page(page, Wrappers.query(sysSocialDetails)));
}
/**
* 信息
* @param type 类型
* @return R
*/
@GetMapping("/{type}")
public R getByType(@PathVariable("type") String type) {
return R.ok(sysSocialDetailsService
.list(Wrappers.<SysSocialDetails>lambdaQuery().eq(SysSocialDetails::getType, type)));
}
@GetMapping("/getById/{id}")
public R info(@PathVariable("id") Long id) {
return R.ok(sysSocialDetailsService.getById(id));
}
/**
* 保存
* @param sysSocialDetails
* @return R
*/
@SysLog("保存三方信息")
@PostMapping
@PreAuthorize("@pms.hasPermission('sys_social_details_add')")
public R save(@Valid @RequestBody SysSocialDetails sysSocialDetails) {
return R.ok(sysSocialDetailsService.save(sysSocialDetails));
}
/**
* 修改
* @param sysSocialDetails
* @return R
*/
@SysLog("修改三方信息")
@PutMapping
@PreAuthorize("@pms.hasPermission('sys_social_details_edit')")
public R updateById(@Validated({ ValidGroup.Update.class }) @RequestBody SysSocialDetails sysSocialDetails) {
sysSocialDetailsService.updateById(sysSocialDetails);
return R.ok(Boolean.TRUE);
}
/**
* 删除
* @param ids id 列表
* @return R
*/
@SysLog("删除三方信息")
@DeleteMapping
@PreAuthorize("@pms.hasPermission('sys_social_details_del')")
public R removeById(@RequestBody Long[] ids) {
return R.ok(sysSocialDetailsService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 通过社交账号、手机号查询用户、角色信息
* @param inStr appid@code
* @return
*/
@Inner
@GetMapping("/info/{inStr}")
public R getUserInfo(@PathVariable String inStr) {
return R.ok(sysSocialDetailsService.getUserInfo(inStr));
}
/**
* 绑定社交账号
* @param state 类型
* @param code code
* @return
*/
@PostMapping("/bind")
public R bindSocial(String state, String code) {
return R.ok(sysSocialDetailsService.bindSocial(state, code));
}
/**
* 导出
*/
@GetMapping("/export")
public List<SysSocialDetails> export(SysSocialDetails sysSocialDetails, Long[] ids) {
return sysSocialDetailsService.list(
Wrappers.lambdaQuery(sysSocialDetails).in(ArrayUtil.isNotEmpty(ids), SysSocialDetails::getId, ids));
}
}

View File

@@ -0,0 +1,59 @@
package com.pig4cloud.pigx.admin.controller;
import com.pig4cloud.pigx.common.core.util.R;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
@RestController
@RequestMapping("/system")
@RequiredArgsConstructor
@Tag(description = "system", name = "系统监控")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysSystemInfoController {
private final RedisTemplate<String, String> redisTemplate;
/**
* 缓存监控
* @return R<Object>
*/
@GetMapping("/cache")
public R cache() {
Properties info = (Properties) redisTemplate.execute((RedisCallback<Object>) RedisServerCommands::info);
Properties commandStats = (Properties) redisTemplate
.execute((RedisCallback<Object>) connection -> connection.info("commandstats"));
Object dbSize = redisTemplate.execute((RedisCallback<Object>) RedisServerCommands::dbSize);
if (commandStats == null) {
return R.failed("获取异常");
}
Map<String, Object> result = new HashMap<>(3);
result.put("info", info);
result.put("dbSize", dbSize);
List<Map<String, String>> pieList = new ArrayList<>();
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);
});
result.put("commandStats", pieList);
return R.ok(result);
}
}

View File

@@ -0,0 +1,175 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.admin.api.entity.SysTenant;
import com.pig4cloud.pigx.admin.service.SysMenuService;
import com.pig4cloud.pigx.admin.service.SysTenantService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.data.resolver.ParamResolver;
import com.pig4cloud.pigx.common.data.tenant.TenantBroker;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import com.pig4cloud.pigx.common.security.annotation.Inner;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 租户管理
*
* @author lengleng
* @date 2019-05-15 15:55:41
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/tenant")
@Tag(description = "tenant", name = "租户管理")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysTenantController {
private final SysTenantService sysTenantService;
private final SysMenuService sysMenuService;
/**
* 分页查询
* @param page 分页对象
* @param sysTenant 租户
* @return
*/
@GetMapping("/page")
public R getSysTenantPage(@ParameterObject Page page, @ParameterObject SysTenant sysTenant) {
return R.ok(sysTenantService.page(page, Wrappers.<SysTenant>lambdaQuery()
.like(StrUtil.isNotBlank(sysTenant.getName()), SysTenant::getName, sysTenant.getName())));
}
/**
* 通过ID 查询租户信息
* @param id ID
* @return R
*/
@GetMapping("/details/{id}")
public R getById(@PathVariable Long id) {
return R.ok(sysTenantService.getById(id));
}
/**
* 查询租户信息
* @param query 查询条件
* @return 租户信息
*/
@GetMapping("/details")
public R getDetails(@ParameterObject SysTenant query) {
return R.ok(sysTenantService.getOne(Wrappers.query(query), false));
}
/**
* 新增租户
* @param sysTenant 租户
* @return R
*/
@SysLog("新增租户")
@PostMapping
@PreAuthorize("@pms.hasPermission('sys_systenant_add')")
@CacheEvict(value = CacheConstants.TENANT_DETAILS, allEntries = true)
public R save(@RequestBody SysTenant sysTenant) {
return R.ok(sysTenantService.saveTenant(sysTenant));
}
/**
* 修改租户
* @param sysTenant 租户
* @return R
*/
@SysLog("修改租户")
@PutMapping
@PreAuthorize("@pms.hasPermission('sys_systenant_edit')")
public R updateById(@RequestBody SysTenant sysTenant) {
return R.ok(sysTenantService.updateTenant(sysTenant));
}
/**
* 通过id删除租户
* <p>
* 为了保证安全,这里只删除租户表的数据,不删除基础表中的租户初始化数据。
* @param ids id 列表
* @return R
*/
@SysLog("删除租户")
@DeleteMapping
@PreAuthorize("@pms.hasPermission('sys_systenant_del')")
@CacheEvict(value = CacheConstants.TENANT_DETAILS, allEntries = true)
public R removeById(@RequestBody Long[] ids) {
return R.ok(sysTenantService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 查询全部有效的租户
* @return
*/
@Inner(value = false)
@GetMapping("/list")
public R list() {
List<SysTenant> tenants = sysTenantService.getNormalTenant().stream()
.filter(tenant -> tenant.getStartTime().isBefore(LocalDateTime.now()))
.filter(tenant -> tenant.getEndTime().isAfter(LocalDateTime.now())).collect(Collectors.toList());
return R.ok(tenants);
}
/**
* 导出excel 表格
* @return
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('sys_systenant_export')")
public List<SysTenant> export(SysTenant sysTenant, Long[] ids) {
return sysTenantService
.list(Wrappers.lambdaQuery(sysTenant).in(ArrayUtil.isNotEmpty(ids), SysTenant::getId, ids));
}
@GetMapping(value = "/tree/menu")
public R getTree() {
Long defaultId = ParamResolver.getLong("TENANT_DEFAULT_ID", 1L);
List<Tree<Long>> trees = new ArrayList<>();
TenantBroker.runAs(defaultId, (id) -> {
trees.addAll(sysMenuService.treeMenu(null, null, null));
});
return R.ok(trees);
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.controller;
import com.pig4cloud.pigx.admin.api.feign.RemoteTokenService;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* @author lengleng
* @date 2018/9/4 getTokenPage 管理
*/
@RestController
@AllArgsConstructor
@RequestMapping("/token")
@Tag(description = "token", name = "令牌管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysTokenController {
private final RemoteTokenService remoteTokenService;
/**
* 分页token 信息
* @param params 参数集
* @return token集合
*/
@RequestMapping("/page")
public R getTokenPage(@RequestBody Map<String, Object> params) {
return remoteTokenService.getTokenPage(params, SecurityConstants.FROM_IN);
}
/**
* 删除
* @param token getTokenPage
* @return success/false
*/
@SysLog("删除用户token")
@DeleteMapping("/delete")
@PreAuthorize("@pms.hasPermission('sys_token_del')")
public R removeById(@RequestBody String[] tokens) {
for (String token : tokens) {
remoteTokenService.removeTokenById(token, SecurityConstants.FROM_IN);
}
return R.ok();
}
}

View File

@@ -0,0 +1,279 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.controller;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.admin.api.dto.UserDTO;
import com.pig4cloud.pigx.admin.api.entity.SysUser;
import com.pig4cloud.pigx.admin.api.vo.UserExcelVO;
import com.pig4cloud.pigx.admin.service.SysUserService;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.excel.annotation.RequestExcel;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import com.pig4cloud.pigx.common.security.annotation.Inner;
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* @author lengleng
* @date 2018/12/16
*/
@RestController
@AllArgsConstructor
@RequestMapping("/user")
@Tag(description = "user", name = "用户管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysUserController {
private final SysUserService userService;
/**
* 获取指定用户全部信息
* @return 用户信息
*/
@Inner
@GetMapping("/info/{username}")
public R info(@PathVariable String username) {
SysUser user = userService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getUsername, username));
if (user == null) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERINFO_EMPTY, username));
}
return R.ok(userService.findUserInfo(user));
}
/**
* 获取当前用户全部信息
* @return 用户信息
*/
@GetMapping(value = { "/info" })
public R info() {
String username = SecurityUtils.getUser().getUsername();
SysUser user = userService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getUsername, username));
if (user == null) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_QUERY_ERROR));
}
return R.ok(userService.findUserInfo(user));
}
/**
* 通过ID查询用户信息
* @param id ID
* @return 用户信息
*/
@GetMapping("/details/{id}")
public R user(@PathVariable Long id) {
return R.ok(userService.selectUserVoById(id));
}
/**
* 查询用户信息
* @param query 查询条件
* @return 不为空返回用户名
*/
@Inner(value = false)
@GetMapping("/details")
public R getDetails(@ParameterObject SysUser query) {
SysUser sysUser = userService.getOne(Wrappers.query(query), false);
return R.ok(sysUser == null ? null : CommonConstants.SUCCESS);
}
/**
* 删除用户信息
* @param ids ID
* @return R
*/
@SysLog("删除用户信息")
@DeleteMapping
@PreAuthorize("@pms.hasPermission('sys_user_del')")
@Operation(summary = "删除用户", description = "根据ID删除用户")
public R userDel(@RequestBody Long[] ids) {
return R.ok(userService.deleteUserByIds(ids));
}
/**
* 添加用户
* @param userDto 用户信息
* @return success/false
*/
@SysLog("添加用户")
@PostMapping
@PreAuthorize("@pms.hasPermission('sys_user_add')")
public R user(@RequestBody UserDTO userDto) {
return R.ok(userService.saveUser(userDto));
}
/**
* 分页查询用户
* @param page 参数集
* @param userDTO 查询参数列表
* @return 用户集合
*/
@GetMapping("/page")
public R getUserPage(@ParameterObject Page page, @ParameterObject UserDTO userDTO) {
return R.ok(userService.getUsersWithRolePage(page, userDTO));
}
/**
* 管理员更新用户信息
* @param userDto 用户信息
* @return R
*/
@SysLog("更新用户信息")
@PutMapping
@PreAuthorize("@pms.hasPermission('sys_user_edit')")
public R updateUser(@Valid @RequestBody UserDTO userDto) {
return R.ok(userService.updateUser(userDto));
}
/**
* 修改个人信息 (当前用户)
* @param userDto userDto
* @return success/false
*/
@SysLog("修改个人信息")
@PutMapping("/personal/edit")
public R updateUserInfo(@Valid @RequestBody UserDTO userDto) {
return userService.updateUserInfo(userDto);
}
/**
* 修改个人密码 (当前用户)
* @param userDto 用户DTO对象包含需要修改密码的用户信息
* @return R 返回结果对象,包含修改密码操作的结果信息
*/
@PutMapping("/personal/password")
public R updatePassword(@RequestBody UserDTO userDto) {
String username = SecurityUtils.getUser().getUsername();
userDto.setUsername(username);
return userService.changePassword(userDto);
}
/**
* @param username 用户名称
* @return 上级部门用户列表
*/
@GetMapping("/ancestor/{username}")
public R listAncestorUsers(@PathVariable String username) {
return R.ok(userService.listAncestorUsers(username));
}
/**
* 导出excel 表格
* @param userDTO 查询条件
* @return
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('sys_user_export')")
public List export(UserDTO userDTO, Long[] ids) {
return userService.listUser(userDTO, ids);
}
/**
* 导入用户
* @param excelVOList 用户列表
* @param bindingResult 错误信息列表
* @return R
*/
@PostMapping("/import")
@PreAuthorize("@pms.hasPermission('sys_user_export')")
public R importUser(@RequestExcel List<UserExcelVO> excelVOList, BindingResult bindingResult) {
return userService.importUser(excelVOList, bindingResult);
}
/**
* 锁定指定用户
* @param username 用户名
* @return R
*/
@Inner
@PutMapping("/lock/{username}")
public R lockUser(@PathVariable String username) {
return userService.lockUser(username);
}
/**
* 解绑定接口
* @param type 需要解绑定的类型
* @return R 返回结果对象,包含解绑定操作的结果信息
*/
@PostMapping("/unbinding")
public R unbinding(String type) {
return userService.unbinding(type);
}
/**
* 校验密码接口
* @param password 需要校验的密码
* @return R 返回结果对象,包含校验密码操作的结果信息
*/
@PostMapping("/check")
public R check(String password) {
return userService.checkPassword(password);
}
/**
* 根据角色ID列表获取用户ID列表接口
* @param roleIdList 角色ID列表
* @return R 返回结果对象包含根据角色ID列表获取到的用户ID列表信息
*/
@GetMapping("/getUserIdListByRoleIdList")
public R<List<Long>> getUserIdListByRoleIdList(Long[] roleIdList) {
return R.ok(userService.listUserIdByRoleIds(CollUtil.toList(roleIdList)));
}
/**
* 根据部门ID列表获取用户ID列表接口
* @param deptIdList 部门ID列表
* @return R 返回结果对象包含根据部门ID列表获取到的用户ID列表信息
*/
@GetMapping("/getUserIdListByDeptIdList")
public R<List<SysUser>> getUserIdListByDeptIdList(Long[] deptIdList) {
return R.ok(userService.listUserIdByDeptIds(CollUtil.toList(deptIdList)));
}
/**
* 根据用户名获取用户列表
* @param username 用户名
* @return 用户列表
*/
@GetMapping("/getUserListByUserName")
public R<List<SysUser>> getUserListByUserName(String username) {
return R.ok(userService.list(Wrappers.<SysUser>lambdaQuery().like(SysUser::getUsername, username)));
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.handler;
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
/**
* @author lengleng
* @date 2018/11/18
*/
public abstract class AbstractLoginHandler implements LoginHandler {
/***
* 数据合法性校验
* @param loginStr 通过用户传入获取唯一标识
* @return 默认不校验
*/
@Override
public Boolean check(String loginStr) {
return true;
}
/**
* 处理方法
* @param loginStr 登录参数
* @return
*/
@Override
public UserInfo handle(String loginStr) {
if (!check(loginStr)) {
return null;
}
String identify = identify(loginStr);
return info(identify);
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.handler;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
import com.pig4cloud.pigx.admin.api.entity.SysUser;
import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper;
import com.pig4cloud.pigx.admin.service.SysUserService;
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.jasig.cas.client.validation.Assertion;
import org.jasig.cas.client.validation.Cas30ProxyTicketValidator;
import org.springframework.stereotype.Component;
/**
* @author lengleng
* @date 2018/11/18
*/
@Slf4j
@Component("CAS")
@AllArgsConstructor
public class CasLoginHandler extends AbstractLoginHandler {
private final SysSocialDetailsMapper sysSocialDetailsMapper;
private final SysUserService sysUserService;
/**
* cas 回到的ticket
* <p>
* 通过ticket 调用CAS获取唯一标识
* @param ticket
* @return
*/
@Override
@SneakyThrows
public String identify(String ticket) {
SysSocialDetails condition = new SysSocialDetails();
condition.setType(LoginTypeEnum.CAS.getType());
SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition));
// remark 字段填写 CAS 服务器的URL
Cas30ProxyTicketValidator cas30ProxyTicketValidator = new Cas30ProxyTicketValidator(socialDetails.getRemark());
Assertion validate = cas30ProxyTicketValidator.validate(ticket, socialDetails.getRedirectUrl());
return validate.getPrincipal().getName();
}
/**
* username 获取用户信息
* @param username
* @return
*/
@Override
public UserInfo info(String username) {
SysUser user = sysUserService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getUsername, username));
if (user == null) {
log.info("CAS 不存在用户:{}", username);
return null;
}
return sysUserService.findUserInfo(user);
}
}

View File

@@ -0,0 +1,112 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.handler;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
import com.pig4cloud.pigx.admin.api.entity.SysUser;
import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper;
import com.pig4cloud.pigx.admin.service.SysUserService;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.HashMap;
/**
* @author lengleng
* @date 2019/4/8
* <p>
* 码云登录
*/
@Slf4j
@Component("GITEE")
@AllArgsConstructor
public class GiteeLoginHandler extends AbstractLoginHandler {
private final SysSocialDetailsMapper sysSocialDetailsMapper;
private final SysUserService sysUserService;
/**
* 码云登录传入code
* <p>
* 通过code 调用qq 获取唯一标识
* @param code
* @return
*/
@Override
public String identify(String code) {
SysSocialDetails condition = new SysSocialDetails();
condition.setType(LoginTypeEnum.GITEE.getType());
SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition));
String url = String.format(SecurityConstants.GITEE_AUTHORIZATION_CODE_URL, code, socialDetails.getAppId(),
URLUtil.encode(socialDetails.getRedirectUrl()), socialDetails.getAppSecret());
String result = HttpUtil.post(url, new HashMap<>(0));
log.debug("码云响应报文:{}", result);
String accessToken = JSONUtil.parseObj(result).getStr("access_token");
String userUrl = String.format(SecurityConstants.GITEE_USER_INFO_URL, accessToken);
String resp = HttpUtil.get(userUrl);
log.debug("码云获取个人信息返回报文{}", resp);
JSONObject userInfo = JSONUtil.parseObj(resp);
// 码云唯一标识
return userInfo.getStr("login");
}
/**
* identify 获取用户信息
* @param identify identify
* @return
*/
@Override
public UserInfo info(String identify) {
SysUser user = sysUserService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getGiteeLogin, identify));
if (user == null) {
log.info("码云未绑定:{}", identify);
return null;
}
return sysUserService.findUserInfo(user);
}
/**
* 绑定逻辑
* @param user 用户实体
* @param identify 渠道返回唯一标识
* @return
*/
@Override
public Boolean bind(SysUser user, String identify) {
user.setGiteeLogin(identify);
sysUserService.updateById(user);
return true;
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.handler;
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
import com.pig4cloud.pigx.admin.api.entity.SysUser;
/**
* @author lengleng
* @date 2018/11/18
* <p>
* 登录处理器
*/
public interface LoginHandler {
/***
* 数据合法性校验
* @param loginStr 通过用户传入获取唯一标识
* @return
*/
Boolean check(String loginStr);
/**
* 通过用户传入获取唯一标识
* @param loginStr
* @return
*/
String identify(String loginStr);
/**
* 通过openId 获取用户信息
* @param identify
* @return
*/
UserInfo info(String identify);
/**
* 处理方法
* @param loginStr 登录参数
* @return
*/
UserInfo handle(String loginStr);
/**
* 绑定逻辑
* @param user 用户实体
* @param identify 渠道返回唯一标识
* @return
*/
default Boolean bind(SysUser user, String identify) {
return false;
}
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.handler;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
import com.pig4cloud.pigx.admin.api.entity.SysUser;
import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper;
import com.pig4cloud.pigx.admin.service.SysUserService;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author lengleng
* @date 2019年11月02日
* <p>
* 微信小程序
*/
@Slf4j
@Component("MINI")
@AllArgsConstructor
public class MiniAppLoginHandler extends AbstractLoginHandler {
private final SysUserService sysUserService;
private final SysSocialDetailsMapper sysSocialDetailsMapper;
/**
* 小程序登录传入code
* <p>
* 通过code 调用qq 获取唯一标识
* @param code
* @return
*/
@Override
public String identify(String code) {
SysSocialDetails condition = new SysSocialDetails();
condition.setType(LoginTypeEnum.MINI_APP.getType());
SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition));
String url = String.format(SecurityConstants.MINI_APP_AUTHORIZATION_CODE_URL, socialDetails.getAppId(),
socialDetails.getAppSecret(), code);
String result = HttpUtil.get(url);
log.debug("微信小程序响应报文:{}", result);
Object obj = JSONUtil.parseObj(result).get("openid");
return obj.toString();
}
/**
* openId 获取用户信息
* @param openId
* @return
*/
@Override
public UserInfo info(String openId) {
SysUser user = sysUserService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getMiniOpenid, openId));
if (user == null) {
log.info("微信小程序未绑定:{}", openId);
return null;
}
return sysUserService.findUserInfo(user);
}
/**
* 绑定逻辑
* @param user 用户实体
* @param identify 渠道返回唯一标识
* @return
*/
@Override
public Boolean bind(SysUser user, String identify) {
user.setMiniOpenid(identify);
sysUserService.updateById(user);
return true;
}
}

View File

@@ -0,0 +1,121 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.handler;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
import com.pig4cloud.pigx.admin.api.entity.SysUser;
import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper;
import com.pig4cloud.pigx.admin.service.SysUserService;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* @author lengleng
* @date 2019/4/8
* <p>
* 开源中国登录
*/
@Slf4j
@Component("OSC")
@AllArgsConstructor
public class OscChinaLoginHandler extends AbstractLoginHandler {
private final SysSocialDetailsMapper sysSocialDetailsMapper;
private final SysUserService sysUserService;
/**
* 开源中国传入code
* <p>
* 通过code 调用qq 获取唯一标识
* @param code
* @return
*/
@Override
public String identify(String code) {
SysSocialDetails condition = new SysSocialDetails();
condition.setType(LoginTypeEnum.OSC.getType());
SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition));
Map<String, Object> params = new HashMap<>(8);
params.put("client_id", socialDetails.getAppId());
params.put("client_secret", socialDetails.getAppSecret());
params.put("grant_type", "authorization_code");
params.put("redirect_uri", socialDetails.getRedirectUrl());
params.put("code", code);
params.put("dataType", "json");
String result = HttpUtil.post(SecurityConstants.OSC_AUTHORIZATION_CODE_URL, params);
log.debug("开源中国响应报文:{}", result);
String accessToken = JSONUtil.parseObj(result).getStr("access_token");
String url = String.format(SecurityConstants.OSC_USER_INFO_URL, accessToken);
String resp = HttpUtil.get(url);
log.debug("开源中国获取个人信息返回报文{}", resp);
JSONObject userInfo = JSONUtil.parseObj(resp);
// 开源中国唯一标识
String id = userInfo.getStr("id");
return id;
}
/**
* identify 获取用户信息
* @param identify 开源中国表示
* @return
*/
@Override
public UserInfo info(String identify) {
SysUser user = sysUserService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getOscId, identify));
if (user == null) {
log.info("开源中国未绑定:{}", identify);
return null;
}
return sysUserService.findUserInfo(user);
}
/**
* 绑定逻辑
* @param user 用户实体
* @param identify 渠道返回唯一标识
* @return
*/
@Override
public Boolean bind(SysUser user, String identify) {
user.setOscId(identify);
sysUserService.updateById(user);
return true;
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.handler;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
import com.pig4cloud.pigx.admin.api.entity.SysUser;
import com.pig4cloud.pigx.admin.service.SysUserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author lengleng
* @date 2018/11/18
*/
@Slf4j
@Component("SMS")
@AllArgsConstructor
public class SmsLoginHandler extends AbstractLoginHandler {
private final SysUserService sysUserService;
/**
* 验证码登录传入为手机号 不用不处理
* @param mobile
* @return
*/
@Override
public String identify(String mobile) {
return mobile;
}
/**
* 通过mobile 获取用户信息
* @param identify
* @return
*/
@Override
public UserInfo info(String identify) {
SysUser user = sysUserService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getPhone, identify));
if (user == null) {
log.info("手机号未注册:{}", identify);
return null;
}
return sysUserService.findUserInfo(user);
}
/**
* 绑定逻辑
* @param user 用户实体
* @param identify 渠道返回唯一标识
* @return
*/
@Override
public Boolean bind(SysUser user, String identify) {
user.setPhone(identify);
sysUserService.updateById(user);
return true;
}
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.handler;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
import com.pig4cloud.pigx.admin.api.entity.SysUser;
import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper;
import com.pig4cloud.pigx.admin.service.SysUserService;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author lengleng
* @date 2018/11/18
*/
@Slf4j
@Component("QQ")
@AllArgsConstructor
public class TencentLoginHandler extends AbstractLoginHandler {
private final SysUserService sysUserService;
private final SysSocialDetailsMapper sysSocialDetailsMapper;
/**
* QQ登录传入code
* <p>
* 通过code 调用qq 获取唯一标识
* @param code
* @return
*/
@Override
public String identify(String code) {
SysSocialDetails condition = new SysSocialDetails();
condition.setType(LoginTypeEnum.QQ.getType());
SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition));
String url = String.format(SecurityConstants.QQ_AUTHORIZATION_CODE_URL, socialDetails.getAppId(),
socialDetails.getAppSecret(), code);
String result = HttpUtil.get(url);
log.debug("QQ响应报文:{}", result);
String accessToken = JSONUtil.parseObj(result).getStr("access_token");
String userUrl = String.format(SecurityConstants.QQ_USER_INFO_URL, accessToken);
String resp = HttpUtil.get(userUrl);
log.debug("QQ获取个人信息返回报文{}", resp);
JSONObject userInfo = JSONUtil.parseObj(resp);
// QQ唯一标识
String openid = userInfo.getStr("openid");
return openid;
}
/**
* openId 获取用户信息
* @param openId
* @return
*/
@Override
public UserInfo info(String openId) {
SysUser user = sysUserService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getQqOpenid, openId));
if (user == null) {
log.info("QQ未绑定:{}", openId);
return null;
}
return sysUserService.findUserInfo(user);
}
/**
* 绑定逻辑
* @param user 用户实体
* @param identify 渠道返回唯一标识
* @return
*/
@Override
public Boolean bind(SysUser user, String identify) {
user.setQqOpenid(identify);
sysUserService.updateById(user);
return true;
}
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.handler;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
import com.pig4cloud.pigx.admin.api.entity.SysUser;
import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper;
import com.pig4cloud.pigx.admin.service.SysUserService;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author lengleng
* @date 2018/11/18
*/
@Slf4j
@Component("WX")
@AllArgsConstructor
public class WeChatLoginHandler extends AbstractLoginHandler {
private final SysUserService sysUserService;
private final SysSocialDetailsMapper sysSocialDetailsMapper;
/**
* 微信登录传入code
* <p>
* 通过code 调用qq 获取唯一标识
* @param code
* @return
*/
@Override
public String identify(String code) {
SysSocialDetails condition = new SysSocialDetails();
condition.setType(LoginTypeEnum.WECHAT.getType());
SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition));
String url = String.format(SecurityConstants.WX_AUTHORIZATION_CODE_URL, socialDetails.getAppId(),
socialDetails.getAppSecret(), code);
String result = HttpUtil.get(url);
log.debug("微信响应报文:{}", result);
Object obj = JSONUtil.parseObj(result).get("openid");
return obj.toString();
}
/**
* openId 获取用户信息
* @param openId
* @return
*/
@Override
public UserInfo info(String openId) {
SysUser user = sysUserService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getWxOpenid, openId));
if (user == null) {
log.info("微信未绑定:{}", openId);
return null;
}
return sysUserService.findUserInfo(user);
}
/**
* 绑定逻辑
* @param user 用户实体
* @param identify 渠道返回唯一标识
* @return
*/
@Override
public Boolean bind(SysUser user, String identify) {
user.setWxOpenid(identify);
sysUserService.updateById(user);
return true;
}
}

View File

@@ -0,0 +1,95 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.handler;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
import com.pig4cloud.pigx.admin.api.entity.SysUser;
import com.pig4cloud.pigx.admin.service.ConnectService;
import com.pig4cloud.pigx.admin.service.SysUserService;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
import me.chanjar.weixin.cp.bean.WxCpOauth2UserInfo;
import org.springframework.stereotype.Component;
/**
* @author lengleng
* @date 2022/7/19
*
* 企业微信免密登录
*/
@Slf4j
@Component("WEIXIN_CP")
@AllArgsConstructor
public class WxCpLoginHandler extends AbstractLoginHandler {
private ConnectService connectService;
private final SysUserService sysUserService;
/**
* 微信登录传入code
* <p>
* 通过code 调用qq 获取唯一标识
* @param code
* @return
*/
@Override
@SneakyThrows
public String identify(String code) {
WxCpService wxCpService = new WxCpServiceImpl();
wxCpService.setWxCpConfigStorage(connectService.getCpConfig());
WxCpOauth2UserInfo userInfo = wxCpService.getOauth2Service().getUserInfo(code);
log.info("企业微信返回报文:{}", userInfo);
return userInfo.getUserId();
}
/**
* openId 获取用户信息
* @param openId
* @return
*/
@Override
public UserInfo info(String openId) {
SysUser user = sysUserService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getWxOpenid, openId));
if (user == null) {
log.info("企业微信未绑定:{}", openId);
return null;
}
return sysUserService.findUserInfo(user);
}
/**
* 绑定逻辑
* @param user 用户实体
* @param identify 渠道返回唯一标识
* @return
*/
@Override
public Boolean bind(SysUser user, String identify) {
user.setWxOpenid(identify);
sysUserService.updateById(user);
return true;
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysAuditLog;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 审计记录表
*
* @author PIG
* @date 2023-02-28 20:12:23
*/
@Mapper
public interface SysAuditLogMapper extends PigxBaseMapper<SysAuditLog> {
}

View File

@@ -0,0 +1,37 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysDept;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 部门管理 Mapper 接口
* </p>
*
* @author lengleng
* @since 2018-01-20
*/
@Mapper
public interface SysDeptMapper extends PigxBaseMapper<SysDept> {
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysDictItem;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 字典项
*
* @author lengleng
* @date 2019/03/19
*/
@Mapper
public interface SysDictItemMapper extends PigxBaseMapper<SysDictItem> {
}

View File

@@ -0,0 +1,37 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysDict;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 字典表 Mapper 接口
* </p>
*
* @author lengleng
* @since 2017-11-19
*/
@Mapper
public interface SysDictMapper extends PigxBaseMapper<SysDict> {
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysFileGroup;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 文件分组管理
*
* @author lbw
* @date 2023年07月25日21:31:48
*/
@Mapper
public interface SysFileGroupMapper extends PigxBaseMapper<SysFileGroup> {
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysFile;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 文件管理
*
* @author Luckly
* @date 2019-06-18 17:18:42
*/
@Mapper
public interface SysFileMapper extends PigxBaseMapper<SysFile> {
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysI18nEntity;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 系统表-国际化
*
* @author PIG
* @date 2023-02-14 09:07:01
*/
@Mapper
public interface SysI18nMapper extends PigxBaseMapper<SysI18nEntity> {
}

View File

@@ -0,0 +1,37 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysLog;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 日志表 Mapper 接口
* </p>
*
* @author lengleng
* @since 2017-11-20
*/
@Mapper
public interface SysLogMapper extends PigxBaseMapper<SysLog> {
}

View File

@@ -0,0 +1,53 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysMenu;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* <p>
* 菜单权限表 Mapper 接口
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Mapper
public interface SysMenuMapper extends PigxBaseMapper<SysMenu> {
/**
* 通过角色编号查询菜单
* @param roleId 角色ID
* @return
*/
List<SysMenu> listMenusByRoleId(Long roleId);
/**
* 通过角色ID查询权限
* @param roleIds Ids
* @return
*/
List<String> listPermissionsByRoleIds(String roleIds);
}

View File

@@ -0,0 +1,37 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysOauthClientDetails;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author lengleng
* @since 2018-05-15
*/
@Mapper
public interface SysOauthClientDetailsMapper extends PigxBaseMapper<SysOauthClientDetails> {
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysPost;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 岗位信息表
*
* @author fxz
* @date 2022-03-26 12:50:43
*/
@Mapper
public interface SysPostMapper extends PigxBaseMapper<SysPost> {
/**
* 通过用户ID查询岗位信息
* @param userId 用户id
* @return 岗位信息
*/
List<SysPost> listPostsByUserId(Long userId);
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysPublicParam;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 公共参数配置
*
* @author Lucky
* @date 2019-04-29
*/
@Mapper
public interface SysPublicParamMapper extends PigxBaseMapper<SysPublicParam> {
}

View File

@@ -0,0 +1,46 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysRole;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Mapper
public interface SysRoleMapper extends PigxBaseMapper<SysRole> {
/**
* 通过用户ID查询角色信息
* @param userId
* @return
*/
List<SysRole> listRolesByUserId(Long userId);
}

View File

@@ -0,0 +1,37 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysRoleMenu;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 角色菜单表 Mapper 接口
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Mapper
public interface SysRoleMenuMapper extends PigxBaseMapper<SysRoleMenu> {
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysRouteConf;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 路由
*
* @author lengleng
* @date 2018-11-06 10:17:18
*/
@Mapper
public interface SysRouteConfMapper extends PigxBaseMapper<SysRouteConf> {
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysScheduleEntity;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 日程
*
* @author aeizzz
* @date 2023-03-06 14:26:23
*/
@Mapper
public interface SysScheduleMapper extends PigxBaseMapper<SysScheduleEntity> {
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 系统社交登录账号表
*
* @author lengleng
* @date 2018-08-16 21:30:41
*/
@Mapper
public interface SysSocialDetailsMapper extends PigxBaseMapper<SysSocialDetails> {
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysTenant;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 租户
*
* @author lengleng
* @date 2019-05-15 15:55:41
*/
@Mapper
public interface SysTenantMapper extends PigxBaseMapper<SysTenant> {
}

View File

@@ -0,0 +1,76 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.admin.api.dto.UserDTO;
import com.pig4cloud.pigx.admin.api.entity.SysUser;
import com.pig4cloud.pigx.admin.api.vo.UserVO;
import com.pig4cloud.pigx.common.data.datascope.DataScope;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 用户表 Mapper 接口
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Mapper
public interface SysUserMapper extends PigxBaseMapper<SysUser> {
/**
* 通过用户名查询用户信息(含有角色信息)
* @param username 用户名
* @return userVo
*/
UserVO getUserVoByUsername(String username);
/**
* 分页查询用户信息(含角色)
* @param page 分页
* @param userDTO 查询参数
* @param dataScope
* @return list
*/
IPage<UserVO> getUserVosPage(Page page, @Param("query") UserDTO userDTO, DataScope dataScope);
/**
* 通过ID查询用户信息
* @param id 用户ID
* @return userVo
*/
UserVO getUserVoById(Long id);
/**
* 查询用户列表
* @param userDTO 查询条件
* @param dataScope 数据权限声明
* @return
*/
List<UserVO> selectVoListByScope(@Param("query") UserDTO userDTO, @Param("ids") Long[] ids, DataScope dataScope);
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pig4cloud.pigx.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig4cloud.pigx.admin.api.entity.SysUserPost;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 用户岗位 Mapper 接口
* </p>
*
* @author fxz
* @since 2022/3/19
*/
@Mapper
public interface SysUserPostMapper extends BaseMapper<SysUserPost> {
}

View File

@@ -0,0 +1,37 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysUserRole;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 用户角色表 Mapper 接口
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Mapper
public interface SysUserRoleMapper extends PigxBaseMapper<SysUserRole> {
}

View File

@@ -0,0 +1,38 @@
package com.pig4cloud.pigx.admin.service;
import com.pig4cloud.pigx.common.core.util.R;
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
/**
* @author lengleng
* @date 2022/4/22
* <p>
* 互联平台
*/
public interface ConnectService {
/**
* 同步钉钉部门
*/
Boolean syncDingDept();
/**
* 同步钉钉用户
*/
R syncDingUser(Long deptId);
/**
* 同步企微部门
* @return
*/
R<Boolean> syncCpDept();
/**
* 同步企微用户
* @return
*/
R<Boolean> syncCpUser();
WxCpDefaultConfigImpl getCpConfig();
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service;
import com.pig4cloud.pigx.common.core.util.R;
/**
* @author lengleng
* @date 2018/11/14
*/
public interface MobileService {
/**
* 发送手机验证码
* @param mobile mobile
* @return code
*/
R<Boolean> sendSmsCode(String mobile);
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.entity.SysAuditLog;
/**
* 审计记录表
*
* @author PIG
* @date 2023-02-28 20:12:23
*/
public interface SysAuditLogService extends IService<SysAuditLog> {
/**
* 分页查询审计日志(数据权限处理)
* @param page 分页条件
* @param sysAuditLog 查询条件
* @return page
*/
Page<SysAuditLog> getAuditsByScope(Page page, SysAuditLog sysAuditLog);
}

View File

@@ -0,0 +1,73 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.service;
import cn.hutool.core.lang.tree.Tree;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.entity.SysDept;
import com.pig4cloud.pigx.admin.api.vo.DeptExcelVo;
import com.pig4cloud.pigx.common.core.util.R;
import org.springframework.validation.BindingResult;
import java.util.List;
/**
* <p>
* 部门管理 服务类
* </p>
*
* @author lengleng
* @since 2018-01-20
*/
public interface SysDeptService extends IService<SysDept> {
/**
* 查询部门树菜单
* @param deptName 部门名称
* @return 树
*/
List<Tree<Long>> selectTree(String deptName, Long parentId);
/**
* 删除部门
* @param id 部门 ID
* @return 成功、失败
*/
Boolean removeDeptById(Long id);
List<DeptExcelVo> listExcelVo();
R importDept(List<DeptExcelVo> excelVOList, BindingResult bindingResult);
/**
* 获取部门的所有后代部门列表
* @param deptId 部门ID
* @return 后代部门列表
*/
List<SysDept> listDescendant(Long deptId);
/**
* 获取部门负责人
* @param deptId deptId
* @return user id list
*/
List<Long> listDeptLeader(Long deptId);
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.entity.SysDictItem;
import com.pig4cloud.pigx.common.core.util.R;
/**
* 字典项
*
* @author lengleng
* @date 2019/03/19
*/
public interface SysDictItemService extends IService<SysDictItem> {
/**
* 删除字典项
* @param id 字典项ID
* @return
*/
R removeDictItem(Long id);
/**
* 更新字典项
* @param item 字典项
* @return
*/
R updateDictItem(SysDictItem item);
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.entity.SysDict;
import com.pig4cloud.pigx.common.core.util.R;
/**
* 字典表
*
* @author lengleng
* @date 2019/03/19
*/
public interface SysDictService extends IService<SysDict> {
/**
* 根据ID 删除字典
* @param ids ID列表
* @return
*/
R removeDictByIds(Long[] ids);
/**
* 更新字典
* @param sysDict 字典
* @return
*/
R updateDict(SysDict sysDict);
/**
* 同步缓存 (清空缓存)
* @return R
*/
R syncDictCache();
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service;
import cn.hutool.core.lang.tree.Tree;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.dto.SysFileGroupDTO;
import com.pig4cloud.pigx.admin.api.entity.SysFile;
import com.pig4cloud.pigx.admin.api.entity.SysFileGroup;
import com.pig4cloud.pigx.common.core.util.R;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 文件管理
*
* @author Luckly
* @date 2019-06-18 17:18:42
*/
public interface SysFileService extends IService<SysFile> {
/**
* 上传文件
* @param file
* @param groupId
* @param type
* @return
*/
R uploadFile(MultipartFile file, Long groupId, String type);
/**
* 读取文件
* @param bucket 桶名称
* @param fileName 文件名称
* @param response 输出流
*/
void getFile(String bucket, String fileName, HttpServletResponse response);
/**
* 删除文件
* @param id
* @return
*/
Boolean deleteFile(Long id);
/**
* 查询文件组列表
* @param fileGroup SysFileGroup对象用于筛选条件
* @return 包含文件组列表的Tree对象列表
*/
List<Tree<Long>> listFileGroup(SysFileGroup fileGroup);
/**
* 添加或更新文件组
* @param fileGroup SysFileGroup对象要添加或更新的文件组信息
* @return 添加或更新成功返回true否则返回false
*/
Boolean saveOrUpdateGroup(SysFileGroup fileGroup);
/**
* 删除文件组
* @param id 待删除文件组的ID
* @return 删除成功返回true否则返回false
*/
Boolean deleteGroup(Long id);
/**
* 移动文件组
* @param fileGroupDTO SysFileGroupDTO对象要移动的文件组信息
* @return 移动成功返回true否则返回false
*/
Boolean moveFileGroup(SysFileGroupDTO fileGroupDTO);
}

View File

@@ -0,0 +1,19 @@
package com.pig4cloud.pigx.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.entity.SysI18nEntity;
import com.pig4cloud.pigx.common.core.util.R;
import java.util.Map;
public interface SysI18nService extends IService<SysI18nEntity> {
Map listMap();
/**
* 同步数据
* @return R
*/
R syncI18nCache();
}

View File

@@ -0,0 +1,62 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.dto.SysLogDTO;
import com.pig4cloud.pigx.admin.api.entity.SysLog;
import com.pig4cloud.pigx.admin.api.vo.PreLogVO;
import java.util.List;
/**
* <p>
* 日志表 服务类
* </p>
*
* @author lengleng
* @since 2017-11-20
*/
public interface SysLogService extends IService<SysLog> {
/**
* 批量插入前端错误日志
* @param preLogVoList 日志信息
* @return true/false
*/
Boolean saveBatchLogs(List<PreLogVO> preLogVoList);
/**
* 分页查询日志
* @param page
* @param sysLog
* @return
*/
Page getLogByPage(Page page, SysLogDTO sysLog);
/**
* 插入日志
* @param sysLog 日志对象
* @return true/false
*/
Boolean saveLog(SysLogDTO sysLog);
}

View File

@@ -0,0 +1,77 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.service;
import cn.hutool.core.lang.tree.Tree;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.entity.SysMenu;
import com.pig4cloud.pigx.common.core.util.R;
import java.util.List;
import java.util.Set;
/**
* <p>
* 菜单权限表 服务类
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
public interface SysMenuService extends IService<SysMenu> {
/**
* 通过角色编号查询URL 权限
* @param roleId 角色ID
* @return 菜单列表
*/
List<SysMenu> findMenuByRoleId(Long roleId);
/**
* 级联删除菜单
* @param id 菜单ID
* @return 成功、失败
*/
R removeMenuById(Long id);
/**
* 更新菜单信息
* @param sysMenu 菜单信息
* @return 成功、失败
*/
Boolean updateMenuById(SysMenu sysMenu);
/**
* 构建树
* @param parentId 父节点ID
* @param menuName 菜单名称
* @return
*/
List<Tree<Long>> treeMenu(Long parentId, String menuName, String type);
/**
* 查询菜单
* @param voSet
* @param parentId
* @return
*/
List<Tree<Long>> filterMenu(Set<SysMenu> voSet, String type, Long parentId);
}

View File

@@ -0,0 +1,66 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.dto.SysOauthClientDetailsDTO;
import com.pig4cloud.pigx.admin.api.entity.SysOauthClientDetails;
import com.pig4cloud.pigx.common.core.util.R;
/**
* <p>
* 服务类
* </p>
*
* @author lengleng
* @since 2018-05-15
*/
public interface SysOauthClientDetailsService extends IService<SysOauthClientDetails> {
/**
* 根据客户端信息
* @param clientDetailsDTO
* @return
*/
Boolean updateClientById(SysOauthClientDetailsDTO clientDetailsDTO);
/**
* 添加客户端
* @param clientDetailsDTO
* @return
*/
Boolean saveClient(SysOauthClientDetailsDTO clientDetailsDTO);
/**
* 分页查询客户端信息
* @param page
* @param query
* @return
*/
Page queryPage(Page page, SysOauthClientDetails query);
/**
* 同步缓存 (清空缓存)
* @return R
*/
R syncClientCache();
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.entity.SysPost;
import com.pig4cloud.pigx.admin.api.vo.PostExcelVO;
import com.pig4cloud.pigx.common.core.util.R;
import org.springframework.validation.BindingResult;
import java.util.List;
/**
* 岗位信息表
*
* @author fxz
* @date 2022-03-26 12:50:43
*/
public interface SysPostService extends IService<SysPost> {
/**
* 导出excel 表格
* @return
*/
List<PostExcelVO> listPost(SysPost post, Long[] ids);
/**
* 导入岗位
* @param excelVOList 岗位列表
* @param bindingResult 错误信息列表
* @return ok fail
*/
R importPost(List<PostExcelVO> excelVOList, BindingResult bindingResult);
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.entity.SysPublicParam;
import com.pig4cloud.pigx.common.core.util.R;
import java.util.Map;
/**
* 公共参数配置
*
* @author Lucky
* @date 2019-04-29
*/
public interface SysPublicParamService extends IService<SysPublicParam> {
/**
* 通过key查询公共参数指定值
* @param publicKey
* @return
*/
String getSysPublicParamKeyToValue(String publicKey);
/**
* 通过key查询公共参数指定值
* @param keys 参数列表
* @return Map
*/
Map<String, Object> getSysPublicParamsKeyToValue(String[] keys);
/**
* 更新参数
* @param sysPublicParam
* @return
*/
R updateParam(SysPublicParam sysPublicParam);
/**
* 删除参数
* @param publicIds 参数列表
* @return
*/
R removeParamByIds(Long[] publicIds);
/**
* 同步缓存
* @return R
*/
R syncParamCache();
}

View File

@@ -0,0 +1,43 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.entity.SysRoleMenu;
/**
* <p>
* 角色菜单表 服务类
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
public interface SysRoleMenuService extends IService<SysRoleMenu> {
/**
* 更新角色菜单
* @param roleId 角色ID
* @param menuIds 菜单ID拼成的字符串每个id之间根据逗号分隔
* @return
*/
Boolean saveRoleMenus(Long roleId, String menuIds);
}

View File

@@ -0,0 +1,86 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.entity.SysRole;
import com.pig4cloud.pigx.admin.api.vo.RoleExcelVO;
import com.pig4cloud.pigx.admin.api.vo.RoleVO;
import com.pig4cloud.pigx.common.core.util.R;
import org.springframework.validation.BindingResult;
import java.util.List;
/**
* <p>
* 服务类
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
public interface SysRoleService extends IService<SysRole> {
/**
* 通过用户ID查询角色信息
* @param userId
* @return
*/
List<SysRole> findRolesByUserId(Long userId);
/**
* 根据角色ID 查询角色列表
* @param roleIdList 角色ID列表
* @param key 缓存key
* @return
*/
List<SysRole> findRolesByRoleIds(List<Long> roleIdList, String key);
/**
* 通过角色ID删除角色
* @param ids
* @return
*/
Boolean removeRoleByIds(Long[] ids);
/**
* 根据角色菜单列表
* @param roleVo 角色&菜单列表
* @return
*/
Boolean updateRoleMenus(RoleVO roleVo);
/**
* 导入角色
* @param excelVOList 角色列表
* @param bindingResult 错误信息列表
* @return ok fail
*/
R importRole(List<RoleExcelVO> excelVOList, BindingResult bindingResult);
/**
* 查询全部的角色
* @param sysRole 查询条件
* @param ids 导出ids
* @return list
*/
List<RoleExcelVO> listRole(SysRole sysRole, Long[] ids);
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service;
import cn.hutool.json.JSONArray;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.entity.SysRouteConf;
import reactor.core.publisher.Mono;
/**
* 路由
*
* @author lengleng
* @date 2018-11-06 10:17:18
*/
public interface SysRouteConfService extends IService<SysRouteConf> {
/**
* 更新路由信息
* @param routes 路由信息
* @return
*/
Mono<Void> updateRoutes(JSONArray routes);
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.entity.SysScheduleEntity;
import java.util.List;
/**
* 日程
*
* @author aeizzz
* @date 2023-03-06 14:26:23
*/
public interface SysScheduleService extends IService<SysScheduleEntity> {
IPage<SysScheduleEntity> getScheduleByScope(Page page, SysScheduleEntity sysSchedule);
List<SysScheduleEntity> selectListByScope(String month);
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
/**
* 系统社交登录账号表
*
* @author lengleng
* @date 2018-08-16 21:30:41
*/
public interface SysSocialDetailsService extends IService<SysSocialDetails> {
/**
* 绑定社交账号
* @param state 类型
* @param code code
* @return
*/
Boolean bindSocial(String state, String code);
/**
* 根据入参查询用户信息
* @param inStr
* @return
*/
UserInfo getUserInfo(String inStr);
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.entity.SysTenant;
import java.util.List;
/**
* 租户管理
*
* @author lengleng
* @date 2019-05-15 15:55:41
*/
public interface SysTenantService extends IService<SysTenant> {
/**
* 获取正常的租户
* @return
*/
List<SysTenant> getNormalTenant();
/**
* 保存租户
* @param sysTenant
* @return
*/
Boolean saveTenant(SysTenant sysTenant);
/**
* 修改租户
* @param sysTenant
* @return
*/
Boolean updateTenant(SysTenant sysTenant);
}

View File

@@ -0,0 +1,35 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.entity.SysUserRole;
/**
* <p>
* 用户角色表 服务类
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
public interface SysUserRoleService extends IService<SysUserRole> {
}

View File

@@ -0,0 +1,148 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.dto.UserDTO;
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
import com.pig4cloud.pigx.admin.api.entity.SysUser;
import com.pig4cloud.pigx.admin.api.vo.UserExcelVO;
import com.pig4cloud.pigx.admin.api.vo.UserVO;
import com.pig4cloud.pigx.common.core.util.R;
import org.springframework.validation.BindingResult;
import java.util.List;
/**
* @author lengleng
* @date 2017/10/31
*/
public interface SysUserService extends IService<SysUser> {
/**
* 查询用户信息
* @param sysUser 用户
* @return userInfo
*/
UserInfo findUserInfo(SysUser sysUser);
/**
* 分页查询用户信息(含有角色信息)
* @param page 分页对象
* @param userDTO 参数列表
* @return
*/
IPage getUsersWithRolePage(Page page, UserDTO userDTO);
/**
* 删除用户
* @param ids 用户
* @return boolean
*/
Boolean deleteUserByIds(Long[] ids);
/**
* 更新当前用户基本信息
* @param userDto 用户信息
* @return Boolean
*/
R<Boolean> updateUserInfo(UserDTO userDto);
/**
* 更新指定用户信息
* @param userDto 用户信息
* @return
*/
Boolean updateUser(UserDTO userDto);
/**
* 通过ID查询用户信息
* @param id 用户ID
* @return 用户信息
*/
UserVO selectUserVoById(Long id);
/**
* 查询上级部门的用户信息
* @param username 用户名
* @return R
*/
List<SysUser> listAncestorUsers(String username);
/**
* 保存用户信息
* @param userDto DTO 对象
* @return success/fail
*/
Boolean saveUser(UserDTO userDto);
/**
* 查询全部的用户
* @param userDTO 查询条件
* @param ids 目标列表
* @return list
*/
List<UserExcelVO> listUser(UserDTO userDTO, Long[] ids);
/**
* excel 导入用户
* @param excelVOList excel 列表数据
* @param bindingResult 错误数据
* @return ok fail
*/
R importUser(List<UserExcelVO> excelVOList, BindingResult bindingResult);
/**
* 注册用户
* @param userDto 用户信息
* @return success/false
*/
R<Boolean> registerUser(UserDTO userDto);
/**
* 锁定用户
* @param username
* @return
*/
R<Boolean> lockUser(String username);
R changePassword(UserDTO userDto);
R unbinding(String type);
R checkPassword(String password);
/**
* 根据角色ID列表获取用户ID列表接口
* @param roleIdList 角色ID列表
* @return List<Long> 返回结果对象包含根据角色ID列表获取到的用户ID列表信息
*/
List<Long> listUserIdByRoleIds(List<Long> roleIdList);
/**
* 根据部门ID列表获取用户ID列表接口
* @param deptIdList 部门ID列表
* @return List<Long> 返回结果对象包含根据部门ID列表获取到的用户ID列表信息
*/
List<SysUser> listUserIdByDeptIds(List<Long> deptIdList);
}

View File

@@ -0,0 +1,330 @@
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.request.OapiUserListidRequest;
import com.dingtalk.api.request.OapiV2DepartmentListsubRequest;
import com.dingtalk.api.request.OapiV2UserGetRequest;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.dingtalk.api.response.OapiUserListidResponse;
import com.dingtalk.api.response.OapiV2DepartmentListsubResponse;
import com.dingtalk.api.response.OapiV2UserGetResponse;
import com.pig4cloud.pigx.admin.api.dto.UserDTO;
import com.pig4cloud.pigx.admin.api.entity.SysDept;
import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
import com.pig4cloud.pigx.admin.api.entity.SysUser;
import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper;
import com.pig4cloud.pigx.admin.service.ConnectService;
import com.pig4cloud.pigx.admin.service.SysDeptService;
import com.pig4cloud.pigx.admin.service.SysUserService;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
import me.chanjar.weixin.cp.bean.WxCpDepart;
import me.chanjar.weixin.cp.bean.WxCpUser;
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 互联平台实现
* <p>
* 钉钉: https://open-dev.dingtalk.com/apiExplorer
*
* @author lengleng
* @date 2022/4/22
*/
@SuppressWarnings("unchecked")
@Slf4j
@Service
@RequiredArgsConstructor
public class ConnectServiceImpl implements ConnectService {
private final SysSocialDetailsMapper sysSocialDetailsMapper;
private final SysDeptService sysDeptService;
private final SysUserService sysUserService;
/**
* 同步钉钉部门
* @return Boolean
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean syncDingDept() {
OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
req.setDeptId(1L);
req.setLanguage("zh_CN");
// 数据库中现有的部门
List<SysDept> deptList = sysDeptService.list(Wrappers.emptyWrapper());
// 查询根部门下的所有部门
List<SysDept> insertDept = queryChildDept(req, getDingAccessToken(), deptList);
// 去重
List<SysDept> syncDept = insertDept.stream().distinct().collect(Collectors.toList());
// 保存部门以及部门关系
if (CollectionUtils.isNotEmpty(syncDept)) {
syncDept.forEach(sysDeptService::save);
}
return Boolean.TRUE;
}
/**
* 同步部门下的钉钉用户
* @param deptId 部门ID
* @return R
*/
@SneakyThrows
@Override
@Transactional(rollbackFor = Exception.class)
public R syncDingUser(Long deptId) {
// 数据库中现有用户
List<SysUser> users = sysUserService.list(Wrappers.emptyWrapper());
String token = getDingAccessToken();
// 查询部门下的用户id列表
DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_DEPT_USERIDS_URL);
OapiUserListidRequest req = new OapiUserListidRequest();
req.setDeptId(deptId);
OapiUserListidResponse rsp = client.execute(req, token);
JSONObject jsonObject = JSONUtil.parseObj(rsp.getBody());
JSONObject result = jsonObject.getJSONObject("result");
if (result == null) {
return R.ok();
}
List<String> useridList = result.get("userid_list", List.class);
// 查询用户详情
for (String userid : useridList) {
DingTalkClient userClient = new DefaultDingTalkClient(SecurityConstants.DING_USER_INFO_URL);
OapiV2UserGetRequest userGetRequest = new OapiV2UserGetRequest();
userGetRequest.setUserid(userid);
OapiV2UserGetResponse userGetResponse = userClient.execute(userGetRequest, token);
JSONObject userResult = JSONUtil.parseObj(userGetResponse.getBody());
JSONObject userObj = JSONUtil.parseObj(userResult.get("result"));
boolean exist = users.stream().filter(user -> StrUtil.isNotBlank(user.getPhone()))
.anyMatch(user -> user.getPhone().equals(userObj.getStr("mobile")));
if (exist || StrUtil.isBlank(userObj.getStr("mobile"))) {
log.info("用户已存在或手机号不合法 {}", userid);
continue;
}
// 用户部门信息
JSONArray deptOrders = userObj.getJSONArray("dept_order_list");
JSONObject deptInfo = (JSONObject) deptOrders.get(0);
// 用户信息
UserDTO userDTO = new UserDTO();
userDTO.setDeptId(deptInfo.getLong("dept_id"));
userDTO.setAvatar(userObj.getStr("avatar"));
userDTO.setUsername(userObj.getStr("mobile"));
userDTO.setPhone(userObj.getStr("mobile"));
userDTO.setNickname(userObj.getStr("nickname"));
userDTO.setName(userObj.getStr("name"));
userDTO.setEmail(userObj.getStr("email"));
// 初始化密码为 手机号
userDTO.setPassword(userObj.getStr("mobile"));
sysUserService.saveUser(userDTO);
}
return R.ok();
}
/**
* 同步企微部门
* @return R
*/
@Override
@Transactional(rollbackFor = Exception.class)
public R<Boolean> syncCpDept() {
WxCpService wxCpService = new WxCpServiceImpl();
wxCpService.setWxCpConfigStorage(getCpConfig());
List<WxCpDepart> departList;
try {
departList = wxCpService.getDepartmentService().list(null);
}
catch (WxErrorException e) {
log.error("获取企业微信部门列表失败", e);
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_CONNECT_CP_DEPT_SYNC_ERROR));
}
if (CollUtil.isEmpty(departList)) {
return R.ok();
}
// 数据库中现有的部门
List<SysDept> deptList = sysDeptService.list(Wrappers.emptyWrapper());
departList.stream()
.filter(depart -> deptList.stream().noneMatch(sysDept -> depart.getName().equals(sysDept.getName())))
.map(dept -> {
SysDept sysDept = new SysDept();
sysDept.setName(dept.getName());
sysDept.setDeptId(dept.getId());
sysDept.setParentId(dept.getParentId());
sysDept.setSortOrder(dept.getOrder().intValue());
return sysDept;
}).forEach(sysDeptService::save);
return R.ok();
}
/**
* 同步企微用户
* @return R
*/
@Override
public R<Boolean> syncCpUser() {
WxCpService wxCpService = new WxCpServiceImpl();
wxCpService.setWxCpConfigStorage(getCpConfig());
List<WxCpUser> cpUserList;
try {
cpUserList = wxCpService.getUserService().listByDepartment(1L, true, 0);
}
catch (WxErrorException e) {
log.error("获取企业微信用户列表失败", e);
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_CONNECT_CP_USER_SYNC_ERROR));
}
if (CollUtil.isEmpty(cpUserList)) {
return R.ok();
}
// 系统原有用户
List<SysUser> userList = sysUserService.list(Wrappers.emptyWrapper());
for (WxCpUser cpUser : cpUserList) {
boolean exist = userList.stream().filter(user -> StrUtil.isNotBlank(user.getPhone()))
.anyMatch(user -> user.getPhone().equals(cpUser.getMobile()));
if (exist || StrUtil.isBlank(cpUser.getMobile())) {
log.info("用户已存在或手机号不合法跳过 {}", cpUser);
continue;
}
UserDTO user = new UserDTO();
user.setUsername(cpUser.getMobile());
user.setName(cpUser.getName());
user.setDeptId(cpUser.getDepartIds()[0]);
user.setEmail(cpUser.getEmail());
user.setPhone(cpUser.getMobile());
user.setAvatar(cpUser.getAvatar());
// 初始化密码为 手机号
user.setPassword(cpUser.getMobile());
sysUserService.saveUser(user);
}
return R.ok();
}
private String getDingAccessToken() {
SysSocialDetails dingTalk = sysSocialDetailsMapper.selectOne(Wrappers.<SysSocialDetails>lambdaQuery()
.eq(SysSocialDetails::getType, LoginTypeEnum.DINGTALK.getType()));
DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_OLD_GET_TOKEN);
OapiGettokenRequest request = new OapiGettokenRequest();
request.setAppkey(dingTalk.getAppId());
request.setAppsecret(dingTalk.getAppSecret());
request.setHttpMethod(HttpMethod.GET.name());
try {
OapiGettokenResponse response = client.execute(request);
return response.getAccessToken();
}
catch (Exception e) {
log.error("调用钉钉异常", e);
}
return null;
}
public WxCpDefaultConfigImpl getCpConfig() {
SysSocialDetails cp = sysSocialDetailsMapper.selectOne(Wrappers.<SysSocialDetails>lambdaQuery()
.eq(SysSocialDetails::getType, LoginTypeEnum.WEIXIN_CP.getType()));
WxCpDefaultConfigImpl config = new WxCpDefaultConfigImpl();
config.setCorpId(cp.getAppId()); // 设置微信企业号的appid
config.setCorpSecret(cp.getAppSecret()); // 设置微信企业号的app
// corpSecret
JSONObject ext = JSONUtil.parseObj(cp.getExt());
config.setAgentId(ext.getInt("agentId")); // 设置微信企业号应用ID
config.setToken(ext.getStr("token")); // 设置微信企业号应用的token
config.setAesKey(ext.getStr("aesKey")); // 设置微信企业号应用的EncodingAESKey
return config;
}
/**
* 查询当前部门下的所有部门
*/
@SneakyThrows
private List<SysDept> queryChildDept(OapiV2DepartmentListsubRequest req, String token, List<SysDept> deptList) {
List<SysDept> sysDepts = new LinkedList<>();
// 调用Api查询
DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_OLD_DEPT_URL);
OapiV2DepartmentListsubResponse rsp = client.execute(req, token);
JSONObject result = JSONUtil.parseObj(rsp.getBody());
List<JSONObject> resultList = result.get("result", List.class);
if (CollUtil.isEmpty(resultList)) {
return sysDepts;
}
// 过滤出数据库存在的部门
List<SysDept> depts = resultList.stream()
.filter(dept -> deptList.stream().noneMatch(sysDept -> sysDept.getName().equals(dept.get("name"))))
.map(dept -> {
SysDept sysDept = new SysDept();
sysDept.setName(Convert.toStr(dept.get("name")));
sysDept.setDeptId(Convert.toLong(dept.get("dept_id")));
sysDept.setParentId(Convert.toLong(dept.get("parent_id")));
return sysDept;
}).collect(Collectors.toList());
// 递归查询下一级
if (CollectionUtils.isNotEmpty(depts)) {
sysDepts.addAll(depts);
depts.forEach(dept -> {
OapiV2DepartmentListsubRequest request = new OapiV2DepartmentListsubRequest();
request.setDeptId(dept.getDeptId());
request.setLanguage("zh_CN");
List<SysDept> childDept = queryChildDept(request, token, deptList);
sysDepts.addAll(childDept);
});
}
return sysDepts;
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pig4cloud.pigx.admin.api.entity.SysUser;
import com.pig4cloud.pigx.admin.mapper.SysUserMapper;
import com.pig4cloud.pigx.admin.service.MobileService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author lengleng
* @date 2018/11/14
* <p>
* 手机登录相关业务实现
*/
@Slf4j
@Service
@AllArgsConstructor
public class MobileServiceImpl implements MobileService {
private final RedisTemplate redisTemplate;
private final SysUserMapper userMapper;
/**
* 发送手机验证码 TODO: 调用短信网关发送验证码,测试返回前端
* @param mobile mobile
* @return code
*/
@Override
public R<Boolean> sendSmsCode(String mobile) {
List<SysUser> userList = userMapper
.selectList(Wrappers.<SysUser>query().lambda().eq(SysUser::getPhone, mobile));
if (CollUtil.isEmpty(userList)) {
log.info("手机号未注册:{}", mobile);
return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_PHONE_UNREGISTERED, mobile));
}
Object codeObj = redisTemplate.opsForValue()
.get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile);
if (codeObj != null) {
log.info("手机号验证码未过期:{}{}", mobile, codeObj);
return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_SMS_OFTEN));
}
String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE));
log.debug("手机号生成验证码成功:{},{}", mobile, code);
redisTemplate.opsForValue().set(
CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile, code,
SecurityConstants.CODE_TIME, TimeUnit.SECONDS);
return R.ok(Boolean.TRUE, code);
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.entity.SysAuditLog;
import com.pig4cloud.pigx.admin.mapper.SysAuditLogMapper;
import com.pig4cloud.pigx.admin.service.SysAuditLogService;
import com.pig4cloud.pigx.common.data.datascope.DataScope;
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
import org.springframework.stereotype.Service;
/**
* 审计记录表
*
* @author PIG
* @date 2023-02-28 20:12:23
*/
@Service
public class SysAuditLogServiceImpl extends ServiceImpl<SysAuditLogMapper, SysAuditLog> implements SysAuditLogService {
/**
* 分页查询审计日志(数据权限处理)
* @param page 分页条件
* @param sysAuditLog 查询条件
* @return page
*/
@Override
public Page<SysAuditLog> getAuditsByScope(Page page, SysAuditLog sysAuditLog) {
LambdaQueryWrapper<SysAuditLog> wrapper = Wrappers.lambdaQuery();
wrapper.like(StrUtil.isNotBlank(sysAuditLog.getAuditName()), SysAuditLog::getAuditName,
sysAuditLog.getAuditName());
wrapper.like(StrUtil.isNotBlank(sysAuditLog.getAuditField()), SysAuditLog::getAuditField,
sysAuditLog.getAuditField());
wrapper.like(StrUtil.isNotBlank(sysAuditLog.getCreateBy()), SysAuditLog::getCreateBy,
sysAuditLog.getCreateBy());
// 数据权限限制,只查询本人的审计日志
DataScope dataScope = new DataScope();
dataScope.setUsername(SecurityUtils.getUser().getUsername());
return baseMapper.selectPageByScope(page, wrapper, dataScope);
}
}

View File

@@ -0,0 +1,250 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.entity.SysDept;
import com.pig4cloud.pigx.admin.api.entity.SysPost;
import com.pig4cloud.pigx.admin.api.entity.SysUser;
import com.pig4cloud.pigx.admin.api.entity.SysUserPost;
import com.pig4cloud.pigx.admin.api.vo.DeptExcelVo;
import com.pig4cloud.pigx.admin.mapper.SysDeptMapper;
import com.pig4cloud.pigx.admin.mapper.SysPostMapper;
import com.pig4cloud.pigx.admin.mapper.SysUserMapper;
import com.pig4cloud.pigx.admin.mapper.SysUserPostMapper;
import com.pig4cloud.pigx.admin.service.SysDeptService;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.data.datascope.DataScope;
import com.pig4cloud.pigx.common.excel.vo.ErrorMessage;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import java.util.*;
import java.util.stream.Collectors;
/**
* <p>
* 部门管理 服务实现类
* </p>
*
* @author lengleng
* @since 2018-01-20
*/
@Service
@AllArgsConstructor
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {
private final SysUserMapper userMapper;
private final SysDeptMapper deptMapper;
private final SysPostMapper postMapper;
private final SysUserPostMapper userPostMapper;
/**
* 删除部门
* @param id 部门 ID
* @return 成功、失败
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean removeDeptById(Long id) {
// 级联删除部门
List<Long> idList = this.listDescendant(id).stream().map(SysDept::getDeptId).collect(Collectors.toList());
Optional.ofNullable(idList).filter(CollUtil::isNotEmpty).ifPresent(this::removeByIds);
return Boolean.TRUE;
}
/**
* 查询全部部门树
* @param deptName
* @param parentId
* @return 树 部门名称
*/
@Override
public List<Tree<Long>> selectTree(String deptName, Long parentId) {
// 查询全部部门
List<SysDept> deptAllList = deptMapper.selectList(
Wrappers.<SysDept>lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName));
// 查询数据权限内部门
List<Long> deptOwnIdList = deptMapper.selectListByScope(
Wrappers.<SysDept>lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName),
DataScope.of()).stream().map(SysDept::getDeptId).collect(Collectors.toList());
// 权限内部门
List<TreeNode<Long>> collect = deptAllList.stream()
.filter(dept -> dept.getDeptId().intValue() != dept.getParentId())
.sorted(Comparator.comparingInt(SysDept::getSortOrder)).map(dept -> {
TreeNode<Long> treeNode = new TreeNode<>();
treeNode.setId(dept.getDeptId());
treeNode.setParentId(dept.getParentId());
treeNode.setName(dept.getName());
treeNode.setWeight(dept.getSortOrder());
// 有权限不返回标识
Map<String, Object> extra = new HashMap<>(8);
extra.put("isLock", !deptOwnIdList.contains(dept.getDeptId()));
extra.put("createTime", dept.getCreateTime());
treeNode.setExtra(extra);
return treeNode;
}).collect(Collectors.toList());
// 模糊查询 不组装树结构 直接返回 表格方便编辑
if (StrUtil.isNotBlank(deptName)) {
return collect.stream().map(node -> {
Tree<Long> tree = new Tree<>();
tree.putAll(node.getExtra());
BeanUtils.copyProperties(node, tree);
return tree;
}).collect(Collectors.toList());
}
return TreeUtil.build(collect, parentId == null ? 0 : parentId);
}
/**
* 导出部门
* @return
*/
@Override
public List<DeptExcelVo> listExcelVo() {
List<SysDept> list = this.list();
List<DeptExcelVo> deptExcelVos = list.stream().map(item -> {
DeptExcelVo deptExcelVo = new DeptExcelVo();
deptExcelVo.setName(item.getName());
Optional<String> first = this.list().stream().filter(it -> item.getParentId().equals(it.getDeptId()))
.map(SysDept::getName).findFirst();
deptExcelVo.setParentName(first.orElse("根部门"));
deptExcelVo.setSortOrder(item.getSortOrder());
return deptExcelVo;
}).collect(Collectors.toList());
return deptExcelVos;
}
@Override
public R importDept(List<DeptExcelVo> excelVOList, BindingResult bindingResult) {
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
List<SysDept> deptList = this.list();
for (DeptExcelVo item : excelVOList) {
Set<String> errorMsg = new HashSet<>();
boolean exsitUsername = deptList.stream().anyMatch(sysDept -> item.getName().equals(sysDept.getName()));
if (exsitUsername) {
errorMsg.add("部门名称已经存在");
}
SysDept one = this.getOne(Wrappers.<SysDept>lambdaQuery().eq(SysDept::getName, item.getParentName()));
if (item.getParentName().equals("根部门")) {
one = new SysDept();
one.setDeptId(0L);
}
if (one == null) {
errorMsg.add("上级部门不存在");
}
if (CollUtil.isEmpty(errorMsg)) {
SysDept sysDept = new SysDept();
sysDept.setName(item.getName());
sysDept.setParentId(one.getDeptId());
sysDept.setSortOrder(item.getSortOrder());
baseMapper.insert(sysDept);
}
else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage(item.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok(null, "部门导入成功");
}
/**
* 查询所有子节点 (包含当前节点)
* @param deptId 部门ID 目标部门ID
* @return ID
*/
@Override
public List<SysDept> listDescendant(Long deptId) {
// 查询全部部门
List<SysDept> allDeptList = baseMapper.selectList(Wrappers.emptyWrapper());
// 递归查询所有子节点
List<SysDept> resDeptList = new ArrayList<>();
recursiveDept(allDeptList, deptId, resDeptList);
// 添加当前节点
resDeptList.addAll(allDeptList.stream().filter(sysDept -> deptId.equals(sysDept.getDeptId()))
.collect(Collectors.toList()));
return resDeptList;
}
/**
* 获取部门负责人
*
* 1. 根据dept 查询用户 2. 筛选用户列表中 post
* @param deptId deptId
* @return user id list
*/
@Override
public List<Long> listDeptLeader(Long deptId) {
List<SysUser> sysUserList = userMapper
.selectList(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getDeptId, deptId));
if (CollUtil.isEmpty(sysUserList)) {
return null;
}
SysPost deptLeader = postMapper
.selectOne(Wrappers.<SysPost>lambdaQuery().eq(SysPost::getPostCode, "DEPT_LEADER"));
if (deptLeader == null) {
return null;
}
List<Long> userIdList = sysUserList.stream().map(SysUser::getUserId).collect(Collectors.toList());
return userPostMapper.selectList(Wrappers.<SysUserPost>lambdaQuery().in(SysUserPost::getUserId, userIdList))
.stream().filter(post -> Objects.equals(post.getPostId(), deptLeader.getPostId()))
.map(SysUserPost::getUserId).collect(Collectors.toList());
}
/**
* 递归查询所有子节点。
* @param allDeptList 所有部门列表
* @param parentId 父部门ID
* @param resDeptList 结果集合
*/
private void recursiveDept(List<SysDept> allDeptList, Long parentId, List<SysDept> resDeptList) {
// 使用 Stream API 进行筛选和遍历
allDeptList.stream().filter(sysDept -> sysDept.getParentId().equals(parentId)).forEach(sysDept -> {
resDeptList.add(sysDept);
recursiveDept(allDeptList, sysDept.getDeptId(), resDeptList);
});
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.entity.SysDict;
import com.pig4cloud.pigx.admin.api.entity.SysDictItem;
import com.pig4cloud.pigx.admin.mapper.SysDictItemMapper;
import com.pig4cloud.pigx.admin.service.SysDictItemService;
import com.pig4cloud.pigx.admin.service.SysDictService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.enums.DictTypeEnum;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
/**
* 字典项
*
* @author lengleng
* @date 2019/03/19
*/
@Service
@AllArgsConstructor
public class SysDictItemServiceImpl extends ServiceImpl<SysDictItemMapper, SysDictItem> implements SysDictItemService {
private final SysDictService dictService;
/**
* 删除字典项
* @param id 字典项ID
* @return
*/
@Override
@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
public R removeDictItem(Long id) {
// 根据ID查询字典ID
SysDictItem dictItem = this.getById(id);
SysDict dict = dictService.getById(dictItem.getDictId());
// 系统内置
if (DictTypeEnum.SYSTEM.getType().equals(dict.getSystemFlag())) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_DICT_DELETE_SYSTEM));
}
return R.ok(this.removeById(id));
}
/**
* 更新字典项
* @param item 字典项
* @return
*/
@Override
@CacheEvict(value = CacheConstants.DICT_DETAILS, key = "#item.dictType")
public R updateDictItem(SysDictItem item) {
// 查询字典
SysDict dict = dictService.getById(item.getDictId());
// 系统内置
if (DictTypeEnum.SYSTEM.getType().equals(dict.getSystemFlag())) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_DICT_UPDATE_SYSTEM));
}
return R.ok(this.updateById(item));
}
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.entity.SysDict;
import com.pig4cloud.pigx.admin.api.entity.SysDictItem;
import com.pig4cloud.pigx.admin.mapper.SysDictItemMapper;
import com.pig4cloud.pigx.admin.mapper.SysDictMapper;
import com.pig4cloud.pigx.admin.service.SysDictService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.enums.DictTypeEnum;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
/**
* 字典表
*
* @author lengleng
* @date 2019/03/19
*/
@Service
@AllArgsConstructor
public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements SysDictService {
private final SysDictItemMapper dictItemMapper;
/**
* 根据ID 删除字典
* @param ids 字典ID 列表
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
public R removeDictByIds(Long[] ids) {
List<Long> dictIdList = baseMapper.selectBatchIds(CollUtil.toList(ids)).stream()
.filter(sysDict -> !sysDict.getSystemFlag().equals(DictTypeEnum.SYSTEM.getType()))// 系统内置类型不删除
.map(SysDict::getId).collect(Collectors.toList());
baseMapper.deleteBatchIds(dictIdList);
dictItemMapper.delete(Wrappers.<SysDictItem>lambdaQuery().in(SysDictItem::getDictId, dictIdList));
return R.ok();
}
/**
* 更新字典
* @param dict 字典
* @return
*/
@Override
@CacheEvict(value = CacheConstants.DICT_DETAILS, key = "#dict.dictType")
public R updateDict(SysDict dict) {
SysDict sysDict = this.getById(dict.getId());
// 系统内置
if (DictTypeEnum.SYSTEM.getType().equals(sysDict.getSystemFlag())) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_DICT_UPDATE_SYSTEM));
}
this.updateById(dict);
return R.ok(dict);
}
/**
* 同步缓存 (清空缓存)
* @return R
*/
@Override
@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
public R syncDictCache() {
return R.ok();
}
}

View File

@@ -0,0 +1,225 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.amazonaws.services.s3.model.S3Object;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.dto.SysFileGroupDTO;
import com.pig4cloud.pigx.admin.api.entity.SysFile;
import com.pig4cloud.pigx.admin.api.entity.SysFileGroup;
import com.pig4cloud.pigx.admin.mapper.SysFileGroupMapper;
import com.pig4cloud.pigx.admin.mapper.SysFileMapper;
import com.pig4cloud.pigx.admin.service.SysFileService;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.file.core.FileProperties;
import com.pig4cloud.pigx.common.file.core.FileTemplate;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
/**
* 文件管理
*
* @author Luckly
* @date 2019-06-18 17:18:42
*/
@Slf4j
@Service
@AllArgsConstructor
public class SysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFile> implements SysFileService {
private final FileTemplate fileTemplate;
private final SysFileGroupMapper fileGroupMapper;
private final FileProperties properties;
/**
* 上传文件
* @param file
* @param groupId
* @param type
* @return
*/
@Override
public R uploadFile(MultipartFile file, Long groupId, String type) {
String fileName = IdUtil.simpleUUID() + StrUtil.DOT + FileUtil.extName(file.getOriginalFilename());
Map<String, String> resultMap = new HashMap<>(4);
resultMap.put("bucketName", properties.getBucketName());
resultMap.put("fileName", fileName);
resultMap.put("url", String.format("/admin/sys-file/%s/%s", properties.getBucketName(), fileName));
try (InputStream inputStream = file.getInputStream()) {
fileTemplate.putObject(properties.getBucketName(), fileName, inputStream, file.getContentType());
// 文件管理数据记录,收集管理追踪文件
fileLog(file, fileName, groupId, type);
}
catch (Exception e) {
log.error("上传失败", e);
return R.failed(e.getLocalizedMessage());
}
return R.ok(resultMap);
}
/**
* 读取文件
* @param bucket
* @param fileName
* @param response
*/
@Override
public void getFile(String bucket, String fileName, HttpServletResponse response) {
try (S3Object s3Object = fileTemplate.getObject(bucket, fileName)) {
response.setContentType("application/octet-stream; charset=UTF-8");
IoUtil.copy(s3Object.getObjectContent(), response.getOutputStream());
}
catch (Exception e) {
log.error("文件读取异常: {}", e.getLocalizedMessage());
}
}
/**
* 删除文件
* @param id
* @return
*/
@Override
@SneakyThrows
@Transactional(rollbackFor = Exception.class)
public Boolean deleteFile(Long id) {
SysFile file = this.getById(id);
if (Objects.isNull(file)) {
return Boolean.FALSE;
}
fileTemplate.removeObject(properties.getBucketName(), file.getFileName());
return this.removeById(id);
}
/**
* 查询文件组列表
* @param fileGroup SysFileGroup对象用于筛选条件
* @return 包含文件组树形结构列表的List对象
*/
@Override
public List<Tree<Long>> listFileGroup(SysFileGroup fileGroup) {
// 从数据库查询文件组列表
List<TreeNode<Long>> treeNodeList = fileGroupMapper.selectList(Wrappers.query(fileGroup)).stream()
.map(group -> {
TreeNode<Long> treeNode = new TreeNode<>();
treeNode.setName(group.getName());
treeNode.setId(group.getId());
treeNode.setParentId(group.getPid());
return treeNode;
}).collect(Collectors.toList());
// 构建树形结构
List<Tree<Long>> treeList = TreeUtil.build(treeNodeList, CommonConstants.MENU_TREE_ROOT_ID);
return CollUtil.isEmpty(treeList) ? new ArrayList<>() : treeList;
}
/**
* 添加或更新文件组
* @param fileGroup SysFileGroup对象要添加或更新的文件组信息
* @return 添加或更新成功返回true否则返回false
*/
@Override
public Boolean saveOrUpdateGroup(SysFileGroup fileGroup) {
if (Objects.isNull(fileGroup.getId())) {
// 插入文件组
fileGroupMapper.insert(fileGroup);
}
else {
// 更新文件组
fileGroupMapper.updateById(fileGroup);
}
return Boolean.TRUE;
}
/**
* 删除文件组
* @param id 待删除文件组的ID
* @return 删除成功返回true否则返回false
*/
@Override
public Boolean deleteGroup(Long id) {
// 根据ID删除文件组
fileGroupMapper.deleteById(id);
return Boolean.TRUE;
}
/**
* 移动文件组
* @param fileGroupDTO SysFileGroupDTO对象要移动的文件组信息
* @return 移动成功返回true否则返回false
*/
@Override
public Boolean moveFileGroup(SysFileGroupDTO fileGroupDTO) {
// 创建SysFile对象并设置groupId属性
SysFile file = new SysFile();
file.setGroupId(fileGroupDTO.getGroupId());
// 根据IDS更新对应的SysFile记录
baseMapper.update(file, Wrappers.<SysFile>lambdaQuery().in(SysFile::getId, fileGroupDTO.getIds()));
return Boolean.TRUE;
}
/**
* 文件管理数据记录,收集管理追踪文件
* @param file 上传的文件格式
* @param fileName 文件名
* @param groupId 文件组ID
* @param type 文件类型
*/
private void fileLog(MultipartFile file, String fileName, Long groupId, String type) {
// 创建SysFile对象并设置相关属性
SysFile sysFile = new SysFile();
sysFile.setFileName(fileName);
// 对原始文件名进行编码转换
String originalFilename = new String(
Objects.requireNonNull(file.getOriginalFilename()).getBytes(StandardCharsets.ISO_8859_1),
StandardCharsets.UTF_8);
sysFile.setOriginal(originalFilename);
sysFile.setFileSize(file.getSize());
sysFile.setBucketName(properties.getBucketName());
sysFile.setType(type);
sysFile.setGroupId(groupId);
// 调用save方法保存SysFile对象
this.save(sysFile);
}
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.entity.SysI18nEntity;
import com.pig4cloud.pigx.admin.mapper.SysI18nMapper;
import com.pig4cloud.pigx.admin.service.SysI18nService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.util.R;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 系统表-国际化
*
* @author PIG
* @date 2023-02-14 09:07:01
*/
@Service
public class SysI18nServiceImpl extends ServiceImpl<SysI18nMapper, SysI18nEntity> implements SysI18nService {
/**
* 生成前段需要的i18n 格式内容
* @return
*/
@Override
@Cacheable(value = CacheConstants.I18N_DETAILS)
public Map listMap() {
List<SysI18nEntity> sysI18nEntities = baseMapper.selectList(null);
HashMap<String, List<Map<String, String>>> stringListHashMap = new HashMap<>();
List<Map<String, String>> zhCh = new ArrayList<>();
List<Map<String, String>> en = new ArrayList<>();
sysI18nEntities.forEach(item -> {
HashMap<String, String> zhChMap = new HashMap<>();
HashMap<String, String> enMap = new HashMap<>();
zhChMap.put(item.getName(), item.getZhCn());
enMap.put(item.getName(), item.getEn());
zhCh.add(zhChMap);
en.add(enMap);
});
stringListHashMap.put("zh-cn", zhCh);
stringListHashMap.put("en", en);
return stringListHashMap;
}
/**
* 同步数据
* @return
*/
@Override
@CacheEvict(value = CacheConstants.I18N_DETAILS, allEntries = true)
public R syncI18nCache() {
return R.ok();
}
}

View File

@@ -0,0 +1,109 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.dto.SysLogDTO;
import com.pig4cloud.pigx.admin.api.entity.SysLog;
import com.pig4cloud.pigx.admin.api.vo.PreLogVO;
import com.pig4cloud.pigx.admin.mapper.SysLogMapper;
import com.pig4cloud.pigx.admin.service.SysLogService;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.data.tenant.TenantBroker;
import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 日志表 服务实现类
* </p>
*
* @author lengleng
* @since 2017-11-20
*/
@Service
public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> implements SysLogService {
/**
* 批量插入前端错误日志
* @param preLogVoList 日志信息
* @return true/false
*/
@Override
public Boolean saveBatchLogs(List<PreLogVO> preLogVoList) {
List<SysLog> sysLogs = preLogVoList.stream().map(pre -> {
SysLog log = new SysLog();
log.setLogType(CommonConstants.STATUS_LOCK);
log.setTitle(pre.getInfo());
log.setException(pre.getStack());
log.setParams(pre.getMessage());
log.setCreateTime(LocalDateTime.now());
log.setRequestUri(pre.getUrl());
log.setCreateBy(pre.getUser());
return log;
}).collect(Collectors.toList());
return this.saveBatch(sysLogs);
}
@Override
public Page getLogByPage(Page page, SysLogDTO sysLog) {
LambdaQueryWrapper<SysLog> wrapper = Wrappers.lambdaQuery();
if (StrUtil.isNotBlank(sysLog.getLogType())) {
wrapper.eq(SysLog::getLogType, sysLog.getLogType());
}
if (ArrayUtil.isNotEmpty(sysLog.getCreateTime())) {
wrapper.ge(SysLog::getCreateTime, sysLog.getCreateTime()[0]).le(SysLog::getCreateTime,
sysLog.getCreateTime()[1]);
}
return baseMapper.selectPage(page, wrapper);
}
/**
* 插入日志
* @param sysLog 日志对象
* @return true/false
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean saveLog(SysLogDTO sysLog) {
TenantBroker.applyAs(sysLog::getTenantId, tenantId -> {
TenantContextHolder.setTenantId(tenantId);
SysLog log = new SysLog();
BeanUtils.copyProperties(sysLog, log, "createTime");
return baseMapper.insert(log);
});
return Boolean.TRUE;
}
}

View File

@@ -0,0 +1,195 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.entity.SysI18nEntity;
import com.pig4cloud.pigx.admin.api.entity.SysMenu;
import com.pig4cloud.pigx.admin.api.entity.SysRoleMenu;
import com.pig4cloud.pigx.admin.mapper.SysMenuMapper;
import com.pig4cloud.pigx.admin.mapper.SysRoleMenuMapper;
import com.pig4cloud.pigx.admin.service.SysI18nService;
import com.pig4cloud.pigx.admin.service.SysMenuService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.constant.enums.MenuTypeEnum;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* <p>
* 菜单权限表 服务实现类
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Service
@AllArgsConstructor
@Slf4j
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {
private final SysRoleMenuMapper sysRoleMenuMapper;
private final SysI18nService sysI18nService;
@Override
@Cacheable(value = CacheConstants.MENU_DETAILS, key = "#roleId", unless = "#result.isEmpty()")
public List<SysMenu> findMenuByRoleId(Long roleId) {
return baseMapper.listMenusByRoleId(roleId);
}
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = CacheConstants.MENU_DETAILS, allEntries = true)
public R removeMenuById(Long id) {
// 查询父节点为当前节点的节点
List<SysMenu> menuList = this.list(Wrappers.<SysMenu>query().lambda().eq(SysMenu::getParentId, id));
if (CollUtil.isNotEmpty(menuList)) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_MENU_DELETE_EXISTING));
}
sysRoleMenuMapper.delete(Wrappers.<SysRoleMenu>query().lambda().eq(SysRoleMenu::getMenuId, id));
// 删除当前菜单及其子菜单
return R.ok(this.removeById(id));
}
@Override
@CacheEvict(value = CacheConstants.MENU_DETAILS, allEntries = true)
public Boolean updateMenuById(SysMenu sysMenu) {
return this.updateById(sysMenu);
}
/**
* 构建树查询 1. 不是懒加载情况,查询全部 2. 是懒加载根据parentId 查询 2.1 父节点为空则查询ID -1
* @param parentId 父节点ID
* @param menuName 菜单名称
* @return
*/
@Override
public List<Tree<Long>> treeMenu(Long parentId, String menuName, String type) {
Long parent = parentId == null ? CommonConstants.MENU_TREE_ROOT_ID : parentId;
List<TreeNode<Long>> collect = baseMapper
.selectList(Wrappers.<SysMenu>lambdaQuery()
.like(StrUtil.isNotBlank(menuName), SysMenu::getName, menuName)
.eq(StrUtil.isNotBlank(type), SysMenu::getMenuType, type).orderByAsc(SysMenu::getSortOrder))
.stream().map(getNodeFunction()).collect(Collectors.toList());
// 模糊查询 不组装树结构 直接返回 表格方便编辑
if (StrUtil.isNotBlank(menuName)) {
return collect.stream().map(node -> {
Tree<Long> tree = new Tree<>();
tree.putAll(node.getExtra());
BeanUtils.copyProperties(node, tree);
return tree;
}).collect(Collectors.toList());
}
return TreeUtil.build(collect, parent);
}
/**
* 查询菜单
* @param all 全部菜单
* @param type 类型
* @param parentId 父节点ID
* @return
*/
@Override
public List<Tree<Long>> filterMenu(Set<SysMenu> all, String type, Long parentId) {
List<SysI18nEntity> list = sysI18nService.list();
List<TreeNode<Long>> collect = all.stream().filter(menuTypePredicate(type)).peek(item -> {
Optional<SysI18nEntity> first = list.stream().filter(it -> it.getZhCn().equals(item.getName())).findFirst();
first.ifPresent(sysI18nEntity -> item.setName(sysI18nEntity.getName()));
}).map(getNodeFunction()).collect(Collectors.toList());
Long parent = parentId == null ? CommonConstants.MENU_TREE_ROOT_ID : parentId;
return TreeUtil.build(collect, parent);
}
@NotNull
private Function<SysMenu, TreeNode<Long>> getNodeFunction() {
return menu -> {
TreeNode<Long> node = new TreeNode<>();
node.setId(menu.getMenuId());
node.setName(menu.getName());
node.setParentId(menu.getParentId());
node.setWeight(menu.getSortOrder());
// 扩展属性
Map<String, Object> extra = new HashMap<>();
extra.put("path", menu.getPath());
extra.put("menuType", menu.getMenuType());
extra.put("permission", menu.getPermission());
extra.put("sortOrder", menu.getSortOrder());
// 适配 vue3
Map<String, Object> meta = new HashMap<>();
meta.put("title", menu.getName());
meta.put("isLink", menu.getPath() != null && menu.getPath().startsWith("http") ? menu.getPath() : "");
meta.put("isHide", !BooleanUtil.toBooleanObject(menu.getVisible()));
meta.put("isKeepAlive", BooleanUtil.toBooleanObject(menu.getKeepAlive()));
meta.put("isAffix", false);
meta.put("isIframe", BooleanUtil.toBooleanObject(menu.getEmbedded()));
meta.put("icon", menu.getIcon());
extra.put("meta", meta);
node.setExtra(extra);
return node;
};
}
/**
* menu 类型断言
* @param type 类型
* @return Predicate
*/
private Predicate<SysMenu> menuTypePredicate(String type) {
return vo -> {
if (MenuTypeEnum.TOP_MENU.getDescription().equals(type)) {
return MenuTypeEnum.TOP_MENU.getType().equals(vo.getMenuType());
}
// 其他查询 左侧 + 顶部
return !MenuTypeEnum.BUTTON.getType().equals(vo.getMenuType());
};
}
}

View File

@@ -0,0 +1,146 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.dto.SysOauthClientDetailsDTO;
import com.pig4cloud.pigx.admin.api.entity.SysOauthClientDetails;
import com.pig4cloud.pigx.admin.config.ClientDetailsInitRunner;
import com.pig4cloud.pigx.admin.mapper.SysOauthClientDetailsMapper;
import com.pig4cloud.pigx.admin.service.SysOauthClientDetailsService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 服务实现类
* </p>
*
* @author lengleng
* @since 2018-05-15
*/
@Service
@RequiredArgsConstructor
public class SysOauthClientDetailsServiceImpl extends ServiceImpl<SysOauthClientDetailsMapper, SysOauthClientDetails>
implements SysOauthClientDetailsService {
/**
* 根据客户端信息
* @param clientDetailsDTO
* @return
*/
@Override
@CacheEvict(value = CacheConstants.CLIENT_DETAILS_KEY, key = "#clientDetailsDTO.clientId")
@Transactional(rollbackFor = Exception.class)
public Boolean updateClientById(SysOauthClientDetailsDTO clientDetailsDTO) {
this.insertOrUpdate(clientDetailsDTO);
return Boolean.TRUE;
}
/**
* 添加客户端
* @param clientDetailsDTO
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean saveClient(SysOauthClientDetailsDTO clientDetailsDTO) {
this.insertOrUpdate(clientDetailsDTO);
return Boolean.TRUE;
}
/**
* 插入或更新客户端对象
* @param clientDetailsDTO
* @return
*/
private SysOauthClientDetails insertOrUpdate(SysOauthClientDetailsDTO clientDetailsDTO) {
// copy dto 对象
SysOauthClientDetails clientDetails = new SysOauthClientDetails();
BeanUtils.copyProperties(clientDetailsDTO, clientDetails);
// 获取扩展信息,插入开关相关
String information = clientDetailsDTO.getAdditionalInformation();
JSONObject informationObj = JSONUtil.parseObj(information)
.set(CommonConstants.CAPTCHA_FLAG, clientDetailsDTO.getCaptchaFlag())
.set(CommonConstants.ENC_FLAG, clientDetailsDTO.getEncFlag())
.set(CommonConstants.ONLINE_QUANTITY, clientDetailsDTO.getOnlineQuantity());
clientDetails.setAdditionalInformation(informationObj.toString());
// 更新数据库
saveOrUpdate(clientDetails);
// 更新Redis
SpringContextHolder.publishEvent(new ClientDetailsInitRunner.ClientDetailsInitEvent(clientDetails));
return clientDetails;
}
/**
* 分页查询客户端信息
* @param page
* @param query
* @return
*/
@Override
public Page queryPage(Page page, SysOauthClientDetails query) {
Page<SysOauthClientDetails> selectPage = baseMapper.selectPage(page, Wrappers.query(query));
// 处理扩展字段组装dto
List<SysOauthClientDetailsDTO> collect = selectPage.getRecords().stream().map(details -> {
String information = details.getAdditionalInformation();
String captchaFlag = JSONUtil.parseObj(information).getStr(CommonConstants.CAPTCHA_FLAG);
String encFlag = JSONUtil.parseObj(information).getStr(CommonConstants.ENC_FLAG);
String onlineQuantity = JSONUtil.parseObj(information).getStr(CommonConstants.ONLINE_QUANTITY);
SysOauthClientDetailsDTO dto = new SysOauthClientDetailsDTO();
BeanUtils.copyProperties(details, dto);
dto.setCaptchaFlag(captchaFlag);
dto.setEncFlag(encFlag);
dto.setOnlineQuantity(onlineQuantity);
return dto;
}).collect(Collectors.toList());
// 构建dto page 对象
Page<SysOauthClientDetailsDTO> dtoPage = new Page<>(page.getCurrent(), page.getSize(), selectPage.getTotal());
dtoPage.setRecords(collect);
return dtoPage;
}
@Override
@CacheEvict(value = CacheConstants.CLIENT_DETAILS_KEY, allEntries = true)
public R syncClientCache() {
// 更新Redis
SpringContextHolder.publishEvent(new ClientDetailsInitRunner.ClientDetailsInitEvent(this));
return R.ok();
}
}

View File

@@ -0,0 +1,115 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.entity.SysPost;
import com.pig4cloud.pigx.admin.api.vo.PostExcelVO;
import com.pig4cloud.pigx.admin.mapper.SysPostMapper;
import com.pig4cloud.pigx.admin.service.SysPostService;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.excel.vo.ErrorMessage;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 岗位信息表
*
* @author fxz
* @date 2022-03-26 12:50:43
*/
@Service
public class SysPostServiceImpl extends ServiceImpl<SysPostMapper, SysPost> implements SysPostService {
/**
* 导入岗位
* @param excelVOList 岗位列表
* @param bindingResult 错误信息列表
* @return ok fail
*/
@Override
public R importPost(List<PostExcelVO> excelVOList, BindingResult bindingResult) {
// 通用校验获取失败的数据
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
// 个性化校验逻辑
List<SysPost> postList = this.list();
// 执行数据插入操作 组装 PostDto
for (PostExcelVO excel : excelVOList) {
Set<String> errorMsg = new HashSet<>();
// 检验岗位名称或者岗位编码是否存在
boolean existPost = postList.stream().anyMatch(post -> excel.getPostName().equals(post.getPostName())
|| excel.getPostCode().equals(post.getPostCode()));
if (existPost) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_POST_NAMEORCODE_EXISTING, excel.getPostName(),
excel.getPostCode()));
}
// 数据合法情况
if (CollUtil.isEmpty(errorMsg)) {
insertExcelPost(excel);
}
else {
// 数据不合法
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok();
}
/**
* 导出excel 表格
* @return
*/
@Override
public List<PostExcelVO> listPost(SysPost query, Long[] ids) {
List<SysPost> postList = this
.list(Wrappers.lambdaQuery(query).in(ArrayUtil.isNotEmpty(ids), SysPost::getPostId, ids));
// 转换成execl 对象输出
return postList.stream().map(post -> {
PostExcelVO postExcelVO = new PostExcelVO();
BeanUtil.copyProperties(post, postExcelVO);
return postExcelVO;
}).collect(Collectors.toList());
}
/**
* 插入excel Post
*/
private void insertExcelPost(PostExcelVO excel) {
SysPost sysPost = new SysPost();
BeanUtil.copyProperties(excel, sysPost);
this.save(sysPost);
}
}

View File

@@ -0,0 +1,118 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.entity.SysPublicParam;
import com.pig4cloud.pigx.admin.mapper.SysPublicParamMapper;
import com.pig4cloud.pigx.admin.service.SysPublicParamService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.enums.DictTypeEnum;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 公共参数配置
*
* @author Lucky
* @date 2019-04-29
*/
@Service
@AllArgsConstructor
public class SysPublicParamServiceImpl extends ServiceImpl<SysPublicParamMapper, SysPublicParam>
implements SysPublicParamService {
@Override
@Cacheable(value = CacheConstants.PARAMS_DETAILS, key = "#publicKey", unless = "#result == null ")
public String getSysPublicParamKeyToValue(String publicKey) {
SysPublicParam sysPublicParam = this.baseMapper
.selectOne(Wrappers.<SysPublicParam>lambdaQuery().eq(SysPublicParam::getPublicKey, publicKey));
if (sysPublicParam != null) {
return sysPublicParam.getPublicValue();
}
return null;
}
/**
* 通过key查询公共参数指定值
* @param keys 参数列表
* @return Map
*/
@Override
public Map<String, Object> getSysPublicParamsKeyToValue(String[] keys) {
List<SysPublicParam> paramList = this.baseMapper
.selectList(Wrappers.<SysPublicParam>lambdaQuery().in(SysPublicParam::getPublicKey, keys));
Map<String, Object> result = new HashMap<>(8);
paramList.forEach(param -> result.put(param.getPublicKey(), param.getPublicValue()));
return result;
}
/**
* 更新参数
* @param sysPublicParam
* @return
*/
@Override
@CacheEvict(value = CacheConstants.PARAMS_DETAILS, key = "#sysPublicParam.publicKey")
public R updateParam(SysPublicParam sysPublicParam) {
SysPublicParam param = this.getById(sysPublicParam.getPublicId());
// 系统内置
if (DictTypeEnum.SYSTEM.getType().equals(param.getSystemFlag())) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_PARAM_DELETE_SYSTEM));
}
return R.ok(this.updateById(sysPublicParam));
}
/**
* 删除参数
* @param publicIds 参数ID列表
* @return
*/
@Override
@CacheEvict(value = CacheConstants.PARAMS_DETAILS, allEntries = true)
public R removeParamByIds(Long[] publicIds) {
List<Long> idList = this.baseMapper.selectBatchIds(CollUtil.toList(publicIds)).stream()
.filter(p -> !p.getSystemFlag().equals(DictTypeEnum.SYSTEM.getType()))// 系统内置的跳过不能删除
.map(SysPublicParam::getPublicId).collect(Collectors.toList());
return R.ok(this.removeBatchByIds(idList));
}
/**
* 同步缓存
* @return R
*/
@Override
@CacheEvict(value = CacheConstants.PARAMS_DETAILS, allEntries = true)
public R syncParamCache() {
return R.ok();
}
}

View File

@@ -0,0 +1,81 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.entity.SysRoleMenu;
import com.pig4cloud.pigx.admin.mapper.SysRoleMenuMapper;
import com.pig4cloud.pigx.admin.service.SysRoleMenuService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import lombok.AllArgsConstructor;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 角色菜单表 服务实现类
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Service
@AllArgsConstructor
public class SysRoleMenuServiceImpl extends ServiceImpl<SysRoleMenuMapper, SysRoleMenu> implements SysRoleMenuService {
private final CacheManager cacheManager;
/**
* @param role
* @param roleId 角色
* @param menuIds 菜单ID拼成的字符串每个id之间根据逗号分隔
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = CacheConstants.MENU_DETAILS, key = "#roleId")
public Boolean saveRoleMenus(Long roleId, String menuIds) {
this.remove(Wrappers.<SysRoleMenu>query().lambda().eq(SysRoleMenu::getRoleId, roleId));
if (StrUtil.isBlank(menuIds)) {
return Boolean.TRUE;
}
List<SysRoleMenu> roleMenuList = Arrays.stream(menuIds.split(StrUtil.COMMA)).map(menuId -> {
SysRoleMenu roleMenu = new SysRoleMenu();
roleMenu.setRoleId(roleId);
roleMenu.setMenuId(Long.valueOf(menuId));
return roleMenu;
}).collect(Collectors.toList());
// 清空userinfo
cacheManager.getCache(CacheConstants.USER_DETAILS).clear();
this.saveBatch(roleMenuList);
return Boolean.TRUE;
}
}

View File

@@ -0,0 +1,177 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.entity.SysRole;
import com.pig4cloud.pigx.admin.api.entity.SysRoleMenu;
import com.pig4cloud.pigx.admin.api.vo.RoleExcelVO;
import com.pig4cloud.pigx.admin.api.vo.RoleVO;
import com.pig4cloud.pigx.admin.mapper.SysRoleMapper;
import com.pig4cloud.pigx.admin.service.SysRoleMenuService;
import com.pig4cloud.pigx.admin.service.SysRoleService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.excel.vo.ErrorMessage;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* <p>
* 服务实现类
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Service
@AllArgsConstructor
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
private SysRoleMenuService roleMenuService;
/**
* 通过用户ID查询角色信息
* @param userId
* @return
*/
@Override
public List findRolesByUserId(Long userId) {
return baseMapper.listRolesByUserId(userId);
}
/**
* 根据角色ID 查询角色列表,注意缓存删除
* @param roleIdList 角色ID列表
* @param key 缓存key
* @return
*/
@Override
@Cacheable(value = CacheConstants.ROLE_DETAILS, key = "#key", unless = "#result.isEmpty()")
public List<SysRole> findRolesByRoleIds(List<Long> roleIdList, String key) {
return baseMapper.selectBatchIds(roleIdList);
}
/**
* 通过角色ID删除角色,并清空角色菜单缓存
* @param ids
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean removeRoleByIds(Long[] ids) {
roleMenuService
.remove(Wrappers.<SysRoleMenu>update().lambda().in(SysRoleMenu::getRoleId, CollUtil.toList(ids)));
return this.removeBatchByIds(CollUtil.toList(ids));
}
/**
* 根据角色菜单列表
* @param roleVo 角色&菜单列表
* @return
*/
@Override
public Boolean updateRoleMenus(RoleVO roleVo) {
return roleMenuService.saveRoleMenus(roleVo.getRoleId(), roleVo.getMenuIds());
}
/**
* 导入角色
* @param excelVOList 角色列表
* @param bindingResult 错误信息列表
* @return ok fail
*/
@Override
public R importRole(List<RoleExcelVO> excelVOList, BindingResult bindingResult) {
// 通用校验获取失败的数据
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
// 个性化校验逻辑
List<SysRole> roleList = this.list();
// 执行数据插入操作 组装 RoleDto
for (RoleExcelVO excel : excelVOList) {
Set<String> errorMsg = new HashSet<>();
// 检验角色名称或者角色编码是否存在
boolean existRole = roleList.stream().anyMatch(sysRole -> excel.getRoleName().equals(sysRole.getRoleName())
|| excel.getRoleCode().equals(sysRole.getRoleCode()));
if (existRole) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_ROLE_NAMEORCODE_EXISTING, excel.getRoleName(),
excel.getRoleCode()));
}
// 数据合法情况
if (CollUtil.isEmpty(errorMsg)) {
insertExcelRole(excel);
}
else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok();
}
/**
* 查询全部的角色
* @return list
*/
@Override
public List<RoleExcelVO> listRole(SysRole sysRole, Long[] ids) {
List<SysRole> roleList = this
.list(Wrappers.lambdaQuery(sysRole).in(ArrayUtil.isNotEmpty(ids), SysRole::getRoleId, ids));
// 转换成execl 对象输出
return roleList.stream().map(role -> {
RoleExcelVO roleExcelVO = new RoleExcelVO();
BeanUtil.copyProperties(role, roleExcelVO);
return roleExcelVO;
}).collect(Collectors.toList());
}
/**
* 插入excel Role
*/
private void insertExcelRole(RoleExcelVO excel) {
SysRole sysRole = new SysRole();
sysRole.setRoleName(excel.getRoleName());
sysRole.setRoleDesc(excel.getRoleDesc());
sysRole.setRoleCode(excel.getRoleCode());
this.save(sysRole);
}
}

View File

@@ -0,0 +1,164 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.entity.SysRouteConf;
import com.pig4cloud.pigx.admin.mapper.SysRouteConfMapper;
import com.pig4cloud.pigx.admin.service.SysRouteConfService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.gateway.support.DynamicRouteInitEvent;
import com.pig4cloud.pigx.common.gateway.vo.RouteDefinitionVo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import reactor.core.publisher.Mono;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author lengleng
* @date 2018年11月06日10:27:55
* <p>
* 动态路由处理类
*/
@Slf4j
@AllArgsConstructor
@Service("sysRouteConfService")
public class SysRouteConfServiceImpl extends ServiceImpl<SysRouteConfMapper, SysRouteConf>
implements SysRouteConfService {
private final RedisTemplate redisTemplate;
private final ApplicationEventPublisher applicationEventPublisher;
/**
* 更新路由信息
* @param routes 路由信息
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Mono<Void> updateRoutes(JSONArray routes) {
// 清空Redis 缓存
Boolean result = redisTemplate.delete(CacheConstants.ROUTE_KEY);
log.info("清空网关路由 {} ", result);
// 遍历修改的routes保存到Redis
List<RouteDefinitionVo> routeDefinitionVoList = new ArrayList<>();
try {
routes.forEach(value -> {
log.info("更新路由 ->{}", value);
RouteDefinitionVo vo = new RouteDefinitionVo();
Map<String, Object> map = (Map) value;
Object id = map.get("routeId");
if (id != null) {
vo.setId(String.valueOf(id));
}
Object routeName = map.get("routeName");
if (routeName != null) {
vo.setRouteName(String.valueOf(routeName));
}
Object predicates = map.get("predicates");
if (predicates != null) {
JSONArray predicatesArray = (JSONArray) predicates;
List<PredicateDefinition> predicateDefinitionList = predicatesArray
.toList(PredicateDefinition.class);
vo.setPredicates(predicateDefinitionList);
}
Object filters = map.get("filters");
if (filters != null) {
JSONArray filtersArray = (JSONArray) filters;
List<FilterDefinition> filterDefinitionList = filtersArray.toList(FilterDefinition.class);
vo.setFilters(filterDefinitionList);
}
Object uri = map.get("uri");
if (uri != null) {
vo.setUri(URI.create(String.valueOf(uri)));
}
Object order = map.get("order");
if (order != null) {
vo.setOrder(Integer.parseInt(String.valueOf(order)));
}
Object metadata = map.get("metadata");
if (metadata != null) {
Map<String, Object> metadataMap = JSONUtil.toBean(String.valueOf(metadata), Map.class);
vo.setMetadata(metadataMap);
}
redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(RouteDefinitionVo.class));
redisTemplate.opsForHash().put(CacheConstants.ROUTE_KEY, vo.getId(), vo);
routeDefinitionVoList.add(vo);
});
// 逻辑删除全部
SysRouteConf condition = new SysRouteConf();
condition.setDelFlag(CommonConstants.STATUS_NORMAL);
this.remove(new UpdateWrapper<>(condition));
// 插入生效路由
List<SysRouteConf> routeConfList = routeDefinitionVoList.stream().map(vo -> {
SysRouteConf routeConf = new SysRouteConf();
routeConf.setRouteId(vo.getId());
routeConf.setRouteName(vo.getRouteName());
routeConf.setFilters(JSONUtil.toJsonStr(vo.getFilters()));
routeConf.setPredicates(JSONUtil.toJsonStr(vo.getPredicates()));
routeConf.setSortOrder(vo.getOrder());
routeConf.setUri(vo.getUri().toString());
routeConf.setMetadata(JSONUtil.toJsonStr(vo.getMetadata()));
return routeConf;
}).collect(Collectors.toList());
this.saveBatch(routeConfList);
log.debug("更新网关路由结束 ");
// 通知网关重置路由
redisTemplate.convertAndSend(CacheConstants.ROUTE_JVM_RELOAD_TOPIC, "路由信息,网关缓存更新");
}
catch (Exception e) {
log.error("路由配置解析失败", e);
// 回滚路由,重新加载即可
this.applicationEventPublisher.publishEvent(new DynamicRouteInitEvent(this));
// 抛出异常
throw new RuntimeException(e);
}
return Mono.empty();
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.entity.SysScheduleEntity;
import com.pig4cloud.pigx.admin.mapper.SysScheduleMapper;
import com.pig4cloud.pigx.admin.service.SysScheduleService;
import com.pig4cloud.pigx.common.data.datascope.DataScope;
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.List;
import java.util.Objects;
/**
* 日程
*
* @author aeizzz
* @date 2023-03-06 14:26:23
*/
@Service
public class SysScheduleServiceImpl extends ServiceImpl<SysScheduleMapper, SysScheduleEntity>
implements SysScheduleService {
@Override
public IPage<SysScheduleEntity> getScheduleByScope(Page page, SysScheduleEntity sysSchedule) {
LambdaQueryWrapper<SysScheduleEntity> wrapper = Wrappers.lambdaQuery();
wrapper.like(StrUtil.isNotBlank(sysSchedule.getTitle()), SysScheduleEntity::getTitle, sysSchedule.getTitle());
wrapper.like(StrUtil.isNotBlank(sysSchedule.getType()), SysScheduleEntity::getType, sysSchedule.getType());
wrapper.eq(Objects.nonNull(sysSchedule.getDate()), SysScheduleEntity::getDate, sysSchedule.getDate());
DataScope dataScope = new DataScope();
dataScope.setUsername(SecurityUtils.getUser().getUsername());
return baseMapper.selectPageByScope(page, wrapper, dataScope);
}
@Override
public List<SysScheduleEntity> selectListByScope(String month) {
LocalDate parse = LocalDate.parse(month, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
LocalDate firstDay = parse.with(TemporalAdjusters.firstDayOfMonth()); // 获取当前月的第一天
LocalDate lastDay = parse.with(TemporalAdjusters.lastDayOfMonth());
LambdaQueryWrapper<SysScheduleEntity> wrapper = Wrappers.lambdaQuery();
wrapper.between(SysScheduleEntity::getDate, firstDay, lastDay);
DataScope dataScope = new DataScope();
dataScope.setUsername(SecurityUtils.getUser().getUsername());
return baseMapper.selectListByScope(wrapper, dataScope);
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service.impl;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
import com.pig4cloud.pigx.admin.api.entity.SysUser;
import com.pig4cloud.pigx.admin.handler.LoginHandler;
import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper;
import com.pig4cloud.pigx.admin.mapper.SysUserMapper;
import com.pig4cloud.pigx.admin.service.SysSocialDetailsService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* @author lengleng
* @date 2018年08月16日
*/
@Slf4j
@AllArgsConstructor
@Service("sysSocialDetailsService")
public class SysSocialDetailsServiceImpl extends ServiceImpl<SysSocialDetailsMapper, SysSocialDetails>
implements SysSocialDetailsService {
private final Map<String, LoginHandler> loginHandlerMap;
private final CacheManager cacheManager;
private final SysUserMapper sysUserMapper;
/**
* 绑定社交账号
* @param type type
* @param code code
* @return
*/
@Override
public Boolean bindSocial(String type, String code) {
LoginHandler loginHandler = loginHandlerMap.get(type);
// 绑定逻辑
String identify = loginHandler.identify(code);
SysUser sysUser = sysUserMapper.selectById(SecurityUtils.getUser().getId());
loginHandler.bind(sysUser, identify);
// 更新緩存
cacheManager.getCache(CacheConstants.USER_DETAILS).evict(sysUser.getUsername());
return Boolean.TRUE;
}
/**
* 根据入参查询用户信息
* @param inStr TYPE@code
* @return
*/
@Override
public UserInfo getUserInfo(String inStr) {
String[] inStrs = inStr.split(StringPool.AT);
String type = inStrs[0];
String loginStr = inStr.substring(type.length() + 1);
return loginHandlerMap.get(type).handle(loginStr);
}
}

View File

@@ -0,0 +1,306 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.entity.*;
import com.pig4cloud.pigx.admin.config.ClientDetailsInitRunner;
import com.pig4cloud.pigx.admin.mapper.SysRoleMenuMapper;
import com.pig4cloud.pigx.admin.mapper.SysTenantMapper;
import com.pig4cloud.pigx.admin.service.*;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import com.pig4cloud.pigx.common.data.datascope.DataScopeTypeEnum;
import com.pig4cloud.pigx.common.data.resolver.ParamResolver;
import com.pig4cloud.pigx.common.data.tenant.TenantBroker;
import lombok.AllArgsConstructor;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 租户
* <p>
* mybatis-plus 3.4.3.3 特殊处理 https://github.com/baomidou/mybatis-plus/pull/3592
*
* @author lengleng
* @date 2019-05-15 15:55:41
*/
@Service
@AllArgsConstructor
public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant> implements SysTenantService {
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
private final SysOauthClientDetailsService clientServices;
private final SysUserRoleService userRoleService;
private final SysRoleMenuMapper roleMenuMapper;
private final SysDictItemService dictItemService;
private final SysPublicParamService paramService;
private final SysUserService userService;
private final SysRoleService roleService;
private final SysMenuService menuService;
private final SysDeptService deptService;
private final SysDictService dictService;
private final CacheManager cacheManager;
/**
* 获取正常状态租户
* <p>
* 1. 状态正常 2. 开始时间小于等于当前时间 3. 结束时间大于等于当前时间
* @return
*/
@Override
@Cacheable(value = CacheConstants.TENANT_DETAILS)
public List<SysTenant> getNormalTenant() {
return baseMapper
.selectList(Wrappers.<SysTenant>lambdaQuery().eq(SysTenant::getStatus, CommonConstants.STATUS_NORMAL));
}
/**
* 保存租户
* <p>
* 1. 保存租户 2. 初始化权限相关表 - sys_user - sys_role - sys_menu - sys_user_role -
* sys_role_menu - sys_dict - sys_dict_item - sys_client_details - sys_public_params
* @param sysTenant 租户实体
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = CacheConstants.TENANT_DETAILS)
public Boolean saveTenant(SysTenant sysTenant) {
this.save(sysTenant);
// 查询系统默认租户配置参数
Long defaultId = ParamResolver.getLong("TENANT_DEFAULT_ID", 1L);
String defaultDeptName = ParamResolver.getStr("TENANT_DEFAULT_DEPTNAME", "租户默认部门");
String defaultUsername = ParamResolver.getStr("TENANT_DEFAULT_USERNAME", "admin");
String defaultPassword = ParamResolver.getStr("TENANT_DEFAULT_PASSWORD", "123456");
String defaultRoleCode = ParamResolver.getStr("TENANT_DEFAULT_ROLECODE", "ROLE_ADMIN");
String defaultRoleName = ParamResolver.getStr("TENANT_DEFAULT_ROLENAME", "租户默认角色");
String userDefaultRoleCode = ParamResolver.getStr("USER_DEFAULT_ROLECODE", "GENERAL_USER");
String userDefaultRoleName = ParamResolver.getStr("USER_DEFAULT_ROLENAME", "普通用户");
List<SysDict> dictList = new ArrayList<>(32);
List<Long> dictIdList = new ArrayList<>(32);
List<SysDictItem> dictItemList = new ArrayList<>(64);
List<SysMenu> menuList = new ArrayList<>(128);
List<SysOauthClientDetails> clientDetailsList = new ArrayList<>(16);
List<SysPublicParam> publicParamList = new ArrayList<>(64);
TenantBroker.runAs(defaultId, (id) -> {
// 查询系统内置字典
dictList.addAll(dictService.list());
// 查询系统内置字典项目
dictIdList.addAll(dictList.stream().map(SysDict::getId).collect(Collectors.toList()));
dictItemList.addAll(
dictItemService.list(Wrappers.<SysDictItem>lambdaQuery().in(SysDictItem::getDictId, dictIdList)));
List<SysMenu> newMenuList = menuService.list(Wrappers.<SysMenu>lambdaQuery().in(SysMenu::getMenuId,
StrUtil.split(sysTenant.getMenuId(), CharUtil.COMMA)));
// 查询当前租户菜单
menuList.addAll(newMenuList);
// 查询客户端配置
clientDetailsList.addAll(clientServices.list());
// 查询系统参数配置
publicParamList.addAll(paramService.list());
});
// 保证插入租户为新的租户
TenantBroker.applyAs(sysTenant.getId(), (id -> {
// 插入部门
SysDept dept = new SysDept();
dept.setName(defaultDeptName);
dept.setParentId(0L);
deptService.save(dept);
// 构造初始化用户
SysUser user = new SysUser();
user.setUsername(defaultUsername);
user.setPassword(ENCODER.encode(defaultPassword));
user.setDeptId(dept.getDeptId());
userService.save(user);
// 构造普通用户角色
SysRole roleDefault = new SysRole();
roleDefault.setRoleCode(userDefaultRoleCode);
roleDefault.setRoleName(userDefaultRoleName);
roleDefault.setDsType(DataScopeTypeEnum.SELF_LEVEL.getType());
roleService.save(roleDefault);
// 构造新角色 管理员角色
SysRole role = new SysRole();
role.setRoleCode(defaultRoleCode);
role.setRoleName(defaultRoleName);
role.setDsType(DataScopeTypeEnum.ALL.getType());
roleService.save(role);
// 用户角色关系
SysUserRole userRole = new SysUserRole();
userRole.setUserId(user.getUserId());
userRole.setRoleId(role.getRoleId());
userRoleService.save(userRole);
// 插入新的菜单
saveTenantMenu(menuList, CommonConstants.MENU_TREE_ROOT_ID, CommonConstants.MENU_TREE_ROOT_ID);
// 重新查询出所有的菜单关联角色
List<SysMenu> list = menuService.list();
// 查询全部菜单,构造角色菜单关系
List<SysRoleMenu> roleMenuList = list.stream().map(menu -> {
SysRoleMenu roleMenu = new SysRoleMenu();
roleMenu.setRoleId(role.getRoleId());
roleMenu.setMenuId(menu.getMenuId());
return roleMenu;
}).collect(Collectors.toList());
roleMenuList.forEach(roleMenuMapper::insert);
// 插入系统字典
dictService.saveBatch(dictList.stream().peek(d -> d.setId(null)).collect(Collectors.toList()));
// 处理字典项最新关联的字典ID
List<SysDictItem> itemList = dictList.stream().flatMap(dict -> dictItemList.stream()
.filter(item -> item.getDictType().equals(dict.getDictType())).peek(item -> {
item.setDictId(dict.getId());
item.setId(null);
})).collect(Collectors.toList());
// 插入客户端
clientServices.saveBatch(clientDetailsList.stream().peek(d -> d.setId(null)).collect(Collectors.toList()));
// 插入系统配置
paramService
.saveBatch(publicParamList.stream().peek(d -> d.setPublicId(null)).collect(Collectors.toList()));
return dictItemService.saveBatch(itemList);
}));
SpringContextHolder.publishEvent(new ClientDetailsInitRunner.ClientDetailsInitEvent(sysTenant));
return Boolean.TRUE;
}
/**
* 修改租户
* @param tenantDTO
* @return
*/
@Override
@CacheEvict(value = CacheConstants.TENANT_DETAILS, allEntries = true)
public Boolean updateTenant(SysTenant tenantDTO) {
SysTenant tenant = baseMapper.selectById(tenantDTO.getId());
// 更新租户数据
updateById(tenantDTO);
// 如果没有修改租户套餐
Long defaultId = ParamResolver.getLong("TENANT_DEFAULT_ID", 1L);
if (defaultId.equals(tenantDTO.getId())) {
return Boolean.TRUE;
}
if (tenant.getMenuId().equals(tenantDTO.getMenuId())) {
return Boolean.TRUE;
}
List<SysMenu> sysMenuList = TenantBroker.applyAs(defaultId, id -> menuService.list(Wrappers
.<SysMenu>lambdaQuery().in(SysMenu::getMenuId, StrUtil.split(tenantDTO.getMenuId(), CharUtil.COMMA))));
TenantBroker.runAs(tenantDTO.getId(), (tenantId -> {
// 查询当前租户的所有菜单
List<SysMenu> menuList = menuService.list(Wrappers.emptyWrapper());
// 套餐功能对比和已有菜单对比 (新增)
List<SysMenu> addMenuList = new ArrayList<>();
List<SysMenu> delMenuList = new ArrayList<>();
// 判断新增的菜单列表
menuExist(sysMenuList, menuList, addMenuList);
// 判断删除的菜单列表
menuExist(menuList, sysMenuList, delMenuList);
// 新增的菜单
this.saveTenantMenu(addMenuList, CommonConstants.MENU_TREE_ROOT_ID, CommonConstants.MENU_TREE_ROOT_ID);
// 套餐删除的菜单
List<Long> menuIdList = delMenuList.stream().map(SysMenu::getMenuId).collect(Collectors.toList());
menuService.removeBatchByIds(menuIdList);
// 清空菜单权限
cacheManager.getCache(CacheConstants.MENU_DETAILS).clear();
}));
return Boolean.TRUE;
}
/**
* 判断菜单是否存在
* @param sysMenuList 要判断的菜单列表
* @param menuList 已有菜单列表
* @param addMenuList 待添加的菜单列表
*/
private void menuExist(List<SysMenu> sysMenuList, List<SysMenu> menuList, List<SysMenu> addMenuList) {
for (SysMenu sysMenu : sysMenuList) {
if (StrUtil.isNotBlank(sysMenu.getPath())) {
// 根据菜单path名称查询套餐菜单是否存在
if (menuList.stream().noneMatch(menu -> sysMenu.getPath().equals(menu.getPath()))) {
addMenuList.add(sysMenu);
}
}
if (StrUtil.isNotBlank(sysMenu.getPermission())) {
// 根据菜单permission名称查询套餐菜单是否存在
if (menuList.stream().noneMatch(menu -> sysMenu.getPermission().equals(menu.getPermission()))) {
addMenuList.add(sysMenu);
}
}
}
}
/**
* 保存新的租户菜单,维护成新的菜单
* @param menuList 菜单列表
* @param originParentId 原始上级
* @param targetParentId 目标上级
*/
private void saveTenantMenu(List<SysMenu> menuList, Long originParentId, Long targetParentId) {
menuList.stream().filter(menu -> menu.getParentId().equals(originParentId)).forEach(menu -> {
// 保存菜单原始menuId 方便查询子节点使用
Long originMenuId = menu.getMenuId();
menu.setMenuId(null);
menu.setParentId(targetParentId);
menuService.save(menu);
// 查找此节点的子节点然后子节点的重新插入父节点更改为新的menuId
saveTenantMenu(menuList, originMenuId, menu.getMenuId());
});
}
}

View File

@@ -0,0 +1,39 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.entity.SysUserRole;
import com.pig4cloud.pigx.admin.mapper.SysUserRoleMapper;
import com.pig4cloud.pigx.admin.service.SysUserRoleService;
import org.springframework.stereotype.Service;
/**
* <p>
* 用户角色表 服务实现类
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Service
public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRoleMapper, SysUserRole> implements SysUserRoleService {
}

View File

@@ -0,0 +1,525 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.dto.UserDTO;
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
import com.pig4cloud.pigx.admin.api.entity.*;
import com.pig4cloud.pigx.admin.api.vo.UserExcelVO;
import com.pig4cloud.pigx.admin.api.vo.UserVO;
import com.pig4cloud.pigx.admin.mapper.SysUserMapper;
import com.pig4cloud.pigx.admin.mapper.SysUserPostMapper;
import com.pig4cloud.pigx.admin.mapper.SysUserRoleMapper;
import com.pig4cloud.pigx.admin.service.*;
import com.pig4cloud.pigx.common.audit.annotation.Audit;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.data.datascope.DataScope;
import com.pig4cloud.pigx.common.data.resolver.ParamResolver;
import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
import com.pig4cloud.pigx.common.excel.vo.ErrorMessage;
import com.pig4cloud.pigx.common.security.service.PigxUser;
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author lengleng
* @date 2017/10/31
*/
@Slf4j
@Service
@AllArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
private final SysMenuService sysMenuService;
private final SysRoleService sysRoleService;
private final SysPostService sysPostService;
private final SysDeptService sysDeptService;
private final SysUserRoleMapper sysUserRoleMapper;
private final SysUserPostMapper sysUserPostMapper;
private final CacheManager cacheManager;
/**
* 保存用户信息
* @param userDto DTO 对象
* @return success/fail
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean saveUser(UserDTO userDto) {
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(userDto, sysUser);
sysUser.setDelFlag(CommonConstants.STATUS_NORMAL);
sysUser.setCreateBy(userDto.getUsername());
sysUser.setUpdateBy(userDto.getUsername());
sysUser.setPassword(ENCODER.encode(userDto.getPassword()));
baseMapper.insert(sysUser);
// 保存用户岗位信息
Optional.ofNullable(userDto.getPost()).ifPresent(posts -> {
posts.stream().map(postId -> {
SysUserPost userPost = new SysUserPost();
userPost.setUserId(sysUser.getUserId());
userPost.setPostId(postId);
return userPost;
}).forEach(sysUserPostMapper::insert);
});
// 如果角色为空,赋默认角色
if (CollUtil.isEmpty(userDto.getRole())) {
Long tenantId = TenantContextHolder.getTenantId();
// 获取默认角色编码
String defaultRole = ParamResolver.getStr("USER_DEFAULT_ROLE");
// 默认角色 //fix pigX功能bug 添加租户查询(或者去掉租户属性)
SysRole sysRole = sysRoleService
.getOne(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleCode, defaultRole).eq(SysRole::getTenantId,tenantId));
userDto.setRole(Collections.singletonList(sysRole.getRoleId()));
}
// 插入用户角色关系表
userDto.getRole().stream().map(roleId -> {
SysUserRole userRole = new SysUserRole();
userRole.setUserId(sysUser.getUserId());
userRole.setRoleId(roleId);
return userRole;
}).forEach(sysUserRoleMapper::insert);
return Boolean.TRUE;
}
/**
* 通过查用户的全部信息
* @param sysUser 用户
* @return
*/
@Override
public UserInfo findUserInfo(SysUser sysUser) {
UserInfo userInfo = new UserInfo();
userInfo.setSysUser(sysUser);
// 设置角色列表 ID
List<Long> roleIds = sysRoleService.findRolesByUserId(sysUser.getUserId()).stream().map(SysRole::getRoleId)
.collect(Collectors.toList());
userInfo.setRoles(ArrayUtil.toArray(roleIds, Long.class));
// 设置权限列表menu.permission
Set<String> permissions = new HashSet<>();
roleIds.forEach(roleId -> {
List<String> permissionList = sysMenuService.findMenuByRoleId(roleId).stream()
.filter(menu -> StrUtil.isNotEmpty(menu.getPermission())).map(SysMenu::getPermission)
.collect(Collectors.toList());
permissions.addAll(permissionList);
});
userInfo.setPermissions(ArrayUtil.toArray(permissions, String.class));
return userInfo;
}
/**
* 分页查询用户信息(含有角色信息)
* @param page 分页对象
* @param userDTO 参数列表
* @return
*/
@Override
public IPage getUsersWithRolePage(Page page, UserDTO userDTO) {
return baseMapper.getUserVosPage(page, userDTO, DataScope.of());
}
/**
* 通过ID查询用户信息
* @param id 用户ID
* @return 用户信息
*/
@Override
public UserVO selectUserVoById(Long id) {
return baseMapper.getUserVoById(id);
}
/**
* 删除用户
* @param ids 用户ID 列表
* @return Boolean
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteUserByIds(Long[] ids) {
// 删除 spring cache
List<SysUser> userList = baseMapper.selectBatchIds(CollUtil.toList(ids));
Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS);
for (SysUser sysUser : userList) {
cache.evict(sysUser.getUsername());
}
sysUserRoleMapper.delete(Wrappers.<SysUserRole>lambdaQuery().in(SysUserRole::getUserId, CollUtil.toList(ids)));
this.removeBatchByIds(CollUtil.toList(ids));
return Boolean.TRUE;
}
@Override
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username")
public R<Boolean> updateUserInfo(UserDTO userDto) {
UserVO userVO = baseMapper.getUserVoByUsername(userDto.getUsername());
SysUser sysUser = new SysUser();
sysUser.setPhone(userDto.getPhone());
sysUser.setUserId(userVO.getUserId());
sysUser.setAvatar(userDto.getAvatar());
sysUser.setNickname(userDto.getNickname());
sysUser.setName(userDto.getName());
sysUser.setEmail(userDto.getEmail());
return R.ok(this.updateById(sysUser));
}
@Override
@Transactional(rollbackFor = Exception.class)
@Audit(name = "用户更新", spel = "@sysUserMapper.selectById(#userDto.userId)")
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username")
public Boolean updateUser(UserDTO userDto) {
// 更新用户表信息
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(userDto, sysUser);
sysUser.setUpdateTime(LocalDateTime.now());
if (StrUtil.isNotBlank(userDto.getPassword())) {
sysUser.setPassword(ENCODER.encode(userDto.getPassword()));
}
this.updateById(sysUser);
// 更新用户角色表
if (userDto.getRole() != null) {
sysUserRoleMapper
.delete(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserId, userDto.getUserId()));
userDto.getRole().stream().map(roleId -> {
SysUserRole userRole = new SysUserRole();
userRole.setUserId(sysUser.getUserId());
userRole.setRoleId(roleId);
return userRole;
}).forEach(SysUserRole::insert);
}
// 更新用户岗位表
if (userDto.getPost() != null) {
sysUserPostMapper
.delete(Wrappers.<SysUserPost>lambdaQuery().eq(SysUserPost::getUserId, userDto.getUserId()));
userDto.getPost().stream().map(postId -> {
SysUserPost userPost = new SysUserPost();
userPost.setUserId(sysUser.getUserId());
userPost.setPostId(postId);
return userPost;
}).forEach(SysUserPost::insert);
}
return Boolean.TRUE;
}
/**
* 查询上级部门的用户信息
* @param username 用户名
* @return R
*/
@Override
public List<SysUser> listAncestorUsers(String username) {
SysUser sysUser = this.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getUsername, username));
SysDept sysDept = sysDeptService.getById(sysUser.getDeptId());
if (sysDept == null) {
return null;
}
Long parentId = sysDept.getParentId();
return this.list(Wrappers.<SysUser>query().lambda().eq(SysUser::getDeptId, parentId));
}
/**
* 查询全部的用户
* @param userDTO 查询条件
* @param ids ids 用户列表
* @return list
*/
@Override
public List<UserExcelVO> listUser(UserDTO userDTO, Long[] ids) {
// 根据数据权限查询全部的用户信息
List<UserVO> voList = baseMapper.selectVoListByScope(userDTO, ids, DataScope.of());
// 转换成execl 对象输出
List<UserExcelVO> userExcelVOList = voList.stream().map(userVO -> {
UserExcelVO excelVO = new UserExcelVO();
BeanUtils.copyProperties(userVO, excelVO);
String roleNameList = userVO.getRoleList().stream().map(SysRole::getRoleName)
.collect(Collectors.joining(StrUtil.COMMA));
excelVO.setRoleNameList(roleNameList);
String postNameList = userVO.getPostList().stream().map(SysPost::getPostName)
.collect(Collectors.joining(StrUtil.COMMA));
excelVO.setPostNameList(postNameList);
return excelVO;
}).collect(Collectors.toList());
return userExcelVOList;
}
/**
* excel 导入用户, 插入正确的 错误的提示行号
* @param excelVOList excel 列表数据
* @param bindingResult 错误数据
* @return ok fail
*/
@Override
public R importUser(List<UserExcelVO> excelVOList, BindingResult bindingResult) {
// 通用校验获取失败的数据
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
List<SysDept> deptList = sysDeptService.list();
List<SysRole> roleList = sysRoleService.list();
List<SysPost> postList = sysPostService.list();
// 执行数据插入操作 组装 UserDto
for (UserExcelVO excel : excelVOList) {
// 个性化校验逻辑
List<SysUser> userList = this.list();
Set<String> errorMsg = new HashSet<>();
// 校验用户名是否存在
boolean exsitUserName = userList.stream()
.anyMatch(sysUser -> excel.getUsername().equals(sysUser.getUsername()));
if (exsitUserName) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, excel.getUsername()));
}
// 判断输入的部门名称列表是否合法
Optional<SysDept> deptOptional = deptList.stream()
.filter(dept -> excel.getDeptName().equals(dept.getName())).findFirst();
if (!deptOptional.isPresent()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_DEPT_DEPTNAME_INEXISTENCE, excel.getDeptName()));
}
// 判断输入的角色名称列表是否合法
List<String> roleNameList = StrUtil.split(excel.getRoleNameList(), StrUtil.COMMA);
List<SysRole> roleCollList = roleList.stream()
.filter(role -> roleNameList.stream().anyMatch(name -> role.getRoleName().equals(name)))
.collect(Collectors.toList());
if (roleCollList.size() != roleNameList.size()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_ROLE_ROLENAME_INEXISTENCE, excel.getRoleNameList()));
}
// 判断输入的部门名称列表是否合法
List<String> postNameList = StrUtil.split(excel.getPostNameList(), StrUtil.COMMA);
List<SysPost> postCollList = postList.stream()
.filter(post -> postNameList.stream().anyMatch(name -> post.getPostName().equals(name)))
.collect(Collectors.toList());
if (postCollList.size() != postNameList.size()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_POST_POSTNAME_INEXISTENCE, excel.getPostNameList()));
}
// 数据合法情况
if (CollUtil.isEmpty(errorMsg)) {
insertExcelUser(excel, deptOptional, roleCollList, postCollList);
}
else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok(null, MsgUtils.getMessage(ErrorCodes.SYS_USER_IMPORT_SUCCEED));
}
/**
* 插入excel User
*/
private void insertExcelUser(UserExcelVO excel, Optional<SysDept> deptOptional, List<SysRole> roleCollList,
List<SysPost> postCollList) {
UserDTO userDTO = new UserDTO();
userDTO.setUsername(excel.getUsername());
userDTO.setPhone(excel.getPhone());
userDTO.setNickname(excel.getNickname());
userDTO.setName(excel.getName());
userDTO.setEmail(excel.getEmail());
// 批量导入初始密码为手机号
userDTO.setPassword(userDTO.getPhone());
// 根据部门名称查询部门ID
userDTO.setDeptId(deptOptional.get().getDeptId());
// 插入岗位名称
List<Long> postIdList = postCollList.stream().map(SysPost::getPostId).collect(Collectors.toList());
userDTO.setPost(postIdList);
// 根据角色名称查询角色ID
List<Long> roleIdList = roleCollList.stream().map(SysRole::getRoleId).collect(Collectors.toList());
userDTO.setRole(roleIdList);
// 插入用户
this.saveUser(userDTO);
}
/**
* 注册用户 赋予用户默认角色
* @param userDto 用户信息
* @return success/false
*/
@Override
@Transactional(rollbackFor = Exception.class)
public R<Boolean> registerUser(UserDTO userDto) {
// 判断用户名是否存在
SysUser sysUser = this.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, userDto.getUsername()));
if (sysUser != null) {
String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, userDto.getUsername());
return R.failed(message);
}
return R.ok(saveUser(userDto));
}
/**
* 锁定用户
* @param username 用户名
* @return
*/
@Override
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#username")
public R<Boolean> lockUser(String username) {
SysUser sysUser = baseMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
if (Objects.nonNull(sysUser)) {
sysUser.setLockFlag(CommonConstants.STATUS_LOCK);
baseMapper.updateById(sysUser);
}
return R.ok();
}
@Override
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username")
public R changePassword(UserDTO userDto) {
UserVO userVO = baseMapper.getUserVoByUsername(userDto.getUsername());
if (Objects.isNull(userVO)) {
return R.failed("用户不存在");
}
if (StrUtil.isEmpty(userDto.getPassword())) {
return R.failed("原密码不能为空");
}
if (!ENCODER.matches(userDto.getPassword(), userVO.getPassword())) {
log.info("原密码错误,修改个人信息失败:{}", userDto.getUsername());
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_UPDATE_PASSWORDERROR));
}
if (StrUtil.isEmpty(userDto.getNewpassword1())) {
return R.failed("新密码不能为空");
}
String password = ENCODER.encode(userDto.getNewpassword1());
this.update(Wrappers.<SysUser>lambdaUpdate().set(SysUser::getPassword, password).eq(SysUser::getUserId,
userVO.getUserId()));
return R.ok();
}
@Override
public R unbinding(String type) {
PigxUser user = SecurityUtils.getUser();
LambdaUpdateWrapper<SysUser> wrapper = null;
if (type.equals("wechat")) {
wrapper = Wrappers.<SysUser>lambdaUpdate().set(SysUser::getWxOpenid, null).eq(SysUser::getUserId,
user.getId());
}
else if (type.equals("gitee")) {
wrapper = Wrappers.<SysUser>lambdaUpdate().set(SysUser::getGiteeLogin, null).eq(SysUser::getUserId,
user.getId());
}
else if (type.equals("osc")) {
wrapper = Wrappers.<SysUser>lambdaUpdate().set(SysUser::getOscId, null).eq(SysUser::getUserId,
user.getId());
}
else if (type.equals("tencent")) {
wrapper = Wrappers.<SysUser>lambdaUpdate().set(SysUser::getQqOpenid, null).eq(SysUser::getUserId,
user.getId());
}
if (wrapper == null) {
return R.failed("解绑账号类型不存在");
}
this.update(wrapper);
return R.ok();
}
@Override
public R checkPassword(String password) {
String username = SecurityUtils.getUser().getUsername();
SysUser condition = new SysUser();
condition.setUsername(username);
SysUser sysUser = this.getOne(new QueryWrapper<>(condition));
if (!ENCODER.matches(password, sysUser.getPassword())) {
log.info("原密码错误");
return R.failed("密码输入错误");
}
else {
return R.ok();
}
}
@Override
public List<Long> listUserIdByRoleIds(List<Long> roleIdList) {
return sysUserRoleMapper.selectList(Wrappers.<SysUserRole>lambdaQuery().in(SysUserRole::getRoleId, roleIdList))
.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
}
/**
* 根据部门ID列表获取用户ID列表接口
* @param deptIdList 部门ID列表
* @return List<Long> 返回结果对象包含根据部门ID列表获取到的用户ID列表信息
*/
@Override
public List<SysUser> listUserIdByDeptIds(List<Long> deptIdList) {
return baseMapper.selectList(Wrappers.<SysUser>lambdaQuery().in(SysUser::getDeptId, deptIdList));
}
}

View File

@@ -0,0 +1,21 @@
server:
port: 4000
spring:
application:
name: @artifactId@
cloud:
nacos:
username: @nacos.username@
password: @nacos.password@
discovery:
server-addr: ${NACOS_HOST:pigx-register}:${NACOS_PORT:8848}
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
config:
import:
- optional:nacos:application-@profiles.active@.yml
- optional:nacos:${spring.application.name}-@profiles.active@.yml

Some files were not shown because too many files have changed in this diff Show More